UNPKG

@heroku/buildpack-registry

Version:

Node.js/TypeScript library for interfacing with the Heroku Buildpack Registry

232 lines (231 loc) 8.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const true_myth_1 = require("true-myth"); const buildpack_registry_api_1 = require("./buildpack-registry-api"); const BUILDPACK_FORMATTING_MESSAGE = "To specify a buildpack, please format it like the following: namespace/name (e.g. heroku/ruby). Also names can only contain letters, numbers, '_', and '-'."; class BuildpackRegistry { static isValidBuildpackSlug(buildpack) { let nameParts = buildpack.split('/'); if (nameParts.length === 2 && nameParts[0].length > 0 && nameParts[1].length > 0 && /^[a-z0-9][a-z0-9_\-]*$/i.exec(nameParts[1])) { return true_myth_1.Result.ok(true); } else { return true_myth_1.Result.err(BUILDPACK_FORMATTING_MESSAGE); } } constructor() { this.api = buildpack_registry_api_1.BuildpackRegistryApi.create(); } async requiresTwoFactor(buildpack) { let path = `/buildpacks/${encodeURIComponent(buildpack)}`; let response = await this.api.get(path); if (response.status === 200) { let body = await response.json(); return true_myth_1.Result.ok(body.two_factor_authentication); } else { return true_myth_1.Result.err({ status: response.status, path, description: await response.text() }); } } async publish(buildpack, ref, token, secondFactor) { let options = { token }; if (secondFactor !== undefined) { options.secondFactor = secondFactor; } let path = `/buildpacks/${encodeURIComponent(buildpack)}/revisions`; let response = await this.api.post(path, { ref }, this.api.headers(options)); if (response.status === 200) { return true_myth_1.Result.ok(await response.json()); } else { return true_myth_1.Result.err({ status: response.status, path, description: await response.text() }); } } async rollback(buildpack, token, secondFactor) { let options = { token }; if (secondFactor !== undefined) { options.secondFactor = secondFactor; } let path = `/buildpacks/${encodeURIComponent(buildpack)}/actions/rollback`; let response = await this.api.post(path, undefined, this.api.headers(options)); if (response.status === 200) { return true_myth_1.Result.ok(await response.json()); } else { return true_myth_1.Result.err({ status: response.status, path, description: await response.text(), }); } } async search(namespace, name, description) { let queryParams = []; let queryString = ''; if (namespace) { queryParams = namespace.split(',') .map(namespace => `in[namespace][]=${namespace}`); } if (name) { queryParams = queryParams.concat(name.split(',') .map(name => `in[name][]=${name}`)); } if (description) { queryParams = queryParams.concat(`like[description]=${encodeURIComponent(description)}`); } if (queryParams.length > 0) { queryString = `?${queryParams.join('&')}`; } let path = `/buildpacks${queryString}`; let response = await this.api.get(path); if (response.status === 200) { return true_myth_1.Result.ok(await response.json()); } else { return true_myth_1.Result.err({ status: response.status, path, description: await response.text(), }); } } async info(buildpack) { let path = `/buildpacks/${encodeURIComponent(buildpack)}`; let response = await this.api.get(path); if (response.status !== 200) { return true_myth_1.Result.err({ status: response.status, path, description: await response.text(), }); } let bp_body = await response.json(); let result = await this.listVersions(buildpack); if (result.isErr()) { return true_myth_1.Result.err(result.unsafelyUnwrapErr()); } let revisions = result.unsafelyUnwrap(); let revision = revisions.sort((a, b) => { return a.release > b.release ? -1 : 1; })[0]; path = `/buildpacks/${encodeURIComponent(buildpack)}/readme`; response = await this.api.get(path); if (response.status !== 200) { return true_myth_1.Result.err({ status: response.status, path, description: await response.text() }); } let readme = await response.json(); let data = { description: bp_body.description, category: bp_body.category, license: revision.license }; if (bp_body.support.method === 'email') { data.support = bp_body.support.address.replace('mailto:', ''); } else if (bp_body.support.method === 'github') { data.support = `https://github.com/${bp_body.source.owner}/${bp_body.source.repo}/issues`; } else if (bp_body.support.method === 'unsupported') { data.support = 'Unsupported by author'; } else { data.support = bp_body.support.address; } if (bp_body.source.type === 'github') { data.source = `https://github.com/${bp_body.source.owner}/${bp_body.source.repo}`; } if (readme.content) { data.readme = `\n${Buffer.from(readme.content, readme.encoding).toString()}`; } return true_myth_1.Result.ok(data); } async archive(buildpack, token, secondFactor) { let options = { token }; if (secondFactor !== undefined) { options.secondFactor = secondFactor; } let path = `/buildpacks/${encodeURIComponent(buildpack)}/actions/archive`; let response = await this.api.post(path, undefined, this.api.headers(options)); if (response.status === 200) { return true_myth_1.Result.ok(await response.json()); } else { return true_myth_1.Result.err({ status: response.status, path, description: await response.text(), }); } } async revisionInfo(buildpack, revision_id) { let path = `/buildpacks/${encodeURIComponent(buildpack)}/revisions/${encodeURIComponent(revision_id)}`; let response = await this.api.get(path); if (response.status === 200) { return true_myth_1.Result.ok(await response.json()); } else { return true_myth_1.Result.err({ status: response.status, path, description: await response.text(), }); } } async buildpackExists(buildpack) { return this.api.get(`/buildpacks/${encodeURIComponent(buildpack)}`); } async listVersions(buildpack) { let path = `/buildpacks/${encodeURIComponent(buildpack)}/revisions`; let response = await this.api.get(path); if (response.status === 200) { return true_myth_1.Result.ok(await response.json()); } else { return true_myth_1.Result.err({ status: response.status, path, description: await response.text() }); } } async delay(ms) { // Disable lint is Temporary // until this issue is resolved https://github.com/Microsoft/tslint-microsoft-contrib/issues/355#issuecomment-407209401 // tslint:disable-next-line no-string-based-set-timeout return new Promise(resolve => setTimeout(resolve, ms)); } async waitForRelease(buildpack_id, revision_id) { let status = 'failed'; let status_count = 0; let running = true; while (running) { status_count += 1; let result = await this.revisionInfo(buildpack_id, revision_id); if (result.isOk()) { let revision = result.unsafelyUnwrap(); status = revision.status; if (status !== 'pending') { break; } if (status_count === 60) { break; } } await this.delay(2000); } return status; } } exports.BuildpackRegistry = BuildpackRegistry;