-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
102 lines (85 loc) · 3.23 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
var path = require('path');
var crypto = require('crypto');
var fs = require('fs');
var api = require('./api');
var EventEmitter = require('events');
class B2 {
constructor(user, password, config = {}) {
this._auth = [user, password].join(':');
this._config = Object.assign({connections: 4, bucket: null}, config);
this._init = {expires: 0};
}
init(callback) {
// If initted in the last two minutes don't bother initing again
if (Date.now() < this._init.expires)
return callback(null, this._init);
api.authorizeAccount(this._auth, (err, settings) => {
if (err) return callback(err);
api.listBuckets(settings, (err, data) => {
if (err) return callback(err);
if (data.buckets.length === 0) return callback(new Error('No buckets in account'));
this._init = {'buckets': data.buckets, 'settings': settings, 'expires': Date.now() + 120000};
callback(null, this._init);
});
});
}
uploadFile(file, options) {
var emitter = new EventEmitter();
var args = [...arguments];
var callback = function() {
};
if (args[args.length - 1] instanceof Function) {
callback = args.pop();
if (args.length === 1) options = {};
}
// console.log('Upload file options are:', options);
if (options.name && !options.name instanceof String) throw new Error('Name must be a string');
if (options.bucket && !options.bucket instanceof String) throw new Error('Bucket must be a string');
if (options.password && !options.password instanceof String) throw new Error('Password must be a string');
var uploadBuffer = (fileBuffer) => {
this.init((err, context) => {
if (err) return callback(err);
// Pick the proper bucket based on defaults and user preference
let bucket = context.buckets[0];
options.bucket = options.bucket || this._config.bucket;
if (options.bucket) {
bucket = context.buckets.find(r => r.bucketName == options.bucket);
if (!bucket) throw new Error(`bucket ${options.bucket} could not be found`);
}
// If a password is specified, encrypt the file
if (options.password) {
var cipher = crypto.createCipher('aes-256-ctr', options.password);
fileBuffer = Buffer.concat([cipher.update(fileBuffer), cipher.final()]);
}
// Get an endpoint to upload to
api.getUploadUrl(context.settings, bucket.bucketId, (err, uploadUrl) => {
if (err) return callback(err);
// Upload it
// var fileName = options.name || path.basename(options.file);
api.uploadFile(uploadUrl, fileBuffer, options.name, (err, res) => {
if (err) return callback(err);
callback(null, `${context.settings.downloadUrl}/file/${bucket.bucketName}/${res.fileName}`);
}, emitter);
});
});
};
// If file is a string, read it in to a buffer
if (file instanceof Buffer) {
if (options.name) {
uploadBuffer(file);
} else {
callback(new Error('If using a buffer you must specify a name for your file'));
}
} else if (typeof file === 'string') {
options.name = options.name || path.basename(file);
fs.readFile(file, (err, fileBuffer) => {
if (err) return callback(err);
uploadBuffer(fileBuffer, options, callback);
});
} else {
callback(new Error('Invalid file, must be a path or buffer'));
}
return emitter;
}
}
module.exports = B2;