bdy 1.16.28-stage → 1.16.30-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 (36) hide show
  1. package/distTs/package.json +1 -1
  2. package/distTs/src/api/client.js +32 -31
  3. package/distTs/src/command/package/create.js +10 -2
  4. package/distTs/src/command/package/delete.js +3 -1
  5. package/distTs/src/command/package/download.js +3 -120
  6. package/distTs/src/command/package/get.js +1 -1
  7. package/distTs/src/command/package/list.js +1 -1
  8. package/distTs/src/command/package/publish.js +4 -3
  9. package/distTs/src/command/package/version/delete.js +1 -0
  10. package/distTs/src/command/package/version/get.js +1 -0
  11. package/distTs/src/command/package/version/list.js +1 -0
  12. package/distTs/src/command/pipeline/run.js +1 -0
  13. package/distTs/src/command/sandbox/cp.js +79 -17
  14. package/distTs/src/command/sandbox/create.js +2 -15
  15. package/distTs/src/command/sandbox/endpoint/add.js +1 -0
  16. package/distTs/src/command/sandbox/endpoint/delete.js +1 -0
  17. package/distTs/src/command/sandbox/endpoint/get.js +1 -0
  18. package/distTs/src/command/sandbox/endpoint/list.js +1 -0
  19. package/distTs/src/command/sandbox/endpoint.js +4 -0
  20. package/distTs/src/command/sandbox/exec/command.js +1 -0
  21. package/distTs/src/command/sandbox/exec/kill.js +1 -0
  22. package/distTs/src/command/sandbox/exec/list.js +1 -0
  23. package/distTs/src/command/sandbox/exec/logs.js +1 -0
  24. package/distTs/src/command/sandbox/exec/status.js +1 -0
  25. package/distTs/src/command/sandbox/exec.js +5 -0
  26. package/distTs/src/command/sandbox/get.js +0 -1
  27. package/distTs/src/command/sandbox/snapshot/create.js +1 -0
  28. package/distTs/src/command/sandbox/snapshot/delete.js +1 -0
  29. package/distTs/src/command/sandbox/snapshot/get.js +1 -0
  30. package/distTs/src/command/sandbox/snapshot/list.js +2 -1
  31. package/distTs/src/command/sandbox/snapshot.js +4 -0
  32. package/distTs/src/command/sandbox/status.js +0 -1
  33. package/distTs/src/input.js +72 -2
  34. package/distTs/src/texts.js +234 -16
  35. package/distTs/src/utils.js +279 -3
  36. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bdy",
3
3
  "preferGlobal": false,
4
- "version": "1.16.28-stage",
4
+ "version": "1.16.30-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,20 @@ 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);
23
+ commandPackageCreate.addHelpText('after', texts_1.EXAMPLE_PACKAGE_CREATE);
22
24
  commandPackageCreate.action(async (name, options) => {
23
25
  const workspace = input_1.default.restApiWorkspace(options.workspace);
24
26
  const project = input_1.default.restApiProject(options.project, true);
25
27
  const client = input_1.default.restApiTokenClient(options.api, options.region, options.token);
26
28
  const type = input_1.default.packageType(options.type);
27
29
  const scope = input_1.default.packageScope(project);
30
+ if (!name) {
31
+ if (options.identifier)
32
+ name = options.identifier;
33
+ else
34
+ name = (0, human_id_1.default)({ separator: '-', capitalize: false });
35
+ }
28
36
  const data = {
29
37
  name,
30
38
  type,
@@ -54,6 +62,6 @@ commandPackageCreate.action(async (name, options) => {
54
62
  };
55
63
  }
56
64
  const result = await client.postPackage(workspace, data);
57
- output_1.default.exitSuccess((0, texts_1.TXT_PACKAGE_CREATED)(workspace, result));
65
+ output_1.default.exitSuccess((0, texts_1.TXT_PACKAGE_CREATED)(client.baseUrl, workspace, result));
58
66
  });
59
67
  exports.default = commandPackageCreate;
@@ -15,6 +15,7 @@ commandPackageDelete.option('--region <region>', texts_1.OPTION_REST_API_REGION)
15
15
  commandPackageDelete.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
16
16
  commandPackageDelete.option('-f, --force', texts_1.OPTION_CONFIRM_FORCE);
17
17
  commandPackageDelete.argument('<identifier>', texts_1.OPT_COMMAND_PACKAGE_IDENTIFIER);
18
+ commandPackageDelete.addHelpText('after', texts_1.EXAMPLE_PACKAGE_DELETE);
18
19
  commandPackageDelete.action(async (identifier, options) => {
19
20
  const workspace = input_1.default.restApiWorkspace(options.workspace);
20
21
  const client = input_1.default.restApiTokenClient(options.api, options.region, options.token);
@@ -25,7 +26,8 @@ commandPackageDelete.action(async (identifier, options) => {
25
26
  if (!data.pkg_id) {
26
27
  output_1.default.exitError(texts_1.ERR_PACKAGE_NOT_FOUND);
27
28
  }
28
- const confirmed = options.force || await output_1.default.confirm((0, texts_1.TXT_PACKAGE_DELETE_CONFIRM)(identifier));
29
+ const confirmed = options.force ||
30
+ (await output_1.default.confirm((0, texts_1.TXT_PACKAGE_DELETE_CONFIRM)(identifier)));
29
31
  if (confirmed) {
30
32
  await client.deletePackage(workspace, data.pkg_id);
31
33
  output_1.default.exitSuccess(texts_1.TXT_PACKAGE_DELETED);
@@ -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);
@@ -24,6 +23,7 @@ commandPackageDownload.option('-m, --merge', texts_1.OPTION_PACKAGE_DOWNLOAD_MER
24
23
  commandPackageDownload.option('-r, --replace', texts_1.OPTION_PACKAGE_DOWNLOAD_REPLACE);
25
24
  commandPackageDownload.argument('<identifier>', texts_1.OPTION_PACKAGE_ID);
26
25
  commandPackageDownload.argument('<directory>', texts_1.OPTION_PACKAGE_DOWNLOAD_PATH);
26
+ commandPackageDownload.addHelpText('after', texts_1.EXAMPLE_PACKAGE_DOWNLOAD);
27
27
  commandPackageDownload.action(async (id, path, options) => {
28
28
  const client = input_1.default.restApiTokenClient(options.api, options.region, options.token);
29
29
  const workspace = input_1.default.restApiWorkspace(options.workspace);
@@ -120,7 +120,7 @@ commandPackageDownload.action(async (id, path, options) => {
120
120
  output_1.default.normal(texts_1.TXT_PACKAGE_DOWNLOADED_ZIP);
121
121
  output_1.default.normal(texts_1.TXT_PACKAGE_UNZIPPING);
122
122
  let count = 0;
123
- await unzip(dirPath, zipPath, () => {
123
+ await (0, utils_1.unzipFile)(dirPath, zipPath, () => {
124
124
  count += 1;
125
125
  output_1.default.clearPreviousLine();
126
126
  output_1.default.normal((0, texts_1.TXT_PACKAGE_UNZIPPING_COUNT)(count));
@@ -136,121 +136,4 @@ commandPackageDownload.action(async (id, path, options) => {
136
136
  }
137
137
  output_1.default.exitSuccess((0, texts_1.TXT_PACKAGE_DOWNLOADED)(version, dirPath));
138
138
  });
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
139
  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;
@@ -23,6 +23,7 @@ commandPackagePublish.option('-c, --create', texts_1.OPTION_PACKAGE_PUBLISH_CREA
23
23
  commandPackagePublish.option('-f, --force', texts_1.OPTION_PACKAGE_PUBLISH_OVERWRITE_VERSION);
24
24
  commandPackagePublish.argument('<identifier>', texts_1.OPTION_PACKAGE_ID);
25
25
  commandPackagePublish.argument('<directory>', texts_1.OPTION_PACKAGE_PUBLISH_PATH);
26
+ commandPackagePublish.addHelpText('after', texts_1.EXAMPLE_PACKAGE_PUBLISH);
26
27
  commandPackagePublish.action(async (id, path, options) => {
27
28
  let dirPath = input_1.default.resolvePath(path);
28
29
  const workspace = input_1.default.restApiWorkspace(options.workspace);
@@ -48,13 +49,13 @@ commandPackagePublish.action(async (id, path, options) => {
48
49
  type: utils_1.PACKAGE_TYPE.FILE,
49
50
  scope: utils_1.PACKAGE_SCOPE.WORKSPACE,
50
51
  authorization: {
51
- type: utils_1.PACKAGE_AUTH_TYPE.BUDDY
52
- }
52
+ type: utils_1.PACKAGE_AUTH_TYPE.BUDDY,
53
+ },
53
54
  };
54
55
  if (project) {
55
56
  data.scope = utils_1.PACKAGE_SCOPE.PROJECT;
56
57
  data.project = {
57
- name: project
58
+ name: project,
58
59
  };
59
60
  }
60
61
  const d = await client.postPackage(workspace, data);
@@ -17,6 +17,7 @@ commandPackageVersionDelete.option('-p, --project <name>', texts_1.OPTION_REST_A
17
17
  commandPackageVersionDelete.argument('<identifier>', texts_1.OPT_COMMAND_PACKAGE_IDENTIFIER);
18
18
  commandPackageVersionDelete.option('-f, --force', texts_1.OPTION_CONFIRM_FORCE);
19
19
  commandPackageVersionDelete.argument('<version>', texts_1.OPT_COMMAND_PACKAGE_VERSION);
20
+ commandPackageVersionDelete.addHelpText('after', texts_1.EXAMPLE_PACKAGE_VERSION_DELETE);
20
21
  commandPackageVersionDelete.action(async (identifier, version, options) => {
21
22
  const workspace = input_1.default.restApiWorkspace(options.workspace);
22
23
  const project = input_1.default.restApiProject(options.project, true);
@@ -15,6 +15,7 @@ commandPackageVersionGet.option('-w, --workspace <domain>', texts_1.OPTION_REST_
15
15
  commandPackageVersionGet.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
16
16
  commandPackageVersionGet.argument('<identifier>', texts_1.OPT_COMMAND_PACKAGE_IDENTIFIER);
17
17
  commandPackageVersionGet.argument('<version>', texts_1.OPT_COMMAND_PACKAGE_VERSION);
18
+ commandPackageVersionGet.addHelpText('after', texts_1.EXAMPLE_PACKAGE_VERSION_GET);
18
19
  commandPackageVersionGet.action(async (identifier, version, options) => {
19
20
  const workspace = input_1.default.restApiWorkspace(options.workspace);
20
21
  const project = input_1.default.restApiProject(options.project, true);
@@ -17,6 +17,7 @@ commandPackageVersionList.option('--page <number>', texts_1.OPTION_REST_API_PAGE
17
17
  commandPackageVersionList.option('--per-page <number>', texts_1.OPTION_REST_API_PER_PAGE, '10');
18
18
  commandPackageVersionList.alias('ls');
19
19
  commandPackageVersionList.argument('<identifier>', texts_1.OPT_COMMAND_PACKAGE_IDENTIFIER);
20
+ commandPackageVersionList.addHelpText('after', texts_1.EXAMPLE_PACKAGE_VERSION_LIST);
20
21
  commandPackageVersionList.action(async (identifier, options) => {
21
22
  const page = input_1.default.restApiPage(options.page);
22
23
  const perPage = input_1.default.restApiPerPage(options.perPage);
@@ -29,6 +29,7 @@ commandPipelineRun.option('--action <actions...>', texts_1.OPTION_PIPELINE_RUN_A
29
29
  commandPipelineRun.option('--wait [minutes]', texts_1.OPTION_PIPELINE_RUN_WAIT);
30
30
  commandPipelineRun.argument('<identifier>', texts_1.OPTION_PIPELINE_RUN_ARGUMENT);
31
31
  commandPipelineRun.usage('<identifier> [options]');
32
+ commandPipelineRun.addHelpText('after', texts_1.EXAMPLE_PIPELINE_RUN);
32
33
  commandPipelineRun.action(async (identifier, options) => {
33
34
  const workspace = input_1.default.restApiWorkspace(options.workspace);
34
35
  const project = input_1.default.restApiProject(options.project);
@@ -9,34 +9,35 @@ 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
+ commandSandboxCp.addHelpText('after', texts_1.EXAMPLE_SANDBOX_CP);
26
+ const upload = async (client, workspace, project, source, destination) => {
27
+ const { sourcePath, sourceStats } = input_1.default.restApiSandboxUploadSourcePath(source);
28
+ const { identifier, remotePath } = input_1.default.restApiSandboxUploadDestinationPath(destination);
25
29
  const result = await client.listSandboxes(workspace, project);
26
30
  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
31
  const found = sandboxes.find((s) => s.identifier === identifier);
31
32
  if (!found) {
32
33
  output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
33
34
  }
34
35
  if (sourceStats.isFile()) {
35
36
  // 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);
37
+ const name = (0, path_1.basename)(sourcePath);
38
+ output_1.default.normal((0, texts_1.TXT_SANDBOX_CP_PROGRESS)(1, 1, name));
39
+ const remoteFile = (0, path_1.join)(remotePath, name);
40
+ await client.sandboxUploadFile(workspace, found.id, remoteFile, sourcePath);
40
41
  output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(1));
41
42
  }
42
43
  else if (sourceStats.isDirectory()) {
@@ -48,15 +49,13 @@ commandSandboxCp.action(async (source, destination, options) => {
48
49
  if (files.length === 0) {
49
50
  output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(0));
50
51
  }
51
- if (!silent)
52
- output_1.default.normal(`Copying ${files.length} file(s)...`);
52
+ output_1.default.normal('\n', false);
53
53
  for (let i = 0; i < files.length; i++) {
54
54
  const localFile = files[i];
55
55
  const relativePath = (0, path_1.relative)(sourcePath, localFile);
56
56
  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
- }
57
+ output_1.default.clearPreviousLine();
58
+ output_1.default.normal((0, texts_1.TXT_SANDBOX_CP_PROGRESS)(i + 1, files.length, relativePath));
60
59
  await client.sandboxUploadFile(workspace, found.id, remoteFile, localFile);
61
60
  }
62
61
  output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(files.length));
@@ -64,5 +63,68 @@ commandSandboxCp.action(async (source, destination, options) => {
64
63
  else {
65
64
  output_1.default.exitError((0, texts_1.ERR_SANDBOX_CP_SOURCE_NOT_FOUND)(source));
66
65
  }
66
+ };
67
+ const download = async (client, workspace, project, source, destination, merge, replace) => {
68
+ const destPath = input_1.default.restApiSandboxDownloadDestinationPath(destination, merge, replace);
69
+ const { sourcePath, identifier } = input_1.default.restApiSandboxDownloadSourcePath(source);
70
+ const result = await client.listSandboxes(workspace, project);
71
+ const sandboxes = result.sandboxes || [];
72
+ const found = sandboxes.find((s) => s.identifier === identifier);
73
+ if (!found) {
74
+ output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
75
+ }
76
+ output_1.default.normal(texts_1.TXT_SANDBOX_CP_DOWNLOAD, false);
77
+ const { body, headers } = await client.sandboxDownloadFile(workspace, found.id, sourcePath);
78
+ const isFile = headers['content-type'] === 'application/octet-stream';
79
+ if (isFile) {
80
+ const name = (0, path_1.basename)(sourcePath);
81
+ await node_fs_1.default.promises.writeFile((0, path_1.join)(destPath, name), body);
82
+ output_1.default.clearPreviousLine();
83
+ output_1.default.normal(texts_1.TXT_SANDBOX_CP_DOWNLOAD_DONE);
84
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(1));
85
+ }
86
+ else {
87
+ const zipPath = (0, path_1.join)((0, utils_1.getHomeDirectory)(), `${(0, uuid_1.v4)()}.tar.gz`);
88
+ const clearZip = () => {
89
+ try {
90
+ node_fs_1.default.rmSync(zipPath);
91
+ }
92
+ catch {
93
+ // do nothing
94
+ }
95
+ };
96
+ try {
97
+ await promises_1.default.pipeline(body, node_fs_1.default.createWriteStream(zipPath));
98
+ output_1.default.clearPreviousLine();
99
+ output_1.default.normal(texts_1.TXT_SANDBOX_CP_DOWNLOAD_DONE);
100
+ output_1.default.normal(texts_1.TXT_SANDBOX_UNZIP);
101
+ let count = 0;
102
+ await (0, utils_1.untarGz)(destPath, zipPath, () => {
103
+ count += 1;
104
+ output_1.default.clearPreviousLine();
105
+ output_1.default.normal((0, texts_1.TXT_SANDBOX_UNZIPPING_COUNT)(count));
106
+ });
107
+ clearZip();
108
+ output_1.default.clearPreviousLine();
109
+ output_1.default.normal(texts_1.TXT_SANDBOX_UNZIP_DONE);
110
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(count));
111
+ }
112
+ catch {
113
+ clearZip();
114
+ output_1.default.exitError(texts_1.ERR_SWW);
115
+ }
116
+ }
117
+ };
118
+ commandSandboxCp.action(async (source, destination, options) => {
119
+ const workspace = input_1.default.restApiWorkspace(options.workspace);
120
+ const project = input_1.default.restApiProject(options.project);
121
+ const client = input_1.default.restApiTokenClient(options.api, options.region, options.token);
122
+ const isUpload = input_1.default.restApiSandboxIsUpload(destination);
123
+ if (isUpload) {
124
+ await upload(client, workspace, project, source, destination);
125
+ }
126
+ else {
127
+ await download(client, workspace, project, source, destination, !!options.merge, !!options.replace);
128
+ }
67
129
  });
68
130
  exports.default = commandSandboxCp;
@@ -41,7 +41,7 @@ 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);
44
+ commandSandboxCreate.addHelpText('after', texts_1.EXAMPLE_SANDBOX_CREATE);
45
45
  commandSandboxCreate.action(async (options) => {
46
46
  const workspace = input_1.default.restApiWorkspace(options.workspace);
47
47
  const project = input_1.default.restApiProject(options.project);
@@ -53,7 +53,7 @@ commandSandboxCreate.action(async (options) => {
53
53
  const baseName = (0, human_id_1.default)({ separator: '-', capitalize: false });
54
54
  const defaultIdentifier = `${baseName}-${timestamp}`;
55
55
  const body = {
56
- name: options.name || baseName,
56
+ name: options.name || options.identifier || baseName,
57
57
  identifier: options.identifier || defaultIdentifier,
58
58
  };
59
59
  if (options.snapshot) {
@@ -124,19 +124,6 @@ commandSandboxCreate.action(async (options) => {
124
124
  output_1.default.exitError(texts_1.ERR_SANDBOX_SETUP_TIMEOUT);
125
125
  }
126
126
  }
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
127
  output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CREATED)(result.identifier, result.html_url));
141
128
  });
142
129
  exports.default = commandSandboxCreate;
@@ -10,6 +10,7 @@ const input_1 = __importDefault(require("../../../input"));
10
10
  const logger_1 = __importDefault(require("../../../logger"));
11
11
  const commandSandboxEndpointAdd = (0, utils_1.getBasicCommandSandboxEndpoint)('add', texts_1.DESC_COMMAND_SANDBOX_ENDPOINT_ADD);
12
12
  commandSandboxEndpointAdd.alias('create');
13
+ commandSandboxEndpointAdd.addHelpText('after', `\nEXAMPLES:${texts_1.EXAMPLE_SANDBOX_ENDPOINT_CREATE}`);
13
14
  commandSandboxEndpointAdd.action(async (identifier, options) => {
14
15
  const workspace = input_1.default.restApiWorkspace(options.workspace);
15
16
  const project = input_1.default.restApiProject(options.project);
@@ -17,6 +17,7 @@ commandSandboxEndpointDelete.option('-p, --project <name>', texts_1.OPTION_REST_
17
17
  commandSandboxEndpointDelete.option('-f, --force', texts_1.OPTION_CONFIRM_FORCE);
18
18
  commandSandboxEndpointDelete.argument('<identifier>', texts_1.OPTION_SANDBOX_IDENTIFIER);
19
19
  commandSandboxEndpointDelete.argument('<endpoint-name>', texts_1.OPTION_SANDBOX_ENDPOINT_NAME_ARG);
20
+ commandSandboxEndpointDelete.addHelpText('after', `\nEXAMPLES:${texts_1.EXAMPLE_SANDBOX_ENDPOINT_DELETE}`);
20
21
  commandSandboxEndpointDelete.action(async (identifier, endpointName, options) => {
21
22
  const workspace = input_1.default.restApiWorkspace(options.workspace);
22
23
  const project = input_1.default.restApiProject(options.project);
@@ -15,6 +15,7 @@ commandSandboxEndpointGet.option('-w, --workspace <domain>', texts_1.OPTION_REST
15
15
  commandSandboxEndpointGet.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
16
16
  commandSandboxEndpointGet.argument('<identifier>', texts_1.OPTION_SANDBOX_IDENTIFIER);
17
17
  commandSandboxEndpointGet.argument('<endpoint-name>', texts_1.OPTION_SANDBOX_ENDPOINT_NAME_ARG);
18
+ commandSandboxEndpointGet.addHelpText('after', `\nEXAMPLES:${texts_1.EXAMPLE_SANDBOX_ENDPOINT_GET}`);
18
19
  commandSandboxEndpointGet.action(async (identifier, endpointName, options) => {
19
20
  const workspace = input_1.default.restApiWorkspace(options.workspace);
20
21
  const project = input_1.default.restApiProject(options.project);