@codefresh-io/cf-git-providers
Advanced tools
Comparing version
@@ -19,2 +19,3 @@ import { ProviderName, Provider, Branch, Repository, Webhook } from './types'; | ||
private performAPICall; | ||
private paginate; | ||
fetchRawFile(opts: { | ||
@@ -31,7 +32,7 @@ owner: string; | ||
}): Promise<Branch>; | ||
getRepository(opt: { | ||
getRepository(opts: { | ||
owner: string; | ||
repo: string; | ||
}): Promise<Repository>; | ||
listBranches(opt: { | ||
listBranches(opts: { | ||
owner: string; | ||
@@ -38,0 +39,0 @@ repo: string; |
@@ -6,7 +6,11 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const lodash_1 = __importDefault(require("lodash")); | ||
const lodash_1 = require("lodash"); | ||
const request_promise_1 = __importDefault(require("request-promise")); | ||
const https_1 = require("https"); | ||
const helpers_1 = require("../helpers"); | ||
// tslint:disable-next-line: no-var-requires | ||
const CFError = require('cf-errors'); | ||
const logger = helpers_1.createNewLogger('codefresh:infra:git-providers:bitbucket'); | ||
const LIMIT_PER_PAGE = 100; | ||
const MAX_PAGES = 30; | ||
const ApiVersions = { | ||
@@ -23,2 +27,48 @@ V1: 'api/1.0/', | ||
}; | ||
const _buildErrorString = (response) => { | ||
let errStr = `${lodash_1.get(response, 'body.error.message')}`; | ||
if (lodash_1.get(response, 'body.error.id')) { | ||
errStr = `${errStr} [${lodash_1.get(response, 'body.error.id')}]`; | ||
} | ||
return `code: ${response.statusCode}, ${errStr}`; | ||
}; | ||
const _toRepo = (rawRepo, issues) => { | ||
const isGroup = lodash_1.get(rawRepo, 'owner.type') === 'team'; | ||
const httpsClone = rawRepo.links.clone.find((link) => link.name === 'https'); | ||
const sshClone = rawRepo.links.clone.find((link) => link.name === 'ssh'); | ||
return { | ||
id: rawRepo.uuid, | ||
provider: 'bitbucket', | ||
name: rawRepo.name, | ||
full_name: rawRepo.full_name, | ||
private: rawRepo.is_private, | ||
pushed_at: rawRepo.updated_on, | ||
open_issues: issues ? issues : 0, | ||
clone_url: lodash_1.get(httpsClone, 'href', ''), | ||
ssh_url: lodash_1.get(sshClone, 'href', ''), | ||
owner: { | ||
login: lodash_1.get(rawRepo, 'owner.display_name', ''), | ||
avatar_url: lodash_1.get(rawRepo, 'owner.links.avatar.href', ''), | ||
creator: null, | ||
}, | ||
org: isGroup ? lodash_1.get(rawRepo, 'owner.username') : null, | ||
default_branch: lodash_1.get(rawRepo, 'mainbranch.name', ''), | ||
permissions: { | ||
admin: true, | ||
}, | ||
webUrl: lodash_1.get(rawRepo, 'links.html.href', ''), | ||
}; | ||
}; | ||
const _toBranch = (rawBranch) => { | ||
return { | ||
name: rawBranch.name, | ||
id: rawBranch.name, | ||
commit: { | ||
sha: rawBranch.target.hash, | ||
commiter_name: lodash_1.get(rawBranch, 'target.author.user.display_name', ''), | ||
message: lodash_1.get(rawBranch, 'target.message', ''), | ||
url: lodash_1.get(rawBranch, 'target.links.html.href', ''), | ||
} | ||
}; | ||
}; | ||
class Bitbucket { | ||
@@ -46,3 +96,3 @@ constructor(opts) { | ||
const method = opts.method || 'GET'; | ||
const requestHeaders = lodash_1.default.merge(opts.noAuth ? {} : this.authenticationHeader, opts.headers || {}); | ||
const requestHeaders = lodash_1.merge(opts.noAuth ? {} : this.authenticationHeader, opts.headers || {}); | ||
const requestOptions = { | ||
@@ -58,5 +108,39 @@ method, | ||
agent: this.agent, | ||
simple: false, | ||
}; | ||
return request_promise_1.default(requestOptions); | ||
} | ||
async paginate(opts, predicate) { | ||
let start = 1; | ||
let isLastPage = false; | ||
const results = []; | ||
const limit = opts.limit || Number.MAX_SAFE_INTEGER; | ||
while (!isLastPage && start <= MAX_PAGES && results.length < limit) { | ||
opts.qs = lodash_1.merge(opts.qs, { | ||
page: '' + start, | ||
pagelen: '' + (limit - results.length > LIMIT_PER_PAGE ? LIMIT_PER_PAGE : limit - results.length), | ||
}); | ||
const res = await this.performAPICall(opts); | ||
if (res.statusCode >= 400) { | ||
return res; | ||
} | ||
if (predicate) { | ||
const predicateResult = lodash_1.find(res.body.values, predicate); | ||
if (predicateResult) { | ||
// found the wanted result | ||
return { | ||
statusCode: 200, | ||
body: predicateResult, | ||
}; | ||
} | ||
} | ||
res.body.values.forEach((result) => { results.push(result); }); | ||
isLastPage = !lodash_1.has(res.body, 'next'); | ||
start += 1; | ||
} | ||
return { | ||
statusCode: 200, | ||
body: results, | ||
}; | ||
} | ||
async fetchRawFile(opts) { | ||
@@ -81,18 +165,37 @@ const res = await this.performAPICall({ | ||
} | ||
return { | ||
name: res.body.name, | ||
id: res.body.name, | ||
commit: { | ||
sha: res.body.target.hash, | ||
commiter_name: lodash_1.default.get(res.body, 'target.author.user.display_name', ''), | ||
message: lodash_1.default.get(res.body, 'target.message', ''), | ||
url: lodash_1.default.get(res.body, 'target.links.html.href', ''), | ||
} | ||
}; | ||
return _toBranch(res.body); | ||
} | ||
async getRepository(opt) { | ||
throw new Error("Method not implemented."); | ||
async getRepository(opts) { | ||
const repoPromise = this.performAPICall({ | ||
apiVersion: ApiVersions.V2, | ||
api: `repositories/${opts.owner}/${opts.repo}`, | ||
json: true, | ||
}); | ||
const issuesPromise = this.performAPICall({ | ||
apiVersion: ApiVersions.V2, | ||
api: `repositories/${opts.owner}/${opts.repo}/issues`, | ||
json: true, | ||
}); | ||
const [repoResponse, issuesResponse] = await Promise.all([repoPromise, issuesPromise]); | ||
if (repoResponse.statusCode >= 400) { | ||
throw new CFError(`Failed to get repository: ${JSON.stringify(opts)}, ${_buildErrorString(repoResponse)}`); | ||
} | ||
if (issuesResponse.statusCode >= 400) { | ||
logger.warn(`Failed to get repository issues: ${JSON.stringify(opts)}, ${_buildErrorString(issuesResponse)}`); | ||
issuesResponse.body.size = 0; // have 0 issues | ||
} | ||
return _toRepo(repoResponse.body, issuesResponse.body.size); | ||
} | ||
async listBranches(opt) { | ||
throw new Error("Method not implemented."); | ||
async listBranches(opts) { | ||
const res = await this.paginate({ | ||
apiVersion: ApiVersions.V2, | ||
api: `repositories/${opts.owner}/${opts.repo}/refs/branches`, | ||
json: true, | ||
page: opts.page, | ||
limit: opts.limit, | ||
}); | ||
if (res.statusCode >= 400) { | ||
throw new CFError(`Failed to get branches list: ${JSON.stringify(opts)}, ${_buildErrorString(res)}`); | ||
} | ||
return res.body.map(_toBranch); | ||
} | ||
@@ -99,0 +202,0 @@ async listRepositoriesForOwner(opt) { |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const lodash_1 = __importDefault(require("lodash")); | ||
const lodash_1 = require("lodash"); | ||
const request_promise_1 = __importDefault(require("request-promise")); | ||
@@ -21,2 +21,27 @@ const https_1 = require("https"); | ||
}; | ||
const _toRepo = (rawRepo) => { | ||
const isGroup = lodash_1.get(rawRepo, 'namespace.kind') === 'group'; // is it a group/org repository | ||
return { | ||
id: rawRepo.id.toString(), | ||
provider: 'gitlab', | ||
name: rawRepo.name, | ||
full_name: rawRepo.path_with_namespace, | ||
private: rawRepo.visibility === 'private', | ||
pushed_at: rawRepo.last_activity_at, | ||
open_issues: rawRepo.open_issues_count, | ||
clone_url: rawRepo.http_url_to_repo, | ||
ssh_url: rawRepo.ssh_url_to_repo, | ||
owner: { | ||
login: lodash_1.get(rawRepo, isGroup ? 'namespace.name' : 'owner.username', ''), | ||
avatar_url: lodash_1.get(rawRepo, isGroup ? 'namespace.avatar_url' : 'owner.avatar_url', ''), | ||
creator: null, | ||
}, | ||
org: isGroup ? lodash_1.get(rawRepo, 'namespace.name') : null, | ||
default_branch: rawRepo.default_branch, | ||
permissions: { | ||
admin: lodash_1.get(rawRepo, `permissions.${isGroup ? 'group_access' : 'project_access'}.access_level`, 0) >= 40, | ||
}, | ||
webUrl: rawRepo.web_url || '', | ||
}; | ||
}; | ||
class Gitlab { | ||
@@ -37,3 +62,3 @@ constructor(opts) { | ||
const method = opts.method || 'GET'; | ||
const requestHeaders = lodash_1.default.merge(opts.noAuth ? {} : this.authenticationHeader, opts.headers || {}); | ||
const requestHeaders = lodash_1.merge(opts.noAuth ? {} : this.authenticationHeader, opts.headers || {}); | ||
const requestOptions = { | ||
@@ -49,2 +74,3 @@ method, | ||
agent: this.agent, | ||
simple: false, | ||
}; | ||
@@ -88,3 +114,10 @@ return request_promise_1.default(requestOptions); | ||
async getRepository(opt) { | ||
throw new Error("Method not implemented."); | ||
const res = await this.performAPICall({ | ||
api: `projects/${_encodeProjectPath(opt.owner, opt.repo)}`, | ||
json: true, | ||
}); | ||
if (res.statusCode >= 400) { | ||
throw new CFError(`Failed to get repository: ${JSON.stringify(opt)}, status code: ${res.statusCode}`); | ||
} | ||
return _toRepo(res.body); | ||
} | ||
@@ -91,0 +124,0 @@ async listBranches(opt) { |
{ | ||
"name": "@codefresh-io/cf-git-providers", | ||
"version": "0.0.39", | ||
"version": "0.0.40", | ||
"description": "An NPM module/CLI for interacting with various git providers", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
167850
9.3%69
4.55%2599
7.84%