bdy 1.16.28-stage → 1.16.29-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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bdy",
3
3
  "preferGlobal": false,
4
- "version": "1.16.28-stage",
4
+ "version": "1.16.29-dev",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
7
7
  "scripts": {
@@ -58,7 +58,7 @@ class ApiClient {
58
58
  }
59
59
  return false;
60
60
  }
61
- async request({ method = 'GET', path, query, body = null, headers = {}, parseResponseBody = false, rawResponseBody = false, httpUrlEncoded = false, tryRefreshingToken = true, }) {
61
+ async request({ method = 'GET', path, query, body = null, headers = {}, parseResponseBody = false, rawResponseBody = false, rawResponse = false, httpUrlEncoded = false, tryRefreshingToken = true, }) {
62
62
  if (!headers)
63
63
  headers = {};
64
64
  if (this.token && !headers.authorization) {
@@ -94,6 +94,8 @@ class ApiClient {
94
94
  };
95
95
  let status;
96
96
  let responseBody;
97
+ let response;
98
+ let rateLimitReset;
97
99
  logger_1.default.debug(`API CLIENT: ${method} ${this.baseUrl.protocol}//${this.baseUrl.host}${path}`);
98
100
  logger_1.default.debug('QUERY');
99
101
  logger_1.default.debug(query);
@@ -102,9 +104,10 @@ class ApiClient {
102
104
  logger_1.default.debug('BODY');
103
105
  logger_1.default.debug(bodyParsed);
104
106
  try {
105
- const r = await this.client.request(opts);
106
- status = r.statusCode;
107
- responseBody = r.body;
107
+ response = await this.client.request(opts);
108
+ rateLimitReset = response.headers['x-rate-limit-reset'];
109
+ status = response.statusCode;
110
+ responseBody = response.body;
108
111
  logger_1.default.debug(`API CLIENT RESPONSE STATUS: ${status}`);
109
112
  }
110
113
  catch (err) {
@@ -131,6 +134,7 @@ class ApiClient {
131
134
  headers,
132
135
  parseResponseBody,
133
136
  rawResponseBody,
137
+ rawResponse,
134
138
  httpUrlEncoded,
135
139
  tryRefreshingToken: false,
136
140
  });
@@ -147,12 +151,12 @@ class ApiClient {
147
151
  }
148
152
  catch {
149
153
  await responseBody.dump();
150
- throw new Error(texts_1.ERR_REST_API_RATE_LIMIT);
154
+ throw new Error((0, texts_1.ERR_REST_API_RATE_LIMIT)(rateLimitReset));
151
155
  }
152
156
  if (json.errors && json.errors[0] && json.errors[0].message) {
153
- throw new Error((0, texts_1.ERR_API_MESSAGE_REPLACER)(json.errors[0].message, path, this.baseUrl));
157
+ throw new Error((0, texts_1.ERR_API_MESSAGE_REPLACER)(json.errors[0].message, path, this.baseUrl, rateLimitReset));
154
158
  }
155
- throw new Error(texts_1.ERR_REST_API_RATE_LIMIT);
159
+ throw new Error((0, texts_1.ERR_REST_API_RATE_LIMIT)(rateLimitReset));
156
160
  }
157
161
  if ([400, 404].includes(status)) {
158
162
  let json;
@@ -168,7 +172,7 @@ class ApiClient {
168
172
  logger_1.default.debug('API CLIENT PARSED RESPONSE:');
169
173
  logger_1.default.debug(json);
170
174
  if (json.errors && json.errors[0] && json.errors[0].message) {
171
- throw new Error((0, texts_1.ERR_API_MESSAGE_REPLACER)(json.errors[0].message, path, this.baseUrl));
175
+ throw new Error((0, texts_1.ERR_API_MESSAGE_REPLACER)(json.errors[0].message, path, this.baseUrl, rateLimitReset));
172
176
  }
173
177
  if (status === 404)
174
178
  throw new Error(texts_1.ERR_REST_API_RESOURCE_NOT_FOUND);
@@ -189,6 +193,9 @@ class ApiClient {
189
193
  throw new Error(texts_1.ERR_REST_API_GENERAL_ERROR);
190
194
  }
191
195
  }
196
+ else if (rawResponse) {
197
+ return response;
198
+ }
192
199
  else if (rawResponseBody) {
193
200
  return responseBody;
194
201
  }
@@ -258,6 +265,13 @@ class ApiClient {
258
265
  parseResponseBody: true,
259
266
  });
260
267
  }
268
+ async sandboxDownloadFile(workspace, sandboxId, remotePath) {
269
+ return await this.request({
270
+ method: 'GET',
271
+ path: `/workspaces/${encodeURIComponent(workspace)}/sandboxes/${encodeURIComponent(sandboxId)}/download${remotePath}`,
272
+ rawResponse: true,
273
+ });
274
+ }
261
275
  async sandboxUploadFile(workspace, sandboxId, remotePath, localPath) {
262
276
  const formData = new undici_1.FormData();
263
277
  const file = await node_fs_1.default.openAsBlob(localPath);
@@ -503,23 +517,6 @@ class ApiClient {
503
517
  await this.waitSleep();
504
518
  }
505
519
  }
506
- async sandboxWaitForApp(workspace, sandboxId, timeout = 300) {
507
- const end = Date.now() + timeout * 1000;
508
- for (;;) {
509
- const sb = await this.getSandbox(workspace, sandboxId);
510
- if ([
511
- utils_1.SANDBOX_APP_STATUS.RUNNING,
512
- utils_1.SANDBOX_APP_STATUS.FAILED,
513
- utils_1.SANDBOX_APP_STATUS.ENDED,
514
- ].includes(sb.app_status)) {
515
- return sb.app_status;
516
- }
517
- if (Date.now() > end) {
518
- throw new Error('timeout');
519
- }
520
- await this.waitSleep();
521
- }
522
- }
523
520
  async getWorkspaces() {
524
521
  return await this.request({
525
522
  method: 'GET',
@@ -537,10 +534,15 @@ class ApiClient {
537
534
  parseResponseBody: true,
538
535
  });
539
536
  }
540
- async getProjects(workspace) {
537
+ async getProjects(workspace, page = 1, perPage = 100) {
538
+ const query = {
539
+ page: page.toString(),
540
+ per_page: perPage.toString(),
541
+ };
541
542
  return await this.request({
542
543
  method: 'GET',
543
544
  path: `/workspaces/${encodeURIComponent(workspace)}/projects`,
545
+ query,
544
546
  parseResponseBody: true,
545
547
  });
546
548
  }
@@ -570,7 +572,7 @@ class ApiClient {
570
572
  async deletePackageVersion(workspace, packageId, versionId) {
571
573
  return await this.request({
572
574
  method: 'DELETE',
573
- path: `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(packageId)}/versions/${encodeURIComponent(versionId)}`
575
+ path: `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(packageId)}/versions/${encodeURIComponent(versionId)}`,
574
576
  });
575
577
  }
576
578
  async getPackageVersionByIdentifier(workspace, project, pkg, version) {
@@ -589,9 +591,9 @@ class ApiClient {
589
591
  path: `/workspaces/${encodeURIComponent(workspace)}/packages/${pkgId}/versions`,
590
592
  query: {
591
593
  page: page.toString(),
592
- per_page: perPage.toString()
594
+ per_page: perPage.toString(),
593
595
  },
594
- parseResponseBody: true
596
+ parseResponseBody: true,
595
597
  });
596
598
  }
597
599
  async getPackageVersion(workspace, pkgId, versionId) {
@@ -654,11 +656,10 @@ class ApiClient {
654
656
  parseResponseBody: true,
655
657
  });
656
658
  }
657
- ;
658
659
  async deletePackage(workspace, packageId) {
659
660
  return await this.request({
660
661
  method: 'DELETE',
661
- path: `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(packageId)}`
662
+ path: `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(packageId)}`,
662
663
  });
663
664
  }
664
665
  }
@@ -7,6 +7,7 @@ const utils_1 = require("../../utils");
7
7
  const texts_1 = require("../../texts");
8
8
  const input_1 = __importDefault(require("../../input"));
9
9
  const output_1 = __importDefault(require("../../output"));
10
+ const human_id_1 = __importDefault(require("human-id"));
10
11
  const commandPackageCreate = (0, utils_1.newCommand)('create', texts_1.DESC_COMMAND_PACKAGE_CREATE);
11
12
  commandPackageCreate.alias('add');
12
13
  commandPackageCreate.option('--token <token>', texts_1.OPTION_REST_API_TOKEN);
@@ -18,13 +19,19 @@ commandPackageCreate.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJ
18
19
  commandPackageCreate.option('-t, --type <type>', texts_1.OPT_COMMAND_PACKAGE_TYPE, utils_1.PACKAGE_TYPE.FILE);
19
20
  commandPackageCreate.option('-b, --buddy', texts_1.OPTION_HTTP_AUTH_BUDDY);
20
21
  commandPackageCreate.option('-a, --auth <user:pass>', texts_1.OPTION_HTTP_AUTH);
21
- commandPackageCreate.argument('<name>', texts_1.OPT_COMMAND_PACKAGE_NAME);
22
+ commandPackageCreate.argument('[name]', texts_1.OPT_COMMAND_PACKAGE_NAME);
22
23
  commandPackageCreate.action(async (name, options) => {
23
24
  const workspace = input_1.default.restApiWorkspace(options.workspace);
24
25
  const project = input_1.default.restApiProject(options.project, true);
25
26
  const client = input_1.default.restApiTokenClient(options.api, options.region, options.token);
26
27
  const type = input_1.default.packageType(options.type);
27
28
  const scope = input_1.default.packageScope(project);
29
+ if (!name) {
30
+ if (options.identifier)
31
+ name = options.identifier;
32
+ else
33
+ name = (0, human_id_1.default)({ separator: '-', capitalize: false });
34
+ }
28
35
  const data = {
29
36
  name,
30
37
  type,
@@ -54,6 +61,6 @@ commandPackageCreate.action(async (name, options) => {
54
61
  };
55
62
  }
56
63
  const result = await client.postPackage(workspace, data);
57
- output_1.default.exitSuccess((0, texts_1.TXT_PACKAGE_CREATED)(workspace, result));
64
+ output_1.default.exitSuccess((0, texts_1.TXT_PACKAGE_CREATED)(client.baseUrl, workspace, result));
58
65
  });
59
66
  exports.default = commandPackageCreate;
@@ -11,8 +11,7 @@ const logger_1 = __importDefault(require("../../logger"));
11
11
  const path_1 = require("path");
12
12
  const uuid_1 = require("uuid");
13
13
  const fs_1 = __importDefault(require("fs"));
14
- const promises_1 = __importDefault(require("stream/promises"));
15
- const fflate_1 = require("fflate");
14
+ const promises_1 = __importDefault(require("node:stream/promises"));
16
15
  const commandPackageDownload = (0, utils_1.newCommand)('download', texts_1.DESC_COMMAND_PACKAGE_DOWNLOAD);
17
16
  commandPackageDownload.alias('dd');
18
17
  commandPackageDownload.option('-t, --token <token>', texts_1.OPTION_REST_API_TOKEN);
@@ -120,7 +119,7 @@ commandPackageDownload.action(async (id, path, options) => {
120
119
  output_1.default.normal(texts_1.TXT_PACKAGE_DOWNLOADED_ZIP);
121
120
  output_1.default.normal(texts_1.TXT_PACKAGE_UNZIPPING);
122
121
  let count = 0;
123
- await unzip(dirPath, zipPath, () => {
122
+ await (0, utils_1.unzipFile)(dirPath, zipPath, () => {
124
123
  count += 1;
125
124
  output_1.default.clearPreviousLine();
126
125
  output_1.default.normal((0, texts_1.TXT_PACKAGE_UNZIPPING_COUNT)(count));
@@ -136,121 +135,4 @@ commandPackageDownload.action(async (id, path, options) => {
136
135
  }
137
136
  output_1.default.exitSuccess((0, texts_1.TXT_PACKAGE_DOWNLOADED)(version, dirPath));
138
137
  });
139
- const unzip = (dirPath, zipPath, onFile) => {
140
- return new Promise((resolve, reject) => {
141
- let _startedFiles = 0;
142
- let _finishedFiles = 0;
143
- let _finishedStream = false;
144
- let _finishedError = null;
145
- let _calledResolve = false;
146
- const rs = fs_1.default.createReadStream(zipPath);
147
- const _finish = () => {
148
- if (_finishedError || _finishedStream) {
149
- try {
150
- rs.removeAllListeners();
151
- rs.close();
152
- }
153
- catch {
154
- // do nothing
155
- }
156
- }
157
- if (_calledResolve)
158
- return;
159
- if (_finishedError) {
160
- _calledResolve = true;
161
- reject(_finishedError);
162
- return;
163
- }
164
- if (_finishedStream && _startedFiles === _finishedFiles) {
165
- _calledResolve = true;
166
- resolve();
167
- }
168
- };
169
- const finishFile = (err, fws) => {
170
- if (!_finishedError && err)
171
- _finishedError = err;
172
- _finishedFiles += 1;
173
- if (fws) {
174
- try {
175
- fws.removeAllListeners();
176
- fws.close();
177
- }
178
- catch {
179
- // do nothing
180
- }
181
- }
182
- onFile();
183
- _finish();
184
- };
185
- const finishStream = (err) => {
186
- if (!_finishedError && err)
187
- _finishedError = err;
188
- _finishedStream = true;
189
- _finish();
190
- };
191
- const unzip = new fflate_1.Unzip(async (file) => {
192
- if (_finishedError)
193
- return;
194
- _startedFiles += 1;
195
- const fullPath = (0, path_1.join)(dirPath, file.name);
196
- const parentPath = (0, path_1.dirname)(fullPath);
197
- let fws;
198
- try {
199
- await fs_1.default.promises.rm(fullPath, {
200
- recursive: true,
201
- force: true,
202
- });
203
- }
204
- catch {
205
- // do nothing
206
- }
207
- try {
208
- if (fullPath.endsWith('/')) {
209
- await fs_1.default.promises.mkdir(fullPath, {
210
- recursive: true,
211
- });
212
- finishFile();
213
- return;
214
- }
215
- await fs_1.default.promises.mkdir(parentPath, {
216
- recursive: true,
217
- });
218
- fws = fs_1.default.createWriteStream(fullPath, {
219
- flags: 'w',
220
- });
221
- fws.on('error', (err) => {
222
- finishFile(err, fws);
223
- });
224
- }
225
- catch (err) {
226
- finishFile(err, fws);
227
- return;
228
- }
229
- file.ondata = (err, data, final) => {
230
- if (_finishedError)
231
- return;
232
- if (err)
233
- finishFile(err, fws);
234
- else {
235
- if (fws)
236
- fws.write(data);
237
- if (final)
238
- finishFile(null, fws);
239
- }
240
- };
241
- file.start();
242
- });
243
- unzip.register(fflate_1.AsyncUnzipInflate);
244
- rs.on('data', (chunk) => {
245
- unzip.push(chunk, false);
246
- });
247
- rs.on('error', (err) => {
248
- finishStream(err);
249
- });
250
- rs.on('end', () => {
251
- unzip.push(new Uint8Array(0), true);
252
- finishStream();
253
- });
254
- });
255
- };
256
138
  exports.default = commandPackageDownload;
@@ -34,6 +34,6 @@ commandSandboxGet.action(async (identifier, options) => {
34
34
  'Size': (0, utils_1.formatBytes)(pkg.size || 0),
35
35
  'Created': pkg.created_date,
36
36
  });
37
- output_1.default.exitNormal();
37
+ output_1.default.exitNormal(`\n${(0, texts_1.TXT_PACKAGE_PUBLISH)(client.baseUrl, workspace, pkg)}`);
38
38
  });
39
39
  exports.default = commandSandboxGet;
@@ -22,7 +22,7 @@ commandPackageList.action(async (options) => {
22
22
  if (!response.packages || response.packages.length === 0) {
23
23
  output_1.default.exitError(texts_1.ERR_COMMAND_PACKAGE_NO_PROJECTS);
24
24
  }
25
- const data = [['NAME', 'IDENTIFIER', 'TYPE', 'SCOPE', 'URL']];
25
+ const data = [['NAME', 'IDENTIFIER', 'TYPE', 'URL']];
26
26
  for (const pkg of response.packages) {
27
27
  if (project && pkg.scope === utils_1.PACKAGE_SCOPE.WORKSPACE)
28
28
  continue;
@@ -9,34 +9,34 @@ const output_1 = __importDefault(require("../../output"));
9
9
  const input_1 = __importDefault(require("../../input"));
10
10
  const fdir_1 = require("fdir");
11
11
  const path_1 = require("path");
12
+ const node_fs_1 = __importDefault(require("node:fs"));
13
+ const uuid_1 = require("uuid");
14
+ const promises_1 = __importDefault(require("node:stream/promises"));
12
15
  const commandSandboxCp = (0, utils_1.newCommand)('cp', texts_1.DESC_COMMAND_SANDBOX_CP);
13
16
  commandSandboxCp.option('--token <token>', texts_1.OPTION_REST_API_TOKEN);
14
17
  commandSandboxCp.option('--api <url>', texts_1.OPTION_REST_API_ENDPOINT);
15
18
  commandSandboxCp.option('--region <region>', texts_1.OPTION_REST_API_REGION);
16
19
  commandSandboxCp.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
17
20
  commandSandboxCp.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
18
- commandSandboxCp.option('-s, --silent', texts_1.OPTION_SANDBOX_CP_SILENT);
21
+ commandSandboxCp.option('-m, --merge', texts_1.OPTION_SANDBOX_CP_DOWNLOAD_MERGE);
22
+ commandSandboxCp.option('-r, --replace', texts_1.OPTION_SANDBOX_CP_DOWNLOAD_REPLACE);
19
23
  commandSandboxCp.argument('<source>', texts_1.OPTION_SANDBOX_CP_SOURCE);
20
24
  commandSandboxCp.argument('<destination>', texts_1.OPTION_SANDBOX_CP_DEST);
21
- commandSandboxCp.action(async (source, destination, options) => {
22
- const workspace = input_1.default.restApiWorkspace(options.workspace);
23
- const project = input_1.default.restApiProject(options.project);
24
- const client = input_1.default.restApiTokenClient(options.api, options.region, options.token);
25
+ const upload = async (client, workspace, project, source, destination) => {
26
+ const { sourcePath, sourceStats } = input_1.default.restApiSandboxUploadSourcePath(source);
27
+ const { identifier, remotePath } = input_1.default.restApiSandboxUploadDestinationPath(destination);
25
28
  const result = await client.listSandboxes(workspace, project);
26
29
  const sandboxes = result.sandboxes || [];
27
- const { identifier, remotePath } = input_1.default.restApiSandboxDestinationPath(destination);
28
- const { sourcePath, sourceStats } = input_1.default.restApiSandboxSourcePath(source);
29
- const silent = options.silent;
30
30
  const found = sandboxes.find((s) => s.identifier === identifier);
31
31
  if (!found) {
32
32
  output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
33
33
  }
34
34
  if (sourceStats.isFile()) {
35
35
  // Single file copy
36
- if (!silent) {
37
- output_1.default.gray((0, texts_1.TXT_SANDBOX_CP_PROGRESS)(1, 1, (0, path_1.basename)(sourcePath)));
38
- }
39
- await client.sandboxUploadFile(workspace, found.id, remotePath, sourcePath);
36
+ const name = (0, path_1.basename)(sourcePath);
37
+ output_1.default.normal((0, texts_1.TXT_SANDBOX_CP_PROGRESS)(1, 1, name));
38
+ const remoteFile = (0, path_1.join)(remotePath, name);
39
+ await client.sandboxUploadFile(workspace, found.id, remoteFile, sourcePath);
40
40
  output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(1));
41
41
  }
42
42
  else if (sourceStats.isDirectory()) {
@@ -48,15 +48,13 @@ commandSandboxCp.action(async (source, destination, options) => {
48
48
  if (files.length === 0) {
49
49
  output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(0));
50
50
  }
51
- if (!silent)
52
- output_1.default.normal(`Copying ${files.length} file(s)...`);
51
+ output_1.default.normal('\n', false);
53
52
  for (let i = 0; i < files.length; i++) {
54
53
  const localFile = files[i];
55
54
  const relativePath = (0, path_1.relative)(sourcePath, localFile);
56
55
  const remoteFile = (0, path_1.join)(remotePath, relativePath).replace(/\\/g, '/');
57
- if (!silent) {
58
- output_1.default.gray((0, texts_1.TXT_SANDBOX_CP_PROGRESS)(i + 1, files.length, relativePath));
59
- }
56
+ output_1.default.clearPreviousLine();
57
+ output_1.default.normal((0, texts_1.TXT_SANDBOX_CP_PROGRESS)(i + 1, files.length, relativePath));
60
58
  await client.sandboxUploadFile(workspace, found.id, remoteFile, localFile);
61
59
  }
62
60
  output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(files.length));
@@ -64,5 +62,68 @@ commandSandboxCp.action(async (source, destination, options) => {
64
62
  else {
65
63
  output_1.default.exitError((0, texts_1.ERR_SANDBOX_CP_SOURCE_NOT_FOUND)(source));
66
64
  }
65
+ };
66
+ const download = async (client, workspace, project, source, destination, merge, replace) => {
67
+ const destPath = input_1.default.restApiSandboxDownloadDestinationPath(destination, merge, replace);
68
+ const { sourcePath, identifier } = input_1.default.restApiSandboxDownloadSourcePath(source);
69
+ const result = await client.listSandboxes(workspace, project);
70
+ const sandboxes = result.sandboxes || [];
71
+ const found = sandboxes.find((s) => s.identifier === identifier);
72
+ if (!found) {
73
+ output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
74
+ }
75
+ output_1.default.normal(texts_1.TXT_SANDBOX_CP_DOWNLOAD, false);
76
+ const { body, headers } = await client.sandboxDownloadFile(workspace, found.id, sourcePath);
77
+ const isFile = headers['content-type'] === 'application/octet-stream';
78
+ if (isFile) {
79
+ const name = (0, path_1.basename)(sourcePath);
80
+ await node_fs_1.default.promises.writeFile((0, path_1.join)(destPath, name), body);
81
+ output_1.default.clearPreviousLine();
82
+ output_1.default.normal(texts_1.TXT_SANDBOX_CP_DOWNLOAD_DONE);
83
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(1));
84
+ }
85
+ else {
86
+ const zipPath = (0, path_1.join)((0, utils_1.getHomeDirectory)(), `${(0, uuid_1.v4)()}.tar.gz`);
87
+ const clearZip = () => {
88
+ try {
89
+ node_fs_1.default.rmSync(zipPath);
90
+ }
91
+ catch {
92
+ // do nothing
93
+ }
94
+ };
95
+ try {
96
+ await promises_1.default.pipeline(body, node_fs_1.default.createWriteStream(zipPath));
97
+ output_1.default.clearPreviousLine();
98
+ output_1.default.normal(texts_1.TXT_SANDBOX_CP_DOWNLOAD_DONE);
99
+ output_1.default.normal(texts_1.TXT_SANDBOX_UNZIP);
100
+ let count = 0;
101
+ await (0, utils_1.untarGz)(destPath, zipPath, () => {
102
+ count += 1;
103
+ output_1.default.clearPreviousLine();
104
+ output_1.default.normal((0, texts_1.TXT_SANDBOX_UNZIPPING_COUNT)(count));
105
+ });
106
+ clearZip();
107
+ output_1.default.clearPreviousLine();
108
+ output_1.default.normal(texts_1.TXT_SANDBOX_UNZIP_DONE);
109
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(count));
110
+ }
111
+ catch {
112
+ clearZip();
113
+ output_1.default.exitError(texts_1.ERR_SWW);
114
+ }
115
+ }
116
+ };
117
+ commandSandboxCp.action(async (source, destination, options) => {
118
+ const workspace = input_1.default.restApiWorkspace(options.workspace);
119
+ const project = input_1.default.restApiProject(options.project);
120
+ const client = input_1.default.restApiTokenClient(options.api, options.region, options.token);
121
+ const isUpload = input_1.default.restApiSandboxIsUpload(destination);
122
+ if (isUpload) {
123
+ await upload(client, workspace, project, source, destination);
124
+ }
125
+ else {
126
+ await download(client, workspace, project, source, destination, !!options.merge, !!options.replace);
127
+ }
67
128
  });
68
129
  exports.default = commandSandboxCp;
@@ -41,7 +41,6 @@ commandSandboxCreate.option('--app-type <type>', texts_1.OPTION_SANDBOX_APP_TYPE
41
41
  commandSandboxCreate.option('--tag <tags...>', texts_1.OPTION_SANDBOX_TAGS);
42
42
  commandSandboxCreate.option('--wait-for-running [seconds]', texts_1.OPTION_SANDBOX_WAIT_RUNNING);
43
43
  commandSandboxCreate.option('--wait-for-configured [seconds]', texts_1.OPTION_SANDBOX_WAIT_CONFIGURED);
44
- commandSandboxCreate.option('--wait-for-app [seconds]', texts_1.OPTION_SANDBOX_WAIT_APP);
45
44
  commandSandboxCreate.action(async (options) => {
46
45
  const workspace = input_1.default.restApiWorkspace(options.workspace);
47
46
  const project = input_1.default.restApiProject(options.project);
@@ -53,7 +52,7 @@ commandSandboxCreate.action(async (options) => {
53
52
  const baseName = (0, human_id_1.default)({ separator: '-', capitalize: false });
54
53
  const defaultIdentifier = `${baseName}-${timestamp}`;
55
54
  const body = {
56
- name: options.name || baseName,
55
+ name: options.name || options.identifier || baseName,
57
56
  identifier: options.identifier || defaultIdentifier,
58
57
  };
59
58
  if (options.snapshot) {
@@ -124,19 +123,6 @@ commandSandboxCreate.action(async (options) => {
124
123
  output_1.default.exitError(texts_1.ERR_SANDBOX_SETUP_TIMEOUT);
125
124
  }
126
125
  }
127
- if (options.waitForApp) {
128
- output_1.default.normal(texts_1.TXT_SANDBOX_WAITING_APP);
129
- const timeout = parseInt(options.waitForApp, 10) || 300;
130
- try {
131
- const status = await client.sandboxWaitForApp(workspace, sandboxId, timeout);
132
- if (status !== utils_1.SANDBOX_APP_STATUS.RUNNING) {
133
- output_1.default.exitError(texts_1.ERR_SANDBOX_APP_FAILED);
134
- }
135
- }
136
- catch {
137
- output_1.default.exitError(texts_1.ERR_SANDBOX_APP_TIMEOUT);
138
- }
139
- }
140
126
  output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CREATED)(result.identifier, result.html_url));
141
127
  });
142
128
  exports.default = commandSandboxCreate;
@@ -32,7 +32,6 @@ commandSandboxGet.action(async (identifier, options) => {
32
32
  ['Name', sandbox.name || '-'],
33
33
  ['Status', sandbox.status || '-'],
34
34
  ['Setup Status', sandbox.setup_status || '-'],
35
- ['App Status', sandbox.app_status || '-'],
36
35
  ['OS', sandbox.os || '-'],
37
36
  ['Resources', sandbox.resources || '-'],
38
37
  ['Tags', (sandbox.tags || []).join(', ') || '-'],
@@ -29,7 +29,6 @@ commandSandboxStatus.action(async (identifier, options) => {
29
29
  ['Type', 'Status'],
30
30
  ['Status', sandbox.status || 'UNKNOWN'],
31
31
  ['Setup', sandbox.setup_status || 'UNKNOWN'],
32
- ['App', sandbox.app_status || 'UNKNOWN']
33
32
  ]);
34
33
  output_1.default.exitNormal();
35
34
  });
@@ -493,7 +493,28 @@ class Input {
493
493
  identifier: s[0],
494
494
  };
495
495
  }
496
- static restApiSandboxDestinationPath(destPath) {
496
+ static restApiSandboxIsUpload(destPath) {
497
+ return (destPath || '').split(':').length === 2;
498
+ }
499
+ static restApiSandboxDownloadSourcePath(source) {
500
+ const s = (source || '').split(':');
501
+ if (s.length !== 2) {
502
+ output_1.default.exitError(texts_1.ERR_SANDBOX_CP_INVALID_SOURCE);
503
+ }
504
+ const identifier = s[0];
505
+ let sourcePath = s[1];
506
+ if (!identifier) {
507
+ output_1.default.exitError(texts_1.ERR_SANDBOX_CP_INVALID_SOURCE);
508
+ }
509
+ if (!sourcePath.startsWith('/')) {
510
+ sourcePath = `/${sourcePath}`;
511
+ }
512
+ return {
513
+ identifier,
514
+ sourcePath,
515
+ };
516
+ }
517
+ static restApiSandboxUploadDestinationPath(destPath) {
497
518
  const s = (destPath || '').split(':');
498
519
  if (s.length !== 2) {
499
520
  output_1.default.exitError(texts_1.ERR_SANDBOX_CP_INVALID_DEST);
@@ -511,7 +532,56 @@ class Input {
511
532
  remotePath,
512
533
  };
513
534
  }
514
- static restApiSandboxSourcePath(sourcePath) {
535
+ static restApiSandboxDownloadDestinationPath(destPath, merge, replace) {
536
+ const dirPath = node_path_1.default.resolve(destPath);
537
+ const exists = node_fs_1.default.existsSync(dirPath);
538
+ if (!exists) {
539
+ try {
540
+ node_fs_1.default.mkdirSync(dirPath, {
541
+ recursive: true,
542
+ });
543
+ }
544
+ catch {
545
+ output_1.default.exitError((0, texts_1.ERR_SANDBOX_CP_MKDIR)(dirPath));
546
+ }
547
+ }
548
+ else if (replace) {
549
+ try {
550
+ node_fs_1.default.rmSync(dirPath, {
551
+ recursive: true,
552
+ force: true,
553
+ });
554
+ node_fs_1.default.mkdirSync(dirPath, {
555
+ recursive: true,
556
+ });
557
+ }
558
+ catch {
559
+ output_1.default.exitError((0, texts_1.ERR_SANDBOX_CP_REPLACE)(dirPath));
560
+ }
561
+ }
562
+ try {
563
+ const stats = node_fs_1.default.statSync(dirPath);
564
+ if (!stats.isDirectory()) {
565
+ output_1.default.exitError((0, texts_1.ERR_SANDBOX_CP_DEST_NOT_FOLDER)(destPath));
566
+ }
567
+ }
568
+ catch {
569
+ output_1.default.exitError(texts_1.ERR_SWW);
570
+ }
571
+ let empty = true;
572
+ try {
573
+ const entries = node_fs_1.default.readdirSync(dirPath);
574
+ empty = !entries.length;
575
+ }
576
+ catch {
577
+ output_1.default.exitError((0, texts_1.ERR_SANDBOX_CP_READDIR)(dirPath));
578
+ }
579
+ if (!empty && !merge) {
580
+ output_1.default.exitError((0, texts_1.ERR_SANDBOX_CP_NOT_EMPTY_DIR)(dirPath));
581
+ }
582
+ return dirPath;
583
+ }
584
+ static restApiSandboxUploadSourcePath(sourcePath) {
515
585
  const s = node_path_1.default.resolve(sourcePath);
516
586
  let sourceStats;
517
587
  try {
@@ -8,17 +8,27 @@ exports.OPTION_PACKAGE_DOWNLOAD_REPLACE = exports.OPTION_PACKAGE_DOWNLOAD_MERGE
8
8
  exports.OPTION_COMPARE_URLS_FILE = exports.OPTION_COMPARE_SITEMAP = exports.OPTION_COMPARE_URLS = exports.OPTION_COMPARE_RESPECT_ROBOTS = exports.OPTION_COMPARE_FOLLOW = exports.OPTION_EXEC_PARALLEL = exports.OPTION_EXEC_ONE_BY_ONE = exports.OPTION_EXEC_SKIP_DISCOVERY = exports.OPTION_EXEC_COMMAND = exports.OPTION_AGENT_DEBUG = exports.OPTION_AGENT_PORT = exports.OPTION_AGENT_TARGET = exports.OPTION_PASS = exports.OPTION_APP = exports.OPTION_USER = exports.OPTION_AGENT_TOKEN = exports.OPTION_AGENT_START = exports.OPTION_AGENT_ID = exports.OPTION_ID = exports.OPTION_NAME = exports.OPTION_TARGET = exports.OPTION_TLS_TERMINATE = exports.OPTION_TLS_CA = exports.OPTION_TLS_CERT = exports.OPTION_TLS_KEY = exports.OPTION_HTTP_CIRCUIT_BREAKER = exports.OPTION_HTTP_COMPRESSION = exports.OPTION_HTTP_2 = exports.OPTION_HTTP_VERIFY = exports.OPTION_HTTP_LOG = exports.OPTION_HTTP_AUTH_BUDDY = exports.OPTION_HTTP_AUTH = exports.OPTION_HTTP_HOST = exports.OPTION_CONFIRM_FORCE = exports.OPTION_FORCE = exports.OPTION_TOKEN = exports.OPTION_TIMEOUT = exports.OPTION_FOLLOW = exports.OPTION_SERVE = exports.OPTION_HEADER_USER_AGENT = exports.OPTION_RESPONSE_HEADER = exports.OPTION_HEADER = exports.OPTION_WHITELIST = exports.OPTION_REST_API_PER_PAGE = exports.OPTION_REST_API_PAGE = exports.OPTION_REST_API_PROJECT = exports.OPTION_REST_API_WORKSPACE = exports.OPTION_PIPELINE_RUN_WAIT = exports.OPTION_PIPELINE_RUN_ACTION = exports.OPTION_REST_API_TOKEN = void 0;
9
9
  exports.LOG_TUNNEL_REGISTERED = exports.LOG_ERROR_WHILE_REFRESHING_AGENT = exports.LOG_REGISTERING_TUNNEL = exports.LOG_GETTING_AGENT = exports.LOG_UNREGISTERING_AGENT = exports.LOG_REGION_DETECTED = exports.LOG_AGENT_REGISTERED = exports.LOG_SOCKET_DISCONNECTED = exports.LOG_SOCKET_CONNECTED = exports.LOG_AGENT_NSSM_CLEARING = exports.LOG_AGENT_NSSM_EXTRACTING = exports.LOG_AGENT_NSSM_DOWNLOADING = exports.LOG_AGENT_ENABLED = exports.LOG_AGENT_STARTING_SYSTEM = exports.LOG_AGENT_STOPPING_SYSTEM = exports.LOG_AGENT_ENABLING_SYSTEM = exports.LOG_AGENT_SYSTEM_SERVICE_CONFIG = exports.LOG_AGENT_EXTRACTING_ARCHIVE = exports.LOG_AGENT_DOWNLOADING_ARCHIVE = exports.LOG_AGENT_SYSTEM_DIR = exports.LOG_ERROR_SAVING_AGENT_LOCAL_CONFIG = exports.LOG_ERROR_REMOVING_AGENT_STANDALONE_LOCK_FILE = exports.LOG_ERROR_SAVING_AGENT_STANDALONE_CONFIG = exports.LOG_ERROR_SAVING_AGENT_SYSTEM_CONFIG = exports.LOG_SAVING_AGENT_LOCAL_CONFIG = exports.LOG_REMOVING_AGENT_PROC_ID = exports.LOG_SAVING_AGENT_PROC_ID = exports.LOG_SAVING_AGENT_SYSTEM_CONFIG = exports.LOG_REGISTERING_AGENT = exports.OPTION_SCRAPE_OUTPUT_DIR = exports.OPTION_SCRAPE_DELAY = exports.OPTION_SCRAPE_DARK_MODE = exports.OPTION_SCRAPE_WAIT_FOR_ELEMENT = exports.OPTION_SCRAPE_DEVICE_PIXEL_RATIO = exports.OPTION_SCRAPE_VIEWPORT = exports.OPTION_SCRAPE_BROWSER = exports.OPTION_SCRAPE_XPATH_SELECTOR = exports.OPTION_SCRAPE_CSS_SELECTOR = exports.OPTION_SCRAPE_FULL_PAGE = exports.OPTION_SCRAPE_QUALITY = exports.OPTION_SCRAPE_OUTPUT_TYPE = exports.OPTION_SCRAPE_FOLLOW = exports.OPTION_SCRAPE_URL = exports.OPTION_COMPARE_WAIT_FOR = exports.OPTION_COMPARE_DELAY = exports.OPTION_COMPARE_HEADER = exports.OPTION_COMPARE_COOKIE = exports.OPTION_COMPARE_IGNORE = exports.OPTION_COMPARE_IGNORE_URLS = exports.OPTION_COMPARE_DRY_RUN = void 0;
10
10
  exports.DESC_COMMAND_SANDBOX_LIST = exports.DESC_COMMAND_SANDBOX_CREATE = exports.DESC_COMMAND_SANDBOX = exports.DEBUG_WAIT_FOR_IDLE_TIMEOUT = exports.DEBUG_WAIT_FOR_IDLE = exports.DEBUG_RESOURCE_DISCOVERY_TIMEOUT = exports.DEBUG_AUTO_WIDTH = exports.DEBUG_AUTO_SCROLL = exports.DEBUG_RESOURCE_SCRAPPING_URL = exports.DEBUG_SNAPSHOT_PROCESSING = exports.DEBUG_SNAPSHOTS_PROCESSING = exports.DEBUG_EXEC_COMMAND = exports.DEBUG_EXEC_TEST_COMMAND = exports.LOG_INSTALLED_BROWSER = exports.LOG_SESSION_LINK = exports.LOG_SENDING_DATA = exports.LOG_SENDING_REQUEST = exports.LOG_PROCESSING_SNAPSHOTS = exports.LOG_RUNNING_EXEC_COMMAND = exports.LOG_TUNNEL_SSH_STREAM = exports.LOG_TUNNEL_TLS_AGENT_STREAM = exports.LOG_TUNNEL_TLS_REGION_STREAM = exports.LOG_TUNNEL_TLS_TARGET_STREAM = exports.LOG_TUNNEL_HTTP2_STREAM = exports.LOG_TUNNEL_HTTP1_STREAM = exports.LOG_TUNNEL_TCP_STREAM = exports.LOG_TUNNEL_HTTP_WRONG_USER_AGENTS = exports.LOG_TUNNEL_HTTP_CIRCUIT_BREAKER_OPEN = exports.LOG_TUNNEL_HTTP_RATE_LIMIT = exports.LOG_TUNNEL_HTTP_WRON_AUTH = exports.LOG_TUNNEL_IDENTIFIED = exports.LOG_TUNNEL_DISCONNECTED = exports.LOG_TUNNEL_FAILED = exports.LOG_TUNNEL_CONNECTED = exports.LOG_AGENT_STARTED = exports.LOG_AGENT_SERVER_STARTED = exports.LOG_ERROR_STARTING_AGENT_SERVER = exports.LOG_SSH_CONNECTION = exports.LOG_WRONG_STREAM = exports.LOG_DETECTED_STREAM = exports.LOG_HTTP2_REQUEST = exports.LOG_HTTP2_CONNECTION = exports.LOG_HTTP1_REQUEST = exports.LOG_HTTP1_CONNECTION = exports.LOG_ERROR = exports.LOG_STOPPING_TUNNEL = exports.LOG_STARTING_TUNNEL = exports.LOG_ENABLING_AGENT_TARGET = exports.LOG_DISABLING_AGENT_TARGET = exports.LOG_REMOVING_TUNNEL = void 0;
11
- exports.OPTION_SANDBOX_COMMAND_KILL_CONFIRM = exports.OPTION_SANDBOX_COMMAND_ID = exports.DESC_COMMAND_SANDBOX_EXEC_KILL = exports.DESC_COMMAND_SANDBOX_EXEC_LOGS = exports.DESC_COMMAND_SANDBOX_EXEC_STATUS = exports.DESC_COMMAND_SANDBOX_EXEC_LIST = exports.TXT_SANDBOX_WAITING_START = exports.TXT_SANDBOX_WAITING_STOP = exports.TXT_SANDBOX_WAITING_APP = exports.TXT_SANDBOX_WAITING_SETUP = exports.TXT_SANDBOX_WAITING_RUNNING = exports.TXT_SANDBOX_STOPPED = exports.TXT_SANDBOX_STARTED = exports.TXT_SANDBOX_DESTROYED = exports.TXT_SANDBOX_DESTROY_CONFIRM = exports.TXT_SANDBOX_CREATED = exports.TXT_SANDBOX_CREATING = exports.OPTION_SANDBOX_WAIT = exports.OPTION_SANDBOX_WAIT_APP = exports.OPTION_SANDBOX_WAIT_CONFIGURED = exports.OPTION_SANDBOX_WAIT_RUNNING = exports.ERR_SANDBOX_STOP_FAILED = exports.ERR_SANDBOX_NO_COMMANDS = exports.ERR_SANDBOX_RUNNING_FAILED = exports.ERR_SANDBOX_STOP_TIMEOUT = exports.ERR_SANDBOX_SNAPSHOT_TIMEOUT = exports.ERR_SANDBOX_RUNNING_TIMEOUT = exports.ERR_SANDBOX_APP_TIMEOUT = exports.ERR_SANDBOX_SETUP_TIMEOUT = exports.ERR_SANDBOX_APP_FAILED = exports.ERR_SANDBOX_SETUP_FAILED = exports.ERR_SANDBOX_INVALID_RESOURCES = exports.ERR_SANDBOX_NOT_FOUND = exports.OPTION_SANDBOX_RUNTIME = exports.OPTION_SANDBOX_APP_TYPE = exports.OPTION_SANDBOX_APP_DIR = exports.OPTION_SANDBOX_RUN_COMMAND = exports.OPTION_SANDBOX_TAGS = exports.OPTION_SANDBOX_INSTALL_COMMANDS = exports.OPTION_SANDBOX_RESOURCES = exports.OPTION_SANDBOX_OS = exports.OPTION_SANDBOX_NAME = exports.OPTION_SANDBOX_IDENTIFIER = exports.DESC_COMMAND_SANDBOX_EXEC = exports.DESC_COMMAND_SANDBOX_STATUS = exports.DESC_COMMAND_SANDBOX_RESTART = exports.DESC_COMMAND_SANDBOX_STOP = exports.DESC_COMMAND_SANDBOX_START = exports.DESC_COMMAND_SANDBOX_DESTROY = exports.DESC_COMMAND_SANDBOX_GET = void 0;
12
- exports.DESC_COMMAND_LOGOUT = exports.DESC_COMMAND_LOGIN = exports.ERR_WHOAMI_LOGOUT = exports.TXT_WHOAMI_NO_PROJECT = exports.TXT_WHOAMI_NO_WORKSPACE = exports.DESC_COMMAND_WHOAMI = exports.TXT_SANDBOX_EXEC_FAILED = exports.TXT_SANDBOX_EXEC_INPROGRESS = exports.TXT_SANDBOX_EXEC_SUCCESS = exports.TXT_SANDBOX_EXEC_BACKGROUND = exports.TXT_SANDBOX_EXEC_ID = exports.ERR_SANDBOX_CP_INVALID_DEST = exports.ERR_SANDBOX_CP_SOURCE_NOT_FOUND = exports.TXT_SANDBOX_CP_DONE = exports.TXT_SANDBOX_CP_PROGRESS = exports.OPTION_SANDBOX_CP_SILENT = exports.OPTION_SANDBOX_CP_DEST = exports.OPTION_SANDBOX_CP_SOURCE = exports.DESC_COMMAND_SANDBOX_CP = exports.ERR_SANDBOX_ENDPOINTS_NOT_FOUND = exports.ERR_SANDBOX_ENDPOINT_NOT_FOUND = exports.ERR_SANDBOX_ENDPOINT_EXISTS = exports.TXT_SANDBOX_ENDPOINT_DELETED = exports.TXT_SANDBOX_ENDPOINT_DELETE_CONFIRM = exports.TXT_SANDBOX_ENDPOINT_ADDED = exports.OPTION_SANDBOX_ENDPOINT_TYPE = exports.OPTION_SANDBOX_ENDPOINT_PORT = exports.OPTION_SANDBOX_ENDPOINT_NAME_ARG = exports.OPTION_SANDBOX_ENDPOINT_NAME = exports.DESC_COMMAND_SANDBOX_ENDPOINT_DELETE = exports.DESC_COMMAND_SANDBOX_ENDPOINT_ADD = exports.DESC_COMMAND_SANDBOX_ENDPOINT_GET = exports.DESC_COMMAND_SANDBOX_ENDPOINT_LIST = exports.DESC_COMMAND_SANDBOX_ENDPOINT = exports.ERR_SANDBOX_SNAPSHOTS_NOT_FOUND = exports.ERR_SANDBOX_SNAPSHOT_NOT_FOUND = exports.ERR_SANDBOX_SNAPSHOT_FAILED = exports.TXT_SANDBOX_SNAPSHOT_WAITING = exports.TXT_SANDBOX_SNAPSHOT_DELETE_CONFIRM = exports.TXT_SANDBOX_SNAPSHOT_DELETED = exports.TXT_SANDBOX_SNAPSHOT_CREATED = exports.OPTION_SANDBOX_FROM_SNAPSHOT = exports.OPTION_SANDBOX_SNAPSHOT_NAME_ARG = exports.OPTION_SANDBOX_SNAPSHOT_NAME = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_DELETE = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_GET = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_CREATE = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_LIST = exports.DESC_COMMAND_SANDBOX_SNAPSHOT = exports.TXT_SANDBOX_COMMAND_KILLED = void 0;
13
- exports.DESC_COMMAND_PROJECT_GET = exports.ARG_COMMAND_PROJECT_NAME = exports.DESC_COMMAND_PROJECT_SET = exports.DESC_COMMAND_PROJECT_LIST = exports.DESC_COMMAND_PROJECT = exports.TXT_PACKAGE_VERSION_DOWNLOAD = exports.TXT_PACKAGE_CREATED = exports.TXT_PACKAGE_VERSION_DELETED = exports.TXT_PACKAGE_DELETED = exports.ERR_COMMAND_PACKAGE_TYPE = exports.OPT_COMMAND_PACKAGE_VERSION = exports.OPT_COMMAND_PACKAGE_IDENTIFIER = exports.OPT_COMMAND_PACKAGE_CREATE_IDENTIFIER = exports.OPT_COMMAND_PACKAGE_NAME = exports.OPT_COMMAND_PACKAGE_TYPE = exports.DESC_COMMAND_PACKAGE_CREATE = exports.DESC_COMMAND_PACKAGE_GET = exports.TXT_PACKAGE_DOCKER_LOGIN_FAILED = exports.TXT_PACKAGE_DOCKER_LOGIN_SUCCESS = exports.TXT_PACKAGE_VERSION_DELETE_CONFIRM = exports.TXT_PACKAGE_DELETE_CONFIRM = exports.DESC_COMMAND_PACKAGE_DELETE = exports.ERR_COMMAND_PACKAGE_NO_PROJECTS = exports.DESC_COMMAND_PACKAGE_VERSION_GET = exports.DESC_COMMAND_PACKAGE_VERSION_LIST = exports.DESC_COMMAND_PACKAGE_VERSION_DELETE = exports.DESC_COMMAND_PACKAGE_DOCKER_LOGIN = exports.DESC_COMMAND_PACKAGE_LIST = exports.DESC_COMMAND_PACKAGE_VERSION = exports.ERR_API_MESSAGE_REPLACER = exports.ERR_LOGIN_INVALID_BASE_URL = exports.ERR_LOGIN_NO_PROJECT_FOUND = exports.ERR_LOGIN_NO_WORKSPACE_FOUND = exports.ERR_LOGIN_NO_WORKSPACES = exports.ERR_LOGIN_HTTP_SUCCESS = exports.ERR_LOGIN_HTTP_FAILED = exports.TXT_LOGIN_OAUTH = exports.ERR_LOGIN_HTTP_SERVER_PORT_TAKEN = exports.TXT_LOGIN_SUCCESS = exports.TXT_LOGIN_SELECT_WORKSPACE = exports.TXT_LOGIN_ENTER_BASE_URL = exports.TXT_LOGIN_SELECT_REGION = exports.TXT_WORKSPACE_NONE = exports.TXT_WORKSPACE_SET_SUCCESS = exports.ARG_COMMAND_WORKSPACE = exports.DESC_COMMAND_WORKSPACE_GET = exports.DESC_COMMAND_WORKSPACE_SET = exports.DESC_COMMAND_WORKSPACE_LIST = exports.DESC_COMMAND_WORKSPACE = exports.TXT_LOGOUT_SUCCESS = void 0;
14
- exports.TXT_PROJECT_NONE = exports.ERR_PROJECT_NO_PROJECTS = exports.TXT_LOGIN_SELECT_PROJECT = exports.TXT_PROJECT_SET_CLEARED = exports.TXT_PROJECT_SET_SUCCESS = void 0;
11
+ exports.DESC_COMMAND_SANDBOX_SNAPSHOT_CREATE = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_LIST = exports.DESC_COMMAND_SANDBOX_SNAPSHOT = exports.TXT_SANDBOX_COMMAND_KILLED = exports.OPTION_SANDBOX_COMMAND_KILL_CONFIRM = exports.OPTION_SANDBOX_COMMAND_ID = exports.DESC_COMMAND_SANDBOX_EXEC_KILL = exports.DESC_COMMAND_SANDBOX_EXEC_LOGS = exports.DESC_COMMAND_SANDBOX_EXEC_STATUS = exports.DESC_COMMAND_SANDBOX_EXEC_LIST = exports.TXT_SANDBOX_WAITING_START = exports.TXT_SANDBOX_WAITING_STOP = exports.TXT_SANDBOX_WAITING_SETUP = exports.TXT_SANDBOX_WAITING_RUNNING = exports.TXT_SANDBOX_STOPPED = exports.TXT_SANDBOX_STARTED = exports.TXT_SANDBOX_DESTROYED = exports.TXT_SANDBOX_DESTROY_CONFIRM = exports.TXT_SANDBOX_CREATED = exports.TXT_SANDBOX_CREATING = exports.OPTION_SANDBOX_WAIT = exports.OPTION_SANDBOX_WAIT_CONFIGURED = exports.OPTION_SANDBOX_WAIT_RUNNING = exports.ERR_SANDBOX_STOP_FAILED = exports.ERR_SANDBOX_NO_COMMANDS = exports.ERR_SANDBOX_RUNNING_FAILED = exports.ERR_SANDBOX_STOP_TIMEOUT = exports.ERR_SANDBOX_SNAPSHOT_TIMEOUT = exports.ERR_SANDBOX_RUNNING_TIMEOUT = exports.ERR_SANDBOX_SETUP_TIMEOUT = exports.ERR_SANDBOX_SETUP_FAILED = exports.ERR_SANDBOX_INVALID_RESOURCES = exports.ERR_SANDBOX_NOT_FOUND = exports.OPTION_SANDBOX_RUNTIME = exports.OPTION_SANDBOX_APP_TYPE = exports.OPTION_SANDBOX_APP_DIR = exports.OPTION_SANDBOX_RUN_COMMAND = exports.OPTION_SANDBOX_TAGS = exports.OPTION_SANDBOX_INSTALL_COMMANDS = exports.OPTION_SANDBOX_RESOURCES = exports.OPTION_SANDBOX_OS = exports.OPTION_SANDBOX_NAME = exports.OPTION_SANDBOX_IDENTIFIER = exports.DESC_COMMAND_SANDBOX_EXEC = exports.DESC_COMMAND_SANDBOX_STATUS = exports.DESC_COMMAND_SANDBOX_RESTART = exports.DESC_COMMAND_SANDBOX_STOP = exports.DESC_COMMAND_SANDBOX_START = exports.DESC_COMMAND_SANDBOX_DESTROY = exports.DESC_COMMAND_SANDBOX_GET = void 0;
12
+ exports.TXT_SANDBOX_EXEC_SUCCESS = exports.TXT_SANDBOX_EXEC_BACKGROUND = exports.TXT_SANDBOX_EXEC_ID = exports.ERR_SANDBOX_CP_INVALID_SOURCE = exports.ERR_SANDBOX_CP_INVALID_DEST = exports.ERR_SANDBOX_CP_REPLACE = exports.ERR_SANDBOX_CP_MKDIR = exports.ERR_SANDBOX_CP_NOT_EMPTY_DIR = exports.ERR_SANDBOX_CP_READDIR = exports.ERR_SANDBOX_CP_DEST_NOT_FOLDER = exports.ERR_SANDBOX_CP_SOURCE_NOT_FOUND = exports.TXT_SANDBOX_CP_DONE = exports.TXT_SANDBOX_CP_PROGRESS = exports.TXT_SANDBOX_UNZIPPING_COUNT = exports.TXT_SANDBOX_UNZIP_DONE = exports.TXT_SANDBOX_UNZIP = exports.TXT_SANDBOX_CP_DOWNLOAD_DONE = exports.TXT_SANDBOX_CP_DOWNLOAD = exports.OPTION_SANDBOX_CP_DOWNLOAD_REPLACE = exports.OPTION_SANDBOX_CP_DOWNLOAD_MERGE = exports.OPTION_SANDBOX_CP_DEST = exports.OPTION_SANDBOX_CP_SOURCE = exports.DESC_COMMAND_SANDBOX_CP = exports.ERR_SANDBOX_ENDPOINTS_NOT_FOUND = exports.ERR_SANDBOX_ENDPOINT_NOT_FOUND = exports.ERR_SANDBOX_ENDPOINT_EXISTS = exports.TXT_SANDBOX_ENDPOINT_DELETED = exports.TXT_SANDBOX_ENDPOINT_DELETE_CONFIRM = exports.TXT_SANDBOX_ENDPOINT_ADDED = exports.OPTION_SANDBOX_ENDPOINT_TYPE = exports.OPTION_SANDBOX_ENDPOINT_PORT = exports.OPTION_SANDBOX_ENDPOINT_NAME_ARG = exports.OPTION_SANDBOX_ENDPOINT_NAME = exports.DESC_COMMAND_SANDBOX_ENDPOINT_DELETE = exports.DESC_COMMAND_SANDBOX_ENDPOINT_ADD = exports.DESC_COMMAND_SANDBOX_ENDPOINT_GET = exports.DESC_COMMAND_SANDBOX_ENDPOINT_LIST = exports.DESC_COMMAND_SANDBOX_ENDPOINT = exports.ERR_SANDBOX_SNAPSHOTS_NOT_FOUND = exports.ERR_SANDBOX_SNAPSHOT_NOT_FOUND = exports.ERR_SANDBOX_SNAPSHOT_FAILED = exports.TXT_SANDBOX_SNAPSHOT_WAITING = exports.TXT_SANDBOX_SNAPSHOT_DELETE_CONFIRM = exports.TXT_SANDBOX_SNAPSHOT_DELETED = exports.TXT_SANDBOX_SNAPSHOT_CREATED = exports.OPTION_SANDBOX_FROM_SNAPSHOT = exports.OPTION_SANDBOX_SNAPSHOT_NAME_ARG = exports.OPTION_SANDBOX_SNAPSHOT_NAME = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_DELETE = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_GET = void 0;
13
+ exports.TXT_PACKAGE_DELETED = exports.ERR_COMMAND_PACKAGE_TYPE = exports.OPT_COMMAND_PACKAGE_VERSION = exports.OPT_COMMAND_PACKAGE_IDENTIFIER = exports.OPT_COMMAND_PACKAGE_CREATE_IDENTIFIER = exports.OPT_COMMAND_PACKAGE_NAME = exports.OPT_COMMAND_PACKAGE_TYPE = exports.DESC_COMMAND_PACKAGE_CREATE = exports.DESC_COMMAND_PACKAGE_GET = exports.TXT_PACKAGE_DOCKER_LOGIN_FAILED = exports.TXT_PACKAGE_DOCKER_LOGIN_SUCCESS = exports.TXT_PACKAGE_VERSION_DELETE_CONFIRM = exports.TXT_PACKAGE_DELETE_CONFIRM = exports.DESC_COMMAND_PACKAGE_DELETE = exports.ERR_COMMAND_PACKAGE_NO_PROJECTS = exports.DESC_COMMAND_PACKAGE_VERSION_GET = exports.DESC_COMMAND_PACKAGE_VERSION_LIST = exports.DESC_COMMAND_PACKAGE_VERSION_DELETE = exports.DESC_COMMAND_PACKAGE_DOCKER_LOGIN = exports.DESC_COMMAND_PACKAGE_LIST = exports.DESC_COMMAND_PACKAGE_VERSION = exports.ERR_API_MESSAGE_REPLACER = exports.ERR_LOGIN_INVALID_BASE_URL = exports.ERR_LOGIN_NO_PROJECT_FOUND = exports.ERR_LOGIN_NO_WORKSPACE_FOUND = exports.ERR_LOGIN_NO_WORKSPACES = exports.ERR_LOGIN_HTTP_SUCCESS = exports.ERR_LOGIN_HTTP_FAILED = exports.TXT_LOGIN_OAUTH = exports.ERR_LOGIN_HTTP_SERVER_PORT_TAKEN = exports.TXT_LOGIN_SUCCESS = exports.TXT_LOGIN_SELECT_WORKSPACE = exports.TXT_LOGIN_ENTER_BASE_URL = exports.TXT_LOGIN_SELECT_REGION = exports.TXT_WORKSPACE_NONE = exports.TXT_WORKSPACE_SET_SUCCESS = exports.ARG_COMMAND_WORKSPACE = exports.DESC_COMMAND_WORKSPACE_GET = exports.DESC_COMMAND_WORKSPACE_SET = exports.DESC_COMMAND_WORKSPACE_LIST = exports.DESC_COMMAND_WORKSPACE = exports.TXT_LOGOUT_SUCCESS = exports.DESC_COMMAND_LOGOUT = exports.DESC_COMMAND_LOGIN = exports.ERR_WHOAMI_LOGOUT = exports.TXT_WHOAMI_NO_PROJECT = exports.TXT_WHOAMI_NO_WORKSPACE = exports.DESC_COMMAND_WHOAMI = exports.TXT_SANDBOX_EXEC_FAILED = exports.TXT_SANDBOX_EXEC_INPROGRESS = void 0;
14
+ exports.TXT_PROJECT_NONE = exports.ERR_PROJECT_NO_PROJECTS = exports.TXT_LOGIN_SELECT_PROJECT = exports.TXT_PROJECT_SET_CLEARED = exports.TXT_PROJECT_SET_SUCCESS = exports.DESC_COMMAND_PROJECT_GET = exports.ARG_COMMAND_PROJECT_NAME = exports.DESC_COMMAND_PROJECT_SET = exports.DESC_COMMAND_PROJECT_LIST = exports.DESC_COMMAND_PROJECT = exports.TXT_PACKAGE_VERSION_DOWNLOAD = exports.TXT_PACKAGE_PUBLISH = exports.TXT_PACKAGE_CREATED = exports.TXT_PACKAGE_VERSION_DELETED = void 0;
15
15
  const utils_1 = require("./utils");
16
16
  exports.ERR_REST_API_GENERAL_ERROR = 'Something went wrong';
17
17
  exports.ERR_REST_API_NOT_RESPONDING = 'Api endpoint not responding. Try again later...';
18
18
  exports.ERR_REST_API_CONNECT_ERROR = 'Connection refused. Check selected endpoint';
19
19
  exports.ERR_REST_API_WRONG_TOKEN = 'Valid token with proper scopes is required';
20
20
  exports.ERR_REST_API_RESOURCE_NOT_FOUND = 'Resource not found';
21
- exports.ERR_REST_API_RATE_LIMIT = 'Rate limit exceeded';
21
+ const ERR_REST_API_RATE_LIMIT = (rateLimitReset) => {
22
+ if (rateLimitReset) {
23
+ const ts = Array.isArray(rateLimitReset)
24
+ ? rateLimitReset[0]
25
+ : rateLimitReset;
26
+ const date = new Date(parseInt(ts, 10) * 1000);
27
+ return `Buddy API rate limit exceeded. Window will be reset at ${date.toISOString()}`;
28
+ }
29
+ return 'Buddy API rate limit exceeded';
30
+ };
31
+ exports.ERR_REST_API_RATE_LIMIT = ERR_REST_API_RATE_LIMIT;
22
32
  exports.ERR_REST_API_TOKEN = 'Personal access token is required (--token)';
23
33
  exports.ERR_REST_API_URL = 'Valid rest api endpoint is required (--api)';
24
34
  exports.ERR_REST_API_REGION = 'Valid rest api region is required (eu, us, as, onprem)';
@@ -514,9 +524,7 @@ exports.ERR_SANDBOX_NOT_FOUND = 'Sandbox not found';
514
524
  const ERR_SANDBOX_INVALID_RESOURCES = (resources) => `Invalid resources: ${resources}. Use: 1x2, 2x4, 4x8, 8x16, 12x24`;
515
525
  exports.ERR_SANDBOX_INVALID_RESOURCES = ERR_SANDBOX_INVALID_RESOURCES;
516
526
  exports.ERR_SANDBOX_SETUP_FAILED = 'Sandbox setup failed';
517
- exports.ERR_SANDBOX_APP_FAILED = 'Sandbox app failed';
518
527
  exports.ERR_SANDBOX_SETUP_TIMEOUT = 'Timeout waiting for sandbox setup';
519
- exports.ERR_SANDBOX_APP_TIMEOUT = 'Timeout waiting for sandbox app';
520
528
  exports.ERR_SANDBOX_RUNNING_TIMEOUT = 'Timeout waiting for sandbox running';
521
529
  exports.ERR_SANDBOX_SNAPSHOT_TIMEOUT = 'Timeout waiting for sandbox snapshot';
522
530
  exports.ERR_SANDBOX_STOP_TIMEOUT = 'Timeout waiting for sandbox stop';
@@ -525,7 +533,6 @@ exports.ERR_SANDBOX_NO_COMMANDS = 'No commands found for this sandbox';
525
533
  exports.ERR_SANDBOX_STOP_FAILED = 'Sandbox failed to stop';
526
534
  exports.OPTION_SANDBOX_WAIT_RUNNING = 'Wait until sandbox is running';
527
535
  exports.OPTION_SANDBOX_WAIT_CONFIGURED = 'Wait until sandbox ran setup commands';
528
- exports.OPTION_SANDBOX_WAIT_APP = 'Wait until sandbox ran ran app commands';
529
536
  exports.OPTION_SANDBOX_WAIT = 'Wait until operation completes';
530
537
  // Sandbox success messages
531
538
  const TXT_SANDBOX_CREATING = (name, identifier) => `Creating sandbox: ${name} (${identifier})`;
@@ -544,7 +551,6 @@ const TXT_SANDBOX_STOPPED = (identifier) => `Sandbox stopped: ${identifier}`;
544
551
  exports.TXT_SANDBOX_STOPPED = TXT_SANDBOX_STOPPED;
545
552
  exports.TXT_SANDBOX_WAITING_RUNNING = 'Waiting for sandbox running...';
546
553
  exports.TXT_SANDBOX_WAITING_SETUP = 'Waiting for sandbox setup...';
547
- exports.TXT_SANDBOX_WAITING_APP = 'Waiting for sandbox app...';
548
554
  exports.TXT_SANDBOX_WAITING_STOP = 'Waiting for sandbox stop...';
549
555
  exports.TXT_SANDBOX_WAITING_START = 'Waiting for sandbox start...';
550
556
  // Sandbox command subcommands
@@ -598,16 +604,34 @@ exports.ERR_SANDBOX_ENDPOINT_NOT_FOUND = 'Endpoint not found';
598
604
  exports.ERR_SANDBOX_ENDPOINTS_NOT_FOUND = 'No endpoints found';
599
605
  // Sandbox cp command
600
606
  exports.DESC_COMMAND_SANDBOX_CP = 'Copy files/directories to sandbox';
601
- exports.OPTION_SANDBOX_CP_SOURCE = 'Local file or directory path';
602
- exports.OPTION_SANDBOX_CP_DEST = 'Sandbox destination (sandbox-id:/path). Full file path for single file upload. Remote directory if local directory upload';
603
- exports.OPTION_SANDBOX_CP_SILENT = 'Suppress progress output';
604
- const TXT_SANDBOX_CP_PROGRESS = (current, total, file) => `[${current}/${total}] ${file}`;
607
+ exports.OPTION_SANDBOX_CP_SOURCE = 'Upload: local file (directory) path to upload. Download: sandbox remote file (directory): sandbox-id:/path to download';
608
+ exports.OPTION_SANDBOX_CP_DEST = 'Upload: Sandbox remote file (directory): sandbox-id:/path to upload to. Download: local directory path to download to';
609
+ exports.OPTION_SANDBOX_CP_DOWNLOAD_MERGE = 'Merge contents of the destination directory with sandbox content';
610
+ exports.OPTION_SANDBOX_CP_DOWNLOAD_REPLACE = 'Replace contents of the destination directory with sandbox content';
611
+ exports.TXT_SANDBOX_CP_DOWNLOAD = 'Downloading...';
612
+ exports.TXT_SANDBOX_CP_DOWNLOAD_DONE = 'Downloading...Done';
613
+ exports.TXT_SANDBOX_UNZIP = 'Unzipping...';
614
+ exports.TXT_SANDBOX_UNZIP_DONE = 'Unzipping...Done';
615
+ const TXT_SANDBOX_UNZIPPING_COUNT = (count) => `Unzipping...${count}`;
616
+ exports.TXT_SANDBOX_UNZIPPING_COUNT = TXT_SANDBOX_UNZIPPING_COUNT;
617
+ const TXT_SANDBOX_CP_PROGRESS = (current, total, file) => `Uploading...[${current}/${total}] ${file}`;
605
618
  exports.TXT_SANDBOX_CP_PROGRESS = TXT_SANDBOX_CP_PROGRESS;
606
619
  const TXT_SANDBOX_CP_DONE = (count) => `Copied ${count} file(s)`;
607
620
  exports.TXT_SANDBOX_CP_DONE = TXT_SANDBOX_CP_DONE;
608
621
  const ERR_SANDBOX_CP_SOURCE_NOT_FOUND = (path) => `Source not found: ${path}`;
609
622
  exports.ERR_SANDBOX_CP_SOURCE_NOT_FOUND = ERR_SANDBOX_CP_SOURCE_NOT_FOUND;
623
+ const ERR_SANDBOX_CP_DEST_NOT_FOLDER = (path) => `Path ${path} is not a directory. Change path or use --replace flag`;
624
+ exports.ERR_SANDBOX_CP_DEST_NOT_FOLDER = ERR_SANDBOX_CP_DEST_NOT_FOLDER;
625
+ const ERR_SANDBOX_CP_READDIR = (dirPath) => `Error while reading directory ${dirPath}`;
626
+ exports.ERR_SANDBOX_CP_READDIR = ERR_SANDBOX_CP_READDIR;
627
+ const ERR_SANDBOX_CP_NOT_EMPTY_DIR = (dirPath) => `Directory ${dirPath} is not empty. Use --merge or --replace flags`;
628
+ exports.ERR_SANDBOX_CP_NOT_EMPTY_DIR = ERR_SANDBOX_CP_NOT_EMPTY_DIR;
629
+ const ERR_SANDBOX_CP_MKDIR = (dirPath) => `Error while creating directory ${dirPath}`;
630
+ exports.ERR_SANDBOX_CP_MKDIR = ERR_SANDBOX_CP_MKDIR;
631
+ const ERR_SANDBOX_CP_REPLACE = (dirPath) => `Error while replacing directory ${dirPath}`;
632
+ exports.ERR_SANDBOX_CP_REPLACE = ERR_SANDBOX_CP_REPLACE;
610
633
  exports.ERR_SANDBOX_CP_INVALID_DEST = 'Invalid destination format. Use: sandbox-identifier:/path';
634
+ exports.ERR_SANDBOX_CP_INVALID_SOURCE = 'Invalid source format. Use: sandbox-identifier:/path';
611
635
  // Sandbox exec command
612
636
  const TXT_SANDBOX_EXEC_ID = (id) => `Command id: ${id}`;
613
637
  exports.TXT_SANDBOX_EXEC_ID = TXT_SANDBOX_EXEC_ID;
@@ -649,7 +673,7 @@ exports.ERR_LOGIN_NO_WORKSPACES = 'No workspaces found for this token';
649
673
  exports.ERR_LOGIN_NO_WORKSPACE_FOUND = 'Provided workspace has been not found';
650
674
  exports.ERR_LOGIN_NO_PROJECT_FOUND = 'Provided project has been not found';
651
675
  exports.ERR_LOGIN_INVALID_BASE_URL = 'Invalid URL format';
652
- const ERR_API_MESSAGE_REPLACER = (message, path, baseUrl) => {
676
+ const ERR_API_MESSAGE_REPLACER = (message, path, baseUrl, rateLimitTs) => {
653
677
  let workspaceUrl = null;
654
678
  if (path && baseUrl) {
655
679
  const m = /\/workspaces\/([^/]+)\//.exec(path);
@@ -664,6 +688,9 @@ const ERR_API_MESSAGE_REPLACER = (message, path, baseUrl) => {
664
688
  message += `: ${workspaceUrl}`;
665
689
  }
666
690
  }
691
+ if (message === 'Rate limit exceeded') {
692
+ return (0, exports.ERR_REST_API_RATE_LIMIT)(rateLimitTs);
693
+ }
667
694
  return message;
668
695
  };
669
696
  exports.ERR_API_MESSAGE_REPLACER = ERR_API_MESSAGE_REPLACER;
@@ -692,15 +719,27 @@ exports.OPT_COMMAND_PACKAGE_VERSION = 'Package version';
692
719
  exports.ERR_COMMAND_PACKAGE_TYPE = 'Wrong package type. Allowed: FILE, CONTAINER';
693
720
  exports.TXT_PACKAGE_DELETED = 'Package deleted successfully';
694
721
  exports.TXT_PACKAGE_VERSION_DELETED = 'Package version deleted successfully';
695
- const TXT_PACKAGE_CREATED = (workspace, pkg) => {
722
+ const TXT_PACKAGE_CREATED = (baseUrl, workspace, pkg) => {
696
723
  let txt = `Package added: ${pkg.name} (${pkg.identifier})\n${pkg.html_url}\n\n`;
724
+ txt += (0, exports.TXT_PACKAGE_PUBLISH)(baseUrl, workspace, pkg);
725
+ return txt;
726
+ };
727
+ exports.TXT_PACKAGE_CREATED = TXT_PACKAGE_CREATED;
728
+ const TXT_PACKAGE_PUBLISH = (baseUrl, workspace, pkg) => {
729
+ let txt = '';
697
730
  if (pkg.type === utils_1.PACKAGE_TYPE.FILE) {
698
731
  txt += 'To publish a version:\n';
699
732
  txt += ` bdy pkg publish ${pkg.identifier}@1.0.0 ./dist`;
700
733
  }
734
+ else if (pkg.type === utils_1.PACKAGE_TYPE.CONTAINER) {
735
+ txt += 'Docker login:\n';
736
+ txt += ' bdy pkg docker login\n';
737
+ txt += 'Push:\n';
738
+ txt += ` docker push ${(0, utils_1.getDockerRegistryHostByApiBaseUrl)(baseUrl)}/${encodeURIComponent(workspace)}/${encodeURIComponent(pkg.identifier)}:latest`;
739
+ }
701
740
  return txt;
702
741
  };
703
- exports.TXT_PACKAGE_CREATED = TXT_PACKAGE_CREATED;
742
+ exports.TXT_PACKAGE_PUBLISH = TXT_PACKAGE_PUBLISH;
704
743
  const TXT_PACKAGE_VERSION_DOWNLOAD = (type, identifier, version, versionUrl) => {
705
744
  let txt = '';
706
745
  if (type === utils_1.PACKAGE_TYPE.FILE) {
@@ -43,16 +43,20 @@ exports.isFile = isFile;
43
43
  exports.getAppWorkspaceUrl = getAppWorkspaceUrl;
44
44
  exports.getAppWorkspaceSettingsUrl = getAppWorkspaceSettingsUrl;
45
45
  exports.getAppUrl = getAppUrl;
46
+ exports.untarGz = untarGz;
47
+ exports.unzipFile = unzipFile;
46
48
  exports.getDockerRegistryHostByApiBaseUrl = getDockerRegistryHostByApiBaseUrl;
47
49
  exports.getAppHostByApiBaseUrl = getAppHostByApiBaseUrl;
48
- const node_path_1 = __importStar(require("node:path"));
49
- const node_fs_1 = require("node:fs");
50
+ const node_path_1 = __importDefault(require("node:path"));
51
+ const node_fs_1 = __importStar(require("node:fs"));
50
52
  const texts_1 = require("./texts");
51
53
  const ssh2_1 = __importDefault(require("ssh2"));
52
54
  const node_sea_1 = require("node:sea");
53
55
  const commander_1 = require("commander");
54
56
  const node_os_1 = __importStar(require("node:os"));
55
57
  const node_child_process_1 = require("node:child_process");
58
+ const fflate_1 = require("fflate");
59
+ const tar_stream_1 = __importDefault(require("tar-stream"));
56
60
  exports.TUNNEL_HTTP_RATE_LIMIT = 2000;
57
61
  exports.TUNNEL_HTTP_RATE_WINDOW = 60000;
58
62
  exports.TUNNEL_HTTP_LOG_MAX_BODY = 5242880; // 5MB
@@ -388,7 +392,7 @@ const getVersion = () => {
388
392
  }
389
393
  else {
390
394
  const root = (0, exports.getRootDir)();
391
- packageJson = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.resolve)(root, 'package.json'), 'utf8'));
395
+ packageJson = JSON.parse((0, node_fs_1.readFileSync)(node_path_1.default.resolve(root, 'package.json'), 'utf8'));
392
396
  }
393
397
  cachedVersion = packageJson.version;
394
398
  }
@@ -577,6 +581,278 @@ function getAppWorkspaceSettingsUrl(baseUrl, workspace) {
577
581
  function getAppUrl(baseUrl, path) {
578
582
  return `https://${getAppHostByApiBaseUrl(baseUrl)}${path}`;
579
583
  }
584
+ function untarGz(dirPath, tarGzPath, onFile) {
585
+ return new Promise((resolve, reject) => {
586
+ let _startedFiles = 0;
587
+ let _finishedFiles = 0;
588
+ let _finishedStream = false;
589
+ let _finishedError = null;
590
+ let _calledResolve = false;
591
+ const rs = node_fs_1.default.createReadStream(tarGzPath);
592
+ const extract = tar_stream_1.default.extract();
593
+ const _finish = () => {
594
+ if (_finishedError || _finishedStream) {
595
+ try {
596
+ rs.removeAllListeners();
597
+ rs.close();
598
+ }
599
+ catch {
600
+ // do nothing
601
+ }
602
+ }
603
+ if (_calledResolve)
604
+ return;
605
+ if (_finishedError) {
606
+ _calledResolve = true;
607
+ reject(_finishedError);
608
+ return;
609
+ }
610
+ if (_finishedStream && _startedFiles === _finishedFiles) {
611
+ _calledResolve = true;
612
+ resolve();
613
+ }
614
+ };
615
+ const finishFile = (err, fws) => {
616
+ if (!_finishedError && err)
617
+ _finishedError = err;
618
+ const complete = () => {
619
+ _finishedFiles += 1;
620
+ onFile();
621
+ _finish();
622
+ };
623
+ if (fws) {
624
+ fws.once('finish', () => {
625
+ fws.removeAllListeners();
626
+ complete();
627
+ });
628
+ fws.end();
629
+ }
630
+ else {
631
+ complete();
632
+ }
633
+ };
634
+ const finishStream = (err) => {
635
+ if (!_finishedError && err)
636
+ _finishedError = err;
637
+ _finishedStream = true;
638
+ _finish();
639
+ };
640
+ extract.on('entry', async (header, stream, next) => {
641
+ if (_finishedError) {
642
+ stream.resume();
643
+ next();
644
+ return;
645
+ }
646
+ _startedFiles += 1;
647
+ const fullPath = node_path_1.default.join(dirPath, header.name);
648
+ const parentPath = node_path_1.default.dirname(fullPath);
649
+ let fws;
650
+ try {
651
+ await node_fs_1.default.promises.rm(fullPath, {
652
+ recursive: true,
653
+ force: true,
654
+ });
655
+ }
656
+ catch {
657
+ // do nothing
658
+ }
659
+ try {
660
+ if (header.type === 'directory') {
661
+ await node_fs_1.default.promises.mkdir(fullPath, {
662
+ recursive: true,
663
+ });
664
+ stream.resume();
665
+ finishFile();
666
+ next();
667
+ return;
668
+ }
669
+ await node_fs_1.default.promises.mkdir(parentPath, {
670
+ recursive: true,
671
+ });
672
+ fws = node_fs_1.default.createWriteStream(fullPath, {
673
+ flags: 'w',
674
+ });
675
+ fws.on('error', (err) => {
676
+ finishFile(err, fws);
677
+ });
678
+ }
679
+ catch (err) {
680
+ stream.resume();
681
+ finishFile(err, fws);
682
+ next();
683
+ return;
684
+ }
685
+ stream.on('data', (chunk) => {
686
+ if (_finishedError)
687
+ return;
688
+ if (fws) {
689
+ fws.write(chunk);
690
+ }
691
+ });
692
+ stream.on('end', () => {
693
+ finishFile(null, fws);
694
+ next();
695
+ });
696
+ stream.on('error', (err) => {
697
+ finishFile(err, fws);
698
+ next();
699
+ });
700
+ });
701
+ extract.on('finish', () => {
702
+ finishStream();
703
+ });
704
+ extract.on('error', (err) => {
705
+ finishStream(err);
706
+ });
707
+ const gunzip = new fflate_1.Gunzip((data, final) => {
708
+ if (_finishedError)
709
+ return;
710
+ extract.write(Buffer.from(data));
711
+ if (final) {
712
+ extract.end();
713
+ }
714
+ });
715
+ rs.on('data', (chunk) => {
716
+ try {
717
+ gunzip.push(chunk, false);
718
+ }
719
+ catch (err) {
720
+ finishStream(err);
721
+ }
722
+ });
723
+ rs.on('error', (err) => {
724
+ finishStream(err);
725
+ });
726
+ rs.on('end', () => {
727
+ try {
728
+ gunzip.push(new Uint8Array(0), true);
729
+ }
730
+ catch (err) {
731
+ finishStream(err);
732
+ }
733
+ });
734
+ });
735
+ }
736
+ function unzipFile(dirPath, zipPath, onFile) {
737
+ return new Promise((resolve, reject) => {
738
+ let _startedFiles = 0;
739
+ let _finishedFiles = 0;
740
+ let _finishedStream = false;
741
+ let _finishedError = null;
742
+ let _calledResolve = false;
743
+ const rs = node_fs_1.default.createReadStream(zipPath);
744
+ const _finish = () => {
745
+ if (_finishedError || _finishedStream) {
746
+ try {
747
+ rs.removeAllListeners();
748
+ rs.close();
749
+ }
750
+ catch {
751
+ // do nothing
752
+ }
753
+ }
754
+ if (_calledResolve)
755
+ return;
756
+ if (_finishedError) {
757
+ _calledResolve = true;
758
+ reject(_finishedError);
759
+ return;
760
+ }
761
+ if (_finishedStream && _startedFiles === _finishedFiles) {
762
+ _calledResolve = true;
763
+ resolve();
764
+ }
765
+ };
766
+ const finishFile = (err, fws) => {
767
+ if (!_finishedError && err)
768
+ _finishedError = err;
769
+ const complete = () => {
770
+ _finishedFiles += 1;
771
+ onFile();
772
+ _finish();
773
+ };
774
+ if (fws) {
775
+ fws.once('finish', () => {
776
+ fws.removeAllListeners();
777
+ complete();
778
+ });
779
+ fws.end();
780
+ }
781
+ else {
782
+ complete();
783
+ }
784
+ };
785
+ const finishStream = (err) => {
786
+ if (!_finishedError && err)
787
+ _finishedError = err;
788
+ _finishedStream = true;
789
+ _finish();
790
+ };
791
+ const unzip = new fflate_1.Unzip(async (file) => {
792
+ if (_finishedError)
793
+ return;
794
+ _startedFiles += 1;
795
+ const fullPath = node_path_1.default.join(dirPath, file.name);
796
+ const parentPath = node_path_1.default.dirname(fullPath);
797
+ let fws;
798
+ try {
799
+ await node_fs_1.default.promises.rm(fullPath, {
800
+ recursive: true,
801
+ force: true,
802
+ });
803
+ }
804
+ catch {
805
+ // do nothing
806
+ }
807
+ try {
808
+ if (fullPath.endsWith('/')) {
809
+ await node_fs_1.default.promises.mkdir(fullPath, {
810
+ recursive: true,
811
+ });
812
+ finishFile();
813
+ return;
814
+ }
815
+ await node_fs_1.default.promises.mkdir(parentPath, {
816
+ recursive: true,
817
+ });
818
+ fws = node_fs_1.default.createWriteStream(fullPath, {
819
+ flags: 'w',
820
+ });
821
+ fws.on('error', (err) => {
822
+ finishFile(err, fws);
823
+ });
824
+ }
825
+ catch (err) {
826
+ finishFile(err, fws);
827
+ return;
828
+ }
829
+ file.ondata = (err, data, final) => {
830
+ if (_finishedError)
831
+ return;
832
+ if (err)
833
+ finishFile(err, fws);
834
+ else {
835
+ if (fws)
836
+ fws.write(data);
837
+ if (final)
838
+ finishFile(null, fws);
839
+ }
840
+ };
841
+ file.start();
842
+ });
843
+ unzip.register(fflate_1.AsyncUnzipInflate);
844
+ rs.on('data', (chunk) => {
845
+ unzip.push(chunk, false);
846
+ });
847
+ rs.on('error', (err) => {
848
+ finishStream(err);
849
+ });
850
+ rs.on('end', () => {
851
+ unzip.push(new Uint8Array(0), true);
852
+ finishStream();
853
+ });
854
+ });
855
+ }
580
856
  function getDockerRegistryHostByApiBaseUrl(baseUrl) {
581
857
  if (baseUrl.hostname.includes('api.buddy.works')) {
582
858
  return 'container-pkg.buddy.works';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bdy",
3
3
  "preferGlobal": false,
4
- "version": "1.16.28-stage",
4
+ "version": "1.16.29-dev",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
7
7
  "scripts": {