UNPKG

9.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const path_1 = require("path");
4const fs = require("fs");
5const os_1 = require("os");
6const axios_1 = require("axios");
7const colors = require("colors");
8const FormData = require('form-data');
9const util = require('util');
10const exec = util.promisify(require('child_process').exec);
11const { hashElement } = require('folder-hash');
12const ora = require('ora');
13const BOTONIC_CLIENT_ID = process.env.BOTONIC_CLIENT_ID || 'jOIYDdvcfwqwSs7ZJ1CpmTKcE7UDapZDOSobFmEp';
14const BOTONIC_CLIENT_SECRET = process.env.BOTONIC_CLIENT_SECRET ||
15 'YY34FaaNMnIVKztd6LbLIKn3wFqtiLhDgl6ZVyICwsLVWkZN9UzXw0GXFMmWinP3noNGU9Obtb6Nrr1BwMc4IlCTcRDOKJ96JME5N02IGnIY62ZUezMgfeiUZUmMSu68';
16const BOTONIC_URL = process.env.BOTONIC_URL || 'https://api.hubtype.com';
17class BotonicAPIService {
18 constructor() {
19 this.cliendId = BOTONIC_CLIENT_ID;
20 this.clientSecret = BOTONIC_CLIENT_SECRET;
21 this.baseUrl = BOTONIC_URL;
22 this.baseApiUrl = this.baseUrl + '/v1/';
23 this.loginUrl = this.baseUrl + '/o/token/';
24 this.botPath = process.cwd();
25 this.botCredentialsPath = path_1.join(this.botPath, '.botonic.json');
26 this.globalConfigPath = path_1.join(os_1.homedir(), '.botonic');
27 this.globalCredentialsPath = path_1.join(this.globalConfigPath, 'credentials.json');
28 this.bot = null;
29 this.headers = null;
30 this.loadGlobalCredentials();
31 this.loadBotCredentials();
32 }
33 beforeExit() {
34 this.saveGlobalCredentials();
35 this.saveBotCredentials();
36 }
37 loadGlobalCredentials() {
38 try {
39 var credentials = JSON.parse(fs.readFileSync(this.globalCredentialsPath, 'utf8'));
40 }
41 catch (e) { }
42 if (credentials) {
43 this.oauth = credentials.oauth;
44 this.me = credentials.me;
45 this.analytics = credentials.analytics;
46 if (credentials.oauth)
47 this.headers = {
48 Authorization: `Bearer ${this.oauth.access_token}`,
49 'content-type': 'application/json',
50 'x-segment-anonymous-id': this.analytics.anonymous_id
51 };
52 }
53 }
54 loadBotCredentials() {
55 try {
56 var credentials = JSON.parse(fs.readFileSync(this.botCredentialsPath, 'utf8'));
57 }
58 catch (e) { }
59 if (credentials) {
60 if (credentials.hasOwnProperty('bot')) {
61 this.bot = credentials.bot;
62 this.lastBuildHash = credentials.lastBuildHash;
63 }
64 else {
65 // Allow users < v0.1.12 to upgrade smoothly
66 this.bot = credentials;
67 this.lastBuildHash = '';
68 }
69 }
70 }
71 async checkGlobalCredentialsPath() {
72 if (!fs.existsSync(this.globalConfigPath))
73 fs.mkdirSync(this.globalConfigPath);
74 }
75 async saveGlobalCredentials() {
76 await this.checkGlobalCredentialsPath();
77 fs.writeFileSync(this.globalCredentialsPath, JSON.stringify({
78 oauth: this.oauth,
79 me: this.me,
80 analytics: this.analytics
81 }));
82 }
83 saveBotCredentials() {
84 let bc = { bot: this.bot, lastBuildHash: this.lastBuildHash };
85 fs.writeFileSync(this.botCredentialsPath, JSON.stringify(bc));
86 }
87 async getCurrentBuildHash() {
88 const options = {
89 folders: { exclude: ['.*', 'node_modules', 'dist'] },
90 files: {
91 include: [
92 '*.js',
93 '*.jsx',
94 '*.ts',
95 '*.tsx',
96 '*.css',
97 '*.scss',
98 'webpack.config.js',
99 '.babelrc',
100 'tsconfig.json'
101 ]
102 }
103 };
104 let hash = await hashElement('.', options);
105 return hash.hash;
106 }
107 async build(npmCommand = 'build') {
108 let spinner = new ora({
109 text: 'Building...',
110 spinner: 'bouncingBar'
111 }).start();
112 try {
113 var build_out = await exec(`npm run ${npmCommand}`);
114 }
115 catch (error) {
116 spinner.fail();
117 console.log(`${error.stdout}` + colors.red(`\n\nBuild error:\n${error}`));
118 return false;
119 }
120 spinner.succeed();
121 return true;
122 }
123 async buildIfChanged(force, npmCommand) {
124 let hash = await this.getCurrentBuildHash();
125 if (force || hash != this.lastBuildHash) {
126 this.lastBuildHash = hash;
127 return await this.build(npmCommand);
128 }
129 return true;
130 }
131 setCurrentBot(bot) {
132 this.bot = bot;
133 }
134 logout() {
135 if (fs.existsSync(this.globalCredentialsPath))
136 fs.unlinkSync(this.globalCredentialsPath);
137 }
138 async api(path, body = null, method = 'get', headers = null, params = null) {
139 var b = 0;
140 try {
141 return await axios_1.default({
142 method: method,
143 url: this.baseApiUrl + path,
144 headers: headers || this.headers,
145 data: body,
146 params: params
147 });
148 }
149 catch (e) {
150 if (e.response.status == 401) {
151 b = 1;
152 }
153 else {
154 return e;
155 }
156 }
157 if (b == 1) {
158 await this.refreshToken();
159 }
160 return await axios_1.default({
161 method: method,
162 url: this.baseApiUrl + path,
163 headers: headers || this.headers,
164 data: body,
165 params: params
166 });
167 }
168 async refreshToken() {
169 let resp = await axios_1.default({
170 method: 'post',
171 url: this.loginUrl,
172 params: {
173 callback: 'none',
174 grant_type: 'refresh_token',
175 refresh_token: this.oauth.refresh_token,
176 client_id: this.cliendId,
177 client_secret: this.clientSecret
178 }
179 });
180 if (!resp)
181 return;
182 this.oauth = resp.data;
183 this.headers = {
184 Authorization: `Bearer ${this.oauth.access_token}`,
185 'content-type': 'application/json',
186 'x-segment-anonymous-id': this.analytics.anonymous_id
187 };
188 await this.saveGlobalCredentials();
189 return resp;
190 }
191 async login(email, password) {
192 let resp = await axios_1.default({
193 method: 'post',
194 url: this.loginUrl,
195 params: {
196 username: email,
197 password: password,
198 client_id: this.cliendId,
199 client_secret: this.clientSecret,
200 grant_type: 'password'
201 }
202 });
203 this.oauth = resp.data;
204 this.headers = {
205 Authorization: `Bearer ${this.oauth.access_token}`,
206 'content-type': 'application/json',
207 'x-segment-anonymous-id': this.analytics.anonymous_id
208 };
209 resp = await this.api('users/me');
210 if (resp)
211 this.me = resp.data;
212 return resp;
213 }
214 signup(email, password, org_name, campaign) {
215 let url = `${this.baseApiUrl}users/`;
216 let signup_data = { email, password, org_name, campaign };
217 return axios_1.default({ method: 'post', url: url, data: signup_data });
218 }
219 async saveBot(bot_name) {
220 let resp = await this.api('bots/', { name: bot_name, framework: 'framework_botonic' }, 'post');
221 if (resp.data)
222 this.setCurrentBot(resp.data);
223 return resp;
224 }
225 async getMe() {
226 return this.api('users/me/');
227 }
228 async getBots() {
229 return this.api('bots/bots_paginator/', null, 'get', null, {
230 organization_id: this.me.organization_id
231 });
232 }
233 async getMoreBots(bots, nextBots) {
234 if (!nextBots)
235 return bots;
236 let resp = await this.api(nextBots.split(this.baseApiUrl)[1], null, 'get', null);
237 resp.data.results.map(b => bots.push(b));
238 nextBots = resp.data.next;
239 return this.getMoreBots(bots, nextBots);
240 }
241 async getProviders() {
242 return this.api('provider_accounts/', null, 'get', null, {
243 bot_id: this.bot.id
244 });
245 }
246 async deployBot(bundlePath, forceDeploy) {
247 try {
248 let a = await this.getMe();
249 }
250 catch (e) {
251 console.log(`Error deploying: ${e}`);
252 }
253 const form = new FormData();
254 let data = fs.createReadStream(bundlePath);
255 form.append('bundle', data, 'botonic_bundle.zip');
256 let headers = await this.getHeaders(form);
257 return await this.api(`bots/${this.bot.id}/deploy_botonic_new/`, form, 'post', Object.assign(Object.assign({}, this.headers), headers), { forceDeploy: forceDeploy, version: '0.7' });
258 }
259 async deployStatus(deploy_id) {
260 return this.api(`bots/${this.bot.id}/deploy_botonic_status/`, null, 'get', null, { deploy_id });
261 }
262 async getHeaders(form) {
263 //https://github.com/axios/axios/issues/1006#issuecomment-352071490
264 return new Promise((resolve, reject) => {
265 form.getLength((err, length) => {
266 if (err) {
267 reject(err);
268 }
269 let headers = Object.assign({ 'Content-Length': length }, form.getHeaders());
270 resolve(headers);
271 });
272 });
273 }
274}
275exports.BotonicAPIService = BotonicAPIService;
276//# sourceMappingURL=botonicAPIService.js.map
\No newline at end of file