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.
- package/distTs/package.json +2 -2
- package/distTs/src/api/client.js +294 -62
- package/distTs/src/command/login.js +25 -14
- package/distTs/src/command/logout.js +18 -0
- package/distTs/src/command/package/download.js +1 -3
- package/distTs/src/command/package/list.js +1 -3
- package/distTs/src/command/package/publish.js +1 -3
- package/distTs/src/command/pipeline/run.js +1 -3
- package/distTs/src/command/project/list.js +1 -3
- package/distTs/src/command/project/set.js +1 -3
- package/distTs/src/command/sandbox/cp.js +1 -3
- package/distTs/src/command/sandbox/create.js +1 -3
- package/distTs/src/command/sandbox/destroy.js +1 -3
- package/distTs/src/command/sandbox/endpoint/add.js +1 -3
- package/distTs/src/command/sandbox/endpoint/delete.js +4 -4
- package/distTs/src/command/sandbox/endpoint/get.js +1 -3
- package/distTs/src/command/sandbox/endpoint/list.js +1 -3
- package/distTs/src/command/sandbox/exec/command.js +1 -3
- package/distTs/src/command/sandbox/exec/kill.js +1 -3
- package/distTs/src/command/sandbox/exec/list.js +1 -3
- package/distTs/src/command/sandbox/exec/logs.js +1 -3
- package/distTs/src/command/sandbox/exec/status.js +1 -3
- package/distTs/src/command/sandbox/get.js +5 -4
- package/distTs/src/command/sandbox/list.js +1 -3
- package/distTs/src/command/sandbox/restart.js +1 -3
- package/distTs/src/command/sandbox/snapshot/create.js +1 -3
- package/distTs/src/command/sandbox/snapshot/delete.js +1 -3
- package/distTs/src/command/sandbox/snapshot/get.js +5 -4
- package/distTs/src/command/sandbox/snapshot/list.js +1 -3
- package/distTs/src/command/sandbox/start.js +1 -3
- package/distTs/src/command/sandbox/status.js +2 -4
- package/distTs/src/command/sandbox/stop.js +1 -3
- package/distTs/src/command/whoami.js +6 -5
- package/distTs/src/command/workspace/list.js +1 -3
- package/distTs/src/command/workspace/set.js +1 -3
- package/distTs/src/input.js +16 -2
- package/distTs/src/output.js +3 -0
- package/distTs/src/texts.js +58 -22
- package/distTs/src/tunnel/cfg.js +24 -5
- package/distTs/src/visualTest/server.js +1 -0
- package/package.json +2 -2
package/distTs/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bdy",
|
|
3
3
|
"preferGlobal": false,
|
|
4
|
-
"version": "1.16.
|
|
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.
|
|
54
|
+
"undici": "6.23.0",
|
|
55
55
|
"uuid": "10.0.0",
|
|
56
56
|
"which": "4.0.0",
|
|
57
57
|
"ws": "8.18.0",
|
package/distTs/src/api/client.js
CHANGED
|
@@ -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
|
|
25
|
-
|
|
26
|
-
|
|
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']
|
|
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']
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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(
|
|
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(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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, {
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
356
|
-
|
|
357
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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 ||
|
|
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('
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
});
|