Skip to content

Commit

Permalink
Merge pull request #60 from yakovkhalinsky/update-b2api
Browse files Browse the repository at this point in the history
Update to expose get bucket API call
  • Loading branch information
cbess authored Jan 30, 2019
2 parents 99d9a86 + 95bb1d6 commit d387b0c
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 30 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
### v1.2.0 (January 30, 2017) - The getBucket release

Features

- Adds `B2.getBucket(...)` to help get bucket IDs with restricted bucket keys. In B2 v2, `B2.listBuckets()` will respond with an error, if you authorize without the `master key`.

### v1.1.0 (January 27, 2017) - The B2 v2 release

Features
Expand Down
42 changes: 24 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,17 @@ Each request returns an object with:
const B2 = require('backblaze-b2');

const b2 = new B2({
accountId: '<accountId>',
applicationKey: 'applicationKey'
accountId: 'applicationKeyId', // or accountId
applicationKey: 'applicationKey' // or masterApplicationKey
});

async function GetBuckets() {
async function GetBucket() {
try {
await b2.authorize();
let response = await b2.listBuckets();
await b2.authorize(); // must authorize first
let response = await b2.getBucket({bucketName: 'my-bucket'});
console.log(response.data);
} catch (err) {
console.log('Error getting buckets:', err);
console.log('Error getting bucket:', err);
}
}
```
Expand All @@ -61,18 +61,18 @@ To upload large files, you need to split the file into parts (between 5MB and 5G

First, you initiate the large file upload to get the fileId:
```javascript
let response = await this.b2.startLargeFile({bucketId, fileName});
let fileID = response.data.fileId;
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:
Then for each part you request an `uploadUrl`, and use the response to upload the part:
```javascript
let response = await this.b2.getUploadPartUrl({fileId: this.fileID});
let response = await b2.getUploadPartUrl({fileId});

let uploadURL = response.data.uploadUrl;
let authToken = response.data.authorizationToken;

response = await this.b2.uploadPart({
response = await b2.uploadPart({
partNumber: parNum,
uploadUrl: uploadURL,
uploadAuthToken: authToken,
Expand All @@ -83,8 +83,8 @@ response = await this.b2.uploadPart({

Then finish the uploadUrl:
```javascript
let response = await this.b2.finishLargeFile({
fileId: this.fileID,
let response = await b2.finishLargeFile({
fileId,
partSha1Array: parts.map(buf => sha1(buf))
})
```
Expand All @@ -95,12 +95,12 @@ let response = await this.b2.finishLargeFile({
const B2 = require('backblaze-b2');

// All functions on the b2 instance return the response from the B2 API in the success callback
// i.e. b2.foo(...).then(function(b2JsonResponse) {})
// i.e. b2.foo(...).then((b2JsonResponse) => {})

// create b2 object instance
// create B2 object instance
const b2 = new B2({
accountId: 'accountId',
applicationKey: 'applicationKey'
accountId: 'applicationKeyId', // or accountId
applicationKey: 'applicationKey' // or masterApplicationKey
});

// authorize with provided credentials
Expand All @@ -118,7 +118,13 @@ b2.deleteBucket(bucketId); // returns promise
// list buckets
b2.listBuckets(); // returns promise

// update bucket2
// get the bucket
b2.getBucket({
bucketName,
bucketId // optional
}); // returns promise

// update bucket
b2.updateBucket(bucketId, bucketType); // returns promise

// get upload url
Expand Down
22 changes: 22 additions & 0 deletions lib/actions/bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,28 @@ exports.list = function(b2) {
return request.sendRequest(options);
};

// https://www.backblaze.com/b2/docs/b2_list_buckets.html
exports.get = function(b2, args) {
const data = {
accountId: b2.accountId,
};

// only one of these can/should be used at a time
if (args.bucketName) {
data.bucketName = args.bucketName;
} else if (args.bucketId) {
data.bucketId = args.bucketId;
}

const options = {
url: getListUrl(b2),
method: 'POST',
data,
headers: utils.getAuthHeaderObjectWithToken(b2)
};
return request.sendRequest(options);
};

exports.update = function(b2, bucketId, bucketType) {
var options = {
url: getUpdateUrl(b2),
Expand Down
7 changes: 7 additions & 0 deletions lib/b2.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ B2.prototype.listBuckets = function() {
return actions.bucket.list(this);
};

// args:
// - bucketName
// - bucketId
B2.prototype.getBucket = function(args) {
return actions.bucket.get(this, args);
};

B2.prototype.updateBucket = function(bucketId, bucketType) {
return actions.bucket.update(this, bucketId, bucketType);
};
Expand Down
1 change: 1 addition & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ exports.saveAuthContext = function (context, authResponse) {
context.authorizationToken = authResponse.authorizationToken;
context.apiUrl = authResponse.apiUrl;
context.downloadUrl = authResponse.downloadUrl;
context.accountId = authResponse.accountId;
};

exports.getProcessFileSuccess = function(deferred) {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "backblaze-b2",
"version": "1.1.0",
"version": "1.2.0",
"description": "Node.js Library for the Backblaze B2 Storage Service",
"main": "index.js",
"scripts": {
Expand Down Expand Up @@ -29,7 +29,7 @@
},
"license": "MIT",
"devDependencies": {
"eslint": "^5.12.0",
"eslint": "^5.12.1",
"expect.js": "^0.3.1",
"mocha": "^5.2.0"
},
Expand Down
95 changes: 85 additions & 10 deletions test/unit/lib/actions/bucketTest.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/* global describe, beforeEach, it */

var expect = require('expect.js');
const expect = require('expect.js');

var request = require('../../../../lib/request');
const request = require('../../../../lib/request');
const utils = require('../../../../lib/utils');
var bucket = require('../../../../lib/actions/bucket');
const bucket = require('../../../../lib/actions/bucket');

describe('actions/bucket', function() {
var requestOptions;
var bogusRequestModule;
var response;
var actualResponse;
var errorMessage;
var b2;
let requestOptions;
let bogusRequestModule;
let response;
let actualResponse;
let errorMessage;
let b2;

beforeEach(function() {
errorMessage = undefined;
Expand All @@ -25,7 +25,7 @@ describe('actions/bucket', function() {
};

bogusRequestModule = function(options, cb) {
var deferred = new utils.Deferred();
let deferred = new utils.Deferred();
requestOptions = options;
cb(errorMessage, false, JSON.stringify(response), deferred);

Expand Down Expand Up @@ -185,6 +185,81 @@ describe('actions/bucket', function() {

});

describe('get', function() {

describe('with good response', function() {

beforeEach(function(done) {
response = {
buckets:[
{
accountId: '98765',
bucketId: '1234abcd',
bucketName: 'bucket-foo',
bucketType: 'allPrivate',
bucketInfo: {},
corsRules: [],
lifecycleRules: [],
revision: 1
}
]
};

bucket.get(b2, {bucketName: 'bucket-foo'}).then((response) => {
actualResponse = response;
done();
});
});

it('should set correct options and resolve with good response', function() {
expect(actualResponse).to.eql(response);
expect(requestOptions).to.eql({
method: 'POST',
url: 'https://foo/b2api/v2/b2_list_buckets',
data: {
accountId: '98765',
bucketName: 'bucket-foo'
},
headers: { Authorization: 'unicorns and rainbows' }
});
});
});

describe('with response containing no buckets', function() {

beforeEach(function(done) {
errorMessage = 'unauthorized';

bucket.get(b2, {bucketName: 'not-a-real-bucket'}).then(null, function(error) {
actualResponse = error;
done();
});
});

it('Should respond with an error and reject promise', function() {
// status code is 401
expect(actualResponse).to.be(errorMessage);
});
});

describe('with error response', function() {

beforeEach(function(done) {
errorMessage = 'Something went wrong';

bucket.get(b2, {}).then(null, function(error) {
actualResponse = error;
done();
});
});

it('Should respond with an error and reject promise', function() {
expect(actualResponse).to.be(errorMessage);
});
});

});

describe('update', function() {

describe('with good response', function() {
Expand Down

0 comments on commit d387b0c

Please sign in to comment.