@tarout/cli 0.2.1 → 0.2.2
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/dist/{api-SHKZO2SZ.js → api-735LN7BA.js} +2 -2
- package/dist/{billing-ENTHZKID.js → billing-WOKNOS4N.js} +4 -4
- package/dist/{chunk-XSJKHLNL.js → chunk-5XBVQICT.js} +113 -14
- package/dist/{chunk-FKX4CRPL.js → chunk-7YS2WBLB.js} +1 -1
- package/dist/chunk-CJMIX35A.js +127 -0
- package/dist/{chunk-FS74WWHV.js → chunk-KL3JNPAY.js} +7 -2
- package/dist/index.js +1220 -303
- package/dist/{prompts-WNFR34TG.js → prompts-QQ2FZKQT.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-J3H7LTFT.js +0 -68
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
stopSpinner,
|
|
7
7
|
succeedSpinner,
|
|
8
8
|
updateSpinner
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-5XBVQICT.js";
|
|
10
10
|
import {
|
|
11
11
|
AuthError,
|
|
12
12
|
BuildFailedError,
|
|
@@ -33,14 +33,14 @@ import {
|
|
|
33
33
|
setProfile,
|
|
34
34
|
setProjectConfig,
|
|
35
35
|
updateProfile
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-7YS2WBLB.js";
|
|
37
37
|
import {
|
|
38
38
|
confirm,
|
|
39
39
|
input,
|
|
40
40
|
password,
|
|
41
41
|
promptOrEmit,
|
|
42
42
|
select
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-CJMIX35A.js";
|
|
44
44
|
import {
|
|
45
45
|
ExitCode,
|
|
46
46
|
box,
|
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
exit,
|
|
50
50
|
getStatusBadge,
|
|
51
51
|
isJsonMode,
|
|
52
|
+
isNonInteractiveMode,
|
|
52
53
|
log,
|
|
53
54
|
outputData,
|
|
54
55
|
outputError,
|
|
@@ -58,7 +59,7 @@ import {
|
|
|
58
59
|
shouldSkipConfirmation,
|
|
59
60
|
success,
|
|
60
61
|
table
|
|
61
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-KL3JNPAY.js";
|
|
62
63
|
|
|
63
64
|
// src/index.ts
|
|
64
65
|
import { Command } from "commander";
|
|
@@ -66,7 +67,7 @@ import { Command } from "commander";
|
|
|
66
67
|
// package.json
|
|
67
68
|
var package_default = {
|
|
68
69
|
name: "@tarout/cli",
|
|
69
|
-
version: "0.2.
|
|
70
|
+
version: "0.2.2",
|
|
70
71
|
description: "Tarout CLI \u2014 the Saudi cloud platform for coding agents",
|
|
71
72
|
type: "module",
|
|
72
73
|
bin: {
|
|
@@ -167,7 +168,11 @@ function registerAccountCommands(program2) {
|
|
|
167
168
|
if (options.email) updates.email = options.email;
|
|
168
169
|
if (options.password) {
|
|
169
170
|
updates.password = options.password;
|
|
170
|
-
updates.currentPassword = options.currentPassword || await input("Current password:"
|
|
171
|
+
updates.currentPassword = options.currentPassword || await input("Current password:", void 0, {
|
|
172
|
+
field: "currentPassword",
|
|
173
|
+
flag: "--current-password",
|
|
174
|
+
sensitive: true
|
|
175
|
+
});
|
|
171
176
|
}
|
|
172
177
|
if (Object.keys(updates).length === 0) {
|
|
173
178
|
log("No changes specified.");
|
|
@@ -197,14 +202,19 @@ function registerAccountCommands(program2) {
|
|
|
197
202
|
log("");
|
|
198
203
|
const confirmed = await confirm(
|
|
199
204
|
"Delete your account? This cannot be undone.",
|
|
200
|
-
false
|
|
205
|
+
false,
|
|
206
|
+
{ field: "confirm_delete_account", flag: "--yes" }
|
|
201
207
|
);
|
|
202
208
|
if (!confirmed) {
|
|
203
209
|
log("Cancelled.");
|
|
204
210
|
return;
|
|
205
211
|
}
|
|
206
212
|
}
|
|
207
|
-
const confirmEmail = await input(
|
|
213
|
+
const confirmEmail = await input(
|
|
214
|
+
"Type your email address to confirm:",
|
|
215
|
+
void 0,
|
|
216
|
+
{ field: "confirm_email", flag: "--confirm-email" }
|
|
217
|
+
);
|
|
208
218
|
const client = getApiClient();
|
|
209
219
|
const _spinner = startSpinner("Deleting account...");
|
|
210
220
|
await client.user.deleteSelf.mutate({ confirmEmail });
|
|
@@ -253,7 +263,10 @@ function registerAccountCommands(program2) {
|
|
|
253
263
|
async (options) => {
|
|
254
264
|
try {
|
|
255
265
|
if (!isLoggedIn()) throw new AuthError();
|
|
256
|
-
const name = options.name || await input("API key name:"
|
|
266
|
+
const name = options.name || await input("API key name:", void 0, {
|
|
267
|
+
field: "name",
|
|
268
|
+
flag: "--name"
|
|
269
|
+
});
|
|
257
270
|
const client = getApiClient();
|
|
258
271
|
const _spinner = startSpinner("Creating API key...");
|
|
259
272
|
const result = await client.user.createApiKey.mutate({
|
|
@@ -292,7 +305,12 @@ function registerAccountCommands(program2) {
|
|
|
292
305
|
if (!shouldSkipConfirmation()) {
|
|
293
306
|
const confirmed = await confirm(
|
|
294
307
|
`Delete API key "${apiKeyId}"?`,
|
|
295
|
-
false
|
|
308
|
+
false,
|
|
309
|
+
{
|
|
310
|
+
field: "confirm_delete_api_key",
|
|
311
|
+
flag: "--yes",
|
|
312
|
+
context: { apiKeyId }
|
|
313
|
+
}
|
|
296
314
|
);
|
|
297
315
|
if (!confirmed) {
|
|
298
316
|
log("Cancelled.");
|
|
@@ -501,10 +519,15 @@ Root access: ${hasAccess ? colors.success("yes") : colors.error("no")}
|
|
|
501
519
|
try {
|
|
502
520
|
if (!isLoggedIn()) throw new AuthError();
|
|
503
521
|
if (!shouldSkipConfirmation()) {
|
|
504
|
-
const { confirm: confirmFn } = await import("./prompts-
|
|
522
|
+
const { confirm: confirmFn } = await import("./prompts-QQ2FZKQT.js");
|
|
505
523
|
const ok = await confirmFn(
|
|
506
524
|
`Remove user "${userId}" from the organization?`,
|
|
507
|
-
false
|
|
525
|
+
false,
|
|
526
|
+
{
|
|
527
|
+
field: "confirm_remove_member",
|
|
528
|
+
flag: "--yes",
|
|
529
|
+
context: { userId }
|
|
530
|
+
}
|
|
508
531
|
);
|
|
509
532
|
if (!ok) {
|
|
510
533
|
log("Cancelled.");
|
|
@@ -523,11 +546,15 @@ Root access: ${hasAccess ? colors.success("yes") : colors.error("no")}
|
|
|
523
546
|
account.command("assign-permissions").argument("<user-id>", "User ID").option("--role <role>", "Role: admin, member").description("Assign permissions/role to a member (org owner only)").action(async (userId, options) => {
|
|
524
547
|
try {
|
|
525
548
|
if (!isLoggedIn()) throw new AuthError();
|
|
526
|
-
const { select: selectFn } = await import("./prompts-
|
|
527
|
-
const role = options.role || await selectFn(
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
549
|
+
const { select: selectFn } = await import("./prompts-QQ2FZKQT.js");
|
|
550
|
+
const role = options.role || await selectFn(
|
|
551
|
+
"Role:",
|
|
552
|
+
[
|
|
553
|
+
{ name: "Admin", value: "admin" },
|
|
554
|
+
{ name: "Member", value: "member" }
|
|
555
|
+
],
|
|
556
|
+
{ field: "role", flag: "--role" }
|
|
557
|
+
);
|
|
531
558
|
const client = getApiClient();
|
|
532
559
|
const _spinner = startSpinner("Assigning permissions...");
|
|
533
560
|
await client.user.assignPermissions.mutate({ userId, role });
|
|
@@ -690,7 +717,10 @@ function registerAiCommands(program2) {
|
|
|
690
717
|
let modelId = options.model;
|
|
691
718
|
const modelProvider = options.provider || "global";
|
|
692
719
|
if (!keyName) {
|
|
693
|
-
keyName = await input("Key name:"
|
|
720
|
+
keyName = await input("Key name:", void 0, {
|
|
721
|
+
field: "name",
|
|
722
|
+
flag: "--name"
|
|
723
|
+
});
|
|
694
724
|
}
|
|
695
725
|
if (!modelId) {
|
|
696
726
|
const client2 = getApiClient();
|
|
@@ -703,13 +733,22 @@ function registerAiCommands(program2) {
|
|
|
703
733
|
modelList.map((m) => ({
|
|
704
734
|
name: m.name || m.displayName || m.id || m.modelId,
|
|
705
735
|
value: m.id || m.modelId
|
|
706
|
-
}))
|
|
736
|
+
})),
|
|
737
|
+
{
|
|
738
|
+
field: "model_id",
|
|
739
|
+
flag: "--model",
|
|
740
|
+
context: { keyName }
|
|
741
|
+
}
|
|
707
742
|
);
|
|
708
743
|
}
|
|
709
744
|
} catch {
|
|
710
745
|
}
|
|
711
746
|
if (!modelId) {
|
|
712
|
-
modelId = await input("Model ID (e.g., gpt-4o):"
|
|
747
|
+
modelId = await input("Model ID (e.g., gpt-4o):", void 0, {
|
|
748
|
+
field: "model_id",
|
|
749
|
+
flag: "--model",
|
|
750
|
+
context: { keyName }
|
|
751
|
+
});
|
|
713
752
|
}
|
|
714
753
|
}
|
|
715
754
|
const client = getApiClient();
|
|
@@ -865,7 +904,12 @@ function registerAiCommands(program2) {
|
|
|
865
904
|
if (!shouldSkipConfirmation()) {
|
|
866
905
|
const confirmed = await confirm(
|
|
867
906
|
`Permanently delete key "${keyId}"?`,
|
|
868
|
-
false
|
|
907
|
+
false,
|
|
908
|
+
{
|
|
909
|
+
field: "confirm_delete_ai_key",
|
|
910
|
+
flag: "--yes",
|
|
911
|
+
context: { keyId }
|
|
912
|
+
}
|
|
869
913
|
);
|
|
870
914
|
if (!confirmed) {
|
|
871
915
|
log("Cancelled.");
|
|
@@ -1036,9 +1080,19 @@ ${colors.bold(prov.name || "AI Config")}: ${prov.apiUrl || "-"}
|
|
|
1036
1080
|
aiProvider.command("create").description("Create a custom AI provider configuration (org owner only)").option("--name <name>", "Provider name").option("--url <url>", "Provider API URL").option("--key <key>", "Provider API key").action(async (options) => {
|
|
1037
1081
|
try {
|
|
1038
1082
|
if (!isLoggedIn()) throw new AuthError();
|
|
1039
|
-
const name = options.name || await input("Provider name:"
|
|
1040
|
-
|
|
1041
|
-
|
|
1083
|
+
const name = options.name || await input("Provider name:", void 0, {
|
|
1084
|
+
field: "name",
|
|
1085
|
+
flag: "--name"
|
|
1086
|
+
});
|
|
1087
|
+
const apiUrl = options.url || await input("Provider API URL:", void 0, {
|
|
1088
|
+
field: "api_url",
|
|
1089
|
+
flag: "--url"
|
|
1090
|
+
});
|
|
1091
|
+
const apiKey = options.key || await input("Provider API key:", void 0, {
|
|
1092
|
+
field: "api_key",
|
|
1093
|
+
flag: "--key",
|
|
1094
|
+
sensitive: true
|
|
1095
|
+
});
|
|
1042
1096
|
const client = getApiClient();
|
|
1043
1097
|
const _spinner = startSpinner("Creating AI provider...");
|
|
1044
1098
|
const result = await client.ai.create.mutate({
|
|
@@ -1077,7 +1131,12 @@ ${colors.bold(prov.name || "AI Config")}: ${prov.apiUrl || "-"}
|
|
|
1077
1131
|
if (!shouldSkipConfirmation()) {
|
|
1078
1132
|
const ok = await confirm(
|
|
1079
1133
|
`Delete AI provider configuration "${aiId}"?`,
|
|
1080
|
-
false
|
|
1134
|
+
false,
|
|
1135
|
+
{
|
|
1136
|
+
field: "confirm_delete_ai_provider",
|
|
1137
|
+
flag: "--yes",
|
|
1138
|
+
context: { aiId }
|
|
1139
|
+
}
|
|
1081
1140
|
);
|
|
1082
1141
|
if (!ok) {
|
|
1083
1142
|
log("Cancelled.");
|
|
@@ -1154,10 +1213,16 @@ function registerAppsCommands(program2) {
|
|
|
1154
1213
|
let appName = name;
|
|
1155
1214
|
let description = options.description;
|
|
1156
1215
|
if (!appName) {
|
|
1157
|
-
appName = await input("Application name:"
|
|
1216
|
+
appName = await input("Application name:", void 0, {
|
|
1217
|
+
field: "app_name",
|
|
1218
|
+
flag: "<name>"
|
|
1219
|
+
});
|
|
1158
1220
|
}
|
|
1159
1221
|
if (!description && !shouldSkipConfirmation()) {
|
|
1160
|
-
description = await input("Description (optional):"
|
|
1222
|
+
description = await input("Description (optional):", void 0, {
|
|
1223
|
+
field: "description",
|
|
1224
|
+
flag: "--description"
|
|
1225
|
+
});
|
|
1161
1226
|
}
|
|
1162
1227
|
const slug = generateSlug(appName);
|
|
1163
1228
|
const client = getApiClient();
|
|
@@ -1214,7 +1279,12 @@ function registerAppsCommands(program2) {
|
|
|
1214
1279
|
log("");
|
|
1215
1280
|
const confirmed = await confirm(
|
|
1216
1281
|
`Are you sure you want to delete "${app.name}"? This cannot be undone.`,
|
|
1217
|
-
false
|
|
1282
|
+
false,
|
|
1283
|
+
{
|
|
1284
|
+
field: "confirm_delete_app",
|
|
1285
|
+
flag: "--yes",
|
|
1286
|
+
context: { appName: app.name, applicationId: app.applicationId }
|
|
1287
|
+
}
|
|
1218
1288
|
);
|
|
1219
1289
|
if (!confirmed) {
|
|
1220
1290
|
log("Cancelled.");
|
|
@@ -1353,10 +1423,15 @@ function registerAppsCommands(program2) {
|
|
|
1353
1423
|
throw new NotFoundError("Application", appIdentifier, suggestions);
|
|
1354
1424
|
}
|
|
1355
1425
|
if (!shouldSkipConfirmation()) {
|
|
1356
|
-
const { confirm: confirm2 } = await import("./prompts-
|
|
1426
|
+
const { confirm: confirm2 } = await import("./prompts-QQ2FZKQT.js");
|
|
1357
1427
|
const confirmed = await confirm2(
|
|
1358
1428
|
`Stop application "${app.name}"?`,
|
|
1359
|
-
false
|
|
1429
|
+
false,
|
|
1430
|
+
{
|
|
1431
|
+
field: "confirm_stop_app",
|
|
1432
|
+
flag: "--yes",
|
|
1433
|
+
context: { appName: app.name, applicationId: app.applicationId }
|
|
1434
|
+
}
|
|
1360
1435
|
);
|
|
1361
1436
|
if (!confirmed) {
|
|
1362
1437
|
log("Cancelled.");
|
|
@@ -1436,7 +1511,10 @@ function registerAppsCommands(program2) {
|
|
|
1436
1511
|
let repo = options.repo;
|
|
1437
1512
|
const branch = options.branch;
|
|
1438
1513
|
if (!repo) {
|
|
1439
|
-
repo = await input("Repository (owner/repo):"
|
|
1514
|
+
repo = await input("Repository (owner/repo):", void 0, {
|
|
1515
|
+
field: "github_repo",
|
|
1516
|
+
flag: "--repo"
|
|
1517
|
+
});
|
|
1440
1518
|
}
|
|
1441
1519
|
const [owner, repository] = (repo || "").split("/");
|
|
1442
1520
|
if (!owner || !repository) {
|
|
@@ -1456,7 +1534,11 @@ function registerAppsCommands(program2) {
|
|
|
1456
1534
|
providerList.map((p) => ({
|
|
1457
1535
|
name: p.name || p.login || p.githubId,
|
|
1458
1536
|
value: p.githubId || p.id
|
|
1459
|
-
}))
|
|
1537
|
+
})),
|
|
1538
|
+
{
|
|
1539
|
+
field: "github_provider_id",
|
|
1540
|
+
flag: "--provider-id"
|
|
1541
|
+
}
|
|
1460
1542
|
);
|
|
1461
1543
|
}
|
|
1462
1544
|
}
|
|
@@ -1501,7 +1583,10 @@ function registerAppsCommands(program2) {
|
|
|
1501
1583
|
}
|
|
1502
1584
|
let repo = options.repo;
|
|
1503
1585
|
if (!repo) {
|
|
1504
|
-
repo = await input("Repository (namespace/repo):"
|
|
1586
|
+
repo = await input("Repository (namespace/repo):", void 0, {
|
|
1587
|
+
field: "gitlab_repo",
|
|
1588
|
+
flag: "--repo"
|
|
1589
|
+
});
|
|
1505
1590
|
}
|
|
1506
1591
|
const parts = (repo || "").split("/");
|
|
1507
1592
|
const gitlabOwner = parts.slice(0, -1).join("/");
|
|
@@ -1518,7 +1603,11 @@ function registerAppsCommands(program2) {
|
|
|
1518
1603
|
providerList.map((p) => ({
|
|
1519
1604
|
name: p.name || p.gitlabId,
|
|
1520
1605
|
value: p.gitlabId || p.id
|
|
1521
|
-
}))
|
|
1606
|
+
})),
|
|
1607
|
+
{
|
|
1608
|
+
field: "gitlab_provider_id",
|
|
1609
|
+
flag: "--provider-id"
|
|
1610
|
+
}
|
|
1522
1611
|
);
|
|
1523
1612
|
}
|
|
1524
1613
|
}
|
|
@@ -1562,7 +1651,12 @@ function registerAppsCommands(program2) {
|
|
|
1562
1651
|
let image = options.image;
|
|
1563
1652
|
if (!image) {
|
|
1564
1653
|
image = await input(
|
|
1565
|
-
"Docker image (e.g., nginx:latest or myorg/app:1.0):"
|
|
1654
|
+
"Docker image (e.g., nginx:latest or myorg/app:1.0):",
|
|
1655
|
+
void 0,
|
|
1656
|
+
{
|
|
1657
|
+
field: "docker_image",
|
|
1658
|
+
flag: "--image"
|
|
1659
|
+
}
|
|
1566
1660
|
);
|
|
1567
1661
|
}
|
|
1568
1662
|
const _configSpinner = startSpinner("Configuring Docker Hub...");
|
|
@@ -1601,7 +1695,10 @@ function registerAppsCommands(program2) {
|
|
|
1601
1695
|
}
|
|
1602
1696
|
let gitUrl = options.url;
|
|
1603
1697
|
if (!gitUrl) {
|
|
1604
|
-
gitUrl = await input("Git URL (https://... or git@...):"
|
|
1698
|
+
gitUrl = await input("Git URL (https://... or git@...):", void 0, {
|
|
1699
|
+
field: "git_url",
|
|
1700
|
+
flag: "--url"
|
|
1701
|
+
});
|
|
1605
1702
|
}
|
|
1606
1703
|
const _configSpinner = startSpinner("Connecting git repository...");
|
|
1607
1704
|
await client.application.saveGitProvider.mutate({
|
|
@@ -1644,10 +1741,15 @@ function registerAppsCommands(program2) {
|
|
|
1644
1741
|
throw new NotFoundError("Application", appIdentifier);
|
|
1645
1742
|
}
|
|
1646
1743
|
if (!shouldSkipConfirmation()) {
|
|
1647
|
-
const { confirm: confirm2 } = await import("./prompts-
|
|
1744
|
+
const { confirm: confirm2 } = await import("./prompts-QQ2FZKQT.js");
|
|
1648
1745
|
const confirmed = await confirm2(
|
|
1649
1746
|
`Disconnect source provider from "${app.name}"?`,
|
|
1650
|
-
false
|
|
1747
|
+
false,
|
|
1748
|
+
{
|
|
1749
|
+
field: "confirm_disconnect_git_provider",
|
|
1750
|
+
flag: "--yes",
|
|
1751
|
+
context: { appName: app.name, applicationId: app.applicationId }
|
|
1752
|
+
}
|
|
1651
1753
|
);
|
|
1652
1754
|
if (!confirmed) {
|
|
1653
1755
|
log("Cancelled.");
|
|
@@ -1682,11 +1784,18 @@ function registerAppsCommands(program2) {
|
|
|
1682
1784
|
}
|
|
1683
1785
|
let buildType = options.type;
|
|
1684
1786
|
if (!buildType) {
|
|
1685
|
-
buildType = await select(
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1787
|
+
buildType = await select(
|
|
1788
|
+
"Build type:",
|
|
1789
|
+
[
|
|
1790
|
+
{ name: "Nixpacks (auto-detect)", value: "nixpacks" },
|
|
1791
|
+
{ name: "Dockerfile", value: "dockerfile" },
|
|
1792
|
+
{ name: "Static / SPA", value: "static" }
|
|
1793
|
+
],
|
|
1794
|
+
{
|
|
1795
|
+
field: "build_type",
|
|
1796
|
+
flag: "--type"
|
|
1797
|
+
}
|
|
1798
|
+
);
|
|
1690
1799
|
}
|
|
1691
1800
|
const _configSpinner = startSpinner("Saving build configuration...");
|
|
1692
1801
|
await client.application.saveBuildType.mutate({
|
|
@@ -1723,7 +1832,10 @@ function registerAppsCommands(program2) {
|
|
|
1723
1832
|
}
|
|
1724
1833
|
let repo = options.repo;
|
|
1725
1834
|
if (!repo) {
|
|
1726
|
-
repo = await input("Repository (owner/repo):"
|
|
1835
|
+
repo = await input("Repository (owner/repo):", void 0, {
|
|
1836
|
+
field: "bitbucket_repo",
|
|
1837
|
+
flag: "--repo"
|
|
1838
|
+
});
|
|
1727
1839
|
}
|
|
1728
1840
|
const parts = (repo || "").split("/");
|
|
1729
1841
|
const bitbucketOwner = parts.slice(0, -1).join("/") || parts[0] || "";
|
|
@@ -1741,7 +1853,11 @@ function registerAppsCommands(program2) {
|
|
|
1741
1853
|
providerList.map((p) => ({
|
|
1742
1854
|
name: p.username || p.bitbucketId,
|
|
1743
1855
|
value: p.bitbucketId || p.id
|
|
1744
|
-
}))
|
|
1856
|
+
})),
|
|
1857
|
+
{
|
|
1858
|
+
field: "bitbucket_provider_id",
|
|
1859
|
+
flag: "--provider-id"
|
|
1860
|
+
}
|
|
1745
1861
|
);
|
|
1746
1862
|
}
|
|
1747
1863
|
} catch {
|
|
@@ -1788,7 +1904,10 @@ function registerAppsCommands(program2) {
|
|
|
1788
1904
|
}
|
|
1789
1905
|
let repo = options.repo;
|
|
1790
1906
|
if (!repo) {
|
|
1791
|
-
repo = await input("Repository (owner/repo):"
|
|
1907
|
+
repo = await input("Repository (owner/repo):", void 0, {
|
|
1908
|
+
field: "gitea_repo",
|
|
1909
|
+
flag: "--repo"
|
|
1910
|
+
});
|
|
1792
1911
|
}
|
|
1793
1912
|
const parts = (repo || "").split("/");
|
|
1794
1913
|
const giteaOwner = parts.slice(0, -1).join("/") || parts[0] || "";
|
|
@@ -2226,7 +2345,16 @@ function registerAppsCommands(program2) {
|
|
|
2226
2345
|
if (!shouldSkipConfirmation()) {
|
|
2227
2346
|
const confirmed = await confirm(
|
|
2228
2347
|
`Change plan for "${app.name}" to "${newPlan}"?`,
|
|
2229
|
-
false
|
|
2348
|
+
false,
|
|
2349
|
+
{
|
|
2350
|
+
field: "confirm_change_plan",
|
|
2351
|
+
flag: "--yes",
|
|
2352
|
+
context: {
|
|
2353
|
+
appName: app.name,
|
|
2354
|
+
applicationId: app.applicationId,
|
|
2355
|
+
newPlan
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2230
2358
|
);
|
|
2231
2359
|
if (!confirmed) {
|
|
2232
2360
|
log("Cancelled.");
|
|
@@ -2442,7 +2570,10 @@ function registerAppsCommands(program2) {
|
|
|
2442
2570
|
failSpinner();
|
|
2443
2571
|
throw new NotFoundError("Application", appIdentifier);
|
|
2444
2572
|
}
|
|
2445
|
-
const dockerfileContent = options.content || await input("Dockerfile content:"
|
|
2573
|
+
const dockerfileContent = options.content || await input("Dockerfile content:", void 0, {
|
|
2574
|
+
field: "dockerfile_content",
|
|
2575
|
+
flag: "--content"
|
|
2576
|
+
});
|
|
2446
2577
|
const _saveSpinner = startSpinner("Saving Dockerfile...");
|
|
2447
2578
|
await client.application.saveDockerfileUploadProvider.mutate({
|
|
2448
2579
|
applicationId: app.applicationId,
|
|
@@ -2849,12 +2980,36 @@ function isCredentialError(error2) {
|
|
|
2849
2980
|
}
|
|
2850
2981
|
|
|
2851
2982
|
// src/commands/auth.ts
|
|
2983
|
+
function refuseBrowserAuthForAgent(action) {
|
|
2984
|
+
const message = `tarout ${action} requires a browser. Agents should ask the user to run \`tarout token <api-token>\` or set TAROUT_TOKEN \u2014 generate one at https://tarout.sa/dashboard/account/api-keys.`;
|
|
2985
|
+
if (isJsonMode()) {
|
|
2986
|
+
outputError("AUTH_BOOTSTRAP_REQUIRED", message, {
|
|
2987
|
+
action,
|
|
2988
|
+
recommendedFlags: [
|
|
2989
|
+
"export TAROUT_TOKEN=<token>",
|
|
2990
|
+
"tarout token <api-token>"
|
|
2991
|
+
]
|
|
2992
|
+
});
|
|
2993
|
+
} else {
|
|
2994
|
+
process.stderr.write(`error: ${message}
|
|
2995
|
+
`);
|
|
2996
|
+
}
|
|
2997
|
+
exit(ExitCode.AUTH_ERROR);
|
|
2998
|
+
}
|
|
2852
2999
|
function registerAuthCommands(program2) {
|
|
2853
3000
|
program2.command("login").description("Authenticate with Tarout via browser").option("--api-url <url>", "Custom API URL", "https://tarout.sa").action(async (options) => {
|
|
2854
3001
|
try {
|
|
2855
3002
|
if (isLoggedIn()) {
|
|
2856
3003
|
const profile = getCurrentProfile();
|
|
2857
3004
|
if (profile) {
|
|
3005
|
+
if (isJsonMode()) {
|
|
3006
|
+
outputData({
|
|
3007
|
+
alreadyLoggedIn: true,
|
|
3008
|
+
userEmail: profile.userEmail,
|
|
3009
|
+
organizationName: profile.organizationName
|
|
3010
|
+
});
|
|
3011
|
+
return;
|
|
3012
|
+
}
|
|
2858
3013
|
log(`Already logged in as ${colors.cyan(profile.userEmail)}`);
|
|
2859
3014
|
log(`Organization: ${profile.organizationName}`);
|
|
2860
3015
|
log("");
|
|
@@ -2862,6 +3017,9 @@ function registerAuthCommands(program2) {
|
|
|
2862
3017
|
return;
|
|
2863
3018
|
}
|
|
2864
3019
|
}
|
|
3020
|
+
if (isJsonMode() || isNonInteractiveMode()) {
|
|
3021
|
+
refuseBrowserAuthForAgent("login");
|
|
3022
|
+
}
|
|
2865
3023
|
const apiUrl = options.apiUrl;
|
|
2866
3024
|
log("");
|
|
2867
3025
|
log("Opening browser to authenticate...");
|
|
@@ -2955,11 +3113,22 @@ function registerAuthCommands(program2) {
|
|
|
2955
3113
|
if (isLoggedIn()) {
|
|
2956
3114
|
const profile = getCurrentProfile();
|
|
2957
3115
|
if (profile) {
|
|
3116
|
+
if (isJsonMode()) {
|
|
3117
|
+
outputData({
|
|
3118
|
+
alreadyLoggedIn: true,
|
|
3119
|
+
userEmail: profile.userEmail,
|
|
3120
|
+
organizationName: profile.organizationName
|
|
3121
|
+
});
|
|
3122
|
+
return;
|
|
3123
|
+
}
|
|
2958
3124
|
log(`Already logged in as ${colors.cyan(profile.userEmail)}`);
|
|
2959
3125
|
log(`Run ${colors.dim("tarout logout")} to sign out first.`);
|
|
2960
3126
|
return;
|
|
2961
3127
|
}
|
|
2962
3128
|
}
|
|
3129
|
+
if (isJsonMode() || isNonInteractiveMode()) {
|
|
3130
|
+
refuseBrowserAuthForAgent("register");
|
|
3131
|
+
}
|
|
2963
3132
|
const apiUrl = options.apiUrl;
|
|
2964
3133
|
log("");
|
|
2965
3134
|
log("Opening browser to create your account...");
|
|
@@ -3081,7 +3250,7 @@ function registerAuthCommands(program2) {
|
|
|
3081
3250
|
() => input("Token name (e.g., ci-deploy):")
|
|
3082
3251
|
);
|
|
3083
3252
|
}
|
|
3084
|
-
const { getApiClient: getApiClient2 } = await import("./api-
|
|
3253
|
+
const { getApiClient: getApiClient2 } = await import("./api-735LN7BA.js");
|
|
3085
3254
|
const client = getApiClient2();
|
|
3086
3255
|
const profile = getCurrentProfile();
|
|
3087
3256
|
const _spinner = startSpinner("Creating API token...");
|
|
@@ -3178,19 +3347,38 @@ function registerBackupsCommands(program2) {
|
|
|
3178
3347
|
dbType = "mysql";
|
|
3179
3348
|
dbId = options.mysqlId;
|
|
3180
3349
|
} else {
|
|
3181
|
-
dbType = await select(
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3350
|
+
dbType = await select(
|
|
3351
|
+
"Database type:",
|
|
3352
|
+
[
|
|
3353
|
+
{ name: "PostgreSQL", value: "postgres" },
|
|
3354
|
+
{ name: "MySQL", value: "mysql" }
|
|
3355
|
+
],
|
|
3356
|
+
{
|
|
3357
|
+
field: "database_type",
|
|
3358
|
+
flag: "--postgres-id|--mysql-id"
|
|
3359
|
+
}
|
|
3360
|
+
);
|
|
3185
3361
|
dbId = await input(
|
|
3186
|
-
`${dbType === "postgres" ? "PostgreSQL" : "MySQL"} database ID
|
|
3362
|
+
`${dbType === "postgres" ? "PostgreSQL" : "MySQL"} database ID:`,
|
|
3363
|
+
void 0,
|
|
3364
|
+
{
|
|
3365
|
+
field: "database_id",
|
|
3366
|
+
flag: dbType === "postgres" ? "--postgres-id" : "--mysql-id",
|
|
3367
|
+
context: { dbType }
|
|
3368
|
+
}
|
|
3187
3369
|
);
|
|
3188
3370
|
}
|
|
3189
3371
|
let destinationId = options.destinationId;
|
|
3190
3372
|
if (!destinationId) {
|
|
3191
|
-
destinationId = await input("Backup destination ID:"
|
|
3373
|
+
destinationId = await input("Backup destination ID:", void 0, {
|
|
3374
|
+
field: "destination_id",
|
|
3375
|
+
flag: "--destination-id"
|
|
3376
|
+
});
|
|
3192
3377
|
}
|
|
3193
|
-
const database = options.database || await input("Database name to back up:"
|
|
3378
|
+
const database = options.database || await input("Database name to back up:", void 0, {
|
|
3379
|
+
field: "database",
|
|
3380
|
+
flag: "--database"
|
|
3381
|
+
});
|
|
3194
3382
|
const _spinner = startSpinner("Creating backup schedule...");
|
|
3195
3383
|
const payload = {
|
|
3196
3384
|
databaseType: dbType,
|
|
@@ -3286,7 +3474,12 @@ function registerBackupsCommands(program2) {
|
|
|
3286
3474
|
if (!shouldSkipConfirmation()) {
|
|
3287
3475
|
const confirmed = await confirm(
|
|
3288
3476
|
`Delete backup schedule "${backupId}"?`,
|
|
3289
|
-
false
|
|
3477
|
+
false,
|
|
3478
|
+
{
|
|
3479
|
+
field: "confirm_delete_backup",
|
|
3480
|
+
flag: "--yes",
|
|
3481
|
+
context: { backupId }
|
|
3482
|
+
}
|
|
3290
3483
|
);
|
|
3291
3484
|
if (!confirmed) {
|
|
3292
3485
|
log("Cancelled.");
|
|
@@ -3416,7 +3609,7 @@ function registerBackupsCommands(program2) {
|
|
|
3416
3609
|
try {
|
|
3417
3610
|
if (!isLoggedIn()) throw new AuthError();
|
|
3418
3611
|
if (!shouldSkipConfirmation()) {
|
|
3419
|
-
const { confirm: confirmFn } = await import("./prompts-
|
|
3612
|
+
const { confirm: confirmFn } = await import("./prompts-QQ2FZKQT.js");
|
|
3420
3613
|
const ok = await confirmFn(
|
|
3421
3614
|
`Restore backup file "${backupFile}"? This will overwrite current data.`,
|
|
3422
3615
|
false
|
|
@@ -4039,21 +4232,32 @@ function registerDbCommands(program2) {
|
|
|
4039
4232
|
handleError(err);
|
|
4040
4233
|
}
|
|
4041
4234
|
});
|
|
4042
|
-
db.command("create").argument("[name]", "Database name").description("Create a new database").option("-t, --type <type>", "Database type (postgres, mysql)", "postgres").option("-d, --description <description>", "Database description").action(async (name, options) => {
|
|
4235
|
+
db.command("create").argument("[name]", "Database name").description("Create a new database").option("-t, --type <type>", "Database type (postgres, mysql)", "postgres").option("-d, --description <description>", "Database description").option("--name <name>", "Database name (alternative to positional argument)").action(async (name, options) => {
|
|
4043
4236
|
try {
|
|
4044
4237
|
if (!isLoggedIn()) throw new AuthError();
|
|
4045
4238
|
const profile = getCurrentProfile();
|
|
4046
4239
|
if (!profile) throw new AuthError();
|
|
4047
|
-
let dbName = name;
|
|
4240
|
+
let dbName = name || options.name;
|
|
4048
4241
|
let dbType = options.type;
|
|
4049
4242
|
if (!dbName) {
|
|
4050
|
-
dbName = await input("Database name:"
|
|
4243
|
+
dbName = await input("Database name:", void 0, {
|
|
4244
|
+
field: "db_name",
|
|
4245
|
+
flag: "--name"
|
|
4246
|
+
});
|
|
4051
4247
|
}
|
|
4052
4248
|
if (!options.type && !shouldSkipConfirmation()) {
|
|
4053
|
-
dbType = await select(
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4249
|
+
dbType = await select(
|
|
4250
|
+
"Database type:",
|
|
4251
|
+
[
|
|
4252
|
+
{ name: "PostgreSQL", value: "postgres" },
|
|
4253
|
+
{ name: "MySQL", value: "mysql" }
|
|
4254
|
+
],
|
|
4255
|
+
{
|
|
4256
|
+
field: "db_type",
|
|
4257
|
+
flag: "--type",
|
|
4258
|
+
context: { name: dbName }
|
|
4259
|
+
}
|
|
4260
|
+
);
|
|
4057
4261
|
}
|
|
4058
4262
|
const slug = generateSlug2(dbName);
|
|
4059
4263
|
const client = getApiClient();
|
|
@@ -4129,7 +4333,12 @@ function registerDbCommands(program2) {
|
|
|
4129
4333
|
log("");
|
|
4130
4334
|
const confirmed = await confirm(
|
|
4131
4335
|
`Are you sure you want to delete "${dbInfo.name}"? This cannot be undone.`,
|
|
4132
|
-
false
|
|
4336
|
+
false,
|
|
4337
|
+
{
|
|
4338
|
+
field: "confirm_delete_db",
|
|
4339
|
+
flag: "--yes",
|
|
4340
|
+
context: { id: dbInfo.id, name: dbInfo.name, type: dbInfo.type }
|
|
4341
|
+
}
|
|
4133
4342
|
);
|
|
4134
4343
|
if (!confirmed) {
|
|
4135
4344
|
log("Cancelled.");
|
|
@@ -4276,7 +4485,12 @@ function registerDbCommands(program2) {
|
|
|
4276
4485
|
if (!shouldSkipConfirmation()) {
|
|
4277
4486
|
const confirmed = await confirm(
|
|
4278
4487
|
`Stop database "${dbInfo.name}"?`,
|
|
4279
|
-
false
|
|
4488
|
+
false,
|
|
4489
|
+
{
|
|
4490
|
+
field: "confirm_stop_db",
|
|
4491
|
+
flag: "--yes",
|
|
4492
|
+
context: { id: dbInfo.id, name: dbInfo.name, type: dbInfo.type }
|
|
4493
|
+
}
|
|
4280
4494
|
);
|
|
4281
4495
|
if (!confirmed) {
|
|
4282
4496
|
log("Cancelled.");
|
|
@@ -4486,7 +4700,15 @@ function registerDbCommands(program2) {
|
|
|
4486
4700
|
failSpinner();
|
|
4487
4701
|
throw new NotFoundError("Database", dbIdentifier);
|
|
4488
4702
|
}
|
|
4489
|
-
const targetPlan = options.plan || await input("Target plan:"
|
|
4703
|
+
const targetPlan = options.plan || await input("Target plan:", void 0, {
|
|
4704
|
+
field: "target_plan",
|
|
4705
|
+
flag: "--plan",
|
|
4706
|
+
context: {
|
|
4707
|
+
id: dbSummary.id,
|
|
4708
|
+
name: dbSummary.name,
|
|
4709
|
+
type: dbSummary.type
|
|
4710
|
+
}
|
|
4711
|
+
});
|
|
4490
4712
|
const _upgradeSpinner = startSpinner(`Upgrading to ${targetPlan}...`);
|
|
4491
4713
|
if (dbSummary.type === "postgres") {
|
|
4492
4714
|
await client.postgres.upgrade.mutate({
|
|
@@ -5079,10 +5301,14 @@ async function promptForCredentials(apiUrl, message) {
|
|
|
5079
5301
|
{ name: "Log in to an existing account", value: "login" },
|
|
5080
5302
|
{ name: "Paste an API token", value: "token" },
|
|
5081
5303
|
{ name: "Create a free Tarout account", value: "register" }
|
|
5082
|
-
]
|
|
5304
|
+
],
|
|
5305
|
+
{ field: "auth_method", flag: "--token" }
|
|
5083
5306
|
);
|
|
5084
5307
|
if (authAction === "token") {
|
|
5085
|
-
const apiToken = await password("Tarout API token:"
|
|
5308
|
+
const apiToken = await password("Tarout API token:", {
|
|
5309
|
+
field: "token",
|
|
5310
|
+
flag: "--token"
|
|
5311
|
+
});
|
|
5086
5312
|
return authenticateViaApiToken(apiToken.trim(), apiUrl, {
|
|
5087
5313
|
showSuccess: true,
|
|
5088
5314
|
persist: true
|
|
@@ -5714,7 +5940,7 @@ function formatPlanPrice(priceHalalas) {
|
|
|
5714
5940
|
return `${(priceHalalas / 100).toFixed(2)} SAR/mo`;
|
|
5715
5941
|
}
|
|
5716
5942
|
async function runInlineUpgrade(client, planKey) {
|
|
5717
|
-
const { pollCheckoutUntilTerminal } = await import("./billing-
|
|
5943
|
+
const { pollCheckoutUntilTerminal } = await import("./billing-WOKNOS4N.js");
|
|
5718
5944
|
const _changing = startSpinner(`Switching to plan "${planKey}"...`);
|
|
5719
5945
|
const result = await client.subscription.changePlan.mutate({ planKey });
|
|
5720
5946
|
if (result?.applied) {
|
|
@@ -6803,8 +7029,12 @@ function registerDeployCommands(program2) {
|
|
|
6803
7029
|
name: `${colors.cyan(d.deploymentId.slice(0, 8))} - ${d.title || "Deployment"} (${formatDate5(d.createdAt)})${index === 0 ? colors.dim(" [current]") : ""}`,
|
|
6804
7030
|
value: d.deploymentId
|
|
6805
7031
|
}));
|
|
6806
|
-
const { select: select2 } = await import("./prompts-
|
|
6807
|
-
targetDeploymentId = await select2(
|
|
7032
|
+
const { select: select2 } = await import("./prompts-QQ2FZKQT.js");
|
|
7033
|
+
targetDeploymentId = await select2(
|
|
7034
|
+
"Select deployment:",
|
|
7035
|
+
choices,
|
|
7036
|
+
{ field: "deployment", flag: "--to" }
|
|
7037
|
+
);
|
|
6808
7038
|
}
|
|
6809
7039
|
if (!options.yes) {
|
|
6810
7040
|
const targetDeployment = successfulDeployments.find(
|
|
@@ -6818,10 +7048,18 @@ function registerDeployCommands(program2) {
|
|
|
6818
7048
|
` Created: ${targetDeployment ? formatDate5(targetDeployment.createdAt) : colors.dim("unknown")}`
|
|
6819
7049
|
);
|
|
6820
7050
|
log("");
|
|
6821
|
-
const { confirm: confirm2 } = await import("./prompts-
|
|
7051
|
+
const { confirm: confirm2 } = await import("./prompts-QQ2FZKQT.js");
|
|
6822
7052
|
const confirmed = await confirm2(
|
|
6823
7053
|
"Are you sure you want to rollback?",
|
|
6824
|
-
false
|
|
7054
|
+
false,
|
|
7055
|
+
{
|
|
7056
|
+
field: "confirm_rollback",
|
|
7057
|
+
flag: "--yes",
|
|
7058
|
+
context: {
|
|
7059
|
+
deploymentId: targetDeploymentId,
|
|
7060
|
+
app: appSummary.name
|
|
7061
|
+
}
|
|
7062
|
+
}
|
|
6825
7063
|
);
|
|
6826
7064
|
if (!confirmed) {
|
|
6827
7065
|
log("Cancelled.");
|
|
@@ -7209,19 +7447,46 @@ function registerDestinationsCommands(program2) {
|
|
|
7209
7447
|
async (options) => {
|
|
7210
7448
|
try {
|
|
7211
7449
|
if (!isLoggedIn()) throw new AuthError();
|
|
7212
|
-
const name = options.name || await input("Destination name:"
|
|
7213
|
-
|
|
7214
|
-
|
|
7215
|
-
|
|
7216
|
-
|
|
7217
|
-
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7450
|
+
const name = options.name || await input("Destination name:", void 0, {
|
|
7451
|
+
field: "name",
|
|
7452
|
+
flag: "--name"
|
|
7453
|
+
});
|
|
7454
|
+
const provider = options.provider || await select(
|
|
7455
|
+
"Storage provider:",
|
|
7456
|
+
[
|
|
7457
|
+
{ name: "S3 (AWS)", value: "s3" },
|
|
7458
|
+
{ name: "GCS (Google Cloud)", value: "gcs" },
|
|
7459
|
+
{ name: "R2 (Cloudflare)", value: "r2" },
|
|
7460
|
+
{ name: "Wasabi", value: "wasabi" },
|
|
7461
|
+
{ name: "MinIO (custom)", value: "minio" }
|
|
7462
|
+
],
|
|
7463
|
+
{
|
|
7464
|
+
field: "provider",
|
|
7465
|
+
flag: "--provider"
|
|
7466
|
+
}
|
|
7467
|
+
);
|
|
7468
|
+
const bucket = options.bucket || await input("Bucket name:", void 0, {
|
|
7469
|
+
field: "bucket",
|
|
7470
|
+
flag: "--bucket"
|
|
7471
|
+
});
|
|
7472
|
+
const region = options.region || await input("Region (or leave blank):", void 0, {
|
|
7473
|
+
field: "region",
|
|
7474
|
+
flag: "--region"
|
|
7475
|
+
}) || void 0;
|
|
7476
|
+
const endpoint = options.endpoint || await input("Custom endpoint URL (or leave blank):", void 0, {
|
|
7477
|
+
field: "endpoint",
|
|
7478
|
+
flag: "--endpoint"
|
|
7479
|
+
}) || void 0;
|
|
7480
|
+
const accessKey = options.accessKey || await input("Access Key ID:", void 0, {
|
|
7481
|
+
field: "access_key",
|
|
7482
|
+
flag: "--access-key",
|
|
7483
|
+
sensitive: true
|
|
7484
|
+
});
|
|
7485
|
+
const secretAccessKey = options.secretKey || await input("Secret Access Key:", void 0, {
|
|
7486
|
+
field: "secret_key",
|
|
7487
|
+
flag: "--secret-key",
|
|
7488
|
+
sensitive: true
|
|
7489
|
+
});
|
|
7225
7490
|
const client = getApiClient();
|
|
7226
7491
|
const _spinner = startSpinner("Creating destination...");
|
|
7227
7492
|
const result = await client.destination.create.mutate({
|
|
@@ -7276,7 +7541,12 @@ function registerDestinationsCommands(program2) {
|
|
|
7276
7541
|
if (!shouldSkipConfirmation()) {
|
|
7277
7542
|
const confirmed = await confirm(
|
|
7278
7543
|
`Delete destination "${destinationId}"?`,
|
|
7279
|
-
false
|
|
7544
|
+
false,
|
|
7545
|
+
{
|
|
7546
|
+
field: "confirm_delete_destination",
|
|
7547
|
+
flag: "--yes",
|
|
7548
|
+
context: { destinationId }
|
|
7549
|
+
}
|
|
7280
7550
|
);
|
|
7281
7551
|
if (!confirmed) {
|
|
7282
7552
|
log("Cancelled.");
|
|
@@ -7312,10 +7582,24 @@ function registerDestinationsCommands(program2) {
|
|
|
7312
7582
|
async (options) => {
|
|
7313
7583
|
try {
|
|
7314
7584
|
if (!isLoggedIn()) throw new AuthError();
|
|
7315
|
-
const provider = options.provider || await input("Storage provider (s3/gcs/r2):"
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7585
|
+
const provider = options.provider || await input("Storage provider (s3/gcs/r2):", void 0, {
|
|
7586
|
+
field: "provider",
|
|
7587
|
+
flag: "--provider"
|
|
7588
|
+
});
|
|
7589
|
+
const bucket = options.bucket || await input("Bucket name:", void 0, {
|
|
7590
|
+
field: "bucket",
|
|
7591
|
+
flag: "--bucket"
|
|
7592
|
+
});
|
|
7593
|
+
const accessKey = options.accessKey || await input("Access Key ID:", void 0, {
|
|
7594
|
+
field: "access_key",
|
|
7595
|
+
flag: "--access-key",
|
|
7596
|
+
sensitive: true
|
|
7597
|
+
});
|
|
7598
|
+
const secretAccessKey = options.secretKey || await input("Secret Access Key:", void 0, {
|
|
7599
|
+
field: "secret_key",
|
|
7600
|
+
flag: "--secret-key",
|
|
7601
|
+
sensitive: true
|
|
7602
|
+
});
|
|
7319
7603
|
const client = getApiClient();
|
|
7320
7604
|
const _spinner = startSpinner("Testing credentials...");
|
|
7321
7605
|
const result = await client.destination.testCredentials.mutate({
|
|
@@ -7561,7 +7845,12 @@ function registerDomainsCommands(program2) {
|
|
|
7561
7845
|
if (!shouldSkipConfirmation()) {
|
|
7562
7846
|
const confirmed = await confirm(
|
|
7563
7847
|
`Proceed to payment for ${domainName}?`,
|
|
7564
|
-
false
|
|
7848
|
+
false,
|
|
7849
|
+
{
|
|
7850
|
+
field: "confirm_register_domain",
|
|
7851
|
+
flag: "--yes",
|
|
7852
|
+
context: { domain: domainName }
|
|
7853
|
+
}
|
|
7565
7854
|
);
|
|
7566
7855
|
if (!confirmed) {
|
|
7567
7856
|
log("Cancelled.");
|
|
@@ -7782,7 +8071,12 @@ function registerDomainsCommands(program2) {
|
|
|
7782
8071
|
log("");
|
|
7783
8072
|
const confirmed = await confirm(
|
|
7784
8073
|
`Are you sure you want to unlink "${domain.host}"?`,
|
|
7785
|
-
false
|
|
8074
|
+
false,
|
|
8075
|
+
{
|
|
8076
|
+
field: "confirm_unlink_domain",
|
|
8077
|
+
flag: "--yes",
|
|
8078
|
+
context: { domain: domain.host, domainId: domain.domainId }
|
|
8079
|
+
}
|
|
7786
8080
|
);
|
|
7787
8081
|
if (!confirmed) {
|
|
7788
8082
|
log("Cancelled.");
|
|
@@ -8091,7 +8385,12 @@ function registerDomainsCommands(program2) {
|
|
|
8091
8385
|
if (!shouldSkipConfirmation()) {
|
|
8092
8386
|
const confirmed = await confirm(
|
|
8093
8387
|
`Are you sure you want to delete DNS record "${recordId}"?`,
|
|
8094
|
-
false
|
|
8388
|
+
false,
|
|
8389
|
+
{
|
|
8390
|
+
field: "confirm_delete_dns_record",
|
|
8391
|
+
flag: "--yes",
|
|
8392
|
+
context: { recordId }
|
|
8393
|
+
}
|
|
8095
8394
|
);
|
|
8096
8395
|
if (!confirmed) {
|
|
8097
8396
|
log("Cancelled.");
|
|
@@ -8429,7 +8728,12 @@ function registerDomainsCommands(program2) {
|
|
|
8429
8728
|
if (!shouldSkipConfirmation()) {
|
|
8430
8729
|
const confirmed = await confirm(
|
|
8431
8730
|
`Delete domain "${domainIdentifier}"?`,
|
|
8432
|
-
false
|
|
8731
|
+
false,
|
|
8732
|
+
{
|
|
8733
|
+
field: "confirm_delete_registered_domain",
|
|
8734
|
+
flag: "--yes",
|
|
8735
|
+
context: { domain: domainIdentifier }
|
|
8736
|
+
}
|
|
8433
8737
|
);
|
|
8434
8738
|
if (!confirmed) {
|
|
8435
8739
|
log("Cancelled.");
|
|
@@ -8542,7 +8846,11 @@ function registerDomainsCommands(program2) {
|
|
|
8542
8846
|
failSpinner();
|
|
8543
8847
|
throw new NotFoundError("Domain", domainIdentifier);
|
|
8544
8848
|
}
|
|
8545
|
-
const targetRegistrar = options.registrar || await input("Target registrar name:"
|
|
8849
|
+
const targetRegistrar = options.registrar || await input("Target registrar name:", void 0, {
|
|
8850
|
+
field: "target_registrar",
|
|
8851
|
+
flag: "--registrar",
|
|
8852
|
+
context: { domain: domainIdentifier }
|
|
8853
|
+
});
|
|
8546
8854
|
const _transferSpinner = startSpinner("Requesting transfer out...");
|
|
8547
8855
|
await client.domainRegistrar.requestTransferOut.mutate({
|
|
8548
8856
|
domainId: domain.domainId,
|
|
@@ -8791,8 +9099,16 @@ function registerDomainsCommands(program2) {
|
|
|
8791
9099
|
failSpinner();
|
|
8792
9100
|
throw new NotFoundError("Domain", domainIdentifier);
|
|
8793
9101
|
}
|
|
8794
|
-
const name = options.name || await input("Rule name:"
|
|
8795
|
-
|
|
9102
|
+
const name = options.name || await input("Rule name:", void 0, {
|
|
9103
|
+
field: "firewall_rule_name",
|
|
9104
|
+
flag: "--name",
|
|
9105
|
+
context: { domain: domainIdentifier }
|
|
9106
|
+
});
|
|
9107
|
+
const expression = options.expression || await input("Firewall expression:", void 0, {
|
|
9108
|
+
field: "firewall_expression",
|
|
9109
|
+
flag: "--expression",
|
|
9110
|
+
context: { domain: domainIdentifier }
|
|
9111
|
+
});
|
|
8796
9112
|
const action = options.action || "block";
|
|
8797
9113
|
const _createSpinner = startSpinner("Creating firewall rule...");
|
|
8798
9114
|
const result = await client.domainRegistrar.createFirewallRule.mutate(
|
|
@@ -8939,7 +9255,11 @@ function registerDomainsCommands(program2) {
|
|
|
8939
9255
|
failSpinner();
|
|
8940
9256
|
throw new NotFoundError("Domain", domainIdentifier);
|
|
8941
9257
|
}
|
|
8942
|
-
const ipAddress = options.ip || await input("IP address:"
|
|
9258
|
+
const ipAddress = options.ip || await input("IP address:", void 0, {
|
|
9259
|
+
field: "ip_address",
|
|
9260
|
+
flag: "--ip",
|
|
9261
|
+
context: { domain: domainIdentifier }
|
|
9262
|
+
});
|
|
8943
9263
|
const _setupSpinner = startSpinner("Setting up DNS records...");
|
|
8944
9264
|
await client.dns.setupCommonRecords.mutate({
|
|
8945
9265
|
registeredDomainId: domain.domainId,
|
|
@@ -9119,9 +9439,20 @@ function registerDomainsCommands(program2) {
|
|
|
9119
9439
|
async (options) => {
|
|
9120
9440
|
try {
|
|
9121
9441
|
if (!isLoggedIn()) throw new AuthError();
|
|
9122
|
-
const registeredDomainId = options.registeredDomain || await input("Registered domain ID:"
|
|
9123
|
-
|
|
9124
|
-
|
|
9442
|
+
const registeredDomainId = options.registeredDomain || await input("Registered domain ID:", void 0, {
|
|
9443
|
+
field: "registered_domain_id",
|
|
9444
|
+
flag: "--registered-domain"
|
|
9445
|
+
});
|
|
9446
|
+
const subdomain = options.subdomain || await input("Subdomain (e.g. www):", void 0, {
|
|
9447
|
+
field: "subdomain",
|
|
9448
|
+
flag: "--subdomain",
|
|
9449
|
+
context: { registeredDomainId }
|
|
9450
|
+
});
|
|
9451
|
+
const applicationId = options.app || await input("Application ID:", void 0, {
|
|
9452
|
+
field: "application_id",
|
|
9453
|
+
flag: "--app",
|
|
9454
|
+
context: { registeredDomainId, subdomain }
|
|
9455
|
+
});
|
|
9125
9456
|
const client = getApiClient();
|
|
9126
9457
|
const _spinner = startSpinner("Creating domain...");
|
|
9127
9458
|
const result = await client.domain.createWithRegisteredDomain.mutate({
|
|
@@ -9290,8 +9621,15 @@ function registerDomainsCommands(program2) {
|
|
|
9290
9621
|
async (options) => {
|
|
9291
9622
|
try {
|
|
9292
9623
|
if (!isLoggedIn()) throw new AuthError();
|
|
9293
|
-
const domainId = options.domainId || await input("Domain ID:"
|
|
9294
|
-
|
|
9624
|
+
const domainId = options.domainId || await input("Domain ID:", void 0, {
|
|
9625
|
+
field: "domain_id",
|
|
9626
|
+
flag: "--domain-id"
|
|
9627
|
+
});
|
|
9628
|
+
const applicationId = options.appId || await input("Application ID:", void 0, {
|
|
9629
|
+
field: "application_id",
|
|
9630
|
+
flag: "--app-id",
|
|
9631
|
+
context: { domainId }
|
|
9632
|
+
});
|
|
9295
9633
|
const client = getApiClient();
|
|
9296
9634
|
const _spinner = startSpinner("Linking domain...");
|
|
9297
9635
|
await client.domain.linkToApplication.mutate({
|
|
@@ -9393,7 +9731,10 @@ function registerEmailCommands(program2) {
|
|
|
9393
9731
|
config.command("get").description("Show email configuration for an environment").option("-e, --env <environment-id>", "Environment ID").action(async (options) => {
|
|
9394
9732
|
try {
|
|
9395
9733
|
if (!isLoggedIn()) throw new AuthError();
|
|
9396
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
9734
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
9735
|
+
field: "environment_id",
|
|
9736
|
+
flag: "--env"
|
|
9737
|
+
});
|
|
9397
9738
|
const client = getApiClient();
|
|
9398
9739
|
const _spinner = startSpinner("Fetching email config...");
|
|
9399
9740
|
const data = await client.emailService.getConfig.query({
|
|
@@ -9433,17 +9774,38 @@ function registerEmailCommands(program2) {
|
|
|
9433
9774
|
async (options) => {
|
|
9434
9775
|
try {
|
|
9435
9776
|
if (!isLoggedIn()) throw new AuthError();
|
|
9436
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9777
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
9778
|
+
field: "environment_id",
|
|
9779
|
+
flag: "--env"
|
|
9780
|
+
});
|
|
9781
|
+
const provider = options.provider || await select(
|
|
9782
|
+
"Email provider:",
|
|
9783
|
+
[
|
|
9784
|
+
{ name: "Resend", value: "resend" },
|
|
9785
|
+
{ name: "SendGrid", value: "sendgrid" },
|
|
9786
|
+
{ name: "Mailgun", value: "mailgun" },
|
|
9787
|
+
{ name: "Amazon SES", value: "ses" }
|
|
9788
|
+
],
|
|
9789
|
+
{ field: "email_provider", flag: "--provider" }
|
|
9790
|
+
);
|
|
9791
|
+
const apiKey = options.apiKey || await input("API Key:", void 0, {
|
|
9792
|
+
field: "api_key",
|
|
9793
|
+
flag: "--api-key",
|
|
9794
|
+
sensitive: true
|
|
9795
|
+
});
|
|
9796
|
+
const fromDomain = options.fromDomain || await input("From domain (e.g. mail.example.com):", void 0, {
|
|
9797
|
+
field: "from_domain",
|
|
9798
|
+
flag: "--from-domain"
|
|
9799
|
+
});
|
|
9800
|
+
const fromName = options.fromName || await input("From name:", void 0, {
|
|
9801
|
+
field: "from_name",
|
|
9802
|
+
flag: "--from-name"
|
|
9803
|
+
});
|
|
9804
|
+
const fromEmail = options.fromEmail || await input(
|
|
9805
|
+
`From email (e.g. hello@${fromDomain}):`,
|
|
9806
|
+
void 0,
|
|
9807
|
+
{ field: "from_email", flag: "--from-email" }
|
|
9808
|
+
);
|
|
9447
9809
|
const client = getApiClient();
|
|
9448
9810
|
const _spinner = startSpinner("Creating email config...");
|
|
9449
9811
|
const result = await client.emailService.createConfig.mutate({
|
|
@@ -9492,7 +9854,12 @@ function registerEmailCommands(program2) {
|
|
|
9492
9854
|
if (!shouldSkipConfirmation()) {
|
|
9493
9855
|
const confirmed = await confirm(
|
|
9494
9856
|
`Delete email configuration "${emailServiceId}"?`,
|
|
9495
|
-
false
|
|
9857
|
+
false,
|
|
9858
|
+
{
|
|
9859
|
+
field: "confirm_delete_email_config",
|
|
9860
|
+
flag: "--yes",
|
|
9861
|
+
context: { emailServiceId }
|
|
9862
|
+
}
|
|
9496
9863
|
);
|
|
9497
9864
|
if (!confirmed) {
|
|
9498
9865
|
log("Cancelled.");
|
|
@@ -9515,8 +9882,14 @@ function registerEmailCommands(program2) {
|
|
|
9515
9882
|
domain.command("verify").description("Initiate email domain verification").option("-e, --env <environment-id>", "Environment ID").option("-d, --domain <domain>", "Domain to verify").action(async (options) => {
|
|
9516
9883
|
try {
|
|
9517
9884
|
if (!isLoggedIn()) throw new AuthError();
|
|
9518
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
9519
|
-
|
|
9885
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
9886
|
+
field: "environment_id",
|
|
9887
|
+
flag: "--env"
|
|
9888
|
+
});
|
|
9889
|
+
const domainName = options.domain || await input("Domain to verify:", void 0, {
|
|
9890
|
+
field: "domain",
|
|
9891
|
+
flag: "--domain"
|
|
9892
|
+
});
|
|
9520
9893
|
const client = getApiClient();
|
|
9521
9894
|
const _spinner = startSpinner("Initiating domain verification...");
|
|
9522
9895
|
const result = await client.emailService.verifyDomain.mutate({
|
|
@@ -9533,8 +9906,14 @@ function registerEmailCommands(program2) {
|
|
|
9533
9906
|
domain.command("status").description("Check email domain verification status").option("-e, --env <environment-id>", "Environment ID").option("-d, --domain <domain>", "Domain to check").action(async (options) => {
|
|
9534
9907
|
try {
|
|
9535
9908
|
if (!isLoggedIn()) throw new AuthError();
|
|
9536
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
9537
|
-
|
|
9909
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
9910
|
+
field: "environment_id",
|
|
9911
|
+
flag: "--env"
|
|
9912
|
+
});
|
|
9913
|
+
const domainName = options.domain || await input("Domain name:", void 0, {
|
|
9914
|
+
field: "domain",
|
|
9915
|
+
flag: "--domain"
|
|
9916
|
+
});
|
|
9538
9917
|
const client = getApiClient();
|
|
9539
9918
|
const _spinner = startSpinner("Checking domain status...");
|
|
9540
9919
|
const data = await client.emailService.getDomainStatus.query({
|
|
@@ -9562,8 +9941,14 @@ function registerEmailCommands(program2) {
|
|
|
9562
9941
|
async (options) => {
|
|
9563
9942
|
try {
|
|
9564
9943
|
if (!isLoggedIn()) throw new AuthError();
|
|
9565
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
9566
|
-
|
|
9944
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
9945
|
+
field: "environment_id",
|
|
9946
|
+
flag: "--env"
|
|
9947
|
+
});
|
|
9948
|
+
const domainName = options.domain || await input("Domain name:", void 0, {
|
|
9949
|
+
field: "domain",
|
|
9950
|
+
flag: "--domain"
|
|
9951
|
+
});
|
|
9567
9952
|
const client = getApiClient();
|
|
9568
9953
|
const _spinner = startSpinner("Fetching DNS records...");
|
|
9569
9954
|
const data = await client.emailService.getDnsRecords.query({
|
|
@@ -9599,7 +9984,10 @@ function registerEmailCommands(program2) {
|
|
|
9599
9984
|
templates.command("list").alias("ls").description("List email templates").option("-e, --env <environment-id>", "Environment ID").option("--active", "Show only active templates").action(async (options) => {
|
|
9600
9985
|
try {
|
|
9601
9986
|
if (!isLoggedIn()) throw new AuthError();
|
|
9602
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
9987
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
9988
|
+
field: "environment_id",
|
|
9989
|
+
flag: "--env"
|
|
9990
|
+
});
|
|
9603
9991
|
const client = getApiClient();
|
|
9604
9992
|
const _spinner = startSpinner("Fetching templates...");
|
|
9605
9993
|
const list = await client.emailService.listTemplates.query({
|
|
@@ -9636,7 +10024,10 @@ function registerEmailCommands(program2) {
|
|
|
9636
10024
|
templates.command("get-by-slug <slug>").description("Get an email template by its slug").option("-e, --env <environment-id>", "Environment ID").action(async (slug, options) => {
|
|
9637
10025
|
try {
|
|
9638
10026
|
if (!isLoggedIn()) throw new AuthError();
|
|
9639
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
10027
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
10028
|
+
field: "environment_id",
|
|
10029
|
+
flag: "--env"
|
|
10030
|
+
});
|
|
9640
10031
|
const client = getApiClient();
|
|
9641
10032
|
const _spinner = startSpinner("Fetching template...");
|
|
9642
10033
|
const data = await client.emailService.getTemplateBySlug.query({
|
|
@@ -9700,10 +10091,22 @@ function registerEmailCommands(program2) {
|
|
|
9700
10091
|
async (options) => {
|
|
9701
10092
|
try {
|
|
9702
10093
|
if (!isLoggedIn()) throw new AuthError();
|
|
9703
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
10094
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
10095
|
+
field: "environment_id",
|
|
10096
|
+
flag: "--env"
|
|
10097
|
+
});
|
|
10098
|
+
const name = options.name || await input("Template name:", void 0, {
|
|
10099
|
+
field: "template_name",
|
|
10100
|
+
flag: "--name"
|
|
10101
|
+
});
|
|
10102
|
+
const subject = options.subject || await input("Email subject:", void 0, {
|
|
10103
|
+
field: "email_subject",
|
|
10104
|
+
flag: "--subject"
|
|
10105
|
+
});
|
|
10106
|
+
const htmlContent = options.html || await input("HTML content (or paste):", void 0, {
|
|
10107
|
+
field: "html_content",
|
|
10108
|
+
flag: "--html"
|
|
10109
|
+
});
|
|
9707
10110
|
const client = getApiClient();
|
|
9708
10111
|
const _spinner = startSpinner("Creating template...");
|
|
9709
10112
|
const result = await client.emailService.createTemplate.mutate({
|
|
@@ -9756,7 +10159,12 @@ function registerEmailCommands(program2) {
|
|
|
9756
10159
|
if (!shouldSkipConfirmation()) {
|
|
9757
10160
|
const confirmed = await confirm(
|
|
9758
10161
|
`Delete template "${templateId}"?`,
|
|
9759
|
-
false
|
|
10162
|
+
false,
|
|
10163
|
+
{
|
|
10164
|
+
field: "confirm_delete_template",
|
|
10165
|
+
flag: "--yes",
|
|
10166
|
+
context: { templateId }
|
|
10167
|
+
}
|
|
9760
10168
|
);
|
|
9761
10169
|
if (!confirmed) {
|
|
9762
10170
|
log("Cancelled.");
|
|
@@ -9778,7 +10186,10 @@ function registerEmailCommands(program2) {
|
|
|
9778
10186
|
templates.command("seed").description("Seed pre-built templates for an environment").option("-e, --env <environment-id>", "Environment ID").action(async (options) => {
|
|
9779
10187
|
try {
|
|
9780
10188
|
if (!isLoggedIn()) throw new AuthError();
|
|
9781
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
10189
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
10190
|
+
field: "environment_id",
|
|
10191
|
+
flag: "--env"
|
|
10192
|
+
});
|
|
9782
10193
|
const client = getApiClient();
|
|
9783
10194
|
const _spinner = startSpinner("Seeding templates...");
|
|
9784
10195
|
const result = await client.emailService.seedPrebuiltTemplates.mutate({
|
|
@@ -9795,9 +10206,18 @@ function registerEmailCommands(program2) {
|
|
|
9795
10206
|
async (options) => {
|
|
9796
10207
|
try {
|
|
9797
10208
|
if (!isLoggedIn()) throw new AuthError();
|
|
9798
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
9799
|
-
|
|
9800
|
-
|
|
10209
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
10210
|
+
field: "environment_id",
|
|
10211
|
+
flag: "--env"
|
|
10212
|
+
});
|
|
10213
|
+
const to = options.to || await input("Recipient email:", void 0, {
|
|
10214
|
+
field: "recipient_email",
|
|
10215
|
+
flag: "--to"
|
|
10216
|
+
});
|
|
10217
|
+
const subject = options.subject || await input("Subject:", void 0, {
|
|
10218
|
+
field: "email_subject",
|
|
10219
|
+
flag: "--subject"
|
|
10220
|
+
});
|
|
9801
10221
|
const html = options.html || options.text;
|
|
9802
10222
|
const client = getApiClient();
|
|
9803
10223
|
const _spinner = startSpinner("Sending email...");
|
|
@@ -9821,9 +10241,18 @@ function registerEmailCommands(program2) {
|
|
|
9821
10241
|
async (options) => {
|
|
9822
10242
|
try {
|
|
9823
10243
|
if (!isLoggedIn()) throw new AuthError();
|
|
9824
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
9825
|
-
|
|
9826
|
-
|
|
10244
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
10245
|
+
field: "environment_id",
|
|
10246
|
+
flag: "--env"
|
|
10247
|
+
});
|
|
10248
|
+
const templateId = options.templateId || await input("Template ID:", void 0, {
|
|
10249
|
+
field: "template_id",
|
|
10250
|
+
flag: "--template-id"
|
|
10251
|
+
});
|
|
10252
|
+
const to = options.to || await input("Recipient email:", void 0, {
|
|
10253
|
+
field: "recipient_email",
|
|
10254
|
+
flag: "--to"
|
|
10255
|
+
});
|
|
9827
10256
|
const variables = options.vars ? JSON.parse(options.vars) : {};
|
|
9828
10257
|
const client = getApiClient();
|
|
9829
10258
|
const _spinner = startSpinner("Sending templated email...");
|
|
@@ -9845,7 +10274,10 @@ function registerEmailCommands(program2) {
|
|
|
9845
10274
|
async (options) => {
|
|
9846
10275
|
try {
|
|
9847
10276
|
if (!isLoggedIn()) throw new AuthError();
|
|
9848
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
10277
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
10278
|
+
field: "environment_id",
|
|
10279
|
+
flag: "--env"
|
|
10280
|
+
});
|
|
9849
10281
|
const client = getApiClient();
|
|
9850
10282
|
const _spinner = startSpinner("Fetching logs...");
|
|
9851
10283
|
const logs = await client.emailService.getEmailLogs.query({
|
|
@@ -9884,7 +10316,10 @@ function registerEmailCommands(program2) {
|
|
|
9884
10316
|
email.command("stats").description("Show email sending statistics").option("-e, --env <environment-id>", "Environment ID").option("--start <date>", "Start date (ISO)").option("--end <date>", "End date (ISO)").action(async (options) => {
|
|
9885
10317
|
try {
|
|
9886
10318
|
if (!isLoggedIn()) throw new AuthError();
|
|
9887
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
10319
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
10320
|
+
field: "environment_id",
|
|
10321
|
+
flag: "--env"
|
|
10322
|
+
});
|
|
9888
10323
|
const client = getApiClient();
|
|
9889
10324
|
const _spinner = startSpinner("Fetching stats...");
|
|
9890
10325
|
const stats = await client.emailService.getEmailStats.query({
|
|
@@ -9916,7 +10351,10 @@ function registerEmailCommands(program2) {
|
|
|
9916
10351
|
apiKeys.command("list").alias("ls").description("List email service API keys").option("-e, --env <environment-id>", "Environment ID").action(async (options) => {
|
|
9917
10352
|
try {
|
|
9918
10353
|
if (!isLoggedIn()) throw new AuthError();
|
|
9919
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
10354
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
10355
|
+
field: "environment_id",
|
|
10356
|
+
flag: "--env"
|
|
10357
|
+
});
|
|
9920
10358
|
const client = getApiClient();
|
|
9921
10359
|
const _spinner = startSpinner("Fetching API keys...");
|
|
9922
10360
|
const list = await client.emailService.listApiKeys.query({
|
|
@@ -9951,8 +10389,14 @@ function registerEmailCommands(program2) {
|
|
|
9951
10389
|
apiKeys.command("create").description("Create an email service API key").option("-e, --env <environment-id>", "Environment ID").option("-n, --name <name>", "Key name").option("--mode <mode>", "Key mode (sending/full)", "sending").action(async (options) => {
|
|
9952
10390
|
try {
|
|
9953
10391
|
if (!isLoggedIn()) throw new AuthError();
|
|
9954
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
9955
|
-
|
|
10392
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
10393
|
+
field: "environment_id",
|
|
10394
|
+
flag: "--env"
|
|
10395
|
+
});
|
|
10396
|
+
const name = options.name || await input("API key name:", void 0, {
|
|
10397
|
+
field: "api_key_name",
|
|
10398
|
+
flag: "--name"
|
|
10399
|
+
});
|
|
9956
10400
|
const client = getApiClient();
|
|
9957
10401
|
const _spinner = startSpinner("Creating API key...");
|
|
9958
10402
|
const result = await client.emailService.createApiKey.mutate({
|
|
@@ -9977,7 +10421,10 @@ function registerEmailCommands(program2) {
|
|
|
9977
10421
|
apiKeys.command("update <api-key-id>").description("Update an email service API key").option("-n, --name <name>", "New name").action(async (apiKeyId, options) => {
|
|
9978
10422
|
try {
|
|
9979
10423
|
if (!isLoggedIn()) throw new AuthError();
|
|
9980
|
-
const name = options.name || await input("New name:"
|
|
10424
|
+
const name = options.name || await input("New name:", void 0, {
|
|
10425
|
+
field: "new_name",
|
|
10426
|
+
flag: "--name"
|
|
10427
|
+
});
|
|
9981
10428
|
const client = getApiClient();
|
|
9982
10429
|
const _spinner = startSpinner("Updating API key...");
|
|
9983
10430
|
await client.emailService.updateApiKey.mutate({
|
|
@@ -9997,7 +10444,12 @@ function registerEmailCommands(program2) {
|
|
|
9997
10444
|
if (!shouldSkipConfirmation()) {
|
|
9998
10445
|
const confirmed = await confirm(
|
|
9999
10446
|
`Revoke API key "${apiKeyId}"?`,
|
|
10000
|
-
false
|
|
10447
|
+
false,
|
|
10448
|
+
{
|
|
10449
|
+
field: "confirm_revoke_api_key",
|
|
10450
|
+
flag: "--yes",
|
|
10451
|
+
context: { apiKeyId }
|
|
10452
|
+
}
|
|
10001
10453
|
);
|
|
10002
10454
|
if (!confirmed) {
|
|
10003
10455
|
log("Cancelled.");
|
|
@@ -10020,7 +10472,12 @@ function registerEmailCommands(program2) {
|
|
|
10020
10472
|
if (!shouldSkipConfirmation()) {
|
|
10021
10473
|
const confirmed = await confirm(
|
|
10022
10474
|
`Delete API key "${apiKeyId}"?`,
|
|
10023
|
-
false
|
|
10475
|
+
false,
|
|
10476
|
+
{
|
|
10477
|
+
field: "confirm_delete_api_key",
|
|
10478
|
+
flag: "--yes",
|
|
10479
|
+
context: { apiKeyId }
|
|
10480
|
+
}
|
|
10024
10481
|
);
|
|
10025
10482
|
if (!confirmed) {
|
|
10026
10483
|
log("Cancelled.");
|
|
@@ -10204,7 +10661,12 @@ function registerEnvCommands(program2) {
|
|
|
10204
10661
|
succeedSpinner();
|
|
10205
10662
|
const confirmed = await confirm(
|
|
10206
10663
|
`File ${options.output} already exists. Overwrite?`,
|
|
10207
|
-
false
|
|
10664
|
+
false,
|
|
10665
|
+
{
|
|
10666
|
+
field: "confirm_overwrite_env_file",
|
|
10667
|
+
flag: "--yes",
|
|
10668
|
+
context: { outputPath: options.output }
|
|
10669
|
+
}
|
|
10208
10670
|
);
|
|
10209
10671
|
if (!confirmed) {
|
|
10210
10672
|
log("Cancelled.");
|
|
@@ -10462,7 +10924,7 @@ ${colors.bold(key)}: ${maskValue(val.value || String(v))}
|
|
|
10462
10924
|
} else {
|
|
10463
10925
|
const _raw = await import("process");
|
|
10464
10926
|
log('Enter JSON key-value object (e.g. {"KEY":"value"}):');
|
|
10465
|
-
const input2 = await (await import("./prompts-
|
|
10927
|
+
const input2 = await (await import("./prompts-QQ2FZKQT.js")).input(
|
|
10466
10928
|
"JSON:"
|
|
10467
10929
|
);
|
|
10468
10930
|
vars = JSON.parse(input2);
|
|
@@ -10485,7 +10947,7 @@ ${colors.bold(key)}: ${maskValue(val.value || String(v))}
|
|
|
10485
10947
|
try {
|
|
10486
10948
|
if (!isLoggedIn()) throw new AuthError();
|
|
10487
10949
|
if (!shouldSkipConfirmation()) {
|
|
10488
|
-
const { confirm: confirmFn } = await import("./prompts-
|
|
10950
|
+
const { confirm: confirmFn } = await import("./prompts-QQ2FZKQT.js");
|
|
10489
10951
|
const ok = await confirmFn(
|
|
10490
10952
|
`Delete ${keys.length} variable(s)?`,
|
|
10491
10953
|
false
|
|
@@ -10524,7 +10986,7 @@ ${colors.bold(key)}: ${maskValue(val.value || String(v))}
|
|
|
10524
10986
|
);
|
|
10525
10987
|
if (!app) throw new NotFoundError("Application", appIdentifier);
|
|
10526
10988
|
if (!shouldSkipConfirmation()) {
|
|
10527
|
-
const { confirm: confirmFn } = await import("./prompts-
|
|
10989
|
+
const { confirm: confirmFn } = await import("./prompts-QQ2FZKQT.js");
|
|
10528
10990
|
const ok = await confirmFn(
|
|
10529
10991
|
`Copy env vars from ${fromEnvId} to ${toEnvId}?`,
|
|
10530
10992
|
false
|
|
@@ -10633,27 +11095,61 @@ function registerFirewallCommands(program2) {
|
|
|
10633
11095
|
handleError(err);
|
|
10634
11096
|
}
|
|
10635
11097
|
});
|
|
10636
|
-
fw.command("create").description("Create a new firewall template").option("-n, --name <name>", "Template name").
|
|
11098
|
+
fw.command("create").description("Create a new firewall template").option("-n, --name <name>", "Template name").option(
|
|
11099
|
+
"--rules <json>",
|
|
11100
|
+
"JSON array of rules: [{protocol,portRange,direction,sourceRanges}]"
|
|
11101
|
+
).action(async (options) => {
|
|
10637
11102
|
try {
|
|
10638
11103
|
if (!isLoggedIn()) throw new AuthError();
|
|
10639
|
-
const name = options.name || await input("Template name:"
|
|
11104
|
+
const name = options.name || await input("Template name:", void 0, {
|
|
11105
|
+
field: "firewall_template_name",
|
|
11106
|
+
flag: "--name"
|
|
11107
|
+
});
|
|
10640
11108
|
log("");
|
|
10641
11109
|
log("Add rules interactively (leave protocol empty to finish):");
|
|
10642
11110
|
const rules = [];
|
|
10643
11111
|
for (let i = 0; i < 10; i++) {
|
|
10644
|
-
const protocol = await select(
|
|
10645
|
-
{
|
|
10646
|
-
|
|
10647
|
-
|
|
10648
|
-
|
|
10649
|
-
|
|
11112
|
+
const protocol = await select(
|
|
11113
|
+
`Rule ${i + 1} protocol (or skip):`,
|
|
11114
|
+
[
|
|
11115
|
+
{ name: "TCP", value: "tcp" },
|
|
11116
|
+
{ name: "UDP", value: "udp" },
|
|
11117
|
+
{ name: "ICMP", value: "icmp" },
|
|
11118
|
+
{ name: "Done \u2014 no more rules", value: "__done__" }
|
|
11119
|
+
],
|
|
11120
|
+
{
|
|
11121
|
+
field: `firewall_rule_${i}_protocol`,
|
|
11122
|
+
flag: "--rules",
|
|
11123
|
+
context: { ruleIndex: i }
|
|
11124
|
+
}
|
|
11125
|
+
);
|
|
10650
11126
|
if (protocol === "__done__") break;
|
|
10651
|
-
const portRange = await input(
|
|
10652
|
-
|
|
10653
|
-
|
|
10654
|
-
{
|
|
10655
|
-
|
|
10656
|
-
|
|
11127
|
+
const portRange = await input(
|
|
11128
|
+
"Port range (e.g. 80 or 8080-8090):",
|
|
11129
|
+
void 0,
|
|
11130
|
+
{
|
|
11131
|
+
field: `firewall_rule_${i}_port_range`,
|
|
11132
|
+
flag: "--rules",
|
|
11133
|
+
context: { ruleIndex: i }
|
|
11134
|
+
}
|
|
11135
|
+
);
|
|
11136
|
+
const direction = await select(
|
|
11137
|
+
"Direction:",
|
|
11138
|
+
[
|
|
11139
|
+
{ name: "Ingress (inbound)", value: "ingress" },
|
|
11140
|
+
{ name: "Egress (outbound)", value: "egress" }
|
|
11141
|
+
],
|
|
11142
|
+
{
|
|
11143
|
+
field: `firewall_rule_${i}_direction`,
|
|
11144
|
+
flag: "--rules",
|
|
11145
|
+
context: { ruleIndex: i }
|
|
11146
|
+
}
|
|
11147
|
+
);
|
|
11148
|
+
const sourceRanges = await input("Source CIDR (default 0.0.0.0/0):", void 0, {
|
|
11149
|
+
field: `firewall_rule_${i}_source_ranges`,
|
|
11150
|
+
flag: "--rules",
|
|
11151
|
+
context: { ruleIndex: i }
|
|
11152
|
+
}) || "0.0.0.0/0";
|
|
10657
11153
|
rules.push({ protocol, portRange, direction, sourceRanges });
|
|
10658
11154
|
}
|
|
10659
11155
|
const client = getApiClient();
|
|
@@ -10678,7 +11174,11 @@ function registerFirewallCommands(program2) {
|
|
|
10678
11174
|
fw.command("update").argument("<id>", "Firewall template ID").description("Update a firewall template name").option("-n, --name <name>", "New template name").action(async (id, options) => {
|
|
10679
11175
|
try {
|
|
10680
11176
|
if (!isLoggedIn()) throw new AuthError();
|
|
10681
|
-
const name = options.name || await input("New name:"
|
|
11177
|
+
const name = options.name || await input("New name:", void 0, {
|
|
11178
|
+
field: "firewall_template_name",
|
|
11179
|
+
flag: "--name",
|
|
11180
|
+
context: { templateId: id }
|
|
11181
|
+
});
|
|
10682
11182
|
const client = getApiClient();
|
|
10683
11183
|
const _spinner = startSpinner("Updating firewall template...");
|
|
10684
11184
|
const result = await client.firewallTemplate.update.mutate({
|
|
@@ -10697,7 +11197,12 @@ function registerFirewallCommands(program2) {
|
|
|
10697
11197
|
if (!shouldSkipConfirmation()) {
|
|
10698
11198
|
const confirmed = await confirm(
|
|
10699
11199
|
`Delete firewall template "${id}"?`,
|
|
10700
|
-
false
|
|
11200
|
+
false,
|
|
11201
|
+
{
|
|
11202
|
+
field: "confirm_delete_firewall_template",
|
|
11203
|
+
flag: "--yes",
|
|
11204
|
+
context: { templateId: id }
|
|
11205
|
+
}
|
|
10701
11206
|
);
|
|
10702
11207
|
if (!confirmed) {
|
|
10703
11208
|
log("Cancelled.");
|
|
@@ -10743,7 +11248,12 @@ function registerFirewallCommands(program2) {
|
|
|
10743
11248
|
if (!shouldSkipConfirmation()) {
|
|
10744
11249
|
const confirmed = await confirm(
|
|
10745
11250
|
`Remove firewall template from server ${serverId}?`,
|
|
10746
|
-
false
|
|
11251
|
+
false,
|
|
11252
|
+
{
|
|
11253
|
+
field: "confirm_remove_firewall_template",
|
|
11254
|
+
flag: "--yes",
|
|
11255
|
+
context: { templateId, serverId }
|
|
11256
|
+
}
|
|
10747
11257
|
);
|
|
10748
11258
|
if (!confirmed) {
|
|
10749
11259
|
log("Cancelled.");
|
|
@@ -10900,7 +11410,11 @@ function registerInboxCommands(program2) {
|
|
|
10900
11410
|
if (!shouldSkipConfirmation()) {
|
|
10901
11411
|
const confirmed = await confirm(
|
|
10902
11412
|
"Clear all notifications? This cannot be undone.",
|
|
10903
|
-
false
|
|
11413
|
+
false,
|
|
11414
|
+
{
|
|
11415
|
+
field: "confirm_clear_notifications",
|
|
11416
|
+
flag: "--yes"
|
|
11417
|
+
}
|
|
10904
11418
|
);
|
|
10905
11419
|
if (!confirmed) {
|
|
10906
11420
|
log("Cancelled.");
|
|
@@ -10965,7 +11479,10 @@ function registerKeysCommands(program2) {
|
|
|
10965
11479
|
let keyName = name;
|
|
10966
11480
|
let publicKey = options.publicKey;
|
|
10967
11481
|
if (!keyName) {
|
|
10968
|
-
keyName = await input("Key name:"
|
|
11482
|
+
keyName = await input("Key name:", void 0, {
|
|
11483
|
+
field: "name",
|
|
11484
|
+
flag: "--name"
|
|
11485
|
+
});
|
|
10969
11486
|
}
|
|
10970
11487
|
if (!publicKey && options.file) {
|
|
10971
11488
|
const { readFileSync: readFileSync4 } = await import("fs");
|
|
@@ -10975,7 +11492,11 @@ function registerKeysCommands(program2) {
|
|
|
10975
11492
|
log(
|
|
10976
11493
|
"Paste your public key below (usually found in ~/.ssh/id_rsa.pub):"
|
|
10977
11494
|
);
|
|
10978
|
-
publicKey = await input("Public key:"
|
|
11495
|
+
publicKey = await input("Public key:", void 0, {
|
|
11496
|
+
field: "publicKey",
|
|
11497
|
+
flag: "--public-key",
|
|
11498
|
+
sensitive: false
|
|
11499
|
+
});
|
|
10979
11500
|
}
|
|
10980
11501
|
const client = getApiClient();
|
|
10981
11502
|
const _spinner = startSpinner("Adding SSH key...");
|
|
@@ -11020,7 +11541,12 @@ function registerKeysCommands(program2) {
|
|
|
11020
11541
|
log("");
|
|
11021
11542
|
const confirmed = await confirm(
|
|
11022
11543
|
`Are you sure you want to delete SSH key "${key.name}"?`,
|
|
11023
|
-
false
|
|
11544
|
+
false,
|
|
11545
|
+
{
|
|
11546
|
+
field: "confirm_delete_ssh_key",
|
|
11547
|
+
flag: "--yes",
|
|
11548
|
+
context: { keyName: key.name }
|
|
11549
|
+
}
|
|
11024
11550
|
);
|
|
11025
11551
|
if (!confirmed) {
|
|
11026
11552
|
log("Cancelled.");
|
|
@@ -11184,7 +11710,12 @@ function registerLinkCommands(program2) {
|
|
|
11184
11710
|
log("");
|
|
11185
11711
|
const confirmed = await confirm(
|
|
11186
11712
|
"Do you want to relink to a different application?",
|
|
11187
|
-
false
|
|
11713
|
+
false,
|
|
11714
|
+
{
|
|
11715
|
+
field: "confirm_relink",
|
|
11716
|
+
flag: "--yes",
|
|
11717
|
+
context: { currentApp: existingConfig.name }
|
|
11718
|
+
}
|
|
11188
11719
|
);
|
|
11189
11720
|
if (!confirmed) {
|
|
11190
11721
|
log("Cancelled.");
|
|
@@ -11222,7 +11753,11 @@ function registerLinkCommands(program2) {
|
|
|
11222
11753
|
value: app.applicationId
|
|
11223
11754
|
})
|
|
11224
11755
|
);
|
|
11225
|
-
const selectedId = await select(
|
|
11756
|
+
const selectedId = await select(
|
|
11757
|
+
"Select an application:",
|
|
11758
|
+
choices,
|
|
11759
|
+
{ field: "app", flag: "--app" }
|
|
11760
|
+
);
|
|
11226
11761
|
selectedApp = apps.find(
|
|
11227
11762
|
(a) => a.applicationId === selectedId
|
|
11228
11763
|
) || null;
|
|
@@ -11282,7 +11817,12 @@ function registerLinkCommands(program2) {
|
|
|
11282
11817
|
log("");
|
|
11283
11818
|
const confirmed = await confirm(
|
|
11284
11819
|
"Are you sure you want to unlink this directory?",
|
|
11285
|
-
false
|
|
11820
|
+
false,
|
|
11821
|
+
{
|
|
11822
|
+
field: "confirm_unlink",
|
|
11823
|
+
flag: "--yes",
|
|
11824
|
+
context: { currentApp: config.name }
|
|
11825
|
+
}
|
|
11286
11826
|
);
|
|
11287
11827
|
if (!confirmed) {
|
|
11288
11828
|
log("Cancelled.");
|
|
@@ -11486,13 +12026,25 @@ function registerMonitorCommands(program2) {
|
|
|
11486
12026
|
let monitorUrl = options.url;
|
|
11487
12027
|
if (!monitorName) {
|
|
11488
12028
|
monitorName = await input(
|
|
11489
|
-
`Monitor name (default: ${app.name} uptime)
|
|
12029
|
+
`Monitor name (default: ${app.name} uptime):`,
|
|
12030
|
+
void 0,
|
|
12031
|
+
{
|
|
12032
|
+
field: "monitor_name",
|
|
12033
|
+
flag: "--name",
|
|
12034
|
+
context: { applicationId: app.applicationId, appName: app.name }
|
|
12035
|
+
}
|
|
11490
12036
|
);
|
|
11491
12037
|
if (!monitorName) monitorName = `${app.name} uptime`;
|
|
11492
12038
|
}
|
|
11493
12039
|
if (!monitorUrl) {
|
|
11494
12040
|
monitorUrl = await input(
|
|
11495
|
-
"URL to monitor (e.g., https://example.com/health):"
|
|
12041
|
+
"URL to monitor (e.g., https://example.com/health):",
|
|
12042
|
+
void 0,
|
|
12043
|
+
{
|
|
12044
|
+
field: "monitor_url",
|
|
12045
|
+
flag: "--url",
|
|
12046
|
+
context: { applicationId: app.applicationId }
|
|
12047
|
+
}
|
|
11496
12048
|
);
|
|
11497
12049
|
}
|
|
11498
12050
|
const _createSpinner = startSpinner("Creating monitor...");
|
|
@@ -11574,7 +12126,12 @@ function registerMonitorCommands(program2) {
|
|
|
11574
12126
|
if (!shouldSkipConfirmation()) {
|
|
11575
12127
|
const confirmed = await confirm(
|
|
11576
12128
|
`Delete monitor "${monitorId}"?`,
|
|
11577
|
-
false
|
|
12129
|
+
false,
|
|
12130
|
+
{
|
|
12131
|
+
field: "confirm_delete_monitor",
|
|
12132
|
+
flag: "--yes",
|
|
12133
|
+
context: { monitorId }
|
|
12134
|
+
}
|
|
11578
12135
|
);
|
|
11579
12136
|
if (!confirmed) {
|
|
11580
12137
|
log("Cancelled.");
|
|
@@ -11810,7 +12367,10 @@ function registerNotificationsCommands(program2) {
|
|
|
11810
12367
|
try {
|
|
11811
12368
|
if (!isLoggedIn()) throw new AuthError();
|
|
11812
12369
|
const client = getApiClient();
|
|
11813
|
-
const name = options.name || await input("Name (press Enter for default):"
|
|
12370
|
+
const name = options.name || await input("Name (press Enter for default):", void 0, {
|
|
12371
|
+
field: "name",
|
|
12372
|
+
flag: "--name"
|
|
12373
|
+
}) || "Email Notifications";
|
|
11814
12374
|
const payload = {
|
|
11815
12375
|
name,
|
|
11816
12376
|
appDeploy: options.deploy ?? false,
|
|
@@ -11841,7 +12401,12 @@ function registerNotificationsCommands(program2) {
|
|
|
11841
12401
|
if (!shouldSkipConfirmation()) {
|
|
11842
12402
|
const confirmed = await confirm(
|
|
11843
12403
|
`Delete notification configuration "${notificationId}"?`,
|
|
11844
|
-
false
|
|
12404
|
+
false,
|
|
12405
|
+
{
|
|
12406
|
+
field: "confirm_delete_notification",
|
|
12407
|
+
flag: "--yes",
|
|
12408
|
+
context: { notificationId }
|
|
12409
|
+
}
|
|
11845
12410
|
);
|
|
11846
12411
|
if (!confirmed) {
|
|
11847
12412
|
log("Cancelled.");
|
|
@@ -11930,10 +12495,16 @@ function registerNotificationsCommands(program2) {
|
|
|
11930
12495
|
let title = options.title;
|
|
11931
12496
|
let message = options.message;
|
|
11932
12497
|
if (!title) {
|
|
11933
|
-
title = await input("Subject:"
|
|
12498
|
+
title = await input("Subject:", void 0, {
|
|
12499
|
+
field: "title",
|
|
12500
|
+
flag: "--title"
|
|
12501
|
+
});
|
|
11934
12502
|
}
|
|
11935
12503
|
if (!message) {
|
|
11936
|
-
message = await input("Message:"
|
|
12504
|
+
message = await input("Message:", void 0, {
|
|
12505
|
+
field: "message",
|
|
12506
|
+
flag: "--message"
|
|
12507
|
+
});
|
|
11937
12508
|
}
|
|
11938
12509
|
const client = getApiClient();
|
|
11939
12510
|
const _spinner = startSpinner("Sending message...");
|
|
@@ -11957,7 +12528,10 @@ function registerNotificationsCommands(program2) {
|
|
|
11957
12528
|
notifications.command("create").description("Create a new notification configuration (org owner only)").option("-n, --name <name>", "Configuration name").option("--deploy", "Enable deploy notifications").option("--errors", "Enable build error notifications").option("--backups", "Enable backup notifications").option("--uptime", "Enable uptime alert notifications").option("--emails <emails>", "Comma-separated additional email addresses").action(async (options) => {
|
|
11958
12529
|
try {
|
|
11959
12530
|
if (!isLoggedIn()) throw new AuthError();
|
|
11960
|
-
const name = options.name || await input("Name:"
|
|
12531
|
+
const name = options.name || await input("Name:", void 0, {
|
|
12532
|
+
field: "name",
|
|
12533
|
+
flag: "--name"
|
|
12534
|
+
}) || "Notifications";
|
|
11961
12535
|
const client = getApiClient();
|
|
11962
12536
|
const _spinner = startSpinner("Creating notification config...");
|
|
11963
12537
|
const result = await client.notification.create.mutate({
|
|
@@ -12048,7 +12622,13 @@ function registerOrgsCommands(program2) {
|
|
|
12048
12622
|
let name = options.name;
|
|
12049
12623
|
if (!name) {
|
|
12050
12624
|
name = await input(
|
|
12051
|
-
`New name (current: ${profile.organizationName})
|
|
12625
|
+
`New name (current: ${profile.organizationName}):`,
|
|
12626
|
+
void 0,
|
|
12627
|
+
{
|
|
12628
|
+
field: "organization_name",
|
|
12629
|
+
flag: "--name",
|
|
12630
|
+
context: { currentName: profile.organizationName }
|
|
12631
|
+
}
|
|
12052
12632
|
);
|
|
12053
12633
|
}
|
|
12054
12634
|
const client = getApiClient();
|
|
@@ -12078,7 +12658,15 @@ function registerOrgsCommands(program2) {
|
|
|
12078
12658
|
log("");
|
|
12079
12659
|
const confirmed = await confirm(
|
|
12080
12660
|
`Type the organization name "${profile.organizationName}" to confirm deletion:`,
|
|
12081
|
-
false
|
|
12661
|
+
false,
|
|
12662
|
+
{
|
|
12663
|
+
field: "confirm_delete_organization",
|
|
12664
|
+
flag: "--yes",
|
|
12665
|
+
context: {
|
|
12666
|
+
organizationId: profile.organizationId,
|
|
12667
|
+
organizationName: profile.organizationName
|
|
12668
|
+
}
|
|
12669
|
+
}
|
|
12082
12670
|
);
|
|
12083
12671
|
if (!confirmed) {
|
|
12084
12672
|
log("Cancelled.");
|
|
@@ -12121,7 +12709,15 @@ function registerOrgsCommands(program2) {
|
|
|
12121
12709
|
log("");
|
|
12122
12710
|
const confirmed = await confirm(
|
|
12123
12711
|
`Transfer ownership to user "${userId}"?`,
|
|
12124
|
-
false
|
|
12712
|
+
false,
|
|
12713
|
+
{
|
|
12714
|
+
field: "confirm_transfer_ownership",
|
|
12715
|
+
flag: "--yes",
|
|
12716
|
+
context: {
|
|
12717
|
+
organizationId: profile.organizationId,
|
|
12718
|
+
newOwnerUserId: userId
|
|
12719
|
+
}
|
|
12720
|
+
}
|
|
12125
12721
|
);
|
|
12126
12722
|
if (!confirmed) {
|
|
12127
12723
|
log("Cancelled.");
|
|
@@ -12223,7 +12819,12 @@ function registerOrgsCommands(program2) {
|
|
|
12223
12819
|
if (!shouldSkipConfirmation()) {
|
|
12224
12820
|
const confirmed = await confirm(
|
|
12225
12821
|
`Revoke invitation "${invitationId}"?`,
|
|
12226
|
-
false
|
|
12822
|
+
false,
|
|
12823
|
+
{
|
|
12824
|
+
field: "confirm_revoke_invitation",
|
|
12825
|
+
flag: "--yes",
|
|
12826
|
+
context: { invitationId }
|
|
12827
|
+
}
|
|
12227
12828
|
);
|
|
12228
12829
|
if (!confirmed) {
|
|
12229
12830
|
log("Cancelled.");
|
|
@@ -12371,7 +12972,11 @@ function registerEnvsCommands(program2) {
|
|
|
12371
12972
|
if (!isLoggedIn()) throw new AuthError();
|
|
12372
12973
|
let envName = name;
|
|
12373
12974
|
if (!envName) {
|
|
12374
|
-
envName = await input(
|
|
12975
|
+
envName = await input(
|
|
12976
|
+
"Environment name (e.g., staging):",
|
|
12977
|
+
void 0,
|
|
12978
|
+
{ field: "environment_name", flag: "name" }
|
|
12979
|
+
);
|
|
12375
12980
|
}
|
|
12376
12981
|
const client = getApiClient();
|
|
12377
12982
|
const _spinner = startSpinner("Creating environment...");
|
|
@@ -12420,7 +13025,15 @@ function registerEnvsCommands(program2) {
|
|
|
12420
13025
|
log("");
|
|
12421
13026
|
const confirmed = await confirm(
|
|
12422
13027
|
`Delete environment "${env.name}"?`,
|
|
12423
|
-
false
|
|
13028
|
+
false,
|
|
13029
|
+
{
|
|
13030
|
+
field: "confirm_delete_environment",
|
|
13031
|
+
flag: "--yes",
|
|
13032
|
+
context: {
|
|
13033
|
+
environmentId: env.environmentId,
|
|
13034
|
+
environmentName: env.name
|
|
13035
|
+
}
|
|
13036
|
+
}
|
|
12424
13037
|
);
|
|
12425
13038
|
if (!confirmed) {
|
|
12426
13039
|
log("Cancelled.");
|
|
@@ -12798,7 +13411,11 @@ function registerProjectsCommands(program2) {
|
|
|
12798
13411
|
if (!isLoggedIn()) throw new AuthError();
|
|
12799
13412
|
let name = options.name;
|
|
12800
13413
|
if (!name) {
|
|
12801
|
-
name = await input("New name (leave blank to keep):"
|
|
13414
|
+
name = await input("New name (leave blank to keep):", void 0, {
|
|
13415
|
+
field: "project_name",
|
|
13416
|
+
flag: "--name",
|
|
13417
|
+
context: { projectId }
|
|
13418
|
+
});
|
|
12802
13419
|
}
|
|
12803
13420
|
const client = getApiClient();
|
|
12804
13421
|
const _spinner = startSpinner("Updating project...");
|
|
@@ -12828,7 +13445,12 @@ function registerProjectsCommands(program2) {
|
|
|
12828
13445
|
log("");
|
|
12829
13446
|
const confirmed = await confirm(
|
|
12830
13447
|
`Delete project "${projectId}"? This cannot be undone.`,
|
|
12831
|
-
false
|
|
13448
|
+
false,
|
|
13449
|
+
{
|
|
13450
|
+
field: "confirm_delete_project",
|
|
13451
|
+
flag: "--yes",
|
|
13452
|
+
context: { projectId }
|
|
13453
|
+
}
|
|
12832
13454
|
);
|
|
12833
13455
|
if (!confirmed) {
|
|
12834
13456
|
log("Cancelled.");
|
|
@@ -13034,7 +13656,12 @@ function registerProvidersCommands(program2) {
|
|
|
13034
13656
|
if (!shouldSkipConfirmation()) {
|
|
13035
13657
|
const confirmed = await confirm(
|
|
13036
13658
|
`Remove provider "${gitProviderId}"?`,
|
|
13037
|
-
false
|
|
13659
|
+
false,
|
|
13660
|
+
{
|
|
13661
|
+
field: "confirm_remove_provider",
|
|
13662
|
+
flag: "--yes",
|
|
13663
|
+
context: { gitProviderId }
|
|
13664
|
+
}
|
|
13038
13665
|
);
|
|
13039
13666
|
if (!confirmed) {
|
|
13040
13667
|
log("Cancelled.");
|
|
@@ -13204,7 +13831,10 @@ function registerProvidersCommands(program2) {
|
|
|
13204
13831
|
github.command("update <github-id>").description("Update a GitHub provider name").option("-n, --name <name>", "New name").action(async (githubId, options) => {
|
|
13205
13832
|
try {
|
|
13206
13833
|
if (!isLoggedIn()) throw new AuthError();
|
|
13207
|
-
const name = options.name || await input("New name for this provider:"
|
|
13834
|
+
const name = options.name || await input("New name for this provider:", void 0, {
|
|
13835
|
+
field: "provider_name",
|
|
13836
|
+
flag: "--name"
|
|
13837
|
+
});
|
|
13208
13838
|
const client = getApiClient();
|
|
13209
13839
|
const _spinner = startSpinner("Updating provider...");
|
|
13210
13840
|
const data = await client.github.one.query({ githubId });
|
|
@@ -13256,8 +13886,15 @@ function registerProvidersCommands(program2) {
|
|
|
13256
13886
|
async (options) => {
|
|
13257
13887
|
try {
|
|
13258
13888
|
if (!isLoggedIn()) throw new AuthError();
|
|
13259
|
-
const applicationId = options.applicationId || await input("GitLab OAuth Application ID:"
|
|
13260
|
-
|
|
13889
|
+
const applicationId = options.applicationId || await input("GitLab OAuth Application ID:", void 0, {
|
|
13890
|
+
field: "gitlab_application_id",
|
|
13891
|
+
flag: "--application-id"
|
|
13892
|
+
});
|
|
13893
|
+
const secret = options.secret || await input("GitLab OAuth Secret:", void 0, {
|
|
13894
|
+
field: "gitlab_oauth_secret",
|
|
13895
|
+
flag: "--secret",
|
|
13896
|
+
sensitive: true
|
|
13897
|
+
});
|
|
13261
13898
|
const client = getApiClient();
|
|
13262
13899
|
const _spinner = startSpinner("Creating GitLab provider...");
|
|
13263
13900
|
const result = await client.gitlab.create.mutate({
|
|
@@ -13422,7 +14059,11 @@ function registerProvidersCommands(program2) {
|
|
|
13422
14059
|
bitbucket.command("create").description("Create a Bitbucket provider").option("--client-id <id>", "Bitbucket OAuth Client ID").option("--secret <secret>", "Bitbucket OAuth Secret").action(async (options) => {
|
|
13423
14060
|
try {
|
|
13424
14061
|
if (!isLoggedIn()) throw new AuthError();
|
|
13425
|
-
const appPassword = options.secret || await input("Bitbucket App Password or Secret:"
|
|
14062
|
+
const appPassword = options.secret || await input("Bitbucket App Password or Secret:", void 0, {
|
|
14063
|
+
field: "bitbucket_oauth_secret",
|
|
14064
|
+
flag: "--secret",
|
|
14065
|
+
sensitive: true
|
|
14066
|
+
});
|
|
13426
14067
|
const client = getApiClient();
|
|
13427
14068
|
const _spinner = startSpinner("Creating Bitbucket provider...");
|
|
13428
14069
|
const result = await client.bitbucket.create.mutate({
|
|
@@ -13680,7 +14321,12 @@ No ${options.status} jobs in queue "${queueName}".
|
|
|
13680
14321
|
if (!shouldSkipConfirmation()) {
|
|
13681
14322
|
const ok = await confirm(
|
|
13682
14323
|
`Retry all failed jobs in queue "${queueName}"?`,
|
|
13683
|
-
false
|
|
14324
|
+
false,
|
|
14325
|
+
{
|
|
14326
|
+
field: "confirm_retry_all_failed_jobs",
|
|
14327
|
+
flag: "--yes",
|
|
14328
|
+
context: { queueName }
|
|
14329
|
+
}
|
|
13684
14330
|
);
|
|
13685
14331
|
if (!ok) {
|
|
13686
14332
|
log("Cancelled.");
|
|
@@ -13708,7 +14354,11 @@ ${colors.success(`${count} job(s) queued for retry.`)}
|
|
|
13708
14354
|
try {
|
|
13709
14355
|
if (!isLoggedIn()) throw new AuthError();
|
|
13710
14356
|
if (!shouldSkipConfirmation()) {
|
|
13711
|
-
const ok = await confirm(`Pause queue "${queueName}"?`, false
|
|
14357
|
+
const ok = await confirm(`Pause queue "${queueName}"?`, false, {
|
|
14358
|
+
field: "confirm_pause_queue",
|
|
14359
|
+
flag: "--yes",
|
|
14360
|
+
context: { queueName }
|
|
14361
|
+
});
|
|
13712
14362
|
if (!ok) {
|
|
13713
14363
|
log("Cancelled.");
|
|
13714
14364
|
return;
|
|
@@ -13742,14 +14392,23 @@ ${colors.success(`${count} job(s) queued for retry.`)}
|
|
|
13742
14392
|
).option("--older-than <ms>", "Clean jobs older than N milliseconds", "0").description("Remove completed or failed jobs from a queue").action(async (queueName, options) => {
|
|
13743
14393
|
try {
|
|
13744
14394
|
if (!isLoggedIn()) throw new AuthError();
|
|
13745
|
-
const status = options.status || await select(
|
|
13746
|
-
|
|
13747
|
-
|
|
13748
|
-
|
|
14395
|
+
const status = options.status || await select(
|
|
14396
|
+
"Clean which jobs?",
|
|
14397
|
+
[
|
|
14398
|
+
{ name: "Completed", value: "completed" },
|
|
14399
|
+
{ name: "Failed", value: "failed" }
|
|
14400
|
+
],
|
|
14401
|
+
{ field: "clean_job_status", flag: "--status" }
|
|
14402
|
+
);
|
|
13749
14403
|
if (!shouldSkipConfirmation()) {
|
|
13750
14404
|
const ok = await confirm(
|
|
13751
14405
|
`Clean ${status} jobs from "${queueName}"?`,
|
|
13752
|
-
false
|
|
14406
|
+
false,
|
|
14407
|
+
{
|
|
14408
|
+
field: "confirm_clean_queue",
|
|
14409
|
+
flag: "--yes",
|
|
14410
|
+
context: { queueName, status }
|
|
14411
|
+
}
|
|
13753
14412
|
);
|
|
13754
14413
|
if (!ok) {
|
|
13755
14414
|
log("Cancelled.");
|
|
@@ -13781,7 +14440,12 @@ ${colors.success(`${count} ${status} job(s) removed.`)}
|
|
|
13781
14440
|
if (!shouldSkipConfirmation()) {
|
|
13782
14441
|
const ok = await confirm(
|
|
13783
14442
|
`Remove job "${jobId}" from queue "${queueName}"?`,
|
|
13784
|
-
false
|
|
14443
|
+
false,
|
|
14444
|
+
{
|
|
14445
|
+
field: "confirm_remove_job",
|
|
14446
|
+
flag: "--yes",
|
|
14447
|
+
context: { queueName, jobId }
|
|
14448
|
+
}
|
|
13785
14449
|
);
|
|
13786
14450
|
if (!ok) {
|
|
13787
14451
|
log("Cancelled.");
|
|
@@ -13859,13 +14523,20 @@ function registerServersCommands(program2) {
|
|
|
13859
14523
|
let serverSize = options.size;
|
|
13860
14524
|
let osType = options.os;
|
|
13861
14525
|
if (!serverName) {
|
|
13862
|
-
serverName = await input("Server name:"
|
|
14526
|
+
serverName = await input("Server name:", void 0, {
|
|
14527
|
+
field: "server_name",
|
|
14528
|
+
flag: "<name>"
|
|
14529
|
+
});
|
|
13863
14530
|
}
|
|
13864
14531
|
if (!serverType) {
|
|
13865
|
-
serverType = await select(
|
|
13866
|
-
|
|
13867
|
-
|
|
13868
|
-
|
|
14532
|
+
serverType = await select(
|
|
14533
|
+
"Server type:",
|
|
14534
|
+
[
|
|
14535
|
+
{ name: "CPU (general purpose)", value: "cpu" },
|
|
14536
|
+
{ name: "GPU (for AI/ML workloads)", value: "gpu" }
|
|
14537
|
+
],
|
|
14538
|
+
{ field: "server_type", flag: "--type" }
|
|
14539
|
+
);
|
|
13869
14540
|
}
|
|
13870
14541
|
const _spinner = startSpinner("Fetching available sizes...");
|
|
13871
14542
|
const sizes = await client.virtualMachine.getServerTypes.query({
|
|
@@ -13879,19 +14550,28 @@ function registerServersCommands(program2) {
|
|
|
13879
14550
|
name: `${s.name || s.id} - ${s.description || ""} ${s.priceHalalas ? `(${(s.priceHalalas / 100).toFixed(2)} SAR/hr)` : ""}`,
|
|
13880
14551
|
value: s.name || s.id || s.size
|
|
13881
14552
|
}));
|
|
13882
|
-
serverSize = await select("Server size:", sizeChoices
|
|
14553
|
+
serverSize = await select("Server size:", sizeChoices, {
|
|
14554
|
+
field: "server_size",
|
|
14555
|
+
flag: "--size"
|
|
14556
|
+
});
|
|
13883
14557
|
} else if (!serverSize) {
|
|
13884
14558
|
serverSize = await input(
|
|
13885
|
-
"Server size (e.g., n2-standard-2 for GCP, GPU-small for RunPod):"
|
|
14559
|
+
"Server size (e.g., n2-standard-2 for GCP, GPU-small for RunPod):",
|
|
14560
|
+
void 0,
|
|
14561
|
+
{ field: "server_size", flag: "--size" }
|
|
13886
14562
|
);
|
|
13887
14563
|
}
|
|
13888
14564
|
if (!osType) {
|
|
13889
|
-
osType = await select(
|
|
13890
|
-
|
|
13891
|
-
|
|
13892
|
-
|
|
13893
|
-
|
|
13894
|
-
|
|
14565
|
+
osType = await select(
|
|
14566
|
+
"Operating system:",
|
|
14567
|
+
[
|
|
14568
|
+
{ name: "Ubuntu 22.04 LTS", value: "ubuntu-22" },
|
|
14569
|
+
{ name: "Ubuntu 24.04 LTS", value: "ubuntu-24" },
|
|
14570
|
+
{ name: "Debian 12", value: "debian-12" },
|
|
14571
|
+
{ name: "Rocky Linux 9", value: "rocky-linux-9" }
|
|
14572
|
+
],
|
|
14573
|
+
{ field: "os_type", flag: "--os" }
|
|
14574
|
+
);
|
|
13895
14575
|
}
|
|
13896
14576
|
if (!shouldSkipConfirmation()) {
|
|
13897
14577
|
log("");
|
|
@@ -13900,7 +14580,11 @@ function registerServersCommands(program2) {
|
|
|
13900
14580
|
log(`Size: ${serverSize}`);
|
|
13901
14581
|
log(`OS: ${osType}`);
|
|
13902
14582
|
log("");
|
|
13903
|
-
const confirmed = await confirm("Create this server?", false
|
|
14583
|
+
const confirmed = await confirm("Create this server?", false, {
|
|
14584
|
+
field: "confirm_create_server",
|
|
14585
|
+
flag: "--yes",
|
|
14586
|
+
context: { name: serverName, type: serverType, size: serverSize }
|
|
14587
|
+
});
|
|
13904
14588
|
if (!confirmed) {
|
|
13905
14589
|
log("Cancelled.");
|
|
13906
14590
|
return;
|
|
@@ -14027,7 +14711,12 @@ function registerServersCommands(program2) {
|
|
|
14027
14711
|
if (!shouldSkipConfirmation()) {
|
|
14028
14712
|
const confirmed = await confirm(
|
|
14029
14713
|
`Stop server "${server.name || serverIdentifier}"?`,
|
|
14030
|
-
false
|
|
14714
|
+
false,
|
|
14715
|
+
{
|
|
14716
|
+
field: "confirm_stop_server",
|
|
14717
|
+
flag: "--yes",
|
|
14718
|
+
context: { server: server.name || serverIdentifier }
|
|
14719
|
+
}
|
|
14031
14720
|
);
|
|
14032
14721
|
if (!confirmed) {
|
|
14033
14722
|
log("Cancelled.");
|
|
@@ -14100,7 +14789,12 @@ function registerServersCommands(program2) {
|
|
|
14100
14789
|
log("");
|
|
14101
14790
|
const confirmed = await confirm(
|
|
14102
14791
|
`Are you sure you want to delete server "${server.name || serverIdentifier}"?`,
|
|
14103
|
-
false
|
|
14792
|
+
false,
|
|
14793
|
+
{
|
|
14794
|
+
field: "confirm_delete_server",
|
|
14795
|
+
flag: "--yes",
|
|
14796
|
+
context: { server: server.name || serverIdentifier }
|
|
14797
|
+
}
|
|
14104
14798
|
);
|
|
14105
14799
|
if (!confirmed) {
|
|
14106
14800
|
log("Cancelled.");
|
|
@@ -14266,7 +14960,9 @@ function registerServersCommands(program2) {
|
|
|
14266
14960
|
let name = snapshotName;
|
|
14267
14961
|
if (!name) {
|
|
14268
14962
|
name = await input(
|
|
14269
|
-
`Snapshot name (default: ${server.name}-snapshot-${Date.now()})
|
|
14963
|
+
`Snapshot name (default: ${server.name}-snapshot-${Date.now()}):`,
|
|
14964
|
+
void 0,
|
|
14965
|
+
{ field: "snapshot_name", flag: "<snapshot-name>" }
|
|
14270
14966
|
);
|
|
14271
14967
|
if (!name) {
|
|
14272
14968
|
name = `${server.name || serverIdentifier}-snapshot-${Date.now()}`;
|
|
@@ -14296,7 +14992,12 @@ function registerServersCommands(program2) {
|
|
|
14296
14992
|
if (!shouldSkipConfirmation()) {
|
|
14297
14993
|
const confirmed = await confirm(
|
|
14298
14994
|
`Delete snapshot "${snapshotId}"?`,
|
|
14299
|
-
false
|
|
14995
|
+
false,
|
|
14996
|
+
{
|
|
14997
|
+
field: "confirm_delete_snapshot",
|
|
14998
|
+
flag: "--yes",
|
|
14999
|
+
context: { snapshotId }
|
|
15000
|
+
}
|
|
14300
15001
|
);
|
|
14301
15002
|
if (!confirmed) {
|
|
14302
15003
|
log("Cancelled.");
|
|
@@ -14372,7 +15073,11 @@ function registerServersCommands(program2) {
|
|
|
14372
15073
|
}
|
|
14373
15074
|
let portRange = options.port;
|
|
14374
15075
|
if (!portRange) {
|
|
14375
|
-
portRange = await input(
|
|
15076
|
+
portRange = await input(
|
|
15077
|
+
"Port or range (e.g., 80, 443, 8000-9000):",
|
|
15078
|
+
void 0,
|
|
15079
|
+
{ field: "port_range", flag: "--port" }
|
|
15080
|
+
);
|
|
14376
15081
|
}
|
|
14377
15082
|
const _addSpinner = startSpinner("Adding firewall rule...");
|
|
14378
15083
|
const result = await client.virtualMachine.createFirewallRule.mutate({
|
|
@@ -14402,7 +15107,12 @@ function registerServersCommands(program2) {
|
|
|
14402
15107
|
if (!shouldSkipConfirmation()) {
|
|
14403
15108
|
const confirmed = await confirm(
|
|
14404
15109
|
`Delete firewall rule "${ruleId}"?`,
|
|
14405
|
-
false
|
|
15110
|
+
false,
|
|
15111
|
+
{
|
|
15112
|
+
field: "confirm_delete_firewall_rule",
|
|
15113
|
+
flag: "--yes",
|
|
15114
|
+
context: { ruleId }
|
|
15115
|
+
}
|
|
14406
15116
|
);
|
|
14407
15117
|
if (!confirmed) {
|
|
14408
15118
|
log("Cancelled.");
|
|
@@ -14618,7 +15328,10 @@ function registerServersCommands(program2) {
|
|
|
14618
15328
|
}
|
|
14619
15329
|
let name = options.name;
|
|
14620
15330
|
if (!name) {
|
|
14621
|
-
name = await input("Volume name:"
|
|
15331
|
+
name = await input("Volume name:", void 0, {
|
|
15332
|
+
field: "volume_name",
|
|
15333
|
+
flag: "--name"
|
|
15334
|
+
});
|
|
14622
15335
|
}
|
|
14623
15336
|
const _createSpinner = startSpinner("Creating volume...");
|
|
14624
15337
|
const vol = await client.virtualMachine.createVolume.mutate({
|
|
@@ -14644,7 +15357,12 @@ function registerServersCommands(program2) {
|
|
|
14644
15357
|
if (!shouldSkipConfirmation()) {
|
|
14645
15358
|
const confirmed = await confirm(
|
|
14646
15359
|
`Delete volume "${volumeId}"? This is irreversible.`,
|
|
14647
|
-
false
|
|
15360
|
+
false,
|
|
15361
|
+
{
|
|
15362
|
+
field: "confirm_delete_volume",
|
|
15363
|
+
flag: "--yes",
|
|
15364
|
+
context: { volumeId }
|
|
15365
|
+
}
|
|
14648
15366
|
);
|
|
14649
15367
|
if (!confirmed) {
|
|
14650
15368
|
log("Cancelled.");
|
|
@@ -14779,7 +15497,11 @@ function registerServersCommands(program2) {
|
|
|
14779
15497
|
try {
|
|
14780
15498
|
if (!isLoggedIn()) throw new AuthError();
|
|
14781
15499
|
if (!shouldSkipConfirmation()) {
|
|
14782
|
-
const confirmed = await confirm(`Release IP "${ipId}"?`, false
|
|
15500
|
+
const confirmed = await confirm(`Release IP "${ipId}"?`, false, {
|
|
15501
|
+
field: "confirm_release_ip",
|
|
15502
|
+
flag: "--yes",
|
|
15503
|
+
context: { ipId }
|
|
15504
|
+
});
|
|
14783
15505
|
if (!confirmed) {
|
|
14784
15506
|
log("Cancelled.");
|
|
14785
15507
|
return;
|
|
@@ -14901,11 +15623,15 @@ function registerServersCommands(program2) {
|
|
|
14901
15623
|
}
|
|
14902
15624
|
let metric = options.metric;
|
|
14903
15625
|
if (!metric) {
|
|
14904
|
-
metric = await select(
|
|
14905
|
-
|
|
14906
|
-
|
|
14907
|
-
|
|
14908
|
-
|
|
15626
|
+
metric = await select(
|
|
15627
|
+
"Alert metric:",
|
|
15628
|
+
[
|
|
15629
|
+
{ name: "CPU Usage", value: "cpu" },
|
|
15630
|
+
{ name: "Memory Usage", value: "memory" },
|
|
15631
|
+
{ name: "Disk Usage", value: "disk" }
|
|
15632
|
+
],
|
|
15633
|
+
{ field: "alert_metric", flag: "--metric" }
|
|
15634
|
+
);
|
|
14909
15635
|
}
|
|
14910
15636
|
const _setSpinner = startSpinner("Saving alert...");
|
|
14911
15637
|
await client.virtualMachine.upsertAlertConfig.mutate({
|
|
@@ -14978,7 +15704,12 @@ ${colors.error("WARNING: This will permanently destroy the server and all data."
|
|
|
14978
15704
|
);
|
|
14979
15705
|
const confirmed = await confirm(
|
|
14980
15706
|
`Terminate server "${server.name || identifier}"?`,
|
|
14981
|
-
false
|
|
15707
|
+
false,
|
|
15708
|
+
{
|
|
15709
|
+
field: "confirm_terminate_server",
|
|
15710
|
+
flag: "--yes",
|
|
15711
|
+
context: { server: server.name || identifier }
|
|
15712
|
+
}
|
|
14982
15713
|
);
|
|
14983
15714
|
if (!confirmed) {
|
|
14984
15715
|
log("Cancelled.");
|
|
@@ -15072,7 +15803,12 @@ ${colors.error("WARNING: This will permanently destroy the server and all data."
|
|
|
15072
15803
|
if (!shouldSkipConfirmation()) {
|
|
15073
15804
|
const confirmed = await confirm(
|
|
15074
15805
|
`Cancel subscription for server "${server.name || identifier}"?`,
|
|
15075
|
-
false
|
|
15806
|
+
false,
|
|
15807
|
+
{
|
|
15808
|
+
field: "confirm_cancel_vm_subscription",
|
|
15809
|
+
flag: "--yes",
|
|
15810
|
+
context: { server: server.name || identifier }
|
|
15811
|
+
}
|
|
15076
15812
|
);
|
|
15077
15813
|
if (!confirmed) {
|
|
15078
15814
|
log("Cancelled.");
|
|
@@ -15308,12 +16044,23 @@ RunPod: ${available ? colors.success("available") : colors.error("unavailable")}
|
|
|
15308
16044
|
pool.command("provision").description("Provision a new dedicated Coolify server").option("--size <size>", "Server size key").option("--region <region>", "Region").action(async (options) => {
|
|
15309
16045
|
try {
|
|
15310
16046
|
if (!isLoggedIn()) throw new AuthError();
|
|
15311
|
-
const sizeKey = options.size || await input("Server size key:"
|
|
15312
|
-
|
|
16047
|
+
const sizeKey = options.size || await input("Server size key:", void 0, {
|
|
16048
|
+
field: "server_size",
|
|
16049
|
+
flag: "--size"
|
|
16050
|
+
});
|
|
16051
|
+
const region = options.region || await input("Region:", void 0, {
|
|
16052
|
+
field: "region",
|
|
16053
|
+
flag: "--region"
|
|
16054
|
+
});
|
|
15313
16055
|
if (!shouldSkipConfirmation()) {
|
|
15314
16056
|
const confirmed = await confirm(
|
|
15315
16057
|
`Provision a dedicated server (${sizeKey} in ${region})?`,
|
|
15316
|
-
false
|
|
16058
|
+
false,
|
|
16059
|
+
{
|
|
16060
|
+
field: "confirm_provision_dedicated",
|
|
16061
|
+
flag: "--yes",
|
|
16062
|
+
context: { sizeKey, region }
|
|
16063
|
+
}
|
|
15317
16064
|
);
|
|
15318
16065
|
if (!confirmed) {
|
|
15319
16066
|
log("Cancelled.");
|
|
@@ -15345,7 +16092,12 @@ RunPod: ${available ? colors.success("available") : colors.error("unavailable")}
|
|
|
15345
16092
|
if (!shouldSkipConfirmation()) {
|
|
15346
16093
|
const confirmed = await confirm(
|
|
15347
16094
|
`Decommission server "${id}"? Apps will be migrated first.`,
|
|
15348
|
-
false
|
|
16095
|
+
false,
|
|
16096
|
+
{
|
|
16097
|
+
field: "confirm_decommission_server",
|
|
16098
|
+
flag: "--yes",
|
|
16099
|
+
context: { id }
|
|
16100
|
+
}
|
|
15349
16101
|
);
|
|
15350
16102
|
if (!confirmed) {
|
|
15351
16103
|
log("Cancelled.");
|
|
@@ -15364,7 +16116,10 @@ RunPod: ${available ? colors.success("available") : colors.error("unavailable")}
|
|
|
15364
16116
|
pool.command("upgrade").argument("<id>", "Server ID").option("--size <size>", "New size key").description("Upgrade a dedicated server to a larger size").action(async (id, options) => {
|
|
15365
16117
|
try {
|
|
15366
16118
|
if (!isLoggedIn()) throw new AuthError();
|
|
15367
|
-
const sizeKey = options.size || await input("New size key:"
|
|
16119
|
+
const sizeKey = options.size || await input("New size key:", void 0, {
|
|
16120
|
+
field: "new_size",
|
|
16121
|
+
flag: "--size"
|
|
16122
|
+
});
|
|
15368
16123
|
const client = getApiClient();
|
|
15369
16124
|
const _spinner = startSpinner("Starting upgrade...");
|
|
15370
16125
|
const result = await client.server.upgradeServer.mutate({
|
|
@@ -15380,7 +16135,10 @@ RunPod: ${available ? colors.success("available") : colors.error("unavailable")}
|
|
|
15380
16135
|
pool.command("blue-green-upgrade").argument("<id>", "Server ID").option("--size <size>", "Target size key").description("Start a blue/green server upgrade (zero-downtime)").action(async (id, options) => {
|
|
15381
16136
|
try {
|
|
15382
16137
|
if (!isLoggedIn()) throw new AuthError();
|
|
15383
|
-
const sizeKey = options.size || await input("Target size:"
|
|
16138
|
+
const sizeKey = options.size || await input("Target size:", void 0, {
|
|
16139
|
+
field: "target_size",
|
|
16140
|
+
flag: "--size"
|
|
16141
|
+
});
|
|
15384
16142
|
const client = getApiClient();
|
|
15385
16143
|
const _spinner = startSpinner("Starting blue/green upgrade...");
|
|
15386
16144
|
const result = await client.server.upgradeBlueGreen.mutate({
|
|
@@ -15425,7 +16183,12 @@ RunPod: ${available ? colors.success("available") : colors.error("unavailable")}
|
|
|
15425
16183
|
if (!shouldSkipConfirmation()) {
|
|
15426
16184
|
const confirmed = await confirm(
|
|
15427
16185
|
`Complete cutover for server "${id}"?`,
|
|
15428
|
-
false
|
|
16186
|
+
false,
|
|
16187
|
+
{
|
|
16188
|
+
field: "confirm_complete_cutover",
|
|
16189
|
+
flag: "--yes",
|
|
16190
|
+
context: { id }
|
|
16191
|
+
}
|
|
15429
16192
|
);
|
|
15430
16193
|
if (!confirmed) {
|
|
15431
16194
|
log("Cancelled.");
|
|
@@ -15471,7 +16234,11 @@ RunPod: ${available ? colors.success("available") : colors.error("unavailable")}
|
|
|
15471
16234
|
if (!shouldSkipConfirmation()) {
|
|
15472
16235
|
const confirmed = await confirm(
|
|
15473
16236
|
"Migrate all shared apps to your dedicated server?",
|
|
15474
|
-
false
|
|
16237
|
+
false,
|
|
16238
|
+
{
|
|
16239
|
+
field: "confirm_migrate_to_dedicated",
|
|
16240
|
+
flag: "--yes"
|
|
16241
|
+
}
|
|
15475
16242
|
);
|
|
15476
16243
|
if (!confirmed) {
|
|
15477
16244
|
log("Cancelled.");
|
|
@@ -15514,7 +16281,10 @@ RunPod: ${available ? colors.success("available") : colors.error("unavailable")}
|
|
|
15514
16281
|
pool.command("request-enterprise").description("Request an enterprise server configuration").option("-m, --message <message>", "Additional requirements or message").action(async (options) => {
|
|
15515
16282
|
try {
|
|
15516
16283
|
if (!isLoggedIn()) throw new AuthError();
|
|
15517
|
-
const message = options.message || await input("Requirements / message (optional):"
|
|
16284
|
+
const message = options.message || await input("Requirements / message (optional):", void 0, {
|
|
16285
|
+
field: "enterprise_message",
|
|
16286
|
+
flag: "--message"
|
|
16287
|
+
});
|
|
15518
16288
|
const client = getApiClient();
|
|
15519
16289
|
const _spinner = startSpinner("Submitting enterprise request...");
|
|
15520
16290
|
await client.server.requestEnterprise.mutate({ message });
|
|
@@ -15702,7 +16472,10 @@ function registerSmsCommands(program2) {
|
|
|
15702
16472
|
sms.command("config").description("Show SMS configuration for an environment").option("-e, --env <environment-id>", "Environment ID").action(async (options) => {
|
|
15703
16473
|
try {
|
|
15704
16474
|
if (!isLoggedIn()) throw new AuthError();
|
|
15705
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
16475
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
16476
|
+
field: "environment_id",
|
|
16477
|
+
flag: "--env"
|
|
16478
|
+
});
|
|
15706
16479
|
const client = getApiClient();
|
|
15707
16480
|
const _spinner = startSpinner("Fetching SMS config...");
|
|
15708
16481
|
const data = await client.sms.getConfig.query({ environmentId });
|
|
@@ -15730,15 +16503,34 @@ function registerSmsCommands(program2) {
|
|
|
15730
16503
|
async (options) => {
|
|
15731
16504
|
try {
|
|
15732
16505
|
if (!isLoggedIn()) throw new AuthError();
|
|
15733
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
15734
|
-
|
|
15735
|
-
|
|
15736
|
-
|
|
15737
|
-
|
|
15738
|
-
|
|
15739
|
-
|
|
15740
|
-
|
|
15741
|
-
|
|
16506
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
16507
|
+
field: "environment_id",
|
|
16508
|
+
flag: "--env"
|
|
16509
|
+
});
|
|
16510
|
+
const provider = options.provider || await select(
|
|
16511
|
+
"SMS provider:",
|
|
16512
|
+
[
|
|
16513
|
+
{ name: "Twilio", value: "twilio" },
|
|
16514
|
+
{ name: "Vonage", value: "vonage" },
|
|
16515
|
+
{ name: "Sinch", value: "sinch" }
|
|
16516
|
+
],
|
|
16517
|
+
{ field: "sms_provider", flag: "--provider" }
|
|
16518
|
+
);
|
|
16519
|
+
const apiKey = options.apiKey || await input("API Key / Account SID:", void 0, {
|
|
16520
|
+
field: "api_key",
|
|
16521
|
+
flag: "--api-key",
|
|
16522
|
+
sensitive: true
|
|
16523
|
+
});
|
|
16524
|
+
const apiSecret = options.apiSecret || await input("API Secret / Auth Token:", void 0, {
|
|
16525
|
+
field: "api_secret",
|
|
16526
|
+
flag: "--api-secret",
|
|
16527
|
+
sensitive: true
|
|
16528
|
+
});
|
|
16529
|
+
const fromNumber = options.from || await input(
|
|
16530
|
+
"From phone number (e.g. +1234567890):",
|
|
16531
|
+
void 0,
|
|
16532
|
+
{ field: "from_number", flag: "--from" }
|
|
16533
|
+
);
|
|
15742
16534
|
const client = getApiClient();
|
|
15743
16535
|
const _spinner = startSpinner("Creating SMS config...");
|
|
15744
16536
|
const result = await client.sms.createConfig.mutate({
|
|
@@ -15762,7 +16554,10 @@ function registerSmsCommands(program2) {
|
|
|
15762
16554
|
async (options) => {
|
|
15763
16555
|
try {
|
|
15764
16556
|
if (!isLoggedIn()) throw new AuthError();
|
|
15765
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
16557
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
16558
|
+
field: "environment_id",
|
|
16559
|
+
flag: "--env"
|
|
16560
|
+
});
|
|
15766
16561
|
const isEnabled = options.enable ? true : options.disable ? false : void 0;
|
|
15767
16562
|
const client = getApiClient();
|
|
15768
16563
|
const _spinner = startSpinner("Updating SMS config...");
|
|
@@ -15786,9 +16581,18 @@ function registerSmsCommands(program2) {
|
|
|
15786
16581
|
async (options) => {
|
|
15787
16582
|
try {
|
|
15788
16583
|
if (!isLoggedIn()) throw new AuthError();
|
|
15789
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
15790
|
-
|
|
15791
|
-
|
|
16584
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
16585
|
+
field: "environment_id",
|
|
16586
|
+
flag: "--env"
|
|
16587
|
+
});
|
|
16588
|
+
const to = options.to || await input("Recipient phone number:", void 0, {
|
|
16589
|
+
field: "recipient_phone",
|
|
16590
|
+
flag: "--to"
|
|
16591
|
+
});
|
|
16592
|
+
const body = options.message || await input("Message:", void 0, {
|
|
16593
|
+
field: "message_body",
|
|
16594
|
+
flag: "--message"
|
|
16595
|
+
});
|
|
15792
16596
|
const client = getApiClient();
|
|
15793
16597
|
const _spinner = startSpinner("Sending SMS...");
|
|
15794
16598
|
const result = await client.sms.send.mutate({
|
|
@@ -15808,7 +16612,10 @@ function registerSmsCommands(program2) {
|
|
|
15808
16612
|
async (options) => {
|
|
15809
16613
|
try {
|
|
15810
16614
|
if (!isLoggedIn()) throw new AuthError();
|
|
15811
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
16615
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
16616
|
+
field: "environment_id",
|
|
16617
|
+
flag: "--env"
|
|
16618
|
+
});
|
|
15812
16619
|
const client = getApiClient();
|
|
15813
16620
|
const _spinner = startSpinner("Fetching logs...");
|
|
15814
16621
|
const logs = await client.sms.getLogs.query({
|
|
@@ -15846,7 +16653,10 @@ function registerSmsCommands(program2) {
|
|
|
15846
16653
|
sms.command("stats").description("Show SMS sending statistics").option("-e, --env <environment-id>", "Environment ID").option("--start <date>", "Start date (ISO format)").option("--end <date>", "End date (ISO format)").action(async (options) => {
|
|
15847
16654
|
try {
|
|
15848
16655
|
if (!isLoggedIn()) throw new AuthError();
|
|
15849
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
16656
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
16657
|
+
field: "environment_id",
|
|
16658
|
+
flag: "--env"
|
|
16659
|
+
});
|
|
15850
16660
|
const client = getApiClient();
|
|
15851
16661
|
const _spinner = startSpinner("Fetching stats...");
|
|
15852
16662
|
const stats = await client.sms.getStats.query({
|
|
@@ -15925,15 +16735,22 @@ function registerStorageCommands(program2) {
|
|
|
15925
16735
|
let bucketName = name;
|
|
15926
16736
|
let plan = (options.plan || "FREE").toUpperCase();
|
|
15927
16737
|
if (!bucketName) {
|
|
15928
|
-
bucketName = await input("Bucket name:"
|
|
16738
|
+
bucketName = await input("Bucket name:", void 0, {
|
|
16739
|
+
field: "name",
|
|
16740
|
+
flag: "--name"
|
|
16741
|
+
});
|
|
15929
16742
|
}
|
|
15930
16743
|
if (!options.plan && !shouldSkipConfirmation()) {
|
|
15931
|
-
plan = await select(
|
|
15932
|
-
|
|
15933
|
-
|
|
15934
|
-
|
|
15935
|
-
|
|
15936
|
-
|
|
16744
|
+
plan = await select(
|
|
16745
|
+
"Storage plan:",
|
|
16746
|
+
[
|
|
16747
|
+
{ name: "FREE (1 GB)", value: "FREE" },
|
|
16748
|
+
{ name: "STARTER (10 GB)", value: "STARTER" },
|
|
16749
|
+
{ name: "STANDARD (100 GB)", value: "STANDARD" },
|
|
16750
|
+
{ name: "PRO (1 TB)", value: "PRO" }
|
|
16751
|
+
],
|
|
16752
|
+
{ field: "plan", flag: "--plan" }
|
|
16753
|
+
);
|
|
15937
16754
|
}
|
|
15938
16755
|
const client = getApiClient();
|
|
15939
16756
|
const _spinner = startSpinner("Creating storage bucket...");
|
|
@@ -16000,7 +16817,12 @@ function registerStorageCommands(program2) {
|
|
|
16000
16817
|
log("");
|
|
16001
16818
|
const confirmed = await confirm(
|
|
16002
16819
|
`Are you sure you want to delete bucket "${bucket.name}"?`,
|
|
16003
|
-
false
|
|
16820
|
+
false,
|
|
16821
|
+
{
|
|
16822
|
+
field: "confirm_delete_bucket",
|
|
16823
|
+
flag: "--yes",
|
|
16824
|
+
context: { bucketName: bucket.name }
|
|
16825
|
+
}
|
|
16004
16826
|
);
|
|
16005
16827
|
if (!confirmed) {
|
|
16006
16828
|
log("Cancelled.");
|
|
@@ -16149,7 +16971,12 @@ function registerStorageCommands(program2) {
|
|
|
16149
16971
|
if (!shouldSkipConfirmation()) {
|
|
16150
16972
|
const confirmed = await confirm(
|
|
16151
16973
|
`Delete file "${fileName}" from bucket "${bucket.name}"?`,
|
|
16152
|
-
false
|
|
16974
|
+
false,
|
|
16975
|
+
{
|
|
16976
|
+
field: "confirm_delete_file",
|
|
16977
|
+
flag: "--yes",
|
|
16978
|
+
context: { fileName, bucketName: bucket.name }
|
|
16979
|
+
}
|
|
16153
16980
|
);
|
|
16154
16981
|
if (!confirmed) {
|
|
16155
16982
|
log("Cancelled.");
|
|
@@ -16245,7 +17072,10 @@ function registerStorageCommands(program2) {
|
|
|
16245
17072
|
throw new NotFoundError("Storage bucket", bucketIdentifier);
|
|
16246
17073
|
}
|
|
16247
17074
|
const bucketId = bucket.bucketId || bucket.id;
|
|
16248
|
-
const targetPlan = options.plan || await input("Target plan (standard/pro):"
|
|
17075
|
+
const targetPlan = options.plan || await input("Target plan (standard/pro):", void 0, {
|
|
17076
|
+
field: "plan",
|
|
17077
|
+
flag: "--plan"
|
|
17078
|
+
});
|
|
16249
17079
|
const _upgradeSpinner = startSpinner(
|
|
16250
17080
|
`Upgrading bucket to ${targetPlan}...`
|
|
16251
17081
|
);
|
|
@@ -16639,34 +17469,47 @@ ${colors.warn(`${unread.count} unread ticket${unread.count === 1 ? "" : "s"}`)}`
|
|
|
16639
17469
|
).option(
|
|
16640
17470
|
"-c, --category <category>",
|
|
16641
17471
|
"Category: billing, technical, account, feature_request"
|
|
16642
|
-
).action(async (options) => {
|
|
17472
|
+
).option("-d, --description <description>", "Ticket description").action(async (options) => {
|
|
16643
17473
|
try {
|
|
16644
17474
|
if (!isLoggedIn()) throw new AuthError();
|
|
16645
17475
|
let subject = options.subject;
|
|
16646
17476
|
let priority = options.priority;
|
|
16647
17477
|
let category = options.category;
|
|
16648
17478
|
if (!subject) {
|
|
16649
|
-
subject = await input("Subject:"
|
|
17479
|
+
subject = await input("Subject:", void 0, {
|
|
17480
|
+
field: "ticket_subject",
|
|
17481
|
+
flag: "--subject"
|
|
17482
|
+
});
|
|
16650
17483
|
}
|
|
16651
17484
|
if (!priority) {
|
|
16652
|
-
priority = await select(
|
|
16653
|
-
|
|
16654
|
-
|
|
16655
|
-
|
|
16656
|
-
|
|
16657
|
-
|
|
17485
|
+
priority = await select(
|
|
17486
|
+
"Priority:",
|
|
17487
|
+
[
|
|
17488
|
+
{ name: "Low", value: "low" },
|
|
17489
|
+
{ name: "Medium", value: "medium" },
|
|
17490
|
+
{ name: "High", value: "high" },
|
|
17491
|
+
{ name: "Critical - Production is down!", value: "critical" }
|
|
17492
|
+
],
|
|
17493
|
+
{ field: "ticket_priority", flag: "--priority" }
|
|
17494
|
+
);
|
|
16658
17495
|
}
|
|
16659
17496
|
if (!category) {
|
|
16660
|
-
category = await select(
|
|
16661
|
-
|
|
16662
|
-
|
|
16663
|
-
|
|
16664
|
-
|
|
16665
|
-
|
|
17497
|
+
category = await select(
|
|
17498
|
+
"Category:",
|
|
17499
|
+
[
|
|
17500
|
+
{ name: "Technical issue", value: "technical" },
|
|
17501
|
+
{ name: "Billing question", value: "billing" },
|
|
17502
|
+
{ name: "Account management", value: "account" },
|
|
17503
|
+
{ name: "Feature request", value: "feature_request" }
|
|
17504
|
+
],
|
|
17505
|
+
{ field: "ticket_category", flag: "--category" }
|
|
17506
|
+
);
|
|
16666
17507
|
}
|
|
16667
17508
|
log("");
|
|
16668
|
-
const description = await input(
|
|
16669
|
-
"Description (press Enter twice when done):"
|
|
17509
|
+
const description = options.description || await input(
|
|
17510
|
+
"Description (press Enter twice when done):",
|
|
17511
|
+
void 0,
|
|
17512
|
+
{ field: "ticket_description", flag: "--description" }
|
|
16670
17513
|
);
|
|
16671
17514
|
if (!shouldSkipConfirmation()) {
|
|
16672
17515
|
log("");
|
|
@@ -16674,7 +17517,11 @@ ${colors.warn(`${unread.count} unread ticket${unread.count === 1 ? "" : "s"}`)}`
|
|
|
16674
17517
|
log(`Priority: ${formatPriority(priority)}`);
|
|
16675
17518
|
log(`Category: ${category}`);
|
|
16676
17519
|
log("");
|
|
16677
|
-
const confirmed = await confirm("Submit this ticket?", true
|
|
17520
|
+
const confirmed = await confirm("Submit this ticket?", true, {
|
|
17521
|
+
field: "confirm_submit_ticket",
|
|
17522
|
+
flag: "--yes",
|
|
17523
|
+
context: { subject, priority, category }
|
|
17524
|
+
});
|
|
16678
17525
|
if (!confirmed) {
|
|
16679
17526
|
log("Cancelled.");
|
|
16680
17527
|
return;
|
|
@@ -16779,7 +17626,10 @@ ${colors.warn(`${unread.count} unread ticket${unread.count === 1 ? "" : "s"}`)}`
|
|
|
16779
17626
|
if (!isLoggedIn()) throw new AuthError();
|
|
16780
17627
|
let message = options.message;
|
|
16781
17628
|
if (!message) {
|
|
16782
|
-
message = await input("Your reply:"
|
|
17629
|
+
message = await input("Your reply:", void 0, {
|
|
17630
|
+
field: "reply_message",
|
|
17631
|
+
flag: "--message"
|
|
17632
|
+
});
|
|
16783
17633
|
}
|
|
16784
17634
|
const client = getApiClient();
|
|
16785
17635
|
let ticketId = ticketIdentifier;
|
|
@@ -16932,7 +17782,12 @@ ${colors.success("File attached to ticket.")}
|
|
|
16932
17782
|
if (!shouldSkipConfirmation()) {
|
|
16933
17783
|
const confirmed = await confirm(
|
|
16934
17784
|
`Close ticket "${ticketIdentifier}"?`,
|
|
16935
|
-
false
|
|
17785
|
+
false,
|
|
17786
|
+
{
|
|
17787
|
+
field: "confirm_close_ticket",
|
|
17788
|
+
flag: "--yes",
|
|
17789
|
+
context: { ticket: ticketIdentifier }
|
|
17790
|
+
}
|
|
16936
17791
|
);
|
|
16937
17792
|
if (!confirmed) {
|
|
16938
17793
|
log("Cancelled.");
|
|
@@ -17303,7 +18158,9 @@ function registerWalletCommands(program2) {
|
|
|
17303
18158
|
amountHalalas = Number.parseInt(options.amount);
|
|
17304
18159
|
} else {
|
|
17305
18160
|
const amountStr = await input(
|
|
17306
|
-
"Amount in SAR (e.g., 50 for 50 SAR, leave blank for default):"
|
|
18161
|
+
"Amount in SAR (e.g., 50 for 50 SAR, leave blank for default):",
|
|
18162
|
+
void 0,
|
|
18163
|
+
{ field: "wallet_topup_amount_sar", flag: "--amount" }
|
|
17307
18164
|
);
|
|
17308
18165
|
if (amountStr) {
|
|
17309
18166
|
amountHalalas = Math.round(Number.parseFloat(amountStr) * 100);
|
|
@@ -17394,7 +18251,10 @@ function registerWhatsappCommands(program2) {
|
|
|
17394
18251
|
wa.command("config").description("Show WhatsApp configuration for an environment").option("-e, --env <environment-id>", "Environment ID").action(async (options) => {
|
|
17395
18252
|
try {
|
|
17396
18253
|
if (!isLoggedIn()) throw new AuthError();
|
|
17397
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
18254
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
18255
|
+
field: "environment_id",
|
|
18256
|
+
flag: "--env"
|
|
18257
|
+
});
|
|
17398
18258
|
const client = getApiClient();
|
|
17399
18259
|
const _spinner = startSpinner("Fetching WhatsApp config...");
|
|
17400
18260
|
const data = await client.whatsapp.getConfig.query({ environmentId });
|
|
@@ -17421,13 +18281,28 @@ function registerWhatsappCommands(program2) {
|
|
|
17421
18281
|
async (options) => {
|
|
17422
18282
|
try {
|
|
17423
18283
|
if (!isLoggedIn()) throw new AuthError();
|
|
17424
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
17425
|
-
|
|
17426
|
-
|
|
17427
|
-
|
|
17428
|
-
|
|
17429
|
-
|
|
17430
|
-
|
|
18284
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
18285
|
+
field: "environment_id",
|
|
18286
|
+
flag: "--env"
|
|
18287
|
+
});
|
|
18288
|
+
const provider = options.provider || await select(
|
|
18289
|
+
"WhatsApp provider:",
|
|
18290
|
+
[
|
|
18291
|
+
{ name: "Meta (official)", value: "meta" },
|
|
18292
|
+
{ name: "Twilio", value: "twilio" }
|
|
18293
|
+
],
|
|
18294
|
+
{ field: "whatsapp_provider", flag: "--provider" }
|
|
18295
|
+
);
|
|
18296
|
+
const apiKey = options.apiKey || await input("API Key / Token:", void 0, {
|
|
18297
|
+
field: "api_key",
|
|
18298
|
+
flag: "--api-key",
|
|
18299
|
+
sensitive: true
|
|
18300
|
+
});
|
|
18301
|
+
const whatsappNumber = options.number || await input(
|
|
18302
|
+
"WhatsApp business number (e.g. +1234567890):",
|
|
18303
|
+
void 0,
|
|
18304
|
+
{ field: "whatsapp_number", flag: "--number" }
|
|
18305
|
+
);
|
|
17431
18306
|
const client = getApiClient();
|
|
17432
18307
|
const _spinner = startSpinner("Creating WhatsApp config...");
|
|
17433
18308
|
const result = await client.whatsapp.createConfig.mutate({
|
|
@@ -17450,7 +18325,10 @@ function registerWhatsappCommands(program2) {
|
|
|
17450
18325
|
async (options) => {
|
|
17451
18326
|
try {
|
|
17452
18327
|
if (!isLoggedIn()) throw new AuthError();
|
|
17453
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
18328
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
18329
|
+
field: "environment_id",
|
|
18330
|
+
flag: "--env"
|
|
18331
|
+
});
|
|
17454
18332
|
const isEnabled = options.enable ? true : options.disable ? false : void 0;
|
|
17455
18333
|
const client = getApiClient();
|
|
17456
18334
|
const _spinner = startSpinner("Updating WhatsApp config...");
|
|
@@ -17473,8 +18351,14 @@ function registerWhatsappCommands(program2) {
|
|
|
17473
18351
|
async (options) => {
|
|
17474
18352
|
try {
|
|
17475
18353
|
if (!isLoggedIn()) throw new AuthError();
|
|
17476
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
17477
|
-
|
|
18354
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
18355
|
+
field: "environment_id",
|
|
18356
|
+
flag: "--env"
|
|
18357
|
+
});
|
|
18358
|
+
const to = options.to || await input("Recipient phone number:", void 0, {
|
|
18359
|
+
field: "recipient_phone",
|
|
18360
|
+
flag: "--to"
|
|
18361
|
+
});
|
|
17478
18362
|
const client = getApiClient();
|
|
17479
18363
|
const _spinner = startSpinner("Sending WhatsApp message...");
|
|
17480
18364
|
const result = await client.whatsapp.send.mutate({
|
|
@@ -17496,7 +18380,10 @@ function registerWhatsappCommands(program2) {
|
|
|
17496
18380
|
async (options) => {
|
|
17497
18381
|
try {
|
|
17498
18382
|
if (!isLoggedIn()) throw new AuthError();
|
|
17499
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
18383
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
18384
|
+
field: "environment_id",
|
|
18385
|
+
flag: "--env"
|
|
18386
|
+
});
|
|
17500
18387
|
const client = getApiClient();
|
|
17501
18388
|
const _spinner = startSpinner("Fetching logs...");
|
|
17502
18389
|
const logs = await client.whatsapp.getLogs.query({
|
|
@@ -17535,7 +18422,10 @@ function registerWhatsappCommands(program2) {
|
|
|
17535
18422
|
wa.command("stats").description("Show WhatsApp messaging statistics").option("-e, --env <environment-id>", "Environment ID").option("--start <date>", "Start date (ISO)").option("--end <date>", "End date (ISO)").action(async (options) => {
|
|
17536
18423
|
try {
|
|
17537
18424
|
if (!isLoggedIn()) throw new AuthError();
|
|
17538
|
-
const environmentId = options.env || await input("Environment ID:"
|
|
18425
|
+
const environmentId = options.env || await input("Environment ID:", void 0, {
|
|
18426
|
+
field: "environment_id",
|
|
18427
|
+
flag: "--env"
|
|
18428
|
+
});
|
|
17539
18429
|
const client = getApiClient();
|
|
17540
18430
|
const _spinner = startSpinner("Fetching stats...");
|
|
17541
18431
|
const stats = await client.whatsapp.getStats.query({
|
|
@@ -17565,11 +18455,15 @@ function registerWhatsappCommands(program2) {
|
|
|
17565
18455
|
|
|
17566
18456
|
// src/index.ts
|
|
17567
18457
|
var program = new Command();
|
|
17568
|
-
program.name("tarout").description("Tarout PaaS Command Line Interface").version(package_default.version).option("--json", "Output as JSON (machine-readable)").option("-y, --yes", "Skip all confirmation prompts").option(
|
|
18458
|
+
program.name("tarout").description("Tarout PaaS Command Line Interface").version(package_default.version).option("--json", "Output as JSON (machine-readable)").option("-y, --yes", "Skip all confirmation prompts").option(
|
|
18459
|
+
"--non-interactive",
|
|
18460
|
+
"Fail fast on missing input (emit needs_input + exit 6 instead of prompting on TTY)"
|
|
18461
|
+
).option("-q, --quiet", "Minimal output").option("-v, --verbose", "Extra debug information").option("--no-color", "Disable colored output").hook("preAction", (thisCommand) => {
|
|
17569
18462
|
const opts = thisCommand.opts();
|
|
17570
18463
|
setGlobalOptions({
|
|
17571
18464
|
json: opts.json || false,
|
|
17572
18465
|
yes: opts.yes || false,
|
|
18466
|
+
nonInteractive: opts.nonInteractive || false,
|
|
17573
18467
|
quiet: opts.quiet || false,
|
|
17574
18468
|
verbose: opts.verbose || false,
|
|
17575
18469
|
noColor: opts.color === false
|
|
@@ -17610,4 +18504,27 @@ registerSmsCommands(program);
|
|
|
17610
18504
|
registerWhatsappCommands(program);
|
|
17611
18505
|
registerFirewallCommands(program);
|
|
17612
18506
|
registerQueuesCommands(program);
|
|
18507
|
+
var argErrorPatterns = [
|
|
18508
|
+
/invalid/i,
|
|
18509
|
+
/missing required/i,
|
|
18510
|
+
/unknown option/i,
|
|
18511
|
+
/unknown command/i
|
|
18512
|
+
];
|
|
18513
|
+
var originalWriteErr = process.stderr.write.bind(process.stderr);
|
|
18514
|
+
program.configureOutput({
|
|
18515
|
+
writeErr: (str) => {
|
|
18516
|
+
if (process.argv.includes("--json")) {
|
|
18517
|
+
setGlobalOptions({ json: true });
|
|
18518
|
+
const isArgError = argErrorPatterns.some((p) => p.test(str));
|
|
18519
|
+
outputError(
|
|
18520
|
+
isArgError ? "INVALID_ARGUMENTS" : "CLI_ERROR",
|
|
18521
|
+
str.replace(/^error:\s*/i, "").trim()
|
|
18522
|
+
);
|
|
18523
|
+
process.exit(
|
|
18524
|
+
isArgError ? ExitCode.INVALID_ARGUMENTS : ExitCode.GENERAL_ERROR
|
|
18525
|
+
);
|
|
18526
|
+
}
|
|
18527
|
+
return originalWriteErr(str);
|
|
18528
|
+
}
|
|
18529
|
+
});
|
|
17613
18530
|
program.parse();
|