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