UNPKG

6.43 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const archiver = require("archiver");
5const axios_1 = require("axios");
6const fs = require("fs-extra");
7const globby = require("globby");
8const Listr = require("listr");
9const serviceClient_1 = require("@bearer/bearer-cli/lib/lib/serviceClient");
10const base_command_1 = require("../base-command");
11const decorators_1 = require("../utils/decorators");
12const helpers_1 = require("../utils/helpers");
13const integration_client_1 = require("../utils/integration-client");
14const locator_1 = require("../utils/locator");
15class Push extends base_command_1.default {
16 constructor() {
17 super(...arguments);
18 this.fetchLoginInformation = async () => {
19 const { BEARER_TOKEN, BEARER_EMAIL } = process.env;
20 if (BEARER_TOKEN && BEARER_EMAIL) {
21 return {
22 Username: BEARER_EMAIL,
23 Password: BEARER_TOKEN
24 };
25 }
26 const data = await this.fetchCredentials();
27 this.debug('received credentials: %j', data);
28 return data;
29 };
30 }
31 async run() {
32 const { Username, Password } = await this.fetchLoginInformation();
33 this.debug({ Username, Password });
34 this.serviceClient = serviceClient_1.default(this.constants.IntegrationServiceUrl);
35 const data = await this.serviceClient.login({ Username, Password });
36 this.debug('auth info : %j', data);
37 this.integrationClient = new integration_client_1.IntegrationClient(this.constants.DeploymentUrl, data.body.authorization.AuthenticationResult.IdToken, this.config.version);
38 helpers_1.ensureFolderExists(this.locator.buildArtifactDir, true);
39 const archivePath = this.locator.buildArtifactResourcePath('integration.zip');
40 const tasks = [
41 {
42 title: 'Generate bundle',
43 task: async (_ctx) => this.archive(archivePath)
44 },
45 {
46 title: 'Transfer bundle',
47 task: async (_ctx) => this.transfer(archivePath)
48 }
49 ];
50 try {
51 await new Listr(tasks).run();
52 this.success(`🐻 Integration successfully pushed.\n`);
53 this.log(
54 // tslint:disable-next-line:prefer-template
55 `Your Integration will be available shortly here: ` +
56 this.colors.bold(`${this.constants.DeveloperPortalUrl}integrations/${this.bearerConfig.bearerUid}`));
57 this.log(
58 // tslint:disable-next-line:prefer-template
59 `\nIn the meantime you can follow the deployment here: ` +
60 this.colors.bold(`${this.constants.DeveloperPortalUrl}integrations/${this.bearerConfig.bearerUid}/logs`));
61 }
62 catch (e) {
63 this.error(e);
64 }
65 }
66 async archive(archivePath) {
67 return new Promise(async (resolve, reject) => {
68 const output = fs.createWriteStream(archivePath);
69 const archive = archiver('zip', {
70 zlib: { level: 9 } // Sets the compression level.
71 });
72 // pipe archive data to the file
73 archive.pipe(output);
74 const files = await globby([
75 'views/**/*',
76 'functions/**/*.ts',
77 'functions/tsconfig.json',
78 'yarn.lock',
79 'package-json.lock',
80 'spec.ts',
81 'package.json',
82 locator_1.AUTH_CONFIG_FILENAME
83 ]);
84 this.debug('Files to upload', files.join('\n'));
85 if (files.length >= 100) {
86 return reject(new Error('Too many files to bundle. Please re-run this command this DEBUG=*'));
87 }
88 output.on('close', () => {
89 this.debug(`Archive created: ${archive.pointer() / 1024} Kb / ${archivePath}`);
90 resolve(archivePath);
91 });
92 archive.on('error', (err) => {
93 reject(err);
94 });
95 archive.on('warning', (err) => {
96 if (err.code === 'ENOENT') {
97 reject(err);
98 }
99 else {
100 this.debug(err);
101 }
102 });
103 files.map(file => {
104 archive.file(file, { name: file });
105 });
106 archive.finalize();
107 });
108 }
109 async getSignedUrl() {
110 return this.integrationClient.getIntegrationArchiveUploadUrl(this.bearerConfig.bearerUid);
111 }
112 async transfer(archivePath) {
113 try {
114 const url = await this.getSignedUrl();
115 this.debug(url);
116 const file = fs.readFileSync(archivePath);
117 await axios_1.default.put(url, file, { headers: { 'Content-Type': 'application/zip' } });
118 return true;
119 }
120 catch (e) {
121 if (e.response) {
122 this.debug(e.response);
123 switch (e.response.status) {
124 case 401: {
125 this.error(`Unauthorized to push, please visit ${this.constants.DeveloperPortalUrl}integrations/${this.bearerConfig.bearerUid} to confirm you have access to ${this.colors.bold(this.bearerConfig.bearerUid)} integration.`);
126 }
127 default: {
128 this.log(e.response.data);
129 }
130 }
131 }
132 this.error(e);
133 return false;
134 }
135 }
136 async fetchCredentials() {
137 const { data } = await this.devPortalClient.request({
138 query: QUERY
139 });
140 if (data.data) {
141 return { Username: data.data.currentUser.email, Password: data.data.currentUser.infrastructure.password };
142 }
143 throw 'Fetch credentials error';
144 }
145}
146Push.description = 'deploy integration to Bearer';
147Push.flags = Object.assign({}, base_command_1.default.flags);
148Push.args = [];
149tslib_1.__decorate([
150 decorators_1.RequireIntegrationFolder(),
151 decorators_1.RequireLinkedIntegration()
152], Push.prototype, "run", null);
153tslib_1.__decorate([
154 decorators_1.ensureFreshToken()
155], Push.prototype, "fetchCredentials", null);
156exports.default = Push;
157const QUERY = `
158query CLIPush {
159 currentUser {
160 email
161 infrastructure {
162 password
163 }
164 }
165}
166`;