backblaze-b2
Advanced tools
Comparing version 1.2.0 to 1.3.1
@@ -21,2 +21,3 @@ module.exports = { | ||
"env": { | ||
es6: true, | ||
"node": true | ||
@@ -23,0 +24,0 @@ }, |
@@ -1,9 +0,14 @@ | ||
var conf = require('../../conf'); | ||
var request = require('./../request'); | ||
var utils = require('./../utils'); | ||
const _ = require('lodash'); | ||
const conf = require('../../conf'); | ||
const request = require('./../request'); | ||
const utils = require('./../utils'); | ||
exports.authorize = function(b2) { | ||
var options = getRequestOptions(b2.accountId, b2.applicationKey); | ||
var axiosInstance = request.getInstance(); | ||
exports.authorize = function(b2, args) { | ||
// merge order matters here: later objects override earlier objects | ||
const options = _.merge({}, | ||
_.get(args, 'axios', {}), | ||
getRequestOptions(b2.accountId, b2.applicationKey), | ||
_.get(args, 'axiosOverride', {}) | ||
); | ||
const axiosInstance = request.getInstance(); | ||
return axiosInstance(options).then(function(res) { | ||
@@ -10,0 +15,0 @@ utils.saveAuthContext(b2, res.data); |
@@ -1,4 +0,5 @@ | ||
var utils = require('./../utils'); | ||
var request = require('../request'); | ||
var conf = require('../../conf'); | ||
const _ = require('lodash'); | ||
const utils = require('./../utils'); | ||
const request = require('../request'); | ||
const endpoints = require('../endpoints'); | ||
@@ -10,5 +11,12 @@ exports.TYPES = { | ||
exports.create = function(b2, bucketName, bucketType) { | ||
var options = { | ||
url: getCreateUrl(b2, bucketName, bucketType), | ||
exports.create = function(b2, argsOrBucketName, undefOrBucketType) { | ||
// we're allowing an args object OR bucketName and bucketType for backwards compatibility | ||
let bucketName = argsOrBucketName; | ||
let bucketType = undefOrBucketType; | ||
if (!_.isString(argsOrBucketName)) { | ||
bucketName = _.get(argsOrBucketName, 'bucketName'); | ||
bucketType = _.get(argsOrBucketName, 'bucketType'); | ||
} | ||
const options = { | ||
url: endpoints(b2).createBucketUrl, | ||
method: 'POST', | ||
@@ -22,8 +30,18 @@ headers: utils.getAuthHeaderObjectWithToken(b2), | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(argsOrBucketName, 'axios', {}), | ||
options, | ||
_.get(argsOrBucketName, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.delete = function(b2, bucketId) { | ||
var options = { | ||
url: getDeleteUrl(b2), | ||
exports.delete = function(b2, argsOrBucketId) { | ||
// we're allowing an args object OR bucketId for backwards compatibility | ||
let bucketId = argsOrBucketId; | ||
if (!_.isString(argsOrBucketId)) { | ||
bucketId = _.get(argsOrBucketId, 'bucketId'); | ||
} | ||
const options = { | ||
url: endpoints(b2).deleteBucketUrl, | ||
method: 'POST', | ||
@@ -36,8 +54,13 @@ data: { | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(argsOrBucketId, 'axios', {}), | ||
options, | ||
_.get(argsOrBucketId, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.list = function(b2) { | ||
var options = { | ||
url: getListUrl(b2), | ||
exports.list = function(b2, args) { | ||
const options = { | ||
url: endpoints(b2).listBucketUrl, | ||
method: 'POST', | ||
@@ -50,3 +73,8 @@ data: { | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
)); | ||
}; | ||
@@ -68,3 +96,3 @@ | ||
const options = { | ||
url: getListUrl(b2), | ||
url: endpoints(b2).listBucketUrl, | ||
method: 'POST', | ||
@@ -74,8 +102,20 @@ data, | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.update = function(b2, bucketId, bucketType) { | ||
var options = { | ||
url: getUpdateUrl(b2), | ||
exports.update = function(b2, argsOrBucketId, undefOrBucketType) { | ||
// we're allowing an args object OR bucketId and bucketType for backwards compatibility | ||
let bucketId = argsOrBucketId; | ||
let bucketType = undefOrBucketType; | ||
if (!_.isString(argsOrBucketId)) { | ||
bucketId = _.get(argsOrBucketId, 'bucketId'); | ||
bucketType = _.get(argsOrBucketId, 'bucketType'); | ||
} | ||
const options = { | ||
url: endpoints(b2).updateBucketUrl, | ||
method: 'POST', | ||
@@ -89,8 +129,18 @@ data: { | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(argsOrBucketId, 'axios', {}), | ||
options, | ||
_.get(argsOrBucketId, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.getUploadUrl = function(b2, bucketId) { | ||
var options = { | ||
url: getGetUploadUrl(b2), | ||
exports.getUploadUrl = function(b2, argsOrBucketId) { | ||
// we're allowing an args object OR bucketId for backwards compatibility | ||
let bucketId = argsOrBucketId; | ||
if (!_.isString(argsOrBucketId)) { | ||
bucketId = _.get(argsOrBucketId, 'bucketId'); | ||
} | ||
const options = { | ||
url: endpoints(b2).getBucketUploadUrl, | ||
method: 'POST', | ||
@@ -102,27 +152,8 @@ data: { | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(argsOrBucketId, 'axios', {}), | ||
options, | ||
_.get(argsOrBucketId, 'axiosOverride', {}) | ||
)); | ||
}; | ||
function getCreateUrl(b2) { | ||
return getApiUrl(b2) + '/b2_create_bucket'; | ||
} | ||
function getDeleteUrl(b2) { | ||
return getApiUrl(b2) + '/b2_delete_bucket'; | ||
} | ||
function getListUrl(b2) { | ||
return getApiUrl(b2) + '/b2_list_buckets'; | ||
} | ||
function getUpdateUrl(b2) { | ||
return getApiUrl(b2) + '/b2_update_bucket'; | ||
} | ||
function getGetUploadUrl(b2) { | ||
return getApiUrl(b2) + '/b2_get_upload_url'; | ||
} | ||
function getApiUrl(b2) { | ||
return b2.apiUrl + conf.API_VERSION_URL; | ||
} |
@@ -1,18 +0,19 @@ | ||
var utils = require('./../utils'); | ||
var headersUtil = require('../headers'); | ||
var request = require('../request'); | ||
var conf = require('../../conf'); | ||
const _ = require('lodash'); | ||
const utils = require('./../utils'); | ||
const headersUtil = require('../headers'); | ||
const request = require('../request'); | ||
const endpoints = require('../endpoints'); | ||
const sha1 = (value) => require('crypto').createHash('sha1').update(value).digest('hex'); | ||
exports.uploadFile = function(b2, args) { | ||
var uploadUrl = args.uploadUrl; | ||
var uploadAuthToken = args.uploadAuthToken; | ||
const uploadUrl = args.uploadUrl; | ||
const uploadAuthToken = args.uploadAuthToken; | ||
// Previous versions used filename (lowercase), so support that here | ||
var fileName = utils.getUrlEncodedFileName(args.fileName || args.filename); | ||
var data = args.data; | ||
var hash = args.hash; | ||
var info = args.info; | ||
var mime = args.mime; | ||
const fileName = utils.getUrlEncodedFileName(args.fileName || args.filename); | ||
const data = args.data; | ||
const hash = args.hash; | ||
const info = args.info; | ||
const mime = args.mime; | ||
var options = { | ||
const options = { | ||
url: uploadUrl, | ||
@@ -31,9 +32,15 @@ method: 'POST', | ||
}; | ||
headersUtil.addInfoHeaders(options, info); | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.startLargeFile = function(b2, args) { | ||
var options = { | ||
url: getStartLargeFileUrl(b2), | ||
const options = { | ||
url: endpoints(b2).startLargeFileUrl, | ||
method: 'POST', | ||
@@ -47,8 +54,14 @@ headers: utils.getAuthHeaderObjectWithToken(b2), | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.getUploadPartUrl = function(b2, args) { | ||
var options = { | ||
url: getGetUploadPartUrl(b2), | ||
const options = { | ||
url: endpoints(b2).getUploadPartUrl, | ||
method: 'POST', | ||
@@ -60,7 +73,13 @@ headers: utils.getAuthHeaderObjectWithToken(b2), | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.uploadPart = function(b2, args) { | ||
var options = { | ||
const options = { | ||
url: args.uploadUrl, | ||
@@ -78,8 +97,14 @@ method: 'POST', | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.finishLargeFile = function(b2, args) { | ||
var options = { | ||
url: getFinishLargeFileUrl(b2), | ||
const options = { | ||
url: endpoints(b2).finishLargeFileUrl, | ||
method: 'POST', | ||
@@ -92,8 +117,14 @@ headers: utils.getAuthHeaderObjectWithToken(b2), | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.cancelLargeFile = function(b2, args) { | ||
var options = { | ||
url: getCancelLargeFileUrl(b2), | ||
const options = { | ||
url: endpoints(b2).cancelLargeFileUrl, | ||
method: 'POST', | ||
@@ -105,14 +136,20 @@ headers: utils.getAuthHeaderObjectWithToken(b2), | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.listFileNames = function(b2, args) { | ||
var bucketId = args.bucketId; | ||
var startFileName = args.startFileName; | ||
var maxFileCount = args.maxFileCount; | ||
var prefix = args.prefix; | ||
var delimiter = args.delimiter; | ||
const bucketId = args.bucketId; | ||
const startFileName = args.startFileName; | ||
const maxFileCount = args.maxFileCount; | ||
const prefix = args.prefix; | ||
const delimiter = args.delimiter; | ||
var options = { | ||
url: getListFilesUrl(b2), | ||
const options = { | ||
url: endpoints(b2).listFilesUrl, | ||
method: 'POST', | ||
@@ -128,12 +165,18 @@ headers: utils.getAuthHeaderObjectWithToken(b2), | ||
}; | ||
return request.sendRequest(options, utils.getProcessFileSuccess(options)); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
), utils.getProcessFileSuccess(options)); | ||
}; | ||
exports.listFileVersions = function(b2, args) { | ||
var bucketId = args.bucketId; | ||
var startFileName = args.startFileName; | ||
var maxFileCount = args.maxFileCount; | ||
const bucketId = args.bucketId; | ||
const startFileName = args.startFileName; | ||
const maxFileCount = args.maxFileCount; | ||
var options = { | ||
url: getListFileVersionsUrl(b2), | ||
const options = { | ||
url: endpoints(b2).listFileVersionsUrl, | ||
method: 'POST', | ||
@@ -147,11 +190,17 @@ headers: utils.getAuthHeaderObjectWithToken(b2), | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.hideFile = function(b2, args) { | ||
var bucketId = args.bucketId; | ||
var fileName = args.fileName; | ||
const bucketId = args.bucketId; | ||
const fileName = args.fileName; | ||
var options = { | ||
url: getHideFileUrl(b2), | ||
const options = { | ||
url: endpoints(b2).hideFileUrl, | ||
method: 'POST', | ||
@@ -164,8 +213,20 @@ headers: utils.getAuthHeaderObjectWithToken(b2), | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.getFileInfo = function(b2, fileId) { | ||
var options = { | ||
url: getFileInfoUrl(b2), | ||
exports.getFileInfo = function(b2, argsOrFileId) { | ||
/* we're allowing an args object OR fileId for backwards compatibility */ | ||
let fileId = argsOrFileId; | ||
if (!_.isString(argsOrFileId)) { | ||
fileId = _.get(argsOrFileId, 'fileId'); | ||
} | ||
const options = { | ||
url: endpoints(b2).fileInfoUrl, | ||
method: 'POST', | ||
@@ -177,13 +238,19 @@ headers: utils.getAuthHeaderObjectWithToken(b2), | ||
}; | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(argsOrFileId, 'axios', {}), | ||
options, | ||
_.get(argsOrFileId, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.getDownloadAuthorization = function (b2, args) { | ||
var bucketId = args.bucketId; | ||
var fileNamePrefix = args.fileNamePrefix; | ||
var validDurationInSeconds = args.validDurationInSeconds; | ||
var b2ContentDisposition = args.b2ContentDisposition; | ||
const bucketId = args.bucketId; | ||
const fileNamePrefix = args.fileNamePrefix; | ||
const validDurationInSeconds = args.validDurationInSeconds; | ||
const b2ContentDisposition = args.b2ContentDisposition; | ||
var options = { | ||
url: getDownloadAuthorizationUrl(b2), | ||
const options = { | ||
url: endpoints(b2).downloadAuthorizationUrl, | ||
method: 'POST', | ||
@@ -199,11 +266,16 @@ headers: utils.getAuthHeaderObjectWithToken(b2), | ||
return request.sendRequest(options); | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
)); | ||
}; | ||
exports.downloadFileByName = function(b2, args) { | ||
var bucketName = args.bucketName; | ||
var fileName = utils.getUrlEncodedFileName(args.fileName); | ||
const bucketName = args.bucketName; | ||
const fileName = utils.getUrlEncodedFileName(args.fileName); | ||
var options = { | ||
url: getDownloadFileByNameUrl(b2, bucketName, fileName), | ||
const options = { | ||
url: endpoints(b2).downloadFileByNameUrl(bucketName, fileName), | ||
headers: utils.getAuthHeaderObjectWithToken(b2), | ||
@@ -216,9 +288,16 @@ responseType: args.responseType || null, | ||
var requestInstance = request.getInstance(); | ||
return requestInstance(options, utils.getProcessFileSuccess()); | ||
const requestInstance = request.getInstance(); | ||
// merge order matters here: later objects override earlier objects | ||
return requestInstance(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
), utils.getProcessFileSuccess()); | ||
}; | ||
exports.downloadFileById = function(b2, args) { | ||
var options = { | ||
url: getDownloadFileByIdUrl(b2, args.fileId), | ||
const options = { | ||
url: endpoints(b2).downloadFileByIdUrl(args.fileId), | ||
headers: utils.getAuthHeaderObjectWithToken(b2), | ||
@@ -231,12 +310,17 @@ responseType: args.responseType || null, | ||
var requestInstance = request.getInstance(); | ||
return requestInstance(options, utils.getProcessFileSuccess()); | ||
const requestInstance = request.getInstance(); | ||
// merge order matters here: later objects override earlier objects | ||
return requestInstance(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
), utils.getProcessFileSuccess()); | ||
}; | ||
exports.deleteFileVersion = function(b2, args) { | ||
var fileId = args.fileId; | ||
var fileName = args.fileName; | ||
const fileId = args.fileId; | ||
const fileName = args.fileName; | ||
var options = { | ||
url: getDeleteFileVersionUrl(b2), | ||
const options = { | ||
url: endpoints(b2).deleteFileVersionUrl, | ||
method: 'POST', | ||
@@ -250,55 +334,8 @@ headers: utils.getAuthHeaderObjectWithToken(b2), | ||
return request.sendRequest(options); | ||
}; | ||
function getListFilesUrl(b2) { | ||
return getApiUrl(b2) + '/b2_list_file_names'; | ||
} | ||
function getListFileVersionsUrl(b2) { | ||
return getApiUrl(b2) + '/b2_list_file_versions'; | ||
} | ||
function getHideFileUrl(b2) { | ||
return getApiUrl(b2) + '/b2_hide_file'; | ||
} | ||
function getFileInfoUrl(b2) { | ||
return getApiUrl(b2) + '/b2_get_file_info'; | ||
} | ||
function getDownloadAuthorizationUrl(b2) { | ||
return getApiUrl(b2) + '/b2_get_download_authorization'; | ||
} | ||
function getDownloadFileByNameUrl(b2, bucketName, fileName) { | ||
return b2.downloadUrl + '/file/' + bucketName + '/' + fileName; | ||
} | ||
function getDownloadFileByIdUrl(b2, fileId) { | ||
return b2.downloadUrl + conf.API_VERSION_URL + '/b2_download_file_by_id?fileId=' + fileId; | ||
} | ||
function getDeleteFileVersionUrl(b2) { | ||
return getApiUrl(b2) + '/b2_delete_file_version'; | ||
} | ||
function getApiUrl(b2) { | ||
return b2.apiUrl + conf.API_VERSION_URL; | ||
} | ||
function getStartLargeFileUrl(b2) { | ||
return getApiUrl(b2) + '/b2_start_large_file'; | ||
} | ||
function getGetUploadPartUrl(b2) { | ||
return getApiUrl(b2) + '/b2_get_upload_part_url'; | ||
} | ||
function getFinishLargeFileUrl(b2) { | ||
return getApiUrl(b2) + '/b2_finish_large_file'; | ||
} | ||
function getCancelLargeFileUrl(b2) { | ||
return getApiUrl(b2) + '/b2_cancel_large_file'; | ||
} | ||
// merge order matters here: later objects override earlier objects | ||
return request.sendRequest(_.merge({}, | ||
_.get(args, 'axios', {}), | ||
options, | ||
_.get(args, 'axiosOverride', {}) | ||
)); | ||
}; |
@@ -0,1 +1,4 @@ | ||
const axios = require('axios'); | ||
const axiosRetry = require('axios-retry'); | ||
const request = require('./request'); | ||
const actions = require('./actions'); | ||
@@ -9,2 +12,15 @@ | ||
this.downloadUrl = null; | ||
/* | ||
allows an optional axios config object that overrides the default axios config | ||
creates new axios instance so that axios-retry isn't injected into the user's code if they also use axios | ||
*/ | ||
const axiosClient = axios.create(Object.assign({ /* no defaults for now */ }, options.axios)); | ||
/* | ||
allows an optional retry config object that overrides the default retry behaviour | ||
please see https://github.com/softonic/axios-retry for additional options | ||
retries 3 times by default | ||
retries only on network errors and 5xx errors on indempotent requests (GET, HEAD, OPTIONS, PUT, or DELETE) by default | ||
*/ | ||
axiosRetry(axiosClient, Object.assign({ retries: 3 }, options.retry)); | ||
request.setup(axiosClient); | ||
} | ||
@@ -14,16 +30,16 @@ | ||
B2.prototype.authorize = function() { | ||
return actions.auth.authorize(this, this.accountId, this.applicationKey); | ||
B2.prototype.authorize = function(args) { | ||
return actions.auth.authorize(this, args); | ||
}; | ||
B2.prototype.createBucket = function(bucketName, bucketType) { | ||
return actions.bucket.create(this, bucketName, bucketType); | ||
B2.prototype.createBucket = function(argsOrBucketName, undefOrBucketType) { | ||
return actions.bucket.create(this, argsOrBucketName, undefOrBucketType); | ||
}; | ||
B2.prototype.deleteBucket = function(bucketId) { | ||
return actions.bucket.delete(this, bucketId); | ||
B2.prototype.deleteBucket = function(argsOrBucketId) { | ||
return actions.bucket.delete(this, argsOrBucketId); | ||
}; | ||
B2.prototype.listBuckets = function() { | ||
return actions.bucket.list(this); | ||
B2.prototype.listBuckets = function(args) { | ||
return actions.bucket.list(this, args); | ||
}; | ||
@@ -38,8 +54,8 @@ | ||
B2.prototype.updateBucket = function(bucketId, bucketType) { | ||
return actions.bucket.update(this, bucketId, bucketType); | ||
B2.prototype.updateBucket = function(argsOrBucketId, undefOrBucketType) { | ||
return actions.bucket.update(this, argsOrBucketId, undefOrBucketType); | ||
}; | ||
B2.prototype.getUploadUrl = function(bucketId) { | ||
return actions.bucket.getUploadUrl(this, bucketId); | ||
B2.prototype.getUploadUrl = function(argsOrBucketId) { | ||
return actions.bucket.getUploadUrl(this, argsOrBucketId); | ||
}; | ||
@@ -80,4 +96,6 @@ | ||
B2.prototype.getFileInfo = function(fileId) { | ||
return actions.file.getFileInfo(this, fileId); | ||
// args: | ||
// - fileId | ||
B2.prototype.getFileInfo = function(argsOrFileId) { | ||
return actions.file.getFileInfo(this, argsOrFileId); | ||
}; | ||
@@ -101,4 +119,4 @@ | ||
B2.prototype.downloadFileById = function(fileId) { | ||
return actions.file.downloadFileById(this, fileId); | ||
B2.prototype.downloadFileById = function(args) { | ||
return actions.file.downloadFileById(this, args); | ||
}; | ||
@@ -105,0 +123,0 @@ |
@@ -26,3 +26,3 @@ const conf = require('../conf'); | ||
if (isValidHeader(infoKey)) { | ||
var key = 'X-Bz-Info-' + infoKey; | ||
const key = 'X-Bz-Info-' + infoKey; | ||
options.headers[key] = encodeURIComponent(info[infoKey]); | ||
@@ -36,3 +36,3 @@ } else { | ||
exports.addBzHeaders = function(headers, targetObj) { | ||
var keys = Object.keys(headers); | ||
const keys = Object.keys(headers); | ||
@@ -48,3 +48,3 @@ return keys.filter(isBzHeader) | ||
function getKeyObj(header) { | ||
var replacement = /^X-Bz-Info-/i.test(header) ? /X-Bz-Info-/i : /X-Bz-/i; | ||
const replacement = /^X-Bz-Info-/i.test(header) ? /X-Bz-Info-/i : /X-Bz-/i; | ||
return { | ||
@@ -51,0 +51,0 @@ original: header, |
@@ -1,3 +0,3 @@ | ||
var utils = require('./utils.js'); | ||
var REQUEST; | ||
const utils = require('./utils.js'); | ||
let REQUEST; | ||
@@ -9,3 +9,3 @@ exports.setup = function(requestObject) { | ||
exports.sendRequest = function(options) { | ||
var requestInstance = exports.getInstance(); | ||
const requestInstance = exports.getInstance(); | ||
return requestInstance(options, utils.processResponseGeneric()); | ||
@@ -12,0 +12,0 @@ }; |
{ | ||
"name": "backblaze-b2", | ||
"version": "1.2.0", | ||
"version": "1.3.1", | ||
"description": "Node.js Library for the Backblaze B2 Storage Service", | ||
@@ -37,7 +37,9 @@ "main": "index.js", | ||
"dependencies": { | ||
"axios": "^0.18.0" | ||
"axios": "^0.18.0", | ||
"axios-retry": "^3.1.2", | ||
"lodash": "^4.17.11" | ||
}, | ||
"engines": { | ||
"node": ">=10.0" | ||
"node": ">=10.0" | ||
} | ||
} |
217
README.md
@@ -1,5 +0,14 @@ | ||
### Backblaze B2 Node.js Library | ||
# Backblaze B2 Node.js Library | ||
[![npm version](https://badge.fury.io/js/backblaze-b2.svg)](https://badge.fury.io/js/backblaze-b2) [![Build Status](https://travis-ci.org/yakovkhalinsky/backblaze-b2.svg?branch=master)](https://travis-ci.org/yakovkhalinsky/backblaze-b2) | ||
A customizable B2 client for Node.js: | ||
* Uses [axios](https://github.com/axios/axios). You can control the axios instance at the request level (see `axios` and `axiosOverride` config arguments) and at the global level (see `axios` config argument at instantiation) so you can use any axios feature. | ||
* Automatically retries on request failure. You can control retry behaviour using the `retries` argument at instantiation. | ||
## Usage | ||
This library uses promises, so all actions on a `B2` instance return a promise in the following pattern: | ||
``` javascript | ||
@@ -12,27 +21,2 @@ b2.instanceFunction(arg1, arg2).then( | ||
### Status of project | ||
See the [CHANGELOG](https://github.com/yakovkhalinsky/backblaze-b2/blob/master/CHANGELOG.md) for a history of updates. | ||
### Contributing | ||
Contributions, suggestions, and questions are welcome. Please review the [contributing guidelines](CONTRIBUTING.md) for details. | ||
### Upgrading from 0.9.x to 1.0.x | ||
For this update, we've switched the back end HTTP request library from `request` to `axios` as it has better Promise and progress support built in. However, there are a couple changes that will break your code and ruin your day. Here are the changes: | ||
* The Promise resolution has a different data structure. Where previously, the request response data was the root object in the promise resolution (`res`), this data now resides in `res.data`. | ||
* In v0.9.12, we added request progress reporting via the third parameter to `then()`. Because we are no longer using the same promise library, this functionality has been removed. However, progress reporting is still available by passing a callback function into the `b2.method()` that you're calling. See the documentation below for details. | ||
* In v0.9.x, `b2.downloadFileById()` accepted a `fileId` parameter as a String or Number. As of 1.0.0, the first parameter is now expected to be a plain Object of arguments. | ||
### Response Object | ||
Each request returns an object with: | ||
- `status` - int, html error Status | ||
- `statusText` | ||
- `headers` | ||
- `config` | ||
- `request` | ||
- `data` - actual returned data from backblaze, https://www.backblaze.com/b2/docs/calling.html | ||
### Basic Example | ||
@@ -51,3 +35,3 @@ | ||
await b2.authorize(); // must authorize first | ||
let response = await b2.getBucket({bucketName: 'my-bucket'}); | ||
let response = await b2.getBucket({ bucketName: 'my-bucket' }); | ||
console.log(response.data); | ||
@@ -60,38 +44,23 @@ } catch (err) { | ||
### Uploading Large Files | ||
### Response Object | ||
To upload large files, you need to split the file into parts (between 5MB and 5GB) and upload each part seperately. | ||
Each request returns an object with: | ||
First, you initiate the large file upload to get the fileId: | ||
```javascript | ||
let response = await b2.startLargeFile({bucketId, fileName}); | ||
let fileId = response.data.fileId; | ||
``` | ||
* `status` - int, html error Status | ||
* `statusText` | ||
* `headers` | ||
* `config` | ||
* `request` | ||
* `data` - actual returned data from backblaze, https://www.backblaze.com/b2/docs/calling.html | ||
Then for each part you request an `uploadUrl`, and use the response to upload the part: | ||
```javascript | ||
let response = await b2.getUploadPartUrl({fileId}); | ||
### How it works | ||
let uploadURL = response.data.uploadUrl; | ||
let authToken = response.data.authorizationToken; | ||
Each action (see reference below) takes arguments and constructs an axios request. You can add additional axios options at the request level using: | ||
response = await b2.uploadPart({ | ||
partNumber: parNum, | ||
uploadUrl: uploadURL, | ||
uploadAuthToken: authToken, | ||
data: buf | ||
}); | ||
// status checks etc. | ||
``` | ||
* The `axios` argument (object): each property in this object is added to the axios request object *only if it does not conflict* with an existing property. | ||
* The `axiosOverride` argument (object): each property in this object is added to the axios request object by *overriding* conflicting properties, if any. Don't use this unless you know what you're doing! | ||
* Both `axios` and `axiosOverride` work by recursively merging properties, so if you pass ```axios: { headers: { 'your-custom-header': 'header-value' } }```, the entire headers object will not be overridden - each header property (`your-custom-header`) will be compared. | ||
Then finish the uploadUrl: | ||
```javascript | ||
let response = await b2.finishLargeFile({ | ||
fileId, | ||
partSha1Array: parts.map(buf => sha1(buf)) | ||
}) | ||
``` | ||
### Reference | ||
### Usage | ||
```javascript | ||
@@ -106,31 +75,66 @@ const B2 = require('backblaze-b2'); | ||
accountId: 'applicationKeyId', // or accountId | ||
applicationKey: 'applicationKey' // or masterApplicationKey | ||
applicationKey: 'applicationKey', // or masterApplicationKey | ||
// optional: | ||
axios: { | ||
// overrides the axios instance default config, see https://github.com/axios/axios | ||
}, | ||
retry: { | ||
retries: 3 // this is the default | ||
// for additional options, see https://github.com/softonic/axios-retry | ||
} | ||
}); | ||
// common arguments - you can use these in any of the functions below | ||
const common_args = { | ||
// axios request level config, see https://github.com/axios/axios#request-config | ||
axios: { | ||
timeout: 30000 // (example) | ||
}, | ||
axiosOverride: { | ||
/* Don't use me unless you know what you're doing! */ | ||
} | ||
} | ||
// authorize with provided credentials | ||
b2.authorize(); // returns promise | ||
b2.authorize({ | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
// create bucket | ||
b2.createBucket( | ||
bucketName, | ||
bucketType // one of `allPublic`, `allPrivate` | ||
); // returns promise | ||
b2.createBucket({ | ||
bucketName: 'bucketName', | ||
bucketType: 'bucketType' // one of `allPublic`, `allPrivate` | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
// delete bucket | ||
b2.deleteBucket(bucketId); // returns promise | ||
b2.deleteBucket({ | ||
bucketId: 'bucketId' | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
// list buckets | ||
b2.listBuckets(); // returns promise | ||
b2.listBuckets({ | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
// get the bucket | ||
b2.getBucket({ | ||
bucketName, | ||
bucketId // optional | ||
bucketName: 'bucketName', | ||
bucketId: 'bucketId' // optional | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
// update bucket | ||
b2.updateBucket(bucketId, bucketType); // returns promise | ||
b2.updateBucket({ | ||
bucketId: 'bucketId', | ||
bucketType: 'bucketType' | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
// get upload url | ||
b2.getUploadUrl(bucketId); // returns promise | ||
b2.getUploadUrl({ | ||
bucketId: 'bucketId' | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -152,2 +156,3 @@ // upload file | ||
onUploadProgress: (event) => {} || null // progress monitoring | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -162,2 +167,3 @@ | ||
prefix: '' | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -170,2 +176,3 @@ | ||
maxFileCount: 100 | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -177,6 +184,10 @@ | ||
fileName: 'fileName' | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
// get file info | ||
b2.getFileInfo(fileId); // returns promise | ||
b2.getFileInfo({ | ||
fileId: 'fileId' | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -189,2 +200,3 @@ // get download authorization | ||
b2ContentDisposition: 'b2ContentDisposition' | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -198,2 +210,3 @@ | ||
onDownloadProgress: (event) => {} || null // progress monitoring | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -206,2 +219,3 @@ | ||
onDownloadProgress: (event) => {} || null // progress monitoring | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -213,2 +227,3 @@ | ||
fileName: 'fileName' | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -220,2 +235,3 @@ | ||
fileName: 'fileName' | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -226,2 +242,3 @@ | ||
fileId: 'fileId' | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -237,2 +254,3 @@ | ||
onUploadProgress: (event) => {} || null // progress monitoring | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -244,2 +262,3 @@ | ||
partSha1Array: [partSha1Array] // array of sha1 for each part | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
@@ -250,9 +269,67 @@ | ||
fileId: 'fileId' | ||
// ...common arguments (optional) | ||
}); // returns promise | ||
``` | ||
### Authors | ||
### Uploading Large Files Example | ||
To upload large files, you should split the file into parts (between 5MB and 5GB) and upload each part seperately. | ||
First, you initiate the large file upload to get the fileId: | ||
```javascript | ||
let response = await b2.startLargeFile({ bucketId, fileName }); | ||
let fileId = response.data.fileId; | ||
``` | ||
Then for each part you request an `uploadUrl`, and use the response to upload the part: | ||
```javascript | ||
let response = await b2.getUploadPartUrl({ fileId }); | ||
let uploadURL = response.data.uploadUrl; | ||
let authToken = response.data.authorizationToken; | ||
response = await b2.uploadPart({ | ||
partNumber: parNum, | ||
uploadUrl: uploadURL, | ||
uploadAuthToken: authToken, | ||
data: buf | ||
}); | ||
// status checks etc. | ||
``` | ||
Then finish the uploadUrl: | ||
```javascript | ||
let response = await b2.finishLargeFile({ | ||
fileId, | ||
partSha1Array: parts.map(buf => sha1(buf)) | ||
}) | ||
``` | ||
## Changes | ||
See the [CHANGELOG](https://github.com/yakovkhalinsky/backblaze-b2/blob/master/CHANGELOG.md) for a history of updates. | ||
### Upgrading from 0.9.x to 1.0.x | ||
For this update, we've switched the back end HTTP request library from `request` to `axios` as it has better Promise and progress support built in. However, there are a couple changes that will break your code and ruin your day. Here are the changes: | ||
* The Promise resolution has a different data structure. Where previously, the request response data was the root object in the promise resolution (`res`), this data now resides in `res.data`. | ||
* In v0.9.12, we added request progress reporting via the third parameter to `then()`. Because we are no longer using the same promise library, this functionality has been removed. However, progress reporting is still available by passing a callback function into the `b2.method()` that you're calling. See the documentation below for details. | ||
* In v0.9.x, `b2.downloadFileById()` accepted a `fileId` parameter as a String or Number. As of 1.0.0, the first parameter is now expected to be a plain Object of arguments. | ||
## Contributing | ||
Contributions, suggestions, and questions are welcome. Please review the [contributing guidelines](CONTRIBUTING.md) for details. | ||
### Authors and Contributors | ||
* Yakov Khalinsky (@yakovkhalinsky) | ||
* Ivan Kalinin (@IvanKalinin) at Isolary | ||
* Brandon Patton (@crazyscience) at Isolary | ||
* C. Bess (@cbess) | ||
* Amit (@Amit-A) | ||
* Zsombor Paróczi (@realhidden) | ||
* Oden (@odensc) |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
125729
27
2007
319
3
1
+ Addedaxios-retry@^3.1.2
+ Addedlodash@^4.17.11
+ Added@babel/runtime@7.24.5(transitive)
+ Addedaxios-retry@3.9.1(transitive)
+ Addedis-retry-allowed@2.2.0(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedregenerator-runtime@0.14.1(transitive)