bdy 1.17.5-dev → 1.17.6-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/distTs/package.json +1 -1
- package/distTs/src/api/client.js +19 -4
- package/distTs/src/command/login.js +3 -6
- package/distTs/src/command/package/create.js +1 -1
- package/distTs/src/command/package/publish.js +3 -3
- package/distTs/src/command/pipeline/run.js +1 -1
- package/distTs/src/command/project/git/credential.js +89 -0
- package/distTs/src/command/project/git.js +11 -0
- package/distTs/src/command/project/link.js +178 -0
- package/distTs/src/command/project/set.js +4 -12
- package/distTs/src/command/project.js +4 -0
- package/distTs/src/command/whoami.js +8 -18
- package/distTs/src/input.js +5 -0
- package/distTs/src/output.js +46 -23
- package/distTs/src/project/cfg.js +52 -0
- package/distTs/src/texts.js +32 -9
- package/distTs/src/utils.js +28 -4
- package/package.json +1 -1
package/distTs/package.json
CHANGED
package/distTs/src/api/client.js
CHANGED
|
@@ -248,7 +248,15 @@ class ApiClient {
|
|
|
248
248
|
parseResponseBody: true,
|
|
249
249
|
});
|
|
250
250
|
}
|
|
251
|
-
async
|
|
251
|
+
async createProject(workspace, body) {
|
|
252
|
+
return await this.request({
|
|
253
|
+
method: 'POST',
|
|
254
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/projects`,
|
|
255
|
+
body,
|
|
256
|
+
parseResponseBody: true
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
async pipelineRun(workspace, project, pipelineId, body) {
|
|
252
260
|
return await this.request({
|
|
253
261
|
method: 'POST',
|
|
254
262
|
path: `/workspaces/${encodeURIComponent(workspace)}/projects/${encodeURIComponent(project)}/pipelines/${encodeURIComponent(pipelineId)}/executions`,
|
|
@@ -534,6 +542,13 @@ class ApiClient {
|
|
|
534
542
|
parseResponseBody: true,
|
|
535
543
|
});
|
|
536
544
|
}
|
|
545
|
+
async getProject(workspace, project) {
|
|
546
|
+
return await this.request({
|
|
547
|
+
method: 'GET',
|
|
548
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/projects/${encodeURIComponent(project)}`,
|
|
549
|
+
parseResponseBody: true
|
|
550
|
+
});
|
|
551
|
+
}
|
|
537
552
|
async getProjects(workspace, page = 1, perPage = 100) {
|
|
538
553
|
const query = {
|
|
539
554
|
page: page.toString(),
|
|
@@ -628,7 +643,7 @@ class ApiClient {
|
|
|
628
643
|
rawResponseBody: true,
|
|
629
644
|
});
|
|
630
645
|
}
|
|
631
|
-
async
|
|
646
|
+
async createPackageVersion(workspace, pkgId, version) {
|
|
632
647
|
return await this.request({
|
|
633
648
|
method: 'POST',
|
|
634
649
|
path: `/workspaces/${encodeURIComponent(workspace)}/packages/${encodeURIComponent(pkgId)}/versions`,
|
|
@@ -638,7 +653,7 @@ class ApiClient {
|
|
|
638
653
|
parseResponseBody: true,
|
|
639
654
|
});
|
|
640
655
|
}
|
|
641
|
-
async
|
|
656
|
+
async createPackageVersionZip(workspace, pkgId, versionId, file) {
|
|
642
657
|
const form = new undici_1.FormData();
|
|
643
658
|
form.append('file', file);
|
|
644
659
|
return await this.request({
|
|
@@ -648,7 +663,7 @@ class ApiClient {
|
|
|
648
663
|
parseResponseBody: true,
|
|
649
664
|
});
|
|
650
665
|
}
|
|
651
|
-
async
|
|
666
|
+
async createPackage(workspace, data) {
|
|
652
667
|
return await this.request({
|
|
653
668
|
method: 'POST',
|
|
654
669
|
path: `/workspaces/${encodeURIComponent(workspace)}/packages`,
|
|
@@ -31,7 +31,7 @@ const OAUTH_CLIENT_APP_SCOPES = [
|
|
|
31
31
|
'SANDBOX_MANAGE',
|
|
32
32
|
'PACKAGE_MANAGE',
|
|
33
33
|
'TUNNEL_MANAGE',
|
|
34
|
-
'UNIT_TEST_MANAGE'
|
|
34
|
+
'UNIT_TEST_MANAGE',
|
|
35
35
|
];
|
|
36
36
|
function normalizeBaseUrl(url) {
|
|
37
37
|
let normalized = url.trim();
|
|
@@ -161,14 +161,11 @@ async function authorizeToken(api, token, refreshToken, clientId, clientSecret,
|
|
|
161
161
|
workspace = await output_1.default.selectWorkspace(w.workspaces);
|
|
162
162
|
}
|
|
163
163
|
cfg_1.default.setWorkspace(workspace);
|
|
164
|
-
const p = await client.getProjects(workspace);
|
|
165
164
|
if (project) {
|
|
166
|
-
|
|
167
|
-
if (!found) {
|
|
168
|
-
output_1.default.exitError(texts_1.ERR_LOGIN_NO_PROJECT_FOUND);
|
|
169
|
-
}
|
|
165
|
+
await client.getProject(workspace, project);
|
|
170
166
|
}
|
|
171
167
|
else {
|
|
168
|
+
const p = await client.getProjects(workspace);
|
|
172
169
|
project = await output_1.default.selectProject(p.projects);
|
|
173
170
|
}
|
|
174
171
|
cfg_1.default.setProject(project);
|
|
@@ -58,7 +58,7 @@ commandPackageCreate.action(async (name, options) => {
|
|
|
58
58
|
type: utils_1.PACKAGE_AUTH_TYPE.BUDDY,
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
|
-
const result = await client.
|
|
61
|
+
const result = await client.createPackage(workspace, data);
|
|
62
62
|
output_1.default.exitSuccess((0, texts_1.TXT_PACKAGE_CREATED)(client.baseUrl, workspace, result));
|
|
63
63
|
});
|
|
64
64
|
exports.default = commandPackageCreate;
|
|
@@ -55,7 +55,7 @@ commandPackagePublish.action(async (id, path, options) => {
|
|
|
55
55
|
name: project,
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
-
const d = await client.
|
|
58
|
+
const d = await client.createPackage(workspace, data);
|
|
59
59
|
packageId = d.id;
|
|
60
60
|
}
|
|
61
61
|
else {
|
|
@@ -68,7 +68,7 @@ commandPackagePublish.action(async (id, path, options) => {
|
|
|
68
68
|
output_1.default.exitError(texts_1.ERR_PACKAGE_VERSION_EXISTS);
|
|
69
69
|
}
|
|
70
70
|
if (!packageVersionId) {
|
|
71
|
-
const d = await client.
|
|
71
|
+
const d = await client.createPackageVersion(workspace, packageId, version);
|
|
72
72
|
url = d.version_url;
|
|
73
73
|
packageVersionId = d.id;
|
|
74
74
|
}
|
|
@@ -141,7 +141,7 @@ commandPackagePublish.action(async (id, path, options) => {
|
|
|
141
141
|
}
|
|
142
142
|
try {
|
|
143
143
|
output_1.default.normal(texts_1.TXT_PACKAGE_UPLOADING);
|
|
144
|
-
await client.
|
|
144
|
+
await client.createPackageVersionZip(workspace, packageId, packageVersionId, blob);
|
|
145
145
|
output_1.default.clearPreviousLine();
|
|
146
146
|
output_1.default.normal(texts_1.TXT_PACKAGE_UPLOADED);
|
|
147
147
|
clearZip();
|
|
@@ -90,7 +90,7 @@ commandPipelineRun.action(async (identifier, options) => {
|
|
|
90
90
|
if (actions) {
|
|
91
91
|
body.actions_to_run = actions;
|
|
92
92
|
}
|
|
93
|
-
const result = await client.
|
|
93
|
+
const result = await client.pipelineRun(workspace, project, data.pipeline_id, body);
|
|
94
94
|
if (options.wait) {
|
|
95
95
|
const minutes = input_1.default.pipelineRunWaitTime(options.wait);
|
|
96
96
|
wait(minutes, workspace, project, data.pipeline_id, result.id, result.html_url, client);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const utils_1 = require("../../../utils");
|
|
40
|
+
const texts_1 = require("../../../texts");
|
|
41
|
+
const readline = __importStar(require("node:readline"));
|
|
42
|
+
const output_1 = __importDefault(require("../../../output"));
|
|
43
|
+
const input_1 = __importDefault(require("../../../input"));
|
|
44
|
+
const commandProjectGitCredential = (0, utils_1.newCommand)('credential', texts_1.DESC_COMMAND_PROJECT_GIT_CREDENTIAL);
|
|
45
|
+
commandProjectGitCredential.hideVersionUpdate = true;
|
|
46
|
+
commandProjectGitCredential.argument('[action]');
|
|
47
|
+
commandProjectGitCredential.action(async (action) => {
|
|
48
|
+
if (action !== 'get') {
|
|
49
|
+
output_1.default.exitNormal();
|
|
50
|
+
}
|
|
51
|
+
const input = await parseGitInput();
|
|
52
|
+
try {
|
|
53
|
+
const client = input_1.default.restApiTokenClient();
|
|
54
|
+
const email = await (0, utils_1.tryGetEmail)(client);
|
|
55
|
+
const workspace = input_1.default.restApiWorkspace();
|
|
56
|
+
let myHost = input.host === 'app.local.io';
|
|
57
|
+
if (!myHost) {
|
|
58
|
+
const projects = await client.getProjects(workspace, 1, 1);
|
|
59
|
+
myHost =
|
|
60
|
+
projects.projects.length > 0 &&
|
|
61
|
+
projects.projects[0].html_url.includes(input.host);
|
|
62
|
+
}
|
|
63
|
+
if (email && myHost) {
|
|
64
|
+
output_1.default.normal(`protocol=${input.protocol || 'https'}`);
|
|
65
|
+
output_1.default.normal(`host=${input.host}`);
|
|
66
|
+
output_1.default.normal(`username=${email}`);
|
|
67
|
+
output_1.default.normal(`password=${client.token}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// do nothing
|
|
72
|
+
}
|
|
73
|
+
output_1.default.exitNormal();
|
|
74
|
+
});
|
|
75
|
+
const parseGitInput = async () => {
|
|
76
|
+
const result = {};
|
|
77
|
+
const rl = readline.createInterface({
|
|
78
|
+
input: process.stdin,
|
|
79
|
+
terminal: false,
|
|
80
|
+
});
|
|
81
|
+
for await (const line of rl) {
|
|
82
|
+
if (!line.trim())
|
|
83
|
+
break;
|
|
84
|
+
const [key, ...valueParts] = line.split('=');
|
|
85
|
+
result[key] = valueParts.join('=');
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
};
|
|
89
|
+
exports.default = commandProjectGitCredential;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const utils_1 = require("../../utils");
|
|
7
|
+
const texts_1 = require("../../texts");
|
|
8
|
+
const credential_1 = __importDefault(require("./git/credential"));
|
|
9
|
+
const commandProjectGit = (0, utils_1.newCommand)('git', texts_1.DESC_COMMAND_PROJECT_GIT);
|
|
10
|
+
commandProjectGit.addCommand(credential_1.default, { hidden: true });
|
|
11
|
+
exports.default = commandProjectGit;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const utils_1 = require("../../utils");
|
|
7
|
+
const texts_1 = require("../../texts");
|
|
8
|
+
const input_1 = __importDefault(require("../../input"));
|
|
9
|
+
const output_1 = __importDefault(require("../../output"));
|
|
10
|
+
const cfg_1 = __importDefault(require("../../project/cfg"));
|
|
11
|
+
const node_path_1 = require("node:path");
|
|
12
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
13
|
+
const human_id_1 = __importDefault(require("human-id"));
|
|
14
|
+
const commandProjectLink = (0, utils_1.newCommand)('link', texts_1.DESC_COMMAND_PROJECT_LINK);
|
|
15
|
+
commandProjectLink.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
|
|
16
|
+
commandProjectLink.option('-r, --relink', texts_1.OPT_COMMAND_PROJECT_LINK_RELINK);
|
|
17
|
+
commandProjectLink.option('-g, --git', texts_1.OPT_COMMAND_PROJECT_LINK_GIT);
|
|
18
|
+
commandProjectLink.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
|
|
19
|
+
commandProjectLink.argument('<directory>', texts_1.OPT_COMMAND_PROJECT_LINK_DIRECTORY);
|
|
20
|
+
commandProjectLink.action(async (dir, options) => {
|
|
21
|
+
output_1.default.handleSignals();
|
|
22
|
+
const { path, git } = await checkPath(dir, options);
|
|
23
|
+
const { workspace, project } = await createOrGetProject(options);
|
|
24
|
+
cfg_1.default.init(path, workspace, project);
|
|
25
|
+
await initRepo(workspace, project, path, git, options);
|
|
26
|
+
output_1.default.exitSuccess((0, texts_1.TXT_COMMAND_PROJECT_LINKED)(project, path));
|
|
27
|
+
});
|
|
28
|
+
const getProjectRemote = (data) => {
|
|
29
|
+
if (!data.integration) {
|
|
30
|
+
return {
|
|
31
|
+
remote: data.http_repository,
|
|
32
|
+
external: false,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
external: true,
|
|
37
|
+
remote: data.http_repository,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
const getRemoteNames = (str) => {
|
|
41
|
+
const names = {};
|
|
42
|
+
(str || '').split('\n').forEach((s) => {
|
|
43
|
+
const m = s.match(/^(\S+)\s+(\S+)/);
|
|
44
|
+
if (m) {
|
|
45
|
+
names[m[1]] = m[2];
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return names;
|
|
49
|
+
};
|
|
50
|
+
const initRepo = async (workspace, project, path, git, options) => {
|
|
51
|
+
const client = input_1.default.restApiTokenClient();
|
|
52
|
+
const data = await client.getProject(workspace, project);
|
|
53
|
+
const { remote } = getProjectRemote(data);
|
|
54
|
+
let repo = options.git;
|
|
55
|
+
if (!repo)
|
|
56
|
+
repo = await output_1.default.confirm(texts_1.TXT_COMMAND_PROJECT_LINK_GIT_REPO);
|
|
57
|
+
if (!repo)
|
|
58
|
+
return;
|
|
59
|
+
if (!git) {
|
|
60
|
+
await (0, utils_1.execLocally)('git init', {
|
|
61
|
+
cwd: path,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const str = await (0, utils_1.execLocally)('git remote -v', {
|
|
65
|
+
cwd: path,
|
|
66
|
+
});
|
|
67
|
+
const remotes = getRemoteNames(str);
|
|
68
|
+
if (!remotes.origin) {
|
|
69
|
+
await (0, utils_1.execLocally)(`git remote add origin ${remote}`, {
|
|
70
|
+
cwd: path,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
else if (remotes.origin !== remote) {
|
|
74
|
+
output_1.default.normal(texts_1.OPT_COMMAND_PROJECT_LINK_HAS_REMOTE);
|
|
75
|
+
output_1.default.normal(`Local: ${remotes.origin}`);
|
|
76
|
+
output_1.default.normal(`Project: ${remote}`);
|
|
77
|
+
const idx = await output_1.default.inputMenu([
|
|
78
|
+
'Add project remote as "buddy" (keep both)',
|
|
79
|
+
'Replace "origin" with project remote',
|
|
80
|
+
'Cancel',
|
|
81
|
+
]);
|
|
82
|
+
if (idx === 0) {
|
|
83
|
+
if (remotes.buddy) {
|
|
84
|
+
await (0, utils_1.execLocally)(`git remote rm buddy`, {
|
|
85
|
+
cwd: path,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
await (0, utils_1.execLocally)(`git remote add buddy ${remote}`, {
|
|
89
|
+
cwd: path,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
else if (idx === 1) {
|
|
93
|
+
await (0, utils_1.execLocally)(`git remote rm origin`, {
|
|
94
|
+
cwd: path,
|
|
95
|
+
});
|
|
96
|
+
await (0, utils_1.execLocally)(`git remote add origin ${remote}`, {
|
|
97
|
+
cwd: path,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
output_1.default.exitNormal();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
await (0, utils_1.execLocally)("git config credential.helper '!bdy project git credential'", {
|
|
105
|
+
cwd: path,
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
const checkPath = async (dir, options) => {
|
|
109
|
+
const path = (0, node_path_1.resolve)(dir);
|
|
110
|
+
try {
|
|
111
|
+
const stat = await node_fs_1.default.promises.stat(path);
|
|
112
|
+
if (!stat.isDirectory()) {
|
|
113
|
+
output_1.default.exitError(texts_1.ERR_COMMAND_PROJECT_LINK_DIR_NOT_DIR);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
try {
|
|
118
|
+
await node_fs_1.default.promises.mkdir(path, {
|
|
119
|
+
recursive: true,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
output_1.default.exitError((0, texts_1.ERR_COMMAND_PROJECT_LINK_DIR_CREATE)(path));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (cfg_1.default.exists(path)) {
|
|
127
|
+
output_1.default.normal(texts_1.TXT_COMMAND_PROJECT_LINK_DIR_LINKED);
|
|
128
|
+
let relink = options.relink;
|
|
129
|
+
if (!relink)
|
|
130
|
+
relink = await output_1.default.confirm(texts_1.TXT_COMMAND_PROJECT_LINK_DIR_CONFIRM);
|
|
131
|
+
if (!relink)
|
|
132
|
+
output_1.default.exitNormal();
|
|
133
|
+
}
|
|
134
|
+
const children = await node_fs_1.default.promises.readdir(path);
|
|
135
|
+
const git = !!children.find((name) => name === '.git');
|
|
136
|
+
return { path, git };
|
|
137
|
+
};
|
|
138
|
+
const createOrGetProject = async (options) => {
|
|
139
|
+
const workspace = input_1.default.restApiWorkspace(options.workspace);
|
|
140
|
+
const client = input_1.default.restApiTokenClient();
|
|
141
|
+
let project = options.project;
|
|
142
|
+
if (project) {
|
|
143
|
+
try {
|
|
144
|
+
await client.getProject(workspace, project);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
output_1.default.normal((0, texts_1.TXT_COMMAND_PROJECT_LINK_NOT_FOUND)(project));
|
|
148
|
+
const response = await client.createProject(workspace, {
|
|
149
|
+
display_name: project,
|
|
150
|
+
});
|
|
151
|
+
project = String(response.name || '');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const existingProject = await output_1.default.confirm(texts_1.TXT_COMMAND_PROJECT_LINK_NEW);
|
|
156
|
+
if (!existingProject) {
|
|
157
|
+
output_1.default.normal(texts_1.TXT_COMMAND_PROJECT_LINK_NAME);
|
|
158
|
+
let name = await output_1.default.inputString();
|
|
159
|
+
if (!name) {
|
|
160
|
+
name = (0, human_id_1.default)({ separator: '-', capitalize: false });
|
|
161
|
+
output_1.default.normal((0, texts_1.TXT_COMMAND_PROJECT_LINK_RANDOM)(name));
|
|
162
|
+
}
|
|
163
|
+
const response = await client.createProject(workspace, {
|
|
164
|
+
display_name: name,
|
|
165
|
+
});
|
|
166
|
+
project = String(response.name || '');
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
const response = await client.getProjects(workspace);
|
|
170
|
+
if (!response.projects || response.projects.length === 0) {
|
|
171
|
+
output_1.default.exitError(texts_1.ERR_PROJECT_NO_PROJECTS);
|
|
172
|
+
}
|
|
173
|
+
project = await output_1.default.selectProject(response.projects, false);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return { project, workspace };
|
|
177
|
+
};
|
|
178
|
+
exports.default = commandProjectLink;
|
|
@@ -11,23 +11,15 @@ const input_1 = __importDefault(require("../../input"));
|
|
|
11
11
|
const commandProjectSet = (0, utils_1.newCommand)('set', texts_1.DESC_COMMAND_PROJECT_SET);
|
|
12
12
|
commandProjectSet.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
|
|
13
13
|
commandProjectSet.argument('[project]', texts_1.ARG_COMMAND_PROJECT_NAME);
|
|
14
|
-
commandProjectSet.action(async (
|
|
14
|
+
commandProjectSet.action(async (project, options) => {
|
|
15
15
|
output_1.default.handleSignals();
|
|
16
16
|
const workspace = input_1.default.restApiWorkspace(options.workspace);
|
|
17
17
|
const client = input_1.default.restApiTokenClient();
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
output_1.default.exitError(texts_1.ERR_PROJECT_NO_PROJECTS);
|
|
21
|
-
}
|
|
22
|
-
let project;
|
|
23
|
-
if (projectName) {
|
|
24
|
-
const found = response.projects.find((p) => p.name === projectName);
|
|
25
|
-
if (!found) {
|
|
26
|
-
output_1.default.exitError(texts_1.ERR_PROJECT_NOT_FOUND);
|
|
27
|
-
}
|
|
28
|
-
project = found.name;
|
|
18
|
+
if (project) {
|
|
19
|
+
await client.getProject(workspace, project);
|
|
29
20
|
}
|
|
30
21
|
else {
|
|
22
|
+
const response = await client.getProjects(workspace);
|
|
31
23
|
project = await output_1.default.selectProject(response.projects);
|
|
32
24
|
}
|
|
33
25
|
cfg_1.default.setProject(project);
|
|
@@ -8,9 +8,13 @@ const utils_1 = require("../utils");
|
|
|
8
8
|
const list_1 = __importDefault(require("./project/list"));
|
|
9
9
|
const set_1 = __importDefault(require("./project/set"));
|
|
10
10
|
const get_1 = __importDefault(require("./project/get"));
|
|
11
|
+
const link_1 = __importDefault(require("./project/link"));
|
|
12
|
+
const git_1 = __importDefault(require("./project/git"));
|
|
11
13
|
const commandProject = (0, utils_1.newCommand)('project', texts_1.DESC_COMMAND_PROJECT);
|
|
12
14
|
commandProject.alias('proj');
|
|
13
15
|
commandProject.addCommand(list_1.default);
|
|
14
16
|
commandProject.addCommand(set_1.default);
|
|
15
17
|
commandProject.addCommand(get_1.default);
|
|
18
|
+
commandProject.addCommand(link_1.default);
|
|
19
|
+
commandProject.addCommand(git_1.default, { hidden: true });
|
|
16
20
|
exports.default = commandProject;
|
|
@@ -8,34 +8,24 @@ const texts_1 = require("../texts");
|
|
|
8
8
|
const cfg_1 = __importDefault(require("../tunnel/cfg"));
|
|
9
9
|
const output_1 = __importDefault(require("../output"));
|
|
10
10
|
const input_1 = __importDefault(require("../input"));
|
|
11
|
-
const
|
|
12
|
-
try {
|
|
13
|
-
const result = await client.getInvokerEmails();
|
|
14
|
-
if (result && result.emails) {
|
|
15
|
-
const e = result.emails.find((e) => e.confirmed);
|
|
16
|
-
if (e) {
|
|
17
|
-
return e.email;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
// do nothing
|
|
23
|
-
}
|
|
24
|
-
return null;
|
|
25
|
-
};
|
|
11
|
+
const cfg_2 = __importDefault(require("../project/cfg"));
|
|
26
12
|
const commandWhoami = (0, utils_1.newCommand)('whoami', texts_1.DESC_COMMAND_WHOAMI);
|
|
27
13
|
commandWhoami.action(async () => {
|
|
28
14
|
const workspace = cfg_1.default.getWorkspace();
|
|
29
15
|
const project = cfg_1.default.getProject();
|
|
16
|
+
const localWorkspace = cfg_2.default.getWorkspace();
|
|
17
|
+
const localProject = cfg_2.default.getProject();
|
|
30
18
|
const client = input_1.default.restApiTokenClient();
|
|
31
19
|
const user = await client.getInvoker();
|
|
32
20
|
if (!user) {
|
|
33
21
|
output_1.default.exitError(texts_1.ERR_WHOAMI_LOGOUT);
|
|
34
22
|
}
|
|
35
|
-
const email = await tryGetEmail(client);
|
|
23
|
+
const email = await (0, utils_1.tryGetEmail)(client);
|
|
36
24
|
output_1.default.normal(`User: ${user.name}${email ? ` (${email})` : ''}`);
|
|
37
|
-
output_1.default.normal(`
|
|
38
|
-
output_1.default.normal(`
|
|
25
|
+
output_1.default.normal(`Global workspace: ${!workspace ? texts_1.TXT_WHOAMI_NO_WORKSPACE : workspace}`);
|
|
26
|
+
output_1.default.normal(`Global project: ${!project ? texts_1.TXT_WHOAMI_NO_PROJECT : project}`);
|
|
27
|
+
output_1.default.normal(`Local workspace: ${!localWorkspace ? texts_1.TXT_WHOAMI_NO_LOCAL_LINK : localWorkspace}`);
|
|
28
|
+
output_1.default.normal(`Local project: ${!localProject ? texts_1.TXT_WHOAMI_NO_LOCAL_LINK : localProject}`);
|
|
39
29
|
output_1.default.exitNormal();
|
|
40
30
|
});
|
|
41
31
|
exports.default = commandWhoami;
|
package/distTs/src/input.js
CHANGED
|
@@ -48,6 +48,7 @@ const texts_1 = require("./texts");
|
|
|
48
48
|
const tunnel_1 = require("./types/tunnel");
|
|
49
49
|
const node_path_1 = __importStar(require("node:path"));
|
|
50
50
|
const cfg_1 = __importDefault(require("./tunnel/cfg"));
|
|
51
|
+
const cfg_2 = __importDefault(require("./project/cfg"));
|
|
51
52
|
const client_1 = __importDefault(require("./api/client"));
|
|
52
53
|
class Input {
|
|
53
54
|
static timeout(timeout) {
|
|
@@ -471,6 +472,8 @@ class Input {
|
|
|
471
472
|
let w = process.env.BUDDY_WORKSPACE;
|
|
472
473
|
if (workspace)
|
|
473
474
|
w = workspace;
|
|
475
|
+
if (!w)
|
|
476
|
+
w = cfg_2.default.getWorkspace();
|
|
474
477
|
if (!w)
|
|
475
478
|
w = cfg_1.default.getWorkspace();
|
|
476
479
|
if (!w) {
|
|
@@ -638,6 +641,8 @@ class Input {
|
|
|
638
641
|
let p = process.env.BUDDY_PROJECT;
|
|
639
642
|
if (project)
|
|
640
643
|
p = project;
|
|
644
|
+
if (!p)
|
|
645
|
+
p = cfg_2.default.getProject();
|
|
641
646
|
if (!p)
|
|
642
647
|
p = cfg_1.default.getProject();
|
|
643
648
|
if (!p) {
|
package/distTs/src/output.js
CHANGED
|
@@ -103,13 +103,13 @@ class Output {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
static clearPreviousLine() {
|
|
106
|
-
if (
|
|
106
|
+
if (process.stdout.isTTY) {
|
|
107
107
|
terminal.previousLine();
|
|
108
108
|
terminal.eraseLine();
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
static async spinner(txt) {
|
|
112
|
-
if (!this.s &&
|
|
112
|
+
if (!this.s && process.stdout.isTTY) {
|
|
113
113
|
this.s = await terminal.spinner();
|
|
114
114
|
if (txt)
|
|
115
115
|
terminal(` ${txt}`);
|
|
@@ -141,7 +141,7 @@ class Output {
|
|
|
141
141
|
terminal.gray(texts_1.TXT_NEW_AGENT_VERSION);
|
|
142
142
|
}
|
|
143
143
|
static tunnel(tunnel) {
|
|
144
|
-
if (
|
|
144
|
+
if (process.stdin.isTTY && process.stdout.isTTY)
|
|
145
145
|
this.tunnelInteractive(tunnel);
|
|
146
146
|
else
|
|
147
147
|
this.tunnelNonInteractive(tunnel);
|
|
@@ -192,26 +192,48 @@ class Output {
|
|
|
192
192
|
terminal(title);
|
|
193
193
|
terminal('\n');
|
|
194
194
|
terminal('(y/N)');
|
|
195
|
-
|
|
196
|
-
terminal(
|
|
197
|
-
|
|
198
|
-
|
|
195
|
+
if (process.stdin.isTTY) {
|
|
196
|
+
terminal.inputField((_, input) => {
|
|
197
|
+
terminal('\n');
|
|
198
|
+
resolve((input || '').trim().toLowerCase() === 'y');
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
terminal('N\n');
|
|
203
|
+
resolve(false);
|
|
204
|
+
}
|
|
199
205
|
});
|
|
200
206
|
}
|
|
201
207
|
static async inputString() {
|
|
202
208
|
return new Promise((resolve) => {
|
|
203
|
-
|
|
209
|
+
if (process.stdin.isTTY) {
|
|
210
|
+
terminal.inputField((_, input) => {
|
|
211
|
+
terminal('\n');
|
|
212
|
+
resolve((input || '').trim());
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
204
216
|
terminal('\n');
|
|
205
|
-
resolve(
|
|
206
|
-
}
|
|
217
|
+
resolve('');
|
|
218
|
+
}
|
|
207
219
|
});
|
|
208
220
|
}
|
|
209
221
|
static async inputMenu(items) {
|
|
210
222
|
return new Promise((resolve) => {
|
|
211
|
-
|
|
223
|
+
if (process.stdin.isTTY) {
|
|
224
|
+
terminal.singleColumnMenu(items, (_, response) => {
|
|
225
|
+
terminal('\n');
|
|
226
|
+
resolve(response.selectedIndex);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
else if (items.length > 0) {
|
|
230
|
+
terminal('\n');
|
|
231
|
+
resolve(0);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
212
234
|
terminal('\n');
|
|
213
|
-
resolve(
|
|
214
|
-
}
|
|
235
|
+
resolve(-1);
|
|
236
|
+
}
|
|
215
237
|
});
|
|
216
238
|
}
|
|
217
239
|
static async selectWorkspace(workspaces) {
|
|
@@ -223,16 +245,17 @@ class Output {
|
|
|
223
245
|
const index = await Output.inputMenu(items);
|
|
224
246
|
return workspaces[index].domain;
|
|
225
247
|
}
|
|
226
|
-
static async selectProject(projects) {
|
|
227
|
-
Output.normal(texts_1.TXT_LOGIN_SELECT_PROJECT);
|
|
228
|
-
const items =
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
248
|
+
static async selectProject(projects, allowNoSet = true) {
|
|
249
|
+
Output.normal((0, texts_1.TXT_LOGIN_SELECT_PROJECT)(allowNoSet));
|
|
250
|
+
const items = projects.map((p) => `${p.display_name} (${p.name})`);
|
|
251
|
+
if (allowNoSet)
|
|
252
|
+
items.unshift("Don't set (default)");
|
|
253
|
+
let index = await Output.inputMenu(items);
|
|
254
|
+
if (allowNoSet && !index)
|
|
255
|
+
return '';
|
|
256
|
+
if (!allowNoSet)
|
|
257
|
+
index += 1;
|
|
258
|
+
return projects[index - 1].name;
|
|
236
259
|
}
|
|
237
260
|
static exitError(err) {
|
|
238
261
|
this.killSpinner();
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
const getFullPath = (path) => (0, node_path_1.resolve)(path, '.bdy', 'project.json');
|
|
10
|
+
class ProjectCfg {
|
|
11
|
+
exists(path) {
|
|
12
|
+
return node_fs_1.default.existsSync(getFullPath(path));
|
|
13
|
+
}
|
|
14
|
+
init(path, workspace, project) {
|
|
15
|
+
const fullPath = getFullPath(path);
|
|
16
|
+
node_fs_1.default.mkdirSync((0, node_path_1.dirname)(fullPath), {
|
|
17
|
+
recursive: true,
|
|
18
|
+
});
|
|
19
|
+
return node_fs_1.default.writeFileSync(fullPath, JSON.stringify({
|
|
20
|
+
workspace,
|
|
21
|
+
project,
|
|
22
|
+
}), 'utf8');
|
|
23
|
+
}
|
|
24
|
+
get(path) {
|
|
25
|
+
let workspace = '';
|
|
26
|
+
let project = '';
|
|
27
|
+
try {
|
|
28
|
+
const str = node_fs_1.default.readFileSync(getFullPath(path), 'utf8');
|
|
29
|
+
const json = JSON.parse(str);
|
|
30
|
+
if (json.workspace)
|
|
31
|
+
workspace = json.workspace;
|
|
32
|
+
if (json.project)
|
|
33
|
+
project = json.project;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// do nothing
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
workspace,
|
|
40
|
+
project,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
getWorkspace() {
|
|
44
|
+
const c = this.get((0, utils_1.getWorkingDir)());
|
|
45
|
+
return c.workspace;
|
|
46
|
+
}
|
|
47
|
+
getProject() {
|
|
48
|
+
const c = this.get((0, utils_1.getWorkingDir)());
|
|
49
|
+
return c.project;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.default = new ProjectCfg();
|
package/distTs/src/texts.js
CHANGED
|
@@ -10,9 +10,10 @@ exports.LOG_SOCKET_CONNECTED = exports.LOG_AGENT_NSSM_CLEARING = exports.LOG_AGE
|
|
|
10
10
|
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 = 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 = void 0;
|
|
11
11
|
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 = 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 = void 0;
|
|
12
12
|
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 = 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 = void 0;
|
|
13
|
-
exports.
|
|
14
|
-
exports.
|
|
15
|
-
exports.
|
|
13
|
+
exports.DESC_COMMAND_LOGOUT = exports.DESC_COMMAND_LOGIN = exports.ERR_API_MEDIA_TYPE_NOT_IMPLEMENTED = exports.ERR_API_PARAMETER_NOT_REPLACED = exports.TXT_API_ENDPOINT_REQUIRED_SCOPES = exports.ERR_API_ENDPOINT_NOT_FOUND = exports.ERR_API_WRONG_METHOD = exports.ERR_SCHEMA_FETCH_FAILED = exports.OPT_COMMAND_API_INFO_URL = exports.OPT_COMMAND_API_INFO_SCHEMA = exports.OPT_COMMAND_API_INFO_METHOD = exports.OPT_COMMAND_API_LIST_SEARCH = exports.OPT_COMMAND_API_LIST_METHOD = exports.ERR_API_REQUEST_BODY_VALUE = exports.ERR_API_REQUEST_QUERY_VALUE = exports.ERR_API_REQUEST_INVALID_JSON = exports.ERR_API_REQUEST_FILE_ERROR = exports.ERR_API_REQUEST_OUTPUT_EXISTS = exports.DESC_COMMAND_API_INFO = exports.DESC_COMMAND_API_FORM = exports.DESC_COMMAND_API_JSON = exports.DESC_COMMAND_API_DATA = exports.DESC_COMMAND_API_OUTPUT = exports.DESC_COMMAND_API_REQUEST_QUERY = exports.DESC_COMMAND_API_PROJECT = exports.DESC_COMMAND_API_WORKSPACE = exports.DESC_COMMAND_API_REQUEST_URL = exports.DESC_COMMAND_API_GET = exports.DESC_COMMAND_API_PATCH = exports.DESC_COMMAND_API_DELETE = exports.DESC_COMMAND_API_PUT = exports.DESC_COMMAND_API_POST = exports.DESC_COMMAND_API_LIST = exports.DESC_COMMAND_API = exports.TXT_WHOAMI_NO_LOCAL_LINK = 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_SOURCE = exports.ERR_SANDBOX_CP_INVALID_DEST = exports.ERR_SANDBOX_CP_REPLACE = exports.ERR_SANDBOX_CP_MKDIR = exports.ERR_SANDBOX_CP_PATH_EXISTS = exports.ERR_SANDBOX_CP_NOT_EMPTY_DIR = void 0;
|
|
14
|
+
exports.DESC_COMMAND_PROJECT_SET = exports.DESC_COMMAND_PROJECT_LIST = exports.DESC_COMMAND_PROJECT_GIT = exports.DESC_COMMAND_PROJECT_GIT_CREDENTIAL = exports.DESC_COMMAND_PROJECT = exports.TXT_PACKAGE_VERSION_DOWNLOAD = exports.TXT_PACKAGE_PUBLISH = 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_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;
|
|
15
|
+
exports.EXAMPLE_PACKAGE_CREATE = exports.EXAMPLE_PACKAGE_DELETE = exports.EXAMPLE_PACKAGE_DOWNLOAD = exports.EXAMPLE_PACKAGE_PUBLISH = exports.EXAMPLE_PIPELINE_RUN = exports.EXAMPLE_SANDBOX_ENDPOINT_LIST = exports.EXAMPLE_SANDBOX_ENDPOINT_GET = exports.EXAMPLE_SANDBOX_ENDPOINT_DELETE = exports.EXAMPLE_SANDBOX_ENDPOINT_CREATE = exports.EXAMPLE_SANDBOX_SNAPSHOT_LIST = exports.EXAMPLE_SANDBOX_SNAPSHOT_GET = exports.EXAMPLE_SANDBOX_SNAPSHOT_DELETE = exports.EXAMPLE_SANDBOX_SNAPSHOT_CREATE = exports.EXAMPLE_SANDBOX_EXEC_STATUS = exports.EXAMPLE_SANDBOX_EXEC_LOGS = exports.EXAMPLE_SANDBOX_EXEC_LIST = exports.EXAMPLE_SANDBOX_EXEC_KILL = exports.EXAMPLE_SANDBOX_EXEC_COMMAND = exports.EXAMPLE_TUNNEL_START = exports.EXAMPLE_TUNNEL_TCP = exports.EXAMPLE_TUNNEL_TLS = exports.EXAMPLE_AGENT_TUNNEL_START = exports.EXAMPLE_AGENT_TUNNEL_STATUS = exports.EXAMPLE_AGENT_TUNNEL_REMOVE = exports.EXAMPLE_AGENT_TUNNEL_LIST = exports.EXAMPLE_TUNNEL_HTTP = exports.EXAMPLE_SANDBOX_CREATE = exports.EXAMPLE_SANDBOX_CP = 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.TXT_COMMAND_PROJECT_LINK_RANDOM = exports.TXT_COMMAND_PROJECT_LINK_NOT_FOUND = exports.TXT_COMMAND_PROJECT_LINK_NAME = exports.TXT_COMMAND_PROJECT_LINK_NEW = exports.ERR_COMMAND_PROJECT_LINK_DIR_NOT_DIR = exports.TXT_COMMAND_PROJECT_LINKED = exports.TXT_COMMAND_PROJECT_LINK_GIT_REPO = exports.TXT_COMMAND_PROJECT_LINK_DIR_CONFIRM = exports.TXT_COMMAND_PROJECT_LINK_DIR_LINKED = exports.ERR_COMMAND_PROJECT_LINK_DIR_CREATE = exports.OPT_COMMAND_PROJECT_LINK_HAS_REMOTE = exports.OPT_COMMAND_PROJECT_LINK_DIRECTORY = exports.OPT_COMMAND_PROJECT_LINK_GIT = exports.OPT_COMMAND_PROJECT_LINK_RELINK = exports.DESC_COMMAND_PROJECT_LINK = exports.DESC_COMMAND_PROJECT_GET = exports.ARG_COMMAND_PROJECT_NAME = void 0;
|
|
16
|
+
exports.EXAMPLE_PACKAGE_VERSION_DELETE = exports.EXAMPLE_PACKAGE_VERSION_GET = exports.EXAMPLE_PACKAGE_VERSION_LIST = void 0;
|
|
16
17
|
const utils_1 = require("./utils");
|
|
17
18
|
exports.ERR_REST_API_GENERAL_ERROR = 'Something went wrong';
|
|
18
19
|
exports.ERR_REST_API_NOT_RESPONDING = 'Api endpoint not responding. Try again later...';
|
|
@@ -660,6 +661,7 @@ exports.DESC_COMMAND_WHOAMI = 'Check login information';
|
|
|
660
661
|
exports.TXT_WHOAMI_NO_WORKSPACE = 'Not set. Run `bdy ws set` to set a workspace';
|
|
661
662
|
exports.TXT_WHOAMI_NO_PROJECT = 'Not set. Run `bdy proj set` to set a project';
|
|
662
663
|
exports.ERR_WHOAMI_LOGOUT = 'Not logged in. Run `bdy login` to authenticate.';
|
|
664
|
+
exports.TXT_WHOAMI_NO_LOCAL_LINK = 'Not set. Run `bdy project link`';
|
|
663
665
|
// api command
|
|
664
666
|
exports.DESC_COMMAND_API = 'Contact Buddy API directly';
|
|
665
667
|
exports.DESC_COMMAND_API_LIST = 'List Buddy API endpoints';
|
|
@@ -704,8 +706,8 @@ exports.TXT_LOGOUT_SUCCESS = 'Logged out successfully.';
|
|
|
704
706
|
// Workspace commands
|
|
705
707
|
exports.DESC_COMMAND_WORKSPACE = 'Manage workspaces';
|
|
706
708
|
exports.DESC_COMMAND_WORKSPACE_LIST = 'List available workspaces';
|
|
707
|
-
exports.DESC_COMMAND_WORKSPACE_SET = 'Set current workspace';
|
|
708
|
-
exports.DESC_COMMAND_WORKSPACE_GET = 'Get current workspace';
|
|
709
|
+
exports.DESC_COMMAND_WORKSPACE_SET = 'Set current global workspace';
|
|
710
|
+
exports.DESC_COMMAND_WORKSPACE_GET = 'Get current global workspace';
|
|
709
711
|
exports.ARG_COMMAND_WORKSPACE = 'Workspace domain to set';
|
|
710
712
|
const TXT_WORKSPACE_SET_SUCCESS = (workspace) => `Workspace set to: ${workspace}`;
|
|
711
713
|
exports.TXT_WORKSPACE_SET_SUCCESS = TXT_WORKSPACE_SET_SUCCESS;
|
|
@@ -720,7 +722,6 @@ exports.ERR_LOGIN_HTTP_FAILED = 'Buddy CLI failed to authorize. Try again...';
|
|
|
720
722
|
exports.ERR_LOGIN_HTTP_SUCCESS = 'Buddy CLI was successfully authenticated. You can now close this tab and return to the terminal';
|
|
721
723
|
exports.ERR_LOGIN_NO_WORKSPACES = 'No workspaces found for this token';
|
|
722
724
|
exports.ERR_LOGIN_NO_WORKSPACE_FOUND = 'Provided workspace has been not found';
|
|
723
|
-
exports.ERR_LOGIN_NO_PROJECT_FOUND = 'Provided project has been not found';
|
|
724
725
|
exports.ERR_LOGIN_INVALID_BASE_URL = 'Invalid URL format';
|
|
725
726
|
const ERR_API_MESSAGE_REPLACER = (message, path, baseUrl, rateLimitTs) => {
|
|
726
727
|
let workspaceUrl = null;
|
|
@@ -805,14 +806,36 @@ const TXT_PACKAGE_VERSION_DOWNLOAD = (type, identifier, version, versionUrl) =>
|
|
|
805
806
|
exports.TXT_PACKAGE_VERSION_DOWNLOAD = TXT_PACKAGE_VERSION_DOWNLOAD;
|
|
806
807
|
// Project commands
|
|
807
808
|
exports.DESC_COMMAND_PROJECT = 'Manage projects';
|
|
809
|
+
exports.DESC_COMMAND_PROJECT_GIT_CREDENTIAL = 'Git credential helper for Buddy';
|
|
810
|
+
exports.DESC_COMMAND_PROJECT_GIT = 'Git helper for Buddy';
|
|
808
811
|
exports.DESC_COMMAND_PROJECT_LIST = 'List projects in current workspace';
|
|
809
|
-
exports.DESC_COMMAND_PROJECT_SET = 'Set current project';
|
|
812
|
+
exports.DESC_COMMAND_PROJECT_SET = 'Set current global project';
|
|
810
813
|
exports.ARG_COMMAND_PROJECT_NAME = 'Project name to set';
|
|
811
|
-
exports.DESC_COMMAND_PROJECT_GET = 'Get current project';
|
|
814
|
+
exports.DESC_COMMAND_PROJECT_GET = 'Get current global project';
|
|
815
|
+
exports.DESC_COMMAND_PROJECT_LINK = 'Link directory with project in Buddy';
|
|
816
|
+
exports.OPT_COMMAND_PROJECT_LINK_RELINK = 'Force relinking directory if already linked to project';
|
|
817
|
+
exports.OPT_COMMAND_PROJECT_LINK_GIT = 'Force initialization of GIT repository';
|
|
818
|
+
exports.OPT_COMMAND_PROJECT_LINK_DIRECTORY = 'Path to directory where link the project';
|
|
819
|
+
exports.OPT_COMMAND_PROJECT_LINK_HAS_REMOTE = 'Local repository has different remote origin than project.';
|
|
820
|
+
const ERR_COMMAND_PROJECT_LINK_DIR_CREATE = (dir) => `Cannot create directory ${dir}`;
|
|
821
|
+
exports.ERR_COMMAND_PROJECT_LINK_DIR_CREATE = ERR_COMMAND_PROJECT_LINK_DIR_CREATE;
|
|
822
|
+
exports.TXT_COMMAND_PROJECT_LINK_DIR_LINKED = 'Directory is already linked to project';
|
|
823
|
+
exports.TXT_COMMAND_PROJECT_LINK_DIR_CONFIRM = 'Relink to different project?';
|
|
824
|
+
exports.TXT_COMMAND_PROJECT_LINK_GIT_REPO = 'Initialize GIT repository?';
|
|
825
|
+
const TXT_COMMAND_PROJECT_LINKED = (project, dir) => `${dir} linked to project ${project}`;
|
|
826
|
+
exports.TXT_COMMAND_PROJECT_LINKED = TXT_COMMAND_PROJECT_LINKED;
|
|
827
|
+
exports.ERR_COMMAND_PROJECT_LINK_DIR_NOT_DIR = 'Path is not a directory';
|
|
828
|
+
exports.TXT_COMMAND_PROJECT_LINK_NEW = 'Link existing project?';
|
|
829
|
+
exports.TXT_COMMAND_PROJECT_LINK_NAME = 'Provide project name:';
|
|
830
|
+
const TXT_COMMAND_PROJECT_LINK_NOT_FOUND = (project) => `Project ${project} not found. Creating new...`;
|
|
831
|
+
exports.TXT_COMMAND_PROJECT_LINK_NOT_FOUND = TXT_COMMAND_PROJECT_LINK_NOT_FOUND;
|
|
832
|
+
const TXT_COMMAND_PROJECT_LINK_RANDOM = (name) => `Generated project name: ${name}`;
|
|
833
|
+
exports.TXT_COMMAND_PROJECT_LINK_RANDOM = TXT_COMMAND_PROJECT_LINK_RANDOM;
|
|
812
834
|
const TXT_PROJECT_SET_SUCCESS = (project) => `Project set to: ${project}`;
|
|
813
835
|
exports.TXT_PROJECT_SET_SUCCESS = TXT_PROJECT_SET_SUCCESS;
|
|
814
836
|
exports.TXT_PROJECT_SET_CLEARED = 'Project cleared';
|
|
815
|
-
|
|
837
|
+
const TXT_LOGIN_SELECT_PROJECT = (optional) => `Select project (${optional ? 'optional' : 'required'}):`;
|
|
838
|
+
exports.TXT_LOGIN_SELECT_PROJECT = TXT_LOGIN_SELECT_PROJECT;
|
|
816
839
|
exports.ERR_PROJECT_NO_PROJECTS = 'No projects found in this workspace';
|
|
817
840
|
exports.TXT_PROJECT_NONE = 'No project configured. Run "bdy login" or "bdy project set" first.';
|
|
818
841
|
// Examples
|
package/distTs/src/utils.js
CHANGED
|
@@ -36,8 +36,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.
|
|
40
|
-
exports.getBasicCommandTls = exports.getBasicCommandHttp = exports.getBasicCommandSandboxEndpoint = exports.getBasicCommandTcp = exports.createSshHostKey = exports.getRealTargetHost = exports.isWindows = exports.isLinux = exports.isOsx = exports.isDocker = void 0;
|
|
39
|
+
exports.getVersionEnv = exports.getCurrentVersionWithoutEnv = exports.getVersionWithoutEnv = exports.getVersion = exports.isInstalledByChoco = exports.isInstalledByApt = exports.isInstalledByBrew = exports.isInstalledByNpm = exports.tryGetEmail = exports.execLocally = exports.getHomeDirectory = exports.newCommand = exports.formatBytes = exports.formatHelp = exports.getPlatform = exports.getHostname = exports.isStringRegExp = exports.getWorkingDir = exports.getRootDir = exports.TARGET_ONLY_PORT_REGEX = exports.TARGET_HTTP_REGEX = exports.TARGET_TCP_TLS_REGEX = exports.ApiErrorTunnelsDisabled = exports.ApiErrorWorkspaceFlagged = exports.ApiErrorTunnelLimitReached = exports.ApiErrorAgentLimitReached = exports.ApiErrorDomainRestricted = exports.ApiErrorTargetInvalid = exports.ApiErrorWrongToken = exports.ApiErrorFailedToConnect = exports.ApiErrorAgentNotFound = exports.PACKAGE_AUTH_TYPE = exports.PACKAGE_SCOPE = exports.PACKAGE_TYPE = exports.SANDBOX_SNAPSHOT_STATUS = exports.SANDBOX_SETUP_STATUS = exports.SANDBOX_EXEC_STATUS = exports.SANDBOX_EXEC_RUNTIME = exports.SANDBOX_STATUS = exports.REST_API_ENDPOINT = exports.REST_API_REGION = exports.SUGGESTED_BROWSER_VERSION = exports.DEFAULT_TIMEOUT = exports.TUNNEL_HTTP_CB_MIN_REQUESTS = exports.TUNNEL_HTTP_CB_WINDOW = exports.TUNNEL_MAX_REQUEST_SIZE_TO_SYNC = exports.TUNNEL_HTTP_LOG_MAX_REQUESTS = exports.TUNNEL_HTTP_LOG_MAX_BODY = exports.TUNNEL_HTTP_RATE_WINDOW = exports.TUNNEL_HTTP_RATE_LIMIT = void 0;
|
|
40
|
+
exports.getBasicCommandTls = exports.getBasicCommandHttp = exports.getBasicCommandSandboxEndpoint = exports.getBasicCommandTcp = exports.createSshHostKey = exports.getRealTargetHost = exports.isWindows = exports.isLinux = exports.isOsx = exports.isDocker = exports.sleep = exports.getLatestVersion = void 0;
|
|
41
41
|
exports.apiErrorCodeToClass = apiErrorCodeToClass;
|
|
42
42
|
exports.isFile = isFile;
|
|
43
43
|
exports.getAppWorkspaceUrl = getAppWorkspaceUrl;
|
|
@@ -219,6 +219,7 @@ exports.TARGET_HTTP_REGEX = /^((https?):\/\/)?([^:/]+:[^@:/]+@)?([^:/]+)(:(\d+))
|
|
|
219
219
|
exports.TARGET_ONLY_PORT_REGEX = /^\d+$/i;
|
|
220
220
|
let cachedVersion;
|
|
221
221
|
let cachedRoot;
|
|
222
|
+
let cachedWorkingDir;
|
|
222
223
|
const getRootDir = () => {
|
|
223
224
|
if (!cachedRoot) {
|
|
224
225
|
cachedRoot = node_path_1.default.resolve(__dirname, '..');
|
|
@@ -226,6 +227,13 @@ const getRootDir = () => {
|
|
|
226
227
|
return cachedRoot;
|
|
227
228
|
};
|
|
228
229
|
exports.getRootDir = getRootDir;
|
|
230
|
+
const getWorkingDir = () => {
|
|
231
|
+
if (!cachedWorkingDir) {
|
|
232
|
+
cachedWorkingDir = process.cwd();
|
|
233
|
+
}
|
|
234
|
+
return cachedWorkingDir;
|
|
235
|
+
};
|
|
236
|
+
exports.getWorkingDir = getWorkingDir;
|
|
229
237
|
const isStringRegExp = (str) => /^\/.*\/$/.test(str);
|
|
230
238
|
exports.isStringRegExp = isStringRegExp;
|
|
231
239
|
const getHostname = () => {
|
|
@@ -328,9 +336,9 @@ const getHomeDirectory = () => {
|
|
|
328
336
|
return p;
|
|
329
337
|
};
|
|
330
338
|
exports.getHomeDirectory = getHomeDirectory;
|
|
331
|
-
const execLocally = async (cmd) => {
|
|
339
|
+
const execLocally = async (cmd, opts = {}) => {
|
|
332
340
|
return new Promise((resolve, reject) => {
|
|
333
|
-
(0, node_child_process_1.exec)(cmd, (err, stdout, stderr) => {
|
|
341
|
+
(0, node_child_process_1.exec)(cmd, opts, (err, stdout, stderr) => {
|
|
334
342
|
if (err)
|
|
335
343
|
reject(err);
|
|
336
344
|
else
|
|
@@ -339,6 +347,22 @@ const execLocally = async (cmd) => {
|
|
|
339
347
|
});
|
|
340
348
|
};
|
|
341
349
|
exports.execLocally = execLocally;
|
|
350
|
+
const tryGetEmail = async (client) => {
|
|
351
|
+
try {
|
|
352
|
+
const result = await client.getInvokerEmails();
|
|
353
|
+
if (result && result.emails) {
|
|
354
|
+
const e = result.emails.find((e) => e.confirmed);
|
|
355
|
+
if (e) {
|
|
356
|
+
return e.email;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
// do nothing
|
|
362
|
+
}
|
|
363
|
+
return null;
|
|
364
|
+
};
|
|
365
|
+
exports.tryGetEmail = tryGetEmail;
|
|
342
366
|
const isInstalledByNpm = async () => {
|
|
343
367
|
try {
|
|
344
368
|
const out = await (0, exports.execLocally)('npm -g list');
|