bdy 1.16.19-dev → 1.16.22-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/distTs/package.json +2 -2
  2. package/distTs/src/api/client.js +294 -62
  3. package/distTs/src/command/login.js +25 -14
  4. package/distTs/src/command/logout.js +18 -0
  5. package/distTs/src/command/package/download.js +1 -3
  6. package/distTs/src/command/package/list.js +1 -3
  7. package/distTs/src/command/package/publish.js +1 -3
  8. package/distTs/src/command/pipeline/run.js +1 -3
  9. package/distTs/src/command/project/list.js +1 -3
  10. package/distTs/src/command/project/set.js +1 -3
  11. package/distTs/src/command/sandbox/cp.js +1 -3
  12. package/distTs/src/command/sandbox/create.js +1 -3
  13. package/distTs/src/command/sandbox/destroy.js +1 -3
  14. package/distTs/src/command/sandbox/endpoint/add.js +1 -3
  15. package/distTs/src/command/sandbox/endpoint/delete.js +4 -4
  16. package/distTs/src/command/sandbox/endpoint/get.js +1 -3
  17. package/distTs/src/command/sandbox/endpoint/list.js +1 -3
  18. package/distTs/src/command/sandbox/exec/command.js +1 -3
  19. package/distTs/src/command/sandbox/exec/kill.js +1 -3
  20. package/distTs/src/command/sandbox/exec/list.js +1 -3
  21. package/distTs/src/command/sandbox/exec/logs.js +1 -3
  22. package/distTs/src/command/sandbox/exec/status.js +1 -3
  23. package/distTs/src/command/sandbox/get.js +5 -4
  24. package/distTs/src/command/sandbox/list.js +1 -3
  25. package/distTs/src/command/sandbox/restart.js +1 -3
  26. package/distTs/src/command/sandbox/snapshot/create.js +1 -3
  27. package/distTs/src/command/sandbox/snapshot/delete.js +1 -3
  28. package/distTs/src/command/sandbox/snapshot/get.js +5 -4
  29. package/distTs/src/command/sandbox/snapshot/list.js +1 -3
  30. package/distTs/src/command/sandbox/start.js +1 -3
  31. package/distTs/src/command/sandbox/status.js +2 -4
  32. package/distTs/src/command/sandbox/stop.js +1 -3
  33. package/distTs/src/command/whoami.js +6 -5
  34. package/distTs/src/command/workspace/list.js +1 -3
  35. package/distTs/src/command/workspace/set.js +1 -3
  36. package/distTs/src/input.js +16 -2
  37. package/distTs/src/output.js +3 -0
  38. package/distTs/src/texts.js +58 -22
  39. package/distTs/src/tunnel/cfg.js +24 -5
  40. package/distTs/src/visualTest/server.js +1 -0
  41. package/package.json +2 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bdy",
3
3
  "preferGlobal": false,
4
- "version": "1.16.19-dev",
4
+ "version": "1.16.22-dev",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
7
7
  "scripts": {
@@ -51,7 +51,7 @@
51
51
  "ssh2": "1.15.0",
52
52
  "tar-stream": "3.1.7",
53
53
  "terminal-kit": "3.1.1",
54
- "undici": "6.21.2",
54
+ "undici": "6.23.0",
55
55
  "uuid": "10.0.0",
56
56
  "which": "4.0.0",
57
57
  "ws": "8.18.0",
@@ -8,23 +8,62 @@ const texts_1 = require("../texts");
8
8
  const logger_1 = __importDefault(require("../logger"));
9
9
  const utils_1 = require("../utils");
10
10
  const node_fs_1 = __importDefault(require("node:fs"));
11
+ const cfg_1 = __importDefault(require("../tunnel/cfg"));
11
12
  class ApiClient {
12
13
  client;
13
14
  token;
15
+ refreshToken;
16
+ clientId;
17
+ clientSecret;
18
+ clientToken;
14
19
  baseUrl;
15
- constructor(baseUrl, token) {
20
+ constructor(baseUrl, token, refreshToken, clientId, clientSecret, clientToken) {
16
21
  this.baseUrl = baseUrl;
17
22
  this.token = token;
23
+ this.refreshToken = refreshToken;
24
+ this.clientId = clientId;
25
+ this.clientSecret = clientSecret;
26
+ this.clientToken = clientToken;
18
27
  this.client = new undici_1.Pool(baseUrl, {
19
28
  connect: {
20
29
  rejectUnauthorized: false,
21
30
  },
22
31
  });
23
32
  }
24
- async request(method, path, body, parseResponseBody = false, rawResponseBody = false, httpUrlEncoded = false) {
25
- const headers = {};
26
- if (this.token)
33
+ async tryRefreshToken() {
34
+ try {
35
+ const data = await this.request({
36
+ method: 'POST',
37
+ path: '/oauth2/token',
38
+ body: {
39
+ refresh_token: this.refreshToken,
40
+ client_id: this.clientId,
41
+ client_secret: this.clientSecret,
42
+ grant_type: 'refresh_token',
43
+ },
44
+ parseResponseBody: true,
45
+ httpUrlEncoded: true,
46
+ tryRefreshingToken: false,
47
+ });
48
+ if (data && data.access_token && data.refresh_token) {
49
+ this.token = data.access_token;
50
+ this.refreshToken = data.refresh_token;
51
+ cfg_1.default.setApiToken(this.token);
52
+ cfg_1.default.setApiRefreshToken(this.refreshToken);
53
+ return true;
54
+ }
55
+ }
56
+ catch {
57
+ // do nothing
58
+ }
59
+ return false;
60
+ }
61
+ async request({ method = 'GET', path, body = null, headers = {}, parseResponseBody = false, rawResponseBody = false, httpUrlEncoded = false, tryRefreshingToken = true, }) {
62
+ if (!headers)
63
+ headers = {};
64
+ if (this.token && !headers.authorization) {
27
65
  headers.authorization = `Bearer ${this.token}`;
66
+ }
28
67
  let bodyParsed = undefined;
29
68
  if (body) {
30
69
  if (body instanceof undici_1.FormData) {
@@ -32,11 +71,15 @@ class ApiClient {
32
71
  }
33
72
  else {
34
73
  if (httpUrlEncoded) {
35
- headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8';
74
+ if (!headers['content-type']) {
75
+ headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8';
76
+ }
36
77
  bodyParsed = new URLSearchParams(body).toString();
37
78
  }
38
79
  else {
39
- headers['content-type'] = 'application/json; charset=utf-8';
80
+ if (!headers['content-type']) {
81
+ headers['content-type'] = 'application/json; charset=utf-8';
82
+ }
40
83
  bodyParsed = JSON.stringify(body);
41
84
  }
42
85
  }
@@ -68,6 +111,24 @@ class ApiClient {
68
111
  }
69
112
  if (status === 401) {
70
113
  await responseBody.dump();
114
+ if (this.refreshToken &&
115
+ this.clientId &&
116
+ this.clientSecret &&
117
+ tryRefreshingToken) {
118
+ const success = await this.tryRefreshToken();
119
+ if (success) {
120
+ return await this.request({
121
+ method,
122
+ path,
123
+ body,
124
+ headers,
125
+ parseResponseBody,
126
+ rawResponseBody,
127
+ httpUrlEncoded,
128
+ tryRefreshingToken: false,
129
+ });
130
+ }
131
+ }
71
132
  throw new Error(texts_1.ERR_REST_API_WRONG_TOKEN);
72
133
  }
73
134
  if (status === 403) {
@@ -82,7 +143,7 @@ class ApiClient {
82
143
  throw new Error(texts_1.ERR_REST_API_RATE_LIMIT);
83
144
  }
84
145
  if (json.errors && json.errors[0] && json.errors[0].message) {
85
- throw new Error(json.errors[0].message);
146
+ throw new Error((0, texts_1.ERR_API_MESSAGE_REPLACER)(json.errors[0].message, path, this.baseUrl));
86
147
  }
87
148
  throw new Error(texts_1.ERR_REST_API_RATE_LIMIT);
88
149
  }
@@ -100,7 +161,7 @@ class ApiClient {
100
161
  logger_1.default.debug('API CLIENT PARSED RESPONSE:');
101
162
  logger_1.default.debug(json);
102
163
  if (json.errors && json.errors[0] && json.errors[0].message) {
103
- throw new Error(json.errors[0].message);
164
+ throw new Error((0, texts_1.ERR_API_MESSAGE_REPLACER)(json.errors[0].message, path, this.baseUrl));
104
165
  }
105
166
  if (status === 404)
106
167
  throw new Error(texts_1.ERR_REST_API_RESOURCE_NOT_FOUND);
@@ -133,106 +194,231 @@ class ApiClient {
133
194
  await responseBody.dump();
134
195
  return null;
135
196
  }
197
+ else if (status === 503) {
198
+ throw new Error(texts_1.ERR_REST_API_NOT_RESPONDING);
199
+ }
136
200
  else {
137
201
  await responseBody.dump();
138
202
  throw new Error(texts_1.ERR_REST_API_GENERAL_ERROR);
139
203
  }
140
204
  }
141
205
  async getPipelineRun(workspace, project, pipelineId, executionId) {
142
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/projects/${encodeURIComponent(project)}/pipelines/${encodeURIComponent(pipelineId)}/executions/${encodeURIComponent(executionId)}`, null, true);
206
+ return await this.request({
207
+ method: 'GET',
208
+ path: `/workspaces/${encodeURIComponent(workspace)}/projects/${encodeURIComponent(project)}/pipelines/${encodeURIComponent(pipelineId)}/executions/${encodeURIComponent(executionId)}`,
209
+ parseResponseBody: true,
210
+ });
143
211
  }
144
212
  async getInvoker() {
145
- return await this.request('GET', '/user', null, true);
213
+ return await this.request({
214
+ method: 'GET',
215
+ path: '/user',
216
+ parseResponseBody: true,
217
+ });
146
218
  }
147
219
  async getInvokerEmails() {
148
- return await this.request('GET', '/user/emails', null, true);
220
+ return await this.request({
221
+ method: 'GET',
222
+ path: '/user/emails',
223
+ parseResponseBody: true,
224
+ });
149
225
  }
150
226
  async postPipelineRun(workspace, project, pipelineId, body) {
151
- return await this.request('POST', `/workspaces/${encodeURIComponent(workspace)}/projects/${encodeURIComponent(project)}/pipelines/${encodeURIComponent(pipelineId)}/executions`, body, true);
227
+ return await this.request({
228
+ method: 'POST',
229
+ path: `/workspaces/${encodeURIComponent(workspace)}/projects/${encodeURIComponent(project)}/pipelines/${encodeURIComponent(pipelineId)}/executions`,
230
+ body,
231
+ parseResponseBody: true,
232
+ });
152
233
  }
153
234
  // Sandbox methods
154
235
  async createSandbox(workspace, project, body) {
155
- return await this.request('POST', `/workspaces/${encodeURIComponent(workspace)}/sandboxes?project_name=${encodeURIComponent(project)}`, body, true);
236
+ return await this.request({
237
+ method: 'POST',
238
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes?project_name=${encodeURIComponent(project)}`,
239
+ body,
240
+ parseResponseBody: true,
241
+ });
156
242
  }
157
243
  async sandboxUploadFile(workspace, sandboxId, remotePath, localPath) {
158
244
  const formData = new undici_1.FormData();
159
245
  const file = await node_fs_1.default.openAsBlob(localPath);
160
246
  formData.set('file', file);
161
- return await this.request('POST', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/content/upload${remotePath}`, formData, true);
247
+ return await this.request({
248
+ method: 'POST',
249
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/content/upload${remotePath}`,
250
+ body: formData,
251
+ parseResponseBody: true,
252
+ });
162
253
  }
163
254
  async listSandboxes(workspace, project) {
164
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/sandboxes?project_name=${encodeURIComponent(project)}`, null, true);
255
+ return await this.request({
256
+ method: 'GET',
257
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes?project_name=${encodeURIComponent(project)}`,
258
+ parseResponseBody: true,
259
+ });
165
260
  }
166
261
  async getSandbox(workspace, sandboxId) {
167
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}`, null, true);
262
+ return await this.request({
263
+ method: 'GET',
264
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}`,
265
+ parseResponseBody: true,
266
+ });
168
267
  }
169
268
  async deleteSandbox(workspace, sandboxId) {
170
- return await this.request('DELETE', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}`, null, false);
269
+ return await this.request({
270
+ method: 'DELETE',
271
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}`,
272
+ parseResponseBody: false,
273
+ });
171
274
  }
172
275
  async updateSandbox(workspace, sandboxId, body) {
173
- return await this.request('PATCH', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}`, body, true);
276
+ return await this.request({
277
+ method: 'PATCH',
278
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}`,
279
+ body,
280
+ parseResponseBody: true,
281
+ });
174
282
  }
175
283
  async startSandbox(workspace, sandboxId) {
176
- return await this.request('POST', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/start`, {}, true);
284
+ return await this.request({
285
+ method: 'POST',
286
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/start`,
287
+ parseResponseBody: true,
288
+ });
177
289
  }
178
290
  async stopSandbox(workspace, sandboxId) {
179
- return await this.request('POST', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/stop`, {}, true);
291
+ return await this.request({
292
+ method: 'POST',
293
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/stop`,
294
+ parseResponseBody: true,
295
+ });
180
296
  }
181
297
  async registerApp(name, redirectUrl) {
182
- return await this.request('POST', '/auth/register', {
183
- redirect_uris: [redirectUrl],
184
- client_name: name,
185
- grant_types: ['authorization_code', 'refresh_token'],
186
- response_types: ['code'],
187
- token_endpoint_auth_method: "client_secret_basic",
188
- token_expires_in: 3600
189
- }, true);
298
+ return await this.request({
299
+ method: 'POST',
300
+ path: '/auth/register',
301
+ body: {
302
+ redirect_uris: [redirectUrl],
303
+ client_name: name,
304
+ grant_types: ['authorization_code', 'refresh_token'],
305
+ response_types: ['code'],
306
+ token_endpoint_auth_method: 'client_secret_basic',
307
+ token_expires_in: 3600,
308
+ },
309
+ parseResponseBody: true,
310
+ });
190
311
  }
191
312
  async getApp(clientId) {
192
- return await this.request('GET', `/auth/register/${encodeURIComponent(clientId)}`, null, true);
313
+ return await this.request({
314
+ method: 'GET',
315
+ path: `/auth/register/${encodeURIComponent(clientId)}`,
316
+ headers: {
317
+ authorization: `Bearer ${this.clientToken || ''}`,
318
+ },
319
+ parseResponseBody: true,
320
+ });
321
+ }
322
+ async deleteApp(clientId) {
323
+ return await this.request({
324
+ method: 'DELETE',
325
+ path: `/auth/register/${encodeURIComponent(clientId)}`,
326
+ headers: {
327
+ authorization: `Bearer ${this.clientToken || ''}`,
328
+ },
329
+ parseResponseBody: true,
330
+ });
193
331
  }
194
332
  async exchangeAppToken(code, clientId, clientSecret, redirectUrl) {
195
- return await this.request('POST', '/oauth2/token', {
196
- grant_type: 'authorization_code',
197
- code,
198
- client_id: clientId,
199
- client_secret: clientSecret,
200
- redirect_uri: redirectUrl
201
- }, true, false, true);
333
+ return await this.request({
334
+ method: 'POST',
335
+ path: '/oauth2/token',
336
+ body: {
337
+ grant_type: 'authorization_code',
338
+ code,
339
+ client_id: clientId,
340
+ client_secret: clientSecret,
341
+ redirect_uri: redirectUrl,
342
+ },
343
+ parseResponseBody: true,
344
+ httpUrlEncoded: true,
345
+ });
202
346
  }
203
347
  async restartSandbox(workspace, sandboxId) {
204
- return await this.request('POST', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/restart`, {}, true);
348
+ return await this.request({
349
+ method: 'POST',
350
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/restart`,
351
+ parseResponseBody: true,
352
+ });
205
353
  }
206
354
  async executeSandboxCommand(workspace, sandboxId, body) {
207
- return await this.request('POST', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/commands`, body, true);
355
+ return await this.request({
356
+ method: 'POST',
357
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/commands`,
358
+ body,
359
+ parseResponseBody: true,
360
+ });
208
361
  }
209
362
  async getSandboxCommand(workspace, sandboxId, commandId) {
210
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/commands/${encodeURIComponent(commandId)}`, null, true);
363
+ return await this.request({
364
+ method: 'GET',
365
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/commands/${encodeURIComponent(commandId)}`,
366
+ parseResponseBody: true,
367
+ });
211
368
  }
212
369
  async listSandboxCommands(workspace, sandboxId) {
213
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/commands`, null, true);
370
+ return await this.request({
371
+ method: 'GET',
372
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/commands`,
373
+ parseResponseBody: true,
374
+ });
214
375
  }
215
376
  async streamSandboxCommandLogs(workspace, sandboxId, commandId, follow = true) {
216
377
  let q = '';
217
378
  if (follow)
218
379
  q = '?follow=true';
219
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/commands/${encodeURIComponent(commandId)}/logs${q}`, null, false, true);
380
+ return await this.request({
381
+ method: 'GET',
382
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/commands/${encodeURIComponent(commandId)}/logs${q}`,
383
+ parseResponseBody: false,
384
+ rawResponseBody: true,
385
+ });
220
386
  }
221
387
  async terminateSandboxCommand(workspace, sandboxId, commandId) {
222
- return await this.request('POST', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/commands/${encodeURIComponent(commandId)}/terminate`, {}, true);
388
+ return await this.request({
389
+ method: 'POST',
390
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/commands/${encodeURIComponent(commandId)}/terminate`,
391
+ parseResponseBody: true,
392
+ });
223
393
  }
224
394
  // Snapshot methods
225
395
  async listSandboxSnapshots(workspace, sandboxId) {
226
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/snapshots`, null, true);
396
+ return await this.request({
397
+ method: 'GET',
398
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/snapshots`,
399
+ parseResponseBody: true,
400
+ });
227
401
  }
228
402
  async createSandboxSnapshot(workspace, sandboxId, body) {
229
- return await this.request('POST', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/snapshots`, body, true);
403
+ return await this.request({
404
+ method: 'POST',
405
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/snapshots`,
406
+ body,
407
+ parseResponseBody: true,
408
+ });
230
409
  }
231
410
  async getSandboxSnapshot(workspace, sandboxId, snapshotId) {
232
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/snapshots/${encodeURIComponent(snapshotId)}`, null, true);
411
+ return await this.request({
412
+ method: 'GET',
413
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/snapshots/${encodeURIComponent(snapshotId)}`,
414
+ parseResponseBody: true,
415
+ });
233
416
  }
234
417
  async deleteSandboxSnapshot(workspace, sandboxId, snapshotId) {
235
- return await this.request('DELETE', `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/snapshots/${encodeURIComponent(snapshotId)}`, null, false);
418
+ return await this.request({
419
+ method: 'DELETE',
420
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/snapshots/${encodeURIComponent(snapshotId)}`,
421
+ });
236
422
  }
237
423
  async sandboxWaitForSnapshot(workspace, sandboxId, snapshotId, timeout = 300) {
238
424
  const end = Date.now() + timeout * 1000;
@@ -303,16 +489,28 @@ class ApiClient {
303
489
  }
304
490
  }
305
491
  async getWorkspaces() {
306
- return await this.request('GET', '/workspaces', null, true);
492
+ return await this.request({
493
+ method: 'GET',
494
+ path: '/workspaces',
495
+ parseResponseBody: true,
496
+ });
307
497
  }
308
498
  async getPackages(workspace, project) {
309
499
  let query = '';
310
500
  if (project)
311
501
  query += `?project_name=${encodeURIComponent(project)}`;
312
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/packages${query}`, null, true);
502
+ return await this.request({
503
+ method: 'GET',
504
+ path: `/workspaces/${encodeURIComponent(workspace)}/packages${query}`,
505
+ parseResponseBody: true,
506
+ });
313
507
  }
314
508
  async getProjects(workspace) {
315
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/projects`, null, true);
509
+ return await this.request({
510
+ method: 'GET',
511
+ path: `/workspaces/${encodeURIComponent(workspace)}/projects`,
512
+ parseResponseBody: true,
513
+ });
316
514
  }
317
515
  async getResourceByIdentifier(workspace, params) {
318
516
  let query = '';
@@ -323,10 +521,17 @@ class ApiClient {
323
521
  query += '&';
324
522
  query += encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
325
523
  });
326
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/identifiers${query}`, null, true);
524
+ return await this.request({
525
+ method: 'GET',
526
+ path: `/workspaces/${encodeURIComponent(workspace)}/identifiers${query}`,
527
+ parseResponseBody: true,
528
+ });
327
529
  }
328
530
  async getPipelineByIdentifier(workspace, project, identifier) {
329
- return await this.getResourceByIdentifier(workspace, { project, pipeline: identifier });
531
+ return await this.getResourceByIdentifier(workspace, {
532
+ project,
533
+ pipeline: identifier,
534
+ });
330
535
  }
331
536
  async getPackageVersionByIdentifier(workspace, project, pkg, version) {
332
537
  const opts = {
@@ -339,27 +544,49 @@ class ApiClient {
339
544
  return await this.getResourceByIdentifier(workspace, opts);
340
545
  }
341
546
  async getPackageVersion(workspace, pkgId, versionId) {
342
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(pkgId)}/versions/${encodeURIComponent(versionId)}`, null, true);
547
+ return await this.request({
548
+ method: 'GET',
549
+ path: `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(pkgId)}/versions/${encodeURIComponent(versionId)}`,
550
+ parseResponseBody: true,
551
+ });
343
552
  }
344
553
  async getPackageLatest(workspace, pkgId) {
345
- const res = await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(pkgId)}/versions?page=1&per_page=1`, null, true);
554
+ const res = await this.request({
555
+ method: 'GET',
556
+ path: `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(pkgId)}/versions?page=1&per_page=1`,
557
+ parseResponseBody: true,
558
+ });
346
559
  if (res && res.versions && res.versions.length > 0) {
347
560
  return res.versions[0];
348
561
  }
349
562
  return null;
350
563
  }
351
564
  async downloadPackageVersion(workspace, pkgId, versionId) {
352
- return await this.request('GET', `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(pkgId)}/versions/${encodeURIComponent(versionId)}/download`, null, false, true);
565
+ return await this.request({
566
+ method: 'GET',
567
+ path: `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(pkgId)}/versions/${encodeURIComponent(versionId)}/download`,
568
+ rawResponseBody: true,
569
+ });
353
570
  }
354
571
  async postPackageVersion(workspace, pkgId, version) {
355
- return await this.request('POST', `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(pkgId)}/versions`, {
356
- version
357
- }, true);
572
+ return await this.request({
573
+ method: 'POST',
574
+ path: `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(pkgId)}/versions`,
575
+ body: {
576
+ version,
577
+ },
578
+ parseResponseBody: true,
579
+ });
358
580
  }
359
581
  async postPackageVersionZip(workspace, pkgId, versionId, file) {
360
582
  const form = new undici_1.FormData();
361
583
  form.append('file', file);
362
- return await this.request('POST', `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(pkgId)}/versions/${versionId}/upload`, form, true);
584
+ return await this.request({
585
+ method: 'POST',
586
+ path: `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(pkgId)}/versions/${versionId}/upload`,
587
+ body: form,
588
+ parseResponseBody: true,
589
+ });
363
590
  }
364
591
  async postPackage(workspace, project, identifier) {
365
592
  const body = {
@@ -368,16 +595,21 @@ class ApiClient {
368
595
  type: 'FILE',
369
596
  scope: 'WORKSPACE',
370
597
  authorization: {
371
- type: 'BUDDY'
372
- }
598
+ type: 'BUDDY',
599
+ },
373
600
  };
374
601
  if (project) {
375
602
  body.project = {
376
- name: project
603
+ name: project,
377
604
  };
378
605
  body.scope = 'PROJECT';
379
606
  }
380
- return await this.request('POST', `/workspaces/${encodeURIComponent(workspace)}/packages`, body, true);
607
+ return await this.request({
608
+ method: 'POST',
609
+ path: `/workspaces/${encodeURIComponent(workspace)}/packages`,
610
+ body,
611
+ parseResponseBody: true,
612
+ });
381
613
  }
382
614
  }
383
615
  exports.default = ApiClient;
@@ -62,7 +62,10 @@ async function oauthServer(api, clientId, clientSecret) {
62
62
  const response = await client.exchangeAppToken(urlCode, clientId, clientSecret, OAUTH_CLIENT_APP_REDIRECT_URL);
63
63
  res.end(texts_1.ERR_LOGIN_HTTP_SUCCESS);
64
64
  s.close();
65
- resolve(response.access_token);
65
+ resolve({
66
+ token: response.access_token,
67
+ refreshToken: response.refresh_token,
68
+ });
66
69
  }
67
70
  catch {
68
71
  res.end(texts_1.ERR_LOGIN_HTTP_FAILED);
@@ -84,11 +87,14 @@ async function getOrCreateApp(api) {
84
87
  const client = new client_1.default(new URL(`https://${api}`));
85
88
  let clientId = cfg_1.default.getApiClientId();
86
89
  let clientSecret = cfg_1.default.getApiClientSecret();
87
- if (clientId && clientSecret) {
90
+ let clientToken = cfg_1.default.getApiClientToken();
91
+ if (clientId && clientSecret && clientToken) {
88
92
  let clear = false;
89
93
  try {
90
94
  const app = await client.getApp(clientId);
91
- if (!app || !app.redirect_uris || !app.redirect_uris.includes(OAUTH_CLIENT_APP_REDIRECT_URL)) {
95
+ if (!app ||
96
+ !app.redirect_uris ||
97
+ !app.redirect_uris.includes(OAUTH_CLIENT_APP_REDIRECT_URL)) {
92
98
  clear = true;
93
99
  }
94
100
  }
@@ -98,25 +104,31 @@ async function getOrCreateApp(api) {
98
104
  if (clear) {
99
105
  clientId = null;
100
106
  clientSecret = null;
107
+ clientToken = null;
101
108
  }
102
109
  }
103
- if (!clientId || !clientSecret) {
104
- const app = await client.registerApp('bdy cli app', OAUTH_CLIENT_APP_REDIRECT_URL);
110
+ if (!clientId || !clientSecret || !clientToken) {
111
+ const app = await client.registerApp('Buddy CLI', OAUTH_CLIENT_APP_REDIRECT_URL);
105
112
  clientId = app.client_id;
106
113
  clientSecret = app.client_secret;
107
- cfg_1.default.setApiClient(clientId, clientSecret);
114
+ clientToken = app.registration_access_token;
115
+ cfg_1.default.setApiClient(clientId, clientSecret, clientToken);
108
116
  }
109
117
  return {
110
118
  clientId,
111
119
  clientSecret,
120
+ clientToken,
112
121
  };
113
122
  }
114
123
  async function authorizeOAuth(api) {
115
- const { clientId, clientSecret } = await getOrCreateApp(api);
116
- return await oauthServer(api, clientId, clientSecret);
124
+ const { clientId, clientSecret, clientToken } = await getOrCreateApp(api);
125
+ const { token, refreshToken } = await oauthServer(api, clientId, clientSecret);
126
+ return { token, refreshToken, clientId, clientSecret, clientToken };
117
127
  }
118
- async function authorizeToken(api, token, workspace, project) {
119
- const client = new client_1.default(new URL(`https://${api}`), token);
128
+ async function authorizeToken(api, token, refreshToken, clientId, clientSecret, clientToken, workspace, project) {
129
+ cfg_1.default.setApiToken(token);
130
+ cfg_1.default.setApiRefreshToken(refreshToken);
131
+ const client = new client_1.default(new URL(`https://${api}`), token, refreshToken, clientId, clientSecret, clientToken);
120
132
  const w = await client.getWorkspaces();
121
133
  if (!w.workspaces?.length) {
122
134
  output_1.default.exitError(texts_1.ERR_LOGIN_NO_WORKSPACES);
@@ -130,7 +142,6 @@ async function authorizeToken(api, token, workspace, project) {
130
142
  else {
131
143
  workspace = await output_1.default.selectWorkspace(w.workspaces);
132
144
  }
133
- cfg_1.default.setApiToken(token);
134
145
  cfg_1.default.setWorkspace(workspace);
135
146
  const p = await client.getProjects(workspace);
136
147
  if (project) {
@@ -185,11 +196,11 @@ commandLogin.action(async (options) => {
185
196
  cfg_1.default.setBaseUrl(api);
186
197
  if (!token) {
187
198
  output_1.default.normal(texts_1.TXT_LOGIN_OAUTH);
188
- const token = await authorizeOAuth(api);
189
- await authorizeToken(api, token, workspace, project);
199
+ const { token, refreshToken, clientId, clientSecret, clientToken } = await authorizeOAuth(api);
200
+ await authorizeToken(api, token, refreshToken, clientId, clientSecret, clientToken, workspace, project);
190
201
  }
191
202
  else {
192
- await authorizeToken(api, token, workspace, project);
203
+ await authorizeToken(api, token, '', '', '', '', workspace, project);
193
204
  }
194
205
  });
195
206
  exports.default = commandLogin;
@@ -7,8 +7,26 @@ const cfg_1 = __importDefault(require("../tunnel/cfg"));
7
7
  const output_1 = __importDefault(require("../output"));
8
8
  const texts_1 = require("../texts");
9
9
  const utils_1 = require("../utils");
10
+ const client_1 = __importDefault(require("../api/client"));
11
+ const input_1 = __importDefault(require("../input"));
10
12
  const commandLogout = (0, utils_1.newCommand)('logout', texts_1.DESC_COMMAND_LOGOUT);
13
+ const tryRemovingApp = async () => {
14
+ try {
15
+ const token = cfg_1.default.getApiToken();
16
+ const refreshToken = cfg_1.default.getApiRefreshApiToken();
17
+ const clientId = cfg_1.default.getApiClientId();
18
+ const clientSecret = cfg_1.default.getApiClientSecret();
19
+ const clientToken = cfg_1.default.getApiClientToken();
20
+ const baseUrl = input_1.default.restApiBaseUrl();
21
+ const client = new client_1.default(baseUrl, token, refreshToken, clientId, clientSecret, clientToken);
22
+ await client.deleteApp(clientId);
23
+ }
24
+ catch {
25
+ // do nothing
26
+ }
27
+ };
11
28
  commandLogout.action(async () => {
29
+ await tryRemovingApp();
12
30
  cfg_1.default.clearLogin();
13
31
  output_1.default.exitSuccess(texts_1.TXT_LOGOUT_SUCCESS);
14
32
  });