UNPKG

bitbucket-repository-provider

Version:
214 lines (189 loc) 5.51 kB
import { replaceWithOneTimeExecutionMethod } from "one-time-execution-method"; import { stateActionHandler } from "fetch-rate-limit-util"; import { url_attribute, token_attribute, username_attribute, password_attribute, object_attribute } from "pacc"; import { MultiGroupProvider } from "repository-provider"; import { BitbucketBranch } from "./bitbucket-branch.mjs"; import { BitbucketRepositoryGroup } from "./bitbucket-repository-group.mjs"; import { BitbucketRepository } from "./bitbucket-repository.mjs"; import { BitbucketPullRequest } from "./bitbucket-pull-request.mjs"; import { BitbucketHook } from "./bitbucket-hook.mjs"; export { BitbucketBranch, BitbucketRepository, BitbucketPullRequest, BitbucketRepositoryGroup, BitbucketHook }; const domain = "bitbucket.org"; /** * Provider for bitbucket repositories. * * Supported name schemes are * - https://user:aSecret@bitbucket.org/owner/repo-name.git * - git+https://user:aSecret@bitbucket.org/owner/repo-name.git * - git@bitbucket.org:owner/repo-name.git * - owner/repo-name * Known environment variables * - BITBUCKET_API api * - BITBUCKET_TOKEN api token * - BITBUCKET_USERNAME username * - BITBUCKET_APP_PASSWORD password * - BITBUCKET_PASSWORD password * @param {Object} config * @param {string} config.url provider scm base * @param {string} config.api provider api base * @param {Object} config.authentication authentication * @param {string} config.authentication.type * @param {string} config.authentication.username * @param {string} config.authentication.password */ export class BitbucketProvider extends MultiGroupProvider { /** * We are called bitbucket. * @return {string} bitbucket */ static get name() { return "bitbucket"; } /** * Default instance env name prefix. */ static get instanceIdentifier() { return "BITBUCKET_"; } /** * Default configuration as given for the cloud privider. * @return {Object} */ static attributes = { ...super.attributes, url: { ...url_attribute, default: `https://${domain}/` }, api: { ...url_attribute, description: "URL of the provider api", env: "{{instanceIdentifier}}API", prepareValue: value => (value.endsWith("/") ? value : value + "/"), default: `https://api.${domain}/2.0/` }, authentication: { ...object_attribute, mandatory: true, attributes: { token: { ...token_attribute, description: "API token", env: "{{instanceIdentifier}}TOKEN", additionalValues: { "authentication.type": "token" } }, password: { ...password_attribute, description: "Password for plain authentification", env: [ "{{instanceIdentifier}}APP_PASSWORD", "{{instanceIdentifier}}PASSWORD" ], additionalValues: { "authentication.type": "basic" } }, username: { ...username_attribute, description: "Username for plain authentification", env: "{{instanceIdentifier}}USERNAME", additionalValues: { "authentication.type": "basic" } } } } }; repositoryGroupClassFor(name, options) { return BitbucketRepositoryGroup; } get repositoryClass() { return BitbucketRepository; } get branchClass() { return BitbucketBranch; } get pullRequestClass() { return BitbucketPullRequest; } get hookClass() { return BitbucketHook; } /** * All possible base urls. * @return {string[]} common base urls of all repositories */ get repositoryBases() { return super.repositoryBases.concat([ this.url, `ssh://${domain}`, `git@${domain}:`, `git@${domain}/`, `git+ssh@${domain}:`, `ssh@${domain}:` ]); } /** * {@link https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories} */ async initializeRepositories() { try { let next = "repositories/?role=contributor"; do { const { json } = await this.fetchJSON(next); next = json.next; json.values.map(b => { const groupName = b.owner.nickname || b.owner.username; this.addRepositoryGroup(groupName, b.owner).addRepository(b.name, b); }); } while (next); } catch {} } fetch(url, options = {}) { let authorization; if (this.authentication.username) { authorization = "Basic " + Buffer.from( this.authentication.username + ":" + this.authentication.password ).toString("base64"); } else { if (this.authentication.token) { authorization = "Bearer " + this.authentication.token; } } const headers = { authorization, ...options.headers }; if (options.data) { options.body = JSON.stringify(options.data); delete options.data; headers["Content-Type"] = "application/json"; } options.reporter = (url, ...args) => this.trace(url.toString(), ...args); return stateActionHandler(new URL(url, this.api), { ...options, headers }); } fetchJSON(url, options = {}) { options.postprocess = async response => { return { response, json: await response.json() }; }; return this.fetch(url, options); } } replaceWithOneTimeExecutionMethod( BitbucketProvider.prototype, "initializeRepositories" ); export default BitbucketProvider;