@wraps.dev/cli 2.29.0 → 2.30.0
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-lambda.zip +0 -0
- package/dist/cli.js +1552 -742
- package/dist/cli.js.map +1 -1
- package/dist/lambda/agent-enforcer/.bundled +1 -1
- package/dist/lambda/event-processor/.bundled +1 -1
- package/dist/lambda/inbound-processor/.bundled +1 -1
- package/dist/lambda/sms-event-processor/.bundled +1 -1
- package/package.json +4 -3
package/dist/cli.js
CHANGED
|
@@ -1253,6 +1253,50 @@ If you believe this is a Wraps bug, report it at:
|
|
|
1253
1253
|
"Your IAM user/role needs SQS permissions.\nRequired actions: CreateQueue, DeleteQueue, GetQueueAttributes\n\nView required permissions:\n wraps permissions --json",
|
|
1254
1254
|
"https://wraps.dev/docs/guides/aws-setup/permissions"
|
|
1255
1255
|
),
|
|
1256
|
+
cloudWatchLogsPermissionDenied: (action) => new WrapsError(
|
|
1257
|
+
"CloudWatch Logs permission denied",
|
|
1258
|
+
"CLOUDWATCH_LOGS_PERMISSION_DENIED",
|
|
1259
|
+
`Your IAM user/role is not allowed to call ${action}.
|
|
1260
|
+
Required actions: logs:DescribeLogGroups, logs:FilterLogEvents, logs:StartLiveTail
|
|
1261
|
+
|
|
1262
|
+
View required permissions:
|
|
1263
|
+
wraps permissions --json`,
|
|
1264
|
+
"https://wraps.dev/docs/guides/aws-setup/permissions"
|
|
1265
|
+
),
|
|
1266
|
+
// Discovery scans for /aws/lambda/wraps-selfhost*, which both the Pulumi and
|
|
1267
|
+
// SST variants create — no groups means no deployment in this region, not an
|
|
1268
|
+
// unsupported variant.
|
|
1269
|
+
noSelfhostLogGroups: (region) => new WrapsError(
|
|
1270
|
+
`No self-hosted log groups found in ${region}`,
|
|
1271
|
+
"SELFHOST_NO_LOG_GROUPS",
|
|
1272
|
+
"Nothing matching /aws/lambda/wraps-selfhost* exists in this region. The deployment may live in another region, or may not have run yet.\n\nCheck the deployment:\n wraps selfhost status\n\nOr target a different region:\n wraps selfhost logs --region <region>",
|
|
1273
|
+
"https://wraps.dev/docs/self-hosting"
|
|
1274
|
+
),
|
|
1275
|
+
invalidLogSource: (value) => new WrapsError(
|
|
1276
|
+
`Unknown --source value: ${value}`,
|
|
1277
|
+
"INVALID_LOG_SOURCE",
|
|
1278
|
+
"Valid sources are: api, web, workers, other, all.\n\nExample:\n wraps selfhost logs --source api",
|
|
1279
|
+
"https://wraps.dev/docs/self-hosting"
|
|
1280
|
+
),
|
|
1281
|
+
// The Pulumi variant deploys the API Lambda only, so `--source web` is a
|
|
1282
|
+
// legitimate request with no matching groups rather than a typo.
|
|
1283
|
+
noLogGroupsForSource: (source, available) => new WrapsError(
|
|
1284
|
+
`No ${source} log groups in this deployment`,
|
|
1285
|
+
"SELFHOST_NO_LOG_GROUPS_FOR_SOURCE",
|
|
1286
|
+
`This deployment has: ${available}.
|
|
1287
|
+
|
|
1288
|
+
The API-only control plane (wraps selfhost deploy) has no dashboard or worker Lambdas \u2014 those ship with the full SST platform.
|
|
1289
|
+
|
|
1290
|
+
Drop the filter to see everything:
|
|
1291
|
+
wraps selfhost logs`,
|
|
1292
|
+
"https://wraps.dev/docs/self-hosting"
|
|
1293
|
+
),
|
|
1294
|
+
invalidLogWindow: (value) => new WrapsError(
|
|
1295
|
+
`Invalid --since value: ${value}`,
|
|
1296
|
+
"INVALID_LOG_WINDOW",
|
|
1297
|
+
"Use a positive number followed by s, m, h, or d.\n\nExamples:\n wraps selfhost logs --since 30m\n wraps selfhost logs --since 6h\n wraps selfhost logs --since 2d",
|
|
1298
|
+
"https://wraps.dev/docs/self-hosting"
|
|
1299
|
+
),
|
|
1256
1300
|
route53PermissionDenied: () => new WrapsError(
|
|
1257
1301
|
"Route53 permission denied",
|
|
1258
1302
|
"ROUTE53_PERMISSION_DENIED",
|
|
@@ -1974,8 +2018,8 @@ async function ensurePulumiWorkDir(options) {
|
|
|
1974
2018
|
);
|
|
1975
2019
|
return;
|
|
1976
2020
|
} catch (error) {
|
|
1977
|
-
const
|
|
1978
|
-
|
|
2021
|
+
const clack69 = await import("@clack/prompts");
|
|
2022
|
+
clack69.log.warn(
|
|
1979
2023
|
`S3 state backend unavailable (${error instanceof Error ? error.message : error}). Using local state.`
|
|
1980
2024
|
);
|
|
1981
2025
|
}
|
|
@@ -2424,7 +2468,7 @@ var init_client = __esm({
|
|
|
2424
2468
|
console.log("\u{1F4CA} Wraps Platform \u2014 analytics, templates, automations");
|
|
2425
2469
|
console.log(` From $10/mo \u2192 ${pc2.cyan("https://wraps.dev/platform")}`);
|
|
2426
2470
|
console.log();
|
|
2427
|
-
console.log(`\u{1F4AC} ${pc2.cyan("hey@wraps.
|
|
2471
|
+
console.log(`\u{1F4AC} ${pc2.cyan("hey@wraps.dev")}`);
|
|
2428
2472
|
console.log(pc2.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
2429
2473
|
return true;
|
|
2430
2474
|
}
|
|
@@ -6480,7 +6524,10 @@ function displaySuccess(outputs) {
|
|
|
6480
6524
|
""
|
|
6481
6525
|
);
|
|
6482
6526
|
}
|
|
6483
|
-
lines.push(
|
|
6527
|
+
lines.push(
|
|
6528
|
+
` 2. View dashboard: ${pc10.blue(outputs.dashboardUrl ?? getAppBaseUrl())}`,
|
|
6529
|
+
""
|
|
6530
|
+
);
|
|
6484
6531
|
clack8.outro(pc10.green("Email infrastructure deployed successfully!"));
|
|
6485
6532
|
console.log(lines.join("\n"));
|
|
6486
6533
|
if (outputs.dnsAutoCreated && outputs.domain) {
|
|
@@ -6774,8 +6821,10 @@ ${pc10.dim("Run:")} ${pc10.yellow(`wraps email verify --domain ${exampleDomain}`
|
|
|
6774
6821
|
`
|
|
6775
6822
|
);
|
|
6776
6823
|
}
|
|
6777
|
-
console.log(
|
|
6778
|
-
|
|
6824
|
+
console.log(
|
|
6825
|
+
`
|
|
6826
|
+
${pc10.bold("Dashboard:")} ${pc10.blue(status2.dashboardUrl ?? getAppBaseUrl())}`
|
|
6827
|
+
);
|
|
6779
6828
|
console.log(`${pc10.bold("Docs:")} ${pc10.blue("https://wraps.dev/docs")}
|
|
6780
6829
|
`);
|
|
6781
6830
|
}
|
|
@@ -6920,6 +6969,7 @@ var init_output = __esm({
|
|
|
6920
6969
|
"src/utils/shared/output.ts"() {
|
|
6921
6970
|
"use strict";
|
|
6922
6971
|
init_esm_shims();
|
|
6972
|
+
init_config();
|
|
6923
6973
|
init_json_output();
|
|
6924
6974
|
DeploymentProgress = class {
|
|
6925
6975
|
currentSpinner = null;
|
|
@@ -7154,23 +7204,23 @@ async function withLockRetry(fn, options) {
|
|
|
7154
7204
|
if (parsed.code !== "STACK_LOCKED") {
|
|
7155
7205
|
throw error;
|
|
7156
7206
|
}
|
|
7157
|
-
const
|
|
7158
|
-
const
|
|
7207
|
+
const clack69 = await import("@clack/prompts");
|
|
7208
|
+
const pc73 = (await import("picocolors")).default;
|
|
7159
7209
|
if (options.autoConfirm) {
|
|
7160
|
-
|
|
7210
|
+
clack69.log.warn(
|
|
7161
7211
|
"Stack is locked from a previous interrupted run. Auto-clearing..."
|
|
7162
7212
|
);
|
|
7163
7213
|
} else {
|
|
7164
|
-
const shouldClear = await
|
|
7165
|
-
message: `Stack is locked from a previous interrupted run. ${
|
|
7214
|
+
const shouldClear = await clack69.confirm({
|
|
7215
|
+
message: `Stack is locked from a previous interrupted run. ${pc73.yellow("Clear the stale lock and retry?")}`,
|
|
7166
7216
|
initialValue: true
|
|
7167
7217
|
});
|
|
7168
|
-
if (
|
|
7218
|
+
if (clack69.isCancel(shouldClear) || !shouldClear) {
|
|
7169
7219
|
throw errors.stackLocked();
|
|
7170
7220
|
}
|
|
7171
7221
|
}
|
|
7172
7222
|
const cleared = await clearStackLocks(options.accountId, options.region);
|
|
7173
|
-
|
|
7223
|
+
clack69.log.info(
|
|
7174
7224
|
`Cleared ${cleared} lock file${cleared === 1 ? "" : "s"}. Retrying...`
|
|
7175
7225
|
);
|
|
7176
7226
|
return fn();
|
|
@@ -31342,8 +31392,8 @@ import { homedir as homedir6, tmpdir as tmpdir2 } from "os";
|
|
|
31342
31392
|
import { join as join26 } from "path";
|
|
31343
31393
|
import { Readable as Readable5 } from "stream";
|
|
31344
31394
|
import { pipeline } from "stream/promises";
|
|
31345
|
-
import { cancel as cancel38, confirm as confirm32, intro as
|
|
31346
|
-
import
|
|
31395
|
+
import { cancel as cancel38, confirm as confirm32, intro as intro63, isCancel as isCancel43, log as log62 } from "@clack/prompts";
|
|
31396
|
+
import pc71 from "picocolors";
|
|
31347
31397
|
function isStandaloneInstall() {
|
|
31348
31398
|
return process.execPath.includes(".wraps/runtime");
|
|
31349
31399
|
}
|
|
@@ -31372,7 +31422,7 @@ function detectPlatformArch() {
|
|
|
31372
31422
|
return { platform: platform3, arch };
|
|
31373
31423
|
}
|
|
31374
31424
|
async function update(currentVersion) {
|
|
31375
|
-
|
|
31425
|
+
intro63(pc71.bold("Wraps CLI Update"));
|
|
31376
31426
|
const progress = new DeploymentProgress();
|
|
31377
31427
|
const result = await progress.execute(
|
|
31378
31428
|
"Checking for updates...",
|
|
@@ -31384,20 +31434,20 @@ async function update(currentVersion) {
|
|
|
31384
31434
|
}
|
|
31385
31435
|
const { version: latestVersion, release: release2 } = result;
|
|
31386
31436
|
if (currentVersion === latestVersion) {
|
|
31387
|
-
progress.succeed(`Already up to date ${
|
|
31437
|
+
progress.succeed(`Already up to date ${pc71.dim(`(v${currentVersion})`)}`);
|
|
31388
31438
|
return;
|
|
31389
31439
|
}
|
|
31390
31440
|
console.log();
|
|
31391
|
-
|
|
31392
|
-
`Current version: ${
|
|
31393
|
-
Latest version: ${
|
|
31441
|
+
log62.info(
|
|
31442
|
+
`Current version: ${pc71.dim(`v${currentVersion}`)}
|
|
31443
|
+
Latest version: ${pc71.cyan(`v${latestVersion}`)}`
|
|
31394
31444
|
);
|
|
31395
31445
|
console.log();
|
|
31396
31446
|
if (!isStandaloneInstall()) {
|
|
31397
|
-
|
|
31447
|
+
log62.info(
|
|
31398
31448
|
`You installed Wraps via npm. Update with:
|
|
31399
31449
|
|
|
31400
|
-
${
|
|
31450
|
+
${pc71.cyan("npm update -g @wraps.dev/cli")}`
|
|
31401
31451
|
);
|
|
31402
31452
|
return;
|
|
31403
31453
|
}
|
|
@@ -31472,7 +31522,7 @@ async function update(currentVersion) {
|
|
|
31472
31522
|
});
|
|
31473
31523
|
console.log();
|
|
31474
31524
|
progress.succeed(
|
|
31475
|
-
`Updated to ${
|
|
31525
|
+
`Updated to ${pc71.cyan(`v${latestVersion}`)} successfully!`
|
|
31476
31526
|
);
|
|
31477
31527
|
} finally {
|
|
31478
31528
|
rmSync(tmp, { recursive: true, force: true });
|
|
@@ -31495,8 +31545,8 @@ init_esm_shims();
|
|
|
31495
31545
|
import { readFileSync as readFileSync4 } from "fs";
|
|
31496
31546
|
import { dirname as dirname8, join as join27 } from "path";
|
|
31497
31547
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
31498
|
-
import * as
|
|
31499
|
-
import
|
|
31548
|
+
import * as clack68 from "@clack/prompts";
|
|
31549
|
+
import pc72 from "picocolors";
|
|
31500
31550
|
|
|
31501
31551
|
// src/commands/auth/login.ts
|
|
31502
31552
|
init_esm_shims();
|
|
@@ -40669,6 +40719,21 @@ import * as clack17 from "@clack/prompts";
|
|
|
40669
40719
|
import * as pulumi16 from "@pulumi/pulumi";
|
|
40670
40720
|
import pc19 from "picocolors";
|
|
40671
40721
|
init_events();
|
|
40722
|
+
|
|
40723
|
+
// src/utils/selfhost/dashboard-url.ts
|
|
40724
|
+
init_esm_shims();
|
|
40725
|
+
init_config();
|
|
40726
|
+
init_metadata();
|
|
40727
|
+
async function resolveDashboardUrl(accountId, region) {
|
|
40728
|
+
try {
|
|
40729
|
+
const metadata = await loadConnectionMetadata(accountId, region);
|
|
40730
|
+
return metadata?.services?.selfhost?.config?.appUrl || getAppBaseUrl();
|
|
40731
|
+
} catch {
|
|
40732
|
+
return getAppBaseUrl();
|
|
40733
|
+
}
|
|
40734
|
+
}
|
|
40735
|
+
|
|
40736
|
+
// src/commands/email/config.ts
|
|
40672
40737
|
init_aws();
|
|
40673
40738
|
init_errors();
|
|
40674
40739
|
init_fs();
|
|
@@ -40922,6 +40987,10 @@ ${pc19.bold("Current Configuration:")}
|
|
|
40922
40987
|
return;
|
|
40923
40988
|
}
|
|
40924
40989
|
displaySuccess({
|
|
40990
|
+
dashboardUrl: await resolveDashboardUrl(
|
|
40991
|
+
identity.accountId,
|
|
40992
|
+
outputs.region
|
|
40993
|
+
),
|
|
40925
40994
|
roleArn: outputs.roleArn,
|
|
40926
40995
|
configSetName: outputs.configSetName,
|
|
40927
40996
|
region: outputs.region,
|
|
@@ -41314,6 +41383,10 @@ ${pc20.dim("\u2500\u2500\u2500 end Pulumi output \u2500\u2500\u2500")}
|
|
|
41314
41383
|
return;
|
|
41315
41384
|
}
|
|
41316
41385
|
displaySuccess({
|
|
41386
|
+
dashboardUrl: await resolveDashboardUrl(
|
|
41387
|
+
identity.accountId,
|
|
41388
|
+
outputs.region
|
|
41389
|
+
),
|
|
41317
41390
|
roleArn: outputs.roleArn,
|
|
41318
41391
|
configSetName: outputs.configSetName,
|
|
41319
41392
|
region: outputs.region,
|
|
@@ -46566,6 +46639,10 @@ ${pc30.yellow(pc30.bold("Configuration Warnings:"))}`);
|
|
|
46566
46639
|
);
|
|
46567
46640
|
}
|
|
46568
46641
|
displaySuccess({
|
|
46642
|
+
dashboardUrl: await resolveDashboardUrl(
|
|
46643
|
+
identity.accountId,
|
|
46644
|
+
outputs.region
|
|
46645
|
+
),
|
|
46569
46646
|
roleArn: outputs.roleArn,
|
|
46570
46647
|
configSetName: outputs.configSetName,
|
|
46571
46648
|
region: outputs.region,
|
|
@@ -46736,12 +46813,12 @@ async function emailLogsList(options) {
|
|
|
46736
46813
|
}
|
|
46737
46814
|
const COL = { time: 8, status: 11, to: 28, subject: 40, msgId: 18 };
|
|
46738
46815
|
const header = pc31.bold("Time".padEnd(COL.time)) + " " + pc31.bold("Status".padEnd(COL.status)) + " " + pc31.bold("To".padEnd(COL.to)) + " " + pc31.bold("Subject".padEnd(COL.subject)) + " " + pc31.bold("Message ID");
|
|
46739
|
-
const rows = data.logs.map((
|
|
46740
|
-
const time2 = relativeTime(
|
|
46741
|
-
const status2 = padVisible(colorStatus(
|
|
46742
|
-
const to = padVisible(truncate(
|
|
46743
|
-
const subject = padVisible(truncate(
|
|
46744
|
-
const msgId = truncate(
|
|
46816
|
+
const rows = data.logs.map((log64) => {
|
|
46817
|
+
const time2 = relativeTime(log64.createdAt).padEnd(COL.time);
|
|
46818
|
+
const status2 = padVisible(colorStatus(log64.status), COL.status);
|
|
46819
|
+
const to = padVisible(truncate(log64.recipient, COL.to), COL.to);
|
|
46820
|
+
const subject = padVisible(truncate(log64.subject, COL.subject), COL.subject);
|
|
46821
|
+
const msgId = truncate(log64.messageId, COL.msgId);
|
|
46745
46822
|
return `${time2} ${status2} ${to} ${subject} ${msgId}`;
|
|
46746
46823
|
});
|
|
46747
46824
|
clack29.note(
|
|
@@ -46797,32 +46874,32 @@ async function emailLogsGet(options) {
|
|
|
46797
46874
|
}
|
|
46798
46875
|
return;
|
|
46799
46876
|
}
|
|
46800
|
-
const
|
|
46877
|
+
const log64 = await resp.json();
|
|
46801
46878
|
if (isJsonMode()) {
|
|
46802
|
-
jsonSuccess("email.logs.get",
|
|
46879
|
+
jsonSuccess("email.logs.get", log64);
|
|
46803
46880
|
return;
|
|
46804
46881
|
}
|
|
46805
46882
|
const kv = (label, value) => `${pc31.dim(label.padEnd(16))} ${value ?? pc31.dim("\u2014")}`;
|
|
46806
|
-
const sentAt =
|
|
46807
|
-
const deliveredAt =
|
|
46808
|
-
const bouncedAt =
|
|
46809
|
-
const createdAt = new Date(
|
|
46883
|
+
const sentAt = log64.sentAt ? new Date(log64.sentAt).toLocaleString() : null;
|
|
46884
|
+
const deliveredAt = log64.deliveredAt ? new Date(log64.deliveredAt).toLocaleString() : null;
|
|
46885
|
+
const bouncedAt = log64.bouncedAt ? new Date(log64.bouncedAt).toLocaleString() : null;
|
|
46886
|
+
const createdAt = new Date(log64.createdAt).toLocaleString();
|
|
46810
46887
|
const lines = [
|
|
46811
|
-
kv("Message ID:",
|
|
46812
|
-
kv("Status:",
|
|
46813
|
-
kv("To:",
|
|
46814
|
-
kv("From:",
|
|
46815
|
-
kv("Subject:",
|
|
46816
|
-
kv("Source:",
|
|
46888
|
+
kv("Message ID:", log64.messageId),
|
|
46889
|
+
kv("Status:", log64.status ? colorStatus(log64.status) : null),
|
|
46890
|
+
kv("To:", log64.recipient),
|
|
46891
|
+
kv("From:", log64.from),
|
|
46892
|
+
kv("Subject:", log64.subject),
|
|
46893
|
+
kv("Source:", log64.sourceType),
|
|
46817
46894
|
kv("Sent:", sentAt),
|
|
46818
46895
|
kv("Delivered:", deliveredAt),
|
|
46819
46896
|
kv("Bounced:", bouncedAt),
|
|
46820
|
-
...
|
|
46897
|
+
...log64.bouncedSubType ? [kv("Bounce type:", log64.bouncedSubType)] : [],
|
|
46821
46898
|
kv("Created:", createdAt)
|
|
46822
46899
|
];
|
|
46823
46900
|
clack29.note(
|
|
46824
46901
|
lines.join("\n"),
|
|
46825
|
-
`Log Detail \u2014 ${
|
|
46902
|
+
`Log Detail \u2014 ${log64.messageId ?? "(no message id)"}`
|
|
46826
46903
|
);
|
|
46827
46904
|
}
|
|
46828
46905
|
|
|
@@ -48264,6 +48341,9 @@ ${pc34.green("\u2713")} ${pc34.bold("Infrastructure removed successfully!")}
|
|
|
48264
48341
|
init_esm_shims();
|
|
48265
48342
|
init_client();
|
|
48266
48343
|
init_events();
|
|
48344
|
+
import * as clack34 from "@clack/prompts";
|
|
48345
|
+
import * as pulumi24 from "@pulumi/pulumi";
|
|
48346
|
+
import pc35 from "picocolors";
|
|
48267
48347
|
init_aws();
|
|
48268
48348
|
init_errors();
|
|
48269
48349
|
init_fs();
|
|
@@ -48271,9 +48351,6 @@ init_json_output();
|
|
|
48271
48351
|
init_metadata();
|
|
48272
48352
|
init_output();
|
|
48273
48353
|
init_pulumi();
|
|
48274
|
-
import * as clack34 from "@clack/prompts";
|
|
48275
|
-
import * as pulumi24 from "@pulumi/pulumi";
|
|
48276
|
-
import pc35 from "picocolors";
|
|
48277
48354
|
async function emailStatus(options) {
|
|
48278
48355
|
await ensurePulumiInstalled();
|
|
48279
48356
|
const startTime = Date.now();
|
|
@@ -48374,6 +48451,7 @@ Run ${pc35.cyan("wraps email init")} to deploy email infrastructure.
|
|
|
48374
48451
|
const statusData = {
|
|
48375
48452
|
integrationLevel,
|
|
48376
48453
|
region,
|
|
48454
|
+
dashboardUrl: await resolveDashboardUrl(identity.accountId, region),
|
|
48377
48455
|
domains: domainsWithTokens,
|
|
48378
48456
|
resources: {
|
|
48379
48457
|
roleArn: stackOutputs.roleArn?.value,
|
|
@@ -52271,6 +52349,10 @@ ${pc39.bold("Cost Impact:")}`);
|
|
|
52271
52349
|
}
|
|
52272
52350
|
const needsCertificateValidation = outputs.httpsTrackingPending || outputs.httpsTrackingEnabled && acmValidationRecords.length > 0 && !outputs.cloudFrontDomain;
|
|
52273
52351
|
displaySuccess({
|
|
52352
|
+
dashboardUrl: await resolveDashboardUrl(
|
|
52353
|
+
identity.accountId,
|
|
52354
|
+
outputs.region
|
|
52355
|
+
),
|
|
52274
52356
|
roleArn: outputs.roleArn,
|
|
52275
52357
|
configSetName: outputs.configSetName,
|
|
52276
52358
|
region: outputs.region,
|
|
@@ -57157,14 +57239,26 @@ To replace it with the API-only control plane: run ${pc49.cyan("pnpm selfhost:de
|
|
|
57157
57239
|
if (!appUrl) {
|
|
57158
57240
|
const appUrlAnswer = await clack46.text({
|
|
57159
57241
|
message: "App URL (where your self-hosted dashboard will be served):",
|
|
57160
|
-
|
|
57161
|
-
|
|
57242
|
+
placeholder: "https://app.yourcompany.com",
|
|
57243
|
+
validate: (value) => {
|
|
57244
|
+
if (!value?.trim()) {
|
|
57245
|
+
return "Required \u2014 this URL is baked into every link your deployment emails to recipients.";
|
|
57246
|
+
}
|
|
57247
|
+
const trimmed = value.trim();
|
|
57248
|
+
if (!URL.canParse(trimmed)) {
|
|
57249
|
+
return "Must be a valid URL, for example https://app.yourcompany.com";
|
|
57250
|
+
}
|
|
57251
|
+
const { protocol } = new URL(trimmed);
|
|
57252
|
+
if (protocol !== "https:" && protocol !== "http:") {
|
|
57253
|
+
return "Must be an http(s) URL";
|
|
57254
|
+
}
|
|
57255
|
+
}
|
|
57162
57256
|
});
|
|
57163
57257
|
if (clack46.isCancel(appUrlAnswer)) {
|
|
57164
57258
|
clack46.cancel("Operation cancelled.");
|
|
57165
57259
|
process.exit(0);
|
|
57166
57260
|
}
|
|
57167
|
-
appUrl = appUrlAnswer
|
|
57261
|
+
appUrl = appUrlAnswer.trim();
|
|
57168
57262
|
}
|
|
57169
57263
|
if (!(options.yes || options.preview)) {
|
|
57170
57264
|
const confirmed = await clack46.confirm({
|
|
@@ -57897,11 +57991,696 @@ Run ${pc53.cyan("wraps selfhost deploy")} to deploy the self-hosted control plan
|
|
|
57897
57991
|
clack50.log.success(`Signed out of ${pc53.cyan(baseURL)}.`);
|
|
57898
57992
|
}
|
|
57899
57993
|
|
|
57900
|
-
// src/commands/selfhost/
|
|
57994
|
+
// src/commands/selfhost/logs.ts
|
|
57901
57995
|
init_esm_shims();
|
|
57902
|
-
init_events();
|
|
57903
57996
|
import * as clack51 from "@clack/prompts";
|
|
57904
57997
|
import pc54 from "picocolors";
|
|
57998
|
+
|
|
57999
|
+
// src/utils/selfhost/logs.ts
|
|
58000
|
+
init_esm_shims();
|
|
58001
|
+
init_errors();
|
|
58002
|
+
var SELFHOST_LOG_GROUP_PREFIX = "/aws/lambda/wraps-selfhost";
|
|
58003
|
+
var LIVE_TAIL_MAX_GROUPS = 10;
|
|
58004
|
+
var POLL_OVERLAP_MS = 15e3;
|
|
58005
|
+
var MAX_SEEN_KEYS = 5e3;
|
|
58006
|
+
var ERROR_FILTER_PATTERN = '?ERROR ?Error ?error ?FATAL ?fatal ?Exception ?exception ?Traceback ?"Task timed out" ?"UnhandledPromiseRejection" ?"Runtime."';
|
|
58007
|
+
var ERROR_LEVELS = /* @__PURE__ */ new Set(["error", "fatal", "critical"]);
|
|
58008
|
+
var PLATFORM_LINE = /^(START|END|REPORT|INIT_START|INIT_REPORT|XRAY) /;
|
|
58009
|
+
var ERROR_TEXT = /(^|\s)(ERROR|FATAL|CRITICAL)(\s|:|$)|Task timed out|UnhandledPromiseRejection|Unhandled Rejection|Runtime\.\w*Error|Traceback \(most recent call last\)/;
|
|
58010
|
+
var LEVEL_TEXT = /(^|\s)(ERROR|WARN|WARNING|INFO|DEBUG|TRACE|FATAL)(\s|:|$)/;
|
|
58011
|
+
var SINCE_DURATION = /^(\d+)(s|m|h|d)$/i;
|
|
58012
|
+
var ARN_WILDCARD_SUFFIX = /:?\*$/;
|
|
58013
|
+
var SOURCE_LABELS = {
|
|
58014
|
+
api: "api",
|
|
58015
|
+
web: "web",
|
|
58016
|
+
workers: "workers",
|
|
58017
|
+
other: "other"
|
|
58018
|
+
};
|
|
58019
|
+
var SELFHOST_LOG_SOURCES = Object.keys(
|
|
58020
|
+
SOURCE_LABELS
|
|
58021
|
+
);
|
|
58022
|
+
function classifyLogGroup(logGroupName) {
|
|
58023
|
+
const name = logGroupName.toLowerCase();
|
|
58024
|
+
if (name.endsWith("wraps-selfhost-api") || name.includes("selfhostapi")) {
|
|
58025
|
+
return "api";
|
|
58026
|
+
}
|
|
58027
|
+
if (name.includes("selfhostweb")) {
|
|
58028
|
+
return "web";
|
|
58029
|
+
}
|
|
58030
|
+
if (name.includes("batch") || name.includes("workflow")) {
|
|
58031
|
+
return "workers";
|
|
58032
|
+
}
|
|
58033
|
+
return "other";
|
|
58034
|
+
}
|
|
58035
|
+
function logSourceLabel(source) {
|
|
58036
|
+
return SOURCE_LABELS[source];
|
|
58037
|
+
}
|
|
58038
|
+
function isValidLogSource(value) {
|
|
58039
|
+
return value in SOURCE_LABELS;
|
|
58040
|
+
}
|
|
58041
|
+
function parseSince(value) {
|
|
58042
|
+
const match = SINCE_DURATION.exec(value.trim());
|
|
58043
|
+
if (!match) {
|
|
58044
|
+
throw errors.invalidLogWindow(value);
|
|
58045
|
+
}
|
|
58046
|
+
const amount = Number.parseInt(match[1], 10);
|
|
58047
|
+
if (amount <= 0) {
|
|
58048
|
+
throw errors.invalidLogWindow(value);
|
|
58049
|
+
}
|
|
58050
|
+
const unit = match[2].toLowerCase();
|
|
58051
|
+
const multipliers = {
|
|
58052
|
+
s: 1e3,
|
|
58053
|
+
m: 6e4,
|
|
58054
|
+
h: 36e5,
|
|
58055
|
+
d: 864e5
|
|
58056
|
+
};
|
|
58057
|
+
return amount * multipliers[unit];
|
|
58058
|
+
}
|
|
58059
|
+
function isPlatformLine(message) {
|
|
58060
|
+
return PLATFORM_LINE.test(message);
|
|
58061
|
+
}
|
|
58062
|
+
function parseStructured(message) {
|
|
58063
|
+
const start = message.indexOf("{");
|
|
58064
|
+
if (start === -1) {
|
|
58065
|
+
return null;
|
|
58066
|
+
}
|
|
58067
|
+
try {
|
|
58068
|
+
const parsed = JSON.parse(message.slice(start));
|
|
58069
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
58070
|
+
} catch {
|
|
58071
|
+
return null;
|
|
58072
|
+
}
|
|
58073
|
+
}
|
|
58074
|
+
function isErrorLine(message) {
|
|
58075
|
+
const structured = parseStructured(message);
|
|
58076
|
+
const level = structured?.level;
|
|
58077
|
+
if (typeof level === "string") {
|
|
58078
|
+
return ERROR_LEVELS.has(level.toLowerCase());
|
|
58079
|
+
}
|
|
58080
|
+
if (typeof level === "number") {
|
|
58081
|
+
return level >= 50;
|
|
58082
|
+
}
|
|
58083
|
+
return ERROR_TEXT.test(message);
|
|
58084
|
+
}
|
|
58085
|
+
function detectLevel(message) {
|
|
58086
|
+
const structured = parseStructured(message);
|
|
58087
|
+
const level = structured?.level;
|
|
58088
|
+
if (typeof level === "string") {
|
|
58089
|
+
return level.toUpperCase();
|
|
58090
|
+
}
|
|
58091
|
+
if (typeof level === "number") {
|
|
58092
|
+
if (level >= 60) {
|
|
58093
|
+
return "FATAL";
|
|
58094
|
+
}
|
|
58095
|
+
if (level >= 50) {
|
|
58096
|
+
return "ERROR";
|
|
58097
|
+
}
|
|
58098
|
+
if (level >= 40) {
|
|
58099
|
+
return "WARN";
|
|
58100
|
+
}
|
|
58101
|
+
if (level >= 30) {
|
|
58102
|
+
return "INFO";
|
|
58103
|
+
}
|
|
58104
|
+
return "DEBUG";
|
|
58105
|
+
}
|
|
58106
|
+
if (isPlatformLine(message)) {
|
|
58107
|
+
return null;
|
|
58108
|
+
}
|
|
58109
|
+
const match = LEVEL_TEXT.exec(message);
|
|
58110
|
+
if (match) {
|
|
58111
|
+
return match[2] === "WARNING" ? "WARN" : match[2];
|
|
58112
|
+
}
|
|
58113
|
+
return ERROR_TEXT.test(message) ? "ERROR" : null;
|
|
58114
|
+
}
|
|
58115
|
+
function formatMessageBody(message) {
|
|
58116
|
+
const structured = parseStructured(message);
|
|
58117
|
+
if (!structured) {
|
|
58118
|
+
return message;
|
|
58119
|
+
}
|
|
58120
|
+
const body = structured.msg ?? structured.message;
|
|
58121
|
+
if (typeof body !== "string" || body.length === 0) {
|
|
58122
|
+
return message;
|
|
58123
|
+
}
|
|
58124
|
+
const err = structured.err ?? structured.error;
|
|
58125
|
+
if (err && typeof err === "object") {
|
|
58126
|
+
const detail = err.message;
|
|
58127
|
+
if (typeof detail === "string" && detail !== body) {
|
|
58128
|
+
return `${body} \u2014 ${detail}`;
|
|
58129
|
+
}
|
|
58130
|
+
}
|
|
58131
|
+
return body;
|
|
58132
|
+
}
|
|
58133
|
+
async function getLogsClient(region) {
|
|
58134
|
+
const { CloudWatchLogsClient } = await import("@aws-sdk/client-cloudwatch-logs");
|
|
58135
|
+
return new CloudWatchLogsClient({ region });
|
|
58136
|
+
}
|
|
58137
|
+
function toLogsError(error, action) {
|
|
58138
|
+
if (!isAWSError(error)) {
|
|
58139
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
58140
|
+
}
|
|
58141
|
+
if (error.name === "AccessDeniedException" || error.name === "AccessDenied" || error.message.includes("AccessDenied") || error.message.includes("not authorized")) {
|
|
58142
|
+
return errors.cloudWatchLogsPermissionDenied(action);
|
|
58143
|
+
}
|
|
58144
|
+
return error;
|
|
58145
|
+
}
|
|
58146
|
+
async function discoverSelfhostLogGroups(region) {
|
|
58147
|
+
const { DescribeLogGroupsCommand } = await import("@aws-sdk/client-cloudwatch-logs");
|
|
58148
|
+
const client2 = await getLogsClient(region);
|
|
58149
|
+
const groups = [];
|
|
58150
|
+
let nextToken;
|
|
58151
|
+
try {
|
|
58152
|
+
do {
|
|
58153
|
+
const result = await client2.send(
|
|
58154
|
+
new DescribeLogGroupsCommand({
|
|
58155
|
+
logGroupNamePrefix: SELFHOST_LOG_GROUP_PREFIX,
|
|
58156
|
+
nextToken
|
|
58157
|
+
})
|
|
58158
|
+
);
|
|
58159
|
+
for (const group3 of result.logGroups ?? []) {
|
|
58160
|
+
if (group3.logGroupName && group3.arn) {
|
|
58161
|
+
groups.push({
|
|
58162
|
+
name: group3.logGroupName,
|
|
58163
|
+
arn: group3.arn,
|
|
58164
|
+
source: classifyLogGroup(group3.logGroupName)
|
|
58165
|
+
});
|
|
58166
|
+
}
|
|
58167
|
+
}
|
|
58168
|
+
nextToken = result.nextToken;
|
|
58169
|
+
} while (nextToken);
|
|
58170
|
+
} catch (error) {
|
|
58171
|
+
throw toLogsError(error, "logs:DescribeLogGroups");
|
|
58172
|
+
}
|
|
58173
|
+
return groups.sort((a6, b6) => a6.name.localeCompare(b6.name));
|
|
58174
|
+
}
|
|
58175
|
+
function toEntries(events, group3) {
|
|
58176
|
+
return events.map((event) => ({
|
|
58177
|
+
timestamp: event.timestamp ?? Date.now(),
|
|
58178
|
+
message: (event.message ?? "").trimEnd(),
|
|
58179
|
+
logStream: event.logStreamName ?? "",
|
|
58180
|
+
logGroup: group3.name,
|
|
58181
|
+
source: group3.source
|
|
58182
|
+
}));
|
|
58183
|
+
}
|
|
58184
|
+
function eventKey(event, groupName) {
|
|
58185
|
+
return event.eventId ?? `${groupName}:${event.timestamp}:${event.message ?? ""}`;
|
|
58186
|
+
}
|
|
58187
|
+
async function fetchGroupEvents(options) {
|
|
58188
|
+
const { FilterLogEventsCommand } = await import("@aws-sdk/client-cloudwatch-logs");
|
|
58189
|
+
const client2 = await getLogsClient(options.region);
|
|
58190
|
+
const collected = [];
|
|
58191
|
+
let nextToken;
|
|
58192
|
+
try {
|
|
58193
|
+
do {
|
|
58194
|
+
const result = await client2.send(
|
|
58195
|
+
new FilterLogEventsCommand({
|
|
58196
|
+
logGroupName: options.group.name,
|
|
58197
|
+
startTime: options.startTime,
|
|
58198
|
+
endTime: options.endTime,
|
|
58199
|
+
filterPattern: options.filterPattern,
|
|
58200
|
+
nextToken,
|
|
58201
|
+
limit: 200
|
|
58202
|
+
})
|
|
58203
|
+
);
|
|
58204
|
+
for (const event of result.events ?? []) {
|
|
58205
|
+
if (options.onKey && !options.onKey(eventKey(event, options.group.name))) {
|
|
58206
|
+
continue;
|
|
58207
|
+
}
|
|
58208
|
+
collected.push(event);
|
|
58209
|
+
}
|
|
58210
|
+
nextToken = result.nextToken;
|
|
58211
|
+
} while (nextToken && collected.length < options.maxEntries);
|
|
58212
|
+
} catch (error) {
|
|
58213
|
+
if (isAWSError(error) && error.name === "ResourceNotFoundException") {
|
|
58214
|
+
return [];
|
|
58215
|
+
}
|
|
58216
|
+
throw toLogsError(error, "logs:FilterLogEvents");
|
|
58217
|
+
}
|
|
58218
|
+
return toEntries(collected.slice(0, options.maxEntries), options.group);
|
|
58219
|
+
}
|
|
58220
|
+
async function fetchLogs(options) {
|
|
58221
|
+
const maxEntries = options.maxEntries ?? 1e3;
|
|
58222
|
+
const perGroup = await Promise.all(
|
|
58223
|
+
options.groups.map(
|
|
58224
|
+
(group3) => fetchGroupEvents({
|
|
58225
|
+
region: options.region,
|
|
58226
|
+
group: group3,
|
|
58227
|
+
startTime: options.startTime,
|
|
58228
|
+
endTime: options.endTime,
|
|
58229
|
+
filterPattern: options.filterPattern,
|
|
58230
|
+
maxEntries
|
|
58231
|
+
})
|
|
58232
|
+
)
|
|
58233
|
+
);
|
|
58234
|
+
return perGroup.flat().sort((a6, b6) => a6.timestamp - b6.timestamp).slice(-maxEntries);
|
|
58235
|
+
}
|
|
58236
|
+
function createLogPoller(options) {
|
|
58237
|
+
const now = options.now ?? (() => Date.now());
|
|
58238
|
+
const seen = /* @__PURE__ */ new Set();
|
|
58239
|
+
const order = [];
|
|
58240
|
+
let nextStart = options.since;
|
|
58241
|
+
const remember = (key) => {
|
|
58242
|
+
if (seen.has(key)) {
|
|
58243
|
+
return false;
|
|
58244
|
+
}
|
|
58245
|
+
seen.add(key);
|
|
58246
|
+
order.push(key);
|
|
58247
|
+
if (order.length > MAX_SEEN_KEYS) {
|
|
58248
|
+
const evicted = order.splice(0, order.length - MAX_SEEN_KEYS);
|
|
58249
|
+
for (const stale of evicted) {
|
|
58250
|
+
seen.delete(stale);
|
|
58251
|
+
}
|
|
58252
|
+
}
|
|
58253
|
+
return true;
|
|
58254
|
+
};
|
|
58255
|
+
return async function poll() {
|
|
58256
|
+
const windowStart = Math.max(0, nextStart - POLL_OVERLAP_MS);
|
|
58257
|
+
const tickStart = now();
|
|
58258
|
+
const perGroup = await Promise.all(
|
|
58259
|
+
options.groups.map(
|
|
58260
|
+
(group3) => fetchGroupEvents({
|
|
58261
|
+
region: options.region,
|
|
58262
|
+
group: group3,
|
|
58263
|
+
startTime: windowStart,
|
|
58264
|
+
filterPattern: options.filterPattern,
|
|
58265
|
+
maxEntries: 1e3,
|
|
58266
|
+
onKey: remember
|
|
58267
|
+
})
|
|
58268
|
+
)
|
|
58269
|
+
);
|
|
58270
|
+
nextStart = tickStart;
|
|
58271
|
+
return perGroup.flat().sort((a6, b6) => a6.timestamp - b6.timestamp);
|
|
58272
|
+
};
|
|
58273
|
+
}
|
|
58274
|
+
function liveTailIdentifier(arn) {
|
|
58275
|
+
return arn.replace(ARN_WILDCARD_SUFFIX, "");
|
|
58276
|
+
}
|
|
58277
|
+
function startSelfhostLiveTail(options) {
|
|
58278
|
+
const abortController = new AbortController();
|
|
58279
|
+
const bySource = new Map(
|
|
58280
|
+
options.groups.map((group3) => [liveTailIdentifier(group3.arn), group3])
|
|
58281
|
+
);
|
|
58282
|
+
const stream = (async function* () {
|
|
58283
|
+
const { StartLiveTailCommand } = await import("@aws-sdk/client-cloudwatch-logs");
|
|
58284
|
+
const client2 = await getLogsClient(options.region);
|
|
58285
|
+
const response = await client2.send(
|
|
58286
|
+
new StartLiveTailCommand({
|
|
58287
|
+
logGroupIdentifiers: [...bySource.keys()].slice(
|
|
58288
|
+
0,
|
|
58289
|
+
LIVE_TAIL_MAX_GROUPS
|
|
58290
|
+
),
|
|
58291
|
+
logEventFilterPattern: options.filterPattern ?? ""
|
|
58292
|
+
}),
|
|
58293
|
+
{ abortSignal: abortController.signal }
|
|
58294
|
+
);
|
|
58295
|
+
if (!response.responseStream) {
|
|
58296
|
+
return;
|
|
58297
|
+
}
|
|
58298
|
+
for await (const event of response.responseStream) {
|
|
58299
|
+
const results = event.sessionUpdate?.sessionResults;
|
|
58300
|
+
if (!results?.length) {
|
|
58301
|
+
continue;
|
|
58302
|
+
}
|
|
58303
|
+
yield results.map((result) => {
|
|
58304
|
+
const identifier = result.logGroupIdentifier ?? "";
|
|
58305
|
+
const group3 = bySource.get(identifier);
|
|
58306
|
+
return {
|
|
58307
|
+
timestamp: result.timestamp ?? Date.now(),
|
|
58308
|
+
message: (result.message ?? "").trimEnd(),
|
|
58309
|
+
logStream: result.logStreamName ?? "",
|
|
58310
|
+
logGroup: group3?.name ?? identifier,
|
|
58311
|
+
source: group3?.source ?? classifyLogGroup(identifier)
|
|
58312
|
+
};
|
|
58313
|
+
});
|
|
58314
|
+
}
|
|
58315
|
+
})();
|
|
58316
|
+
return { stream, abort: () => abortController.abort() };
|
|
58317
|
+
}
|
|
58318
|
+
function liveTailGroupLimit() {
|
|
58319
|
+
return LIVE_TAIL_MAX_GROUPS;
|
|
58320
|
+
}
|
|
58321
|
+
|
|
58322
|
+
// src/commands/selfhost/logs.ts
|
|
58323
|
+
init_aws();
|
|
58324
|
+
init_errors();
|
|
58325
|
+
init_json_output();
|
|
58326
|
+
init_metadata();
|
|
58327
|
+
init_output();
|
|
58328
|
+
init_region_resolver();
|
|
58329
|
+
var DEFAULT_SINCE = "1h";
|
|
58330
|
+
var DEFAULT_INTERVAL_SECONDS = 3;
|
|
58331
|
+
var MIN_INTERVAL_SECONDS = 1;
|
|
58332
|
+
var MAX_INTERVAL_SECONDS = 60;
|
|
58333
|
+
var FOLLOW_BACKFILL_MS = 5 * 60 * 1e3;
|
|
58334
|
+
var MAX_ENTRIES = 1e3;
|
|
58335
|
+
var SOURCE_COLORS = {
|
|
58336
|
+
api: pc54.cyan,
|
|
58337
|
+
web: pc54.magenta,
|
|
58338
|
+
workers: pc54.blue,
|
|
58339
|
+
other: pc54.gray
|
|
58340
|
+
};
|
|
58341
|
+
function formatTime(timestamp) {
|
|
58342
|
+
const date2 = new Date(timestamp);
|
|
58343
|
+
const pad = (n3) => String(n3).padStart(2, "0");
|
|
58344
|
+
return `${pad(date2.getHours())}:${pad(date2.getMinutes())}:${pad(date2.getSeconds())}`;
|
|
58345
|
+
}
|
|
58346
|
+
function colorLevel(level) {
|
|
58347
|
+
if (!level) {
|
|
58348
|
+
return pc54.dim(" ");
|
|
58349
|
+
}
|
|
58350
|
+
const padded = level.padEnd(5).slice(0, 5);
|
|
58351
|
+
if (level === "ERROR" || level === "FATAL" || level === "CRITICAL") {
|
|
58352
|
+
return pc54.red(padded);
|
|
58353
|
+
}
|
|
58354
|
+
if (level === "WARN") {
|
|
58355
|
+
return pc54.yellow(padded);
|
|
58356
|
+
}
|
|
58357
|
+
if (level === "INFO") {
|
|
58358
|
+
return pc54.green(padded);
|
|
58359
|
+
}
|
|
58360
|
+
return pc54.dim(padded);
|
|
58361
|
+
}
|
|
58362
|
+
function renderEntry(entry, options) {
|
|
58363
|
+
const level = detectLevel(entry.message);
|
|
58364
|
+
const label = logSourceLabel(entry.source).padEnd(options.sourceWidth);
|
|
58365
|
+
const body = options.verbose ? entry.message : formatMessageBody(entry.message);
|
|
58366
|
+
return `${pc54.dim(formatTime(entry.timestamp))} ${SOURCE_COLORS[entry.source](label)} ${colorLevel(level)} ${body}`;
|
|
58367
|
+
}
|
|
58368
|
+
function toJsonEntry(entry) {
|
|
58369
|
+
return {
|
|
58370
|
+
timestamp: entry.timestamp,
|
|
58371
|
+
time: new Date(entry.timestamp).toISOString(),
|
|
58372
|
+
source: entry.source,
|
|
58373
|
+
level: detectLevel(entry.message),
|
|
58374
|
+
logGroup: entry.logGroup,
|
|
58375
|
+
logStream: entry.logStream,
|
|
58376
|
+
message: entry.message
|
|
58377
|
+
};
|
|
58378
|
+
}
|
|
58379
|
+
function refine(entries, options) {
|
|
58380
|
+
return entries.filter((entry) => {
|
|
58381
|
+
if (entry.message.length === 0) {
|
|
58382
|
+
return false;
|
|
58383
|
+
}
|
|
58384
|
+
if (!options.platform && isPlatformLine(entry.message)) {
|
|
58385
|
+
return false;
|
|
58386
|
+
}
|
|
58387
|
+
if (options.errorsOnly && !isErrorLine(entry.message)) {
|
|
58388
|
+
return false;
|
|
58389
|
+
}
|
|
58390
|
+
return true;
|
|
58391
|
+
});
|
|
58392
|
+
}
|
|
58393
|
+
function parseInterval(value) {
|
|
58394
|
+
if (!value) {
|
|
58395
|
+
return DEFAULT_INTERVAL_SECONDS;
|
|
58396
|
+
}
|
|
58397
|
+
const parsed = Number.parseInt(value, 10);
|
|
58398
|
+
if (Number.isNaN(parsed)) {
|
|
58399
|
+
return DEFAULT_INTERVAL_SECONDS;
|
|
58400
|
+
}
|
|
58401
|
+
return Math.min(Math.max(parsed, MIN_INTERVAL_SECONDS), MAX_INTERVAL_SECONDS);
|
|
58402
|
+
}
|
|
58403
|
+
function selectGroups(groups, source) {
|
|
58404
|
+
if (!source || source === "all") {
|
|
58405
|
+
return groups;
|
|
58406
|
+
}
|
|
58407
|
+
if (!isValidLogSource(source)) {
|
|
58408
|
+
throw errors.invalidLogSource(source);
|
|
58409
|
+
}
|
|
58410
|
+
return groups.filter((group3) => group3.source === source);
|
|
58411
|
+
}
|
|
58412
|
+
function createInterruptibleSleep() {
|
|
58413
|
+
let wake = null;
|
|
58414
|
+
return {
|
|
58415
|
+
sleep: (ms) => new Promise((resolve) => {
|
|
58416
|
+
const timer = setTimeout(() => {
|
|
58417
|
+
wake = null;
|
|
58418
|
+
resolve();
|
|
58419
|
+
}, ms);
|
|
58420
|
+
wake = () => {
|
|
58421
|
+
clearTimeout(timer);
|
|
58422
|
+
wake = null;
|
|
58423
|
+
resolve();
|
|
58424
|
+
};
|
|
58425
|
+
}),
|
|
58426
|
+
interrupt: () => wake?.()
|
|
58427
|
+
};
|
|
58428
|
+
}
|
|
58429
|
+
function printGroupSummary(groups) {
|
|
58430
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
58431
|
+
for (const group3 of groups) {
|
|
58432
|
+
const existing = bySource.get(group3.source) ?? [];
|
|
58433
|
+
existing.push(group3.name);
|
|
58434
|
+
bySource.set(group3.source, existing);
|
|
58435
|
+
}
|
|
58436
|
+
const parts = [...bySource.entries()].map(
|
|
58437
|
+
([source, names]) => `${SOURCE_COLORS[source](logSourceLabel(source))} ${pc54.dim(`(${names.length})`)}`
|
|
58438
|
+
);
|
|
58439
|
+
console.log(
|
|
58440
|
+
`${pc54.dim("Sources:")} ${parts.join(pc54.dim(" \xB7 "))} ${pc54.dim(`${groups.length} log group${groups.length === 1 ? "" : "s"}`)}`
|
|
58441
|
+
);
|
|
58442
|
+
}
|
|
58443
|
+
async function selfhostLogs(options) {
|
|
58444
|
+
const progress = new DeploymentProgress();
|
|
58445
|
+
const json = isJsonMode();
|
|
58446
|
+
if (!json) {
|
|
58447
|
+
clack51.intro(pc54.bold("Wraps Self-Hosted Logs"));
|
|
58448
|
+
}
|
|
58449
|
+
const sinceMs = parseSince(options.since ?? DEFAULT_SINCE);
|
|
58450
|
+
const intervalSeconds = parseInterval(options.interval);
|
|
58451
|
+
const identity = await progress.execute(
|
|
58452
|
+
"Checking AWS credentials",
|
|
58453
|
+
async () => validateAWSCredentials()
|
|
58454
|
+
);
|
|
58455
|
+
const region = await resolveRegionForCommand({
|
|
58456
|
+
accountId: identity.accountId,
|
|
58457
|
+
optionRegion: options.region,
|
|
58458
|
+
service: "selfhost",
|
|
58459
|
+
label: "self-hosted deployment"
|
|
58460
|
+
});
|
|
58461
|
+
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
58462
|
+
const allGroups = await progress.execute(
|
|
58463
|
+
"Locating log groups",
|
|
58464
|
+
async () => discoverSelfhostLogGroups(region)
|
|
58465
|
+
);
|
|
58466
|
+
const groups = selectGroups(allGroups, options.source);
|
|
58467
|
+
progress.stop();
|
|
58468
|
+
if (!(metadata?.services?.selfhost || json)) {
|
|
58469
|
+
clack51.log.warn(
|
|
58470
|
+
"No self-hosted deployment recorded on this machine \u2014 reading log groups directly from AWS."
|
|
58471
|
+
);
|
|
58472
|
+
}
|
|
58473
|
+
if (allGroups.length === 0) {
|
|
58474
|
+
throw errors.noSelfhostLogGroups(region);
|
|
58475
|
+
}
|
|
58476
|
+
if (groups.length === 0) {
|
|
58477
|
+
throw errors.noLogGroupsForSource(
|
|
58478
|
+
options.source ?? "all",
|
|
58479
|
+
[...new Set(allGroups.map((group3) => group3.source))].join(", ")
|
|
58480
|
+
);
|
|
58481
|
+
}
|
|
58482
|
+
const filterPattern = options.filter ?? (options.errors ? ERROR_FILTER_PATTERN : void 0);
|
|
58483
|
+
const refineOptions = {
|
|
58484
|
+
errorsOnly: Boolean(options.errors),
|
|
58485
|
+
platform: Boolean(options.platform)
|
|
58486
|
+
};
|
|
58487
|
+
const sourceWidth = Math.max(
|
|
58488
|
+
...groups.map((group3) => logSourceLabel(group3.source).length)
|
|
58489
|
+
);
|
|
58490
|
+
const renderOptions = {
|
|
58491
|
+
sourceWidth,
|
|
58492
|
+
verbose: Boolean(options.verbose)
|
|
58493
|
+
};
|
|
58494
|
+
const emit = (entries) => {
|
|
58495
|
+
for (const entry of entries) {
|
|
58496
|
+
console.log(
|
|
58497
|
+
json ? JSON.stringify(toJsonEntry(entry)) : renderEntry(entry, renderOptions)
|
|
58498
|
+
);
|
|
58499
|
+
}
|
|
58500
|
+
};
|
|
58501
|
+
const context = {
|
|
58502
|
+
region,
|
|
58503
|
+
groups,
|
|
58504
|
+
filterPattern,
|
|
58505
|
+
refineOptions,
|
|
58506
|
+
emit,
|
|
58507
|
+
json,
|
|
58508
|
+
live: Boolean(options.live),
|
|
58509
|
+
intervalSeconds
|
|
58510
|
+
};
|
|
58511
|
+
if (options.follow) {
|
|
58512
|
+
await follow(context);
|
|
58513
|
+
return;
|
|
58514
|
+
}
|
|
58515
|
+
await printWindow(context, {
|
|
58516
|
+
sinceMs,
|
|
58517
|
+
sinceLabel: options.since ?? DEFAULT_SINCE,
|
|
58518
|
+
errorsOnly: refineOptions.errorsOnly
|
|
58519
|
+
});
|
|
58520
|
+
}
|
|
58521
|
+
async function printWindow(context, window) {
|
|
58522
|
+
const entries = refine(
|
|
58523
|
+
await fetchLogs({
|
|
58524
|
+
region: context.region,
|
|
58525
|
+
groups: context.groups,
|
|
58526
|
+
startTime: Date.now() - window.sinceMs,
|
|
58527
|
+
filterPattern: context.filterPattern,
|
|
58528
|
+
maxEntries: MAX_ENTRIES
|
|
58529
|
+
}),
|
|
58530
|
+
context.refineOptions
|
|
58531
|
+
);
|
|
58532
|
+
if (context.json) {
|
|
58533
|
+
jsonSuccess("selfhost.logs", {
|
|
58534
|
+
region: context.region,
|
|
58535
|
+
groups: context.groups.map((group3) => ({
|
|
58536
|
+
name: group3.name,
|
|
58537
|
+
source: group3.source
|
|
58538
|
+
})),
|
|
58539
|
+
entries: entries.map(toJsonEntry)
|
|
58540
|
+
});
|
|
58541
|
+
return;
|
|
58542
|
+
}
|
|
58543
|
+
printGroupSummary(context.groups);
|
|
58544
|
+
console.log("");
|
|
58545
|
+
if (entries.length === 0) {
|
|
58546
|
+
clack51.log.info(
|
|
58547
|
+
window.errorsOnly ? `No errors in the last ${window.sinceLabel}.` : `No log events in the last ${window.sinceLabel}.`
|
|
58548
|
+
);
|
|
58549
|
+
clack51.outro(pc54.dim("Nothing to report"));
|
|
58550
|
+
return;
|
|
58551
|
+
}
|
|
58552
|
+
context.emit(entries);
|
|
58553
|
+
console.log("");
|
|
58554
|
+
if (entries.length >= MAX_ENTRIES) {
|
|
58555
|
+
clack51.log.warn(
|
|
58556
|
+
`Showing the most recent ${MAX_ENTRIES} events \u2014 narrow the window with ${pc54.cyan("--since")} to see more.`
|
|
58557
|
+
);
|
|
58558
|
+
}
|
|
58559
|
+
clack51.outro(
|
|
58560
|
+
pc54.dim(
|
|
58561
|
+
`${entries.length} event${entries.length === 1 ? "" : "s"} from the last ${window.sinceLabel}`
|
|
58562
|
+
)
|
|
58563
|
+
);
|
|
58564
|
+
}
|
|
58565
|
+
function printFollowHeader(context) {
|
|
58566
|
+
printGroupSummary(context.groups);
|
|
58567
|
+
if (context.live) {
|
|
58568
|
+
console.log(
|
|
58569
|
+
pc54.yellow(
|
|
58570
|
+
"\u26A0 CloudWatch Live Tail bills ~$0.01/min for as long as this session is open."
|
|
58571
|
+
)
|
|
58572
|
+
);
|
|
58573
|
+
console.log(
|
|
58574
|
+
pc54.dim(`Live tailing \xB7 ${pc54.reset(pc54.bold("Ctrl+C"))} to stop`)
|
|
58575
|
+
);
|
|
58576
|
+
} else {
|
|
58577
|
+
console.log(
|
|
58578
|
+
pc54.dim(
|
|
58579
|
+
`Polling every ${context.intervalSeconds}s \xB7 ${pc54.reset(pc54.bold("Ctrl+C"))} to stop`
|
|
58580
|
+
)
|
|
58581
|
+
);
|
|
58582
|
+
}
|
|
58583
|
+
console.log("");
|
|
58584
|
+
}
|
|
58585
|
+
async function follow(context) {
|
|
58586
|
+
let stopped = false;
|
|
58587
|
+
const timer = createInterruptibleSleep();
|
|
58588
|
+
let abortStream = null;
|
|
58589
|
+
const onSigint = () => {
|
|
58590
|
+
stopped = true;
|
|
58591
|
+
abortStream?.();
|
|
58592
|
+
timer.interrupt();
|
|
58593
|
+
};
|
|
58594
|
+
process.on("SIGINT", onSigint);
|
|
58595
|
+
try {
|
|
58596
|
+
if (!context.json) {
|
|
58597
|
+
printFollowHeader(context);
|
|
58598
|
+
}
|
|
58599
|
+
context.emit(
|
|
58600
|
+
refine(
|
|
58601
|
+
await fetchLogs({
|
|
58602
|
+
region: context.region,
|
|
58603
|
+
groups: context.groups,
|
|
58604
|
+
startTime: Date.now() - FOLLOW_BACKFILL_MS,
|
|
58605
|
+
filterPattern: context.filterPattern,
|
|
58606
|
+
maxEntries: MAX_ENTRIES
|
|
58607
|
+
}),
|
|
58608
|
+
context.refineOptions
|
|
58609
|
+
)
|
|
58610
|
+
);
|
|
58611
|
+
if (context.live) {
|
|
58612
|
+
await runLiveTail(context, {
|
|
58613
|
+
isStopped: () => stopped,
|
|
58614
|
+
onSession: (abort) => {
|
|
58615
|
+
abortStream = abort;
|
|
58616
|
+
}
|
|
58617
|
+
});
|
|
58618
|
+
} else {
|
|
58619
|
+
await runPolling(context, {
|
|
58620
|
+
isStopped: () => stopped,
|
|
58621
|
+
sleep: timer.sleep
|
|
58622
|
+
});
|
|
58623
|
+
}
|
|
58624
|
+
} finally {
|
|
58625
|
+
process.off("SIGINT", onSigint);
|
|
58626
|
+
}
|
|
58627
|
+
if (!context.json) {
|
|
58628
|
+
console.log("");
|
|
58629
|
+
clack51.outro(pc54.dim("Stopped"));
|
|
58630
|
+
}
|
|
58631
|
+
}
|
|
58632
|
+
async function runLiveTail(context, control) {
|
|
58633
|
+
if (context.groups.length > liveTailGroupLimit() && !context.json) {
|
|
58634
|
+
clack51.log.warn(
|
|
58635
|
+
`Live Tail supports ${liveTailGroupLimit()} log groups per session \u2014 tailing the first ${liveTailGroupLimit()}. Use ${pc54.cyan("--source")} to choose which.`
|
|
58636
|
+
);
|
|
58637
|
+
}
|
|
58638
|
+
const session = startSelfhostLiveTail({
|
|
58639
|
+
region: context.region,
|
|
58640
|
+
groups: context.groups,
|
|
58641
|
+
filterPattern: context.filterPattern
|
|
58642
|
+
});
|
|
58643
|
+
control.onSession(session.abort);
|
|
58644
|
+
try {
|
|
58645
|
+
for await (const batch of session.stream) {
|
|
58646
|
+
context.emit(refine(batch, context.refineOptions));
|
|
58647
|
+
}
|
|
58648
|
+
} catch (error) {
|
|
58649
|
+
if (!(control.isStopped() && isAbortError(error))) {
|
|
58650
|
+
throw error;
|
|
58651
|
+
}
|
|
58652
|
+
return;
|
|
58653
|
+
}
|
|
58654
|
+
if (!(control.isStopped() || context.json)) {
|
|
58655
|
+
clack51.log.warn(
|
|
58656
|
+
`Live Tail session ended (AWS caps sessions at ~3 hours). Run ${pc54.cyan("wraps selfhost logs --follow --live")} again to resume.`
|
|
58657
|
+
);
|
|
58658
|
+
}
|
|
58659
|
+
}
|
|
58660
|
+
async function runPolling(context, control) {
|
|
58661
|
+
const poll = createLogPoller({
|
|
58662
|
+
region: context.region,
|
|
58663
|
+
groups: context.groups,
|
|
58664
|
+
filterPattern: context.filterPattern,
|
|
58665
|
+
since: Date.now()
|
|
58666
|
+
});
|
|
58667
|
+
while (!control.isStopped()) {
|
|
58668
|
+
await control.sleep(context.intervalSeconds * 1e3);
|
|
58669
|
+
if (control.isStopped()) {
|
|
58670
|
+
break;
|
|
58671
|
+
}
|
|
58672
|
+
context.emit(refine(await poll(), context.refineOptions));
|
|
58673
|
+
}
|
|
58674
|
+
}
|
|
58675
|
+
function isAbortError(error) {
|
|
58676
|
+
return error instanceof Error && (error.name === "AbortError" || error.message.includes("aborted"));
|
|
58677
|
+
}
|
|
58678
|
+
|
|
58679
|
+
// src/commands/selfhost/status.ts
|
|
58680
|
+
init_esm_shims();
|
|
58681
|
+
init_events();
|
|
58682
|
+
import * as clack52 from "@clack/prompts";
|
|
58683
|
+
import pc55 from "picocolors";
|
|
57905
58684
|
init_aws();
|
|
57906
58685
|
init_json_output();
|
|
57907
58686
|
init_metadata();
|
|
@@ -57911,39 +58690,39 @@ function displaySelfhostStatus(options) {
|
|
|
57911
58690
|
const lines = [];
|
|
57912
58691
|
const incomplete = !(options.apiUrl && options.appUrl);
|
|
57913
58692
|
lines.push(
|
|
57914
|
-
incomplete ?
|
|
58693
|
+
incomplete ? pc55.bold(pc55.yellow("Self-Hosted Control Plane Incomplete")) : pc55.bold(pc55.green("Self-Hosted Control Plane Active"))
|
|
57915
58694
|
);
|
|
57916
58695
|
if (incomplete) {
|
|
57917
58696
|
lines.push(
|
|
57918
|
-
|
|
57919
|
-
`A previous deploy did not finish. Run ${
|
|
58697
|
+
pc55.yellow(
|
|
58698
|
+
`A previous deploy did not finish. Run ${pc55.cyan("pnpm selfhost:upgrade")} from your fork to complete it.`
|
|
57920
58699
|
)
|
|
57921
58700
|
);
|
|
57922
58701
|
}
|
|
57923
58702
|
lines.push("");
|
|
57924
|
-
lines.push(
|
|
57925
|
-
lines.push(` URL: ${
|
|
57926
|
-
lines.push(` Region: ${
|
|
57927
|
-
lines.push(` Deployed: ${
|
|
58703
|
+
lines.push(pc55.bold("API"));
|
|
58704
|
+
lines.push(` URL: ${pc55.cyan(options.apiUrl || "(not deployed)")}`);
|
|
58705
|
+
lines.push(` Region: ${pc55.cyan(options.region)}`);
|
|
58706
|
+
lines.push(` Deployed: ${pc55.dim(options.deployedAt)}`);
|
|
57928
58707
|
if (options.variant) {
|
|
57929
58708
|
lines.push(
|
|
57930
|
-
` Type: ${
|
|
58709
|
+
` Type: ${pc55.cyan(options.variant === "sst" ? "Full platform (SST, deployed from fork)" : "API-only control plane (CLI)")}`
|
|
57931
58710
|
);
|
|
57932
58711
|
}
|
|
57933
58712
|
lines.push("");
|
|
57934
|
-
lines.push(
|
|
57935
|
-
lines.push(` App URL: ${
|
|
57936
|
-
lines.push(` License Key: ${
|
|
58713
|
+
lines.push(pc55.bold("Configuration"));
|
|
58714
|
+
lines.push(` App URL: ${pc55.cyan(options.appUrl || "(not deployed)")}`);
|
|
58715
|
+
lines.push(` License Key: ${pc55.dim(`${options.licenseKeyPrefix}...`)}`);
|
|
57937
58716
|
if (options.neonProjectId) {
|
|
57938
|
-
lines.push(` Neon Project: ${
|
|
58717
|
+
lines.push(` Neon Project: ${pc55.dim(options.neonProjectId)}`);
|
|
57939
58718
|
}
|
|
57940
|
-
|
|
58719
|
+
clack52.note(lines.join("\n"), "Self-Hosted Status");
|
|
57941
58720
|
}
|
|
57942
58721
|
async function selfhostStatus(options) {
|
|
57943
58722
|
const startTime = Date.now();
|
|
57944
58723
|
const progress = new DeploymentProgress();
|
|
57945
58724
|
if (!isJsonMode()) {
|
|
57946
|
-
|
|
58725
|
+
clack52.intro(pc55.bold("Wraps Self-Hosted Status"));
|
|
57947
58726
|
}
|
|
57948
58727
|
const identity = await progress.execute(
|
|
57949
58728
|
"Loading self-hosted status",
|
|
@@ -57958,11 +58737,11 @@ async function selfhostStatus(options) {
|
|
|
57958
58737
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
57959
58738
|
if (!metadata?.services?.selfhost) {
|
|
57960
58739
|
progress.stop();
|
|
57961
|
-
|
|
58740
|
+
clack52.log.error("No self-hosted deployment found");
|
|
57962
58741
|
console.log(
|
|
57963
58742
|
`
|
|
57964
|
-
Run ${
|
|
57965
|
-
or ${
|
|
58743
|
+
Run ${pc55.cyan("pnpm selfhost:deploy")} from your fork to deploy the full platform (API + dashboard),
|
|
58744
|
+
or ${pc55.cyan("wraps selfhost deploy")} for the API-only control plane.
|
|
57966
58745
|
`
|
|
57967
58746
|
);
|
|
57968
58747
|
process.exit(1);
|
|
@@ -57995,15 +58774,15 @@ or ${pc54.cyan("wraps selfhost deploy")} for the API-only control plane.
|
|
|
57995
58774
|
}
|
|
57996
58775
|
displaySelfhostStatus(statusData);
|
|
57997
58776
|
console.log("");
|
|
57998
|
-
|
|
58777
|
+
clack52.log.info(pc55.bold("Commands:"));
|
|
57999
58778
|
console.log(
|
|
58000
|
-
variant === "sst" ? ` ${
|
|
58779
|
+
variant === "sst" ? ` ${pc55.cyan("pnpm selfhost:upgrade")} (from your fork) - Redeploy the platform and run migrations` : ` ${pc55.cyan("wraps selfhost upgrade")} - Rebuild and redeploy the API Lambda`
|
|
58001
58780
|
);
|
|
58002
58781
|
trackCommand("selfhost:status", {
|
|
58003
58782
|
success: true,
|
|
58004
58783
|
duration_ms: Date.now() - startTime
|
|
58005
58784
|
});
|
|
58006
|
-
|
|
58785
|
+
clack52.outro(pc55.dim("Self-hosted deployment is active"));
|
|
58007
58786
|
}
|
|
58008
58787
|
|
|
58009
58788
|
// src/commands/selfhost/upgrade.ts
|
|
@@ -58011,9 +58790,9 @@ init_esm_shims();
|
|
|
58011
58790
|
import { existsSync as existsSync19 } from "fs";
|
|
58012
58791
|
import { dirname as dirname7, join as join24 } from "path";
|
|
58013
58792
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
58014
|
-
import * as
|
|
58793
|
+
import * as clack53 from "@clack/prompts";
|
|
58015
58794
|
import * as pulumi30 from "@pulumi/pulumi";
|
|
58016
|
-
import
|
|
58795
|
+
import pc56 from "picocolors";
|
|
58017
58796
|
init_events();
|
|
58018
58797
|
init_aws();
|
|
58019
58798
|
init_errors();
|
|
@@ -58029,7 +58808,7 @@ var bundledLambdaZip2 = join24(cliDir2, "api-lambda.zip");
|
|
|
58029
58808
|
async function selfhostUpgrade(options) {
|
|
58030
58809
|
const startTime = Date.now();
|
|
58031
58810
|
if (!isJsonMode()) {
|
|
58032
|
-
|
|
58811
|
+
clack53.intro(pc56.bold("Wraps Self-Hosted Control Plane Upgrade"));
|
|
58033
58812
|
}
|
|
58034
58813
|
const progress = new DeploymentProgress();
|
|
58035
58814
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -58044,7 +58823,7 @@ async function selfhostUpgrade(options) {
|
|
|
58044
58823
|
async () => validateAWSCredentialsWithDetails()
|
|
58045
58824
|
);
|
|
58046
58825
|
const identity = credentialResult.identity;
|
|
58047
|
-
progress.info(`Connected to AWS account: ${
|
|
58826
|
+
progress.info(`Connected to AWS account: ${pc56.cyan(identity.accountId)}`);
|
|
58048
58827
|
const region = await resolveRegionForCommand({
|
|
58049
58828
|
accountId: identity.accountId,
|
|
58050
58829
|
optionRegion: options.region,
|
|
@@ -58053,20 +58832,20 @@ async function selfhostUpgrade(options) {
|
|
|
58053
58832
|
});
|
|
58054
58833
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
58055
58834
|
if (!metadata?.services?.selfhost) {
|
|
58056
|
-
|
|
58057
|
-
|
|
58835
|
+
clack53.log.error("No self-hosted deployment found.");
|
|
58836
|
+
clack53.log.info(`Run ${pc56.cyan("wraps selfhost deploy")} first.`);
|
|
58058
58837
|
process.exit(1);
|
|
58059
58838
|
}
|
|
58060
58839
|
const selfhostService = metadata.services.selfhost;
|
|
58061
58840
|
progress.info(`Found deployment from: ${selfhostService.deployedAt}`);
|
|
58062
|
-
progress.info(`API URL: ${
|
|
58841
|
+
progress.info(`API URL: ${pc56.cyan(selfhostService.apiUrl)}`);
|
|
58063
58842
|
if (!(options.yes || options.preview)) {
|
|
58064
|
-
const confirmed = await
|
|
58065
|
-
message: `Upgrade self-hosted deployment in ${
|
|
58843
|
+
const confirmed = await clack53.confirm({
|
|
58844
|
+
message: `Upgrade self-hosted deployment in ${pc56.cyan(identity.accountId)} / ${pc56.cyan(region)}?`,
|
|
58066
58845
|
initialValue: true
|
|
58067
58846
|
});
|
|
58068
|
-
if (
|
|
58069
|
-
|
|
58847
|
+
if (clack53.isCancel(confirmed) || !confirmed) {
|
|
58848
|
+
clack53.cancel("Upgrade cancelled.");
|
|
58070
58849
|
process.exit(0);
|
|
58071
58850
|
}
|
|
58072
58851
|
}
|
|
@@ -58140,8 +58919,8 @@ async function selfhostUpgrade(options) {
|
|
|
58140
58919
|
resourceChanges: previewResult.resourceChanges,
|
|
58141
58920
|
commandName: "wraps selfhost upgrade"
|
|
58142
58921
|
});
|
|
58143
|
-
|
|
58144
|
-
|
|
58922
|
+
clack53.outro(
|
|
58923
|
+
pc56.green("Preview complete. Run without --preview to upgrade.")
|
|
58145
58924
|
);
|
|
58146
58925
|
return;
|
|
58147
58926
|
} catch (error) {
|
|
@@ -58217,28 +58996,28 @@ async function selfhostUpgrade(options) {
|
|
|
58217
58996
|
}
|
|
58218
58997
|
progress.info("Deployment metadata updated");
|
|
58219
58998
|
console.log("\n");
|
|
58220
|
-
|
|
58999
|
+
clack53.log.success(pc56.green(pc56.bold("Self-hosted Wraps API upgraded!")));
|
|
58221
59000
|
console.log("\n");
|
|
58222
|
-
|
|
59001
|
+
clack53.note(
|
|
58223
59002
|
[
|
|
58224
|
-
`${
|
|
58225
|
-
`${
|
|
58226
|
-
`${
|
|
59003
|
+
`${pc56.bold("API URL:")} ${pc56.cyan(outputs.apiUrl || selfhostService.apiUrl)}`,
|
|
59004
|
+
`${pc56.bold("Region:")} ${pc56.cyan(region)}`,
|
|
59005
|
+
`${pc56.bold("Lambda ARN:")} ${pc56.dim(outputs.lambdaArn)}`
|
|
58227
59006
|
].join("\n"),
|
|
58228
59007
|
"Self-Hosted Deployment"
|
|
58229
59008
|
);
|
|
58230
|
-
|
|
58231
|
-
|
|
59009
|
+
clack53.outro(
|
|
59010
|
+
pc56.green(`Upgraded in ${((Date.now() - startTime) / 1e3).toFixed(1)}s`)
|
|
58232
59011
|
);
|
|
58233
59012
|
}
|
|
58234
59013
|
|
|
58235
59014
|
// src/commands/shared/dashboard.ts
|
|
58236
59015
|
init_esm_shims();
|
|
58237
|
-
import * as
|
|
59016
|
+
import * as clack54 from "@clack/prompts";
|
|
58238
59017
|
import * as pulumi31 from "@pulumi/pulumi";
|
|
58239
59018
|
import getPort from "get-port";
|
|
58240
59019
|
import open3 from "open";
|
|
58241
|
-
import
|
|
59020
|
+
import pc57 from "picocolors";
|
|
58242
59021
|
|
|
58243
59022
|
// src/console/server.ts
|
|
58244
59023
|
init_esm_shims();
|
|
@@ -59438,13 +60217,13 @@ function createMetricsRouter(config2) {
|
|
|
59438
60217
|
const router = createRouter5();
|
|
59439
60218
|
router.get("/stream", async (req, res) => {
|
|
59440
60219
|
const connectionId = randomUUID().slice(0, 8);
|
|
59441
|
-
const
|
|
60220
|
+
const log64 = (msg, data) => {
|
|
59442
60221
|
console.log(JSON.stringify({ connectionId, msg, ...data }));
|
|
59443
60222
|
};
|
|
59444
60223
|
res.setHeader("Content-Type", "text/event-stream");
|
|
59445
60224
|
res.setHeader("Cache-Control", "no-cache");
|
|
59446
60225
|
res.setHeader("Connection", "keep-alive");
|
|
59447
|
-
|
|
60226
|
+
log64("SSE connected");
|
|
59448
60227
|
res.write('data: {"type":"connected"}\n\n');
|
|
59449
60228
|
const { startTime, endTime } = req.query;
|
|
59450
60229
|
const getTimeRange = () => ({
|
|
@@ -59454,7 +60233,7 @@ function createMetricsRouter(config2) {
|
|
|
59454
60233
|
const sendMetrics = async () => {
|
|
59455
60234
|
try {
|
|
59456
60235
|
const timeRange = getTimeRange();
|
|
59457
|
-
|
|
60236
|
+
log64("Fetching metrics", {
|
|
59458
60237
|
start: timeRange.start.toISOString(),
|
|
59459
60238
|
end: timeRange.end.toISOString()
|
|
59460
60239
|
});
|
|
@@ -59467,7 +60246,7 @@ function createMetricsRouter(config2) {
|
|
|
59467
60246
|
),
|
|
59468
60247
|
fetchSendQuota(config2.roleArn, config2.region)
|
|
59469
60248
|
]);
|
|
59470
|
-
|
|
60249
|
+
log64("Metrics fetched successfully");
|
|
59471
60250
|
const data = {
|
|
59472
60251
|
type: "metrics",
|
|
59473
60252
|
timestamp: Date.now(),
|
|
@@ -59497,7 +60276,7 @@ function createMetricsRouter(config2) {
|
|
|
59497
60276
|
const interval = setInterval(sendMetrics, 6e4);
|
|
59498
60277
|
req.on("close", () => {
|
|
59499
60278
|
clearInterval(interval);
|
|
59500
|
-
|
|
60279
|
+
log64("SSE disconnected");
|
|
59501
60280
|
});
|
|
59502
60281
|
});
|
|
59503
60282
|
router.get("/snapshot", async (_req, res) => {
|
|
@@ -60892,7 +61671,7 @@ init_output();
|
|
|
60892
61671
|
init_pulumi();
|
|
60893
61672
|
async function dashboard(options) {
|
|
60894
61673
|
await ensurePulumiInstalled();
|
|
60895
|
-
|
|
61674
|
+
clack54.intro(pc57.bold("Wraps Dashboard"));
|
|
60896
61675
|
const progress = new DeploymentProgress();
|
|
60897
61676
|
const identity = await progress.execute(
|
|
60898
61677
|
"Validating AWS credentials",
|
|
@@ -60933,9 +61712,9 @@ async function dashboard(options) {
|
|
|
60933
61712
|
}
|
|
60934
61713
|
} catch (_error) {
|
|
60935
61714
|
progress.stop();
|
|
60936
|
-
|
|
61715
|
+
clack54.log.error("No Wraps infrastructure found");
|
|
60937
61716
|
console.log(
|
|
60938
|
-
`\\nRun ${
|
|
61717
|
+
`\\nRun ${pc57.cyan("wraps email init")}, ${pc57.cyan("wraps sms init")}, or ${pc57.cyan("wraps storage init")} to deploy infrastructure first.\\n`
|
|
60939
61718
|
);
|
|
60940
61719
|
process.exit(1);
|
|
60941
61720
|
}
|
|
@@ -60977,9 +61756,9 @@ async function dashboard(options) {
|
|
|
60977
61756
|
}
|
|
60978
61757
|
const port = options.port || await getPort({ port: [5555, 5556, 5557, 5558, 5559] });
|
|
60979
61758
|
progress.stop();
|
|
60980
|
-
|
|
61759
|
+
clack54.log.success("Starting dashboard server...");
|
|
60981
61760
|
console.log(
|
|
60982
|
-
`${
|
|
61761
|
+
`${pc57.dim("Using current AWS credentials (no role assumption)")}\\n`
|
|
60983
61762
|
);
|
|
60984
61763
|
const { url } = await startConsoleServer({
|
|
60985
61764
|
port,
|
|
@@ -61012,8 +61791,8 @@ async function dashboard(options) {
|
|
|
61012
61791
|
cdnCustomDomain,
|
|
61013
61792
|
cdnCertificateArn
|
|
61014
61793
|
});
|
|
61015
|
-
console.log(`\\n${
|
|
61016
|
-
console.log(`${
|
|
61794
|
+
console.log(`\\n${pc57.bold("Dashboard:")} ${pc57.cyan(url)}`);
|
|
61795
|
+
console.log(`${pc57.dim("Press Ctrl+C to stop")}\\n`);
|
|
61017
61796
|
getTelemetryClient().showFooterOnce();
|
|
61018
61797
|
if (!options.noOpen) {
|
|
61019
61798
|
await open3(url);
|
|
@@ -61034,8 +61813,8 @@ init_aws();
|
|
|
61034
61813
|
init_errors();
|
|
61035
61814
|
init_json_output();
|
|
61036
61815
|
init_metadata();
|
|
61037
|
-
import * as
|
|
61038
|
-
import
|
|
61816
|
+
import * as clack55 from "@clack/prompts";
|
|
61817
|
+
import pc58 from "picocolors";
|
|
61039
61818
|
async function destroy(options) {
|
|
61040
61819
|
trackCommand("destroy", { success: true });
|
|
61041
61820
|
if (isJsonMode() && !options.force) {
|
|
@@ -61046,9 +61825,9 @@ async function destroy(options) {
|
|
|
61046
61825
|
);
|
|
61047
61826
|
}
|
|
61048
61827
|
if (!isJsonMode()) {
|
|
61049
|
-
|
|
61828
|
+
clack55.intro(pc58.bold("Wraps Infrastructure Teardown"));
|
|
61050
61829
|
}
|
|
61051
|
-
const spinner11 =
|
|
61830
|
+
const spinner11 = clack55.spinner();
|
|
61052
61831
|
spinner11.start("Validating AWS credentials");
|
|
61053
61832
|
let identity;
|
|
61054
61833
|
try {
|
|
@@ -61065,17 +61844,17 @@ async function destroy(options) {
|
|
|
61065
61844
|
deployedServices.push("email");
|
|
61066
61845
|
}
|
|
61067
61846
|
if (deployedServices.length === 0) {
|
|
61068
|
-
|
|
61847
|
+
clack55.log.warn("No Wraps services found in this region");
|
|
61069
61848
|
console.log(
|
|
61070
61849
|
`
|
|
61071
|
-
Run ${
|
|
61850
|
+
Run ${pc58.cyan("wraps email init")} to deploy infrastructure.
|
|
61072
61851
|
`
|
|
61073
61852
|
);
|
|
61074
61853
|
process.exit(0);
|
|
61075
61854
|
}
|
|
61076
61855
|
if (deployedServices.length === 1) {
|
|
61077
61856
|
const service = deployedServices[0];
|
|
61078
|
-
|
|
61857
|
+
clack55.log.info(`Found ${pc58.cyan(service)} service deployed`);
|
|
61079
61858
|
if (service === "email") {
|
|
61080
61859
|
await emailDestroy(options);
|
|
61081
61860
|
return;
|
|
@@ -61090,7 +61869,7 @@ Run ${pc57.cyan("wraps email init")} to deploy infrastructure.
|
|
|
61090
61869
|
jsonSuccess("destroy", { destroyed: true });
|
|
61091
61870
|
return;
|
|
61092
61871
|
}
|
|
61093
|
-
const serviceToDestroy = await
|
|
61872
|
+
const serviceToDestroy = await clack55.select({
|
|
61094
61873
|
message: "Which service would you like to destroy?",
|
|
61095
61874
|
options: [
|
|
61096
61875
|
...deployedServices.map((s2) => ({
|
|
@@ -61105,15 +61884,15 @@ Run ${pc57.cyan("wraps email init")} to deploy infrastructure.
|
|
|
61105
61884
|
}
|
|
61106
61885
|
]
|
|
61107
61886
|
});
|
|
61108
|
-
if (
|
|
61109
|
-
|
|
61887
|
+
if (clack55.isCancel(serviceToDestroy)) {
|
|
61888
|
+
clack55.cancel("Operation cancelled.");
|
|
61110
61889
|
process.exit(0);
|
|
61111
61890
|
}
|
|
61112
61891
|
if ((serviceToDestroy === "email" || serviceToDestroy === "all") && deployedServices.includes("email")) {
|
|
61113
61892
|
await emailDestroy(options);
|
|
61114
61893
|
}
|
|
61115
61894
|
if (serviceToDestroy === "all") {
|
|
61116
|
-
|
|
61895
|
+
clack55.outro(pc58.green("All Wraps infrastructure has been removed"));
|
|
61117
61896
|
}
|
|
61118
61897
|
}
|
|
61119
61898
|
|
|
@@ -61125,26 +61904,26 @@ init_fs();
|
|
|
61125
61904
|
init_json_output();
|
|
61126
61905
|
init_output();
|
|
61127
61906
|
init_pulumi();
|
|
61128
|
-
import * as
|
|
61907
|
+
import * as clack56 from "@clack/prompts";
|
|
61129
61908
|
import * as pulumi32 from "@pulumi/pulumi";
|
|
61130
|
-
import
|
|
61909
|
+
import pc59 from "picocolors";
|
|
61131
61910
|
async function status(options) {
|
|
61132
61911
|
await ensurePulumiInstalled();
|
|
61133
61912
|
const startTime = Date.now();
|
|
61134
61913
|
const progress = new DeploymentProgress();
|
|
61135
61914
|
if (!isJsonMode()) {
|
|
61136
|
-
|
|
61915
|
+
clack56.intro(pc59.bold("Wraps Infrastructure Status"));
|
|
61137
61916
|
}
|
|
61138
61917
|
const identity = await progress.execute(
|
|
61139
61918
|
"Loading infrastructure status",
|
|
61140
61919
|
async () => validateAWSCredentials()
|
|
61141
61920
|
);
|
|
61142
61921
|
if (!isJsonMode()) {
|
|
61143
|
-
progress.info(`AWS Account: ${
|
|
61922
|
+
progress.info(`AWS Account: ${pc59.cyan(identity.accountId)}`);
|
|
61144
61923
|
}
|
|
61145
61924
|
const region = options.region || await getAWSRegion();
|
|
61146
61925
|
if (!isJsonMode()) {
|
|
61147
|
-
progress.info(`Region: ${
|
|
61926
|
+
progress.info(`Region: ${pc59.cyan(region)}`);
|
|
61148
61927
|
}
|
|
61149
61928
|
const services = [];
|
|
61150
61929
|
try {
|
|
@@ -61196,35 +61975,35 @@ async function status(options) {
|
|
|
61196
61975
|
return;
|
|
61197
61976
|
}
|
|
61198
61977
|
console.log();
|
|
61199
|
-
|
|
61978
|
+
clack56.note(
|
|
61200
61979
|
services.map((s2) => {
|
|
61201
61980
|
if (s2.status === "deployed") {
|
|
61202
|
-
const details = s2.details ?
|
|
61203
|
-
return ` ${
|
|
61981
|
+
const details = s2.details ? pc59.dim(` (${s2.details})`) : "";
|
|
61982
|
+
return ` ${pc59.green("\u2713")} ${s2.name}${details}`;
|
|
61204
61983
|
}
|
|
61205
|
-
return ` ${
|
|
61984
|
+
return ` ${pc59.dim("\u25CB")} ${s2.name} ${pc59.dim("(not deployed)")}`;
|
|
61206
61985
|
}).join("\n"),
|
|
61207
61986
|
"Services"
|
|
61208
61987
|
);
|
|
61209
61988
|
const hasDeployedServices = services.some((s2) => s2.status === "deployed");
|
|
61210
61989
|
if (hasDeployedServices) {
|
|
61211
61990
|
console.log(`
|
|
61212
|
-
${
|
|
61991
|
+
${pc59.bold("Details:")}`);
|
|
61213
61992
|
if (services.find((s2) => s2.name === "Email")?.status === "deployed") {
|
|
61214
|
-
console.log(` ${
|
|
61993
|
+
console.log(` ${pc59.dim("Email:")} ${pc59.cyan("wraps email status")}`);
|
|
61215
61994
|
}
|
|
61216
61995
|
if (services.find((s2) => s2.name === "SMS")?.status === "deployed") {
|
|
61217
|
-
console.log(` ${
|
|
61996
|
+
console.log(` ${pc59.dim("SMS:")} ${pc59.cyan("wraps sms status")}`);
|
|
61218
61997
|
}
|
|
61219
61998
|
} else {
|
|
61220
61999
|
console.log(`
|
|
61221
|
-
${
|
|
61222
|
-
console.log(` ${
|
|
61223
|
-
console.log(` ${
|
|
62000
|
+
${pc59.bold("Get started:")}`);
|
|
62001
|
+
console.log(` ${pc59.dim("Deploy email:")} ${pc59.cyan("wraps email init")}`);
|
|
62002
|
+
console.log(` ${pc59.dim("Deploy SMS:")} ${pc59.cyan("wraps sms init")}`);
|
|
61224
62003
|
}
|
|
61225
62004
|
console.log(`
|
|
61226
|
-
${
|
|
61227
|
-
console.log(`${
|
|
62005
|
+
${pc59.bold("Dashboard:")} ${pc59.blue("https://app.wraps.dev")}`);
|
|
62006
|
+
console.log(`${pc59.bold("Docs:")} ${pc59.blue("https://wraps.dev/docs")}
|
|
61228
62007
|
`);
|
|
61229
62008
|
trackCommand("status", {
|
|
61230
62009
|
success: true,
|
|
@@ -61235,9 +62014,9 @@ ${pc58.bold("Dashboard:")} ${pc58.blue("https://app.wraps.dev")}`);
|
|
|
61235
62014
|
|
|
61236
62015
|
// src/commands/sms/destroy.ts
|
|
61237
62016
|
init_esm_shims();
|
|
61238
|
-
import * as
|
|
62017
|
+
import * as clack57 from "@clack/prompts";
|
|
61239
62018
|
import * as pulumi34 from "@pulumi/pulumi";
|
|
61240
|
-
import
|
|
62019
|
+
import pc60 from "picocolors";
|
|
61241
62020
|
|
|
61242
62021
|
// src/infrastructure/sms-stack.ts
|
|
61243
62022
|
init_esm_shims();
|
|
@@ -61928,18 +62707,18 @@ async function createSMSProtectConfigurationWithSDK(configurationSetName, region
|
|
|
61928
62707
|
const existing = await client2.send(
|
|
61929
62708
|
new DescribeProtectConfigurationsCommand({})
|
|
61930
62709
|
);
|
|
61931
|
-
for (const
|
|
61932
|
-
if (!(
|
|
62710
|
+
for (const pc73 of existing.ProtectConfigurations || []) {
|
|
62711
|
+
if (!(pc73.ProtectConfigurationArn && pc73.ProtectConfigurationId)) {
|
|
61933
62712
|
continue;
|
|
61934
62713
|
}
|
|
61935
62714
|
const tagsResponse = await client2.send(
|
|
61936
62715
|
new ListTagsForResourceCommand({
|
|
61937
|
-
ResourceArn:
|
|
62716
|
+
ResourceArn: pc73.ProtectConfigurationArn
|
|
61938
62717
|
})
|
|
61939
62718
|
);
|
|
61940
62719
|
const nameTag = tagsResponse.Tags?.find((t) => t.Key === "Name");
|
|
61941
62720
|
if (nameTag?.Value === protectConfigName) {
|
|
61942
|
-
existingProtectConfigId =
|
|
62721
|
+
existingProtectConfigId = pc73.ProtectConfigurationId;
|
|
61943
62722
|
break;
|
|
61944
62723
|
}
|
|
61945
62724
|
}
|
|
@@ -62035,13 +62814,13 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
|
|
|
62035
62814
|
new DescribeProtectConfigurationsCommand({})
|
|
62036
62815
|
);
|
|
62037
62816
|
if (existing.ProtectConfigurations) {
|
|
62038
|
-
for (const
|
|
62039
|
-
if (!(
|
|
62817
|
+
for (const pc73 of existing.ProtectConfigurations) {
|
|
62818
|
+
if (!(pc73.ProtectConfigurationArn && pc73.ProtectConfigurationId)) {
|
|
62040
62819
|
continue;
|
|
62041
62820
|
}
|
|
62042
62821
|
const tagsResponse = await client2.send(
|
|
62043
62822
|
new ListTagsForResourceCommand({
|
|
62044
|
-
ResourceArn:
|
|
62823
|
+
ResourceArn: pc73.ProtectConfigurationArn
|
|
62045
62824
|
})
|
|
62046
62825
|
);
|
|
62047
62826
|
const isWrapsManaged = tagsResponse.Tags?.some(
|
|
@@ -62050,7 +62829,7 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
|
|
|
62050
62829
|
if (isWrapsManaged) {
|
|
62051
62830
|
await client2.send(
|
|
62052
62831
|
new DeleteProtectConfigurationCommand({
|
|
62053
|
-
ProtectConfigurationId:
|
|
62832
|
+
ProtectConfigurationId: pc73.ProtectConfigurationId
|
|
62054
62833
|
})
|
|
62055
62834
|
);
|
|
62056
62835
|
}
|
|
@@ -62085,8 +62864,8 @@ async function smsDestroy(options) {
|
|
|
62085
62864
|
);
|
|
62086
62865
|
}
|
|
62087
62866
|
if (!isJsonMode()) {
|
|
62088
|
-
|
|
62089
|
-
|
|
62867
|
+
clack57.intro(
|
|
62868
|
+
pc60.bold(
|
|
62090
62869
|
options.preview ? "SMS Infrastructure Destruction Preview" : "SMS Infrastructure Teardown"
|
|
62091
62870
|
)
|
|
62092
62871
|
);
|
|
@@ -62112,15 +62891,15 @@ async function smsDestroy(options) {
|
|
|
62112
62891
|
`Available regions: ${smsConnections.map((c6) => c6.region).join(", ")}`
|
|
62113
62892
|
);
|
|
62114
62893
|
}
|
|
62115
|
-
const selectedRegion = await
|
|
62894
|
+
const selectedRegion = await clack57.select({
|
|
62116
62895
|
message: "Multiple SMS deployments found. Which region to destroy?",
|
|
62117
62896
|
options: smsConnections.map((conn) => ({
|
|
62118
62897
|
value: conn.region,
|
|
62119
62898
|
label: conn.region
|
|
62120
62899
|
}))
|
|
62121
62900
|
});
|
|
62122
|
-
if (
|
|
62123
|
-
|
|
62901
|
+
if (clack57.isCancel(selectedRegion)) {
|
|
62902
|
+
clack57.cancel("Operation cancelled");
|
|
62124
62903
|
process.exit(0);
|
|
62125
62904
|
}
|
|
62126
62905
|
region = selectedRegion;
|
|
@@ -62131,18 +62910,18 @@ async function smsDestroy(options) {
|
|
|
62131
62910
|
const storedStackName = smsService?.pulumiStackName;
|
|
62132
62911
|
if (!smsService) {
|
|
62133
62912
|
progress.stop();
|
|
62134
|
-
|
|
62913
|
+
clack57.log.warn("No SMS infrastructure found");
|
|
62135
62914
|
process.exit(0);
|
|
62136
62915
|
}
|
|
62137
62916
|
if (!(options.force || options.preview)) {
|
|
62138
|
-
const confirmed = await
|
|
62139
|
-
message:
|
|
62917
|
+
const confirmed = await clack57.confirm({
|
|
62918
|
+
message: pc60.red(
|
|
62140
62919
|
"Are you sure you want to destroy all SMS infrastructure?"
|
|
62141
62920
|
),
|
|
62142
62921
|
initialValue: false
|
|
62143
62922
|
});
|
|
62144
|
-
if (
|
|
62145
|
-
|
|
62923
|
+
if (clack57.isCancel(confirmed) || !confirmed) {
|
|
62924
|
+
clack57.cancel("Destruction cancelled.");
|
|
62146
62925
|
process.exit(0);
|
|
62147
62926
|
}
|
|
62148
62927
|
}
|
|
@@ -62174,8 +62953,8 @@ async function smsDestroy(options) {
|
|
|
62174
62953
|
costEstimate: "Monthly cost after destruction: $0.00",
|
|
62175
62954
|
commandName: "wraps sms destroy"
|
|
62176
62955
|
});
|
|
62177
|
-
|
|
62178
|
-
|
|
62956
|
+
clack57.outro(
|
|
62957
|
+
pc60.green("Preview complete. Run without --preview to destroy.")
|
|
62179
62958
|
);
|
|
62180
62959
|
trackServiceRemoved("sms", {
|
|
62181
62960
|
preview: true,
|
|
@@ -62186,7 +62965,7 @@ async function smsDestroy(options) {
|
|
|
62186
62965
|
progress.stop();
|
|
62187
62966
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
62188
62967
|
if (errorMessage.includes("No SMS infrastructure found")) {
|
|
62189
|
-
|
|
62968
|
+
clack57.log.warn("No SMS infrastructure found to preview");
|
|
62190
62969
|
process.exit(0);
|
|
62191
62970
|
}
|
|
62192
62971
|
trackError("PREVIEW_FAILED", "sms destroy", { step: "preview" });
|
|
@@ -62235,7 +63014,7 @@ async function smsDestroy(options) {
|
|
|
62235
63014
|
progress.stop();
|
|
62236
63015
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
62237
63016
|
if (errorMessage.includes("No SMS infrastructure found")) {
|
|
62238
|
-
|
|
63017
|
+
clack57.log.warn("No SMS infrastructure found");
|
|
62239
63018
|
if (metadata) {
|
|
62240
63019
|
removeServiceFromConnection(metadata, "sms");
|
|
62241
63020
|
await saveConnectionMetadata(metadata);
|
|
@@ -62248,7 +63027,7 @@ async function smsDestroy(options) {
|
|
|
62248
63027
|
}
|
|
62249
63028
|
trackError("DESTROY_FAILED", "sms destroy", { step: "destroy" });
|
|
62250
63029
|
destroyFailed = true;
|
|
62251
|
-
|
|
63030
|
+
clack57.log.warn(
|
|
62252
63031
|
"Some resources may not have been fully removed. You can re-run this command or clean up manually in the AWS console."
|
|
62253
63032
|
);
|
|
62254
63033
|
}
|
|
@@ -62271,21 +63050,21 @@ async function smsDestroy(options) {
|
|
|
62271
63050
|
return;
|
|
62272
63051
|
}
|
|
62273
63052
|
if (destroyFailed) {
|
|
62274
|
-
|
|
62275
|
-
|
|
63053
|
+
clack57.outro(
|
|
63054
|
+
pc60.yellow("SMS infrastructure partially removed. Metadata cleaned up.")
|
|
62276
63055
|
);
|
|
62277
63056
|
} else {
|
|
62278
|
-
|
|
63057
|
+
clack57.outro(pc60.green("SMS infrastructure has been removed"));
|
|
62279
63058
|
console.log(`
|
|
62280
|
-
${
|
|
62281
|
-
console.log(` ${
|
|
62282
|
-
console.log(` ${
|
|
62283
|
-
console.log(` ${
|
|
62284
|
-
console.log(` ${
|
|
63059
|
+
${pc60.bold("Cleaned up:")}`);
|
|
63060
|
+
console.log(` ${pc60.green("\u2713")} Phone number released`);
|
|
63061
|
+
console.log(` ${pc60.green("\u2713")} Configuration set deleted`);
|
|
63062
|
+
console.log(` ${pc60.green("\u2713")} Event processing infrastructure removed`);
|
|
63063
|
+
console.log(` ${pc60.green("\u2713")} IAM role deleted`);
|
|
62285
63064
|
}
|
|
62286
63065
|
console.log(
|
|
62287
63066
|
`
|
|
62288
|
-
Run ${
|
|
63067
|
+
Run ${pc60.cyan("wraps sms init")} to deploy infrastructure again.
|
|
62289
63068
|
`
|
|
62290
63069
|
);
|
|
62291
63070
|
trackServiceRemoved("sms", {
|
|
@@ -62297,9 +63076,9 @@ Run ${pc59.cyan("wraps sms init")} to deploy infrastructure again.
|
|
|
62297
63076
|
|
|
62298
63077
|
// src/commands/sms/init.ts
|
|
62299
63078
|
init_esm_shims();
|
|
62300
|
-
import * as
|
|
63079
|
+
import * as clack58 from "@clack/prompts";
|
|
62301
63080
|
import * as pulumi35 from "@pulumi/pulumi";
|
|
62302
|
-
import
|
|
63081
|
+
import pc61 from "picocolors";
|
|
62303
63082
|
init_events();
|
|
62304
63083
|
init_aws();
|
|
62305
63084
|
init_fs();
|
|
@@ -62718,7 +63497,7 @@ function validateSMSConfig(config2) {
|
|
|
62718
63497
|
|
|
62719
63498
|
// src/commands/sms/init.ts
|
|
62720
63499
|
async function promptPhoneNumberType() {
|
|
62721
|
-
const result = await
|
|
63500
|
+
const result = await clack58.select({
|
|
62722
63501
|
message: "Select phone number type:",
|
|
62723
63502
|
options: [
|
|
62724
63503
|
{
|
|
@@ -62738,14 +63517,14 @@ async function promptPhoneNumberType() {
|
|
|
62738
63517
|
}
|
|
62739
63518
|
]
|
|
62740
63519
|
});
|
|
62741
|
-
if (
|
|
62742
|
-
|
|
63520
|
+
if (clack58.isCancel(result)) {
|
|
63521
|
+
clack58.cancel("Operation cancelled.");
|
|
62743
63522
|
process.exit(0);
|
|
62744
63523
|
}
|
|
62745
63524
|
return result;
|
|
62746
63525
|
}
|
|
62747
63526
|
async function promptSMSPreset() {
|
|
62748
|
-
const result = await
|
|
63527
|
+
const result = await clack58.select({
|
|
62749
63528
|
message: "Choose configuration preset:",
|
|
62750
63529
|
options: [
|
|
62751
63530
|
{
|
|
@@ -62770,8 +63549,8 @@ async function promptSMSPreset() {
|
|
|
62770
63549
|
}
|
|
62771
63550
|
]
|
|
62772
63551
|
});
|
|
62773
|
-
if (
|
|
62774
|
-
|
|
63552
|
+
if (clack58.isCancel(result)) {
|
|
63553
|
+
clack58.cancel("Operation cancelled.");
|
|
62775
63554
|
process.exit(0);
|
|
62776
63555
|
}
|
|
62777
63556
|
return result;
|
|
@@ -62791,7 +63570,7 @@ var COMMON_COUNTRIES = [
|
|
|
62791
63570
|
{ code: "IN", name: "India" }
|
|
62792
63571
|
];
|
|
62793
63572
|
async function promptAllowedCountries() {
|
|
62794
|
-
const result = await
|
|
63573
|
+
const result = await clack58.multiselect({
|
|
62795
63574
|
message: "Select countries to allow SMS delivery (blocks all others):",
|
|
62796
63575
|
options: COMMON_COUNTRIES.map((c6) => ({
|
|
62797
63576
|
value: c6.code,
|
|
@@ -62800,14 +63579,14 @@ async function promptAllowedCountries() {
|
|
|
62800
63579
|
initialValues: ["US"],
|
|
62801
63580
|
required: true
|
|
62802
63581
|
});
|
|
62803
|
-
if (
|
|
62804
|
-
|
|
63582
|
+
if (clack58.isCancel(result)) {
|
|
63583
|
+
clack58.cancel("Operation cancelled.");
|
|
62805
63584
|
process.exit(0);
|
|
62806
63585
|
}
|
|
62807
63586
|
return result;
|
|
62808
63587
|
}
|
|
62809
63588
|
async function promptEstimatedSMSVolume() {
|
|
62810
|
-
const result = await
|
|
63589
|
+
const result = await clack58.select({
|
|
62811
63590
|
message: "Estimated messages per month:",
|
|
62812
63591
|
options: [
|
|
62813
63592
|
{ value: 100, label: "< 100 (Testing)" },
|
|
@@ -62817,8 +63596,8 @@ async function promptEstimatedSMSVolume() {
|
|
|
62817
63596
|
{ value: 1e5, label: "50,000+" }
|
|
62818
63597
|
]
|
|
62819
63598
|
});
|
|
62820
|
-
if (
|
|
62821
|
-
|
|
63599
|
+
if (clack58.isCancel(result)) {
|
|
63600
|
+
clack58.cancel("Operation cancelled.");
|
|
62822
63601
|
process.exit(0);
|
|
62823
63602
|
}
|
|
62824
63603
|
return result;
|
|
@@ -62826,14 +63605,14 @@ async function promptEstimatedSMSVolume() {
|
|
|
62826
63605
|
async function init3(options) {
|
|
62827
63606
|
const startTime = Date.now();
|
|
62828
63607
|
if (!isJsonMode()) {
|
|
62829
|
-
|
|
63608
|
+
clack58.intro(pc61.bold("Wraps SMS Infrastructure Setup"));
|
|
62830
63609
|
}
|
|
62831
63610
|
const progress = new DeploymentProgress();
|
|
62832
63611
|
const identity = await progress.execute(
|
|
62833
63612
|
"Validating AWS credentials",
|
|
62834
63613
|
async () => validateAWSCredentials()
|
|
62835
63614
|
);
|
|
62836
|
-
progress.info(`Connected to AWS account: ${
|
|
63615
|
+
progress.info(`Connected to AWS account: ${pc61.cyan(identity.accountId)}`);
|
|
62837
63616
|
const wasAutoInstalled = await progress.execute(
|
|
62838
63617
|
"Checking Pulumi CLI installation",
|
|
62839
63618
|
async () => await ensurePulumiInstalled()
|
|
@@ -62852,10 +63631,10 @@ async function init3(options) {
|
|
|
62852
63631
|
region
|
|
62853
63632
|
);
|
|
62854
63633
|
if (existingConnection?.services?.sms) {
|
|
62855
|
-
|
|
62856
|
-
`SMS already configured for account ${
|
|
63634
|
+
clack58.log.warn(
|
|
63635
|
+
`SMS already configured for account ${pc61.cyan(identity.accountId)} in region ${pc61.cyan(region)}`
|
|
62857
63636
|
);
|
|
62858
|
-
|
|
63637
|
+
clack58.log.info(`Use ${pc61.cyan("wraps sms status")} to view current setup`);
|
|
62859
63638
|
process.exit(0);
|
|
62860
63639
|
}
|
|
62861
63640
|
let preset = options.preset;
|
|
@@ -62872,12 +63651,12 @@ async function init3(options) {
|
|
|
62872
63651
|
optOutManagement: true,
|
|
62873
63652
|
sendingEnabled: true
|
|
62874
63653
|
};
|
|
62875
|
-
const enableEventTracking = await
|
|
63654
|
+
const enableEventTracking = await clack58.confirm({
|
|
62876
63655
|
message: "Enable event tracking (EventBridge + DynamoDB)?",
|
|
62877
63656
|
initialValue: false
|
|
62878
63657
|
});
|
|
62879
|
-
if (
|
|
62880
|
-
|
|
63658
|
+
if (clack58.isCancel(enableEventTracking)) {
|
|
63659
|
+
clack58.cancel("Operation cancelled.");
|
|
62881
63660
|
process.exit(0);
|
|
62882
63661
|
}
|
|
62883
63662
|
if (enableEventTracking) {
|
|
@@ -62897,17 +63676,17 @@ async function init3(options) {
|
|
|
62897
63676
|
}
|
|
62898
63677
|
progress.info(
|
|
62899
63678
|
`
|
|
62900
|
-
${
|
|
63679
|
+
${pc61.bold("Fraud Protection")} - Block SMS to countries where you don't do business`
|
|
62901
63680
|
);
|
|
62902
63681
|
const allowedCountries = await promptAllowedCountries();
|
|
62903
63682
|
let aitFiltering = false;
|
|
62904
63683
|
if (smsConfig.phoneNumberType !== "simulator") {
|
|
62905
|
-
const enableAIT = await
|
|
63684
|
+
const enableAIT = await clack58.confirm({
|
|
62906
63685
|
message: "Enable AIT (Artificially Inflated Traffic) filtering? (adds per-message cost)",
|
|
62907
63686
|
initialValue: false
|
|
62908
63687
|
});
|
|
62909
|
-
if (
|
|
62910
|
-
|
|
63688
|
+
if (clack58.isCancel(enableAIT)) {
|
|
63689
|
+
clack58.cancel("Operation cancelled.");
|
|
62911
63690
|
process.exit(0);
|
|
62912
63691
|
}
|
|
62913
63692
|
aitFiltering = enableAIT;
|
|
@@ -62919,21 +63698,21 @@ ${pc60.bold("Fraud Protection")} - Block SMS to countries where you don't do bus
|
|
|
62919
63698
|
};
|
|
62920
63699
|
const estimatedVolume = await promptEstimatedSMSVolume();
|
|
62921
63700
|
progress.info(`
|
|
62922
|
-
${
|
|
63701
|
+
${pc61.bold("Cost Estimate:")}`);
|
|
62923
63702
|
const costSummary = getSMSCostSummary(smsConfig, estimatedVolume);
|
|
62924
|
-
|
|
63703
|
+
clack58.log.info(costSummary);
|
|
62925
63704
|
const warnings = validateSMSConfig(smsConfig);
|
|
62926
63705
|
if (warnings.length > 0) {
|
|
62927
63706
|
progress.info(`
|
|
62928
|
-
${
|
|
63707
|
+
${pc61.yellow(pc61.bold("Important Notes:"))}`);
|
|
62929
63708
|
for (const warning2 of warnings) {
|
|
62930
|
-
|
|
63709
|
+
clack58.log.warn(warning2);
|
|
62931
63710
|
}
|
|
62932
63711
|
}
|
|
62933
63712
|
if (!(options.yes || options.preview)) {
|
|
62934
63713
|
const confirmed = await confirmDeploy();
|
|
62935
63714
|
if (!confirmed) {
|
|
62936
|
-
|
|
63715
|
+
clack58.cancel("Deployment cancelled.");
|
|
62937
63716
|
process.exit(0);
|
|
62938
63717
|
}
|
|
62939
63718
|
}
|
|
@@ -62993,8 +63772,8 @@ ${pc60.yellow(pc60.bold("Important Notes:"))}`);
|
|
|
62993
63772
|
costEstimate: getSMSCostSummary(smsConfig, 0),
|
|
62994
63773
|
commandName: "wraps sms init"
|
|
62995
63774
|
});
|
|
62996
|
-
|
|
62997
|
-
|
|
63775
|
+
clack58.outro(
|
|
63776
|
+
pc61.green("Preview complete. Run without --preview to deploy.")
|
|
62998
63777
|
);
|
|
62999
63778
|
trackServiceInit("sms", true, {
|
|
63000
63779
|
provider,
|
|
@@ -63043,9 +63822,9 @@ ${pc60.yellow(pc60.bold("Important Notes:"))}`);
|
|
|
63043
63822
|
} catch (sdkError) {
|
|
63044
63823
|
sdkResourceWarning = true;
|
|
63045
63824
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
63046
|
-
|
|
63047
|
-
|
|
63048
|
-
`Run ${
|
|
63825
|
+
clack58.log.warn(`Phone pool creation failed: ${msg}`);
|
|
63826
|
+
clack58.log.info(
|
|
63827
|
+
`Run ${pc61.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
63049
63828
|
);
|
|
63050
63829
|
}
|
|
63051
63830
|
}
|
|
@@ -63061,9 +63840,9 @@ ${pc60.yellow(pc60.bold("Important Notes:"))}`);
|
|
|
63061
63840
|
} catch (sdkError) {
|
|
63062
63841
|
sdkResourceWarning = true;
|
|
63063
63842
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
63064
|
-
|
|
63065
|
-
|
|
63066
|
-
`Run ${
|
|
63843
|
+
clack58.log.warn(`Event destination creation failed: ${msg}`);
|
|
63844
|
+
clack58.log.info(
|
|
63845
|
+
`Run ${pc61.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
63067
63846
|
);
|
|
63068
63847
|
}
|
|
63069
63848
|
}
|
|
@@ -63082,14 +63861,14 @@ ${pc60.yellow(pc60.bold("Important Notes:"))}`);
|
|
|
63082
63861
|
} catch (sdkError) {
|
|
63083
63862
|
sdkResourceWarning = true;
|
|
63084
63863
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
63085
|
-
|
|
63086
|
-
|
|
63087
|
-
`Run ${
|
|
63864
|
+
clack58.log.warn(`Protect configuration creation failed: ${msg}`);
|
|
63865
|
+
clack58.log.info(
|
|
63866
|
+
`Run ${pc61.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
63088
63867
|
);
|
|
63089
63868
|
}
|
|
63090
63869
|
}
|
|
63091
63870
|
if (sdkResourceWarning) {
|
|
63092
|
-
|
|
63871
|
+
clack58.log.warn(
|
|
63093
63872
|
"Some SDK resources failed to create. Core infrastructure is deployed."
|
|
63094
63873
|
);
|
|
63095
63874
|
}
|
|
@@ -63134,47 +63913,47 @@ ${pc60.yellow(pc60.bold("Important Notes:"))}`);
|
|
|
63134
63913
|
return;
|
|
63135
63914
|
}
|
|
63136
63915
|
console.log("\n");
|
|
63137
|
-
|
|
63916
|
+
clack58.log.success(pc61.green(pc61.bold("SMS infrastructure deployed!")));
|
|
63138
63917
|
console.log("\n");
|
|
63139
|
-
|
|
63918
|
+
clack58.note(
|
|
63140
63919
|
[
|
|
63141
|
-
`${
|
|
63142
|
-
`${
|
|
63143
|
-
`${
|
|
63144
|
-
`${
|
|
63145
|
-
outputs.tableName ? `${
|
|
63920
|
+
`${pc61.bold("Phone Number:")} ${pc61.cyan(outputs.phoneNumber || "Provisioning...")}`,
|
|
63921
|
+
`${pc61.bold("Phone Type:")} ${pc61.cyan(smsConfig.phoneNumberType || "simulator")}`,
|
|
63922
|
+
`${pc61.bold("Config Set:")} ${pc61.cyan(outputs.configSetName || "wraps-sms-config")}`,
|
|
63923
|
+
`${pc61.bold("Region:")} ${pc61.cyan(outputs.region)}`,
|
|
63924
|
+
outputs.tableName ? `${pc61.bold("History Table:")} ${pc61.cyan(outputs.tableName)}` : "",
|
|
63146
63925
|
"",
|
|
63147
|
-
|
|
63148
|
-
|
|
63926
|
+
pc61.dim("IAM Role:"),
|
|
63927
|
+
pc61.dim(` ${outputs.roleArn}`)
|
|
63149
63928
|
].filter(Boolean).join("\n"),
|
|
63150
63929
|
"SMS Infrastructure"
|
|
63151
63930
|
);
|
|
63152
63931
|
const nextSteps = [];
|
|
63153
63932
|
if (smsConfig.phoneNumberType === "toll-free") {
|
|
63154
63933
|
nextSteps.push(
|
|
63155
|
-
`${
|
|
63934
|
+
`${pc61.cyan("wraps sms register")} - Submit toll-free registration (required before sending)`
|
|
63156
63935
|
);
|
|
63157
63936
|
}
|
|
63158
63937
|
nextSteps.push(
|
|
63159
|
-
`${
|
|
63938
|
+
`${pc61.cyan("wraps sms test --to +1234567890")} - Send a test message`
|
|
63160
63939
|
);
|
|
63161
|
-
nextSteps.push(`${
|
|
63940
|
+
nextSteps.push(`${pc61.cyan("wraps sms status")} - View SMS configuration`);
|
|
63162
63941
|
console.log("\n");
|
|
63163
|
-
|
|
63942
|
+
clack58.log.info(pc61.bold("Next steps:"));
|
|
63164
63943
|
for (const step of nextSteps) {
|
|
63165
63944
|
console.log(` ${step}`);
|
|
63166
63945
|
}
|
|
63167
63946
|
console.log("\n");
|
|
63168
|
-
|
|
63169
|
-
console.log(
|
|
63947
|
+
clack58.log.info(pc61.bold("SDK Usage:"));
|
|
63948
|
+
console.log(pc61.dim(" npm install @wraps.dev/sms"));
|
|
63170
63949
|
console.log("");
|
|
63171
|
-
console.log(
|
|
63172
|
-
console.log(
|
|
63173
|
-
console.log(
|
|
63174
|
-
console.log(
|
|
63175
|
-
console.log(
|
|
63176
|
-
console.log(
|
|
63177
|
-
|
|
63950
|
+
console.log(pc61.dim(" import { Wraps } from '@wraps.dev/sms';"));
|
|
63951
|
+
console.log(pc61.dim(" const wraps = new Wraps();"));
|
|
63952
|
+
console.log(pc61.dim(" await wraps.sms.send({"));
|
|
63953
|
+
console.log(pc61.dim(" to: '+14155551234',"));
|
|
63954
|
+
console.log(pc61.dim(" message: 'Your code is 123456',"));
|
|
63955
|
+
console.log(pc61.dim(" });"));
|
|
63956
|
+
clack58.outro(pc61.green("Setup complete!"));
|
|
63178
63957
|
const duration = Date.now() - startTime;
|
|
63179
63958
|
const enabledFeatures = [];
|
|
63180
63959
|
if (smsConfig.tracking?.enabled) {
|
|
@@ -63210,8 +63989,8 @@ init_aws();
|
|
|
63210
63989
|
init_json_output();
|
|
63211
63990
|
init_metadata();
|
|
63212
63991
|
init_output();
|
|
63213
|
-
import * as
|
|
63214
|
-
import
|
|
63992
|
+
import * as clack59 from "@clack/prompts";
|
|
63993
|
+
import pc62 from "picocolors";
|
|
63215
63994
|
async function getPhoneNumberDetails(region) {
|
|
63216
63995
|
const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePhoneNumbersCommand: DescribePhoneNumbersCommand2 } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
|
|
63217
63996
|
const client2 = new PinpointSMSVoiceV2Client5({ region });
|
|
@@ -63231,7 +64010,7 @@ async function getPhoneNumberDetails(region) {
|
|
|
63231
64010
|
return null;
|
|
63232
64011
|
} catch (error) {
|
|
63233
64012
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
63234
|
-
|
|
64013
|
+
clack59.log.error(`Error fetching phone number: ${errorMessage}`);
|
|
63235
64014
|
return null;
|
|
63236
64015
|
}
|
|
63237
64016
|
}
|
|
@@ -63252,7 +64031,7 @@ async function getRegistrationStatus(region, registrationId) {
|
|
|
63252
64031
|
async function smsRegister(options) {
|
|
63253
64032
|
const startTime = Date.now();
|
|
63254
64033
|
if (!isJsonMode()) {
|
|
63255
|
-
|
|
64034
|
+
clack59.intro(pc62.bold("Wraps SMS - Toll-Free Registration"));
|
|
63256
64035
|
}
|
|
63257
64036
|
const progress = new DeploymentProgress();
|
|
63258
64037
|
const identity = await progress.execute(
|
|
@@ -63265,8 +64044,8 @@ async function smsRegister(options) {
|
|
|
63265
64044
|
}
|
|
63266
64045
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
63267
64046
|
if (!metadata?.services?.sms) {
|
|
63268
|
-
|
|
63269
|
-
|
|
64047
|
+
clack59.log.error("No SMS infrastructure found.");
|
|
64048
|
+
clack59.log.info(`Run ${pc62.cyan("wraps sms init")} first.`);
|
|
63270
64049
|
process.exit(1);
|
|
63271
64050
|
}
|
|
63272
64051
|
const phoneDetails = await progress.execute(
|
|
@@ -63274,7 +64053,7 @@ async function smsRegister(options) {
|
|
|
63274
64053
|
async () => getPhoneNumberDetails(region)
|
|
63275
64054
|
);
|
|
63276
64055
|
if (!phoneDetails) {
|
|
63277
|
-
|
|
64056
|
+
clack59.log.error("No phone number found.");
|
|
63278
64057
|
process.exit(1);
|
|
63279
64058
|
}
|
|
63280
64059
|
let registrationStatus = null;
|
|
@@ -63300,53 +64079,53 @@ async function smsRegister(options) {
|
|
|
63300
64079
|
}
|
|
63301
64080
|
console.log("");
|
|
63302
64081
|
console.log(
|
|
63303
|
-
`${
|
|
64082
|
+
`${pc62.bold("Phone Number:")} ${pc62.cyan(phoneDetails.phoneNumber)}`
|
|
63304
64083
|
);
|
|
63305
|
-
console.log(`${
|
|
64084
|
+
console.log(`${pc62.bold("Type:")} ${pc62.cyan(phoneDetails.type)}`);
|
|
63306
64085
|
console.log(
|
|
63307
|
-
`${
|
|
64086
|
+
`${pc62.bold("Status:")} ${phoneDetails.status === "ACTIVE" ? pc62.green(phoneDetails.status) : pc62.yellow(phoneDetails.status)}`
|
|
63308
64087
|
);
|
|
63309
64088
|
if (registrationStatus) {
|
|
63310
|
-
console.log(`${
|
|
64089
|
+
console.log(`${pc62.bold("Registration:")} ${pc62.cyan(registrationStatus)}`);
|
|
63311
64090
|
}
|
|
63312
64091
|
console.log("");
|
|
63313
64092
|
if (phoneDetails.status === "ACTIVE") {
|
|
63314
|
-
|
|
64093
|
+
clack59.log.success("Your phone number is already ACTIVE and ready to use!");
|
|
63315
64094
|
const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePoolsCommand } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
|
|
63316
64095
|
const client2 = new PinpointSMSVoiceV2Client5({ region });
|
|
63317
64096
|
const pools = await client2.send(new DescribePoolsCommand({}));
|
|
63318
64097
|
if (!pools.Pools?.length) {
|
|
63319
|
-
|
|
64098
|
+
clack59.log.info("Run `wraps sms sync` to create the phone pool.");
|
|
63320
64099
|
}
|
|
63321
64100
|
process.exit(0);
|
|
63322
64101
|
}
|
|
63323
64102
|
if (phoneDetails.type !== "TOLL_FREE") {
|
|
63324
|
-
|
|
63325
|
-
|
|
64103
|
+
clack59.log.info("Only toll-free numbers require registration.");
|
|
64104
|
+
clack59.log.info(`Your ${phoneDetails.type} number should be ready to use.`);
|
|
63326
64105
|
process.exit(0);
|
|
63327
64106
|
}
|
|
63328
|
-
console.log(
|
|
64107
|
+
console.log(pc62.bold("Toll-Free Registration Required"));
|
|
63329
64108
|
console.log("");
|
|
63330
64109
|
console.log(
|
|
63331
|
-
|
|
64110
|
+
pc62.dim("To send SMS at scale, you must register your toll-free number.")
|
|
63332
64111
|
);
|
|
63333
|
-
console.log(
|
|
64112
|
+
console.log(pc62.dim("This process typically takes 1-15 business days."));
|
|
63334
64113
|
console.log("");
|
|
63335
|
-
console.log(
|
|
63336
|
-
console.log(` ${
|
|
64114
|
+
console.log(pc62.bold("You'll need to provide:"));
|
|
64115
|
+
console.log(` ${pc62.dim("\u2022")} Business name and address`);
|
|
63337
64116
|
console.log(
|
|
63338
|
-
` ${
|
|
64117
|
+
` ${pc62.dim("\u2022")} Use case description (what messages you're sending)`
|
|
63339
64118
|
);
|
|
63340
|
-
console.log(` ${
|
|
63341
|
-
console.log(` ${
|
|
63342
|
-
console.log(` ${
|
|
64119
|
+
console.log(` ${pc62.dim("\u2022")} Sample messages (2-3 examples)`);
|
|
64120
|
+
console.log(` ${pc62.dim("\u2022")} How users opt-in to receive messages`);
|
|
64121
|
+
console.log(` ${pc62.dim("\u2022")} Expected monthly message volume`);
|
|
63343
64122
|
console.log("");
|
|
63344
|
-
const openConsole = await
|
|
64123
|
+
const openConsole = await clack59.confirm({
|
|
63345
64124
|
message: "Open AWS Console to start registration?",
|
|
63346
64125
|
initialValue: true
|
|
63347
64126
|
});
|
|
63348
|
-
if (
|
|
63349
|
-
|
|
64127
|
+
if (clack59.isCancel(openConsole)) {
|
|
64128
|
+
clack59.cancel("Registration cancelled.");
|
|
63350
64129
|
process.exit(0);
|
|
63351
64130
|
}
|
|
63352
64131
|
if (openConsole) {
|
|
@@ -63356,41 +64135,41 @@ async function smsRegister(options) {
|
|
|
63356
64135
|
const execAsync2 = promisify3(exec3);
|
|
63357
64136
|
try {
|
|
63358
64137
|
await execAsync2(`open "${consoleUrl}"`);
|
|
63359
|
-
|
|
64138
|
+
clack59.log.success("Opened AWS Console in your browser.");
|
|
63360
64139
|
} catch {
|
|
63361
64140
|
try {
|
|
63362
64141
|
await execAsync2(`xdg-open "${consoleUrl}"`);
|
|
63363
|
-
|
|
64142
|
+
clack59.log.success("Opened AWS Console in your browser.");
|
|
63364
64143
|
} catch {
|
|
63365
|
-
|
|
64144
|
+
clack59.log.info("Open this URL in your browser:");
|
|
63366
64145
|
console.log(`
|
|
63367
|
-
${
|
|
64146
|
+
${pc62.cyan(consoleUrl)}
|
|
63368
64147
|
`);
|
|
63369
64148
|
}
|
|
63370
64149
|
}
|
|
63371
64150
|
console.log("");
|
|
63372
|
-
console.log(
|
|
64151
|
+
console.log(pc62.bold("Next Steps:"));
|
|
63373
64152
|
console.log(
|
|
63374
|
-
` 1. Click ${
|
|
64153
|
+
` 1. Click ${pc62.cyan("Create registration")} in the AWS Console`
|
|
63375
64154
|
);
|
|
63376
|
-
console.log(` 2. Select ${
|
|
64155
|
+
console.log(` 2. Select ${pc62.cyan("Toll-free number registration")}`);
|
|
63377
64156
|
console.log(" 3. Fill out the business information form");
|
|
63378
64157
|
console.log(" 4. Submit and wait for approval (1-15 business days)");
|
|
63379
64158
|
console.log("");
|
|
63380
64159
|
console.log(
|
|
63381
|
-
|
|
64160
|
+
pc62.dim("Once approved, run `wraps sms sync` to complete setup.")
|
|
63382
64161
|
);
|
|
63383
64162
|
} else {
|
|
63384
64163
|
const consoleUrl = `https://${region}.console.aws.amazon.com/sms-voice/home?region=${region}#/registrations`;
|
|
63385
64164
|
console.log("");
|
|
63386
64165
|
console.log("When you're ready, go to:");
|
|
63387
|
-
console.log(` ${
|
|
64166
|
+
console.log(` ${pc62.cyan(consoleUrl)}`);
|
|
63388
64167
|
}
|
|
63389
64168
|
trackCommand("sms:register", {
|
|
63390
64169
|
success: true,
|
|
63391
64170
|
duration_ms: Date.now() - startTime
|
|
63392
64171
|
});
|
|
63393
|
-
|
|
64172
|
+
clack59.outro(pc62.dim("Good luck with your registration!"));
|
|
63394
64173
|
}
|
|
63395
64174
|
|
|
63396
64175
|
// src/commands/sms/status.ts
|
|
@@ -63403,54 +64182,54 @@ init_metadata();
|
|
|
63403
64182
|
init_output();
|
|
63404
64183
|
init_pulumi();
|
|
63405
64184
|
init_region_resolver();
|
|
63406
|
-
import * as
|
|
64185
|
+
import * as clack60 from "@clack/prompts";
|
|
63407
64186
|
import * as pulumi36 from "@pulumi/pulumi";
|
|
63408
|
-
import
|
|
64187
|
+
import pc63 from "picocolors";
|
|
63409
64188
|
function displaySMSStatus(options) {
|
|
63410
64189
|
const lines = [];
|
|
63411
|
-
lines.push(
|
|
64190
|
+
lines.push(pc63.bold(pc63.green("SMS Infrastructure Active")));
|
|
63412
64191
|
lines.push("");
|
|
63413
|
-
lines.push(
|
|
64192
|
+
lines.push(pc63.bold("Phone Number"));
|
|
63414
64193
|
if (options.phoneNumber) {
|
|
63415
|
-
lines.push(` Number: ${
|
|
64194
|
+
lines.push(` Number: ${pc63.cyan(options.phoneNumber)}`);
|
|
63416
64195
|
} else {
|
|
63417
|
-
lines.push(` Number: ${
|
|
64196
|
+
lines.push(` Number: ${pc63.yellow("Provisioning...")}`);
|
|
63418
64197
|
}
|
|
63419
|
-
lines.push(` Type: ${
|
|
64198
|
+
lines.push(` Type: ${pc63.cyan(options.phoneNumberType || "simulator")}`);
|
|
63420
64199
|
lines.push("");
|
|
63421
|
-
lines.push(
|
|
63422
|
-
lines.push(` Region: ${
|
|
64200
|
+
lines.push(pc63.bold("Configuration"));
|
|
64201
|
+
lines.push(` Region: ${pc63.cyan(options.region)}`);
|
|
63423
64202
|
if (options.preset) {
|
|
63424
|
-
lines.push(` Preset: ${
|
|
64203
|
+
lines.push(` Preset: ${pc63.cyan(options.preset)}`);
|
|
63425
64204
|
}
|
|
63426
64205
|
if (options.configSetName) {
|
|
63427
|
-
lines.push(` Config Set: ${
|
|
64206
|
+
lines.push(` Config Set: ${pc63.cyan(options.configSetName)}`);
|
|
63428
64207
|
}
|
|
63429
64208
|
lines.push("");
|
|
63430
|
-
lines.push(
|
|
64209
|
+
lines.push(pc63.bold("Features"));
|
|
63431
64210
|
lines.push(
|
|
63432
|
-
` Event Tracking: ${options.eventTracking ?
|
|
64211
|
+
` Event Tracking: ${options.eventTracking ? pc63.green("Enabled") : pc63.dim("Disabled")}`
|
|
63433
64212
|
);
|
|
63434
64213
|
if (options.tableName) {
|
|
63435
|
-
lines.push(` Message History: ${
|
|
63436
|
-
lines.push(` Table: ${
|
|
64214
|
+
lines.push(` Message History: ${pc63.green("Enabled")}`);
|
|
64215
|
+
lines.push(` Table: ${pc63.dim(options.tableName)}`);
|
|
63437
64216
|
}
|
|
63438
64217
|
if (options.queueUrl) {
|
|
63439
|
-
lines.push(` Event Queue: ${
|
|
64218
|
+
lines.push(` Event Queue: ${pc63.green("Enabled")}`);
|
|
63440
64219
|
}
|
|
63441
64220
|
lines.push("");
|
|
63442
64221
|
if (options.roleArn) {
|
|
63443
|
-
lines.push(
|
|
63444
|
-
lines.push(` ${
|
|
64222
|
+
lines.push(pc63.bold("IAM Role"));
|
|
64223
|
+
lines.push(` ${pc63.dim(options.roleArn)}`);
|
|
63445
64224
|
}
|
|
63446
|
-
|
|
64225
|
+
clack60.note(lines.join("\n"), "SMS Status");
|
|
63447
64226
|
}
|
|
63448
64227
|
async function smsStatus(options) {
|
|
63449
64228
|
await ensurePulumiInstalled();
|
|
63450
64229
|
const startTime = Date.now();
|
|
63451
64230
|
const progress = new DeploymentProgress();
|
|
63452
64231
|
if (!isJsonMode()) {
|
|
63453
|
-
|
|
64232
|
+
clack60.intro(pc63.bold("Wraps SMS Status"));
|
|
63454
64233
|
}
|
|
63455
64234
|
const identity = await progress.execute(
|
|
63456
64235
|
"Loading SMS infrastructure status",
|
|
@@ -63465,10 +64244,10 @@ async function smsStatus(options) {
|
|
|
63465
64244
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
63466
64245
|
if (!metadata?.services?.sms) {
|
|
63467
64246
|
progress.stop();
|
|
63468
|
-
|
|
64247
|
+
clack60.log.error("No SMS infrastructure found");
|
|
63469
64248
|
console.log(
|
|
63470
64249
|
`
|
|
63471
|
-
Run ${
|
|
64250
|
+
Run ${pc63.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
63472
64251
|
`
|
|
63473
64252
|
);
|
|
63474
64253
|
process.exit(1);
|
|
@@ -63504,25 +64283,25 @@ Run ${pc62.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
63504
64283
|
}
|
|
63505
64284
|
displaySMSStatus(smsStatusData);
|
|
63506
64285
|
console.log("");
|
|
63507
|
-
|
|
64286
|
+
clack60.log.info(pc63.bold("Commands:"));
|
|
63508
64287
|
console.log(
|
|
63509
|
-
` ${
|
|
64288
|
+
` ${pc63.cyan("wraps sms test --to +1234567890")} - Send a test message`
|
|
63510
64289
|
);
|
|
63511
|
-
console.log(` ${
|
|
64290
|
+
console.log(` ${pc63.cyan("wraps sms destroy")} - Remove SMS infrastructure`);
|
|
63512
64291
|
trackCommand("sms:status", {
|
|
63513
64292
|
success: true,
|
|
63514
64293
|
phone_type: smsConfig?.phoneNumberType,
|
|
63515
64294
|
event_tracking: smsConfig?.eventTracking?.enabled,
|
|
63516
64295
|
duration_ms: Date.now() - startTime
|
|
63517
64296
|
});
|
|
63518
|
-
|
|
64297
|
+
clack60.outro(pc63.dim("SMS infrastructure is ready"));
|
|
63519
64298
|
}
|
|
63520
64299
|
|
|
63521
64300
|
// src/commands/sms/sync.ts
|
|
63522
64301
|
init_esm_shims();
|
|
63523
|
-
import * as
|
|
64302
|
+
import * as clack61 from "@clack/prompts";
|
|
63524
64303
|
import * as pulumi37 from "@pulumi/pulumi";
|
|
63525
|
-
import
|
|
64304
|
+
import pc64 from "picocolors";
|
|
63526
64305
|
init_events();
|
|
63527
64306
|
init_aws();
|
|
63528
64307
|
init_errors();
|
|
@@ -63535,7 +64314,7 @@ async function smsSync(options) {
|
|
|
63535
64314
|
await ensurePulumiInstalled();
|
|
63536
64315
|
const startTime = Date.now();
|
|
63537
64316
|
if (!isJsonMode()) {
|
|
63538
|
-
|
|
64317
|
+
clack61.intro(pc64.bold("Wraps SMS Infrastructure Sync"));
|
|
63539
64318
|
}
|
|
63540
64319
|
const progress = new DeploymentProgress();
|
|
63541
64320
|
const identity = await progress.execute(
|
|
@@ -63547,10 +64326,10 @@ async function smsSync(options) {
|
|
|
63547
64326
|
const smsService = metadata?.services?.sms;
|
|
63548
64327
|
if (!smsService?.config) {
|
|
63549
64328
|
progress.stop();
|
|
63550
|
-
|
|
64329
|
+
clack61.log.error("No SMS infrastructure found to sync");
|
|
63551
64330
|
console.log(
|
|
63552
64331
|
`
|
|
63553
|
-
Run ${
|
|
64332
|
+
Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
63554
64333
|
`
|
|
63555
64334
|
);
|
|
63556
64335
|
process.exit(1);
|
|
@@ -63559,18 +64338,18 @@ Run ${pc63.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
63559
64338
|
const storedStackName = smsService.pulumiStackName;
|
|
63560
64339
|
progress.info("Found existing SMS configuration");
|
|
63561
64340
|
progress.info(
|
|
63562
|
-
`Phone type: ${
|
|
64341
|
+
`Phone type: ${pc64.cyan(smsConfig.phoneNumberType || "simulator")}`
|
|
63563
64342
|
);
|
|
63564
64343
|
progress.info(
|
|
63565
|
-
`Event tracking: ${
|
|
64344
|
+
`Event tracking: ${pc64.cyan(smsConfig.eventTracking?.enabled ? "enabled" : "disabled")}`
|
|
63566
64345
|
);
|
|
63567
64346
|
if (!options.yes) {
|
|
63568
|
-
const confirmed = await
|
|
64347
|
+
const confirmed = await clack61.confirm({
|
|
63569
64348
|
message: "Sync SMS infrastructure? This will update Lambda code and recreate any missing resources.",
|
|
63570
64349
|
initialValue: true
|
|
63571
64350
|
});
|
|
63572
|
-
if (
|
|
63573
|
-
|
|
64351
|
+
if (clack61.isCancel(confirmed) || !confirmed) {
|
|
64352
|
+
clack61.cancel("Sync cancelled.");
|
|
63574
64353
|
process.exit(0);
|
|
63575
64354
|
}
|
|
63576
64355
|
}
|
|
@@ -63675,7 +64454,7 @@ Run ${pc63.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
63675
64454
|
throw errors.stackLocked();
|
|
63676
64455
|
}
|
|
63677
64456
|
trackError("SYNC_FAILED", "sms:sync", { step: "sync" });
|
|
63678
|
-
|
|
64457
|
+
clack61.log.error(`SMS sync failed: ${errorMessage}`);
|
|
63679
64458
|
process.exit(1);
|
|
63680
64459
|
}
|
|
63681
64460
|
if (metadata && smsService) {
|
|
@@ -63695,7 +64474,7 @@ Run ${pc63.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
63695
64474
|
return;
|
|
63696
64475
|
}
|
|
63697
64476
|
console.log("\n");
|
|
63698
|
-
|
|
64477
|
+
clack61.log.success(pc64.green("SMS infrastructure synced successfully!"));
|
|
63699
64478
|
const changes = [];
|
|
63700
64479
|
if (outputs.lambdaFunctions?.length) {
|
|
63701
64480
|
changes.push("Lambda functions updated");
|
|
@@ -63703,13 +64482,13 @@ Run ${pc63.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
63703
64482
|
changes.push("SDK resources verified");
|
|
63704
64483
|
console.log("");
|
|
63705
64484
|
for (const change of changes) {
|
|
63706
|
-
console.log(` ${
|
|
64485
|
+
console.log(` ${pc64.green("\u2713")} ${change}`);
|
|
63707
64486
|
}
|
|
63708
64487
|
trackCommand("sms:sync", {
|
|
63709
64488
|
success: true,
|
|
63710
64489
|
duration_ms: Date.now() - startTime
|
|
63711
64490
|
});
|
|
63712
|
-
|
|
64491
|
+
clack61.outro(pc64.green("Sync complete!"));
|
|
63713
64492
|
}
|
|
63714
64493
|
|
|
63715
64494
|
// src/commands/sms/test.ts
|
|
@@ -63724,8 +64503,8 @@ import {
|
|
|
63724
64503
|
PinpointSMSVoiceV2Client as PinpointSMSVoiceV2Client3,
|
|
63725
64504
|
SendTextMessageCommand
|
|
63726
64505
|
} from "@aws-sdk/client-pinpoint-sms-voice-v2";
|
|
63727
|
-
import * as
|
|
63728
|
-
import
|
|
64506
|
+
import * as clack62 from "@clack/prompts";
|
|
64507
|
+
import pc65 from "picocolors";
|
|
63729
64508
|
|
|
63730
64509
|
// src/utils/sms/validation.ts
|
|
63731
64510
|
init_esm_shims();
|
|
@@ -63748,7 +64527,7 @@ async function smsTest(options) {
|
|
|
63748
64527
|
const startTime = Date.now();
|
|
63749
64528
|
const progress = new DeploymentProgress();
|
|
63750
64529
|
if (!isJsonMode()) {
|
|
63751
|
-
|
|
64530
|
+
clack62.intro(pc65.bold("Wraps SMS Test"));
|
|
63752
64531
|
}
|
|
63753
64532
|
const identity = await progress.execute(
|
|
63754
64533
|
"Validating AWS credentials",
|
|
@@ -63758,10 +64537,10 @@ async function smsTest(options) {
|
|
|
63758
64537
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
63759
64538
|
if (!metadata?.services?.sms) {
|
|
63760
64539
|
progress.stop();
|
|
63761
|
-
|
|
64540
|
+
clack62.log.error("No SMS infrastructure found");
|
|
63762
64541
|
console.log(
|
|
63763
64542
|
`
|
|
63764
|
-
Run ${
|
|
64543
|
+
Run ${pc65.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
63765
64544
|
`
|
|
63766
64545
|
);
|
|
63767
64546
|
process.exit(1);
|
|
@@ -63775,7 +64554,7 @@ Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
63775
64554
|
);
|
|
63776
64555
|
}
|
|
63777
64556
|
if (!toNumber) {
|
|
63778
|
-
const destinationType = await
|
|
64557
|
+
const destinationType = await clack62.select({
|
|
63779
64558
|
message: "Choose destination number:",
|
|
63780
64559
|
options: [
|
|
63781
64560
|
{
|
|
@@ -63790,25 +64569,25 @@ Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
63790
64569
|
}
|
|
63791
64570
|
]
|
|
63792
64571
|
});
|
|
63793
|
-
if (
|
|
63794
|
-
|
|
64572
|
+
if (clack62.isCancel(destinationType)) {
|
|
64573
|
+
clack62.cancel("Operation cancelled.");
|
|
63795
64574
|
process.exit(0);
|
|
63796
64575
|
}
|
|
63797
64576
|
if (destinationType === "simulator") {
|
|
63798
|
-
const simResult = await
|
|
64577
|
+
const simResult = await clack62.select({
|
|
63799
64578
|
message: "Select simulator destination:",
|
|
63800
64579
|
options: SIMULATOR_DESTINATIONS.map((sim) => ({
|
|
63801
64580
|
value: sim.number,
|
|
63802
64581
|
label: `${sim.number} | ${sim.country}`
|
|
63803
64582
|
}))
|
|
63804
64583
|
});
|
|
63805
|
-
if (
|
|
63806
|
-
|
|
64584
|
+
if (clack62.isCancel(simResult)) {
|
|
64585
|
+
clack62.cancel("Operation cancelled.");
|
|
63807
64586
|
process.exit(0);
|
|
63808
64587
|
}
|
|
63809
64588
|
toNumber = simResult;
|
|
63810
64589
|
} else {
|
|
63811
|
-
const result = await
|
|
64590
|
+
const result = await clack62.text({
|
|
63812
64591
|
message: "Enter destination phone number (E.164 format):",
|
|
63813
64592
|
placeholder: "+14155551234",
|
|
63814
64593
|
validate: (value) => {
|
|
@@ -63821,22 +64600,22 @@ Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
63821
64600
|
return;
|
|
63822
64601
|
}
|
|
63823
64602
|
});
|
|
63824
|
-
if (
|
|
63825
|
-
|
|
64603
|
+
if (clack62.isCancel(result)) {
|
|
64604
|
+
clack62.cancel("Operation cancelled.");
|
|
63826
64605
|
process.exit(0);
|
|
63827
64606
|
}
|
|
63828
64607
|
toNumber = result;
|
|
63829
64608
|
}
|
|
63830
64609
|
} else if (!isValidPhoneNumber(toNumber)) {
|
|
63831
64610
|
progress.stop();
|
|
63832
|
-
|
|
64611
|
+
clack62.log.error(
|
|
63833
64612
|
`Invalid phone number format: ${toNumber}. Use E.164 format (e.g., +14155551234)`
|
|
63834
64613
|
);
|
|
63835
64614
|
process.exit(1);
|
|
63836
64615
|
}
|
|
63837
64616
|
let message = options.message;
|
|
63838
64617
|
if (!message) {
|
|
63839
|
-
const result = await
|
|
64618
|
+
const result = await clack62.text({
|
|
63840
64619
|
message: "Enter test message:",
|
|
63841
64620
|
placeholder: "Hello from Wraps SMS!",
|
|
63842
64621
|
defaultValue: "Hello from Wraps SMS! This is a test message.",
|
|
@@ -63850,8 +64629,8 @@ Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
63850
64629
|
return;
|
|
63851
64630
|
}
|
|
63852
64631
|
});
|
|
63853
|
-
if (
|
|
63854
|
-
|
|
64632
|
+
if (clack62.isCancel(result)) {
|
|
64633
|
+
clack62.cancel("Operation cancelled.");
|
|
63855
64634
|
process.exit(0);
|
|
63856
64635
|
}
|
|
63857
64636
|
message = result;
|
|
@@ -63890,16 +64669,16 @@ Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
63890
64669
|
return;
|
|
63891
64670
|
}
|
|
63892
64671
|
console.log("\n");
|
|
63893
|
-
|
|
64672
|
+
clack62.log.success(pc65.green("Test SMS sent successfully!"));
|
|
63894
64673
|
console.log("");
|
|
63895
|
-
|
|
64674
|
+
clack62.note(
|
|
63896
64675
|
[
|
|
63897
|
-
`${
|
|
63898
|
-
`${
|
|
63899
|
-
`${
|
|
63900
|
-
`${
|
|
64676
|
+
`${pc65.bold("Message ID:")} ${pc65.cyan(messageId || "unknown")}`,
|
|
64677
|
+
`${pc65.bold("To:")} ${pc65.cyan(toNumber)}`,
|
|
64678
|
+
`${pc65.bold("Message:")} ${message}`,
|
|
64679
|
+
`${pc65.bold("Type:")} ${pc65.cyan(smsConfig?.phoneNumberType || "simulator")}`,
|
|
63901
64680
|
"",
|
|
63902
|
-
|
|
64681
|
+
pc65.dim(
|
|
63903
64682
|
smsConfig?.phoneNumberType === "simulator" ? "Note: Simulator messages are not actually delivered" : "Check your phone for the message!"
|
|
63904
64683
|
)
|
|
63905
64684
|
].join("\n"),
|
|
@@ -63907,11 +64686,11 @@ Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
63907
64686
|
);
|
|
63908
64687
|
if (smsConfig?.eventTracking?.enabled) {
|
|
63909
64688
|
console.log("");
|
|
63910
|
-
|
|
63911
|
-
|
|
64689
|
+
clack62.log.info(
|
|
64690
|
+
pc65.dim("Event tracking is enabled. Check DynamoDB for delivery status.")
|
|
63912
64691
|
);
|
|
63913
64692
|
}
|
|
63914
|
-
|
|
64693
|
+
clack62.outro(pc65.green("Test complete!"));
|
|
63915
64694
|
} catch (error) {
|
|
63916
64695
|
progress.stop();
|
|
63917
64696
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -63923,33 +64702,33 @@ Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
63923
64702
|
});
|
|
63924
64703
|
const errorName = error instanceof Error ? error.name : "";
|
|
63925
64704
|
if (errorName === "ConflictException" || errorMessage.includes("opt-out")) {
|
|
63926
|
-
|
|
64705
|
+
clack62.log.error("Destination number has opted out of messages");
|
|
63927
64706
|
console.log("\nThe recipient has opted out of receiving SMS messages.\n");
|
|
63928
64707
|
} else if (errorName === "ThrottlingException" || errorMessage.includes("spending limit")) {
|
|
63929
|
-
|
|
64708
|
+
clack62.log.error("SMS rate or spending limit reached");
|
|
63930
64709
|
console.log(
|
|
63931
64710
|
"\nCheck your AWS account SMS spending limits in the console.\n"
|
|
63932
64711
|
);
|
|
63933
64712
|
} else if (errorName === "ValidationException") {
|
|
63934
|
-
|
|
64713
|
+
clack62.log.error(`Invalid request: ${errorMessage}`);
|
|
63935
64714
|
} else if (errorMessage.includes("not verified") || errorMessage.includes("not registered")) {
|
|
63936
|
-
|
|
64715
|
+
clack62.log.error("Toll-free number registration is not complete");
|
|
63937
64716
|
console.log(
|
|
63938
64717
|
`
|
|
63939
|
-
Run ${
|
|
64718
|
+
Run ${pc65.cyan("wraps sms register")} to check registration status.
|
|
63940
64719
|
`
|
|
63941
64720
|
);
|
|
63942
64721
|
} else if (errorName === "AccessDeniedException") {
|
|
63943
|
-
|
|
64722
|
+
clack62.log.error(
|
|
63944
64723
|
"Permission denied \u2014 IAM role may be missing SMS send permissions"
|
|
63945
64724
|
);
|
|
63946
64725
|
console.log(
|
|
63947
64726
|
`
|
|
63948
|
-
Run ${
|
|
64727
|
+
Run ${pc65.cyan("wraps sms upgrade")} to update IAM policies.
|
|
63949
64728
|
`
|
|
63950
64729
|
);
|
|
63951
64730
|
} else {
|
|
63952
|
-
|
|
64731
|
+
clack62.log.error(`Failed to send SMS: ${errorMessage}`);
|
|
63953
64732
|
}
|
|
63954
64733
|
process.exit(1);
|
|
63955
64734
|
}
|
|
@@ -63957,9 +64736,9 @@ Run ${pc64.cyan("wraps sms upgrade")} to update IAM policies.
|
|
|
63957
64736
|
|
|
63958
64737
|
// src/commands/sms/upgrade.ts
|
|
63959
64738
|
init_esm_shims();
|
|
63960
|
-
import * as
|
|
64739
|
+
import * as clack63 from "@clack/prompts";
|
|
63961
64740
|
import * as pulumi38 from "@pulumi/pulumi";
|
|
63962
|
-
import
|
|
64741
|
+
import pc66 from "picocolors";
|
|
63963
64742
|
init_events();
|
|
63964
64743
|
init_aws();
|
|
63965
64744
|
init_errors();
|
|
@@ -63974,7 +64753,7 @@ async function smsUpgrade(options) {
|
|
|
63974
64753
|
const startTime = Date.now();
|
|
63975
64754
|
let upgradeAction = "";
|
|
63976
64755
|
if (!isJsonMode()) {
|
|
63977
|
-
|
|
64756
|
+
clack63.intro(pc66.bold("Wraps SMS Upgrade - Enhance Your SMS Infrastructure"));
|
|
63978
64757
|
}
|
|
63979
64758
|
const progress = new DeploymentProgress();
|
|
63980
64759
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -63988,7 +64767,7 @@ async function smsUpgrade(options) {
|
|
|
63988
64767
|
"Validating AWS credentials",
|
|
63989
64768
|
async () => validateAWSCredentials()
|
|
63990
64769
|
);
|
|
63991
|
-
progress.info(`Connected to AWS account: ${
|
|
64770
|
+
progress.info(`Connected to AWS account: ${pc66.cyan(identity.accountId)}`);
|
|
63992
64771
|
const region = await resolveRegionForCommand({
|
|
63993
64772
|
accountId: identity.accountId,
|
|
63994
64773
|
optionRegion: options.region,
|
|
@@ -63997,35 +64776,35 @@ async function smsUpgrade(options) {
|
|
|
63997
64776
|
});
|
|
63998
64777
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
63999
64778
|
if (!metadata) {
|
|
64000
|
-
|
|
64001
|
-
`No Wraps connection found for account ${
|
|
64779
|
+
clack63.log.error(
|
|
64780
|
+
`No Wraps connection found for account ${pc66.cyan(identity.accountId)} in region ${pc66.cyan(region)}`
|
|
64002
64781
|
);
|
|
64003
|
-
|
|
64004
|
-
`Use ${
|
|
64782
|
+
clack63.log.info(
|
|
64783
|
+
`Use ${pc66.cyan("wraps sms init")} to create new infrastructure.`
|
|
64005
64784
|
);
|
|
64006
64785
|
process.exit(1);
|
|
64007
64786
|
}
|
|
64008
64787
|
if (!metadata.services.sms) {
|
|
64009
|
-
|
|
64010
|
-
|
|
64011
|
-
`Use ${
|
|
64788
|
+
clack63.log.error("No SMS infrastructure found");
|
|
64789
|
+
clack63.log.info(
|
|
64790
|
+
`Use ${pc66.cyan("wraps sms init")} to deploy SMS infrastructure.`
|
|
64012
64791
|
);
|
|
64013
64792
|
process.exit(1);
|
|
64014
64793
|
}
|
|
64015
64794
|
progress.info(`Found existing connection created: ${metadata.timestamp}`);
|
|
64016
64795
|
console.log(`
|
|
64017
|
-
${
|
|
64796
|
+
${pc66.bold("Current Configuration:")}
|
|
64018
64797
|
`);
|
|
64019
64798
|
if (metadata.services.sms.preset) {
|
|
64020
|
-
console.log(` Preset: ${
|
|
64799
|
+
console.log(` Preset: ${pc66.cyan(metadata.services.sms.preset)}`);
|
|
64021
64800
|
} else {
|
|
64022
|
-
console.log(` Preset: ${
|
|
64801
|
+
console.log(` Preset: ${pc66.cyan("custom")}`);
|
|
64023
64802
|
}
|
|
64024
64803
|
const config2 = metadata.services.sms.config;
|
|
64025
64804
|
if (!config2) {
|
|
64026
|
-
|
|
64027
|
-
|
|
64028
|
-
`Use ${
|
|
64805
|
+
clack63.log.error("No SMS configuration found in metadata");
|
|
64806
|
+
clack63.log.info(
|
|
64807
|
+
`Use ${pc66.cyan("wraps sms init")} to create new infrastructure.`
|
|
64029
64808
|
);
|
|
64030
64809
|
process.exit(1);
|
|
64031
64810
|
}
|
|
@@ -64037,45 +64816,45 @@ ${pc65.bold("Current Configuration:")}
|
|
|
64037
64816
|
"short-code": "Short code ($995+/mo, 100+ MPS)"
|
|
64038
64817
|
};
|
|
64039
64818
|
console.log(
|
|
64040
|
-
` Phone Type: ${
|
|
64819
|
+
` Phone Type: ${pc66.cyan(phoneTypeLabels2[config2.phoneNumberType] || config2.phoneNumberType)}`
|
|
64041
64820
|
);
|
|
64042
64821
|
}
|
|
64043
64822
|
if (config2.tracking?.enabled) {
|
|
64044
|
-
console.log(` ${
|
|
64823
|
+
console.log(` ${pc66.green("\u2713")} Delivery Tracking`);
|
|
64045
64824
|
if (config2.tracking.linkTracking) {
|
|
64046
|
-
console.log(` ${
|
|
64825
|
+
console.log(` ${pc66.dim("\u2514\u2500")} Link click tracking enabled`);
|
|
64047
64826
|
}
|
|
64048
64827
|
}
|
|
64049
64828
|
if (config2.eventTracking?.enabled) {
|
|
64050
|
-
console.log(` ${
|
|
64829
|
+
console.log(` ${pc66.green("\u2713")} Event Tracking (SNS)`);
|
|
64051
64830
|
if (config2.eventTracking.dynamoDBHistory) {
|
|
64052
64831
|
console.log(
|
|
64053
|
-
` ${
|
|
64832
|
+
` ${pc66.dim("\u2514\u2500")} Message History: ${pc66.cyan(config2.eventTracking.archiveRetention || "90days")}`
|
|
64054
64833
|
);
|
|
64055
64834
|
}
|
|
64056
64835
|
}
|
|
64057
64836
|
if (config2.messageArchiving?.enabled) {
|
|
64058
64837
|
console.log(
|
|
64059
|
-
` ${
|
|
64838
|
+
` ${pc66.green("\u2713")} Message Archiving (${config2.messageArchiving.retention})`
|
|
64060
64839
|
);
|
|
64061
64840
|
}
|
|
64062
64841
|
if (config2.optOutManagement) {
|
|
64063
|
-
console.log(` ${
|
|
64842
|
+
console.log(` ${pc66.green("\u2713")} Opt-out Management`);
|
|
64064
64843
|
}
|
|
64065
64844
|
if (config2.protectConfiguration?.enabled) {
|
|
64066
64845
|
const countries = config2.protectConfiguration.allowedCountries?.join(", ") || "US";
|
|
64067
|
-
console.log(` ${
|
|
64068
|
-
console.log(` ${
|
|
64846
|
+
console.log(` ${pc66.green("\u2713")} Fraud Protection`);
|
|
64847
|
+
console.log(` ${pc66.dim("\u2514\u2500")} Allowed countries: ${pc66.cyan(countries)}`);
|
|
64069
64848
|
if (config2.protectConfiguration.aitFiltering) {
|
|
64070
|
-
console.log(` ${
|
|
64849
|
+
console.log(` ${pc66.dim("\u2514\u2500")} AIT filtering: ${pc66.cyan("enabled")}`);
|
|
64071
64850
|
}
|
|
64072
64851
|
} else {
|
|
64073
|
-
console.log(` ${
|
|
64852
|
+
console.log(` ${pc66.dim("\u25CB")} Fraud Protection (not configured)`);
|
|
64074
64853
|
}
|
|
64075
64854
|
const currentCostData = calculateSMSCosts(config2, 1e4);
|
|
64076
64855
|
console.log(
|
|
64077
64856
|
`
|
|
64078
|
-
Estimated Cost: ${
|
|
64857
|
+
Estimated Cost: ${pc66.cyan(`~${formatCost3(currentCostData.total.monthly)}/mo`)}`
|
|
64079
64858
|
);
|
|
64080
64859
|
console.log("");
|
|
64081
64860
|
const phoneTypeLabels = {
|
|
@@ -64084,7 +64863,7 @@ ${pc65.bold("Current Configuration:")}
|
|
|
64084
64863
|
"10dlc": "10DLC",
|
|
64085
64864
|
"short-code": "Short code"
|
|
64086
64865
|
};
|
|
64087
|
-
upgradeAction = await
|
|
64866
|
+
upgradeAction = await clack63.select({
|
|
64088
64867
|
message: "What would you like to do?",
|
|
64089
64868
|
options: [
|
|
64090
64869
|
{
|
|
@@ -64124,8 +64903,8 @@ ${pc65.bold("Current Configuration:")}
|
|
|
64124
64903
|
}
|
|
64125
64904
|
]
|
|
64126
64905
|
});
|
|
64127
|
-
if (
|
|
64128
|
-
|
|
64906
|
+
if (clack63.isCancel(upgradeAction)) {
|
|
64907
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64129
64908
|
process.exit(0);
|
|
64130
64909
|
}
|
|
64131
64910
|
let updatedConfig = { ...config2 };
|
|
@@ -64166,65 +64945,65 @@ ${pc65.bold("Current Configuration:")}
|
|
|
64166
64945
|
hint: p3.hint
|
|
64167
64946
|
}));
|
|
64168
64947
|
if (availableTypes.length === 0) {
|
|
64169
|
-
|
|
64948
|
+
clack63.log.warn(
|
|
64170
64949
|
"Already on highest phone number tier. Contact AWS for dedicated short codes."
|
|
64171
64950
|
);
|
|
64172
64951
|
process.exit(0);
|
|
64173
64952
|
}
|
|
64174
|
-
const selectedType = await
|
|
64953
|
+
const selectedType = await clack63.select({
|
|
64175
64954
|
message: "Select new phone number type:",
|
|
64176
64955
|
options: availableTypes
|
|
64177
64956
|
});
|
|
64178
|
-
if (
|
|
64179
|
-
|
|
64957
|
+
if (clack63.isCancel(selectedType)) {
|
|
64958
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64180
64959
|
process.exit(0);
|
|
64181
64960
|
}
|
|
64182
64961
|
if (selectedType === "toll-free") {
|
|
64183
64962
|
console.log(
|
|
64184
64963
|
`
|
|
64185
|
-
${
|
|
64964
|
+
${pc66.yellow("\u26A0")} ${pc66.bold("Toll-free Registration Required")}
|
|
64186
64965
|
`
|
|
64187
64966
|
);
|
|
64188
64967
|
console.log(
|
|
64189
|
-
|
|
64968
|
+
pc66.dim("Toll-free numbers require carrier registration before")
|
|
64190
64969
|
);
|
|
64191
64970
|
console.log(
|
|
64192
|
-
|
|
64971
|
+
pc66.dim("they can send messages at scale. After deployment:\n")
|
|
64193
64972
|
);
|
|
64194
64973
|
console.log(
|
|
64195
|
-
` 1. Run ${
|
|
64974
|
+
` 1. Run ${pc66.cyan("wraps sms register")} to start registration`
|
|
64196
64975
|
);
|
|
64197
64976
|
console.log(" 2. Submit your business use case information");
|
|
64198
64977
|
console.log(" 3. Wait for carrier verification (1-5 business days)");
|
|
64199
64978
|
console.log(
|
|
64200
|
-
|
|
64979
|
+
pc66.dim("\nUntil verified, sending is limited to low volume.\n")
|
|
64201
64980
|
);
|
|
64202
|
-
const confirmTollFree = await
|
|
64981
|
+
const confirmTollFree = await clack63.confirm({
|
|
64203
64982
|
message: "Continue with toll-free number request?",
|
|
64204
64983
|
initialValue: true
|
|
64205
64984
|
});
|
|
64206
|
-
if (
|
|
64207
|
-
|
|
64985
|
+
if (clack63.isCancel(confirmTollFree) || !confirmTollFree) {
|
|
64986
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64208
64987
|
process.exit(0);
|
|
64209
64988
|
}
|
|
64210
64989
|
}
|
|
64211
64990
|
if (selectedType === "10dlc") {
|
|
64212
64991
|
console.log(
|
|
64213
64992
|
`
|
|
64214
|
-
${
|
|
64993
|
+
${pc66.yellow("\u26A0")} ${pc66.bold("10DLC Campaign Registration Required")}
|
|
64215
64994
|
`
|
|
64216
64995
|
);
|
|
64217
|
-
console.log(
|
|
64996
|
+
console.log(pc66.dim("10DLC requires brand and campaign registration:"));
|
|
64218
64997
|
console.log(" \u2022 Brand registration: one-time $4 fee");
|
|
64219
64998
|
console.log(" \u2022 Campaign registration: $15/mo per campaign");
|
|
64220
64999
|
console.log(" \u2022 Verification takes 1-7 business days");
|
|
64221
65000
|
console.log("");
|
|
64222
|
-
const confirm10DLC = await
|
|
65001
|
+
const confirm10DLC = await clack63.confirm({
|
|
64223
65002
|
message: "Continue with 10DLC number request?",
|
|
64224
65003
|
initialValue: true
|
|
64225
65004
|
});
|
|
64226
|
-
if (
|
|
64227
|
-
|
|
65005
|
+
if (clack63.isCancel(confirm10DLC) || !confirm10DLC) {
|
|
65006
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64228
65007
|
process.exit(0);
|
|
64229
65008
|
}
|
|
64230
65009
|
}
|
|
@@ -64249,15 +65028,15 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64249
65028
|
disabled: currentPresetIdx >= 0 && idx <= currentPresetIdx ? "Current or lower tier" : void 0
|
|
64250
65029
|
})).filter((p3) => !p3.disabled && p3.value !== "custom");
|
|
64251
65030
|
if (availablePresets.length === 0) {
|
|
64252
|
-
|
|
65031
|
+
clack63.log.warn("Already on highest preset (Enterprise)");
|
|
64253
65032
|
process.exit(0);
|
|
64254
65033
|
}
|
|
64255
|
-
const selectedPreset = await
|
|
65034
|
+
const selectedPreset = await clack63.select({
|
|
64256
65035
|
message: "Select new preset:",
|
|
64257
65036
|
options: availablePresets
|
|
64258
65037
|
});
|
|
64259
|
-
if (
|
|
64260
|
-
|
|
65038
|
+
if (clack63.isCancel(selectedPreset)) {
|
|
65039
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64261
65040
|
process.exit(0);
|
|
64262
65041
|
}
|
|
64263
65042
|
const presetConfig = getSMSPreset(selectedPreset);
|
|
@@ -64273,7 +65052,7 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64273
65052
|
}
|
|
64274
65053
|
case "event-tracking": {
|
|
64275
65054
|
if (config2.eventTracking?.enabled) {
|
|
64276
|
-
const eventAction = await
|
|
65055
|
+
const eventAction = await clack63.select({
|
|
64277
65056
|
message: "What would you like to do with event tracking?",
|
|
64278
65057
|
options: [
|
|
64279
65058
|
{
|
|
@@ -64288,17 +65067,17 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64288
65067
|
}
|
|
64289
65068
|
]
|
|
64290
65069
|
});
|
|
64291
|
-
if (
|
|
64292
|
-
|
|
65070
|
+
if (clack63.isCancel(eventAction)) {
|
|
65071
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64293
65072
|
process.exit(0);
|
|
64294
65073
|
}
|
|
64295
65074
|
if (eventAction === "disable") {
|
|
64296
|
-
const confirmDisable = await
|
|
65075
|
+
const confirmDisable = await clack63.confirm({
|
|
64297
65076
|
message: "Are you sure? Existing history will remain, but new events won't be tracked.",
|
|
64298
65077
|
initialValue: false
|
|
64299
65078
|
});
|
|
64300
|
-
if (
|
|
64301
|
-
|
|
65079
|
+
if (clack63.isCancel(confirmDisable) || !confirmDisable) {
|
|
65080
|
+
clack63.cancel("Event tracking not disabled.");
|
|
64302
65081
|
process.exit(0);
|
|
64303
65082
|
}
|
|
64304
65083
|
updatedConfig = {
|
|
@@ -64308,7 +65087,7 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64308
65087
|
}
|
|
64309
65088
|
};
|
|
64310
65089
|
} else {
|
|
64311
|
-
const retention = await
|
|
65090
|
+
const retention = await clack63.select({
|
|
64312
65091
|
message: "Message history retention period:",
|
|
64313
65092
|
options: [
|
|
64314
65093
|
{ value: "7days", label: "7 days", hint: "Minimal storage cost" },
|
|
@@ -64335,8 +65114,8 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64335
65114
|
],
|
|
64336
65115
|
initialValue: config2.eventTracking.archiveRetention || "90days"
|
|
64337
65116
|
});
|
|
64338
|
-
if (
|
|
64339
|
-
|
|
65117
|
+
if (clack63.isCancel(retention)) {
|
|
65118
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64340
65119
|
process.exit(0);
|
|
64341
65120
|
}
|
|
64342
65121
|
updatedConfig = {
|
|
@@ -64348,19 +65127,19 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64348
65127
|
};
|
|
64349
65128
|
}
|
|
64350
65129
|
} else {
|
|
64351
|
-
const enableTracking = await
|
|
65130
|
+
const enableTracking = await clack63.confirm({
|
|
64352
65131
|
message: "Enable event tracking? (Track SMS events with history)",
|
|
64353
65132
|
initialValue: true
|
|
64354
65133
|
});
|
|
64355
|
-
if (
|
|
64356
|
-
|
|
65134
|
+
if (clack63.isCancel(enableTracking)) {
|
|
65135
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64357
65136
|
process.exit(0);
|
|
64358
65137
|
}
|
|
64359
65138
|
if (!enableTracking) {
|
|
64360
|
-
|
|
65139
|
+
clack63.log.info("Event tracking not enabled.");
|
|
64361
65140
|
process.exit(0);
|
|
64362
65141
|
}
|
|
64363
|
-
const retention = await
|
|
65142
|
+
const retention = await clack63.select({
|
|
64364
65143
|
message: "Message history retention period:",
|
|
64365
65144
|
options: [
|
|
64366
65145
|
{ value: "7days", label: "7 days", hint: "Minimal storage cost" },
|
|
@@ -64383,8 +65162,8 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64383
65162
|
],
|
|
64384
65163
|
initialValue: "90days"
|
|
64385
65164
|
});
|
|
64386
|
-
if (
|
|
64387
|
-
|
|
65165
|
+
if (clack63.isCancel(retention)) {
|
|
65166
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64388
65167
|
process.exit(0);
|
|
64389
65168
|
}
|
|
64390
65169
|
updatedConfig = {
|
|
@@ -64403,12 +65182,12 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64403
65182
|
}
|
|
64404
65183
|
case "retention": {
|
|
64405
65184
|
if (!config2.eventTracking?.enabled) {
|
|
64406
|
-
|
|
65185
|
+
clack63.log.error(
|
|
64407
65186
|
"Event tracking is not enabled. Enable it first to change retention."
|
|
64408
65187
|
);
|
|
64409
65188
|
process.exit(1);
|
|
64410
65189
|
}
|
|
64411
|
-
const retention = await
|
|
65190
|
+
const retention = await clack63.select({
|
|
64412
65191
|
message: "Message history retention period (event data in DynamoDB):",
|
|
64413
65192
|
options: [
|
|
64414
65193
|
{ value: "7days", label: "7 days", hint: "Minimal storage cost" },
|
|
@@ -64427,8 +65206,8 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64427
65206
|
],
|
|
64428
65207
|
initialValue: config2.eventTracking.archiveRetention || "90days"
|
|
64429
65208
|
});
|
|
64430
|
-
if (
|
|
64431
|
-
|
|
65209
|
+
if (clack63.isCancel(retention)) {
|
|
65210
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64432
65211
|
process.exit(0);
|
|
64433
65212
|
}
|
|
64434
65213
|
updatedConfig = {
|
|
@@ -64446,21 +65225,21 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64446
65225
|
case "link-tracking": {
|
|
64447
65226
|
const enableLinkTracking = !config2.tracking?.linkTracking;
|
|
64448
65227
|
if (enableLinkTracking) {
|
|
64449
|
-
|
|
64450
|
-
|
|
65228
|
+
clack63.log.info(
|
|
65229
|
+
pc66.dim(
|
|
64451
65230
|
"Link tracking will track clicks on URLs in your SMS messages."
|
|
64452
65231
|
)
|
|
64453
65232
|
);
|
|
64454
|
-
|
|
64455
|
-
|
|
65233
|
+
clack63.log.info(
|
|
65234
|
+
pc66.dim("URLs will be rewritten to go through a tracking endpoint.")
|
|
64456
65235
|
);
|
|
64457
65236
|
}
|
|
64458
|
-
const confirmed = await
|
|
65237
|
+
const confirmed = await clack63.confirm({
|
|
64459
65238
|
message: enableLinkTracking ? "Enable link click tracking?" : "Disable link click tracking?",
|
|
64460
65239
|
initialValue: enableLinkTracking
|
|
64461
65240
|
});
|
|
64462
|
-
if (
|
|
64463
|
-
|
|
65241
|
+
if (clack63.isCancel(confirmed) || !confirmed) {
|
|
65242
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64464
65243
|
process.exit(0);
|
|
64465
65244
|
}
|
|
64466
65245
|
updatedConfig = {
|
|
@@ -64477,7 +65256,7 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64477
65256
|
}
|
|
64478
65257
|
case "archiving": {
|
|
64479
65258
|
if (config2.messageArchiving?.enabled) {
|
|
64480
|
-
const archivingAction = await
|
|
65259
|
+
const archivingAction = await clack63.select({
|
|
64481
65260
|
message: "What would you like to do with message archiving?",
|
|
64482
65261
|
options: [
|
|
64483
65262
|
{
|
|
@@ -64492,17 +65271,17 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64492
65271
|
}
|
|
64493
65272
|
]
|
|
64494
65273
|
});
|
|
64495
|
-
if (
|
|
64496
|
-
|
|
65274
|
+
if (clack63.isCancel(archivingAction)) {
|
|
65275
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64497
65276
|
process.exit(0);
|
|
64498
65277
|
}
|
|
64499
65278
|
if (archivingAction === "disable") {
|
|
64500
|
-
const confirmDisable = await
|
|
65279
|
+
const confirmDisable = await clack63.confirm({
|
|
64501
65280
|
message: "Are you sure? Existing archived messages will remain, but new messages won't be archived.",
|
|
64502
65281
|
initialValue: false
|
|
64503
65282
|
});
|
|
64504
|
-
if (
|
|
64505
|
-
|
|
65283
|
+
if (clack63.isCancel(confirmDisable) || !confirmDisable) {
|
|
65284
|
+
clack63.cancel("Archiving not disabled.");
|
|
64506
65285
|
process.exit(0);
|
|
64507
65286
|
}
|
|
64508
65287
|
updatedConfig = {
|
|
@@ -64513,7 +65292,7 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64513
65292
|
}
|
|
64514
65293
|
};
|
|
64515
65294
|
} else {
|
|
64516
|
-
const retention = await
|
|
65295
|
+
const retention = await clack63.select({
|
|
64517
65296
|
message: "Message archive retention period:",
|
|
64518
65297
|
options: [
|
|
64519
65298
|
{
|
|
@@ -64544,8 +65323,8 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64544
65323
|
],
|
|
64545
65324
|
initialValue: config2.messageArchiving.retention
|
|
64546
65325
|
});
|
|
64547
|
-
if (
|
|
64548
|
-
|
|
65326
|
+
if (clack63.isCancel(retention)) {
|
|
65327
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64549
65328
|
process.exit(0);
|
|
64550
65329
|
}
|
|
64551
65330
|
updatedConfig = {
|
|
@@ -64557,19 +65336,19 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64557
65336
|
};
|
|
64558
65337
|
}
|
|
64559
65338
|
} else {
|
|
64560
|
-
const enableArchiving = await
|
|
65339
|
+
const enableArchiving = await clack63.confirm({
|
|
64561
65340
|
message: "Enable message archiving? (Store full message content for viewing)",
|
|
64562
65341
|
initialValue: true
|
|
64563
65342
|
});
|
|
64564
|
-
if (
|
|
64565
|
-
|
|
65343
|
+
if (clack63.isCancel(enableArchiving)) {
|
|
65344
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64566
65345
|
process.exit(0);
|
|
64567
65346
|
}
|
|
64568
65347
|
if (!enableArchiving) {
|
|
64569
|
-
|
|
65348
|
+
clack63.log.info("Message archiving not enabled.");
|
|
64570
65349
|
process.exit(0);
|
|
64571
65350
|
}
|
|
64572
|
-
const retention = await
|
|
65351
|
+
const retention = await clack63.select({
|
|
64573
65352
|
message: "Message archive retention period:",
|
|
64574
65353
|
options: [
|
|
64575
65354
|
{ value: "7days", label: "7 days", hint: "~$1-2/mo for 10k msgs" },
|
|
@@ -64596,8 +65375,8 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64596
65375
|
],
|
|
64597
65376
|
initialValue: "90days"
|
|
64598
65377
|
});
|
|
64599
|
-
if (
|
|
64600
|
-
|
|
65378
|
+
if (clack63.isCancel(retention)) {
|
|
65379
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64601
65380
|
process.exit(0);
|
|
64602
65381
|
}
|
|
64603
65382
|
updatedConfig = {
|
|
@@ -64629,7 +65408,7 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64629
65408
|
const currentAllowed = config2.protectConfiguration?.allowedCountries || [
|
|
64630
65409
|
"US"
|
|
64631
65410
|
];
|
|
64632
|
-
const selectedCountries = await
|
|
65411
|
+
const selectedCountries = await clack63.multiselect({
|
|
64633
65412
|
message: "Select countries to allow SMS delivery (all others blocked):",
|
|
64634
65413
|
options: commonCountries.map((c6) => ({
|
|
64635
65414
|
value: c6.code,
|
|
@@ -64638,16 +65417,16 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64638
65417
|
initialValues: currentAllowed,
|
|
64639
65418
|
required: true
|
|
64640
65419
|
});
|
|
64641
|
-
if (
|
|
64642
|
-
|
|
65420
|
+
if (clack63.isCancel(selectedCountries)) {
|
|
65421
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64643
65422
|
process.exit(0);
|
|
64644
65423
|
}
|
|
64645
|
-
const enableAIT = await
|
|
65424
|
+
const enableAIT = await clack63.confirm({
|
|
64646
65425
|
message: "Enable AIT (Artificially Inflated Traffic) filtering? (adds per-message cost)",
|
|
64647
65426
|
initialValue: config2.protectConfiguration?.aitFiltering ?? false
|
|
64648
65427
|
});
|
|
64649
|
-
if (
|
|
64650
|
-
|
|
65428
|
+
if (clack63.isCancel(enableAIT)) {
|
|
65429
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64651
65430
|
process.exit(0);
|
|
64652
65431
|
}
|
|
64653
65432
|
updatedConfig = {
|
|
@@ -64665,28 +65444,28 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
|
|
|
64665
65444
|
const newCostData = calculateSMSCosts(updatedConfig, 1e4);
|
|
64666
65445
|
const costDiff = newCostData.total.monthly - currentCostData.total.monthly;
|
|
64667
65446
|
console.log(`
|
|
64668
|
-
${
|
|
65447
|
+
${pc66.bold("Cost Impact:")}`);
|
|
64669
65448
|
console.log(
|
|
64670
|
-
` Current: ${
|
|
65449
|
+
` Current: ${pc66.cyan(`${formatCost3(currentCostData.total.monthly)}/mo`)}`
|
|
64671
65450
|
);
|
|
64672
65451
|
console.log(
|
|
64673
|
-
` New: ${
|
|
65452
|
+
` New: ${pc66.cyan(`${formatCost3(newCostData.total.monthly)}/mo`)}`
|
|
64674
65453
|
);
|
|
64675
65454
|
if (costDiff > 0) {
|
|
64676
|
-
console.log(` Change: ${
|
|
65455
|
+
console.log(` Change: ${pc66.yellow(`+${formatCost3(costDiff)}/mo`)}`);
|
|
64677
65456
|
} else if (costDiff < 0) {
|
|
64678
65457
|
console.log(
|
|
64679
|
-
` Change: ${
|
|
65458
|
+
` Change: ${pc66.green(`-${formatCost3(Math.abs(costDiff))}/mo`)}`
|
|
64680
65459
|
);
|
|
64681
65460
|
}
|
|
64682
65461
|
console.log("");
|
|
64683
65462
|
if (!(options.yes || options.preview)) {
|
|
64684
|
-
const confirmed = await
|
|
65463
|
+
const confirmed = await clack63.confirm({
|
|
64685
65464
|
message: "Proceed with upgrade?",
|
|
64686
65465
|
initialValue: true
|
|
64687
65466
|
});
|
|
64688
|
-
if (
|
|
64689
|
-
|
|
65467
|
+
if (clack63.isCancel(confirmed) || !confirmed) {
|
|
65468
|
+
clack63.cancel("Upgrade cancelled.");
|
|
64690
65469
|
process.exit(0);
|
|
64691
65470
|
}
|
|
64692
65471
|
}
|
|
@@ -64755,8 +65534,8 @@ ${pc65.bold("Cost Impact:")}`);
|
|
|
64755
65534
|
resourceChanges: previewResult.resourceChanges,
|
|
64756
65535
|
commandName: "wraps sms upgrade"
|
|
64757
65536
|
});
|
|
64758
|
-
|
|
64759
|
-
|
|
65537
|
+
clack63.outro(
|
|
65538
|
+
pc66.green("Preview complete. Run without --preview to upgrade.")
|
|
64760
65539
|
);
|
|
64761
65540
|
trackServiceUpgrade("sms", {
|
|
64762
65541
|
region,
|
|
@@ -64861,43 +65640,43 @@ ${pc65.bold("Cost Impact:")}`);
|
|
|
64861
65640
|
}
|
|
64862
65641
|
progress.info("Connection metadata updated");
|
|
64863
65642
|
console.log("\n");
|
|
64864
|
-
|
|
65643
|
+
clack63.log.success(pc66.green(pc66.bold("SMS infrastructure upgraded!")));
|
|
64865
65644
|
console.log("\n");
|
|
64866
|
-
|
|
65645
|
+
clack63.note(
|
|
64867
65646
|
[
|
|
64868
|
-
`${
|
|
64869
|
-
`${
|
|
64870
|
-
`${
|
|
64871
|
-
`${
|
|
64872
|
-
outputs.tableName ? `${
|
|
65647
|
+
`${pc66.bold("Phone Number:")} ${pc66.cyan(outputs.phoneNumber || "Provisioning...")}`,
|
|
65648
|
+
`${pc66.bold("Phone Type:")} ${pc66.cyan(updatedConfig.phoneNumberType || "simulator")}`,
|
|
65649
|
+
`${pc66.bold("Config Set:")} ${pc66.cyan(outputs.configSetName || "wraps-sms-config")}`,
|
|
65650
|
+
`${pc66.bold("Region:")} ${pc66.cyan(outputs.region)}`,
|
|
65651
|
+
outputs.tableName ? `${pc66.bold("History Table:")} ${pc66.cyan(outputs.tableName)}` : "",
|
|
64873
65652
|
"",
|
|
64874
|
-
|
|
64875
|
-
|
|
65653
|
+
pc66.dim("IAM Role:"),
|
|
65654
|
+
pc66.dim(` ${outputs.roleArn}`)
|
|
64876
65655
|
].filter(Boolean).join("\n"),
|
|
64877
65656
|
"SMS Infrastructure"
|
|
64878
65657
|
);
|
|
64879
65658
|
console.log(`
|
|
64880
|
-
${
|
|
65659
|
+
${pc66.green("\u2713")} ${pc66.bold("Upgrade complete!")}
|
|
64881
65660
|
`);
|
|
64882
65661
|
if (upgradeAction === "phone-number") {
|
|
64883
65662
|
console.log(
|
|
64884
|
-
`Upgraded to ${
|
|
65663
|
+
`Upgraded to ${pc66.cyan(updatedConfig.phoneNumberType)} number (${pc66.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
64885
65664
|
`
|
|
64886
65665
|
);
|
|
64887
65666
|
if (updatedConfig.phoneNumberType === "toll-free") {
|
|
64888
|
-
console.log(`${
|
|
65667
|
+
console.log(`${pc66.bold("Next Steps:")}`);
|
|
64889
65668
|
console.log(
|
|
64890
|
-
` 1. Run ${
|
|
65669
|
+
` 1. Run ${pc66.cyan("wraps sms register")} to start toll-free registration`
|
|
64891
65670
|
);
|
|
64892
65671
|
console.log(" 2. Submit your business information and use case");
|
|
64893
65672
|
console.log(" 3. Wait for carrier verification (1-5 business days)");
|
|
64894
65673
|
console.log("");
|
|
64895
65674
|
console.log(
|
|
64896
|
-
|
|
65675
|
+
pc66.dim("Until verified, your number can only send limited messages.")
|
|
64897
65676
|
);
|
|
64898
65677
|
console.log("");
|
|
64899
65678
|
} else if (updatedConfig.phoneNumberType === "10dlc") {
|
|
64900
|
-
console.log(`${
|
|
65679
|
+
console.log(`${pc66.bold("Next Steps:")}`);
|
|
64901
65680
|
console.log(" 1. Register your brand in the AWS Console");
|
|
64902
65681
|
console.log(" 2. Create a 10DLC campaign for your use case");
|
|
64903
65682
|
console.log(" 3. Wait for campaign approval (1-7 business days)");
|
|
@@ -64905,16 +65684,16 @@ ${pc65.green("\u2713")} ${pc65.bold("Upgrade complete!")}
|
|
|
64905
65684
|
}
|
|
64906
65685
|
} else if (upgradeAction === "preset" && newPreset) {
|
|
64907
65686
|
console.log(
|
|
64908
|
-
`Upgraded to ${
|
|
65687
|
+
`Upgraded to ${pc66.cyan(newPreset)} preset (${pc66.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
64909
65688
|
`
|
|
64910
65689
|
);
|
|
64911
65690
|
} else {
|
|
64912
65691
|
console.log(
|
|
64913
|
-
`Updated configuration (${
|
|
65692
|
+
`Updated configuration (${pc66.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
64914
65693
|
`
|
|
64915
65694
|
);
|
|
64916
65695
|
}
|
|
64917
|
-
console.log(
|
|
65696
|
+
console.log(pc66.dim(getSMSCostSummary(updatedConfig, 1e4)));
|
|
64918
65697
|
const enabledFeatures = [];
|
|
64919
65698
|
if (updatedConfig.tracking?.enabled) {
|
|
64920
65699
|
enabledFeatures.push("tracking");
|
|
@@ -64938,7 +65717,7 @@ ${pc65.green("\u2713")} ${pc65.bold("Upgrade complete!")}
|
|
|
64938
65717
|
action: typeof upgradeAction === "string" ? upgradeAction : void 0,
|
|
64939
65718
|
duration_ms: Date.now() - startTime
|
|
64940
65719
|
});
|
|
64941
|
-
|
|
65720
|
+
clack63.outro(pc66.green("Upgrade complete!"));
|
|
64942
65721
|
}
|
|
64943
65722
|
|
|
64944
65723
|
// src/commands/sms/verify-number.ts
|
|
@@ -64957,13 +65736,13 @@ import {
|
|
|
64957
65736
|
SendDestinationNumberVerificationCodeCommand,
|
|
64958
65737
|
VerifyDestinationNumberCommand
|
|
64959
65738
|
} from "@aws-sdk/client-pinpoint-sms-voice-v2";
|
|
64960
|
-
import * as
|
|
64961
|
-
import
|
|
65739
|
+
import * as clack64 from "@clack/prompts";
|
|
65740
|
+
import pc67 from "picocolors";
|
|
64962
65741
|
async function smsVerifyNumber(options) {
|
|
64963
65742
|
const startTime = Date.now();
|
|
64964
65743
|
const progress = new DeploymentProgress();
|
|
64965
65744
|
if (!isJsonMode()) {
|
|
64966
|
-
|
|
65745
|
+
clack64.intro(pc67.bold("Wraps SMS - Verify Destination Number"));
|
|
64967
65746
|
}
|
|
64968
65747
|
const identity = await progress.execute(
|
|
64969
65748
|
"Validating AWS credentials",
|
|
@@ -64973,10 +65752,10 @@ async function smsVerifyNumber(options) {
|
|
|
64973
65752
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
64974
65753
|
if (!metadata?.services?.sms) {
|
|
64975
65754
|
progress.stop();
|
|
64976
|
-
|
|
65755
|
+
clack64.log.error("No SMS infrastructure found");
|
|
64977
65756
|
console.log(
|
|
64978
65757
|
`
|
|
64979
|
-
Run ${
|
|
65758
|
+
Run ${pc67.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
64980
65759
|
`
|
|
64981
65760
|
);
|
|
64982
65761
|
process.exit(1);
|
|
@@ -64990,19 +65769,19 @@ Run ${pc66.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
64990
65769
|
);
|
|
64991
65770
|
progress.stop();
|
|
64992
65771
|
if (!response.VerifiedDestinationNumbers || response.VerifiedDestinationNumbers.length === 0) {
|
|
64993
|
-
|
|
65772
|
+
clack64.log.info("No verified destination numbers found");
|
|
64994
65773
|
console.log(
|
|
64995
65774
|
`
|
|
64996
|
-
Run ${
|
|
65775
|
+
Run ${pc67.cyan("wraps sms verify-number")} to verify a number.
|
|
64997
65776
|
`
|
|
64998
65777
|
);
|
|
64999
65778
|
} else {
|
|
65000
65779
|
console.log("\n");
|
|
65001
|
-
|
|
65780
|
+
clack64.log.info(pc67.bold("Verified Destination Numbers:"));
|
|
65002
65781
|
console.log("");
|
|
65003
65782
|
for (const num of response.VerifiedDestinationNumbers) {
|
|
65004
|
-
const status2 = num.Status === "VERIFIED" ?
|
|
65005
|
-
console.log(` ${
|
|
65783
|
+
const status2 = num.Status === "VERIFIED" ? pc67.green("\u2713 Verified") : pc67.yellow("\u29D6 Pending");
|
|
65784
|
+
console.log(` ${pc67.cyan(num.DestinationPhoneNumber)} - ${status2}`);
|
|
65006
65785
|
}
|
|
65007
65786
|
console.log("");
|
|
65008
65787
|
}
|
|
@@ -65020,7 +65799,7 @@ Run ${pc66.cyan("wraps sms verify-number")} to verify a number.
|
|
|
65020
65799
|
});
|
|
65021
65800
|
return;
|
|
65022
65801
|
}
|
|
65023
|
-
|
|
65802
|
+
clack64.outro(pc67.green("Done!"));
|
|
65024
65803
|
return;
|
|
65025
65804
|
} catch (error) {
|
|
65026
65805
|
progress.stop();
|
|
@@ -65028,7 +65807,7 @@ Run ${pc66.cyan("wraps sms verify-number")} to verify a number.
|
|
|
65028
65807
|
trackError("SMS_LIST_VERIFIED_FAILED", "sms:verify-number:list", {
|
|
65029
65808
|
error: errorMessage
|
|
65030
65809
|
});
|
|
65031
|
-
|
|
65810
|
+
clack64.log.error(`Failed to list verified numbers: ${errorMessage}`);
|
|
65032
65811
|
process.exit(1);
|
|
65033
65812
|
}
|
|
65034
65813
|
}
|
|
@@ -65036,10 +65815,10 @@ Run ${pc66.cyan("wraps sms verify-number")} to verify a number.
|
|
|
65036
65815
|
const phoneNumber2 = options.phoneNumber;
|
|
65037
65816
|
if (!phoneNumber2) {
|
|
65038
65817
|
progress.stop();
|
|
65039
|
-
|
|
65818
|
+
clack64.log.error("Phone number is required for deletion");
|
|
65040
65819
|
console.log(
|
|
65041
65820
|
`
|
|
65042
|
-
Usage: ${
|
|
65821
|
+
Usage: ${pc67.cyan("wraps sms verify-number --delete --phone-number +14155551234")}
|
|
65043
65822
|
`
|
|
65044
65823
|
);
|
|
65045
65824
|
process.exit(1);
|
|
@@ -65053,7 +65832,7 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
65053
65832
|
const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
|
|
65054
65833
|
if (!verifiedNumber?.VerifiedDestinationNumberId) {
|
|
65055
65834
|
progress.stop();
|
|
65056
|
-
|
|
65835
|
+
clack64.log.error(`Number ${phoneNumber2} is not in verified list`);
|
|
65057
65836
|
process.exit(1);
|
|
65058
65837
|
}
|
|
65059
65838
|
await progress.execute(`Removing ${phoneNumber2}`, async () => {
|
|
@@ -65064,7 +65843,7 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
65064
65843
|
);
|
|
65065
65844
|
});
|
|
65066
65845
|
progress.stop();
|
|
65067
|
-
|
|
65846
|
+
clack64.log.success(`Removed ${pc67.cyan(phoneNumber2)} from verified list`);
|
|
65068
65847
|
trackCommand("sms:verify-number:delete", {
|
|
65069
65848
|
success: true,
|
|
65070
65849
|
duration_ms: Date.now() - startTime
|
|
@@ -65076,7 +65855,7 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
65076
65855
|
});
|
|
65077
65856
|
return;
|
|
65078
65857
|
}
|
|
65079
|
-
|
|
65858
|
+
clack64.outro(pc67.green("Done!"));
|
|
65080
65859
|
return;
|
|
65081
65860
|
} catch (error) {
|
|
65082
65861
|
progress.stop();
|
|
@@ -65084,7 +65863,7 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
65084
65863
|
trackError("SMS_DELETE_VERIFIED_FAILED", "sms:verify-number:delete", {
|
|
65085
65864
|
error: errorMessage
|
|
65086
65865
|
});
|
|
65087
|
-
|
|
65866
|
+
clack64.log.error(`Failed to delete verified number: ${errorMessage}`);
|
|
65088
65867
|
process.exit(1);
|
|
65089
65868
|
}
|
|
65090
65869
|
}
|
|
@@ -65097,7 +65876,7 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
65097
65876
|
);
|
|
65098
65877
|
}
|
|
65099
65878
|
if (!phoneNumber) {
|
|
65100
|
-
const result = await
|
|
65879
|
+
const result = await clack64.text({
|
|
65101
65880
|
message: "Enter phone number to verify (E.164 format):",
|
|
65102
65881
|
placeholder: "+14155551234",
|
|
65103
65882
|
validate: (value) => {
|
|
@@ -65110,14 +65889,14 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
65110
65889
|
return;
|
|
65111
65890
|
}
|
|
65112
65891
|
});
|
|
65113
|
-
if (
|
|
65114
|
-
|
|
65892
|
+
if (clack64.isCancel(result)) {
|
|
65893
|
+
clack64.cancel("Operation cancelled.");
|
|
65115
65894
|
process.exit(0);
|
|
65116
65895
|
}
|
|
65117
65896
|
phoneNumber = result;
|
|
65118
65897
|
} else if (!isValidPhoneNumber(phoneNumber)) {
|
|
65119
65898
|
progress.stop();
|
|
65120
|
-
|
|
65899
|
+
clack64.log.error(
|
|
65121
65900
|
`Invalid phone number format: ${phoneNumber}. Use E.164 format (e.g., +14155551234)`
|
|
65122
65901
|
);
|
|
65123
65902
|
process.exit(1);
|
|
@@ -65132,7 +65911,7 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
65132
65911
|
const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
|
|
65133
65912
|
if (!verifiedNumber?.VerifiedDestinationNumberId) {
|
|
65134
65913
|
progress.stop();
|
|
65135
|
-
|
|
65914
|
+
clack64.log.error(
|
|
65136
65915
|
`Number ${phoneNumber} not found. Run without --code first.`
|
|
65137
65916
|
);
|
|
65138
65917
|
process.exit(1);
|
|
@@ -65147,12 +65926,12 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
65147
65926
|
});
|
|
65148
65927
|
progress.stop();
|
|
65149
65928
|
console.log("\n");
|
|
65150
|
-
|
|
65151
|
-
|
|
65929
|
+
clack64.log.success(
|
|
65930
|
+
pc67.green(`Phone number ${pc67.cyan(phoneNumber)} verified!`)
|
|
65152
65931
|
);
|
|
65153
65932
|
console.log("");
|
|
65154
65933
|
console.log(
|
|
65155
|
-
`You can now send test messages to this number with ${
|
|
65934
|
+
`You can now send test messages to this number with ${pc67.cyan("wraps sms test")}`
|
|
65156
65935
|
);
|
|
65157
65936
|
trackCommand("sms:verify-number:confirm", {
|
|
65158
65937
|
success: true,
|
|
@@ -65165,23 +65944,23 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
65165
65944
|
});
|
|
65166
65945
|
return;
|
|
65167
65946
|
}
|
|
65168
|
-
|
|
65947
|
+
clack64.outro(pc67.green("Verification complete!"));
|
|
65169
65948
|
return;
|
|
65170
65949
|
} catch (error) {
|
|
65171
65950
|
progress.stop();
|
|
65172
65951
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
65173
65952
|
if (errorMessage.includes("Invalid verification code")) {
|
|
65174
|
-
|
|
65953
|
+
clack64.log.error("Invalid verification code. Please try again.");
|
|
65175
65954
|
console.log(
|
|
65176
65955
|
`
|
|
65177
|
-
Run ${
|
|
65956
|
+
Run ${pc67.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
|
|
65178
65957
|
`
|
|
65179
65958
|
);
|
|
65180
65959
|
} else {
|
|
65181
65960
|
trackError("SMS_VERIFY_CODE_FAILED", "sms:verify-number:confirm", {
|
|
65182
65961
|
error: errorMessage
|
|
65183
65962
|
});
|
|
65184
|
-
|
|
65963
|
+
clack64.log.error(`Verification failed: ${errorMessage}`);
|
|
65185
65964
|
}
|
|
65186
65965
|
process.exit(1);
|
|
65187
65966
|
}
|
|
@@ -65196,7 +65975,7 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
65196
65975
|
const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
|
|
65197
65976
|
if (!verifiedNumber?.VerifiedDestinationNumberId) {
|
|
65198
65977
|
progress.stop();
|
|
65199
|
-
|
|
65978
|
+
clack64.log.error(
|
|
65200
65979
|
`Number ${phoneNumber} not found. Run without --resend first.`
|
|
65201
65980
|
);
|
|
65202
65981
|
process.exit(1);
|
|
@@ -65210,11 +65989,11 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
65210
65989
|
);
|
|
65211
65990
|
});
|
|
65212
65991
|
progress.stop();
|
|
65213
|
-
|
|
65992
|
+
clack64.log.success(`Verification code resent to ${pc67.cyan(phoneNumber)}`);
|
|
65214
65993
|
console.log("");
|
|
65215
65994
|
console.log(
|
|
65216
65995
|
`Once you receive the code, run:
|
|
65217
|
-
${
|
|
65996
|
+
${pc67.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
|
|
65218
65997
|
);
|
|
65219
65998
|
trackCommand("sms:verify-number:resend", {
|
|
65220
65999
|
success: true,
|
|
@@ -65227,7 +66006,7 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
65227
66006
|
});
|
|
65228
66007
|
return;
|
|
65229
66008
|
}
|
|
65230
|
-
|
|
66009
|
+
clack64.outro(pc67.green("Code sent!"));
|
|
65231
66010
|
return;
|
|
65232
66011
|
} catch (error) {
|
|
65233
66012
|
progress.stop();
|
|
@@ -65235,7 +66014,7 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
65235
66014
|
trackError("SMS_RESEND_CODE_FAILED", "sms:verify-number:resend", {
|
|
65236
66015
|
error: errorMessage
|
|
65237
66016
|
});
|
|
65238
|
-
|
|
66017
|
+
clack64.log.error(`Failed to resend code: ${errorMessage}`);
|
|
65239
66018
|
process.exit(1);
|
|
65240
66019
|
}
|
|
65241
66020
|
}
|
|
@@ -65255,10 +66034,10 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
65255
66034
|
});
|
|
65256
66035
|
return;
|
|
65257
66036
|
}
|
|
65258
|
-
|
|
65259
|
-
`Number ${
|
|
66037
|
+
clack64.log.info(
|
|
66038
|
+
`Number ${pc67.cyan(phoneNumber)} is already verified and ready to use!`
|
|
65260
66039
|
);
|
|
65261
|
-
|
|
66040
|
+
clack64.outro(pc67.green("Done!"));
|
|
65262
66041
|
return;
|
|
65263
66042
|
}
|
|
65264
66043
|
if (existingNumber?.Status === "PENDING") {
|
|
@@ -65282,15 +66061,15 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
65282
66061
|
});
|
|
65283
66062
|
return;
|
|
65284
66063
|
}
|
|
65285
|
-
|
|
65286
|
-
`Verification already in progress. New code sent to ${
|
|
66064
|
+
clack64.log.info(
|
|
66065
|
+
`Verification already in progress. New code sent to ${pc67.cyan(phoneNumber)}`
|
|
65287
66066
|
);
|
|
65288
66067
|
console.log("");
|
|
65289
66068
|
console.log(
|
|
65290
66069
|
`Once you receive the code, run:
|
|
65291
|
-
${
|
|
66070
|
+
${pc67.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
|
|
65292
66071
|
);
|
|
65293
|
-
|
|
66072
|
+
clack64.outro(pc67.green("Code sent!"));
|
|
65294
66073
|
return;
|
|
65295
66074
|
}
|
|
65296
66075
|
const createResponse = await progress.execute(
|
|
@@ -65311,18 +66090,18 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
65311
66090
|
});
|
|
65312
66091
|
progress.stop();
|
|
65313
66092
|
console.log("\n");
|
|
65314
|
-
|
|
65315
|
-
`Verification code sent to ${
|
|
66093
|
+
clack64.log.success(
|
|
66094
|
+
`Verification code sent to ${pc67.cyan(phoneNumber)} via SMS`
|
|
65316
66095
|
);
|
|
65317
66096
|
console.log("");
|
|
65318
|
-
|
|
66097
|
+
clack64.note(
|
|
65319
66098
|
[
|
|
65320
66099
|
"1. Check your phone for the verification code",
|
|
65321
66100
|
"",
|
|
65322
66101
|
"2. Complete verification with:",
|
|
65323
|
-
` ${
|
|
66102
|
+
` ${pc67.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`,
|
|
65324
66103
|
"",
|
|
65325
|
-
|
|
66104
|
+
pc67.dim("The code expires in 24 hours")
|
|
65326
66105
|
].join("\n"),
|
|
65327
66106
|
"Next Steps"
|
|
65328
66107
|
);
|
|
@@ -65338,22 +66117,22 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
65338
66117
|
});
|
|
65339
66118
|
return;
|
|
65340
66119
|
}
|
|
65341
|
-
|
|
66120
|
+
clack64.outro(pc67.green("Verification started!"));
|
|
65342
66121
|
} catch (error) {
|
|
65343
66122
|
progress.stop();
|
|
65344
66123
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
65345
66124
|
if (errorMessage.includes("already exists")) {
|
|
65346
|
-
|
|
66125
|
+
clack64.log.error("This number is already being verified");
|
|
65347
66126
|
console.log(
|
|
65348
66127
|
`
|
|
65349
|
-
Run ${
|
|
66128
|
+
Run ${pc67.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
|
|
65350
66129
|
`
|
|
65351
66130
|
);
|
|
65352
66131
|
} else {
|
|
65353
66132
|
trackError("SMS_CREATE_VERIFIED_FAILED", "sms:verify-number:start", {
|
|
65354
66133
|
error: errorMessage
|
|
65355
66134
|
});
|
|
65356
|
-
|
|
66135
|
+
clack64.log.error(`Failed to start verification: ${errorMessage}`);
|
|
65357
66136
|
}
|
|
65358
66137
|
process.exit(1);
|
|
65359
66138
|
}
|
|
@@ -65362,91 +66141,91 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
65362
66141
|
// src/commands/support.ts
|
|
65363
66142
|
init_esm_shims();
|
|
65364
66143
|
init_events();
|
|
65365
|
-
import * as
|
|
65366
|
-
import
|
|
66144
|
+
import * as clack65 from "@clack/prompts";
|
|
66145
|
+
import pc68 from "picocolors";
|
|
65367
66146
|
async function support() {
|
|
65368
66147
|
trackCommand("support", { success: true });
|
|
65369
|
-
|
|
66148
|
+
clack65.intro(pc68.bold("Get Help with Wraps"));
|
|
65370
66149
|
console.log();
|
|
65371
|
-
console.log(` ${
|
|
66150
|
+
console.log(` ${pc68.bold("Email:")} ${pc68.cyan("hey@wraps.dev")}`);
|
|
65372
66151
|
console.log(
|
|
65373
|
-
` ${
|
|
66152
|
+
` ${pc68.bold("GitHub:")} ${pc68.cyan("https://github.com/wraps-dev/wraps/issues")}`
|
|
65374
66153
|
);
|
|
65375
|
-
console.log(` ${
|
|
66154
|
+
console.log(` ${pc68.bold("Docs:")} ${pc68.cyan("https://wraps.dev/docs")}`);
|
|
65376
66155
|
console.log(
|
|
65377
|
-
` ${
|
|
66156
|
+
` ${pc68.bold("AI docs:")} ${pc68.cyan("https://wraps.dev/llms-full.txt")} ${pc68.dim("(complete docs, one file)")}`
|
|
65378
66157
|
);
|
|
65379
66158
|
console.log();
|
|
65380
|
-
console.log(
|
|
66159
|
+
console.log(pc68.dim(" Response time: Usually within 24 hours"));
|
|
65381
66160
|
console.log();
|
|
65382
66161
|
}
|
|
65383
66162
|
|
|
65384
66163
|
// src/commands/telemetry.ts
|
|
65385
66164
|
init_esm_shims();
|
|
65386
66165
|
init_client();
|
|
65387
|
-
import * as
|
|
65388
|
-
import
|
|
66166
|
+
import * as clack66 from "@clack/prompts";
|
|
66167
|
+
import pc69 from "picocolors";
|
|
65389
66168
|
async function telemetryEnable() {
|
|
65390
66169
|
const client2 = getTelemetryClient();
|
|
65391
66170
|
const override = client2.enable();
|
|
65392
66171
|
if (override) {
|
|
65393
|
-
|
|
66172
|
+
clack66.log.warn(
|
|
65394
66173
|
"Telemetry enabled in config, but overridden by environment"
|
|
65395
66174
|
);
|
|
65396
|
-
console.log(` Reason: ${
|
|
65397
|
-
console.log(` Config: ${
|
|
66175
|
+
console.log(` Reason: ${pc69.yellow(override)}`);
|
|
66176
|
+
console.log(` Config: ${pc69.dim(client2.getConfigPath())}`);
|
|
65398
66177
|
console.log();
|
|
65399
66178
|
} else {
|
|
65400
|
-
|
|
65401
|
-
console.log(` Config: ${
|
|
66179
|
+
clack66.log.success(pc69.green("Telemetry enabled"));
|
|
66180
|
+
console.log(` Config: ${pc69.dim(client2.getConfigPath())}`);
|
|
65402
66181
|
console.log(`
|
|
65403
|
-
${
|
|
66182
|
+
${pc69.dim("Thank you for helping improve Wraps!")}
|
|
65404
66183
|
`);
|
|
65405
66184
|
}
|
|
65406
66185
|
}
|
|
65407
66186
|
async function telemetryDisable() {
|
|
65408
66187
|
const client2 = getTelemetryClient();
|
|
65409
66188
|
client2.disable();
|
|
65410
|
-
|
|
65411
|
-
console.log(` Config: ${
|
|
66189
|
+
clack66.log.success(pc69.green("Telemetry disabled"));
|
|
66190
|
+
console.log(` Config: ${pc69.dim(client2.getConfigPath())}`);
|
|
65412
66191
|
console.log(
|
|
65413
66192
|
`
|
|
65414
|
-
${
|
|
66193
|
+
${pc69.dim("You can re-enable with:")} wraps telemetry enable
|
|
65415
66194
|
`
|
|
65416
66195
|
);
|
|
65417
66196
|
}
|
|
65418
66197
|
async function telemetryStatus() {
|
|
65419
66198
|
const client2 = getTelemetryClient();
|
|
65420
|
-
|
|
66199
|
+
clack66.intro(pc69.bold("Telemetry Status"));
|
|
65421
66200
|
const override = client2.getEnvOverride();
|
|
65422
|
-
const status2 = client2.isEnabled() ?
|
|
66201
|
+
const status2 = client2.isEnabled() ? pc69.green("Enabled") : pc69.red("Disabled");
|
|
65423
66202
|
console.log();
|
|
65424
|
-
console.log(` ${
|
|
66203
|
+
console.log(` ${pc69.bold("Status:")} ${status2}`);
|
|
65425
66204
|
if (!client2.isEnabled() && override) {
|
|
65426
|
-
console.log(` ${
|
|
66205
|
+
console.log(` ${pc69.bold("Reason:")} ${pc69.yellow(override)}`);
|
|
65427
66206
|
}
|
|
65428
|
-
console.log(` ${
|
|
66207
|
+
console.log(` ${pc69.bold("Config file:")} ${pc69.dim(client2.getConfigPath())}`);
|
|
65429
66208
|
if (client2.isEnabled()) {
|
|
65430
66209
|
console.log();
|
|
65431
|
-
console.log(
|
|
65432
|
-
console.log(` ${
|
|
66210
|
+
console.log(pc69.bold(" How to opt-out:"));
|
|
66211
|
+
console.log(` ${pc69.cyan("wraps telemetry disable")}`);
|
|
65433
66212
|
console.log(
|
|
65434
|
-
` ${
|
|
66213
|
+
` ${pc69.dim("Or set:")} ${pc69.cyan("WRAPS_TELEMETRY_DISABLED=1")}`
|
|
65435
66214
|
);
|
|
65436
|
-
console.log(` ${
|
|
66215
|
+
console.log(` ${pc69.dim("Or set:")} ${pc69.cyan("DO_NOT_TRACK=1")}`);
|
|
65437
66216
|
} else {
|
|
65438
66217
|
console.log();
|
|
65439
|
-
console.log(
|
|
65440
|
-
console.log(` ${
|
|
66218
|
+
console.log(pc69.bold(" How to opt-in:"));
|
|
66219
|
+
console.log(` ${pc69.cyan("wraps telemetry enable")}`);
|
|
65441
66220
|
}
|
|
65442
66221
|
console.log();
|
|
65443
|
-
console.log(
|
|
66222
|
+
console.log(pc69.bold(" Debug mode:"));
|
|
65444
66223
|
console.log(
|
|
65445
|
-
` ${
|
|
66224
|
+
` ${pc69.dim("See what would be sent:")} ${pc69.cyan("WRAPS_TELEMETRY_DEBUG=1 wraps <command>")}`
|
|
65446
66225
|
);
|
|
65447
66226
|
console.log();
|
|
65448
66227
|
console.log(
|
|
65449
|
-
` ${
|
|
66228
|
+
` ${pc69.dim("Learn more:")} ${pc69.cyan("https://wraps.dev/docs/telemetry")}`
|
|
65450
66229
|
);
|
|
65451
66230
|
console.log();
|
|
65452
66231
|
}
|
|
@@ -65455,8 +66234,8 @@ async function telemetryStatus() {
|
|
|
65455
66234
|
init_esm_shims();
|
|
65456
66235
|
import { existsSync as existsSync20, mkdirSync as mkdirSync2, writeFileSync } from "fs";
|
|
65457
66236
|
import { join as join25 } from "path";
|
|
65458
|
-
import * as
|
|
65459
|
-
import
|
|
66237
|
+
import * as clack67 from "@clack/prompts";
|
|
66238
|
+
import pc70 from "picocolors";
|
|
65460
66239
|
var EXAMPLE_CASCADE_WORKFLOW = `import {
|
|
65461
66240
|
defineWorkflow,
|
|
65462
66241
|
sendEmail,
|
|
@@ -65551,30 +66330,30 @@ export default defineConfig({
|
|
|
65551
66330
|
});
|
|
65552
66331
|
`;
|
|
65553
66332
|
async function workflowInit(options = {}) {
|
|
65554
|
-
|
|
66333
|
+
clack67.intro(pc70.bgCyan(pc70.black(" wraps workflow init ")));
|
|
65555
66334
|
const wrapsDir = join25(process.cwd(), "wraps");
|
|
65556
66335
|
const workflowsDir = join25(wrapsDir, "workflows");
|
|
65557
66336
|
const configPath = join25(wrapsDir, "wraps.config.ts");
|
|
65558
66337
|
if (existsSync20(workflowsDir)) {
|
|
65559
|
-
|
|
65560
|
-
`Workflows directory already exists at ${
|
|
66338
|
+
clack67.log.info(
|
|
66339
|
+
`Workflows directory already exists at ${pc70.cyan("wraps/workflows/")}`
|
|
65561
66340
|
);
|
|
65562
66341
|
const files = existsSync20(join25(workflowsDir, "cart-recovery.ts")) || existsSync20(join25(workflowsDir, "welcome-sequence.ts"));
|
|
65563
66342
|
if (files && !options.yes) {
|
|
65564
|
-
const shouldContinue = await
|
|
66343
|
+
const shouldContinue = await clack67.confirm({
|
|
65565
66344
|
message: "Example files may already exist. Overwrite them?",
|
|
65566
66345
|
initialValue: false
|
|
65567
66346
|
});
|
|
65568
|
-
if (
|
|
65569
|
-
|
|
66347
|
+
if (clack67.isCancel(shouldContinue) || !shouldContinue) {
|
|
66348
|
+
clack67.log.info("Skipping file creation.");
|
|
65570
66349
|
showNextSteps2();
|
|
65571
|
-
|
|
66350
|
+
clack67.outro("Done!");
|
|
65572
66351
|
return;
|
|
65573
66352
|
}
|
|
65574
66353
|
}
|
|
65575
66354
|
}
|
|
65576
66355
|
try {
|
|
65577
|
-
const s2 =
|
|
66356
|
+
const s2 = clack67.spinner();
|
|
65578
66357
|
s2.start("Creating workflows directory...");
|
|
65579
66358
|
mkdirSync2(workflowsDir, { recursive: true });
|
|
65580
66359
|
s2.stop("Created wraps/workflows/");
|
|
@@ -65592,34 +66371,34 @@ async function workflowInit(options = {}) {
|
|
|
65592
66371
|
s2.stop("Created 2 example workflows");
|
|
65593
66372
|
if (!existsSync20(configPath)) {
|
|
65594
66373
|
writeFileSync(configPath, EXAMPLE_CONFIG, "utf-8");
|
|
65595
|
-
|
|
66374
|
+
clack67.log.info(`Created ${pc70.cyan("wraps/wraps.config.ts")}`);
|
|
65596
66375
|
}
|
|
65597
|
-
|
|
65598
|
-
`${
|
|
65599
|
-
${
|
|
65600
|
-
${
|
|
65601
|
-
${
|
|
66376
|
+
clack67.log.success(
|
|
66377
|
+
`${pc70.bold("Workflows scaffolded!")} Created:
|
|
66378
|
+
${pc70.cyan("wraps/wraps.config.ts")} \u2014 Project config
|
|
66379
|
+
${pc70.cyan("wraps/workflows/cart-recovery.ts")} \u2014 Cross-channel cascade example
|
|
66380
|
+
${pc70.cyan("wraps/workflows/welcome-sequence.ts")} \u2014 Welcome series example`
|
|
65602
66381
|
);
|
|
65603
66382
|
showNextSteps2();
|
|
65604
|
-
|
|
66383
|
+
clack67.outro(pc70.green("Happy orchestrating!"));
|
|
65605
66384
|
} catch (error) {
|
|
65606
|
-
|
|
66385
|
+
clack67.log.error(
|
|
65607
66386
|
`Failed to scaffold workflows: ${error instanceof Error ? error.message : String(error)}`
|
|
65608
66387
|
);
|
|
65609
|
-
|
|
66388
|
+
clack67.outro(pc70.red("Scaffolding failed."));
|
|
65610
66389
|
process.exitCode = 1;
|
|
65611
66390
|
}
|
|
65612
66391
|
}
|
|
65613
66392
|
function showNextSteps2() {
|
|
65614
|
-
|
|
65615
|
-
`${
|
|
66393
|
+
clack67.log.info(
|
|
66394
|
+
`${pc70.bold("Next steps:")}
|
|
65616
66395
|
|
|
65617
|
-
1. Edit ${
|
|
65618
|
-
2. Edit your workflows in ${
|
|
65619
|
-
3. Validate: ${
|
|
65620
|
-
4. Push: ${
|
|
66396
|
+
1. Edit ${pc70.cyan("wraps/wraps.config.ts")} with your org slug and domain
|
|
66397
|
+
2. Edit your workflows in ${pc70.cyan("wraps/workflows/")}
|
|
66398
|
+
3. Validate: ${pc70.cyan("wraps email workflows validate")}
|
|
66399
|
+
4. Push: ${pc70.cyan("wraps email workflows push")}
|
|
65621
66400
|
|
|
65622
|
-
${
|
|
66401
|
+
${pc70.dim("Docs:")} ${pc70.underline("https://wraps.dev/docs/guides/orchestration")}`
|
|
65623
66402
|
);
|
|
65624
66403
|
}
|
|
65625
66404
|
|
|
@@ -65663,7 +66442,10 @@ var STRING_FLAGS = [
|
|
|
65663
66442
|
"limit",
|
|
65664
66443
|
"cursor",
|
|
65665
66444
|
"set",
|
|
65666
|
-
"volume"
|
|
66445
|
+
"volume",
|
|
66446
|
+
"since",
|
|
66447
|
+
"filter",
|
|
66448
|
+
"source"
|
|
65667
66449
|
];
|
|
65668
66450
|
var BOOLEAN_FLAGS = [
|
|
65669
66451
|
"yes",
|
|
@@ -65694,7 +66476,11 @@ var BOOLEAN_FLAGS = [
|
|
|
65694
66476
|
"vdm-engagement",
|
|
65695
66477
|
"vdm-inbox",
|
|
65696
66478
|
"help",
|
|
65697
|
-
"version"
|
|
66479
|
+
"version",
|
|
66480
|
+
"follow",
|
|
66481
|
+
"errors",
|
|
66482
|
+
"live",
|
|
66483
|
+
"platform"
|
|
65698
66484
|
];
|
|
65699
66485
|
var NEGATED_BOOLEANS = [
|
|
65700
66486
|
{ positive: "open", camelKey: "noOpen" },
|
|
@@ -65819,235 +66605,244 @@ function showVersion() {
|
|
|
65819
66605
|
process.exit(0);
|
|
65820
66606
|
}
|
|
65821
66607
|
function showHelp() {
|
|
65822
|
-
|
|
66608
|
+
clack68.intro(pc72.bold(`WRAPS CLI v${VERSION}`));
|
|
65823
66609
|
console.log("Deploy AWS infrastructure to your account\n");
|
|
65824
66610
|
console.log("Usage: wraps [service] <command> [options]\n");
|
|
65825
66611
|
console.log("Services:");
|
|
65826
|
-
console.log(` ${
|
|
66612
|
+
console.log(` ${pc72.cyan("email")} Email infrastructure (AWS SES)`);
|
|
65827
66613
|
console.log(
|
|
65828
|
-
` ${
|
|
66614
|
+
` ${pc72.cyan("sms")} SMS infrastructure (AWS End User Messaging)`
|
|
65829
66615
|
);
|
|
65830
66616
|
console.log(
|
|
65831
|
-
` ${
|
|
66617
|
+
` ${pc72.cyan("cdn")} CDN infrastructure (AWS S3 + CloudFront)`
|
|
65832
66618
|
);
|
|
65833
66619
|
console.log(
|
|
65834
|
-
` ${
|
|
66620
|
+
` ${pc72.cyan("selfhost")} Self-hosted Wraps control plane (enterprise)`
|
|
65835
66621
|
);
|
|
65836
66622
|
console.log(
|
|
65837
|
-
` ${
|
|
66623
|
+
` ${pc72.cyan("license")} License key management (Wraps team only)
|
|
65838
66624
|
`
|
|
65839
66625
|
);
|
|
65840
66626
|
console.log("Email Commands:");
|
|
65841
66627
|
console.log(
|
|
65842
|
-
` ${
|
|
66628
|
+
` ${pc72.cyan("email init")} Deploy new email infrastructure`
|
|
65843
66629
|
);
|
|
65844
66630
|
console.log(
|
|
65845
|
-
` ${
|
|
66631
|
+
` ${pc72.cyan("email check")} Check email deliverability for a domain`
|
|
65846
66632
|
);
|
|
65847
66633
|
console.log(
|
|
65848
|
-
` ${
|
|
66634
|
+
` ${pc72.cyan("email connect")} Connect to existing AWS SES`
|
|
65849
66635
|
);
|
|
65850
66636
|
console.log(
|
|
65851
|
-
` ${
|
|
66637
|
+
` ${pc72.cyan("email status")} Show email infrastructure details`
|
|
65852
66638
|
);
|
|
65853
66639
|
console.log(
|
|
65854
|
-
` ${
|
|
66640
|
+
` ${pc72.cyan("email plan")} Show SES pricing plan and cheaper options`
|
|
65855
66641
|
);
|
|
65856
|
-
console.log(` ${
|
|
65857
|
-
console.log(` ${
|
|
66642
|
+
console.log(` ${pc72.cyan("email test")} Send a test email`);
|
|
66643
|
+
console.log(` ${pc72.cyan("email verify")} Verify domain DNS records`);
|
|
65858
66644
|
console.log(
|
|
65859
|
-
` ${
|
|
66645
|
+
` ${pc72.cyan("email sync")} Apply CLI updates to infrastructure`
|
|
65860
66646
|
);
|
|
65861
|
-
console.log(` ${
|
|
66647
|
+
console.log(` ${pc72.cyan("email upgrade")} Add features`);
|
|
65862
66648
|
console.log(
|
|
65863
|
-
` ${
|
|
66649
|
+
` ${pc72.cyan("email restore")} Restore original configuration`
|
|
65864
66650
|
);
|
|
65865
66651
|
console.log(
|
|
65866
|
-
` ${
|
|
66652
|
+
` ${pc72.cyan("email destroy")} Remove email infrastructure`
|
|
65867
66653
|
);
|
|
65868
66654
|
console.log(
|
|
65869
|
-
` ${
|
|
66655
|
+
` ${pc72.cyan("email doctor")} Diagnose and clean up email infrastructure`
|
|
65870
66656
|
);
|
|
65871
|
-
console.log(` ${
|
|
65872
|
-
console.log(` ${
|
|
65873
|
-
console.log(` ${
|
|
66657
|
+
console.log(` ${pc72.cyan("email domains add")} Add a domain to SES`);
|
|
66658
|
+
console.log(` ${pc72.cyan("email domains list")} List all domains`);
|
|
66659
|
+
console.log(` ${pc72.cyan("email domains remove")} Remove a domain`);
|
|
65874
66660
|
console.log(
|
|
65875
|
-
` ${
|
|
66661
|
+
` ${pc72.cyan("email inbound init")} Enable inbound email receiving`
|
|
65876
66662
|
);
|
|
65877
|
-
console.log(` ${
|
|
66663
|
+
console.log(` ${pc72.cyan("email inbound status")} Show inbound email status`);
|
|
65878
66664
|
console.log(
|
|
65879
|
-
` ${
|
|
66665
|
+
` ${pc72.cyan("email inbound verify")} Verify inbound DNS records`
|
|
65880
66666
|
);
|
|
65881
66667
|
console.log(
|
|
65882
|
-
` ${
|
|
66668
|
+
` ${pc72.cyan("email inbound test")} Send test email and verify receipt`
|
|
65883
66669
|
);
|
|
65884
66670
|
console.log(
|
|
65885
|
-
` ${
|
|
66671
|
+
` ${pc72.cyan("email inbound destroy")} Remove inbound email infrastructure
|
|
65886
66672
|
`
|
|
65887
66673
|
);
|
|
65888
66674
|
console.log("Agent Commands:");
|
|
65889
66675
|
console.log(
|
|
65890
|
-
` ${
|
|
66676
|
+
` ${pc72.cyan("email agent create")} Create a leashed agent mailbox`
|
|
65891
66677
|
);
|
|
65892
|
-
console.log(` ${
|
|
66678
|
+
console.log(` ${pc72.cyan("email agent list")} List agents`);
|
|
65893
66679
|
console.log(
|
|
65894
|
-
` ${
|
|
66680
|
+
` ${pc72.cyan("email agent kill")} Kill an agent (revoke sending)
|
|
65895
66681
|
`
|
|
65896
66682
|
);
|
|
65897
66683
|
console.log("Template Commands:");
|
|
65898
66684
|
console.log(
|
|
65899
|
-
` ${
|
|
66685
|
+
` ${pc72.cyan("email templates init")} Initialize templates-as-code`
|
|
65900
66686
|
);
|
|
65901
66687
|
console.log(
|
|
65902
|
-
` ${
|
|
66688
|
+
` ${pc72.cyan("email templates push")} Push templates to SES + dashboard`
|
|
65903
66689
|
);
|
|
65904
66690
|
console.log(
|
|
65905
|
-
` ${
|
|
66691
|
+
` ${pc72.cyan("email templates preview")} Preview templates in browser`
|
|
65906
66692
|
);
|
|
65907
66693
|
console.log(
|
|
65908
|
-
` ${
|
|
66694
|
+
` ${pc72.cyan("push")} ${pc72.dim("(alias for email templates push)")}
|
|
65909
66695
|
`
|
|
65910
66696
|
);
|
|
65911
66697
|
console.log("Workflow Commands:");
|
|
65912
66698
|
console.log(
|
|
65913
|
-
` ${
|
|
66699
|
+
` ${pc72.cyan("email workflows init")} Initialize workflows-as-code`
|
|
65914
66700
|
);
|
|
65915
66701
|
console.log(
|
|
65916
|
-
` ${
|
|
66702
|
+
` ${pc72.cyan("email workflows validate")} Validate workflow files`
|
|
65917
66703
|
);
|
|
65918
66704
|
console.log(
|
|
65919
|
-
` ${
|
|
66705
|
+
` ${pc72.cyan("email workflows push")} Push workflows to dashboard
|
|
65920
66706
|
`
|
|
65921
66707
|
);
|
|
65922
66708
|
console.log("SMS Commands:");
|
|
65923
|
-
console.log(` ${
|
|
66709
|
+
console.log(` ${pc72.cyan("sms init")} Deploy SMS infrastructure`);
|
|
65924
66710
|
console.log(
|
|
65925
|
-
` ${
|
|
66711
|
+
` ${pc72.cyan("sms status")} Show SMS infrastructure details`
|
|
65926
66712
|
);
|
|
65927
|
-
console.log(` ${
|
|
66713
|
+
console.log(` ${pc72.cyan("sms test")} Send a test SMS message`);
|
|
65928
66714
|
console.log(
|
|
65929
|
-
` ${
|
|
66715
|
+
` ${pc72.cyan("sms verify-number")} Verify a destination phone number`
|
|
65930
66716
|
);
|
|
65931
66717
|
console.log(
|
|
65932
|
-
` ${
|
|
66718
|
+
` ${pc72.cyan("sms sync")} Sync infrastructure (update Lambda, etc.)`
|
|
65933
66719
|
);
|
|
65934
|
-
console.log(` ${
|
|
65935
|
-
console.log(` ${
|
|
66720
|
+
console.log(` ${pc72.cyan("sms upgrade")} Upgrade SMS features`);
|
|
66721
|
+
console.log(` ${pc72.cyan("sms register")} Register toll-free number`);
|
|
65936
66722
|
console.log(
|
|
65937
|
-
` ${
|
|
66723
|
+
` ${pc72.cyan("sms destroy")} Remove SMS infrastructure
|
|
65938
66724
|
`
|
|
65939
66725
|
);
|
|
65940
66726
|
console.log("CDN Commands:");
|
|
65941
66727
|
console.log(
|
|
65942
|
-
` ${
|
|
66728
|
+
` ${pc72.cyan("cdn init")} Deploy CDN infrastructure (S3 + CloudFront)`
|
|
65943
66729
|
);
|
|
65944
66730
|
console.log(
|
|
65945
|
-
` ${
|
|
66731
|
+
` ${pc72.cyan("cdn status")} Show CDN infrastructure details`
|
|
65946
66732
|
);
|
|
65947
66733
|
console.log(
|
|
65948
|
-
` ${
|
|
66734
|
+
` ${pc72.cyan("cdn verify")} Check DNS and certificate status`
|
|
65949
66735
|
);
|
|
65950
66736
|
console.log(
|
|
65951
|
-
` ${
|
|
66737
|
+
` ${pc72.cyan("cdn upgrade")} Add custom domain after cert validation`
|
|
65952
66738
|
);
|
|
65953
66739
|
console.log(
|
|
65954
|
-
` ${
|
|
66740
|
+
` ${pc72.cyan("cdn sync")} Sync infrastructure with current config`
|
|
65955
66741
|
);
|
|
65956
66742
|
console.log(
|
|
65957
|
-
` ${
|
|
66743
|
+
` ${pc72.cyan("cdn destroy")} Remove CDN infrastructure
|
|
65958
66744
|
`
|
|
65959
66745
|
);
|
|
65960
66746
|
console.log("Self-Hosted Commands:");
|
|
65961
66747
|
console.log(
|
|
65962
|
-
` ${
|
|
66748
|
+
` ${pc72.cyan("selfhost deploy")} Deploy Wraps API to your AWS account`
|
|
66749
|
+
);
|
|
66750
|
+
console.log(
|
|
66751
|
+
` ${pc72.cyan("selfhost login")} Sign in to your self-hosted Wraps instance`
|
|
66752
|
+
);
|
|
66753
|
+
console.log(
|
|
66754
|
+
` ${pc72.cyan("selfhost logout")} Sign out of your self-hosted Wraps instance`
|
|
66755
|
+
);
|
|
66756
|
+
console.log(
|
|
66757
|
+
` ${pc72.cyan("selfhost upgrade")} Rebuild and redeploy the self-hosted API`
|
|
65963
66758
|
);
|
|
65964
66759
|
console.log(
|
|
65965
|
-
` ${
|
|
66760
|
+
` ${pc72.cyan("selfhost status")} Show self-hosted deployment details`
|
|
65966
66761
|
);
|
|
65967
66762
|
console.log(
|
|
65968
|
-
` ${
|
|
66763
|
+
` ${pc72.cyan("selfhost logs")} Stream logs from your self-hosted API, dashboard, and workers`
|
|
65969
66764
|
);
|
|
65970
66765
|
console.log(
|
|
65971
|
-
` ${
|
|
66766
|
+
` ${pc72.cyan("selfhost env")} Print env vars for hosting the dashboard yourself`
|
|
65972
66767
|
);
|
|
65973
66768
|
console.log(
|
|
65974
|
-
` ${
|
|
66769
|
+
` ${pc72.cyan("selfhost connect")} Connect your AWS account to your self-hosted instance`
|
|
65975
66770
|
);
|
|
65976
66771
|
console.log(
|
|
65977
|
-
` ${
|
|
66772
|
+
` ${pc72.cyan("selfhost update-role")} Refresh your self-hosted console role's permissions`
|
|
65978
66773
|
);
|
|
65979
66774
|
console.log(
|
|
65980
|
-
` ${
|
|
66775
|
+
` ${pc72.cyan("selfhost destroy")} Tear down the self-hosted deployment
|
|
65981
66776
|
`
|
|
65982
66777
|
);
|
|
65983
66778
|
console.log("Local Development:");
|
|
65984
66779
|
console.log(
|
|
65985
|
-
` ${
|
|
66780
|
+
` ${pc72.cyan("console")} Start local web console
|
|
65986
66781
|
`
|
|
65987
66782
|
);
|
|
65988
66783
|
console.log("Platform:");
|
|
65989
66784
|
console.log(
|
|
65990
|
-
` ${
|
|
66785
|
+
` ${pc72.cyan("platform")} Show platform info and pricing`
|
|
65991
66786
|
);
|
|
65992
66787
|
console.log(
|
|
65993
|
-
` ${
|
|
66788
|
+
` ${pc72.cyan("platform connect")} Connect to Wraps Platform (events + IAM)`
|
|
65994
66789
|
);
|
|
65995
66790
|
console.log(
|
|
65996
|
-
` ${
|
|
66791
|
+
` ${pc72.cyan("platform update-role")} Update platform IAM permissions
|
|
65997
66792
|
`
|
|
65998
66793
|
);
|
|
65999
66794
|
console.log("Auth:");
|
|
66000
66795
|
console.log(
|
|
66001
|
-
` ${
|
|
66796
|
+
` ${pc72.cyan("auth login")} Sign in to wraps.dev (device flow)`
|
|
66002
66797
|
);
|
|
66003
|
-
console.log(` ${
|
|
66798
|
+
console.log(` ${pc72.cyan("auth status")} Show current auth state`);
|
|
66004
66799
|
console.log(
|
|
66005
|
-
` ${
|
|
66800
|
+
` ${pc72.cyan("auth logout")} Sign out and remove stored token
|
|
66006
66801
|
`
|
|
66007
66802
|
);
|
|
66008
66803
|
console.log("AWS Setup:");
|
|
66009
66804
|
console.log(
|
|
66010
|
-
` ${
|
|
66805
|
+
` ${pc72.cyan("aws setup")} Interactive AWS setup wizard`
|
|
66011
66806
|
);
|
|
66012
66807
|
console.log(
|
|
66013
|
-
` ${
|
|
66808
|
+
` ${pc72.cyan("aws doctor")} Diagnose AWS configuration issues
|
|
66014
66809
|
`
|
|
66015
66810
|
);
|
|
66016
66811
|
console.log("Global Commands:");
|
|
66017
|
-
console.log(` ${
|
|
66018
|
-
console.log(` ${
|
|
66019
|
-
console.log(` ${
|
|
66020
|
-
console.log(` ${
|
|
66812
|
+
console.log(` ${pc72.cyan("status")} Show overview of all services`);
|
|
66813
|
+
console.log(` ${pc72.cyan("destroy")} Remove deployed infrastructure`);
|
|
66814
|
+
console.log(` ${pc72.cyan("permissions")} Show required AWS IAM permissions`);
|
|
66815
|
+
console.log(` ${pc72.cyan("completion")} Generate shell completion script`);
|
|
66021
66816
|
console.log(
|
|
66022
|
-
` ${
|
|
66817
|
+
` ${pc72.cyan("telemetry")} Manage anonymous telemetry settings`
|
|
66023
66818
|
);
|
|
66024
|
-
console.log(` ${
|
|
66025
|
-
console.log(` ${
|
|
66819
|
+
console.log(` ${pc72.cyan("update")} Update CLI to latest version`);
|
|
66820
|
+
console.log(` ${pc72.cyan("news")} Show recent Wraps updates`);
|
|
66026
66821
|
console.log(
|
|
66027
|
-
` ${
|
|
66822
|
+
` ${pc72.cyan("support")} Get help and support contact info
|
|
66028
66823
|
`
|
|
66029
66824
|
);
|
|
66030
66825
|
console.log("Options:");
|
|
66031
66826
|
console.log(
|
|
66032
|
-
` ${
|
|
66827
|
+
` ${pc72.dim("-p, --provider")} Hosting provider (vercel, aws, railway, other)`
|
|
66033
66828
|
);
|
|
66034
|
-
console.log(` ${
|
|
66035
|
-
console.log(` ${
|
|
66036
|
-
console.log(` ${
|
|
66037
|
-
console.log(` ${
|
|
66038
|
-
console.log(` ${
|
|
66039
|
-
console.log(` ${
|
|
66040
|
-
console.log(` ${
|
|
66829
|
+
console.log(` ${pc72.dim("-r, --region")} AWS region`);
|
|
66830
|
+
console.log(` ${pc72.dim("-d, --domain")} Domain name`);
|
|
66831
|
+
console.log(` ${pc72.dim("--account")} AWS account ID or alias`);
|
|
66832
|
+
console.log(` ${pc72.dim("--preset")} Configuration preset`);
|
|
66833
|
+
console.log(` ${pc72.dim("--token")} API key or token for auth`);
|
|
66834
|
+
console.log(` ${pc72.dim("-y, --yes")} Skip confirmation prompts`);
|
|
66835
|
+
console.log(` ${pc72.dim("-f, --force")} Force destructive operations`);
|
|
66041
66836
|
console.log(
|
|
66042
|
-
` ${
|
|
66837
|
+
` ${pc72.dim("--preview")} Preview changes without deploying`
|
|
66043
66838
|
);
|
|
66044
|
-
console.log(` ${
|
|
66839
|
+
console.log(` ${pc72.dim("-v, --version")} Show version number
|
|
66045
66840
|
`);
|
|
66046
66841
|
console.log(
|
|
66047
|
-
`Run ${
|
|
66842
|
+
`Run ${pc72.cyan("wraps <service> <command> --help")} for more information.`
|
|
66048
66843
|
);
|
|
66049
66844
|
console.log(
|
|
66050
|
-
`AI agents: complete docs at ${
|
|
66845
|
+
`AI agents: complete docs at ${pc72.cyan("https://wraps.dev/llms-full.txt")}
|
|
66051
66846
|
`
|
|
66052
66847
|
);
|
|
66053
66848
|
}
|
|
@@ -66069,27 +66864,27 @@ if (!primaryCommand) {
|
|
|
66069
66864
|
const telemetry = getTelemetryClient();
|
|
66070
66865
|
if (telemetry.shouldShowNotification()) {
|
|
66071
66866
|
console.log();
|
|
66072
|
-
|
|
66867
|
+
clack68.log.info(pc72.bold("Anonymous Telemetry"));
|
|
66073
66868
|
console.log(
|
|
66074
|
-
` Wraps collects ${
|
|
66869
|
+
` Wraps collects ${pc72.cyan("anonymous usage data")} to improve the CLI.`
|
|
66075
66870
|
);
|
|
66076
66871
|
console.log(
|
|
66077
|
-
` We ${
|
|
66872
|
+
` We ${pc72.bold("never")} collect: domains, AWS credentials, email content, or PII.`
|
|
66078
66873
|
);
|
|
66079
66874
|
console.log(
|
|
66080
|
-
` We ${
|
|
66875
|
+
` We ${pc72.bold("only")} collect: command names, success/failure, CLI version, OS.`
|
|
66081
66876
|
);
|
|
66082
66877
|
console.log();
|
|
66083
|
-
console.log(` Opt-out anytime: ${
|
|
66084
|
-
console.log(` Or set: ${
|
|
66085
|
-
console.log(` Learn more: ${
|
|
66878
|
+
console.log(` Opt-out anytime: ${pc72.cyan("wraps telemetry disable")}`);
|
|
66879
|
+
console.log(` Or set: ${pc72.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
|
|
66880
|
+
console.log(` Learn more: ${pc72.cyan("https://wraps.dev/docs")}`);
|
|
66086
66881
|
console.log();
|
|
66087
66882
|
telemetry.markNotificationShown();
|
|
66088
66883
|
}
|
|
66089
66884
|
trackCommand("interactive:menu", { success: true, duration_ms: 0 });
|
|
66090
|
-
|
|
66885
|
+
clack68.intro(pc72.bold(`WRAPS CLI v${VERSION}`));
|
|
66091
66886
|
console.log(" Deploy AWS infrastructure to your account.\n");
|
|
66092
|
-
const action = await
|
|
66887
|
+
const action = await clack68.select({
|
|
66093
66888
|
message: "What would you like to do?",
|
|
66094
66889
|
options: [
|
|
66095
66890
|
{
|
|
@@ -66139,13 +66934,13 @@ if (!primaryCommand) {
|
|
|
66139
66934
|
}
|
|
66140
66935
|
]
|
|
66141
66936
|
});
|
|
66142
|
-
if (
|
|
66937
|
+
if (clack68.isCancel(action)) {
|
|
66143
66938
|
trackCommand("interactive:cancel", {
|
|
66144
66939
|
success: true,
|
|
66145
66940
|
duration_ms: Date.now() - startTime
|
|
66146
66941
|
});
|
|
66147
66942
|
await telemetry.shutdown();
|
|
66148
|
-
|
|
66943
|
+
clack68.cancel("Operation cancelled.");
|
|
66149
66944
|
process.exit(0);
|
|
66150
66945
|
}
|
|
66151
66946
|
trackCommand(`interactive:${action}`, {
|
|
@@ -66225,20 +67020,20 @@ async function run() {
|
|
|
66225
67020
|
const telemetry = getTelemetryClient();
|
|
66226
67021
|
if (telemetry.shouldShowNotification()) {
|
|
66227
67022
|
console.log();
|
|
66228
|
-
|
|
67023
|
+
clack68.log.info(pc72.bold("Anonymous Telemetry"));
|
|
66229
67024
|
console.log(
|
|
66230
|
-
` Wraps collects ${
|
|
67025
|
+
` Wraps collects ${pc72.cyan("anonymous usage data")} to improve the CLI.`
|
|
66231
67026
|
);
|
|
66232
67027
|
console.log(
|
|
66233
|
-
` We ${
|
|
67028
|
+
` We ${pc72.bold("never")} collect: domains, AWS credentials, email content, or PII.`
|
|
66234
67029
|
);
|
|
66235
67030
|
console.log(
|
|
66236
|
-
` We ${
|
|
67031
|
+
` We ${pc72.bold("only")} collect: command names, success/failure, CLI version, OS.`
|
|
66237
67032
|
);
|
|
66238
67033
|
console.log();
|
|
66239
|
-
console.log(` Opt-out anytime: ${
|
|
66240
|
-
console.log(` Or set: ${
|
|
66241
|
-
console.log(` Learn more: ${
|
|
67034
|
+
console.log(` Opt-out anytime: ${pc72.cyan("wraps telemetry disable")}`);
|
|
67035
|
+
console.log(` Or set: ${pc72.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
|
|
67036
|
+
console.log(` Learn more: ${pc72.cyan("https://wraps.dev/docs")}`);
|
|
66242
67037
|
console.log();
|
|
66243
67038
|
telemetry.markNotificationShown();
|
|
66244
67039
|
}
|
|
@@ -66332,10 +67127,10 @@ async function run() {
|
|
|
66332
67127
|
break;
|
|
66333
67128
|
case "verify": {
|
|
66334
67129
|
if (!flags.domain) {
|
|
66335
|
-
|
|
67130
|
+
clack68.log.error("--domain flag is required");
|
|
66336
67131
|
console.log(
|
|
66337
67132
|
`
|
|
66338
|
-
Usage: ${
|
|
67133
|
+
Usage: ${pc72.cyan("wraps email verify --domain yourapp.com")}
|
|
66339
67134
|
`
|
|
66340
67135
|
);
|
|
66341
67136
|
throw new Error("Missing required flag: --domain");
|
|
@@ -66407,12 +67202,12 @@ Usage: ${pc71.cyan("wraps email verify --domain yourapp.com")}
|
|
|
66407
67202
|
});
|
|
66408
67203
|
break;
|
|
66409
67204
|
default:
|
|
66410
|
-
|
|
67205
|
+
clack68.log.error(
|
|
66411
67206
|
`Unknown inbound command: ${inboundSubCommand || "(none)"}`
|
|
66412
67207
|
);
|
|
66413
67208
|
console.log(
|
|
66414
67209
|
`
|
|
66415
|
-
Available commands: ${
|
|
67210
|
+
Available commands: ${pc72.cyan("init")}, ${pc72.cyan("destroy")}, ${pc72.cyan("status")}, ${pc72.cyan("verify")}, ${pc72.cyan("test")}, ${pc72.cyan("add")}, ${pc72.cyan("remove")}
|
|
66416
67211
|
`
|
|
66417
67212
|
);
|
|
66418
67213
|
throw new Error(
|
|
@@ -66449,12 +67244,12 @@ Available commands: ${pc71.cyan("init")}, ${pc71.cyan("destroy")}, ${pc71.cyan("
|
|
|
66449
67244
|
});
|
|
66450
67245
|
break;
|
|
66451
67246
|
default:
|
|
66452
|
-
|
|
67247
|
+
clack68.log.error(
|
|
66453
67248
|
`Unknown agent command: ${agentSubCommand || "(none)"}`
|
|
66454
67249
|
);
|
|
66455
67250
|
console.log(
|
|
66456
67251
|
`
|
|
66457
|
-
Available commands: ${
|
|
67252
|
+
Available commands: ${pc72.cyan("create")}, ${pc72.cyan("list")}, ${pc72.cyan("kill")}
|
|
66458
67253
|
`
|
|
66459
67254
|
);
|
|
66460
67255
|
throw new Error(
|
|
@@ -66506,12 +67301,12 @@ Available commands: ${pc71.cyan("create")}, ${pc71.cyan("list")}, ${pc71.cyan("k
|
|
|
66506
67301
|
break;
|
|
66507
67302
|
}
|
|
66508
67303
|
default:
|
|
66509
|
-
|
|
67304
|
+
clack68.log.error(
|
|
66510
67305
|
`Unknown reply command: ${replySubCommand || "(none)"}`
|
|
66511
67306
|
);
|
|
66512
67307
|
console.log(
|
|
66513
67308
|
`
|
|
66514
|
-
Available commands: ${
|
|
67309
|
+
Available commands: ${pc72.cyan("init")}, ${pc72.cyan("rotate")}, ${pc72.cyan("status")}, ${pc72.cyan("destroy")}, ${pc72.cyan("decode")}
|
|
66515
67310
|
`
|
|
66516
67311
|
);
|
|
66517
67312
|
throw new Error(
|
|
@@ -66536,10 +67331,10 @@ Available commands: ${pc71.cyan("init")}, ${pc71.cyan("rotate")}, ${pc71.cyan("s
|
|
|
66536
67331
|
break;
|
|
66537
67332
|
case "verify": {
|
|
66538
67333
|
if (!flags.domain) {
|
|
66539
|
-
|
|
67334
|
+
clack68.log.error("--domain flag is required");
|
|
66540
67335
|
console.log(
|
|
66541
67336
|
`
|
|
66542
|
-
Usage: ${
|
|
67337
|
+
Usage: ${pc72.cyan("wraps email domains verify --domain yourapp.com")}
|
|
66543
67338
|
`
|
|
66544
67339
|
);
|
|
66545
67340
|
throw new Error("Missing required flag: --domain");
|
|
@@ -66549,10 +67344,10 @@ Usage: ${pc71.cyan("wraps email domains verify --domain yourapp.com")}
|
|
|
66549
67344
|
}
|
|
66550
67345
|
case "get-dkim": {
|
|
66551
67346
|
if (!flags.domain) {
|
|
66552
|
-
|
|
67347
|
+
clack68.log.error("--domain flag is required");
|
|
66553
67348
|
console.log(
|
|
66554
67349
|
`
|
|
66555
|
-
Usage: ${
|
|
67350
|
+
Usage: ${pc72.cyan("wraps email domains get-dkim --domain yourapp.com")}
|
|
66556
67351
|
`
|
|
66557
67352
|
);
|
|
66558
67353
|
throw new Error("Missing required flag: --domain");
|
|
@@ -66562,10 +67357,10 @@ Usage: ${pc71.cyan("wraps email domains get-dkim --domain yourapp.com")}
|
|
|
66562
67357
|
}
|
|
66563
67358
|
case "remove": {
|
|
66564
67359
|
if (!flags.domain) {
|
|
66565
|
-
|
|
67360
|
+
clack68.log.error("--domain flag is required");
|
|
66566
67361
|
console.log(
|
|
66567
67362
|
`
|
|
66568
|
-
Usage: ${
|
|
67363
|
+
Usage: ${pc72.cyan("wraps email domains remove --domain yourapp.com --force")}
|
|
66569
67364
|
`
|
|
66570
67365
|
);
|
|
66571
67366
|
throw new Error("Missing required flag: --domain");
|
|
@@ -66595,12 +67390,12 @@ Usage: ${pc71.cyan("wraps email domains remove --domain yourapp.com --force")}
|
|
|
66595
67390
|
break;
|
|
66596
67391
|
}
|
|
66597
67392
|
default:
|
|
66598
|
-
|
|
67393
|
+
clack68.log.error(
|
|
66599
67394
|
`Unknown domains command: ${domainsSubCommand || "(none)"}`
|
|
66600
67395
|
);
|
|
66601
67396
|
console.log(
|
|
66602
67397
|
`
|
|
66603
|
-
Available commands: ${
|
|
67398
|
+
Available commands: ${pc72.cyan("add")}, ${pc72.cyan("list")}, ${pc72.cyan("verify")}, ${pc72.cyan("get-dkim")}, ${pc72.cyan("remove")}, ${pc72.cyan("config")}
|
|
66604
67399
|
`
|
|
66605
67400
|
);
|
|
66606
67401
|
throw new Error(
|
|
@@ -66642,12 +67437,12 @@ Available commands: ${pc71.cyan("add")}, ${pc71.cyan("list")}, ${pc71.cyan("veri
|
|
|
66642
67437
|
});
|
|
66643
67438
|
break;
|
|
66644
67439
|
default:
|
|
66645
|
-
|
|
67440
|
+
clack68.log.error(
|
|
66646
67441
|
`Unknown templates command: ${templatesSubCommand || "(none)"}`
|
|
66647
67442
|
);
|
|
66648
67443
|
console.log(
|
|
66649
67444
|
`
|
|
66650
|
-
Available commands: ${
|
|
67445
|
+
Available commands: ${pc72.cyan("init")}, ${pc72.cyan("push")}, ${pc72.cyan("preview")}
|
|
66651
67446
|
`
|
|
66652
67447
|
);
|
|
66653
67448
|
throw new Error(
|
|
@@ -66686,12 +67481,12 @@ Available commands: ${pc71.cyan("init")}, ${pc71.cyan("push")}, ${pc71.cyan("pre
|
|
|
66686
67481
|
});
|
|
66687
67482
|
break;
|
|
66688
67483
|
default:
|
|
66689
|
-
|
|
67484
|
+
clack68.log.error(
|
|
66690
67485
|
`Unknown workflows command: ${workflowsSubCommand || "(none)"}`
|
|
66691
67486
|
);
|
|
66692
67487
|
console.log(
|
|
66693
67488
|
`
|
|
66694
|
-
Available commands: ${
|
|
67489
|
+
Available commands: ${pc72.cyan("init")}, ${pc72.cyan("validate")}, ${pc72.cyan("push")}
|
|
66695
67490
|
`
|
|
66696
67491
|
);
|
|
66697
67492
|
throw new Error(
|
|
@@ -66716,7 +67511,7 @@ Available commands: ${pc71.cyan("init")}, ${pc71.cyan("validate")}, ${pc71.cyan(
|
|
|
66716
67511
|
case "get": {
|
|
66717
67512
|
const messageId = sub[3];
|
|
66718
67513
|
if (!messageId) {
|
|
66719
|
-
|
|
67514
|
+
clack68.log.error("Usage: wraps email logs get <message-id>");
|
|
66720
67515
|
throw new Error("Missing required argument: <message-id>");
|
|
66721
67516
|
}
|
|
66722
67517
|
await emailLogsGet({
|
|
@@ -66728,12 +67523,12 @@ Available commands: ${pc71.cyan("init")}, ${pc71.cyan("validate")}, ${pc71.cyan(
|
|
|
66728
67523
|
break;
|
|
66729
67524
|
}
|
|
66730
67525
|
default:
|
|
66731
|
-
|
|
67526
|
+
clack68.log.error(
|
|
66732
67527
|
`Unknown logs command: ${logsSubCommand || "(none)"}`
|
|
66733
67528
|
);
|
|
66734
67529
|
console.log(
|
|
66735
67530
|
`
|
|
66736
|
-
Available commands: ${
|
|
67531
|
+
Available commands: ${pc72.cyan("list")}, ${pc72.cyan("get <message-id>")}
|
|
66737
67532
|
`
|
|
66738
67533
|
);
|
|
66739
67534
|
throw new Error(
|
|
@@ -66758,10 +67553,10 @@ Available commands: ${pc71.cyan("list")}, ${pc71.cyan("get <message-id>")}
|
|
|
66758
67553
|
});
|
|
66759
67554
|
break;
|
|
66760
67555
|
default:
|
|
66761
|
-
|
|
67556
|
+
clack68.log.error(`Unknown email command: ${subCommand}`);
|
|
66762
67557
|
console.log(
|
|
66763
67558
|
`
|
|
66764
|
-
Run ${
|
|
67559
|
+
Run ${pc72.cyan("wraps --help")} for available commands.
|
|
66765
67560
|
`
|
|
66766
67561
|
);
|
|
66767
67562
|
throw new Error(`Unknown email command: ${subCommand}`);
|
|
@@ -66786,10 +67581,10 @@ Run ${pc71.cyan("wraps --help")} for available commands.
|
|
|
66786
67581
|
});
|
|
66787
67582
|
break;
|
|
66788
67583
|
default:
|
|
66789
|
-
|
|
67584
|
+
clack68.log.error(`Unknown license command: ${subCommand}`);
|
|
66790
67585
|
console.log(
|
|
66791
67586
|
`
|
|
66792
|
-
Run ${
|
|
67587
|
+
Run ${pc72.cyan("wraps --help")} for available commands.
|
|
66793
67588
|
`
|
|
66794
67589
|
);
|
|
66795
67590
|
throw new Error(`Unknown license command: ${subCommand}`);
|
|
@@ -66836,6 +67631,21 @@ Run ${pc71.cyan("wraps --help")} for available commands.
|
|
|
66836
67631
|
json: flags.json
|
|
66837
67632
|
});
|
|
66838
67633
|
break;
|
|
67634
|
+
case "logs":
|
|
67635
|
+
await selfhostLogs({
|
|
67636
|
+
region: flags.region,
|
|
67637
|
+
follow: flags.follow,
|
|
67638
|
+
errors: flags.errors,
|
|
67639
|
+
source: flags.source,
|
|
67640
|
+
since: flags.since,
|
|
67641
|
+
filter: flags.filter,
|
|
67642
|
+
interval: flags.interval,
|
|
67643
|
+
live: flags.live,
|
|
67644
|
+
platform: flags.platform,
|
|
67645
|
+
verbose: flags.verbose,
|
|
67646
|
+
json: flags.json
|
|
67647
|
+
});
|
|
67648
|
+
break;
|
|
66839
67649
|
case "login":
|
|
66840
67650
|
await selfhostLogin({
|
|
66841
67651
|
region: flags.region,
|
|
@@ -66873,10 +67683,10 @@ Run ${pc71.cyan("wraps --help")} for available commands.
|
|
|
66873
67683
|
});
|
|
66874
67684
|
break;
|
|
66875
67685
|
default:
|
|
66876
|
-
|
|
67686
|
+
clack68.log.error(`Unknown selfhost command: ${subCommand}`);
|
|
66877
67687
|
console.log(
|
|
66878
67688
|
`
|
|
66879
|
-
Run ${
|
|
67689
|
+
Run ${pc72.cyan("wraps --help")} for available commands.
|
|
66880
67690
|
`
|
|
66881
67691
|
);
|
|
66882
67692
|
throw new Error(`Unknown selfhost command: ${subCommand}`);
|
|
@@ -66956,10 +67766,10 @@ Run ${pc71.cyan("wraps --help")} for available commands.
|
|
|
66956
67766
|
});
|
|
66957
67767
|
break;
|
|
66958
67768
|
default:
|
|
66959
|
-
|
|
67769
|
+
clack68.log.error(`Unknown sms command: ${subCommand}`);
|
|
66960
67770
|
console.log(
|
|
66961
67771
|
`
|
|
66962
|
-
Run ${
|
|
67772
|
+
Run ${pc72.cyan("wraps --help")} for available commands.
|
|
66963
67773
|
`
|
|
66964
67774
|
);
|
|
66965
67775
|
throw new Error(`Unknown sms command: ${subCommand}`);
|
|
@@ -67020,10 +67830,10 @@ Run ${pc71.cyan("wraps --help")} for available commands.
|
|
|
67020
67830
|
});
|
|
67021
67831
|
break;
|
|
67022
67832
|
default:
|
|
67023
|
-
|
|
67833
|
+
clack68.log.error(`Unknown cdn command: ${subCommand}`);
|
|
67024
67834
|
console.log(
|
|
67025
67835
|
`
|
|
67026
|
-
Run ${
|
|
67836
|
+
Run ${pc72.cyan("wraps --help")} for available commands.
|
|
67027
67837
|
`
|
|
67028
67838
|
);
|
|
67029
67839
|
throw new Error(`Unknown cdn command: ${subCommand}`);
|
|
@@ -67045,13 +67855,13 @@ Run ${pc71.cyan("wraps --help")} for available commands.
|
|
|
67045
67855
|
});
|
|
67046
67856
|
break;
|
|
67047
67857
|
default:
|
|
67048
|
-
|
|
67858
|
+
clack68.log.error(
|
|
67049
67859
|
`Unknown workflow command: ${subCommand || "(none)"}`
|
|
67050
67860
|
);
|
|
67051
67861
|
console.log(`
|
|
67052
|
-
Available commands: ${
|
|
67862
|
+
Available commands: ${pc72.cyan("init")}
|
|
67053
67863
|
`);
|
|
67054
|
-
console.log(`Run ${
|
|
67864
|
+
console.log(`Run ${pc72.cyan("wraps --help")} for more information.
|
|
67055
67865
|
`);
|
|
67056
67866
|
throw new Error(
|
|
67057
67867
|
`Unknown workflow command: ${subCommand || "(none)"}`
|
|
@@ -67093,14 +67903,14 @@ Available commands: ${pc71.cyan("init")}
|
|
|
67093
67903
|
});
|
|
67094
67904
|
break;
|
|
67095
67905
|
default:
|
|
67096
|
-
|
|
67906
|
+
clack68.log.error(`Unknown platform command: ${subCommand}`);
|
|
67097
67907
|
console.log(
|
|
67098
67908
|
`
|
|
67099
|
-
Available commands: ${
|
|
67909
|
+
Available commands: ${pc72.cyan("connect")}, ${pc72.cyan("update-role")}
|
|
67100
67910
|
`
|
|
67101
67911
|
);
|
|
67102
67912
|
console.log(
|
|
67103
|
-
`Run ${
|
|
67913
|
+
`Run ${pc72.cyan("wraps platform")} for more information.
|
|
67104
67914
|
`
|
|
67105
67915
|
);
|
|
67106
67916
|
throw new Error(`Unknown platform command: ${subCommand}`);
|
|
@@ -67125,10 +67935,10 @@ Available commands: ${pc71.cyan("connect")}, ${pc71.cyan("update-role")}
|
|
|
67125
67935
|
await logout();
|
|
67126
67936
|
break;
|
|
67127
67937
|
default:
|
|
67128
|
-
|
|
67938
|
+
clack68.log.error(`Unknown auth command: ${subCommand || "(none)"}`);
|
|
67129
67939
|
console.log(
|
|
67130
67940
|
`
|
|
67131
|
-
Available commands: ${
|
|
67941
|
+
Available commands: ${pc72.cyan("login")}, ${pc72.cyan("status")}, ${pc72.cyan("logout")}
|
|
67132
67942
|
`
|
|
67133
67943
|
);
|
|
67134
67944
|
throw new Error(`Unknown auth command: ${subCommand || "(none)"}`);
|
|
@@ -67146,13 +67956,13 @@ Available commands: ${pc71.cyan("login")}, ${pc71.cyan("status")}, ${pc71.cyan("
|
|
|
67146
67956
|
await doctor();
|
|
67147
67957
|
break;
|
|
67148
67958
|
default:
|
|
67149
|
-
|
|
67959
|
+
clack68.log.error(`Unknown aws command: ${subCommand}`);
|
|
67150
67960
|
console.log(
|
|
67151
67961
|
`
|
|
67152
|
-
Available commands: ${
|
|
67962
|
+
Available commands: ${pc72.cyan("setup")}, ${pc72.cyan("doctor")}
|
|
67153
67963
|
`
|
|
67154
67964
|
);
|
|
67155
|
-
console.log(`Run ${
|
|
67965
|
+
console.log(`Run ${pc72.cyan("wraps --help")} for more information.
|
|
67156
67966
|
`);
|
|
67157
67967
|
throw new Error(`Unknown aws command: ${subCommand}`);
|
|
67158
67968
|
}
|
|
@@ -67233,10 +68043,10 @@ Available commands: ${pc71.cyan("setup")}, ${pc71.cyan("doctor")}
|
|
|
67233
68043
|
await telemetryStatus();
|
|
67234
68044
|
break;
|
|
67235
68045
|
default:
|
|
67236
|
-
|
|
68046
|
+
clack68.log.error(`Unknown telemetry command: ${subCommand}`);
|
|
67237
68047
|
console.log(
|
|
67238
68048
|
`
|
|
67239
|
-
Available commands: ${
|
|
68049
|
+
Available commands: ${pc72.cyan("enable")}, ${pc72.cyan("disable")}, ${pc72.cyan("status")}
|
|
67240
68050
|
`
|
|
67241
68051
|
);
|
|
67242
68052
|
throw new Error(`Unknown telemetry command: ${subCommand}`);
|
|
@@ -67260,10 +68070,10 @@ Please specify a command for ${primaryCommand} service.
|
|
|
67260
68070
|
showHelp();
|
|
67261
68071
|
break;
|
|
67262
68072
|
default:
|
|
67263
|
-
|
|
68073
|
+
clack68.log.error(`Unknown command: ${primaryCommand}`);
|
|
67264
68074
|
console.log(
|
|
67265
68075
|
`
|
|
67266
|
-
Run ${
|
|
68076
|
+
Run ${pc72.cyan("wraps --help")} for available commands.
|
|
67267
68077
|
`
|
|
67268
68078
|
);
|
|
67269
68079
|
throw new Error(`Unknown command: ${primaryCommand}`);
|