bitbucket-v2
Advanced tools
Comparing version 0.4.4 to 0.5.0
@@ -1,6 +0,6 @@ | ||
const Constants = require('./constants'); | ||
const Repositories = require('./repositories'); | ||
const Request = require('./request'); | ||
const Teams = require('./teams'); | ||
const User = require('./user'); | ||
const constants = require('./constants'); | ||
const buildRepositories = require('./repositories'); | ||
const buildRequest = require('./request'); | ||
const buildUser = require('./user'); | ||
const buildWorkspaces = require('./workspaces'); | ||
@@ -28,9 +28,9 @@ | ||
$proxy_port, | ||
constants: Constants | ||
constants | ||
}; | ||
apiModel.repositories = Repositories(apiModel); | ||
apiModel.request = Request({ proxy_host: $proxy_host, proxy_port: $proxy_port, use_xhr: useXhr }); | ||
apiModel.teams = Teams(apiModel); | ||
apiModel.user = User(apiModel); | ||
apiModel.repositories = buildRepositories(apiModel); | ||
apiModel.request = buildRequest({ proxy_host: $proxy_host, proxy_port: $proxy_port, use_xhr: useXhr }); | ||
apiModel.user = buildUser(apiModel); | ||
apiModel.workspaces = buildWorkspaces(apiModel); | ||
@@ -71,4 +71,4 @@ /** | ||
*/ | ||
apiModel.get = (route, parameters, requestOptions, callback) => | ||
apiModel.request.get(route, parameters || {}, requestOptions, callback); | ||
apiModel.get = (route, parameters, requestOptions) => | ||
apiModel.request.get(route, parameters || {}, requestOptions); | ||
@@ -83,4 +83,4 @@ /** | ||
*/ | ||
apiModel.delete = (route, parameters, requestOptions, callback) => | ||
apiModel.request.send(route, parameters, 'DELETE', requestOptions, callback); | ||
apiModel.delete = (route, parameters, requestOptions) => | ||
apiModel.request.delete(route, parameters, requestOptions); | ||
@@ -95,8 +95,8 @@ /** | ||
*/ | ||
apiModel.post = (route, parameters, requestOptions, callback) => | ||
apiModel.request.post(route, parameters || {}, requestOptions, callback); | ||
apiModel.post = (route, parameters, requestOptions) => | ||
apiModel.request.post(route, parameters || {}, requestOptions); | ||
/** | ||
* Check for whether we can iterate to another page using this.getNextPage(response). | ||
* @param {response} A response that was received from the API. | ||
* @param {response} response A response that was received from the API. | ||
* @return {boolean} true if the response indicates more pages are available, false otherwise. | ||
@@ -108,3 +108,3 @@ */ | ||
* Check for whether we can iterate to another page using this.getPreviousPage(response). | ||
* @param {response} A response that was received from the API. | ||
* @param {response} response A response that was received from the API. | ||
* @return {boolean} true if the response indicates a previous pages is available, false otherwise. | ||
@@ -115,10 +115,8 @@ */ | ||
/** | ||
* Takes a response and a callback and makes an API request for the response's next page. When the next page | ||
* comes back, the param callback is run on the next-page response. | ||
* NOTE this should only be called guarded behind a check to this.hasNextPage(response) ! | ||
* Takes a response and makes an API request for the response's next page. | ||
* NOTE this should only be called guarded behind a check to `this.hasNextPage(response)`! | ||
* | ||
* @param {response} A response that was received from the API. | ||
* @param {callback} The callback to run when the response comes back. | ||
* @param {response} response A response that was received from the API. | ||
*/ | ||
apiModel.getNextPage = (response, callback) => { | ||
apiModel.getNextPage = (response) => { | ||
if (!apiModel.hasNextPage(response)) { | ||
@@ -130,14 +128,12 @@ throw new Error( | ||
apiModel.request.doPrebuiltSend(response.next, callback); | ||
return apiModel.request.doPrebuiltSend(response.next); | ||
}; | ||
/** | ||
* Takes a response and a callback and makes an API request for the response's previous page. When the previous page | ||
* comes back, the param callback is run on the previous-page response. | ||
* NOTE this should only be called guarded behind a check to this.hasPreviousPage(response) ! | ||
* Takes a response and makes an API request for the response's previous page. | ||
* NOTE this should only be called guarded behind a check to `this.hasPreviousPage(response)`! | ||
* | ||
* @param {response} A response that was received from the API. | ||
* @param {callback} The callback to run when the response comes back. | ||
* @param {response} response A response that was received from the API. | ||
*/ | ||
apiModel.getPreviousPage = (response, callback) => { | ||
apiModel.getPreviousPage = (response) => { | ||
if (!apiModel.hasPreviousPage(response)) { | ||
@@ -149,3 +145,3 @@ throw new Error( | ||
apiModel.request.doPrebuiltSend(response.previous, callback); | ||
return apiModel.request.doPrebuiltSend(response.previous); | ||
}; | ||
@@ -152,0 +148,0 @@ |
const _ = require('lodash'); | ||
const AbstractApi = require('./abstract_api'); | ||
const constants = require('./constants'); | ||
@@ -11,9 +10,6 @@ | ||
module.exports = function RepositoriesApi(api) { | ||
const result = AbstractApi(api); | ||
return _.assign(result, { | ||
return { | ||
/** | ||
* Create a new repository | ||
* @param {String} repo owner | ||
* @param {String} name of the repo. This is not a slug (may include special characters) | ||
* @param {String} workspace workspace UUID or slug | ||
* @param {Object} repo repo metadata as specified by Bitbucket's API documentation. | ||
@@ -23,3 +19,3 @@ * NOTE Unlike the normal API, Including an explicit name property in repo is REQUIRED!! | ||
*/ | ||
create(username, repo, callback) { | ||
create: (workspace, repo) => { | ||
if (!repo || !_.isBoolean(repo.is_private) || !_.isString(repo.name)) { | ||
@@ -47,6 +43,5 @@ throw new Error('Repo must be initialized with a booelan privacy setting and a string name'); | ||
api.post( | ||
`repositories/${encodeURI(username)}/${encodeURI(repoSlug)}`, | ||
repo, null, | ||
result.$createListener(callback) | ||
return api.post( | ||
`repositories/${encodeURI(workspace)}/${encodeURI(repoSlug)}`, | ||
repo | ||
); | ||
@@ -58,13 +53,10 @@ }, | ||
* | ||
* @param {String} repo owner | ||
* @param {String} slug (name) of the repo. | ||
* @param {String} workspace workspace UUID or slug | ||
* @param {String} repoSlug (name) of the repo. | ||
* @param {Object} pullRequest The PR POST body as specified by Bitbucket's API documentation | ||
*/ | ||
createPullRequest(username, repoSlug, pullRequest, callback) { | ||
api.post( | ||
`repositories/${encodeURI(username)}/${encodeURI(repoSlug)}/pullrequests`, | ||
pullRequest, null, | ||
result.$createListener(callback) | ||
); | ||
}, | ||
createPullRequest: (workspace, repoSlug, pullRequest) => api.post( | ||
`repositories/${encodeURI(workspace)}/${encodeURI(repoSlug)}/pullrequests`, | ||
pullRequest | ||
), | ||
@@ -74,12 +66,6 @@ /** | ||
* | ||
* @param {String} repo owner | ||
* @param {String} workspace workspace UUID or slug | ||
* @param {String} slug (name) of the repo. | ||
*/ | ||
get(username, repoSlug, callback) { | ||
api.get( | ||
`repositories/${encodeURI(username)}/${encodeURI(repoSlug)}`, | ||
null, null, | ||
result.$createListener(callback) | ||
); | ||
}, | ||
get: (workspace, repoSlug) => api.get(`repositories/${encodeURI(workspace)}/${encodeURI(repoSlug)}`), | ||
@@ -89,26 +75,16 @@ /** | ||
* | ||
* @param {String} repo owner | ||
* @param {String} workspace workspace UUID or slug | ||
* @param {String} slug (name) of the repo. | ||
*/ | ||
getBranches(username, repoSlug, callback) { | ||
api.get( | ||
`repositories/${encodeURI(username)}/${encodeURI(repoSlug)}/refs/branches`, | ||
null, null, | ||
result.$createListener(callback) | ||
); | ||
}, | ||
getBranches: (workspace, repoSlug) => | ||
api.get(`repositories/${encodeURI(workspace)}/${encodeURI(repoSlug)}/refs/branches`), | ||
/** | ||
* Get a single commit | ||
* @param {String} repo owner | ||
* @param {String} workspace workspace UUID or slug | ||
* @param {String} slug (name) of the repo. | ||
* @param {String} the sha of the commit | ||
*/ | ||
getCommit(username, repoSlug, sha, callback) { | ||
api.get( | ||
`repositories/${encodeURI(username)}/${encodeURI(repoSlug)}/commit/${sha}`, | ||
null, null, | ||
result.$createListener(callback) | ||
); | ||
}, | ||
getCommit: (workspace, repoSlug, sha) => | ||
api.get(`repositories/${encodeURI(workspace)}/${encodeURI(repoSlug)}/commit/${sha}`), | ||
@@ -118,7 +94,7 @@ /** | ||
* | ||
* @param {String} repo owner | ||
* @param {String} workspace workspace UUID or slug | ||
* @param {String} slug (name) of the repo. | ||
* @param {constants.pullRequest.states or Array thereof} The PR state. If invalid or undefined, defaults to OPEN | ||
*/ | ||
getPullRequests(username, repoSlug, state, callback) { | ||
getPullRequests: (workspace, repoSlug, state) => { | ||
let stateArray = state; | ||
@@ -141,6 +117,5 @@ if (!stateArray) { | ||
api.get( | ||
`repositories/${encodeURI(username)}/${encodeURI(repoSlug)}/pullrequests`, | ||
apiParameters, null, | ||
result.$createListener(callback) | ||
return api.get( | ||
`repositories/${encodeURI(workspace)}/${encodeURI(repoSlug)}/pullrequests`, | ||
apiParameters | ||
); | ||
@@ -153,7 +128,7 @@ }, | ||
* | ||
* @param {String} repo owner | ||
* @param {String} slug (name) of the repo. | ||
* @param {String} workspace workspace UUID or slug | ||
* @param {String} repoSlug (name) of the repo. | ||
* @param {Object} options The fields to populate, and optionally the PR state (defaults to OPEN) | ||
*/ | ||
getPullRequestsWithFields(username, repoSlug, { state, fields } = {}, callback) { | ||
getPullRequestsWithFields: (workspace, repoSlug, { state, fields } = {}) => { | ||
if (!_.isArray(fields) || fields.length < 1) { | ||
@@ -183,6 +158,5 @@ throw new Error('getPullRequestsWithFields: options argument missing or has missing/empty \'fields\' array.'); | ||
api.get( | ||
`repositories/${encodeURI(username)}/${encodeURI(repoSlug)}/pullrequests`, // eslint-disable-line max-len | ||
apiParameters, null, | ||
result.$createListener(callback) | ||
return api.get( | ||
`repositories/${encodeURI(workspace)}/${encodeURI(repoSlug)}/pullrequests`, // eslint-disable-line max-len | ||
apiParameters | ||
); | ||
@@ -192,40 +166,15 @@ }, | ||
/** | ||
* Get the repositories of a user | ||
* Get the repositories of a workspace | ||
* | ||
* @param {String} username | ||
* @param {String} workspace workspace UUID or slug | ||
*/ | ||
getByUser(username, callback) { | ||
api.get( | ||
`repositories/${encodeURI(username)}`, | ||
null, null, | ||
result.$createListener(callback) | ||
); | ||
}, | ||
getByWorkspace: (workspace) => api.get(`repositories/${encodeURI(workspace)}`), | ||
/** | ||
* Get the repositories of a team | ||
* | ||
* @param {String} teamname | ||
*/ | ||
getByTeam(teamname, callback) { | ||
api.get( | ||
`repositories/${encodeURI(teamname)}`, | ||
null, null, | ||
result.$createListener(callback) | ||
); | ||
}, | ||
/** | ||
* Get the forks for a repo | ||
* | ||
* @param {String} repo owner | ||
* @param {String} slug (name) of the repo. | ||
* @param {String} workspace workspace UUID or slug | ||
* @param {String} repoSlug (name) of the repo. | ||
*/ | ||
getForks(username, repoSlug, callback) { | ||
api.get( | ||
`repositories/${encodeURI(username)}/${encodeURI(repoSlug)}/forks`, | ||
null, null, | ||
result.$createListener(callback) | ||
); | ||
}, | ||
getForks: (workspace, repoSlug) => api.get(`repositories/${encodeURI(workspace)}/${encodeURI(repoSlug)}/forks`), | ||
@@ -237,3 +186,3 @@ /** | ||
*/ | ||
getForksFromResponse(response, callback) { | ||
getForksFromResponse: (response) => { | ||
const prebuiltURL = response && response.links && response.links.forks && response.links.forks.href; | ||
@@ -245,6 +194,3 @@ | ||
api.request.doPrebuiltSend( | ||
prebuiltURL, | ||
result.$createListener(callback) | ||
); | ||
return api.request.doPrebuiltSend(prebuiltURL); | ||
}, | ||
@@ -258,3 +204,3 @@ | ||
*/ | ||
getParentFromResponse(response, callback) { | ||
getParentFromResponse: (response) => { | ||
const prebuiltURL = _.get(response, 'parent.links.self.href'); | ||
@@ -268,6 +214,3 @@ | ||
api.request.doPrebuiltSend( | ||
prebuiltURL, | ||
result.$createListener(callback) | ||
); | ||
return api.request.doPrebuiltSend(prebuiltURL); | ||
}, | ||
@@ -281,6 +224,4 @@ | ||
*/ | ||
hasParent(response) { | ||
return !!response.parent; | ||
} | ||
}); | ||
hasParent: (response) => Boolean(response.parent) | ||
}; | ||
}; |
@@ -16,3 +16,3 @@ const _ = require('lodash'); | ||
format: 'json', | ||
user_agent: 'js-bitbucket-api-v2 (http://github.com/Mr-Wallet/node-bitbucket-v2)', | ||
user_agent: 'node-bitbucket-v2 (https://www.npmjs.com/package/bitbucket-v2)', | ||
http_port: 443, | ||
@@ -64,6 +64,6 @@ timeout: 20, | ||
* Send a GET request | ||
* @see send | ||
* @see doSend | ||
*/ | ||
get(apiPath, parameters, options, callback) { | ||
return result.send(apiPath, parameters, 'GET', options, callback); | ||
get(apiPath, parameters, options) { | ||
return result.doSend(apiPath, parameters, 'GET', options); | ||
}, | ||
@@ -73,35 +73,16 @@ | ||
* Send a POST request | ||
* @see send | ||
* @see doSend | ||
*/ | ||
post(apiPath, parameters, options, callback) { | ||
return result.send(apiPath, parameters, 'POST', options, callback); | ||
post(apiPath, parameters, options) { | ||
return result.doSend(apiPath, parameters, 'POST', options); | ||
}, | ||
/** | ||
* Send a request to the server, receive a response, | ||
* decode the response and returns an associative array | ||
* | ||
* @param {String} apiPath Request API path | ||
* @param {Object} parameters Parameters | ||
* @param {String} httpMethod HTTP method to use | ||
* @param {Object} options reconfigure the request for this call only | ||
* Send a DELETE request | ||
* @see doSend | ||
*/ | ||
send(apiPath, parameters, httpMethod = 'GET', __options, callback) { | ||
const options = __options || $options; | ||
result.doSend(apiPath, parameters, httpMethod, options, (err, _response) => { | ||
if (err) { | ||
if (callback) { | ||
callback(err); | ||
} | ||
return; | ||
} | ||
const response = options.use_xhr ? _response : result.decodeResponse(_response); | ||
if (callback) { | ||
callback(null, response); | ||
} | ||
}); | ||
delete(apiPath, parameters, options) { | ||
return result.doSend(apiPath, parameters, 'GET', options); | ||
}, | ||
/** | ||
@@ -112,15 +93,5 @@ * Send a request to the server using a URL received from the API directly, receive a response | ||
*/ | ||
doPrebuiltSend(prebuiltURL, callback) { | ||
doPrebuiltSend(prebuiltURL) { | ||
const { headers, port } = result.prepRequest($options); | ||
let called = false; | ||
function done(err, body) { | ||
if (called) { | ||
return; | ||
} | ||
called = true; | ||
callback(err, body); | ||
} | ||
if ($options.use_xhr) { | ||
@@ -134,4 +105,3 @@ const xhrOptions = { | ||
result.sendXhrRequest(xhrOptions, done); | ||
return; | ||
return result.sendXhrRequest(xhrOptions); | ||
} | ||
@@ -148,3 +118,3 @@ | ||
result.sendHttpsRequest(httpsOptions, undefined, done); | ||
return result.sendHttpsRequest(httpsOptions); | ||
}, | ||
@@ -155,7 +125,8 @@ | ||
* | ||
* @param {String} $apiPath Request API path | ||
* @param {Object} $parameters Parameters | ||
* @param {String} $httpMethod HTTP method to use | ||
* @param {String} apiPath Request API path | ||
* @param {Object} parameters Parameters | ||
* @param {String} _httpMethod HTTP method to use | ||
* @param {Object} options reconfigure the request for this call only | ||
*/ | ||
doSend(apiPath, parameters, _httpMethod, options, callback) { | ||
doSend(apiPath, parameters, _httpMethod = 'GET', options = $options) { | ||
const method = _httpMethod.toUpperCase(); | ||
@@ -178,12 +149,2 @@ const { headers, hostname, port } = result.prepRequest(options); | ||
let called = false; | ||
function done(err, body) { | ||
if (called) { | ||
return; | ||
} | ||
called = true; | ||
callback(err, body); | ||
} | ||
if (options.use_xhr) { | ||
@@ -201,4 +162,3 @@ const xhrOptions = { | ||
result.sendXhrRequest(xhrOptions, done); | ||
return; | ||
return result.sendXhrRequest(xhrOptions); | ||
} | ||
@@ -214,3 +174,3 @@ | ||
result.sendHttpsRequest(httpsOptions, query, done); | ||
return result.sendHttpsRequest(httpsOptions, query); | ||
}, | ||
@@ -223,2 +183,5 @@ | ||
if ($options.format === 'json') { | ||
if (!response) { | ||
return {}; | ||
} | ||
return JSON.parse(response); | ||
@@ -256,36 +219,39 @@ } | ||
sendHttpsRequest(httpsOptions, query, done) { | ||
sendHttpsRequest(httpsOptions, query) { | ||
let resolve; | ||
let reject; | ||
const resultPromise = new Promise((_resolve, _reject) => { | ||
resolve = _resolve; | ||
reject = _reject; | ||
}); | ||
const request = https.request(httpsOptions, (response) => { | ||
response.setEncoding('utf8'); | ||
const body = []; | ||
const rawBody = []; | ||
response.addListener('data', (chunk) => { | ||
body.push(chunk); | ||
rawBody.push(chunk); | ||
}); | ||
response.addListener('end', () => { | ||
let msg = body.join(''); | ||
let body = rawBody.join(''); | ||
if (response.statusCode > 204) { | ||
if (response.statusCode >= 400) { | ||
if (response.headers['content-type'].includes('application/json')) { | ||
msg = JSON.parse(msg); | ||
body = JSON.parse(body); | ||
} | ||
done({ status: response.statusCode, msg }); | ||
reject({ statusCode: response.statusCode, body }); | ||
return; | ||
} | ||
if (response.statusCode === 204) { | ||
msg = {}; | ||
} | ||
else { | ||
msg = result.decodeResponse(msg); | ||
} | ||
done(null, msg); | ||
body = result.decodeResponse(body); | ||
resolve({ statusCode: response.statusCode, body }); | ||
}); | ||
response.addListener('error', (e) => { | ||
done(e); | ||
reject(e); | ||
}); | ||
response.addListener('timeout', () => { | ||
done(new Error('Request timed out')); | ||
reject(new Error('Request timed out')); | ||
}); | ||
@@ -295,3 +261,3 @@ }); | ||
request.on('error', (e) => { | ||
done(e); | ||
reject(e); | ||
}); | ||
@@ -304,24 +270,31 @@ | ||
request.end(); | ||
return resultPromise; | ||
}, | ||
sendXhrRequest(xhrOptions, done) { | ||
sendXhrRequest(xhrOptions) { | ||
let resolve; | ||
let reject; | ||
const resultPromise = new Promise((_resolve, _reject) => { | ||
resolve = _resolve; | ||
reject = _reject; | ||
}); | ||
xhr(xhrOptions, (error, response) => { | ||
if (error) { | ||
done(error); | ||
reject(error); | ||
return; | ||
} | ||
let msg = response.body; | ||
if (response.statusCode > 204) { | ||
done({ status: response.statusCode, msg }); | ||
if (response.statusCode >= 400) { | ||
reject(response); | ||
return; | ||
} | ||
if (response.statusCode === 204) { | ||
msg = {}; | ||
} | ||
done(null, msg); | ||
resolve(response); | ||
}); | ||
return resultPromise; | ||
} | ||
}); | ||
}; |
@@ -1,5 +0,1 @@ | ||
const _ = require('lodash'); | ||
const AbstractApi = require('./abstract_api'); | ||
/** | ||
@@ -9,16 +5,8 @@ * API docs: https://confluence.atlassian.com/bitbucket/user-endpoint-2-0-744527199.html | ||
module.exports = function UserApi(api) { | ||
const result = AbstractApi(api); | ||
return _.assign(result, { | ||
return { | ||
/** | ||
* Get the info for the authenticated user | ||
*/ | ||
get(callback) { | ||
api.get( | ||
'user', | ||
null, null, | ||
result.$createListener(callback) | ||
); | ||
} | ||
}); | ||
get: () => api.get('user') | ||
}; | ||
}; |
{ | ||
"name": "bitbucket-v2", | ||
"version": "0.4.4", | ||
"version": "0.5.0", | ||
"description": "Wrapper for the BitBucket API v2, the version required to use OAuth2. Includes support for XHR requests.", | ||
@@ -16,6 +16,6 @@ "author": "Jordan Wallet <jjwallet@gmail.com>", | ||
"engine": [ | ||
"node >=6.2.1" | ||
"node >=7.6.0" | ||
], | ||
"dependencies": { | ||
"lodash": "^4.6.1", | ||
"lodash": "^4.17.15", | ||
"oauth": "~0.9.14", | ||
@@ -22,0 +22,0 @@ "xhr": "^2.2.0" |
@@ -5,11 +5,19 @@ # node-bitbucket-v2 | ||
## usage | ||
Not supported for Node < 7.6 | ||
``` | ||
const Bitbucket = require('node-bitbucket-v2') | ||
const bitbucketApi = new Bitbucket(); //or: new Bitbucket({useXhr: true}) | ||
bitbucketApi.authenticateOAuth2(someAccessToken); | ||
bitbucketApi.user.get((response) => { | ||
console.log(response.username); | ||
const Bitbucket = require('node-bitbucket-v2'); | ||
const bitbucketApi = new Bitbucket(options); | ||
bitbucketApi.authenticateOAuth2(accessTokenString); | ||
bitbucketApi.user.get().then(({ body }) => { | ||
console.log(body.uuid); | ||
}); | ||
``` | ||
### `options` | ||
It is not necessary to provide any options at all (`Bitbucket` can be constructed with no argument). | ||
- `useXhr` (`Boolean`): If `true`, requests will be made using XMLHttpRequest. This is only available in a web browser, and will fail otherwise. This can be very useful in Electron for automatically resolving proxies and custom SSL certificates. | ||
- `proxy` (`String`): Defines a proxy to make requests against, instead of `api.bitbucket.org:443`. This option is _ignored_ when `useXhr` is active. | ||
For implemented methods, check `bitbucket/repositories.js` and `bitbucket/user.js`. |
23
25591
598
Updatedlodash@^4.17.15