1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const archiver = require("archiver");
|
5 | const axios_1 = require("axios");
|
6 | const fs = require("fs-extra");
|
7 | const globby = require("globby");
|
8 | const Listr = require("listr");
|
9 | const serviceClient_1 = require("@bearer/bearer-cli/lib/lib/serviceClient");
|
10 | const base_command_1 = require("../base-command");
|
11 | const decorators_1 = require("../utils/decorators");
|
12 | const helpers_1 = require("../utils/helpers");
|
13 | const integration_client_1 = require("../utils/integration-client");
|
14 | const locator_1 = require("../utils/locator");
|
15 | class 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 |
|
55 | `Your Integration will be available shortly here: ` +
|
56 | this.colors.bold(`${this.constants.DeveloperPortalUrl}integrations/${this.bearerConfig.bearerUid}`));
|
57 | this.log(
|
58 |
|
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 }
|
71 | });
|
72 |
|
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 | }
|
146 | Push.description = 'deploy integration to Bearer';
|
147 | Push.flags = Object.assign({}, base_command_1.default.flags);
|
148 | Push.args = [];
|
149 | tslib_1.__decorate([
|
150 | decorators_1.RequireIntegrationFolder(),
|
151 | decorators_1.RequireLinkedIntegration()
|
152 | ], Push.prototype, "run", null);
|
153 | tslib_1.__decorate([
|
154 | decorators_1.ensureFreshToken()
|
155 | ], Push.prototype, "fetchCredentials", null);
|
156 | exports.default = Push;
|
157 | const QUERY = `
|
158 | query CLIPush {
|
159 | currentUser {
|
160 | email
|
161 | infrastructure {
|
162 | password
|
163 | }
|
164 | }
|
165 | }
|
166 | `;
|