@wraps.dev/cli 2.21.5 → 2.21.6
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/cli.js
CHANGED
|
@@ -1748,8 +1748,8 @@ async function ensurePulumiWorkDir(options) {
|
|
|
1748
1748
|
);
|
|
1749
1749
|
return;
|
|
1750
1750
|
} catch (error) {
|
|
1751
|
-
const
|
|
1752
|
-
|
|
1751
|
+
const clack62 = await import("@clack/prompts");
|
|
1752
|
+
clack62.log.warn(
|
|
1753
1753
|
`S3 state backend unavailable (${error instanceof Error ? error.message : error}). Using local state.`
|
|
1754
1754
|
);
|
|
1755
1755
|
}
|
|
@@ -6730,7 +6730,7 @@ __export(pulumi_exports, {
|
|
|
6730
6730
|
import { exec } from "child_process";
|
|
6731
6731
|
import { existsSync as existsSync6, readdirSync as readdirSync2 } from "fs";
|
|
6732
6732
|
import { homedir as homedir3 } from "os";
|
|
6733
|
-
import { dirname as dirname2, join as join7 } from "path";
|
|
6733
|
+
import { delimiter, dirname as dirname2, join as join7 } from "path";
|
|
6734
6734
|
import { promisify } from "util";
|
|
6735
6735
|
import { PulumiCommand } from "@pulumi/pulumi/automation/index.js";
|
|
6736
6736
|
function findSdkInstalledPulumi() {
|
|
@@ -6739,8 +6739,9 @@ function findSdkInstalledPulumi() {
|
|
|
6739
6739
|
return;
|
|
6740
6740
|
}
|
|
6741
6741
|
const versions = readdirSync2(versionsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort().reverse();
|
|
6742
|
+
const binaryName = process.platform === "win32" ? "pulumi.exe" : "pulumi";
|
|
6742
6743
|
for (const version of versions) {
|
|
6743
|
-
const binPath = join7(versionsDir, version, "bin",
|
|
6744
|
+
const binPath = join7(versionsDir, version, "bin", binaryName);
|
|
6744
6745
|
if (existsSync6(binPath)) {
|
|
6745
6746
|
return dirname2(binPath);
|
|
6746
6747
|
}
|
|
@@ -6754,7 +6755,7 @@ async function checkPulumiInstalled() {
|
|
|
6754
6755
|
} catch {
|
|
6755
6756
|
const binDir = findSdkInstalledPulumi();
|
|
6756
6757
|
if (binDir) {
|
|
6757
|
-
process.env.PATH = `${binDir}
|
|
6758
|
+
process.env.PATH = `${binDir}${delimiter}${process.env.PATH}`;
|
|
6758
6759
|
return true;
|
|
6759
6760
|
}
|
|
6760
6761
|
return false;
|
|
@@ -6766,7 +6767,7 @@ async function ensurePulumiInstalled() {
|
|
|
6766
6767
|
try {
|
|
6767
6768
|
const cmd = await PulumiCommand.install();
|
|
6768
6769
|
const binDir = dirname2(cmd.command);
|
|
6769
|
-
process.env.PATH = `${binDir}
|
|
6770
|
+
process.env.PATH = `${binDir}${delimiter}${process.env.PATH}`;
|
|
6770
6771
|
return true;
|
|
6771
6772
|
} catch (_error) {
|
|
6772
6773
|
throw errors.pulumiNotInstalled();
|
|
@@ -6854,23 +6855,23 @@ async function withLockRetry(fn, options) {
|
|
|
6854
6855
|
if (parsed.code !== "STACK_LOCKED") {
|
|
6855
6856
|
throw error;
|
|
6856
6857
|
}
|
|
6857
|
-
const
|
|
6858
|
-
const
|
|
6858
|
+
const clack62 = await import("@clack/prompts");
|
|
6859
|
+
const pc66 = (await import("picocolors")).default;
|
|
6859
6860
|
if (options.autoConfirm) {
|
|
6860
|
-
|
|
6861
|
+
clack62.log.warn(
|
|
6861
6862
|
"Stack is locked from a previous interrupted run. Auto-clearing..."
|
|
6862
6863
|
);
|
|
6863
6864
|
} else {
|
|
6864
|
-
const shouldClear = await
|
|
6865
|
-
message: `Stack is locked from a previous interrupted run. ${
|
|
6865
|
+
const shouldClear = await clack62.confirm({
|
|
6866
|
+
message: `Stack is locked from a previous interrupted run. ${pc66.yellow("Clear the stale lock and retry?")}`,
|
|
6866
6867
|
initialValue: true
|
|
6867
6868
|
});
|
|
6868
|
-
if (
|
|
6869
|
+
if (clack62.isCancel(shouldClear) || !shouldClear) {
|
|
6869
6870
|
throw errors.stackLocked();
|
|
6870
6871
|
}
|
|
6871
6872
|
}
|
|
6872
6873
|
const cleared = await clearStackLocks(options.accountId, options.region);
|
|
6873
|
-
|
|
6874
|
+
clack62.log.info(
|
|
6874
6875
|
`Cleared ${cleared} lock file${cleared === 1 ? "" : "s"}. Retrying...`
|
|
6875
6876
|
);
|
|
6876
6877
|
return fn();
|
|
@@ -10204,8 +10205,8 @@ import { homedir as homedir4, tmpdir as tmpdir2 } from "os";
|
|
|
10204
10205
|
import { join as join23 } from "path";
|
|
10205
10206
|
import { Readable } from "stream";
|
|
10206
10207
|
import { pipeline } from "stream/promises";
|
|
10207
|
-
import { cancel as cancel35, confirm as confirm29, intro as
|
|
10208
|
-
import
|
|
10208
|
+
import { cancel as cancel35, confirm as confirm29, intro as intro57, isCancel as isCancel40, log as log55 } from "@clack/prompts";
|
|
10209
|
+
import pc64 from "picocolors";
|
|
10209
10210
|
function isStandaloneInstall() {
|
|
10210
10211
|
return process.execPath.includes(".wraps/runtime");
|
|
10211
10212
|
}
|
|
@@ -10234,7 +10235,7 @@ function detectPlatformArch() {
|
|
|
10234
10235
|
return { platform: platform2, arch };
|
|
10235
10236
|
}
|
|
10236
10237
|
async function update(currentVersion) {
|
|
10237
|
-
|
|
10238
|
+
intro57(pc64.bold("Wraps CLI Update"));
|
|
10238
10239
|
const progress = new DeploymentProgress();
|
|
10239
10240
|
const result = await progress.execute(
|
|
10240
10241
|
"Checking for updates...",
|
|
@@ -10246,20 +10247,20 @@ async function update(currentVersion) {
|
|
|
10246
10247
|
}
|
|
10247
10248
|
const { version: latestVersion, release } = result;
|
|
10248
10249
|
if (currentVersion === latestVersion) {
|
|
10249
|
-
progress.succeed(`Already up to date ${
|
|
10250
|
+
progress.succeed(`Already up to date ${pc64.dim(`(v${currentVersion})`)}`);
|
|
10250
10251
|
return;
|
|
10251
10252
|
}
|
|
10252
10253
|
console.log();
|
|
10253
|
-
|
|
10254
|
-
`Current version: ${
|
|
10255
|
-
Latest version: ${
|
|
10254
|
+
log55.info(
|
|
10255
|
+
`Current version: ${pc64.dim(`v${currentVersion}`)}
|
|
10256
|
+
Latest version: ${pc64.cyan(`v${latestVersion}`)}`
|
|
10256
10257
|
);
|
|
10257
10258
|
console.log();
|
|
10258
10259
|
if (!isStandaloneInstall()) {
|
|
10259
|
-
|
|
10260
|
+
log55.info(
|
|
10260
10261
|
`You installed Wraps via npm. Update with:
|
|
10261
10262
|
|
|
10262
|
-
${
|
|
10263
|
+
${pc64.cyan("npm update -g @wraps.dev/cli")}`
|
|
10263
10264
|
);
|
|
10264
10265
|
return;
|
|
10265
10266
|
}
|
|
@@ -10334,7 +10335,7 @@ async function update(currentVersion) {
|
|
|
10334
10335
|
});
|
|
10335
10336
|
console.log();
|
|
10336
10337
|
progress.succeed(
|
|
10337
|
-
`Updated to ${
|
|
10338
|
+
`Updated to ${pc64.cyan(`v${latestVersion}`)} successfully!`
|
|
10338
10339
|
);
|
|
10339
10340
|
} finally {
|
|
10340
10341
|
rmSync(tmp, { recursive: true, force: true });
|
|
@@ -10357,8 +10358,8 @@ init_esm_shims();
|
|
|
10357
10358
|
import { readFileSync as readFileSync3 } from "fs";
|
|
10358
10359
|
import { dirname as dirname5, join as join24 } from "path";
|
|
10359
10360
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
10360
|
-
import * as
|
|
10361
|
-
import
|
|
10361
|
+
import * as clack61 from "@clack/prompts";
|
|
10362
|
+
import pc65 from "picocolors";
|
|
10362
10363
|
|
|
10363
10364
|
// src/commands/auth/login.ts
|
|
10364
10365
|
init_esm_shims();
|
|
@@ -12281,7 +12282,17 @@ async function createServiceIAMRole(config2) {
|
|
|
12281
12282
|
}]
|
|
12282
12283
|
}`);
|
|
12283
12284
|
} else {
|
|
12284
|
-
|
|
12285
|
+
const identity = await aws2.getCallerIdentity();
|
|
12286
|
+
assumeRolePolicy = pulumi3.output(`{
|
|
12287
|
+
"Version": "2012-10-17",
|
|
12288
|
+
"Statement": [{
|
|
12289
|
+
"Effect": "Allow",
|
|
12290
|
+
"Principal": {
|
|
12291
|
+
"AWS": "arn:aws:iam::${identity.accountId}:root"
|
|
12292
|
+
},
|
|
12293
|
+
"Action": "sts:AssumeRole"
|
|
12294
|
+
}]
|
|
12295
|
+
}`);
|
|
12285
12296
|
}
|
|
12286
12297
|
const roleName = `wraps-${config2.serviceName}-role`;
|
|
12287
12298
|
const exists = await roleExists(roleName);
|
|
@@ -33212,6 +33223,7 @@ function buildConsolePolicyDocument2(emailConfig, smsConfig) {
|
|
|
33212
33223
|
init_esm_shims();
|
|
33213
33224
|
import { execSync as execSync2 } from "child_process";
|
|
33214
33225
|
import { randomBytes as randomBytes6 } from "crypto";
|
|
33226
|
+
import { writeFileSync } from "fs";
|
|
33215
33227
|
import { join as join20 } from "path";
|
|
33216
33228
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
33217
33229
|
import * as clack43 from "@clack/prompts";
|
|
@@ -33539,18 +33551,24 @@ async function selfhostDeploy(options) {
|
|
|
33539
33551
|
clack43.log.info(`To update: run ${pc46.cyan("wraps selfhost upgrade")}`);
|
|
33540
33552
|
process.exit(0);
|
|
33541
33553
|
}
|
|
33542
|
-
let
|
|
33543
|
-
|
|
33544
|
-
|
|
33545
|
-
|
|
33546
|
-
|
|
33547
|
-
|
|
33548
|
-
|
|
33549
|
-
|
|
33554
|
+
let resolvedDatabaseUrl = options.databaseUrl;
|
|
33555
|
+
let resolvedNeonProjectId;
|
|
33556
|
+
let neonApiKey;
|
|
33557
|
+
let neonOrgId;
|
|
33558
|
+
if (!resolvedDatabaseUrl) {
|
|
33559
|
+
neonApiKey = options.neonApiKey;
|
|
33560
|
+
if (!neonApiKey) {
|
|
33561
|
+
const neonApiKeyAnswer = await clack43.password({
|
|
33562
|
+
message: "Neon API key (create one at console.neon.tech/app/settings/api-keys):"
|
|
33563
|
+
});
|
|
33564
|
+
if (clack43.isCancel(neonApiKeyAnswer)) {
|
|
33565
|
+
clack43.cancel("Operation cancelled.");
|
|
33566
|
+
process.exit(0);
|
|
33567
|
+
}
|
|
33568
|
+
neonApiKey = neonApiKeyAnswer;
|
|
33550
33569
|
}
|
|
33551
|
-
|
|
33570
|
+
neonOrgId = options.neonOrgId;
|
|
33552
33571
|
}
|
|
33553
|
-
const neonOrgId = options.neonOrgId;
|
|
33554
33572
|
let licenseKey = options.licenseKey;
|
|
33555
33573
|
if (!licenseKey) {
|
|
33556
33574
|
const licenseKeyAnswer = await clack43.text({
|
|
@@ -33594,26 +33612,38 @@ async function selfhostDeploy(options) {
|
|
|
33594
33612
|
});
|
|
33595
33613
|
});
|
|
33596
33614
|
const lambdaZipPath = join20(repoRoot, "apps/api/lambda.zip");
|
|
33615
|
+
const distDir = join20(repoRoot, "apps/api/dist");
|
|
33597
33616
|
await progress.execute("Packaging Lambda", async () => {
|
|
33617
|
+
writeFileSync(join20(distDir, "package.json"), '{"type":"module"}\n');
|
|
33598
33618
|
execSync2("/bin/sh -c 'zip -r ../lambda.zip .'", {
|
|
33599
|
-
cwd:
|
|
33619
|
+
cwd: distDir,
|
|
33600
33620
|
stdio: childStdio
|
|
33601
33621
|
});
|
|
33602
33622
|
});
|
|
33603
|
-
|
|
33604
|
-
|
|
33605
|
-
|
|
33606
|
-
|
|
33607
|
-
|
|
33608
|
-
|
|
33609
|
-
|
|
33610
|
-
|
|
33611
|
-
|
|
33623
|
+
if (!resolvedDatabaseUrl) {
|
|
33624
|
+
const neonProject = await progress.execute(
|
|
33625
|
+
"Provisioning Neon PostgreSQL database",
|
|
33626
|
+
async () => provisionNeonProject(
|
|
33627
|
+
neonApiKey,
|
|
33628
|
+
buildNeonProjectName(identity.accountId, region),
|
|
33629
|
+
{ orgId: neonOrgId }
|
|
33630
|
+
)
|
|
33631
|
+
);
|
|
33632
|
+
progress.info(`Neon project created: ${pc46.cyan(neonProject.name)}`);
|
|
33633
|
+
resolvedDatabaseUrl = neonProject.connectionString;
|
|
33634
|
+
resolvedNeonProjectId = neonProject.id;
|
|
33635
|
+
}
|
|
33636
|
+
if (!resolvedDatabaseUrl) {
|
|
33637
|
+
throw new Error(
|
|
33638
|
+
"[bug] resolvedDatabaseUrl was not set after DB resolution"
|
|
33639
|
+
);
|
|
33640
|
+
}
|
|
33641
|
+
const databaseUrl = resolvedDatabaseUrl;
|
|
33612
33642
|
const unsubscribeSecret = randomBytes6(32).toString("hex");
|
|
33613
33643
|
const betterAuthSecret = randomBytes6(32).toString("hex");
|
|
33614
33644
|
const selfhostConfig = {
|
|
33615
|
-
neonProjectId:
|
|
33616
|
-
databaseUrl
|
|
33645
|
+
neonProjectId: resolvedNeonProjectId,
|
|
33646
|
+
databaseUrl,
|
|
33617
33647
|
licenseKey,
|
|
33618
33648
|
appUrl,
|
|
33619
33649
|
unsubscribeSecret,
|
|
@@ -33644,7 +33674,7 @@ async function selfhostDeploy(options) {
|
|
|
33644
33674
|
cwd: repoRoot,
|
|
33645
33675
|
env: {
|
|
33646
33676
|
...process.env,
|
|
33647
|
-
DATABASE_URL:
|
|
33677
|
+
DATABASE_URL: databaseUrl
|
|
33648
33678
|
}
|
|
33649
33679
|
});
|
|
33650
33680
|
});
|
|
@@ -33662,7 +33692,7 @@ async function selfhostDeploy(options) {
|
|
|
33662
33692
|
accountId: identity.accountId,
|
|
33663
33693
|
region,
|
|
33664
33694
|
lambdaZipPath,
|
|
33665
|
-
databaseUrl
|
|
33695
|
+
databaseUrl,
|
|
33666
33696
|
licenseKey,
|
|
33667
33697
|
appUrl,
|
|
33668
33698
|
unsubscribeSecret,
|
|
@@ -33784,7 +33814,7 @@ async function selfhostDeploy(options) {
|
|
|
33784
33814
|
`${pc46.bold("API URL:")} ${pc46.cyan(outputs.apiUrl)}`,
|
|
33785
33815
|
`${pc46.bold("Region:")} ${pc46.cyan(region)}`,
|
|
33786
33816
|
`${pc46.bold("Lambda ARN:")} ${pc46.dim(outputs.lambdaArn)}`,
|
|
33787
|
-
`${pc46.bold("Neon Project:")} ${pc46.dim(
|
|
33817
|
+
...resolvedNeonProjectId ? [`${pc46.bold("Neon Project:")} ${pc46.dim(resolvedNeonProjectId)}`] : [],
|
|
33788
33818
|
"",
|
|
33789
33819
|
pc46.dim("Next steps:"),
|
|
33790
33820
|
pc46.dim(` Set WRAPS_API_URL=${outputs.apiUrl} in your app`),
|
|
@@ -33797,36 +33827,112 @@ async function selfhostDeploy(options) {
|
|
|
33797
33827
|
);
|
|
33798
33828
|
}
|
|
33799
33829
|
|
|
33800
|
-
// src/commands/selfhost/
|
|
33830
|
+
// src/commands/selfhost/env.ts
|
|
33801
33831
|
init_esm_shims();
|
|
33802
33832
|
init_events();
|
|
33803
33833
|
init_aws();
|
|
33804
33834
|
init_json_output();
|
|
33805
33835
|
init_metadata();
|
|
33806
|
-
init_output();
|
|
33807
33836
|
init_region_resolver();
|
|
33808
33837
|
import * as clack44 from "@clack/prompts";
|
|
33809
33838
|
import pc47 from "picocolors";
|
|
33839
|
+
async function selfhostEnv(options) {
|
|
33840
|
+
const startTime = Date.now();
|
|
33841
|
+
if (!isJsonMode()) {
|
|
33842
|
+
clack44.intro(pc47.bold("Wraps Self-Hosted \u2014 Vercel Environment Variables"));
|
|
33843
|
+
}
|
|
33844
|
+
const identity = await validateAWSCredentials();
|
|
33845
|
+
const region = await resolveRegionForCommand({
|
|
33846
|
+
accountId: identity.accountId,
|
|
33847
|
+
optionRegion: options.region,
|
|
33848
|
+
service: "selfhost",
|
|
33849
|
+
label: "self-hosted deployment"
|
|
33850
|
+
});
|
|
33851
|
+
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
33852
|
+
if (!metadata?.services?.selfhost) {
|
|
33853
|
+
clack44.log.error("No self-hosted deployment found");
|
|
33854
|
+
console.log(
|
|
33855
|
+
`
|
|
33856
|
+
Run ${pc47.cyan("wraps selfhost deploy")} to deploy the self-hosted control plane.
|
|
33857
|
+
`
|
|
33858
|
+
);
|
|
33859
|
+
process.exit(1);
|
|
33860
|
+
return;
|
|
33861
|
+
}
|
|
33862
|
+
const { config: config2 } = metadata.services.selfhost;
|
|
33863
|
+
const env = {
|
|
33864
|
+
DATABASE_URL: config2.databaseUrl,
|
|
33865
|
+
NEXT_PUBLIC_APP_URL: config2.appUrl,
|
|
33866
|
+
CORS_ORIGIN: config2.appUrl,
|
|
33867
|
+
BETTER_AUTH_SECRET: config2.betterAuthSecret,
|
|
33868
|
+
WRAPS_LICENSE_KEY: config2.licenseKey,
|
|
33869
|
+
AWS_BACKEND_ACCOUNT_ID: identity.accountId
|
|
33870
|
+
};
|
|
33871
|
+
if (isJsonMode()) {
|
|
33872
|
+
jsonSuccess("selfhost.env", { env });
|
|
33873
|
+
return;
|
|
33874
|
+
}
|
|
33875
|
+
console.log("# Wraps Self-Hosted \u2014 environment for apps/web on Vercel");
|
|
33876
|
+
console.log(
|
|
33877
|
+
`# Deployment: ${identity.accountId} / ${region} \u2014 ${config2.appUrl}`
|
|
33878
|
+
);
|
|
33879
|
+
console.log(`# Generated: ${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
33880
|
+
console.log("");
|
|
33881
|
+
for (const [key, value] of Object.entries(env)) {
|
|
33882
|
+
console.log(`${key}=${value}`);
|
|
33883
|
+
}
|
|
33884
|
+
console.log("");
|
|
33885
|
+
console.log(
|
|
33886
|
+
"# AWS credentials for role assumption \u2014 create an IAM user in your account"
|
|
33887
|
+
);
|
|
33888
|
+
console.log(
|
|
33889
|
+
`# with sts:AssumeRole permission on arn:aws:iam::${identity.accountId}:role/wraps-console-access-role`
|
|
33890
|
+
);
|
|
33891
|
+
console.log("# AWS_ACCESS_KEY_ID=<fill-in>");
|
|
33892
|
+
console.log("# AWS_SECRET_ACCESS_KEY=<fill-in>");
|
|
33893
|
+
clack44.outro(
|
|
33894
|
+
pc47.dim(
|
|
33895
|
+
"Paste into Vercel \u2192 Settings \u2192 Environment Variables \u2192 Add from .env"
|
|
33896
|
+
)
|
|
33897
|
+
);
|
|
33898
|
+
trackCommand("selfhost:env", {
|
|
33899
|
+
success: true,
|
|
33900
|
+
duration_ms: Date.now() - startTime
|
|
33901
|
+
});
|
|
33902
|
+
}
|
|
33903
|
+
|
|
33904
|
+
// src/commands/selfhost/status.ts
|
|
33905
|
+
init_esm_shims();
|
|
33906
|
+
init_events();
|
|
33907
|
+
init_aws();
|
|
33908
|
+
init_json_output();
|
|
33909
|
+
init_metadata();
|
|
33910
|
+
init_output();
|
|
33911
|
+
init_region_resolver();
|
|
33912
|
+
import * as clack45 from "@clack/prompts";
|
|
33913
|
+
import pc48 from "picocolors";
|
|
33810
33914
|
function displaySelfhostStatus(options) {
|
|
33811
33915
|
const lines = [];
|
|
33812
|
-
lines.push(
|
|
33916
|
+
lines.push(pc48.bold(pc48.green("Self-Hosted Control Plane Active")));
|
|
33813
33917
|
lines.push("");
|
|
33814
|
-
lines.push(
|
|
33815
|
-
lines.push(` URL: ${
|
|
33816
|
-
lines.push(` Region: ${
|
|
33817
|
-
lines.push(` Deployed: ${
|
|
33918
|
+
lines.push(pc48.bold("API"));
|
|
33919
|
+
lines.push(` URL: ${pc48.cyan(options.apiUrl)}`);
|
|
33920
|
+
lines.push(` Region: ${pc48.cyan(options.region)}`);
|
|
33921
|
+
lines.push(` Deployed: ${pc48.dim(options.deployedAt)}`);
|
|
33818
33922
|
lines.push("");
|
|
33819
|
-
lines.push(
|
|
33820
|
-
lines.push(` App URL: ${
|
|
33821
|
-
lines.push(` License Key: ${
|
|
33822
|
-
|
|
33823
|
-
|
|
33923
|
+
lines.push(pc48.bold("Configuration"));
|
|
33924
|
+
lines.push(` App URL: ${pc48.cyan(options.appUrl)}`);
|
|
33925
|
+
lines.push(` License Key: ${pc48.dim(`${options.licenseKeyPrefix}...`)}`);
|
|
33926
|
+
if (options.neonProjectId) {
|
|
33927
|
+
lines.push(` Neon Project: ${pc48.dim(options.neonProjectId)}`);
|
|
33928
|
+
}
|
|
33929
|
+
clack45.note(lines.join("\n"), "Self-Hosted Status");
|
|
33824
33930
|
}
|
|
33825
33931
|
async function selfhostStatus(options) {
|
|
33826
33932
|
const startTime = Date.now();
|
|
33827
33933
|
const progress = new DeploymentProgress();
|
|
33828
33934
|
if (!isJsonMode()) {
|
|
33829
|
-
|
|
33935
|
+
clack45.intro(pc48.bold("Wraps Self-Hosted Status"));
|
|
33830
33936
|
}
|
|
33831
33937
|
const identity = await progress.execute(
|
|
33832
33938
|
"Loading self-hosted status",
|
|
@@ -33841,10 +33947,10 @@ async function selfhostStatus(options) {
|
|
|
33841
33947
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
33842
33948
|
if (!metadata?.services?.selfhost) {
|
|
33843
33949
|
progress.stop();
|
|
33844
|
-
|
|
33950
|
+
clack45.log.error("No self-hosted deployment found");
|
|
33845
33951
|
console.log(
|
|
33846
33952
|
`
|
|
33847
|
-
Run ${
|
|
33953
|
+
Run ${pc48.cyan("wraps selfhost deploy")} to deploy the self-hosted control plane.
|
|
33848
33954
|
`
|
|
33849
33955
|
);
|
|
33850
33956
|
process.exit(1);
|
|
@@ -33866,25 +33972,26 @@ Run ${pc47.cyan("wraps selfhost deploy")} to deploy the self-hosted control plan
|
|
|
33866
33972
|
}
|
|
33867
33973
|
displaySelfhostStatus(statusData);
|
|
33868
33974
|
console.log("");
|
|
33869
|
-
|
|
33975
|
+
clack45.log.info(pc48.bold("Commands:"));
|
|
33870
33976
|
console.log(
|
|
33871
|
-
` ${
|
|
33977
|
+
` ${pc48.cyan("wraps selfhost upgrade")} - Rebuild and redeploy the API Lambda`
|
|
33872
33978
|
);
|
|
33873
33979
|
trackCommand("selfhost:status", {
|
|
33874
33980
|
success: true,
|
|
33875
33981
|
duration_ms: Date.now() - startTime
|
|
33876
33982
|
});
|
|
33877
|
-
|
|
33983
|
+
clack45.outro(pc48.dim("Self-hosted deployment is active"));
|
|
33878
33984
|
}
|
|
33879
33985
|
|
|
33880
33986
|
// src/commands/selfhost/upgrade.ts
|
|
33881
33987
|
init_esm_shims();
|
|
33882
33988
|
import { execSync as execSync3 } from "child_process";
|
|
33989
|
+
import { writeFileSync as writeFileSync2 } from "fs";
|
|
33883
33990
|
import { join as join21 } from "path";
|
|
33884
33991
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
33885
|
-
import * as
|
|
33992
|
+
import * as clack46 from "@clack/prompts";
|
|
33886
33993
|
import * as pulumi27 from "@pulumi/pulumi";
|
|
33887
|
-
import
|
|
33994
|
+
import pc49 from "picocolors";
|
|
33888
33995
|
init_events();
|
|
33889
33996
|
init_aws();
|
|
33890
33997
|
init_errors();
|
|
@@ -33899,7 +34006,7 @@ var repoRoot2 = join21(__filename3, "../../../..");
|
|
|
33899
34006
|
async function selfhostUpgrade(options) {
|
|
33900
34007
|
const startTime = Date.now();
|
|
33901
34008
|
if (!isJsonMode()) {
|
|
33902
|
-
|
|
34009
|
+
clack46.intro(pc49.bold("Wraps Self-Hosted Control Plane Upgrade"));
|
|
33903
34010
|
}
|
|
33904
34011
|
const progress = new DeploymentProgress();
|
|
33905
34012
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -33914,7 +34021,7 @@ async function selfhostUpgrade(options) {
|
|
|
33914
34021
|
async () => validateAWSCredentialsWithDetails()
|
|
33915
34022
|
);
|
|
33916
34023
|
const identity = credentialResult.identity;
|
|
33917
|
-
progress.info(`Connected to AWS account: ${
|
|
34024
|
+
progress.info(`Connected to AWS account: ${pc49.cyan(identity.accountId)}`);
|
|
33918
34025
|
const region = await resolveRegionForCommand({
|
|
33919
34026
|
accountId: identity.accountId,
|
|
33920
34027
|
optionRegion: options.region,
|
|
@@ -33923,20 +34030,20 @@ async function selfhostUpgrade(options) {
|
|
|
33923
34030
|
});
|
|
33924
34031
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
33925
34032
|
if (!metadata?.services?.selfhost) {
|
|
33926
|
-
|
|
33927
|
-
|
|
34033
|
+
clack46.log.error("No self-hosted deployment found.");
|
|
34034
|
+
clack46.log.info(`Run ${pc49.cyan("wraps selfhost deploy")} first.`);
|
|
33928
34035
|
process.exit(1);
|
|
33929
34036
|
}
|
|
33930
34037
|
const selfhostService = metadata.services.selfhost;
|
|
33931
34038
|
progress.info(`Found deployment from: ${selfhostService.deployedAt}`);
|
|
33932
|
-
progress.info(`API URL: ${
|
|
34039
|
+
progress.info(`API URL: ${pc49.cyan(selfhostService.apiUrl)}`);
|
|
33933
34040
|
if (!(options.yes || options.preview)) {
|
|
33934
|
-
const confirmed = await
|
|
33935
|
-
message: `Upgrade self-hosted deployment in ${
|
|
34041
|
+
const confirmed = await clack46.confirm({
|
|
34042
|
+
message: `Upgrade self-hosted deployment in ${pc49.cyan(identity.accountId)} / ${pc49.cyan(region)}?`,
|
|
33936
34043
|
initialValue: true
|
|
33937
34044
|
});
|
|
33938
|
-
if (
|
|
33939
|
-
|
|
34045
|
+
if (clack46.isCancel(confirmed) || !confirmed) {
|
|
34046
|
+
clack46.cancel("Upgrade cancelled.");
|
|
33940
34047
|
process.exit(0);
|
|
33941
34048
|
}
|
|
33942
34049
|
}
|
|
@@ -33950,9 +34057,11 @@ async function selfhostUpgrade(options) {
|
|
|
33950
34057
|
});
|
|
33951
34058
|
});
|
|
33952
34059
|
const lambdaZipPath = join21(repoRoot2, "apps/api/lambda.zip");
|
|
34060
|
+
const distDir = join21(repoRoot2, "apps/api/dist");
|
|
33953
34061
|
await progress.execute("Packaging Lambda", async () => {
|
|
34062
|
+
writeFileSync2(join21(distDir, "package.json"), '{"type":"module"}\n');
|
|
33954
34063
|
execSync3("/bin/sh -c 'zip -r ../lambda.zip .'", {
|
|
33955
|
-
cwd:
|
|
34064
|
+
cwd: distDir,
|
|
33956
34065
|
stdio: childStdio
|
|
33957
34066
|
});
|
|
33958
34067
|
});
|
|
@@ -34018,8 +34127,8 @@ async function selfhostUpgrade(options) {
|
|
|
34018
34127
|
resourceChanges: previewResult.resourceChanges,
|
|
34019
34128
|
commandName: "wraps selfhost upgrade"
|
|
34020
34129
|
});
|
|
34021
|
-
|
|
34022
|
-
|
|
34130
|
+
clack46.outro(
|
|
34131
|
+
pc49.green("Preview complete. Run without --preview to upgrade.")
|
|
34023
34132
|
);
|
|
34024
34133
|
return;
|
|
34025
34134
|
} catch (error) {
|
|
@@ -34090,28 +34199,28 @@ async function selfhostUpgrade(options) {
|
|
|
34090
34199
|
}
|
|
34091
34200
|
progress.info("Deployment metadata updated");
|
|
34092
34201
|
console.log("\n");
|
|
34093
|
-
|
|
34202
|
+
clack46.log.success(pc49.green(pc49.bold("Self-hosted Wraps API upgraded!")));
|
|
34094
34203
|
console.log("\n");
|
|
34095
|
-
|
|
34204
|
+
clack46.note(
|
|
34096
34205
|
[
|
|
34097
|
-
`${
|
|
34098
|
-
`${
|
|
34099
|
-
`${
|
|
34206
|
+
`${pc49.bold("API URL:")} ${pc49.cyan(outputs.apiUrl || selfhostService.apiUrl)}`,
|
|
34207
|
+
`${pc49.bold("Region:")} ${pc49.cyan(region)}`,
|
|
34208
|
+
`${pc49.bold("Lambda ARN:")} ${pc49.dim(outputs.lambdaArn)}`
|
|
34100
34209
|
].join("\n"),
|
|
34101
34210
|
"Self-Hosted Deployment"
|
|
34102
34211
|
);
|
|
34103
|
-
|
|
34104
|
-
|
|
34212
|
+
clack46.outro(
|
|
34213
|
+
pc49.green(`Upgraded in ${((Date.now() - startTime) / 1e3).toFixed(1)}s`)
|
|
34105
34214
|
);
|
|
34106
34215
|
}
|
|
34107
34216
|
|
|
34108
34217
|
// src/commands/shared/dashboard.ts
|
|
34109
34218
|
init_esm_shims();
|
|
34110
|
-
import * as
|
|
34219
|
+
import * as clack47 from "@clack/prompts";
|
|
34111
34220
|
import * as pulumi28 from "@pulumi/pulumi";
|
|
34112
34221
|
import getPort from "get-port";
|
|
34113
34222
|
import open2 from "open";
|
|
34114
|
-
import
|
|
34223
|
+
import pc50 from "picocolors";
|
|
34115
34224
|
|
|
34116
34225
|
// src/console/server.ts
|
|
34117
34226
|
init_esm_shims();
|
|
@@ -35311,13 +35420,13 @@ function createMetricsRouter(config2) {
|
|
|
35311
35420
|
const router = createRouter5();
|
|
35312
35421
|
router.get("/stream", async (req, res) => {
|
|
35313
35422
|
const connectionId = randomUUID().slice(0, 8);
|
|
35314
|
-
const
|
|
35423
|
+
const log57 = (msg, data) => {
|
|
35315
35424
|
console.log(JSON.stringify({ connectionId, msg, ...data }));
|
|
35316
35425
|
};
|
|
35317
35426
|
res.setHeader("Content-Type", "text/event-stream");
|
|
35318
35427
|
res.setHeader("Cache-Control", "no-cache");
|
|
35319
35428
|
res.setHeader("Connection", "keep-alive");
|
|
35320
|
-
|
|
35429
|
+
log57("SSE connected");
|
|
35321
35430
|
res.write('data: {"type":"connected"}\n\n');
|
|
35322
35431
|
const { startTime, endTime } = req.query;
|
|
35323
35432
|
const getTimeRange = () => ({
|
|
@@ -35327,7 +35436,7 @@ function createMetricsRouter(config2) {
|
|
|
35327
35436
|
const sendMetrics = async () => {
|
|
35328
35437
|
try {
|
|
35329
35438
|
const timeRange = getTimeRange();
|
|
35330
|
-
|
|
35439
|
+
log57("Fetching metrics", {
|
|
35331
35440
|
start: timeRange.start.toISOString(),
|
|
35332
35441
|
end: timeRange.end.toISOString()
|
|
35333
35442
|
});
|
|
@@ -35340,7 +35449,7 @@ function createMetricsRouter(config2) {
|
|
|
35340
35449
|
),
|
|
35341
35450
|
fetchSendQuota(config2.roleArn, config2.region)
|
|
35342
35451
|
]);
|
|
35343
|
-
|
|
35452
|
+
log57("Metrics fetched successfully");
|
|
35344
35453
|
const data = {
|
|
35345
35454
|
type: "metrics",
|
|
35346
35455
|
timestamp: Date.now(),
|
|
@@ -35370,7 +35479,7 @@ function createMetricsRouter(config2) {
|
|
|
35370
35479
|
const interval = setInterval(sendMetrics, 6e4);
|
|
35371
35480
|
req.on("close", () => {
|
|
35372
35481
|
clearInterval(interval);
|
|
35373
|
-
|
|
35482
|
+
log57("SSE disconnected");
|
|
35374
35483
|
});
|
|
35375
35484
|
});
|
|
35376
35485
|
router.get("/snapshot", async (_req, res) => {
|
|
@@ -36765,7 +36874,7 @@ init_output();
|
|
|
36765
36874
|
init_pulumi();
|
|
36766
36875
|
async function dashboard(options) {
|
|
36767
36876
|
await ensurePulumiInstalled();
|
|
36768
|
-
|
|
36877
|
+
clack47.intro(pc50.bold("Wraps Dashboard"));
|
|
36769
36878
|
const progress = new DeploymentProgress();
|
|
36770
36879
|
const identity = await progress.execute(
|
|
36771
36880
|
"Validating AWS credentials",
|
|
@@ -36806,9 +36915,9 @@ async function dashboard(options) {
|
|
|
36806
36915
|
}
|
|
36807
36916
|
} catch (_error) {
|
|
36808
36917
|
progress.stop();
|
|
36809
|
-
|
|
36918
|
+
clack47.log.error("No Wraps infrastructure found");
|
|
36810
36919
|
console.log(
|
|
36811
|
-
`\\nRun ${
|
|
36920
|
+
`\\nRun ${pc50.cyan("wraps email init")}, ${pc50.cyan("wraps sms init")}, or ${pc50.cyan("wraps storage init")} to deploy infrastructure first.\\n`
|
|
36812
36921
|
);
|
|
36813
36922
|
process.exit(1);
|
|
36814
36923
|
}
|
|
@@ -36850,9 +36959,9 @@ async function dashboard(options) {
|
|
|
36850
36959
|
}
|
|
36851
36960
|
const port = options.port || await getPort({ port: [5555, 5556, 5557, 5558, 5559] });
|
|
36852
36961
|
progress.stop();
|
|
36853
|
-
|
|
36962
|
+
clack47.log.success("Starting dashboard server...");
|
|
36854
36963
|
console.log(
|
|
36855
|
-
`${
|
|
36964
|
+
`${pc50.dim("Using current AWS credentials (no role assumption)")}\\n`
|
|
36856
36965
|
);
|
|
36857
36966
|
const { url } = await startConsoleServer({
|
|
36858
36967
|
port,
|
|
@@ -36885,8 +36994,8 @@ async function dashboard(options) {
|
|
|
36885
36994
|
cdnCustomDomain,
|
|
36886
36995
|
cdnCertificateArn
|
|
36887
36996
|
});
|
|
36888
|
-
console.log(`\\n${
|
|
36889
|
-
console.log(`${
|
|
36997
|
+
console.log(`\\n${pc50.bold("Dashboard:")} ${pc50.cyan(url)}`);
|
|
36998
|
+
console.log(`${pc50.dim("Press Ctrl+C to stop")}\\n`);
|
|
36890
36999
|
getTelemetryClient().showFooterOnce();
|
|
36891
37000
|
if (!options.noOpen) {
|
|
36892
37001
|
await open2(url);
|
|
@@ -36907,8 +37016,8 @@ init_aws();
|
|
|
36907
37016
|
init_errors();
|
|
36908
37017
|
init_json_output();
|
|
36909
37018
|
init_metadata();
|
|
36910
|
-
import * as
|
|
36911
|
-
import
|
|
37019
|
+
import * as clack48 from "@clack/prompts";
|
|
37020
|
+
import pc51 from "picocolors";
|
|
36912
37021
|
async function destroy(options) {
|
|
36913
37022
|
trackCommand("destroy", { success: true });
|
|
36914
37023
|
if (isJsonMode() && !options.force) {
|
|
@@ -36919,9 +37028,9 @@ async function destroy(options) {
|
|
|
36919
37028
|
);
|
|
36920
37029
|
}
|
|
36921
37030
|
if (!isJsonMode()) {
|
|
36922
|
-
|
|
37031
|
+
clack48.intro(pc51.bold("Wraps Infrastructure Teardown"));
|
|
36923
37032
|
}
|
|
36924
|
-
const spinner10 =
|
|
37033
|
+
const spinner10 = clack48.spinner();
|
|
36925
37034
|
spinner10.start("Validating AWS credentials");
|
|
36926
37035
|
let identity;
|
|
36927
37036
|
try {
|
|
@@ -36938,17 +37047,17 @@ async function destroy(options) {
|
|
|
36938
37047
|
deployedServices.push("email");
|
|
36939
37048
|
}
|
|
36940
37049
|
if (deployedServices.length === 0) {
|
|
36941
|
-
|
|
37050
|
+
clack48.log.warn("No Wraps services found in this region");
|
|
36942
37051
|
console.log(
|
|
36943
37052
|
`
|
|
36944
|
-
Run ${
|
|
37053
|
+
Run ${pc51.cyan("wraps email init")} to deploy infrastructure.
|
|
36945
37054
|
`
|
|
36946
37055
|
);
|
|
36947
37056
|
process.exit(0);
|
|
36948
37057
|
}
|
|
36949
37058
|
if (deployedServices.length === 1) {
|
|
36950
37059
|
const service = deployedServices[0];
|
|
36951
|
-
|
|
37060
|
+
clack48.log.info(`Found ${pc51.cyan(service)} service deployed`);
|
|
36952
37061
|
if (service === "email") {
|
|
36953
37062
|
await emailDestroy(options);
|
|
36954
37063
|
return;
|
|
@@ -36963,7 +37072,7 @@ Run ${pc50.cyan("wraps email init")} to deploy infrastructure.
|
|
|
36963
37072
|
jsonSuccess("destroy", { destroyed: true });
|
|
36964
37073
|
return;
|
|
36965
37074
|
}
|
|
36966
|
-
const serviceToDestroy = await
|
|
37075
|
+
const serviceToDestroy = await clack48.select({
|
|
36967
37076
|
message: "Which service would you like to destroy?",
|
|
36968
37077
|
options: [
|
|
36969
37078
|
...deployedServices.map((s) => ({
|
|
@@ -36978,15 +37087,15 @@ Run ${pc50.cyan("wraps email init")} to deploy infrastructure.
|
|
|
36978
37087
|
}
|
|
36979
37088
|
]
|
|
36980
37089
|
});
|
|
36981
|
-
if (
|
|
36982
|
-
|
|
37090
|
+
if (clack48.isCancel(serviceToDestroy)) {
|
|
37091
|
+
clack48.cancel("Operation cancelled.");
|
|
36983
37092
|
process.exit(0);
|
|
36984
37093
|
}
|
|
36985
37094
|
if ((serviceToDestroy === "email" || serviceToDestroy === "all") && deployedServices.includes("email")) {
|
|
36986
37095
|
await emailDestroy(options);
|
|
36987
37096
|
}
|
|
36988
37097
|
if (serviceToDestroy === "all") {
|
|
36989
|
-
|
|
37098
|
+
clack48.outro(pc51.green("All Wraps infrastructure has been removed"));
|
|
36990
37099
|
}
|
|
36991
37100
|
}
|
|
36992
37101
|
|
|
@@ -36998,26 +37107,26 @@ init_fs();
|
|
|
36998
37107
|
init_json_output();
|
|
36999
37108
|
init_output();
|
|
37000
37109
|
init_pulumi();
|
|
37001
|
-
import * as
|
|
37110
|
+
import * as clack49 from "@clack/prompts";
|
|
37002
37111
|
import * as pulumi29 from "@pulumi/pulumi";
|
|
37003
|
-
import
|
|
37112
|
+
import pc52 from "picocolors";
|
|
37004
37113
|
async function status(options) {
|
|
37005
37114
|
await ensurePulumiInstalled();
|
|
37006
37115
|
const startTime = Date.now();
|
|
37007
37116
|
const progress = new DeploymentProgress();
|
|
37008
37117
|
if (!isJsonMode()) {
|
|
37009
|
-
|
|
37118
|
+
clack49.intro(pc52.bold("Wraps Infrastructure Status"));
|
|
37010
37119
|
}
|
|
37011
37120
|
const identity = await progress.execute(
|
|
37012
37121
|
"Loading infrastructure status",
|
|
37013
37122
|
async () => validateAWSCredentials()
|
|
37014
37123
|
);
|
|
37015
37124
|
if (!isJsonMode()) {
|
|
37016
|
-
progress.info(`AWS Account: ${
|
|
37125
|
+
progress.info(`AWS Account: ${pc52.cyan(identity.accountId)}`);
|
|
37017
37126
|
}
|
|
37018
37127
|
const region = options.region || await getAWSRegion();
|
|
37019
37128
|
if (!isJsonMode()) {
|
|
37020
|
-
progress.info(`Region: ${
|
|
37129
|
+
progress.info(`Region: ${pc52.cyan(region)}`);
|
|
37021
37130
|
}
|
|
37022
37131
|
const services = [];
|
|
37023
37132
|
try {
|
|
@@ -37069,35 +37178,35 @@ async function status(options) {
|
|
|
37069
37178
|
return;
|
|
37070
37179
|
}
|
|
37071
37180
|
console.log();
|
|
37072
|
-
|
|
37181
|
+
clack49.note(
|
|
37073
37182
|
services.map((s) => {
|
|
37074
37183
|
if (s.status === "deployed") {
|
|
37075
|
-
const details = s.details ?
|
|
37076
|
-
return ` ${
|
|
37184
|
+
const details = s.details ? pc52.dim(` (${s.details})`) : "";
|
|
37185
|
+
return ` ${pc52.green("\u2713")} ${s.name}${details}`;
|
|
37077
37186
|
}
|
|
37078
|
-
return ` ${
|
|
37187
|
+
return ` ${pc52.dim("\u25CB")} ${s.name} ${pc52.dim("(not deployed)")}`;
|
|
37079
37188
|
}).join("\n"),
|
|
37080
37189
|
"Services"
|
|
37081
37190
|
);
|
|
37082
37191
|
const hasDeployedServices = services.some((s) => s.status === "deployed");
|
|
37083
37192
|
if (hasDeployedServices) {
|
|
37084
37193
|
console.log(`
|
|
37085
|
-
${
|
|
37194
|
+
${pc52.bold("Details:")}`);
|
|
37086
37195
|
if (services.find((s) => s.name === "Email")?.status === "deployed") {
|
|
37087
|
-
console.log(` ${
|
|
37196
|
+
console.log(` ${pc52.dim("Email:")} ${pc52.cyan("wraps email status")}`);
|
|
37088
37197
|
}
|
|
37089
37198
|
if (services.find((s) => s.name === "SMS")?.status === "deployed") {
|
|
37090
|
-
console.log(` ${
|
|
37199
|
+
console.log(` ${pc52.dim("SMS:")} ${pc52.cyan("wraps sms status")}`);
|
|
37091
37200
|
}
|
|
37092
37201
|
} else {
|
|
37093
37202
|
console.log(`
|
|
37094
|
-
${
|
|
37095
|
-
console.log(` ${
|
|
37096
|
-
console.log(` ${
|
|
37203
|
+
${pc52.bold("Get started:")}`);
|
|
37204
|
+
console.log(` ${pc52.dim("Deploy email:")} ${pc52.cyan("wraps email init")}`);
|
|
37205
|
+
console.log(` ${pc52.dim("Deploy SMS:")} ${pc52.cyan("wraps sms init")}`);
|
|
37097
37206
|
}
|
|
37098
37207
|
console.log(`
|
|
37099
|
-
${
|
|
37100
|
-
console.log(`${
|
|
37208
|
+
${pc52.bold("Dashboard:")} ${pc52.blue("https://app.wraps.dev")}`);
|
|
37209
|
+
console.log(`${pc52.bold("Docs:")} ${pc52.blue("https://wraps.dev/docs")}
|
|
37101
37210
|
`);
|
|
37102
37211
|
trackCommand("status", {
|
|
37103
37212
|
success: true,
|
|
@@ -37108,9 +37217,9 @@ ${pc51.bold("Dashboard:")} ${pc51.blue("https://app.wraps.dev")}`);
|
|
|
37108
37217
|
|
|
37109
37218
|
// src/commands/sms/destroy.ts
|
|
37110
37219
|
init_esm_shims();
|
|
37111
|
-
import * as
|
|
37220
|
+
import * as clack50 from "@clack/prompts";
|
|
37112
37221
|
import * as pulumi31 from "@pulumi/pulumi";
|
|
37113
|
-
import
|
|
37222
|
+
import pc53 from "picocolors";
|
|
37114
37223
|
|
|
37115
37224
|
// src/infrastructure/sms-stack.ts
|
|
37116
37225
|
init_esm_shims();
|
|
@@ -37801,18 +37910,18 @@ async function createSMSProtectConfigurationWithSDK(configurationSetName, region
|
|
|
37801
37910
|
const existing = await client.send(
|
|
37802
37911
|
new DescribeProtectConfigurationsCommand({})
|
|
37803
37912
|
);
|
|
37804
|
-
for (const
|
|
37805
|
-
if (!(
|
|
37913
|
+
for (const pc66 of existing.ProtectConfigurations || []) {
|
|
37914
|
+
if (!(pc66.ProtectConfigurationArn && pc66.ProtectConfigurationId)) {
|
|
37806
37915
|
continue;
|
|
37807
37916
|
}
|
|
37808
37917
|
const tagsResponse = await client.send(
|
|
37809
37918
|
new ListTagsForResourceCommand({
|
|
37810
|
-
ResourceArn:
|
|
37919
|
+
ResourceArn: pc66.ProtectConfigurationArn
|
|
37811
37920
|
})
|
|
37812
37921
|
);
|
|
37813
37922
|
const nameTag = tagsResponse.Tags?.find((t) => t.Key === "Name");
|
|
37814
37923
|
if (nameTag?.Value === protectConfigName) {
|
|
37815
|
-
existingProtectConfigId =
|
|
37924
|
+
existingProtectConfigId = pc66.ProtectConfigurationId;
|
|
37816
37925
|
break;
|
|
37817
37926
|
}
|
|
37818
37927
|
}
|
|
@@ -37908,13 +38017,13 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
|
|
|
37908
38017
|
new DescribeProtectConfigurationsCommand({})
|
|
37909
38018
|
);
|
|
37910
38019
|
if (existing.ProtectConfigurations) {
|
|
37911
|
-
for (const
|
|
37912
|
-
if (!(
|
|
38020
|
+
for (const pc66 of existing.ProtectConfigurations) {
|
|
38021
|
+
if (!(pc66.ProtectConfigurationArn && pc66.ProtectConfigurationId)) {
|
|
37913
38022
|
continue;
|
|
37914
38023
|
}
|
|
37915
38024
|
const tagsResponse = await client.send(
|
|
37916
38025
|
new ListTagsForResourceCommand({
|
|
37917
|
-
ResourceArn:
|
|
38026
|
+
ResourceArn: pc66.ProtectConfigurationArn
|
|
37918
38027
|
})
|
|
37919
38028
|
);
|
|
37920
38029
|
const isWrapsManaged = tagsResponse.Tags?.some(
|
|
@@ -37923,7 +38032,7 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
|
|
|
37923
38032
|
if (isWrapsManaged) {
|
|
37924
38033
|
await client.send(
|
|
37925
38034
|
new DeleteProtectConfigurationCommand({
|
|
37926
|
-
ProtectConfigurationId:
|
|
38035
|
+
ProtectConfigurationId: pc66.ProtectConfigurationId
|
|
37927
38036
|
})
|
|
37928
38037
|
);
|
|
37929
38038
|
}
|
|
@@ -37958,8 +38067,8 @@ async function smsDestroy(options) {
|
|
|
37958
38067
|
);
|
|
37959
38068
|
}
|
|
37960
38069
|
if (!isJsonMode()) {
|
|
37961
|
-
|
|
37962
|
-
|
|
38070
|
+
clack50.intro(
|
|
38071
|
+
pc53.bold(
|
|
37963
38072
|
options.preview ? "SMS Infrastructure Destruction Preview" : "SMS Infrastructure Teardown"
|
|
37964
38073
|
)
|
|
37965
38074
|
);
|
|
@@ -37985,15 +38094,15 @@ async function smsDestroy(options) {
|
|
|
37985
38094
|
`Available regions: ${smsConnections.map((c) => c.region).join(", ")}`
|
|
37986
38095
|
);
|
|
37987
38096
|
}
|
|
37988
|
-
const selectedRegion = await
|
|
38097
|
+
const selectedRegion = await clack50.select({
|
|
37989
38098
|
message: "Multiple SMS deployments found. Which region to destroy?",
|
|
37990
38099
|
options: smsConnections.map((conn) => ({
|
|
37991
38100
|
value: conn.region,
|
|
37992
38101
|
label: conn.region
|
|
37993
38102
|
}))
|
|
37994
38103
|
});
|
|
37995
|
-
if (
|
|
37996
|
-
|
|
38104
|
+
if (clack50.isCancel(selectedRegion)) {
|
|
38105
|
+
clack50.cancel("Operation cancelled");
|
|
37997
38106
|
process.exit(0);
|
|
37998
38107
|
}
|
|
37999
38108
|
region = selectedRegion;
|
|
@@ -38004,18 +38113,18 @@ async function smsDestroy(options) {
|
|
|
38004
38113
|
const storedStackName = smsService?.pulumiStackName;
|
|
38005
38114
|
if (!smsService) {
|
|
38006
38115
|
progress.stop();
|
|
38007
|
-
|
|
38116
|
+
clack50.log.warn("No SMS infrastructure found");
|
|
38008
38117
|
process.exit(0);
|
|
38009
38118
|
}
|
|
38010
38119
|
if (!(options.force || options.preview)) {
|
|
38011
|
-
const confirmed = await
|
|
38012
|
-
message:
|
|
38120
|
+
const confirmed = await clack50.confirm({
|
|
38121
|
+
message: pc53.red(
|
|
38013
38122
|
"Are you sure you want to destroy all SMS infrastructure?"
|
|
38014
38123
|
),
|
|
38015
38124
|
initialValue: false
|
|
38016
38125
|
});
|
|
38017
|
-
if (
|
|
38018
|
-
|
|
38126
|
+
if (clack50.isCancel(confirmed) || !confirmed) {
|
|
38127
|
+
clack50.cancel("Destruction cancelled.");
|
|
38019
38128
|
process.exit(0);
|
|
38020
38129
|
}
|
|
38021
38130
|
}
|
|
@@ -38047,8 +38156,8 @@ async function smsDestroy(options) {
|
|
|
38047
38156
|
costEstimate: "Monthly cost after destruction: $0.00",
|
|
38048
38157
|
commandName: "wraps sms destroy"
|
|
38049
38158
|
});
|
|
38050
|
-
|
|
38051
|
-
|
|
38159
|
+
clack50.outro(
|
|
38160
|
+
pc53.green("Preview complete. Run without --preview to destroy.")
|
|
38052
38161
|
);
|
|
38053
38162
|
trackServiceRemoved("sms", {
|
|
38054
38163
|
preview: true,
|
|
@@ -38059,7 +38168,7 @@ async function smsDestroy(options) {
|
|
|
38059
38168
|
progress.stop();
|
|
38060
38169
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
38061
38170
|
if (errorMessage.includes("No SMS infrastructure found")) {
|
|
38062
|
-
|
|
38171
|
+
clack50.log.warn("No SMS infrastructure found to preview");
|
|
38063
38172
|
process.exit(0);
|
|
38064
38173
|
}
|
|
38065
38174
|
trackError("PREVIEW_FAILED", "sms destroy", { step: "preview" });
|
|
@@ -38108,7 +38217,7 @@ async function smsDestroy(options) {
|
|
|
38108
38217
|
progress.stop();
|
|
38109
38218
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
38110
38219
|
if (errorMessage.includes("No SMS infrastructure found")) {
|
|
38111
|
-
|
|
38220
|
+
clack50.log.warn("No SMS infrastructure found");
|
|
38112
38221
|
if (metadata) {
|
|
38113
38222
|
removeServiceFromConnection(metadata, "sms");
|
|
38114
38223
|
await saveConnectionMetadata(metadata);
|
|
@@ -38121,7 +38230,7 @@ async function smsDestroy(options) {
|
|
|
38121
38230
|
}
|
|
38122
38231
|
trackError("DESTROY_FAILED", "sms destroy", { step: "destroy" });
|
|
38123
38232
|
destroyFailed = true;
|
|
38124
|
-
|
|
38233
|
+
clack50.log.warn(
|
|
38125
38234
|
"Some resources may not have been fully removed. You can re-run this command or clean up manually in the AWS console."
|
|
38126
38235
|
);
|
|
38127
38236
|
}
|
|
@@ -38144,21 +38253,21 @@ async function smsDestroy(options) {
|
|
|
38144
38253
|
return;
|
|
38145
38254
|
}
|
|
38146
38255
|
if (destroyFailed) {
|
|
38147
|
-
|
|
38148
|
-
|
|
38256
|
+
clack50.outro(
|
|
38257
|
+
pc53.yellow("SMS infrastructure partially removed. Metadata cleaned up.")
|
|
38149
38258
|
);
|
|
38150
38259
|
} else {
|
|
38151
|
-
|
|
38260
|
+
clack50.outro(pc53.green("SMS infrastructure has been removed"));
|
|
38152
38261
|
console.log(`
|
|
38153
|
-
${
|
|
38154
|
-
console.log(` ${
|
|
38155
|
-
console.log(` ${
|
|
38156
|
-
console.log(` ${
|
|
38157
|
-
console.log(` ${
|
|
38262
|
+
${pc53.bold("Cleaned up:")}`);
|
|
38263
|
+
console.log(` ${pc53.green("\u2713")} Phone number released`);
|
|
38264
|
+
console.log(` ${pc53.green("\u2713")} Configuration set deleted`);
|
|
38265
|
+
console.log(` ${pc53.green("\u2713")} Event processing infrastructure removed`);
|
|
38266
|
+
console.log(` ${pc53.green("\u2713")} IAM role deleted`);
|
|
38158
38267
|
}
|
|
38159
38268
|
console.log(
|
|
38160
38269
|
`
|
|
38161
|
-
Run ${
|
|
38270
|
+
Run ${pc53.cyan("wraps sms init")} to deploy infrastructure again.
|
|
38162
38271
|
`
|
|
38163
38272
|
);
|
|
38164
38273
|
trackServiceRemoved("sms", {
|
|
@@ -38170,9 +38279,9 @@ Run ${pc52.cyan("wraps sms init")} to deploy infrastructure again.
|
|
|
38170
38279
|
|
|
38171
38280
|
// src/commands/sms/init.ts
|
|
38172
38281
|
init_esm_shims();
|
|
38173
|
-
import * as
|
|
38282
|
+
import * as clack51 from "@clack/prompts";
|
|
38174
38283
|
import * as pulumi32 from "@pulumi/pulumi";
|
|
38175
|
-
import
|
|
38284
|
+
import pc54 from "picocolors";
|
|
38176
38285
|
init_events();
|
|
38177
38286
|
init_aws();
|
|
38178
38287
|
init_fs();
|
|
@@ -38591,7 +38700,7 @@ function validateSMSConfig(config2) {
|
|
|
38591
38700
|
|
|
38592
38701
|
// src/commands/sms/init.ts
|
|
38593
38702
|
async function promptPhoneNumberType() {
|
|
38594
|
-
const result = await
|
|
38703
|
+
const result = await clack51.select({
|
|
38595
38704
|
message: "Select phone number type:",
|
|
38596
38705
|
options: [
|
|
38597
38706
|
{
|
|
@@ -38611,14 +38720,14 @@ async function promptPhoneNumberType() {
|
|
|
38611
38720
|
}
|
|
38612
38721
|
]
|
|
38613
38722
|
});
|
|
38614
|
-
if (
|
|
38615
|
-
|
|
38723
|
+
if (clack51.isCancel(result)) {
|
|
38724
|
+
clack51.cancel("Operation cancelled.");
|
|
38616
38725
|
process.exit(0);
|
|
38617
38726
|
}
|
|
38618
38727
|
return result;
|
|
38619
38728
|
}
|
|
38620
38729
|
async function promptSMSPreset() {
|
|
38621
|
-
const result = await
|
|
38730
|
+
const result = await clack51.select({
|
|
38622
38731
|
message: "Choose configuration preset:",
|
|
38623
38732
|
options: [
|
|
38624
38733
|
{
|
|
@@ -38643,8 +38752,8 @@ async function promptSMSPreset() {
|
|
|
38643
38752
|
}
|
|
38644
38753
|
]
|
|
38645
38754
|
});
|
|
38646
|
-
if (
|
|
38647
|
-
|
|
38755
|
+
if (clack51.isCancel(result)) {
|
|
38756
|
+
clack51.cancel("Operation cancelled.");
|
|
38648
38757
|
process.exit(0);
|
|
38649
38758
|
}
|
|
38650
38759
|
return result;
|
|
@@ -38664,7 +38773,7 @@ var COMMON_COUNTRIES = [
|
|
|
38664
38773
|
{ code: "IN", name: "India" }
|
|
38665
38774
|
];
|
|
38666
38775
|
async function promptAllowedCountries() {
|
|
38667
|
-
const result = await
|
|
38776
|
+
const result = await clack51.multiselect({
|
|
38668
38777
|
message: "Select countries to allow SMS delivery (blocks all others):",
|
|
38669
38778
|
options: COMMON_COUNTRIES.map((c) => ({
|
|
38670
38779
|
value: c.code,
|
|
@@ -38673,14 +38782,14 @@ async function promptAllowedCountries() {
|
|
|
38673
38782
|
initialValues: ["US"],
|
|
38674
38783
|
required: true
|
|
38675
38784
|
});
|
|
38676
|
-
if (
|
|
38677
|
-
|
|
38785
|
+
if (clack51.isCancel(result)) {
|
|
38786
|
+
clack51.cancel("Operation cancelled.");
|
|
38678
38787
|
process.exit(0);
|
|
38679
38788
|
}
|
|
38680
38789
|
return result;
|
|
38681
38790
|
}
|
|
38682
38791
|
async function promptEstimatedSMSVolume() {
|
|
38683
|
-
const result = await
|
|
38792
|
+
const result = await clack51.select({
|
|
38684
38793
|
message: "Estimated messages per month:",
|
|
38685
38794
|
options: [
|
|
38686
38795
|
{ value: 100, label: "< 100 (Testing)" },
|
|
@@ -38690,8 +38799,8 @@ async function promptEstimatedSMSVolume() {
|
|
|
38690
38799
|
{ value: 1e5, label: "50,000+" }
|
|
38691
38800
|
]
|
|
38692
38801
|
});
|
|
38693
|
-
if (
|
|
38694
|
-
|
|
38802
|
+
if (clack51.isCancel(result)) {
|
|
38803
|
+
clack51.cancel("Operation cancelled.");
|
|
38695
38804
|
process.exit(0);
|
|
38696
38805
|
}
|
|
38697
38806
|
return result;
|
|
@@ -38699,7 +38808,7 @@ async function promptEstimatedSMSVolume() {
|
|
|
38699
38808
|
async function init3(options) {
|
|
38700
38809
|
const startTime = Date.now();
|
|
38701
38810
|
if (!isJsonMode()) {
|
|
38702
|
-
|
|
38811
|
+
clack51.intro(pc54.bold("Wraps SMS Infrastructure Setup"));
|
|
38703
38812
|
}
|
|
38704
38813
|
const progress = new DeploymentProgress();
|
|
38705
38814
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -38713,7 +38822,7 @@ async function init3(options) {
|
|
|
38713
38822
|
"Validating AWS credentials",
|
|
38714
38823
|
async () => validateAWSCredentials()
|
|
38715
38824
|
);
|
|
38716
|
-
progress.info(`Connected to AWS account: ${
|
|
38825
|
+
progress.info(`Connected to AWS account: ${pc54.cyan(identity.accountId)}`);
|
|
38717
38826
|
const provider = options.provider || await promptProvider();
|
|
38718
38827
|
const region = options.region || await promptRegion(await getAWSRegion());
|
|
38719
38828
|
let vercelConfig;
|
|
@@ -38725,10 +38834,10 @@ async function init3(options) {
|
|
|
38725
38834
|
region
|
|
38726
38835
|
);
|
|
38727
38836
|
if (existingConnection?.services?.sms) {
|
|
38728
|
-
|
|
38729
|
-
`SMS already configured for account ${
|
|
38837
|
+
clack51.log.warn(
|
|
38838
|
+
`SMS already configured for account ${pc54.cyan(identity.accountId)} in region ${pc54.cyan(region)}`
|
|
38730
38839
|
);
|
|
38731
|
-
|
|
38840
|
+
clack51.log.info(`Use ${pc54.cyan("wraps sms status")} to view current setup`);
|
|
38732
38841
|
process.exit(0);
|
|
38733
38842
|
}
|
|
38734
38843
|
let preset = options.preset;
|
|
@@ -38745,12 +38854,12 @@ async function init3(options) {
|
|
|
38745
38854
|
optOutManagement: true,
|
|
38746
38855
|
sendingEnabled: true
|
|
38747
38856
|
};
|
|
38748
|
-
const enableEventTracking = await
|
|
38857
|
+
const enableEventTracking = await clack51.confirm({
|
|
38749
38858
|
message: "Enable event tracking (EventBridge + DynamoDB)?",
|
|
38750
38859
|
initialValue: false
|
|
38751
38860
|
});
|
|
38752
|
-
if (
|
|
38753
|
-
|
|
38861
|
+
if (clack51.isCancel(enableEventTracking)) {
|
|
38862
|
+
clack51.cancel("Operation cancelled.");
|
|
38754
38863
|
process.exit(0);
|
|
38755
38864
|
}
|
|
38756
38865
|
if (enableEventTracking) {
|
|
@@ -38770,17 +38879,17 @@ async function init3(options) {
|
|
|
38770
38879
|
}
|
|
38771
38880
|
progress.info(
|
|
38772
38881
|
`
|
|
38773
|
-
${
|
|
38882
|
+
${pc54.bold("Fraud Protection")} - Block SMS to countries where you don't do business`
|
|
38774
38883
|
);
|
|
38775
38884
|
const allowedCountries = await promptAllowedCountries();
|
|
38776
38885
|
let aitFiltering = false;
|
|
38777
38886
|
if (smsConfig.phoneNumberType !== "simulator") {
|
|
38778
|
-
const enableAIT = await
|
|
38887
|
+
const enableAIT = await clack51.confirm({
|
|
38779
38888
|
message: "Enable AIT (Artificially Inflated Traffic) filtering? (adds per-message cost)",
|
|
38780
38889
|
initialValue: false
|
|
38781
38890
|
});
|
|
38782
|
-
if (
|
|
38783
|
-
|
|
38891
|
+
if (clack51.isCancel(enableAIT)) {
|
|
38892
|
+
clack51.cancel("Operation cancelled.");
|
|
38784
38893
|
process.exit(0);
|
|
38785
38894
|
}
|
|
38786
38895
|
aitFiltering = enableAIT;
|
|
@@ -38792,21 +38901,21 @@ ${pc53.bold("Fraud Protection")} - Block SMS to countries where you don't do bus
|
|
|
38792
38901
|
};
|
|
38793
38902
|
const estimatedVolume = await promptEstimatedSMSVolume();
|
|
38794
38903
|
progress.info(`
|
|
38795
|
-
${
|
|
38904
|
+
${pc54.bold("Cost Estimate:")}`);
|
|
38796
38905
|
const costSummary = getSMSCostSummary(smsConfig, estimatedVolume);
|
|
38797
|
-
|
|
38906
|
+
clack51.log.info(costSummary);
|
|
38798
38907
|
const warnings = validateSMSConfig(smsConfig);
|
|
38799
38908
|
if (warnings.length > 0) {
|
|
38800
38909
|
progress.info(`
|
|
38801
|
-
${
|
|
38910
|
+
${pc54.yellow(pc54.bold("Important Notes:"))}`);
|
|
38802
38911
|
for (const warning of warnings) {
|
|
38803
|
-
|
|
38912
|
+
clack51.log.warn(warning);
|
|
38804
38913
|
}
|
|
38805
38914
|
}
|
|
38806
38915
|
if (!(options.yes || options.preview)) {
|
|
38807
38916
|
const confirmed = await confirmDeploy();
|
|
38808
38917
|
if (!confirmed) {
|
|
38809
|
-
|
|
38918
|
+
clack51.cancel("Deployment cancelled.");
|
|
38810
38919
|
process.exit(0);
|
|
38811
38920
|
}
|
|
38812
38921
|
}
|
|
@@ -38866,8 +38975,8 @@ ${pc53.yellow(pc53.bold("Important Notes:"))}`);
|
|
|
38866
38975
|
costEstimate: getSMSCostSummary(smsConfig, 0),
|
|
38867
38976
|
commandName: "wraps sms init"
|
|
38868
38977
|
});
|
|
38869
|
-
|
|
38870
|
-
|
|
38978
|
+
clack51.outro(
|
|
38979
|
+
pc54.green("Preview complete. Run without --preview to deploy.")
|
|
38871
38980
|
);
|
|
38872
38981
|
trackServiceInit("sms", true, {
|
|
38873
38982
|
provider,
|
|
@@ -38916,9 +39025,9 @@ ${pc53.yellow(pc53.bold("Important Notes:"))}`);
|
|
|
38916
39025
|
} catch (sdkError) {
|
|
38917
39026
|
sdkResourceWarning = true;
|
|
38918
39027
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
38919
|
-
|
|
38920
|
-
|
|
38921
|
-
`Run ${
|
|
39028
|
+
clack51.log.warn(`Phone pool creation failed: ${msg}`);
|
|
39029
|
+
clack51.log.info(
|
|
39030
|
+
`Run ${pc54.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
38922
39031
|
);
|
|
38923
39032
|
}
|
|
38924
39033
|
}
|
|
@@ -38934,9 +39043,9 @@ ${pc53.yellow(pc53.bold("Important Notes:"))}`);
|
|
|
38934
39043
|
} catch (sdkError) {
|
|
38935
39044
|
sdkResourceWarning = true;
|
|
38936
39045
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
38937
|
-
|
|
38938
|
-
|
|
38939
|
-
`Run ${
|
|
39046
|
+
clack51.log.warn(`Event destination creation failed: ${msg}`);
|
|
39047
|
+
clack51.log.info(
|
|
39048
|
+
`Run ${pc54.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
38940
39049
|
);
|
|
38941
39050
|
}
|
|
38942
39051
|
}
|
|
@@ -38955,14 +39064,14 @@ ${pc53.yellow(pc53.bold("Important Notes:"))}`);
|
|
|
38955
39064
|
} catch (sdkError) {
|
|
38956
39065
|
sdkResourceWarning = true;
|
|
38957
39066
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
38958
|
-
|
|
38959
|
-
|
|
38960
|
-
`Run ${
|
|
39067
|
+
clack51.log.warn(`Protect configuration creation failed: ${msg}`);
|
|
39068
|
+
clack51.log.info(
|
|
39069
|
+
`Run ${pc54.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
38961
39070
|
);
|
|
38962
39071
|
}
|
|
38963
39072
|
}
|
|
38964
39073
|
if (sdkResourceWarning) {
|
|
38965
|
-
|
|
39074
|
+
clack51.log.warn(
|
|
38966
39075
|
"Some SDK resources failed to create. Core infrastructure is deployed."
|
|
38967
39076
|
);
|
|
38968
39077
|
}
|
|
@@ -39007,47 +39116,47 @@ ${pc53.yellow(pc53.bold("Important Notes:"))}`);
|
|
|
39007
39116
|
return;
|
|
39008
39117
|
}
|
|
39009
39118
|
console.log("\n");
|
|
39010
|
-
|
|
39119
|
+
clack51.log.success(pc54.green(pc54.bold("SMS infrastructure deployed!")));
|
|
39011
39120
|
console.log("\n");
|
|
39012
|
-
|
|
39121
|
+
clack51.note(
|
|
39013
39122
|
[
|
|
39014
|
-
`${
|
|
39015
|
-
`${
|
|
39016
|
-
`${
|
|
39017
|
-
`${
|
|
39018
|
-
outputs.tableName ? `${
|
|
39123
|
+
`${pc54.bold("Phone Number:")} ${pc54.cyan(outputs.phoneNumber || "Provisioning...")}`,
|
|
39124
|
+
`${pc54.bold("Phone Type:")} ${pc54.cyan(smsConfig.phoneNumberType || "simulator")}`,
|
|
39125
|
+
`${pc54.bold("Config Set:")} ${pc54.cyan(outputs.configSetName || "wraps-sms-config")}`,
|
|
39126
|
+
`${pc54.bold("Region:")} ${pc54.cyan(outputs.region)}`,
|
|
39127
|
+
outputs.tableName ? `${pc54.bold("History Table:")} ${pc54.cyan(outputs.tableName)}` : "",
|
|
39019
39128
|
"",
|
|
39020
|
-
|
|
39021
|
-
|
|
39129
|
+
pc54.dim("IAM Role:"),
|
|
39130
|
+
pc54.dim(` ${outputs.roleArn}`)
|
|
39022
39131
|
].filter(Boolean).join("\n"),
|
|
39023
39132
|
"SMS Infrastructure"
|
|
39024
39133
|
);
|
|
39025
39134
|
const nextSteps = [];
|
|
39026
39135
|
if (smsConfig.phoneNumberType === "toll-free") {
|
|
39027
39136
|
nextSteps.push(
|
|
39028
|
-
`${
|
|
39137
|
+
`${pc54.cyan("wraps sms register")} - Submit toll-free registration (required before sending)`
|
|
39029
39138
|
);
|
|
39030
39139
|
}
|
|
39031
39140
|
nextSteps.push(
|
|
39032
|
-
`${
|
|
39141
|
+
`${pc54.cyan("wraps sms test --to +1234567890")} - Send a test message`
|
|
39033
39142
|
);
|
|
39034
|
-
nextSteps.push(`${
|
|
39143
|
+
nextSteps.push(`${pc54.cyan("wraps sms status")} - View SMS configuration`);
|
|
39035
39144
|
console.log("\n");
|
|
39036
|
-
|
|
39145
|
+
clack51.log.info(pc54.bold("Next steps:"));
|
|
39037
39146
|
for (const step of nextSteps) {
|
|
39038
39147
|
console.log(` ${step}`);
|
|
39039
39148
|
}
|
|
39040
39149
|
console.log("\n");
|
|
39041
|
-
|
|
39042
|
-
console.log(
|
|
39150
|
+
clack51.log.info(pc54.bold("SDK Usage:"));
|
|
39151
|
+
console.log(pc54.dim(" npm install @wraps.dev/sms"));
|
|
39043
39152
|
console.log("");
|
|
39044
|
-
console.log(
|
|
39045
|
-
console.log(
|
|
39046
|
-
console.log(
|
|
39047
|
-
console.log(
|
|
39048
|
-
console.log(
|
|
39049
|
-
console.log(
|
|
39050
|
-
|
|
39153
|
+
console.log(pc54.dim(" import { Wraps } from '@wraps.dev/sms';"));
|
|
39154
|
+
console.log(pc54.dim(" const wraps = new Wraps();"));
|
|
39155
|
+
console.log(pc54.dim(" await wraps.sms.send({"));
|
|
39156
|
+
console.log(pc54.dim(" to: '+14155551234',"));
|
|
39157
|
+
console.log(pc54.dim(" message: 'Your code is 123456',"));
|
|
39158
|
+
console.log(pc54.dim(" });"));
|
|
39159
|
+
clack51.outro(pc54.green("Setup complete!"));
|
|
39051
39160
|
const duration = Date.now() - startTime;
|
|
39052
39161
|
const enabledFeatures = [];
|
|
39053
39162
|
if (smsConfig.tracking?.enabled) {
|
|
@@ -39083,8 +39192,8 @@ init_aws();
|
|
|
39083
39192
|
init_json_output();
|
|
39084
39193
|
init_metadata();
|
|
39085
39194
|
init_output();
|
|
39086
|
-
import * as
|
|
39087
|
-
import
|
|
39195
|
+
import * as clack52 from "@clack/prompts";
|
|
39196
|
+
import pc55 from "picocolors";
|
|
39088
39197
|
async function getPhoneNumberDetails(region) {
|
|
39089
39198
|
const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePhoneNumbersCommand: DescribePhoneNumbersCommand2 } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
|
|
39090
39199
|
const client = new PinpointSMSVoiceV2Client5({ region });
|
|
@@ -39104,7 +39213,7 @@ async function getPhoneNumberDetails(region) {
|
|
|
39104
39213
|
return null;
|
|
39105
39214
|
} catch (error) {
|
|
39106
39215
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
39107
|
-
|
|
39216
|
+
clack52.log.error(`Error fetching phone number: ${errorMessage}`);
|
|
39108
39217
|
return null;
|
|
39109
39218
|
}
|
|
39110
39219
|
}
|
|
@@ -39125,7 +39234,7 @@ async function getRegistrationStatus(region, registrationId) {
|
|
|
39125
39234
|
async function smsRegister(options) {
|
|
39126
39235
|
const startTime = Date.now();
|
|
39127
39236
|
if (!isJsonMode()) {
|
|
39128
|
-
|
|
39237
|
+
clack52.intro(pc55.bold("Wraps SMS - Toll-Free Registration"));
|
|
39129
39238
|
}
|
|
39130
39239
|
const progress = new DeploymentProgress();
|
|
39131
39240
|
const identity = await progress.execute(
|
|
@@ -39138,8 +39247,8 @@ async function smsRegister(options) {
|
|
|
39138
39247
|
}
|
|
39139
39248
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
39140
39249
|
if (!metadata?.services?.sms) {
|
|
39141
|
-
|
|
39142
|
-
|
|
39250
|
+
clack52.log.error("No SMS infrastructure found.");
|
|
39251
|
+
clack52.log.info(`Run ${pc55.cyan("wraps sms init")} first.`);
|
|
39143
39252
|
process.exit(1);
|
|
39144
39253
|
}
|
|
39145
39254
|
const phoneDetails = await progress.execute(
|
|
@@ -39147,7 +39256,7 @@ async function smsRegister(options) {
|
|
|
39147
39256
|
async () => getPhoneNumberDetails(region)
|
|
39148
39257
|
);
|
|
39149
39258
|
if (!phoneDetails) {
|
|
39150
|
-
|
|
39259
|
+
clack52.log.error("No phone number found.");
|
|
39151
39260
|
process.exit(1);
|
|
39152
39261
|
}
|
|
39153
39262
|
let registrationStatus = null;
|
|
@@ -39173,53 +39282,53 @@ async function smsRegister(options) {
|
|
|
39173
39282
|
}
|
|
39174
39283
|
console.log("");
|
|
39175
39284
|
console.log(
|
|
39176
|
-
`${
|
|
39285
|
+
`${pc55.bold("Phone Number:")} ${pc55.cyan(phoneDetails.phoneNumber)}`
|
|
39177
39286
|
);
|
|
39178
|
-
console.log(`${
|
|
39287
|
+
console.log(`${pc55.bold("Type:")} ${pc55.cyan(phoneDetails.type)}`);
|
|
39179
39288
|
console.log(
|
|
39180
|
-
`${
|
|
39289
|
+
`${pc55.bold("Status:")} ${phoneDetails.status === "ACTIVE" ? pc55.green(phoneDetails.status) : pc55.yellow(phoneDetails.status)}`
|
|
39181
39290
|
);
|
|
39182
39291
|
if (registrationStatus) {
|
|
39183
|
-
console.log(`${
|
|
39292
|
+
console.log(`${pc55.bold("Registration:")} ${pc55.cyan(registrationStatus)}`);
|
|
39184
39293
|
}
|
|
39185
39294
|
console.log("");
|
|
39186
39295
|
if (phoneDetails.status === "ACTIVE") {
|
|
39187
|
-
|
|
39296
|
+
clack52.log.success("Your phone number is already ACTIVE and ready to use!");
|
|
39188
39297
|
const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePoolsCommand } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
|
|
39189
39298
|
const client = new PinpointSMSVoiceV2Client5({ region });
|
|
39190
39299
|
const pools = await client.send(new DescribePoolsCommand({}));
|
|
39191
39300
|
if (!pools.Pools?.length) {
|
|
39192
|
-
|
|
39301
|
+
clack52.log.info("Run `wraps sms sync` to create the phone pool.");
|
|
39193
39302
|
}
|
|
39194
39303
|
process.exit(0);
|
|
39195
39304
|
}
|
|
39196
39305
|
if (phoneDetails.type !== "TOLL_FREE") {
|
|
39197
|
-
|
|
39198
|
-
|
|
39306
|
+
clack52.log.info("Only toll-free numbers require registration.");
|
|
39307
|
+
clack52.log.info(`Your ${phoneDetails.type} number should be ready to use.`);
|
|
39199
39308
|
process.exit(0);
|
|
39200
39309
|
}
|
|
39201
|
-
console.log(
|
|
39310
|
+
console.log(pc55.bold("Toll-Free Registration Required"));
|
|
39202
39311
|
console.log("");
|
|
39203
39312
|
console.log(
|
|
39204
|
-
|
|
39313
|
+
pc55.dim("To send SMS at scale, you must register your toll-free number.")
|
|
39205
39314
|
);
|
|
39206
|
-
console.log(
|
|
39315
|
+
console.log(pc55.dim("This process typically takes 1-15 business days."));
|
|
39207
39316
|
console.log("");
|
|
39208
|
-
console.log(
|
|
39209
|
-
console.log(` ${
|
|
39317
|
+
console.log(pc55.bold("You'll need to provide:"));
|
|
39318
|
+
console.log(` ${pc55.dim("\u2022")} Business name and address`);
|
|
39210
39319
|
console.log(
|
|
39211
|
-
` ${
|
|
39320
|
+
` ${pc55.dim("\u2022")} Use case description (what messages you're sending)`
|
|
39212
39321
|
);
|
|
39213
|
-
console.log(` ${
|
|
39214
|
-
console.log(` ${
|
|
39215
|
-
console.log(` ${
|
|
39322
|
+
console.log(` ${pc55.dim("\u2022")} Sample messages (2-3 examples)`);
|
|
39323
|
+
console.log(` ${pc55.dim("\u2022")} How users opt-in to receive messages`);
|
|
39324
|
+
console.log(` ${pc55.dim("\u2022")} Expected monthly message volume`);
|
|
39216
39325
|
console.log("");
|
|
39217
|
-
const openConsole = await
|
|
39326
|
+
const openConsole = await clack52.confirm({
|
|
39218
39327
|
message: "Open AWS Console to start registration?",
|
|
39219
39328
|
initialValue: true
|
|
39220
39329
|
});
|
|
39221
|
-
if (
|
|
39222
|
-
|
|
39330
|
+
if (clack52.isCancel(openConsole)) {
|
|
39331
|
+
clack52.cancel("Registration cancelled.");
|
|
39223
39332
|
process.exit(0);
|
|
39224
39333
|
}
|
|
39225
39334
|
if (openConsole) {
|
|
@@ -39229,41 +39338,41 @@ async function smsRegister(options) {
|
|
|
39229
39338
|
const execAsync2 = promisify2(exec2);
|
|
39230
39339
|
try {
|
|
39231
39340
|
await execAsync2(`open "${consoleUrl}"`);
|
|
39232
|
-
|
|
39341
|
+
clack52.log.success("Opened AWS Console in your browser.");
|
|
39233
39342
|
} catch {
|
|
39234
39343
|
try {
|
|
39235
39344
|
await execAsync2(`xdg-open "${consoleUrl}"`);
|
|
39236
|
-
|
|
39345
|
+
clack52.log.success("Opened AWS Console in your browser.");
|
|
39237
39346
|
} catch {
|
|
39238
|
-
|
|
39347
|
+
clack52.log.info("Open this URL in your browser:");
|
|
39239
39348
|
console.log(`
|
|
39240
|
-
${
|
|
39349
|
+
${pc55.cyan(consoleUrl)}
|
|
39241
39350
|
`);
|
|
39242
39351
|
}
|
|
39243
39352
|
}
|
|
39244
39353
|
console.log("");
|
|
39245
|
-
console.log(
|
|
39354
|
+
console.log(pc55.bold("Next Steps:"));
|
|
39246
39355
|
console.log(
|
|
39247
|
-
` 1. Click ${
|
|
39356
|
+
` 1. Click ${pc55.cyan("Create registration")} in the AWS Console`
|
|
39248
39357
|
);
|
|
39249
|
-
console.log(` 2. Select ${
|
|
39358
|
+
console.log(` 2. Select ${pc55.cyan("Toll-free number registration")}`);
|
|
39250
39359
|
console.log(" 3. Fill out the business information form");
|
|
39251
39360
|
console.log(" 4. Submit and wait for approval (1-15 business days)");
|
|
39252
39361
|
console.log("");
|
|
39253
39362
|
console.log(
|
|
39254
|
-
|
|
39363
|
+
pc55.dim("Once approved, run `wraps sms sync` to complete setup.")
|
|
39255
39364
|
);
|
|
39256
39365
|
} else {
|
|
39257
39366
|
const consoleUrl = `https://${region}.console.aws.amazon.com/sms-voice/home?region=${region}#/registrations`;
|
|
39258
39367
|
console.log("");
|
|
39259
39368
|
console.log("When you're ready, go to:");
|
|
39260
|
-
console.log(` ${
|
|
39369
|
+
console.log(` ${pc55.cyan(consoleUrl)}`);
|
|
39261
39370
|
}
|
|
39262
39371
|
trackCommand("sms:register", {
|
|
39263
39372
|
success: true,
|
|
39264
39373
|
duration_ms: Date.now() - startTime
|
|
39265
39374
|
});
|
|
39266
|
-
|
|
39375
|
+
clack52.outro(pc55.dim("Good luck with your registration!"));
|
|
39267
39376
|
}
|
|
39268
39377
|
|
|
39269
39378
|
// src/commands/sms/status.ts
|
|
@@ -39276,54 +39385,54 @@ init_metadata();
|
|
|
39276
39385
|
init_output();
|
|
39277
39386
|
init_pulumi();
|
|
39278
39387
|
init_region_resolver();
|
|
39279
|
-
import * as
|
|
39388
|
+
import * as clack53 from "@clack/prompts";
|
|
39280
39389
|
import * as pulumi33 from "@pulumi/pulumi";
|
|
39281
|
-
import
|
|
39390
|
+
import pc56 from "picocolors";
|
|
39282
39391
|
function displaySMSStatus(options) {
|
|
39283
39392
|
const lines = [];
|
|
39284
|
-
lines.push(
|
|
39393
|
+
lines.push(pc56.bold(pc56.green("SMS Infrastructure Active")));
|
|
39285
39394
|
lines.push("");
|
|
39286
|
-
lines.push(
|
|
39395
|
+
lines.push(pc56.bold("Phone Number"));
|
|
39287
39396
|
if (options.phoneNumber) {
|
|
39288
|
-
lines.push(` Number: ${
|
|
39397
|
+
lines.push(` Number: ${pc56.cyan(options.phoneNumber)}`);
|
|
39289
39398
|
} else {
|
|
39290
|
-
lines.push(` Number: ${
|
|
39399
|
+
lines.push(` Number: ${pc56.yellow("Provisioning...")}`);
|
|
39291
39400
|
}
|
|
39292
|
-
lines.push(` Type: ${
|
|
39401
|
+
lines.push(` Type: ${pc56.cyan(options.phoneNumberType || "simulator")}`);
|
|
39293
39402
|
lines.push("");
|
|
39294
|
-
lines.push(
|
|
39295
|
-
lines.push(` Region: ${
|
|
39403
|
+
lines.push(pc56.bold("Configuration"));
|
|
39404
|
+
lines.push(` Region: ${pc56.cyan(options.region)}`);
|
|
39296
39405
|
if (options.preset) {
|
|
39297
|
-
lines.push(` Preset: ${
|
|
39406
|
+
lines.push(` Preset: ${pc56.cyan(options.preset)}`);
|
|
39298
39407
|
}
|
|
39299
39408
|
if (options.configSetName) {
|
|
39300
|
-
lines.push(` Config Set: ${
|
|
39409
|
+
lines.push(` Config Set: ${pc56.cyan(options.configSetName)}`);
|
|
39301
39410
|
}
|
|
39302
39411
|
lines.push("");
|
|
39303
|
-
lines.push(
|
|
39412
|
+
lines.push(pc56.bold("Features"));
|
|
39304
39413
|
lines.push(
|
|
39305
|
-
` Event Tracking: ${options.eventTracking ?
|
|
39414
|
+
` Event Tracking: ${options.eventTracking ? pc56.green("Enabled") : pc56.dim("Disabled")}`
|
|
39306
39415
|
);
|
|
39307
39416
|
if (options.tableName) {
|
|
39308
|
-
lines.push(` Message History: ${
|
|
39309
|
-
lines.push(` Table: ${
|
|
39417
|
+
lines.push(` Message History: ${pc56.green("Enabled")}`);
|
|
39418
|
+
lines.push(` Table: ${pc56.dim(options.tableName)}`);
|
|
39310
39419
|
}
|
|
39311
39420
|
if (options.queueUrl) {
|
|
39312
|
-
lines.push(` Event Queue: ${
|
|
39421
|
+
lines.push(` Event Queue: ${pc56.green("Enabled")}`);
|
|
39313
39422
|
}
|
|
39314
39423
|
lines.push("");
|
|
39315
39424
|
if (options.roleArn) {
|
|
39316
|
-
lines.push(
|
|
39317
|
-
lines.push(` ${
|
|
39425
|
+
lines.push(pc56.bold("IAM Role"));
|
|
39426
|
+
lines.push(` ${pc56.dim(options.roleArn)}`);
|
|
39318
39427
|
}
|
|
39319
|
-
|
|
39428
|
+
clack53.note(lines.join("\n"), "SMS Status");
|
|
39320
39429
|
}
|
|
39321
39430
|
async function smsStatus(options) {
|
|
39322
39431
|
await ensurePulumiInstalled();
|
|
39323
39432
|
const startTime = Date.now();
|
|
39324
39433
|
const progress = new DeploymentProgress();
|
|
39325
39434
|
if (!isJsonMode()) {
|
|
39326
|
-
|
|
39435
|
+
clack53.intro(pc56.bold("Wraps SMS Status"));
|
|
39327
39436
|
}
|
|
39328
39437
|
const identity = await progress.execute(
|
|
39329
39438
|
"Loading SMS infrastructure status",
|
|
@@ -39338,10 +39447,10 @@ async function smsStatus(options) {
|
|
|
39338
39447
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
39339
39448
|
if (!metadata?.services?.sms) {
|
|
39340
39449
|
progress.stop();
|
|
39341
|
-
|
|
39450
|
+
clack53.log.error("No SMS infrastructure found");
|
|
39342
39451
|
console.log(
|
|
39343
39452
|
`
|
|
39344
|
-
Run ${
|
|
39453
|
+
Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
39345
39454
|
`
|
|
39346
39455
|
);
|
|
39347
39456
|
process.exit(1);
|
|
@@ -39377,25 +39486,25 @@ Run ${pc55.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39377
39486
|
}
|
|
39378
39487
|
displaySMSStatus(smsStatusData);
|
|
39379
39488
|
console.log("");
|
|
39380
|
-
|
|
39489
|
+
clack53.log.info(pc56.bold("Commands:"));
|
|
39381
39490
|
console.log(
|
|
39382
|
-
` ${
|
|
39491
|
+
` ${pc56.cyan("wraps sms test --to +1234567890")} - Send a test message`
|
|
39383
39492
|
);
|
|
39384
|
-
console.log(` ${
|
|
39493
|
+
console.log(` ${pc56.cyan("wraps sms destroy")} - Remove SMS infrastructure`);
|
|
39385
39494
|
trackCommand("sms:status", {
|
|
39386
39495
|
success: true,
|
|
39387
39496
|
phone_type: smsConfig?.phoneNumberType,
|
|
39388
39497
|
event_tracking: smsConfig?.eventTracking?.enabled,
|
|
39389
39498
|
duration_ms: Date.now() - startTime
|
|
39390
39499
|
});
|
|
39391
|
-
|
|
39500
|
+
clack53.outro(pc56.dim("SMS infrastructure is ready"));
|
|
39392
39501
|
}
|
|
39393
39502
|
|
|
39394
39503
|
// src/commands/sms/sync.ts
|
|
39395
39504
|
init_esm_shims();
|
|
39396
|
-
import * as
|
|
39505
|
+
import * as clack54 from "@clack/prompts";
|
|
39397
39506
|
import * as pulumi34 from "@pulumi/pulumi";
|
|
39398
|
-
import
|
|
39507
|
+
import pc57 from "picocolors";
|
|
39399
39508
|
init_events();
|
|
39400
39509
|
init_aws();
|
|
39401
39510
|
init_errors();
|
|
@@ -39408,7 +39517,7 @@ async function smsSync(options) {
|
|
|
39408
39517
|
await ensurePulumiInstalled();
|
|
39409
39518
|
const startTime = Date.now();
|
|
39410
39519
|
if (!isJsonMode()) {
|
|
39411
|
-
|
|
39520
|
+
clack54.intro(pc57.bold("Wraps SMS Infrastructure Sync"));
|
|
39412
39521
|
}
|
|
39413
39522
|
const progress = new DeploymentProgress();
|
|
39414
39523
|
const identity = await progress.execute(
|
|
@@ -39420,10 +39529,10 @@ async function smsSync(options) {
|
|
|
39420
39529
|
const smsService = metadata?.services?.sms;
|
|
39421
39530
|
if (!smsService?.config) {
|
|
39422
39531
|
progress.stop();
|
|
39423
|
-
|
|
39532
|
+
clack54.log.error("No SMS infrastructure found to sync");
|
|
39424
39533
|
console.log(
|
|
39425
39534
|
`
|
|
39426
|
-
Run ${
|
|
39535
|
+
Run ${pc57.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
39427
39536
|
`
|
|
39428
39537
|
);
|
|
39429
39538
|
process.exit(1);
|
|
@@ -39432,18 +39541,18 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
39432
39541
|
const storedStackName = smsService.pulumiStackName;
|
|
39433
39542
|
progress.info("Found existing SMS configuration");
|
|
39434
39543
|
progress.info(
|
|
39435
|
-
`Phone type: ${
|
|
39544
|
+
`Phone type: ${pc57.cyan(smsConfig.phoneNumberType || "simulator")}`
|
|
39436
39545
|
);
|
|
39437
39546
|
progress.info(
|
|
39438
|
-
`Event tracking: ${
|
|
39547
|
+
`Event tracking: ${pc57.cyan(smsConfig.eventTracking?.enabled ? "enabled" : "disabled")}`
|
|
39439
39548
|
);
|
|
39440
39549
|
if (!options.yes) {
|
|
39441
|
-
const confirmed = await
|
|
39550
|
+
const confirmed = await clack54.confirm({
|
|
39442
39551
|
message: "Sync SMS infrastructure? This will update Lambda code and recreate any missing resources.",
|
|
39443
39552
|
initialValue: true
|
|
39444
39553
|
});
|
|
39445
|
-
if (
|
|
39446
|
-
|
|
39554
|
+
if (clack54.isCancel(confirmed) || !confirmed) {
|
|
39555
|
+
clack54.cancel("Sync cancelled.");
|
|
39447
39556
|
process.exit(0);
|
|
39448
39557
|
}
|
|
39449
39558
|
}
|
|
@@ -39548,7 +39657,7 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
39548
39657
|
throw errors.stackLocked();
|
|
39549
39658
|
}
|
|
39550
39659
|
trackError("SYNC_FAILED", "sms:sync", { step: "sync" });
|
|
39551
|
-
|
|
39660
|
+
clack54.log.error(`SMS sync failed: ${errorMessage}`);
|
|
39552
39661
|
process.exit(1);
|
|
39553
39662
|
}
|
|
39554
39663
|
if (metadata && smsService) {
|
|
@@ -39568,7 +39677,7 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
39568
39677
|
return;
|
|
39569
39678
|
}
|
|
39570
39679
|
console.log("\n");
|
|
39571
|
-
|
|
39680
|
+
clack54.log.success(pc57.green("SMS infrastructure synced successfully!"));
|
|
39572
39681
|
const changes = [];
|
|
39573
39682
|
if (outputs.lambdaFunctions?.length) {
|
|
39574
39683
|
changes.push("Lambda functions updated");
|
|
@@ -39576,13 +39685,13 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
39576
39685
|
changes.push("SDK resources verified");
|
|
39577
39686
|
console.log("");
|
|
39578
39687
|
for (const change of changes) {
|
|
39579
|
-
console.log(` ${
|
|
39688
|
+
console.log(` ${pc57.green("\u2713")} ${change}`);
|
|
39580
39689
|
}
|
|
39581
39690
|
trackCommand("sms:sync", {
|
|
39582
39691
|
success: true,
|
|
39583
39692
|
duration_ms: Date.now() - startTime
|
|
39584
39693
|
});
|
|
39585
|
-
|
|
39694
|
+
clack54.outro(pc57.green("Sync complete!"));
|
|
39586
39695
|
}
|
|
39587
39696
|
|
|
39588
39697
|
// src/commands/sms/test.ts
|
|
@@ -39597,8 +39706,8 @@ import {
|
|
|
39597
39706
|
PinpointSMSVoiceV2Client as PinpointSMSVoiceV2Client3,
|
|
39598
39707
|
SendTextMessageCommand
|
|
39599
39708
|
} from "@aws-sdk/client-pinpoint-sms-voice-v2";
|
|
39600
|
-
import * as
|
|
39601
|
-
import
|
|
39709
|
+
import * as clack55 from "@clack/prompts";
|
|
39710
|
+
import pc58 from "picocolors";
|
|
39602
39711
|
|
|
39603
39712
|
// src/utils/sms/validation.ts
|
|
39604
39713
|
init_esm_shims();
|
|
@@ -39621,7 +39730,7 @@ async function smsTest(options) {
|
|
|
39621
39730
|
const startTime = Date.now();
|
|
39622
39731
|
const progress = new DeploymentProgress();
|
|
39623
39732
|
if (!isJsonMode()) {
|
|
39624
|
-
|
|
39733
|
+
clack55.intro(pc58.bold("Wraps SMS Test"));
|
|
39625
39734
|
}
|
|
39626
39735
|
const identity = await progress.execute(
|
|
39627
39736
|
"Validating AWS credentials",
|
|
@@ -39631,10 +39740,10 @@ async function smsTest(options) {
|
|
|
39631
39740
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
39632
39741
|
if (!metadata?.services?.sms) {
|
|
39633
39742
|
progress.stop();
|
|
39634
|
-
|
|
39743
|
+
clack55.log.error("No SMS infrastructure found");
|
|
39635
39744
|
console.log(
|
|
39636
39745
|
`
|
|
39637
|
-
Run ${
|
|
39746
|
+
Run ${pc58.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
39638
39747
|
`
|
|
39639
39748
|
);
|
|
39640
39749
|
process.exit(1);
|
|
@@ -39648,7 +39757,7 @@ Run ${pc57.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39648
39757
|
);
|
|
39649
39758
|
}
|
|
39650
39759
|
if (!toNumber) {
|
|
39651
|
-
const destinationType = await
|
|
39760
|
+
const destinationType = await clack55.select({
|
|
39652
39761
|
message: "Choose destination number:",
|
|
39653
39762
|
options: [
|
|
39654
39763
|
{
|
|
@@ -39663,25 +39772,25 @@ Run ${pc57.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39663
39772
|
}
|
|
39664
39773
|
]
|
|
39665
39774
|
});
|
|
39666
|
-
if (
|
|
39667
|
-
|
|
39775
|
+
if (clack55.isCancel(destinationType)) {
|
|
39776
|
+
clack55.cancel("Operation cancelled.");
|
|
39668
39777
|
process.exit(0);
|
|
39669
39778
|
}
|
|
39670
39779
|
if (destinationType === "simulator") {
|
|
39671
|
-
const simResult = await
|
|
39780
|
+
const simResult = await clack55.select({
|
|
39672
39781
|
message: "Select simulator destination:",
|
|
39673
39782
|
options: SIMULATOR_DESTINATIONS.map((sim) => ({
|
|
39674
39783
|
value: sim.number,
|
|
39675
39784
|
label: `${sim.number} | ${sim.country}`
|
|
39676
39785
|
}))
|
|
39677
39786
|
});
|
|
39678
|
-
if (
|
|
39679
|
-
|
|
39787
|
+
if (clack55.isCancel(simResult)) {
|
|
39788
|
+
clack55.cancel("Operation cancelled.");
|
|
39680
39789
|
process.exit(0);
|
|
39681
39790
|
}
|
|
39682
39791
|
toNumber = simResult;
|
|
39683
39792
|
} else {
|
|
39684
|
-
const result = await
|
|
39793
|
+
const result = await clack55.text({
|
|
39685
39794
|
message: "Enter destination phone number (E.164 format):",
|
|
39686
39795
|
placeholder: "+14155551234",
|
|
39687
39796
|
validate: (value) => {
|
|
@@ -39694,22 +39803,22 @@ Run ${pc57.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39694
39803
|
return;
|
|
39695
39804
|
}
|
|
39696
39805
|
});
|
|
39697
|
-
if (
|
|
39698
|
-
|
|
39806
|
+
if (clack55.isCancel(result)) {
|
|
39807
|
+
clack55.cancel("Operation cancelled.");
|
|
39699
39808
|
process.exit(0);
|
|
39700
39809
|
}
|
|
39701
39810
|
toNumber = result;
|
|
39702
39811
|
}
|
|
39703
39812
|
} else if (!isValidPhoneNumber(toNumber)) {
|
|
39704
39813
|
progress.stop();
|
|
39705
|
-
|
|
39814
|
+
clack55.log.error(
|
|
39706
39815
|
`Invalid phone number format: ${toNumber}. Use E.164 format (e.g., +14155551234)`
|
|
39707
39816
|
);
|
|
39708
39817
|
process.exit(1);
|
|
39709
39818
|
}
|
|
39710
39819
|
let message = options.message;
|
|
39711
39820
|
if (!message) {
|
|
39712
|
-
const result = await
|
|
39821
|
+
const result = await clack55.text({
|
|
39713
39822
|
message: "Enter test message:",
|
|
39714
39823
|
placeholder: "Hello from Wraps SMS!",
|
|
39715
39824
|
defaultValue: "Hello from Wraps SMS! This is a test message.",
|
|
@@ -39723,8 +39832,8 @@ Run ${pc57.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39723
39832
|
return;
|
|
39724
39833
|
}
|
|
39725
39834
|
});
|
|
39726
|
-
if (
|
|
39727
|
-
|
|
39835
|
+
if (clack55.isCancel(result)) {
|
|
39836
|
+
clack55.cancel("Operation cancelled.");
|
|
39728
39837
|
process.exit(0);
|
|
39729
39838
|
}
|
|
39730
39839
|
message = result;
|
|
@@ -39763,16 +39872,16 @@ Run ${pc57.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39763
39872
|
return;
|
|
39764
39873
|
}
|
|
39765
39874
|
console.log("\n");
|
|
39766
|
-
|
|
39875
|
+
clack55.log.success(pc58.green("Test SMS sent successfully!"));
|
|
39767
39876
|
console.log("");
|
|
39768
|
-
|
|
39877
|
+
clack55.note(
|
|
39769
39878
|
[
|
|
39770
|
-
`${
|
|
39771
|
-
`${
|
|
39772
|
-
`${
|
|
39773
|
-
`${
|
|
39879
|
+
`${pc58.bold("Message ID:")} ${pc58.cyan(messageId || "unknown")}`,
|
|
39880
|
+
`${pc58.bold("To:")} ${pc58.cyan(toNumber)}`,
|
|
39881
|
+
`${pc58.bold("Message:")} ${message}`,
|
|
39882
|
+
`${pc58.bold("Type:")} ${pc58.cyan(smsConfig?.phoneNumberType || "simulator")}`,
|
|
39774
39883
|
"",
|
|
39775
|
-
|
|
39884
|
+
pc58.dim(
|
|
39776
39885
|
smsConfig?.phoneNumberType === "simulator" ? "Note: Simulator messages are not actually delivered" : "Check your phone for the message!"
|
|
39777
39886
|
)
|
|
39778
39887
|
].join("\n"),
|
|
@@ -39780,11 +39889,11 @@ Run ${pc57.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39780
39889
|
);
|
|
39781
39890
|
if (smsConfig?.eventTracking?.enabled) {
|
|
39782
39891
|
console.log("");
|
|
39783
|
-
|
|
39784
|
-
|
|
39892
|
+
clack55.log.info(
|
|
39893
|
+
pc58.dim("Event tracking is enabled. Check DynamoDB for delivery status.")
|
|
39785
39894
|
);
|
|
39786
39895
|
}
|
|
39787
|
-
|
|
39896
|
+
clack55.outro(pc58.green("Test complete!"));
|
|
39788
39897
|
} catch (error) {
|
|
39789
39898
|
progress.stop();
|
|
39790
39899
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -39796,33 +39905,33 @@ Run ${pc57.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39796
39905
|
});
|
|
39797
39906
|
const errorName = error instanceof Error ? error.name : "";
|
|
39798
39907
|
if (errorName === "ConflictException" || errorMessage.includes("opt-out")) {
|
|
39799
|
-
|
|
39908
|
+
clack55.log.error("Destination number has opted out of messages");
|
|
39800
39909
|
console.log("\nThe recipient has opted out of receiving SMS messages.\n");
|
|
39801
39910
|
} else if (errorName === "ThrottlingException" || errorMessage.includes("spending limit")) {
|
|
39802
|
-
|
|
39911
|
+
clack55.log.error("SMS rate or spending limit reached");
|
|
39803
39912
|
console.log(
|
|
39804
39913
|
"\nCheck your AWS account SMS spending limits in the console.\n"
|
|
39805
39914
|
);
|
|
39806
39915
|
} else if (errorName === "ValidationException") {
|
|
39807
|
-
|
|
39916
|
+
clack55.log.error(`Invalid request: ${errorMessage}`);
|
|
39808
39917
|
} else if (errorMessage.includes("not verified") || errorMessage.includes("not registered")) {
|
|
39809
|
-
|
|
39918
|
+
clack55.log.error("Toll-free number registration is not complete");
|
|
39810
39919
|
console.log(
|
|
39811
39920
|
`
|
|
39812
|
-
Run ${
|
|
39921
|
+
Run ${pc58.cyan("wraps sms register")} to check registration status.
|
|
39813
39922
|
`
|
|
39814
39923
|
);
|
|
39815
39924
|
} else if (errorName === "AccessDeniedException") {
|
|
39816
|
-
|
|
39925
|
+
clack55.log.error(
|
|
39817
39926
|
"Permission denied \u2014 IAM role may be missing SMS send permissions"
|
|
39818
39927
|
);
|
|
39819
39928
|
console.log(
|
|
39820
39929
|
`
|
|
39821
|
-
Run ${
|
|
39930
|
+
Run ${pc58.cyan("wraps sms upgrade")} to update IAM policies.
|
|
39822
39931
|
`
|
|
39823
39932
|
);
|
|
39824
39933
|
} else {
|
|
39825
|
-
|
|
39934
|
+
clack55.log.error(`Failed to send SMS: ${errorMessage}`);
|
|
39826
39935
|
}
|
|
39827
39936
|
process.exit(1);
|
|
39828
39937
|
}
|
|
@@ -39830,9 +39939,9 @@ Run ${pc57.cyan("wraps sms upgrade")} to update IAM policies.
|
|
|
39830
39939
|
|
|
39831
39940
|
// src/commands/sms/upgrade.ts
|
|
39832
39941
|
init_esm_shims();
|
|
39833
|
-
import * as
|
|
39942
|
+
import * as clack56 from "@clack/prompts";
|
|
39834
39943
|
import * as pulumi35 from "@pulumi/pulumi";
|
|
39835
|
-
import
|
|
39944
|
+
import pc59 from "picocolors";
|
|
39836
39945
|
init_events();
|
|
39837
39946
|
init_aws();
|
|
39838
39947
|
init_errors();
|
|
@@ -39847,7 +39956,7 @@ async function smsUpgrade(options) {
|
|
|
39847
39956
|
const startTime = Date.now();
|
|
39848
39957
|
let upgradeAction = "";
|
|
39849
39958
|
if (!isJsonMode()) {
|
|
39850
|
-
|
|
39959
|
+
clack56.intro(pc59.bold("Wraps SMS Upgrade - Enhance Your SMS Infrastructure"));
|
|
39851
39960
|
}
|
|
39852
39961
|
const progress = new DeploymentProgress();
|
|
39853
39962
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -39861,7 +39970,7 @@ async function smsUpgrade(options) {
|
|
|
39861
39970
|
"Validating AWS credentials",
|
|
39862
39971
|
async () => validateAWSCredentials()
|
|
39863
39972
|
);
|
|
39864
|
-
progress.info(`Connected to AWS account: ${
|
|
39973
|
+
progress.info(`Connected to AWS account: ${pc59.cyan(identity.accountId)}`);
|
|
39865
39974
|
const region = await resolveRegionForCommand({
|
|
39866
39975
|
accountId: identity.accountId,
|
|
39867
39976
|
optionRegion: options.region,
|
|
@@ -39870,35 +39979,35 @@ async function smsUpgrade(options) {
|
|
|
39870
39979
|
});
|
|
39871
39980
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
39872
39981
|
if (!metadata) {
|
|
39873
|
-
|
|
39874
|
-
`No Wraps connection found for account ${
|
|
39982
|
+
clack56.log.error(
|
|
39983
|
+
`No Wraps connection found for account ${pc59.cyan(identity.accountId)} in region ${pc59.cyan(region)}`
|
|
39875
39984
|
);
|
|
39876
|
-
|
|
39877
|
-
`Use ${
|
|
39985
|
+
clack56.log.info(
|
|
39986
|
+
`Use ${pc59.cyan("wraps sms init")} to create new infrastructure.`
|
|
39878
39987
|
);
|
|
39879
39988
|
process.exit(1);
|
|
39880
39989
|
}
|
|
39881
39990
|
if (!metadata.services.sms) {
|
|
39882
|
-
|
|
39883
|
-
|
|
39884
|
-
`Use ${
|
|
39991
|
+
clack56.log.error("No SMS infrastructure found");
|
|
39992
|
+
clack56.log.info(
|
|
39993
|
+
`Use ${pc59.cyan("wraps sms init")} to deploy SMS infrastructure.`
|
|
39885
39994
|
);
|
|
39886
39995
|
process.exit(1);
|
|
39887
39996
|
}
|
|
39888
39997
|
progress.info(`Found existing connection created: ${metadata.timestamp}`);
|
|
39889
39998
|
console.log(`
|
|
39890
|
-
${
|
|
39999
|
+
${pc59.bold("Current Configuration:")}
|
|
39891
40000
|
`);
|
|
39892
40001
|
if (metadata.services.sms.preset) {
|
|
39893
|
-
console.log(` Preset: ${
|
|
40002
|
+
console.log(` Preset: ${pc59.cyan(metadata.services.sms.preset)}`);
|
|
39894
40003
|
} else {
|
|
39895
|
-
console.log(` Preset: ${
|
|
40004
|
+
console.log(` Preset: ${pc59.cyan("custom")}`);
|
|
39896
40005
|
}
|
|
39897
40006
|
const config2 = metadata.services.sms.config;
|
|
39898
40007
|
if (!config2) {
|
|
39899
|
-
|
|
39900
|
-
|
|
39901
|
-
`Use ${
|
|
40008
|
+
clack56.log.error("No SMS configuration found in metadata");
|
|
40009
|
+
clack56.log.info(
|
|
40010
|
+
`Use ${pc59.cyan("wraps sms init")} to create new infrastructure.`
|
|
39902
40011
|
);
|
|
39903
40012
|
process.exit(1);
|
|
39904
40013
|
}
|
|
@@ -39910,45 +40019,45 @@ ${pc58.bold("Current Configuration:")}
|
|
|
39910
40019
|
"short-code": "Short code ($995+/mo, 100+ MPS)"
|
|
39911
40020
|
};
|
|
39912
40021
|
console.log(
|
|
39913
|
-
` Phone Type: ${
|
|
40022
|
+
` Phone Type: ${pc59.cyan(phoneTypeLabels2[config2.phoneNumberType] || config2.phoneNumberType)}`
|
|
39914
40023
|
);
|
|
39915
40024
|
}
|
|
39916
40025
|
if (config2.tracking?.enabled) {
|
|
39917
|
-
console.log(` ${
|
|
40026
|
+
console.log(` ${pc59.green("\u2713")} Delivery Tracking`);
|
|
39918
40027
|
if (config2.tracking.linkTracking) {
|
|
39919
|
-
console.log(` ${
|
|
40028
|
+
console.log(` ${pc59.dim("\u2514\u2500")} Link click tracking enabled`);
|
|
39920
40029
|
}
|
|
39921
40030
|
}
|
|
39922
40031
|
if (config2.eventTracking?.enabled) {
|
|
39923
|
-
console.log(` ${
|
|
40032
|
+
console.log(` ${pc59.green("\u2713")} Event Tracking (SNS)`);
|
|
39924
40033
|
if (config2.eventTracking.dynamoDBHistory) {
|
|
39925
40034
|
console.log(
|
|
39926
|
-
` ${
|
|
40035
|
+
` ${pc59.dim("\u2514\u2500")} Message History: ${pc59.cyan(config2.eventTracking.archiveRetention || "90days")}`
|
|
39927
40036
|
);
|
|
39928
40037
|
}
|
|
39929
40038
|
}
|
|
39930
40039
|
if (config2.messageArchiving?.enabled) {
|
|
39931
40040
|
console.log(
|
|
39932
|
-
` ${
|
|
40041
|
+
` ${pc59.green("\u2713")} Message Archiving (${config2.messageArchiving.retention})`
|
|
39933
40042
|
);
|
|
39934
40043
|
}
|
|
39935
40044
|
if (config2.optOutManagement) {
|
|
39936
|
-
console.log(` ${
|
|
40045
|
+
console.log(` ${pc59.green("\u2713")} Opt-out Management`);
|
|
39937
40046
|
}
|
|
39938
40047
|
if (config2.protectConfiguration?.enabled) {
|
|
39939
40048
|
const countries = config2.protectConfiguration.allowedCountries?.join(", ") || "US";
|
|
39940
|
-
console.log(` ${
|
|
39941
|
-
console.log(` ${
|
|
40049
|
+
console.log(` ${pc59.green("\u2713")} Fraud Protection`);
|
|
40050
|
+
console.log(` ${pc59.dim("\u2514\u2500")} Allowed countries: ${pc59.cyan(countries)}`);
|
|
39942
40051
|
if (config2.protectConfiguration.aitFiltering) {
|
|
39943
|
-
console.log(` ${
|
|
40052
|
+
console.log(` ${pc59.dim("\u2514\u2500")} AIT filtering: ${pc59.cyan("enabled")}`);
|
|
39944
40053
|
}
|
|
39945
40054
|
} else {
|
|
39946
|
-
console.log(` ${
|
|
40055
|
+
console.log(` ${pc59.dim("\u25CB")} Fraud Protection (not configured)`);
|
|
39947
40056
|
}
|
|
39948
40057
|
const currentCostData = calculateSMSCosts(config2, 1e4);
|
|
39949
40058
|
console.log(
|
|
39950
40059
|
`
|
|
39951
|
-
Estimated Cost: ${
|
|
40060
|
+
Estimated Cost: ${pc59.cyan(`~${formatCost3(currentCostData.total.monthly)}/mo`)}`
|
|
39952
40061
|
);
|
|
39953
40062
|
console.log("");
|
|
39954
40063
|
const phoneTypeLabels = {
|
|
@@ -39957,7 +40066,7 @@ ${pc58.bold("Current Configuration:")}
|
|
|
39957
40066
|
"10dlc": "10DLC",
|
|
39958
40067
|
"short-code": "Short code"
|
|
39959
40068
|
};
|
|
39960
|
-
upgradeAction = await
|
|
40069
|
+
upgradeAction = await clack56.select({
|
|
39961
40070
|
message: "What would you like to do?",
|
|
39962
40071
|
options: [
|
|
39963
40072
|
{
|
|
@@ -39997,8 +40106,8 @@ ${pc58.bold("Current Configuration:")}
|
|
|
39997
40106
|
}
|
|
39998
40107
|
]
|
|
39999
40108
|
});
|
|
40000
|
-
if (
|
|
40001
|
-
|
|
40109
|
+
if (clack56.isCancel(upgradeAction)) {
|
|
40110
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40002
40111
|
process.exit(0);
|
|
40003
40112
|
}
|
|
40004
40113
|
let updatedConfig = { ...config2 };
|
|
@@ -40039,65 +40148,65 @@ ${pc58.bold("Current Configuration:")}
|
|
|
40039
40148
|
hint: p.hint
|
|
40040
40149
|
}));
|
|
40041
40150
|
if (availableTypes.length === 0) {
|
|
40042
|
-
|
|
40151
|
+
clack56.log.warn(
|
|
40043
40152
|
"Already on highest phone number tier. Contact AWS for dedicated short codes."
|
|
40044
40153
|
);
|
|
40045
40154
|
process.exit(0);
|
|
40046
40155
|
}
|
|
40047
|
-
const selectedType = await
|
|
40156
|
+
const selectedType = await clack56.select({
|
|
40048
40157
|
message: "Select new phone number type:",
|
|
40049
40158
|
options: availableTypes
|
|
40050
40159
|
});
|
|
40051
|
-
if (
|
|
40052
|
-
|
|
40160
|
+
if (clack56.isCancel(selectedType)) {
|
|
40161
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40053
40162
|
process.exit(0);
|
|
40054
40163
|
}
|
|
40055
40164
|
if (selectedType === "toll-free") {
|
|
40056
40165
|
console.log(
|
|
40057
40166
|
`
|
|
40058
|
-
${
|
|
40167
|
+
${pc59.yellow("\u26A0")} ${pc59.bold("Toll-free Registration Required")}
|
|
40059
40168
|
`
|
|
40060
40169
|
);
|
|
40061
40170
|
console.log(
|
|
40062
|
-
|
|
40171
|
+
pc59.dim("Toll-free numbers require carrier registration before")
|
|
40063
40172
|
);
|
|
40064
40173
|
console.log(
|
|
40065
|
-
|
|
40174
|
+
pc59.dim("they can send messages at scale. After deployment:\n")
|
|
40066
40175
|
);
|
|
40067
40176
|
console.log(
|
|
40068
|
-
` 1. Run ${
|
|
40177
|
+
` 1. Run ${pc59.cyan("wraps sms register")} to start registration`
|
|
40069
40178
|
);
|
|
40070
40179
|
console.log(" 2. Submit your business use case information");
|
|
40071
40180
|
console.log(" 3. Wait for carrier verification (1-5 business days)");
|
|
40072
40181
|
console.log(
|
|
40073
|
-
|
|
40182
|
+
pc59.dim("\nUntil verified, sending is limited to low volume.\n")
|
|
40074
40183
|
);
|
|
40075
|
-
const confirmTollFree = await
|
|
40184
|
+
const confirmTollFree = await clack56.confirm({
|
|
40076
40185
|
message: "Continue with toll-free number request?",
|
|
40077
40186
|
initialValue: true
|
|
40078
40187
|
});
|
|
40079
|
-
if (
|
|
40080
|
-
|
|
40188
|
+
if (clack56.isCancel(confirmTollFree) || !confirmTollFree) {
|
|
40189
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40081
40190
|
process.exit(0);
|
|
40082
40191
|
}
|
|
40083
40192
|
}
|
|
40084
40193
|
if (selectedType === "10dlc") {
|
|
40085
40194
|
console.log(
|
|
40086
40195
|
`
|
|
40087
|
-
${
|
|
40196
|
+
${pc59.yellow("\u26A0")} ${pc59.bold("10DLC Campaign Registration Required")}
|
|
40088
40197
|
`
|
|
40089
40198
|
);
|
|
40090
|
-
console.log(
|
|
40199
|
+
console.log(pc59.dim("10DLC requires brand and campaign registration:"));
|
|
40091
40200
|
console.log(" \u2022 Brand registration: one-time $4 fee");
|
|
40092
40201
|
console.log(" \u2022 Campaign registration: $15/mo per campaign");
|
|
40093
40202
|
console.log(" \u2022 Verification takes 1-7 business days");
|
|
40094
40203
|
console.log("");
|
|
40095
|
-
const confirm10DLC = await
|
|
40204
|
+
const confirm10DLC = await clack56.confirm({
|
|
40096
40205
|
message: "Continue with 10DLC number request?",
|
|
40097
40206
|
initialValue: true
|
|
40098
40207
|
});
|
|
40099
|
-
if (
|
|
40100
|
-
|
|
40208
|
+
if (clack56.isCancel(confirm10DLC) || !confirm10DLC) {
|
|
40209
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40101
40210
|
process.exit(0);
|
|
40102
40211
|
}
|
|
40103
40212
|
}
|
|
@@ -40122,15 +40231,15 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40122
40231
|
disabled: currentPresetIdx >= 0 && idx <= currentPresetIdx ? "Current or lower tier" : void 0
|
|
40123
40232
|
})).filter((p) => !p.disabled && p.value !== "custom");
|
|
40124
40233
|
if (availablePresets.length === 0) {
|
|
40125
|
-
|
|
40234
|
+
clack56.log.warn("Already on highest preset (Enterprise)");
|
|
40126
40235
|
process.exit(0);
|
|
40127
40236
|
}
|
|
40128
|
-
const selectedPreset = await
|
|
40237
|
+
const selectedPreset = await clack56.select({
|
|
40129
40238
|
message: "Select new preset:",
|
|
40130
40239
|
options: availablePresets
|
|
40131
40240
|
});
|
|
40132
|
-
if (
|
|
40133
|
-
|
|
40241
|
+
if (clack56.isCancel(selectedPreset)) {
|
|
40242
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40134
40243
|
process.exit(0);
|
|
40135
40244
|
}
|
|
40136
40245
|
const presetConfig = getSMSPreset(selectedPreset);
|
|
@@ -40146,7 +40255,7 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40146
40255
|
}
|
|
40147
40256
|
case "event-tracking": {
|
|
40148
40257
|
if (config2.eventTracking?.enabled) {
|
|
40149
|
-
const eventAction = await
|
|
40258
|
+
const eventAction = await clack56.select({
|
|
40150
40259
|
message: "What would you like to do with event tracking?",
|
|
40151
40260
|
options: [
|
|
40152
40261
|
{
|
|
@@ -40161,17 +40270,17 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40161
40270
|
}
|
|
40162
40271
|
]
|
|
40163
40272
|
});
|
|
40164
|
-
if (
|
|
40165
|
-
|
|
40273
|
+
if (clack56.isCancel(eventAction)) {
|
|
40274
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40166
40275
|
process.exit(0);
|
|
40167
40276
|
}
|
|
40168
40277
|
if (eventAction === "disable") {
|
|
40169
|
-
const confirmDisable = await
|
|
40278
|
+
const confirmDisable = await clack56.confirm({
|
|
40170
40279
|
message: "Are you sure? Existing history will remain, but new events won't be tracked.",
|
|
40171
40280
|
initialValue: false
|
|
40172
40281
|
});
|
|
40173
|
-
if (
|
|
40174
|
-
|
|
40282
|
+
if (clack56.isCancel(confirmDisable) || !confirmDisable) {
|
|
40283
|
+
clack56.cancel("Event tracking not disabled.");
|
|
40175
40284
|
process.exit(0);
|
|
40176
40285
|
}
|
|
40177
40286
|
updatedConfig = {
|
|
@@ -40181,7 +40290,7 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40181
40290
|
}
|
|
40182
40291
|
};
|
|
40183
40292
|
} else {
|
|
40184
|
-
const retention = await
|
|
40293
|
+
const retention = await clack56.select({
|
|
40185
40294
|
message: "Message history retention period:",
|
|
40186
40295
|
options: [
|
|
40187
40296
|
{ value: "7days", label: "7 days", hint: "Minimal storage cost" },
|
|
@@ -40208,8 +40317,8 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40208
40317
|
],
|
|
40209
40318
|
initialValue: config2.eventTracking.archiveRetention || "90days"
|
|
40210
40319
|
});
|
|
40211
|
-
if (
|
|
40212
|
-
|
|
40320
|
+
if (clack56.isCancel(retention)) {
|
|
40321
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40213
40322
|
process.exit(0);
|
|
40214
40323
|
}
|
|
40215
40324
|
updatedConfig = {
|
|
@@ -40221,19 +40330,19 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40221
40330
|
};
|
|
40222
40331
|
}
|
|
40223
40332
|
} else {
|
|
40224
|
-
const enableTracking = await
|
|
40333
|
+
const enableTracking = await clack56.confirm({
|
|
40225
40334
|
message: "Enable event tracking? (Track SMS events with history)",
|
|
40226
40335
|
initialValue: true
|
|
40227
40336
|
});
|
|
40228
|
-
if (
|
|
40229
|
-
|
|
40337
|
+
if (clack56.isCancel(enableTracking)) {
|
|
40338
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40230
40339
|
process.exit(0);
|
|
40231
40340
|
}
|
|
40232
40341
|
if (!enableTracking) {
|
|
40233
|
-
|
|
40342
|
+
clack56.log.info("Event tracking not enabled.");
|
|
40234
40343
|
process.exit(0);
|
|
40235
40344
|
}
|
|
40236
|
-
const retention = await
|
|
40345
|
+
const retention = await clack56.select({
|
|
40237
40346
|
message: "Message history retention period:",
|
|
40238
40347
|
options: [
|
|
40239
40348
|
{ value: "7days", label: "7 days", hint: "Minimal storage cost" },
|
|
@@ -40256,8 +40365,8 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40256
40365
|
],
|
|
40257
40366
|
initialValue: "90days"
|
|
40258
40367
|
});
|
|
40259
|
-
if (
|
|
40260
|
-
|
|
40368
|
+
if (clack56.isCancel(retention)) {
|
|
40369
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40261
40370
|
process.exit(0);
|
|
40262
40371
|
}
|
|
40263
40372
|
updatedConfig = {
|
|
@@ -40276,12 +40385,12 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40276
40385
|
}
|
|
40277
40386
|
case "retention": {
|
|
40278
40387
|
if (!config2.eventTracking?.enabled) {
|
|
40279
|
-
|
|
40388
|
+
clack56.log.error(
|
|
40280
40389
|
"Event tracking is not enabled. Enable it first to change retention."
|
|
40281
40390
|
);
|
|
40282
40391
|
process.exit(1);
|
|
40283
40392
|
}
|
|
40284
|
-
const retention = await
|
|
40393
|
+
const retention = await clack56.select({
|
|
40285
40394
|
message: "Message history retention period (event data in DynamoDB):",
|
|
40286
40395
|
options: [
|
|
40287
40396
|
{ value: "7days", label: "7 days", hint: "Minimal storage cost" },
|
|
@@ -40300,8 +40409,8 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40300
40409
|
],
|
|
40301
40410
|
initialValue: config2.eventTracking.archiveRetention || "90days"
|
|
40302
40411
|
});
|
|
40303
|
-
if (
|
|
40304
|
-
|
|
40412
|
+
if (clack56.isCancel(retention)) {
|
|
40413
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40305
40414
|
process.exit(0);
|
|
40306
40415
|
}
|
|
40307
40416
|
updatedConfig = {
|
|
@@ -40319,21 +40428,21 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40319
40428
|
case "link-tracking": {
|
|
40320
40429
|
const enableLinkTracking = !config2.tracking?.linkTracking;
|
|
40321
40430
|
if (enableLinkTracking) {
|
|
40322
|
-
|
|
40323
|
-
|
|
40431
|
+
clack56.log.info(
|
|
40432
|
+
pc59.dim(
|
|
40324
40433
|
"Link tracking will track clicks on URLs in your SMS messages."
|
|
40325
40434
|
)
|
|
40326
40435
|
);
|
|
40327
|
-
|
|
40328
|
-
|
|
40436
|
+
clack56.log.info(
|
|
40437
|
+
pc59.dim("URLs will be rewritten to go through a tracking endpoint.")
|
|
40329
40438
|
);
|
|
40330
40439
|
}
|
|
40331
|
-
const confirmed = await
|
|
40440
|
+
const confirmed = await clack56.confirm({
|
|
40332
40441
|
message: enableLinkTracking ? "Enable link click tracking?" : "Disable link click tracking?",
|
|
40333
40442
|
initialValue: enableLinkTracking
|
|
40334
40443
|
});
|
|
40335
|
-
if (
|
|
40336
|
-
|
|
40444
|
+
if (clack56.isCancel(confirmed) || !confirmed) {
|
|
40445
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40337
40446
|
process.exit(0);
|
|
40338
40447
|
}
|
|
40339
40448
|
updatedConfig = {
|
|
@@ -40350,7 +40459,7 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40350
40459
|
}
|
|
40351
40460
|
case "archiving": {
|
|
40352
40461
|
if (config2.messageArchiving?.enabled) {
|
|
40353
|
-
const archivingAction = await
|
|
40462
|
+
const archivingAction = await clack56.select({
|
|
40354
40463
|
message: "What would you like to do with message archiving?",
|
|
40355
40464
|
options: [
|
|
40356
40465
|
{
|
|
@@ -40365,17 +40474,17 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40365
40474
|
}
|
|
40366
40475
|
]
|
|
40367
40476
|
});
|
|
40368
|
-
if (
|
|
40369
|
-
|
|
40477
|
+
if (clack56.isCancel(archivingAction)) {
|
|
40478
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40370
40479
|
process.exit(0);
|
|
40371
40480
|
}
|
|
40372
40481
|
if (archivingAction === "disable") {
|
|
40373
|
-
const confirmDisable = await
|
|
40482
|
+
const confirmDisable = await clack56.confirm({
|
|
40374
40483
|
message: "Are you sure? Existing archived messages will remain, but new messages won't be archived.",
|
|
40375
40484
|
initialValue: false
|
|
40376
40485
|
});
|
|
40377
|
-
if (
|
|
40378
|
-
|
|
40486
|
+
if (clack56.isCancel(confirmDisable) || !confirmDisable) {
|
|
40487
|
+
clack56.cancel("Archiving not disabled.");
|
|
40379
40488
|
process.exit(0);
|
|
40380
40489
|
}
|
|
40381
40490
|
updatedConfig = {
|
|
@@ -40386,7 +40495,7 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40386
40495
|
}
|
|
40387
40496
|
};
|
|
40388
40497
|
} else {
|
|
40389
|
-
const retention = await
|
|
40498
|
+
const retention = await clack56.select({
|
|
40390
40499
|
message: "Message archive retention period:",
|
|
40391
40500
|
options: [
|
|
40392
40501
|
{
|
|
@@ -40417,8 +40526,8 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40417
40526
|
],
|
|
40418
40527
|
initialValue: config2.messageArchiving.retention
|
|
40419
40528
|
});
|
|
40420
|
-
if (
|
|
40421
|
-
|
|
40529
|
+
if (clack56.isCancel(retention)) {
|
|
40530
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40422
40531
|
process.exit(0);
|
|
40423
40532
|
}
|
|
40424
40533
|
updatedConfig = {
|
|
@@ -40430,19 +40539,19 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40430
40539
|
};
|
|
40431
40540
|
}
|
|
40432
40541
|
} else {
|
|
40433
|
-
const enableArchiving = await
|
|
40542
|
+
const enableArchiving = await clack56.confirm({
|
|
40434
40543
|
message: "Enable message archiving? (Store full message content for viewing)",
|
|
40435
40544
|
initialValue: true
|
|
40436
40545
|
});
|
|
40437
|
-
if (
|
|
40438
|
-
|
|
40546
|
+
if (clack56.isCancel(enableArchiving)) {
|
|
40547
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40439
40548
|
process.exit(0);
|
|
40440
40549
|
}
|
|
40441
40550
|
if (!enableArchiving) {
|
|
40442
|
-
|
|
40551
|
+
clack56.log.info("Message archiving not enabled.");
|
|
40443
40552
|
process.exit(0);
|
|
40444
40553
|
}
|
|
40445
|
-
const retention = await
|
|
40554
|
+
const retention = await clack56.select({
|
|
40446
40555
|
message: "Message archive retention period:",
|
|
40447
40556
|
options: [
|
|
40448
40557
|
{ value: "7days", label: "7 days", hint: "~$1-2/mo for 10k msgs" },
|
|
@@ -40469,8 +40578,8 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40469
40578
|
],
|
|
40470
40579
|
initialValue: "90days"
|
|
40471
40580
|
});
|
|
40472
|
-
if (
|
|
40473
|
-
|
|
40581
|
+
if (clack56.isCancel(retention)) {
|
|
40582
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40474
40583
|
process.exit(0);
|
|
40475
40584
|
}
|
|
40476
40585
|
updatedConfig = {
|
|
@@ -40502,7 +40611,7 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40502
40611
|
const currentAllowed = config2.protectConfiguration?.allowedCountries || [
|
|
40503
40612
|
"US"
|
|
40504
40613
|
];
|
|
40505
|
-
const selectedCountries = await
|
|
40614
|
+
const selectedCountries = await clack56.multiselect({
|
|
40506
40615
|
message: "Select countries to allow SMS delivery (all others blocked):",
|
|
40507
40616
|
options: commonCountries.map((c) => ({
|
|
40508
40617
|
value: c.code,
|
|
@@ -40511,16 +40620,16 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40511
40620
|
initialValues: currentAllowed,
|
|
40512
40621
|
required: true
|
|
40513
40622
|
});
|
|
40514
|
-
if (
|
|
40515
|
-
|
|
40623
|
+
if (clack56.isCancel(selectedCountries)) {
|
|
40624
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40516
40625
|
process.exit(0);
|
|
40517
40626
|
}
|
|
40518
|
-
const enableAIT = await
|
|
40627
|
+
const enableAIT = await clack56.confirm({
|
|
40519
40628
|
message: "Enable AIT (Artificially Inflated Traffic) filtering? (adds per-message cost)",
|
|
40520
40629
|
initialValue: config2.protectConfiguration?.aitFiltering ?? false
|
|
40521
40630
|
});
|
|
40522
|
-
if (
|
|
40523
|
-
|
|
40631
|
+
if (clack56.isCancel(enableAIT)) {
|
|
40632
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40524
40633
|
process.exit(0);
|
|
40525
40634
|
}
|
|
40526
40635
|
updatedConfig = {
|
|
@@ -40538,28 +40647,28 @@ ${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
|
40538
40647
|
const newCostData = calculateSMSCosts(updatedConfig, 1e4);
|
|
40539
40648
|
const costDiff = newCostData.total.monthly - currentCostData.total.monthly;
|
|
40540
40649
|
console.log(`
|
|
40541
|
-
${
|
|
40650
|
+
${pc59.bold("Cost Impact:")}`);
|
|
40542
40651
|
console.log(
|
|
40543
|
-
` Current: ${
|
|
40652
|
+
` Current: ${pc59.cyan(`${formatCost3(currentCostData.total.monthly)}/mo`)}`
|
|
40544
40653
|
);
|
|
40545
40654
|
console.log(
|
|
40546
|
-
` New: ${
|
|
40655
|
+
` New: ${pc59.cyan(`${formatCost3(newCostData.total.monthly)}/mo`)}`
|
|
40547
40656
|
);
|
|
40548
40657
|
if (costDiff > 0) {
|
|
40549
|
-
console.log(` Change: ${
|
|
40658
|
+
console.log(` Change: ${pc59.yellow(`+${formatCost3(costDiff)}/mo`)}`);
|
|
40550
40659
|
} else if (costDiff < 0) {
|
|
40551
40660
|
console.log(
|
|
40552
|
-
` Change: ${
|
|
40661
|
+
` Change: ${pc59.green(`-${formatCost3(Math.abs(costDiff))}/mo`)}`
|
|
40553
40662
|
);
|
|
40554
40663
|
}
|
|
40555
40664
|
console.log("");
|
|
40556
40665
|
if (!(options.yes || options.preview)) {
|
|
40557
|
-
const confirmed = await
|
|
40666
|
+
const confirmed = await clack56.confirm({
|
|
40558
40667
|
message: "Proceed with upgrade?",
|
|
40559
40668
|
initialValue: true
|
|
40560
40669
|
});
|
|
40561
|
-
if (
|
|
40562
|
-
|
|
40670
|
+
if (clack56.isCancel(confirmed) || !confirmed) {
|
|
40671
|
+
clack56.cancel("Upgrade cancelled.");
|
|
40563
40672
|
process.exit(0);
|
|
40564
40673
|
}
|
|
40565
40674
|
}
|
|
@@ -40628,8 +40737,8 @@ ${pc58.bold("Cost Impact:")}`);
|
|
|
40628
40737
|
resourceChanges: previewResult.resourceChanges,
|
|
40629
40738
|
commandName: "wraps sms upgrade"
|
|
40630
40739
|
});
|
|
40631
|
-
|
|
40632
|
-
|
|
40740
|
+
clack56.outro(
|
|
40741
|
+
pc59.green("Preview complete. Run without --preview to upgrade.")
|
|
40633
40742
|
);
|
|
40634
40743
|
trackServiceUpgrade("sms", {
|
|
40635
40744
|
region,
|
|
@@ -40734,43 +40843,43 @@ ${pc58.bold("Cost Impact:")}`);
|
|
|
40734
40843
|
}
|
|
40735
40844
|
progress.info("Connection metadata updated");
|
|
40736
40845
|
console.log("\n");
|
|
40737
|
-
|
|
40846
|
+
clack56.log.success(pc59.green(pc59.bold("SMS infrastructure upgraded!")));
|
|
40738
40847
|
console.log("\n");
|
|
40739
|
-
|
|
40848
|
+
clack56.note(
|
|
40740
40849
|
[
|
|
40741
|
-
`${
|
|
40742
|
-
`${
|
|
40743
|
-
`${
|
|
40744
|
-
`${
|
|
40745
|
-
outputs.tableName ? `${
|
|
40850
|
+
`${pc59.bold("Phone Number:")} ${pc59.cyan(outputs.phoneNumber || "Provisioning...")}`,
|
|
40851
|
+
`${pc59.bold("Phone Type:")} ${pc59.cyan(updatedConfig.phoneNumberType || "simulator")}`,
|
|
40852
|
+
`${pc59.bold("Config Set:")} ${pc59.cyan(outputs.configSetName || "wraps-sms-config")}`,
|
|
40853
|
+
`${pc59.bold("Region:")} ${pc59.cyan(outputs.region)}`,
|
|
40854
|
+
outputs.tableName ? `${pc59.bold("History Table:")} ${pc59.cyan(outputs.tableName)}` : "",
|
|
40746
40855
|
"",
|
|
40747
|
-
|
|
40748
|
-
|
|
40856
|
+
pc59.dim("IAM Role:"),
|
|
40857
|
+
pc59.dim(` ${outputs.roleArn}`)
|
|
40749
40858
|
].filter(Boolean).join("\n"),
|
|
40750
40859
|
"SMS Infrastructure"
|
|
40751
40860
|
);
|
|
40752
40861
|
console.log(`
|
|
40753
|
-
${
|
|
40862
|
+
${pc59.green("\u2713")} ${pc59.bold("Upgrade complete!")}
|
|
40754
40863
|
`);
|
|
40755
40864
|
if (upgradeAction === "phone-number") {
|
|
40756
40865
|
console.log(
|
|
40757
|
-
`Upgraded to ${
|
|
40866
|
+
`Upgraded to ${pc59.cyan(updatedConfig.phoneNumberType)} number (${pc59.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
40758
40867
|
`
|
|
40759
40868
|
);
|
|
40760
40869
|
if (updatedConfig.phoneNumberType === "toll-free") {
|
|
40761
|
-
console.log(`${
|
|
40870
|
+
console.log(`${pc59.bold("Next Steps:")}`);
|
|
40762
40871
|
console.log(
|
|
40763
|
-
` 1. Run ${
|
|
40872
|
+
` 1. Run ${pc59.cyan("wraps sms register")} to start toll-free registration`
|
|
40764
40873
|
);
|
|
40765
40874
|
console.log(" 2. Submit your business information and use case");
|
|
40766
40875
|
console.log(" 3. Wait for carrier verification (1-5 business days)");
|
|
40767
40876
|
console.log("");
|
|
40768
40877
|
console.log(
|
|
40769
|
-
|
|
40878
|
+
pc59.dim("Until verified, your number can only send limited messages.")
|
|
40770
40879
|
);
|
|
40771
40880
|
console.log("");
|
|
40772
40881
|
} else if (updatedConfig.phoneNumberType === "10dlc") {
|
|
40773
|
-
console.log(`${
|
|
40882
|
+
console.log(`${pc59.bold("Next Steps:")}`);
|
|
40774
40883
|
console.log(" 1. Register your brand in the AWS Console");
|
|
40775
40884
|
console.log(" 2. Create a 10DLC campaign for your use case");
|
|
40776
40885
|
console.log(" 3. Wait for campaign approval (1-7 business days)");
|
|
@@ -40778,16 +40887,16 @@ ${pc58.green("\u2713")} ${pc58.bold("Upgrade complete!")}
|
|
|
40778
40887
|
}
|
|
40779
40888
|
} else if (upgradeAction === "preset" && newPreset) {
|
|
40780
40889
|
console.log(
|
|
40781
|
-
`Upgraded to ${
|
|
40890
|
+
`Upgraded to ${pc59.cyan(newPreset)} preset (${pc59.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
40782
40891
|
`
|
|
40783
40892
|
);
|
|
40784
40893
|
} else {
|
|
40785
40894
|
console.log(
|
|
40786
|
-
`Updated configuration (${
|
|
40895
|
+
`Updated configuration (${pc59.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
40787
40896
|
`
|
|
40788
40897
|
);
|
|
40789
40898
|
}
|
|
40790
|
-
console.log(
|
|
40899
|
+
console.log(pc59.dim(getSMSCostSummary(updatedConfig, 1e4)));
|
|
40791
40900
|
const enabledFeatures = [];
|
|
40792
40901
|
if (updatedConfig.tracking?.enabled) {
|
|
40793
40902
|
enabledFeatures.push("tracking");
|
|
@@ -40811,7 +40920,7 @@ ${pc58.green("\u2713")} ${pc58.bold("Upgrade complete!")}
|
|
|
40811
40920
|
action: typeof upgradeAction === "string" ? upgradeAction : void 0,
|
|
40812
40921
|
duration_ms: Date.now() - startTime
|
|
40813
40922
|
});
|
|
40814
|
-
|
|
40923
|
+
clack56.outro(pc59.green("Upgrade complete!"));
|
|
40815
40924
|
}
|
|
40816
40925
|
|
|
40817
40926
|
// src/commands/sms/verify-number.ts
|
|
@@ -40830,13 +40939,13 @@ import {
|
|
|
40830
40939
|
SendDestinationNumberVerificationCodeCommand,
|
|
40831
40940
|
VerifyDestinationNumberCommand
|
|
40832
40941
|
} from "@aws-sdk/client-pinpoint-sms-voice-v2";
|
|
40833
|
-
import * as
|
|
40834
|
-
import
|
|
40942
|
+
import * as clack57 from "@clack/prompts";
|
|
40943
|
+
import pc60 from "picocolors";
|
|
40835
40944
|
async function smsVerifyNumber(options) {
|
|
40836
40945
|
const startTime = Date.now();
|
|
40837
40946
|
const progress = new DeploymentProgress();
|
|
40838
40947
|
if (!isJsonMode()) {
|
|
40839
|
-
|
|
40948
|
+
clack57.intro(pc60.bold("Wraps SMS - Verify Destination Number"));
|
|
40840
40949
|
}
|
|
40841
40950
|
const identity = await progress.execute(
|
|
40842
40951
|
"Validating AWS credentials",
|
|
@@ -40846,10 +40955,10 @@ async function smsVerifyNumber(options) {
|
|
|
40846
40955
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
40847
40956
|
if (!metadata?.services?.sms) {
|
|
40848
40957
|
progress.stop();
|
|
40849
|
-
|
|
40958
|
+
clack57.log.error("No SMS infrastructure found");
|
|
40850
40959
|
console.log(
|
|
40851
40960
|
`
|
|
40852
|
-
Run ${
|
|
40961
|
+
Run ${pc60.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
40853
40962
|
`
|
|
40854
40963
|
);
|
|
40855
40964
|
process.exit(1);
|
|
@@ -40863,19 +40972,19 @@ Run ${pc59.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
40863
40972
|
);
|
|
40864
40973
|
progress.stop();
|
|
40865
40974
|
if (!response.VerifiedDestinationNumbers || response.VerifiedDestinationNumbers.length === 0) {
|
|
40866
|
-
|
|
40975
|
+
clack57.log.info("No verified destination numbers found");
|
|
40867
40976
|
console.log(
|
|
40868
40977
|
`
|
|
40869
|
-
Run ${
|
|
40978
|
+
Run ${pc60.cyan("wraps sms verify-number")} to verify a number.
|
|
40870
40979
|
`
|
|
40871
40980
|
);
|
|
40872
40981
|
} else {
|
|
40873
40982
|
console.log("\n");
|
|
40874
|
-
|
|
40983
|
+
clack57.log.info(pc60.bold("Verified Destination Numbers:"));
|
|
40875
40984
|
console.log("");
|
|
40876
40985
|
for (const num of response.VerifiedDestinationNumbers) {
|
|
40877
|
-
const status2 = num.Status === "VERIFIED" ?
|
|
40878
|
-
console.log(` ${
|
|
40986
|
+
const status2 = num.Status === "VERIFIED" ? pc60.green("\u2713 Verified") : pc60.yellow("\u29D6 Pending");
|
|
40987
|
+
console.log(` ${pc60.cyan(num.DestinationPhoneNumber)} - ${status2}`);
|
|
40879
40988
|
}
|
|
40880
40989
|
console.log("");
|
|
40881
40990
|
}
|
|
@@ -40893,7 +41002,7 @@ Run ${pc59.cyan("wraps sms verify-number")} to verify a number.
|
|
|
40893
41002
|
});
|
|
40894
41003
|
return;
|
|
40895
41004
|
}
|
|
40896
|
-
|
|
41005
|
+
clack57.outro(pc60.green("Done!"));
|
|
40897
41006
|
return;
|
|
40898
41007
|
} catch (error) {
|
|
40899
41008
|
progress.stop();
|
|
@@ -40901,7 +41010,7 @@ Run ${pc59.cyan("wraps sms verify-number")} to verify a number.
|
|
|
40901
41010
|
trackError("SMS_LIST_VERIFIED_FAILED", "sms:verify-number:list", {
|
|
40902
41011
|
error: errorMessage
|
|
40903
41012
|
});
|
|
40904
|
-
|
|
41013
|
+
clack57.log.error(`Failed to list verified numbers: ${errorMessage}`);
|
|
40905
41014
|
process.exit(1);
|
|
40906
41015
|
}
|
|
40907
41016
|
}
|
|
@@ -40909,10 +41018,10 @@ Run ${pc59.cyan("wraps sms verify-number")} to verify a number.
|
|
|
40909
41018
|
const phoneNumber2 = options.phoneNumber;
|
|
40910
41019
|
if (!phoneNumber2) {
|
|
40911
41020
|
progress.stop();
|
|
40912
|
-
|
|
41021
|
+
clack57.log.error("Phone number is required for deletion");
|
|
40913
41022
|
console.log(
|
|
40914
41023
|
`
|
|
40915
|
-
Usage: ${
|
|
41024
|
+
Usage: ${pc60.cyan("wraps sms verify-number --delete --phone-number +14155551234")}
|
|
40916
41025
|
`
|
|
40917
41026
|
);
|
|
40918
41027
|
process.exit(1);
|
|
@@ -40926,7 +41035,7 @@ Usage: ${pc59.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40926
41035
|
const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
|
|
40927
41036
|
if (!verifiedNumber?.VerifiedDestinationNumberId) {
|
|
40928
41037
|
progress.stop();
|
|
40929
|
-
|
|
41038
|
+
clack57.log.error(`Number ${phoneNumber2} is not in verified list`);
|
|
40930
41039
|
process.exit(1);
|
|
40931
41040
|
}
|
|
40932
41041
|
await progress.execute(`Removing ${phoneNumber2}`, async () => {
|
|
@@ -40937,7 +41046,7 @@ Usage: ${pc59.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40937
41046
|
);
|
|
40938
41047
|
});
|
|
40939
41048
|
progress.stop();
|
|
40940
|
-
|
|
41049
|
+
clack57.log.success(`Removed ${pc60.cyan(phoneNumber2)} from verified list`);
|
|
40941
41050
|
trackCommand("sms:verify-number:delete", {
|
|
40942
41051
|
success: true,
|
|
40943
41052
|
duration_ms: Date.now() - startTime
|
|
@@ -40949,7 +41058,7 @@ Usage: ${pc59.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40949
41058
|
});
|
|
40950
41059
|
return;
|
|
40951
41060
|
}
|
|
40952
|
-
|
|
41061
|
+
clack57.outro(pc60.green("Done!"));
|
|
40953
41062
|
return;
|
|
40954
41063
|
} catch (error) {
|
|
40955
41064
|
progress.stop();
|
|
@@ -40957,7 +41066,7 @@ Usage: ${pc59.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40957
41066
|
trackError("SMS_DELETE_VERIFIED_FAILED", "sms:verify-number:delete", {
|
|
40958
41067
|
error: errorMessage
|
|
40959
41068
|
});
|
|
40960
|
-
|
|
41069
|
+
clack57.log.error(`Failed to delete verified number: ${errorMessage}`);
|
|
40961
41070
|
process.exit(1);
|
|
40962
41071
|
}
|
|
40963
41072
|
}
|
|
@@ -40970,7 +41079,7 @@ Usage: ${pc59.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40970
41079
|
);
|
|
40971
41080
|
}
|
|
40972
41081
|
if (!phoneNumber) {
|
|
40973
|
-
const result = await
|
|
41082
|
+
const result = await clack57.text({
|
|
40974
41083
|
message: "Enter phone number to verify (E.164 format):",
|
|
40975
41084
|
placeholder: "+14155551234",
|
|
40976
41085
|
validate: (value) => {
|
|
@@ -40983,14 +41092,14 @@ Usage: ${pc59.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40983
41092
|
return;
|
|
40984
41093
|
}
|
|
40985
41094
|
});
|
|
40986
|
-
if (
|
|
40987
|
-
|
|
41095
|
+
if (clack57.isCancel(result)) {
|
|
41096
|
+
clack57.cancel("Operation cancelled.");
|
|
40988
41097
|
process.exit(0);
|
|
40989
41098
|
}
|
|
40990
41099
|
phoneNumber = result;
|
|
40991
41100
|
} else if (!isValidPhoneNumber(phoneNumber)) {
|
|
40992
41101
|
progress.stop();
|
|
40993
|
-
|
|
41102
|
+
clack57.log.error(
|
|
40994
41103
|
`Invalid phone number format: ${phoneNumber}. Use E.164 format (e.g., +14155551234)`
|
|
40995
41104
|
);
|
|
40996
41105
|
process.exit(1);
|
|
@@ -41005,7 +41114,7 @@ Usage: ${pc59.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
41005
41114
|
const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
|
|
41006
41115
|
if (!verifiedNumber?.VerifiedDestinationNumberId) {
|
|
41007
41116
|
progress.stop();
|
|
41008
|
-
|
|
41117
|
+
clack57.log.error(
|
|
41009
41118
|
`Number ${phoneNumber} not found. Run without --code first.`
|
|
41010
41119
|
);
|
|
41011
41120
|
process.exit(1);
|
|
@@ -41020,12 +41129,12 @@ Usage: ${pc59.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
41020
41129
|
});
|
|
41021
41130
|
progress.stop();
|
|
41022
41131
|
console.log("\n");
|
|
41023
|
-
|
|
41024
|
-
|
|
41132
|
+
clack57.log.success(
|
|
41133
|
+
pc60.green(`Phone number ${pc60.cyan(phoneNumber)} verified!`)
|
|
41025
41134
|
);
|
|
41026
41135
|
console.log("");
|
|
41027
41136
|
console.log(
|
|
41028
|
-
`You can now send test messages to this number with ${
|
|
41137
|
+
`You can now send test messages to this number with ${pc60.cyan("wraps sms test")}`
|
|
41029
41138
|
);
|
|
41030
41139
|
trackCommand("sms:verify-number:confirm", {
|
|
41031
41140
|
success: true,
|
|
@@ -41038,23 +41147,23 @@ Usage: ${pc59.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
41038
41147
|
});
|
|
41039
41148
|
return;
|
|
41040
41149
|
}
|
|
41041
|
-
|
|
41150
|
+
clack57.outro(pc60.green("Verification complete!"));
|
|
41042
41151
|
return;
|
|
41043
41152
|
} catch (error) {
|
|
41044
41153
|
progress.stop();
|
|
41045
41154
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
41046
41155
|
if (errorMessage.includes("Invalid verification code")) {
|
|
41047
|
-
|
|
41156
|
+
clack57.log.error("Invalid verification code. Please try again.");
|
|
41048
41157
|
console.log(
|
|
41049
41158
|
`
|
|
41050
|
-
Run ${
|
|
41159
|
+
Run ${pc60.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
|
|
41051
41160
|
`
|
|
41052
41161
|
);
|
|
41053
41162
|
} else {
|
|
41054
41163
|
trackError("SMS_VERIFY_CODE_FAILED", "sms:verify-number:confirm", {
|
|
41055
41164
|
error: errorMessage
|
|
41056
41165
|
});
|
|
41057
|
-
|
|
41166
|
+
clack57.log.error(`Verification failed: ${errorMessage}`);
|
|
41058
41167
|
}
|
|
41059
41168
|
process.exit(1);
|
|
41060
41169
|
}
|
|
@@ -41069,7 +41178,7 @@ Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41069
41178
|
const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
|
|
41070
41179
|
if (!verifiedNumber?.VerifiedDestinationNumberId) {
|
|
41071
41180
|
progress.stop();
|
|
41072
|
-
|
|
41181
|
+
clack57.log.error(
|
|
41073
41182
|
`Number ${phoneNumber} not found. Run without --resend first.`
|
|
41074
41183
|
);
|
|
41075
41184
|
process.exit(1);
|
|
@@ -41083,11 +41192,11 @@ Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41083
41192
|
);
|
|
41084
41193
|
});
|
|
41085
41194
|
progress.stop();
|
|
41086
|
-
|
|
41195
|
+
clack57.log.success(`Verification code resent to ${pc60.cyan(phoneNumber)}`);
|
|
41087
41196
|
console.log("");
|
|
41088
41197
|
console.log(
|
|
41089
41198
|
`Once you receive the code, run:
|
|
41090
|
-
${
|
|
41199
|
+
${pc60.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
|
|
41091
41200
|
);
|
|
41092
41201
|
trackCommand("sms:verify-number:resend", {
|
|
41093
41202
|
success: true,
|
|
@@ -41100,7 +41209,7 @@ Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41100
41209
|
});
|
|
41101
41210
|
return;
|
|
41102
41211
|
}
|
|
41103
|
-
|
|
41212
|
+
clack57.outro(pc60.green("Code sent!"));
|
|
41104
41213
|
return;
|
|
41105
41214
|
} catch (error) {
|
|
41106
41215
|
progress.stop();
|
|
@@ -41108,7 +41217,7 @@ Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41108
41217
|
trackError("SMS_RESEND_CODE_FAILED", "sms:verify-number:resend", {
|
|
41109
41218
|
error: errorMessage
|
|
41110
41219
|
});
|
|
41111
|
-
|
|
41220
|
+
clack57.log.error(`Failed to resend code: ${errorMessage}`);
|
|
41112
41221
|
process.exit(1);
|
|
41113
41222
|
}
|
|
41114
41223
|
}
|
|
@@ -41128,10 +41237,10 @@ Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41128
41237
|
});
|
|
41129
41238
|
return;
|
|
41130
41239
|
}
|
|
41131
|
-
|
|
41132
|
-
`Number ${
|
|
41240
|
+
clack57.log.info(
|
|
41241
|
+
`Number ${pc60.cyan(phoneNumber)} is already verified and ready to use!`
|
|
41133
41242
|
);
|
|
41134
|
-
|
|
41243
|
+
clack57.outro(pc60.green("Done!"));
|
|
41135
41244
|
return;
|
|
41136
41245
|
}
|
|
41137
41246
|
if (existingNumber?.Status === "PENDING") {
|
|
@@ -41155,15 +41264,15 @@ Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41155
41264
|
});
|
|
41156
41265
|
return;
|
|
41157
41266
|
}
|
|
41158
|
-
|
|
41159
|
-
`Verification already in progress. New code sent to ${
|
|
41267
|
+
clack57.log.info(
|
|
41268
|
+
`Verification already in progress. New code sent to ${pc60.cyan(phoneNumber)}`
|
|
41160
41269
|
);
|
|
41161
41270
|
console.log("");
|
|
41162
41271
|
console.log(
|
|
41163
41272
|
`Once you receive the code, run:
|
|
41164
|
-
${
|
|
41273
|
+
${pc60.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
|
|
41165
41274
|
);
|
|
41166
|
-
|
|
41275
|
+
clack57.outro(pc60.green("Code sent!"));
|
|
41167
41276
|
return;
|
|
41168
41277
|
}
|
|
41169
41278
|
const createResponse = await progress.execute(
|
|
@@ -41184,18 +41293,18 @@ Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41184
41293
|
});
|
|
41185
41294
|
progress.stop();
|
|
41186
41295
|
console.log("\n");
|
|
41187
|
-
|
|
41188
|
-
`Verification code sent to ${
|
|
41296
|
+
clack57.log.success(
|
|
41297
|
+
`Verification code sent to ${pc60.cyan(phoneNumber)} via SMS`
|
|
41189
41298
|
);
|
|
41190
41299
|
console.log("");
|
|
41191
|
-
|
|
41300
|
+
clack57.note(
|
|
41192
41301
|
[
|
|
41193
41302
|
"1. Check your phone for the verification code",
|
|
41194
41303
|
"",
|
|
41195
41304
|
"2. Complete verification with:",
|
|
41196
|
-
` ${
|
|
41305
|
+
` ${pc60.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`,
|
|
41197
41306
|
"",
|
|
41198
|
-
|
|
41307
|
+
pc60.dim("The code expires in 24 hours")
|
|
41199
41308
|
].join("\n"),
|
|
41200
41309
|
"Next Steps"
|
|
41201
41310
|
);
|
|
@@ -41211,22 +41320,22 @@ Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41211
41320
|
});
|
|
41212
41321
|
return;
|
|
41213
41322
|
}
|
|
41214
|
-
|
|
41323
|
+
clack57.outro(pc60.green("Verification started!"));
|
|
41215
41324
|
} catch (error) {
|
|
41216
41325
|
progress.stop();
|
|
41217
41326
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
41218
41327
|
if (errorMessage.includes("already exists")) {
|
|
41219
|
-
|
|
41328
|
+
clack57.log.error("This number is already being verified");
|
|
41220
41329
|
console.log(
|
|
41221
41330
|
`
|
|
41222
|
-
Run ${
|
|
41331
|
+
Run ${pc60.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
|
|
41223
41332
|
`
|
|
41224
41333
|
);
|
|
41225
41334
|
} else {
|
|
41226
41335
|
trackError("SMS_CREATE_VERIFIED_FAILED", "sms:verify-number:start", {
|
|
41227
41336
|
error: errorMessage
|
|
41228
41337
|
});
|
|
41229
|
-
|
|
41338
|
+
clack57.log.error(`Failed to start verification: ${errorMessage}`);
|
|
41230
41339
|
}
|
|
41231
41340
|
process.exit(1);
|
|
41232
41341
|
}
|
|
@@ -41235,98 +41344,98 @@ Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41235
41344
|
// src/commands/support.ts
|
|
41236
41345
|
init_esm_shims();
|
|
41237
41346
|
init_events();
|
|
41238
|
-
import * as
|
|
41239
|
-
import
|
|
41347
|
+
import * as clack58 from "@clack/prompts";
|
|
41348
|
+
import pc61 from "picocolors";
|
|
41240
41349
|
async function support() {
|
|
41241
41350
|
trackCommand("support", { success: true });
|
|
41242
|
-
|
|
41351
|
+
clack58.intro(pc61.bold("Get Help with Wraps"));
|
|
41243
41352
|
console.log();
|
|
41244
|
-
console.log(` ${
|
|
41353
|
+
console.log(` ${pc61.bold("Email:")} ${pc61.cyan("hey@wraps.sh")}`);
|
|
41245
41354
|
console.log(
|
|
41246
|
-
` ${
|
|
41355
|
+
` ${pc61.bold("GitHub:")} ${pc61.cyan("https://github.com/wraps-dev/wraps/issues")}`
|
|
41247
41356
|
);
|
|
41248
|
-
console.log(` ${
|
|
41357
|
+
console.log(` ${pc61.bold("Docs:")} ${pc61.cyan("https://wraps.dev/docs")}`);
|
|
41249
41358
|
console.log();
|
|
41250
|
-
console.log(
|
|
41359
|
+
console.log(pc61.dim(" Response time: Usually within 24 hours"));
|
|
41251
41360
|
console.log();
|
|
41252
41361
|
}
|
|
41253
41362
|
|
|
41254
41363
|
// src/commands/telemetry.ts
|
|
41255
41364
|
init_esm_shims();
|
|
41256
41365
|
init_client();
|
|
41257
|
-
import * as
|
|
41258
|
-
import
|
|
41366
|
+
import * as clack59 from "@clack/prompts";
|
|
41367
|
+
import pc62 from "picocolors";
|
|
41259
41368
|
async function telemetryEnable() {
|
|
41260
41369
|
const client = getTelemetryClient();
|
|
41261
41370
|
const override = client.enable();
|
|
41262
41371
|
if (override) {
|
|
41263
|
-
|
|
41372
|
+
clack59.log.warn(
|
|
41264
41373
|
"Telemetry enabled in config, but overridden by environment"
|
|
41265
41374
|
);
|
|
41266
|
-
console.log(` Reason: ${
|
|
41267
|
-
console.log(` Config: ${
|
|
41375
|
+
console.log(` Reason: ${pc62.yellow(override)}`);
|
|
41376
|
+
console.log(` Config: ${pc62.dim(client.getConfigPath())}`);
|
|
41268
41377
|
console.log();
|
|
41269
41378
|
} else {
|
|
41270
|
-
|
|
41271
|
-
console.log(` Config: ${
|
|
41379
|
+
clack59.log.success(pc62.green("Telemetry enabled"));
|
|
41380
|
+
console.log(` Config: ${pc62.dim(client.getConfigPath())}`);
|
|
41272
41381
|
console.log(`
|
|
41273
|
-
${
|
|
41382
|
+
${pc62.dim("Thank you for helping improve Wraps!")}
|
|
41274
41383
|
`);
|
|
41275
41384
|
}
|
|
41276
41385
|
}
|
|
41277
41386
|
async function telemetryDisable() {
|
|
41278
41387
|
const client = getTelemetryClient();
|
|
41279
41388
|
client.disable();
|
|
41280
|
-
|
|
41281
|
-
console.log(` Config: ${
|
|
41389
|
+
clack59.log.success(pc62.green("Telemetry disabled"));
|
|
41390
|
+
console.log(` Config: ${pc62.dim(client.getConfigPath())}`);
|
|
41282
41391
|
console.log(
|
|
41283
41392
|
`
|
|
41284
|
-
${
|
|
41393
|
+
${pc62.dim("You can re-enable with:")} wraps telemetry enable
|
|
41285
41394
|
`
|
|
41286
41395
|
);
|
|
41287
41396
|
}
|
|
41288
41397
|
async function telemetryStatus() {
|
|
41289
41398
|
const client = getTelemetryClient();
|
|
41290
|
-
|
|
41399
|
+
clack59.intro(pc62.bold("Telemetry Status"));
|
|
41291
41400
|
const override = client.getEnvOverride();
|
|
41292
|
-
const status2 = client.isEnabled() ?
|
|
41401
|
+
const status2 = client.isEnabled() ? pc62.green("Enabled") : pc62.red("Disabled");
|
|
41293
41402
|
console.log();
|
|
41294
|
-
console.log(` ${
|
|
41403
|
+
console.log(` ${pc62.bold("Status:")} ${status2}`);
|
|
41295
41404
|
if (!client.isEnabled() && override) {
|
|
41296
|
-
console.log(` ${
|
|
41405
|
+
console.log(` ${pc62.bold("Reason:")} ${pc62.yellow(override)}`);
|
|
41297
41406
|
}
|
|
41298
|
-
console.log(` ${
|
|
41407
|
+
console.log(` ${pc62.bold("Config file:")} ${pc62.dim(client.getConfigPath())}`);
|
|
41299
41408
|
if (client.isEnabled()) {
|
|
41300
41409
|
console.log();
|
|
41301
|
-
console.log(
|
|
41302
|
-
console.log(` ${
|
|
41410
|
+
console.log(pc62.bold(" How to opt-out:"));
|
|
41411
|
+
console.log(` ${pc62.cyan("wraps telemetry disable")}`);
|
|
41303
41412
|
console.log(
|
|
41304
|
-
` ${
|
|
41413
|
+
` ${pc62.dim("Or set:")} ${pc62.cyan("WRAPS_TELEMETRY_DISABLED=1")}`
|
|
41305
41414
|
);
|
|
41306
|
-
console.log(` ${
|
|
41415
|
+
console.log(` ${pc62.dim("Or set:")} ${pc62.cyan("DO_NOT_TRACK=1")}`);
|
|
41307
41416
|
} else {
|
|
41308
41417
|
console.log();
|
|
41309
|
-
console.log(
|
|
41310
|
-
console.log(` ${
|
|
41418
|
+
console.log(pc62.bold(" How to opt-in:"));
|
|
41419
|
+
console.log(` ${pc62.cyan("wraps telemetry enable")}`);
|
|
41311
41420
|
}
|
|
41312
41421
|
console.log();
|
|
41313
|
-
console.log(
|
|
41422
|
+
console.log(pc62.bold(" Debug mode:"));
|
|
41314
41423
|
console.log(
|
|
41315
|
-
` ${
|
|
41424
|
+
` ${pc62.dim("See what would be sent:")} ${pc62.cyan("WRAPS_TELEMETRY_DEBUG=1 wraps <command>")}`
|
|
41316
41425
|
);
|
|
41317
41426
|
console.log();
|
|
41318
41427
|
console.log(
|
|
41319
|
-
` ${
|
|
41428
|
+
` ${pc62.dim("Learn more:")} ${pc62.cyan("https://wraps.dev/docs/telemetry")}`
|
|
41320
41429
|
);
|
|
41321
41430
|
console.log();
|
|
41322
41431
|
}
|
|
41323
41432
|
|
|
41324
41433
|
// src/commands/workflow/init.ts
|
|
41325
41434
|
init_esm_shims();
|
|
41326
|
-
import { existsSync as existsSync18, mkdirSync as mkdirSync2, writeFileSync } from "fs";
|
|
41435
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
41327
41436
|
import { join as join22 } from "path";
|
|
41328
|
-
import * as
|
|
41329
|
-
import
|
|
41437
|
+
import * as clack60 from "@clack/prompts";
|
|
41438
|
+
import pc63 from "picocolors";
|
|
41330
41439
|
var EXAMPLE_CASCADE_WORKFLOW = `import {
|
|
41331
41440
|
defineWorkflow,
|
|
41332
41441
|
sendEmail,
|
|
@@ -41421,75 +41530,75 @@ export default defineConfig({
|
|
|
41421
41530
|
});
|
|
41422
41531
|
`;
|
|
41423
41532
|
async function workflowInit(options = {}) {
|
|
41424
|
-
|
|
41533
|
+
clack60.intro(pc63.bgCyan(pc63.black(" wraps workflow init ")));
|
|
41425
41534
|
const wrapsDir = join22(process.cwd(), "wraps");
|
|
41426
41535
|
const workflowsDir = join22(wrapsDir, "workflows");
|
|
41427
41536
|
const configPath = join22(wrapsDir, "wraps.config.ts");
|
|
41428
41537
|
if (existsSync18(workflowsDir)) {
|
|
41429
|
-
|
|
41430
|
-
`Workflows directory already exists at ${
|
|
41538
|
+
clack60.log.info(
|
|
41539
|
+
`Workflows directory already exists at ${pc63.cyan("wraps/workflows/")}`
|
|
41431
41540
|
);
|
|
41432
41541
|
const files = existsSync18(join22(workflowsDir, "cart-recovery.ts")) || existsSync18(join22(workflowsDir, "welcome-sequence.ts"));
|
|
41433
41542
|
if (files && !options.yes) {
|
|
41434
|
-
const shouldContinue = await
|
|
41543
|
+
const shouldContinue = await clack60.confirm({
|
|
41435
41544
|
message: "Example files may already exist. Overwrite them?",
|
|
41436
41545
|
initialValue: false
|
|
41437
41546
|
});
|
|
41438
|
-
if (
|
|
41439
|
-
|
|
41547
|
+
if (clack60.isCancel(shouldContinue) || !shouldContinue) {
|
|
41548
|
+
clack60.log.info("Skipping file creation.");
|
|
41440
41549
|
showNextSteps2();
|
|
41441
|
-
|
|
41550
|
+
clack60.outro("Done!");
|
|
41442
41551
|
return;
|
|
41443
41552
|
}
|
|
41444
41553
|
}
|
|
41445
41554
|
}
|
|
41446
41555
|
try {
|
|
41447
|
-
const s =
|
|
41556
|
+
const s = clack60.spinner();
|
|
41448
41557
|
s.start("Creating workflows directory...");
|
|
41449
41558
|
mkdirSync2(workflowsDir, { recursive: true });
|
|
41450
41559
|
s.stop("Created wraps/workflows/");
|
|
41451
41560
|
s.start("Scaffolding example workflows...");
|
|
41452
|
-
|
|
41561
|
+
writeFileSync3(
|
|
41453
41562
|
join22(workflowsDir, "cart-recovery.ts"),
|
|
41454
41563
|
EXAMPLE_CASCADE_WORKFLOW,
|
|
41455
41564
|
"utf-8"
|
|
41456
41565
|
);
|
|
41457
|
-
|
|
41566
|
+
writeFileSync3(
|
|
41458
41567
|
join22(workflowsDir, "welcome-sequence.ts"),
|
|
41459
41568
|
EXAMPLE_WELCOME_WORKFLOW,
|
|
41460
41569
|
"utf-8"
|
|
41461
41570
|
);
|
|
41462
41571
|
s.stop("Created 2 example workflows");
|
|
41463
41572
|
if (!existsSync18(configPath)) {
|
|
41464
|
-
|
|
41465
|
-
|
|
41573
|
+
writeFileSync3(configPath, EXAMPLE_CONFIG, "utf-8");
|
|
41574
|
+
clack60.log.info(`Created ${pc63.cyan("wraps/wraps.config.ts")}`);
|
|
41466
41575
|
}
|
|
41467
|
-
|
|
41468
|
-
`${
|
|
41469
|
-
${
|
|
41470
|
-
${
|
|
41471
|
-
${
|
|
41576
|
+
clack60.log.success(
|
|
41577
|
+
`${pc63.bold("Workflows scaffolded!")} Created:
|
|
41578
|
+
${pc63.cyan("wraps/wraps.config.ts")} \u2014 Project config
|
|
41579
|
+
${pc63.cyan("wraps/workflows/cart-recovery.ts")} \u2014 Cross-channel cascade example
|
|
41580
|
+
${pc63.cyan("wraps/workflows/welcome-sequence.ts")} \u2014 Welcome series example`
|
|
41472
41581
|
);
|
|
41473
41582
|
showNextSteps2();
|
|
41474
|
-
|
|
41583
|
+
clack60.outro(pc63.green("Happy orchestrating!"));
|
|
41475
41584
|
} catch (error) {
|
|
41476
|
-
|
|
41585
|
+
clack60.log.error(
|
|
41477
41586
|
`Failed to scaffold workflows: ${error instanceof Error ? error.message : String(error)}`
|
|
41478
41587
|
);
|
|
41479
|
-
|
|
41588
|
+
clack60.outro(pc63.red("Scaffolding failed."));
|
|
41480
41589
|
process.exitCode = 1;
|
|
41481
41590
|
}
|
|
41482
41591
|
}
|
|
41483
41592
|
function showNextSteps2() {
|
|
41484
|
-
|
|
41485
|
-
`${
|
|
41593
|
+
clack60.log.info(
|
|
41594
|
+
`${pc63.bold("Next steps:")}
|
|
41486
41595
|
|
|
41487
|
-
1. Edit ${
|
|
41488
|
-
2. Edit your workflows in ${
|
|
41489
|
-
3. Validate: ${
|
|
41490
|
-
4. Push: ${
|
|
41596
|
+
1. Edit ${pc63.cyan("wraps/wraps.config.ts")} with your org slug and domain
|
|
41597
|
+
2. Edit your workflows in ${pc63.cyan("wraps/workflows/")}
|
|
41598
|
+
3. Validate: ${pc63.cyan("wraps email workflows validate")}
|
|
41599
|
+
4. Push: ${pc63.cyan("wraps email workflows push")}
|
|
41491
41600
|
|
|
41492
|
-
${
|
|
41601
|
+
${pc63.dim("Docs:")} ${pc63.underline("https://wraps.dev/docs/guides/orchestration")}`
|
|
41493
41602
|
);
|
|
41494
41603
|
}
|
|
41495
41604
|
|
|
@@ -41524,6 +41633,7 @@ var STRING_FLAGS = [
|
|
|
41524
41633
|
"subdomain",
|
|
41525
41634
|
"tier",
|
|
41526
41635
|
"expires",
|
|
41636
|
+
"database-url",
|
|
41527
41637
|
"neon-api-key",
|
|
41528
41638
|
"neon-org-id",
|
|
41529
41639
|
"license-key",
|
|
@@ -41683,208 +41793,208 @@ function showVersion() {
|
|
|
41683
41793
|
process.exit(0);
|
|
41684
41794
|
}
|
|
41685
41795
|
function showHelp() {
|
|
41686
|
-
|
|
41796
|
+
clack61.intro(pc65.bold(`WRAPS CLI v${VERSION}`));
|
|
41687
41797
|
console.log("Deploy AWS infrastructure to your account\n");
|
|
41688
41798
|
console.log("Usage: wraps [service] <command> [options]\n");
|
|
41689
41799
|
console.log("Services:");
|
|
41690
|
-
console.log(` ${
|
|
41800
|
+
console.log(` ${pc65.cyan("email")} Email infrastructure (AWS SES)`);
|
|
41691
41801
|
console.log(
|
|
41692
|
-
` ${
|
|
41802
|
+
` ${pc65.cyan("sms")} SMS infrastructure (AWS End User Messaging)`
|
|
41693
41803
|
);
|
|
41694
41804
|
console.log(
|
|
41695
|
-
` ${
|
|
41805
|
+
` ${pc65.cyan("cdn")} CDN infrastructure (AWS S3 + CloudFront)`
|
|
41696
41806
|
);
|
|
41697
41807
|
console.log(
|
|
41698
|
-
` ${
|
|
41808
|
+
` ${pc65.cyan("selfhost")} Self-hosted Wraps control plane (enterprise)`
|
|
41699
41809
|
);
|
|
41700
41810
|
console.log(
|
|
41701
|
-
` ${
|
|
41811
|
+
` ${pc65.cyan("license")} License key management (Wraps team only)
|
|
41702
41812
|
`
|
|
41703
41813
|
);
|
|
41704
41814
|
console.log("Email Commands:");
|
|
41705
41815
|
console.log(
|
|
41706
|
-
` ${
|
|
41816
|
+
` ${pc65.cyan("email init")} Deploy new email infrastructure`
|
|
41707
41817
|
);
|
|
41708
41818
|
console.log(
|
|
41709
|
-
` ${
|
|
41819
|
+
` ${pc65.cyan("email check")} Check email deliverability for a domain`
|
|
41710
41820
|
);
|
|
41711
41821
|
console.log(
|
|
41712
|
-
` ${
|
|
41822
|
+
` ${pc65.cyan("email connect")} Connect to existing AWS SES`
|
|
41713
41823
|
);
|
|
41714
41824
|
console.log(
|
|
41715
|
-
` ${
|
|
41825
|
+
` ${pc65.cyan("email status")} Show email infrastructure details`
|
|
41716
41826
|
);
|
|
41717
|
-
console.log(` ${
|
|
41718
|
-
console.log(` ${
|
|
41827
|
+
console.log(` ${pc65.cyan("email test")} Send a test email`);
|
|
41828
|
+
console.log(` ${pc65.cyan("email verify")} Verify domain DNS records`);
|
|
41719
41829
|
console.log(
|
|
41720
|
-
` ${
|
|
41830
|
+
` ${pc65.cyan("email sync")} Apply CLI updates to infrastructure`
|
|
41721
41831
|
);
|
|
41722
|
-
console.log(` ${
|
|
41832
|
+
console.log(` ${pc65.cyan("email upgrade")} Add features`);
|
|
41723
41833
|
console.log(
|
|
41724
|
-
` ${
|
|
41834
|
+
` ${pc65.cyan("email restore")} Restore original configuration`
|
|
41725
41835
|
);
|
|
41726
41836
|
console.log(
|
|
41727
|
-
` ${
|
|
41837
|
+
` ${pc65.cyan("email destroy")} Remove email infrastructure`
|
|
41728
41838
|
);
|
|
41729
41839
|
console.log(
|
|
41730
|
-
` ${
|
|
41840
|
+
` ${pc65.cyan("email doctor")} Diagnose and clean up email infrastructure`
|
|
41731
41841
|
);
|
|
41732
|
-
console.log(` ${
|
|
41733
|
-
console.log(` ${
|
|
41734
|
-
console.log(` ${
|
|
41842
|
+
console.log(` ${pc65.cyan("email domains add")} Add a domain to SES`);
|
|
41843
|
+
console.log(` ${pc65.cyan("email domains list")} List all domains`);
|
|
41844
|
+
console.log(` ${pc65.cyan("email domains remove")} Remove a domain`);
|
|
41735
41845
|
console.log(
|
|
41736
|
-
` ${
|
|
41846
|
+
` ${pc65.cyan("email inbound init")} Enable inbound email receiving`
|
|
41737
41847
|
);
|
|
41738
|
-
console.log(` ${
|
|
41848
|
+
console.log(` ${pc65.cyan("email inbound status")} Show inbound email status`);
|
|
41739
41849
|
console.log(
|
|
41740
|
-
` ${
|
|
41850
|
+
` ${pc65.cyan("email inbound verify")} Verify inbound DNS records`
|
|
41741
41851
|
);
|
|
41742
41852
|
console.log(
|
|
41743
|
-
` ${
|
|
41853
|
+
` ${pc65.cyan("email inbound test")} Send test email and verify receipt`
|
|
41744
41854
|
);
|
|
41745
41855
|
console.log(
|
|
41746
|
-
` ${
|
|
41856
|
+
` ${pc65.cyan("email inbound destroy")} Remove inbound email infrastructure
|
|
41747
41857
|
`
|
|
41748
41858
|
);
|
|
41749
41859
|
console.log("Template Commands:");
|
|
41750
41860
|
console.log(
|
|
41751
|
-
` ${
|
|
41861
|
+
` ${pc65.cyan("email templates init")} Initialize templates-as-code`
|
|
41752
41862
|
);
|
|
41753
41863
|
console.log(
|
|
41754
|
-
` ${
|
|
41864
|
+
` ${pc65.cyan("email templates push")} Push templates to SES + dashboard`
|
|
41755
41865
|
);
|
|
41756
41866
|
console.log(
|
|
41757
|
-
` ${
|
|
41867
|
+
` ${pc65.cyan("email templates preview")} Preview templates in browser`
|
|
41758
41868
|
);
|
|
41759
41869
|
console.log(
|
|
41760
|
-
` ${
|
|
41870
|
+
` ${pc65.cyan("push")} ${pc65.dim("(alias for email templates push)")}
|
|
41761
41871
|
`
|
|
41762
41872
|
);
|
|
41763
41873
|
console.log("Workflow Commands:");
|
|
41764
41874
|
console.log(
|
|
41765
|
-
` ${
|
|
41875
|
+
` ${pc65.cyan("email workflows init")} Initialize workflows-as-code`
|
|
41766
41876
|
);
|
|
41767
41877
|
console.log(
|
|
41768
|
-
` ${
|
|
41878
|
+
` ${pc65.cyan("email workflows validate")} Validate workflow files`
|
|
41769
41879
|
);
|
|
41770
41880
|
console.log(
|
|
41771
|
-
` ${
|
|
41881
|
+
` ${pc65.cyan("email workflows push")} Push workflows to dashboard
|
|
41772
41882
|
`
|
|
41773
41883
|
);
|
|
41774
41884
|
console.log("SMS Commands:");
|
|
41775
|
-
console.log(` ${
|
|
41885
|
+
console.log(` ${pc65.cyan("sms init")} Deploy SMS infrastructure`);
|
|
41776
41886
|
console.log(
|
|
41777
|
-
` ${
|
|
41887
|
+
` ${pc65.cyan("sms status")} Show SMS infrastructure details`
|
|
41778
41888
|
);
|
|
41779
|
-
console.log(` ${
|
|
41889
|
+
console.log(` ${pc65.cyan("sms test")} Send a test SMS message`);
|
|
41780
41890
|
console.log(
|
|
41781
|
-
` ${
|
|
41891
|
+
` ${pc65.cyan("sms verify-number")} Verify a destination phone number`
|
|
41782
41892
|
);
|
|
41783
41893
|
console.log(
|
|
41784
|
-
` ${
|
|
41894
|
+
` ${pc65.cyan("sms sync")} Sync infrastructure (update Lambda, etc.)`
|
|
41785
41895
|
);
|
|
41786
|
-
console.log(` ${
|
|
41787
|
-
console.log(` ${
|
|
41896
|
+
console.log(` ${pc65.cyan("sms upgrade")} Upgrade SMS features`);
|
|
41897
|
+
console.log(` ${pc65.cyan("sms register")} Register toll-free number`);
|
|
41788
41898
|
console.log(
|
|
41789
|
-
` ${
|
|
41899
|
+
` ${pc65.cyan("sms destroy")} Remove SMS infrastructure
|
|
41790
41900
|
`
|
|
41791
41901
|
);
|
|
41792
41902
|
console.log("CDN Commands:");
|
|
41793
41903
|
console.log(
|
|
41794
|
-
` ${
|
|
41904
|
+
` ${pc65.cyan("cdn init")} Deploy CDN infrastructure (S3 + CloudFront)`
|
|
41795
41905
|
);
|
|
41796
41906
|
console.log(
|
|
41797
|
-
` ${
|
|
41907
|
+
` ${pc65.cyan("cdn status")} Show CDN infrastructure details`
|
|
41798
41908
|
);
|
|
41799
41909
|
console.log(
|
|
41800
|
-
` ${
|
|
41910
|
+
` ${pc65.cyan("cdn verify")} Check DNS and certificate status`
|
|
41801
41911
|
);
|
|
41802
41912
|
console.log(
|
|
41803
|
-
` ${
|
|
41913
|
+
` ${pc65.cyan("cdn upgrade")} Add custom domain after cert validation`
|
|
41804
41914
|
);
|
|
41805
41915
|
console.log(
|
|
41806
|
-
` ${
|
|
41916
|
+
` ${pc65.cyan("cdn sync")} Sync infrastructure with current config`
|
|
41807
41917
|
);
|
|
41808
41918
|
console.log(
|
|
41809
|
-
` ${
|
|
41919
|
+
` ${pc65.cyan("cdn destroy")} Remove CDN infrastructure
|
|
41810
41920
|
`
|
|
41811
41921
|
);
|
|
41812
41922
|
console.log("Self-Hosted Commands:");
|
|
41813
41923
|
console.log(
|
|
41814
|
-
` ${
|
|
41924
|
+
` ${pc65.cyan("selfhost deploy")} Deploy Wraps API to your AWS account`
|
|
41815
41925
|
);
|
|
41816
41926
|
console.log(
|
|
41817
|
-
` ${
|
|
41927
|
+
` ${pc65.cyan("selfhost upgrade")} Rebuild and redeploy the self-hosted API`
|
|
41818
41928
|
);
|
|
41819
41929
|
console.log(
|
|
41820
|
-
` ${
|
|
41930
|
+
` ${pc65.cyan("selfhost status")} Show self-hosted deployment details
|
|
41821
41931
|
`
|
|
41822
41932
|
);
|
|
41823
41933
|
console.log("Local Development:");
|
|
41824
41934
|
console.log(
|
|
41825
|
-
` ${
|
|
41935
|
+
` ${pc65.cyan("console")} Start local web console
|
|
41826
41936
|
`
|
|
41827
41937
|
);
|
|
41828
41938
|
console.log("Platform:");
|
|
41829
41939
|
console.log(
|
|
41830
|
-
` ${
|
|
41940
|
+
` ${pc65.cyan("platform")} Show platform info and pricing`
|
|
41831
41941
|
);
|
|
41832
41942
|
console.log(
|
|
41833
|
-
` ${
|
|
41943
|
+
` ${pc65.cyan("platform connect")} Connect to Wraps Platform (events + IAM)`
|
|
41834
41944
|
);
|
|
41835
41945
|
console.log(
|
|
41836
|
-
` ${
|
|
41946
|
+
` ${pc65.cyan("platform update-role")} Update platform IAM permissions
|
|
41837
41947
|
`
|
|
41838
41948
|
);
|
|
41839
41949
|
console.log("Auth:");
|
|
41840
41950
|
console.log(
|
|
41841
|
-
` ${
|
|
41951
|
+
` ${pc65.cyan("auth login")} Sign in to wraps.dev (device flow)`
|
|
41842
41952
|
);
|
|
41843
|
-
console.log(` ${
|
|
41953
|
+
console.log(` ${pc65.cyan("auth status")} Show current auth state`);
|
|
41844
41954
|
console.log(
|
|
41845
|
-
` ${
|
|
41955
|
+
` ${pc65.cyan("auth logout")} Sign out and remove stored token
|
|
41846
41956
|
`
|
|
41847
41957
|
);
|
|
41848
41958
|
console.log("AWS Setup:");
|
|
41849
41959
|
console.log(
|
|
41850
|
-
` ${
|
|
41960
|
+
` ${pc65.cyan("aws setup")} Interactive AWS setup wizard`
|
|
41851
41961
|
);
|
|
41852
41962
|
console.log(
|
|
41853
|
-
` ${
|
|
41963
|
+
` ${pc65.cyan("aws doctor")} Diagnose AWS configuration issues
|
|
41854
41964
|
`
|
|
41855
41965
|
);
|
|
41856
41966
|
console.log("Global Commands:");
|
|
41857
|
-
console.log(` ${
|
|
41858
|
-
console.log(` ${
|
|
41859
|
-
console.log(` ${
|
|
41860
|
-
console.log(` ${
|
|
41967
|
+
console.log(` ${pc65.cyan("status")} Show overview of all services`);
|
|
41968
|
+
console.log(` ${pc65.cyan("destroy")} Remove deployed infrastructure`);
|
|
41969
|
+
console.log(` ${pc65.cyan("permissions")} Show required AWS IAM permissions`);
|
|
41970
|
+
console.log(` ${pc65.cyan("completion")} Generate shell completion script`);
|
|
41861
41971
|
console.log(
|
|
41862
|
-
` ${
|
|
41972
|
+
` ${pc65.cyan("telemetry")} Manage anonymous telemetry settings`
|
|
41863
41973
|
);
|
|
41864
|
-
console.log(` ${
|
|
41865
|
-
console.log(` ${
|
|
41974
|
+
console.log(` ${pc65.cyan("update")} Update CLI to latest version`);
|
|
41975
|
+
console.log(` ${pc65.cyan("news")} Show recent Wraps updates`);
|
|
41866
41976
|
console.log(
|
|
41867
|
-
` ${
|
|
41977
|
+
` ${pc65.cyan("support")} Get help and support contact info
|
|
41868
41978
|
`
|
|
41869
41979
|
);
|
|
41870
41980
|
console.log("Options:");
|
|
41871
41981
|
console.log(
|
|
41872
|
-
` ${
|
|
41873
|
-
);
|
|
41874
|
-
console.log(` ${
|
|
41875
|
-
console.log(` ${
|
|
41876
|
-
console.log(` ${
|
|
41877
|
-
console.log(` ${
|
|
41878
|
-
console.log(` ${
|
|
41879
|
-
console.log(` ${
|
|
41880
|
-
console.log(` ${
|
|
41982
|
+
` ${pc65.dim("-p, --provider")} Hosting provider (vercel, aws, railway, other)`
|
|
41983
|
+
);
|
|
41984
|
+
console.log(` ${pc65.dim("-r, --region")} AWS region`);
|
|
41985
|
+
console.log(` ${pc65.dim("-d, --domain")} Domain name`);
|
|
41986
|
+
console.log(` ${pc65.dim("--account")} AWS account ID or alias`);
|
|
41987
|
+
console.log(` ${pc65.dim("--preset")} Configuration preset`);
|
|
41988
|
+
console.log(` ${pc65.dim("--token")} API key or token for auth`);
|
|
41989
|
+
console.log(` ${pc65.dim("-y, --yes")} Skip confirmation prompts`);
|
|
41990
|
+
console.log(` ${pc65.dim("-f, --force")} Force destructive operations`);
|
|
41881
41991
|
console.log(
|
|
41882
|
-
` ${
|
|
41992
|
+
` ${pc65.dim("--preview")} Preview changes without deploying`
|
|
41883
41993
|
);
|
|
41884
|
-
console.log(` ${
|
|
41994
|
+
console.log(` ${pc65.dim("-v, --version")} Show version number
|
|
41885
41995
|
`);
|
|
41886
41996
|
console.log(
|
|
41887
|
-
`Run ${
|
|
41997
|
+
`Run ${pc65.cyan("wraps <service> <command> --help")} for more information.
|
|
41888
41998
|
`
|
|
41889
41999
|
);
|
|
41890
42000
|
}
|
|
@@ -41906,27 +42016,27 @@ if (!primaryCommand) {
|
|
|
41906
42016
|
const telemetry = getTelemetryClient();
|
|
41907
42017
|
if (telemetry.shouldShowNotification()) {
|
|
41908
42018
|
console.log();
|
|
41909
|
-
|
|
42019
|
+
clack61.log.info(pc65.bold("Anonymous Telemetry"));
|
|
41910
42020
|
console.log(
|
|
41911
|
-
` Wraps collects ${
|
|
42021
|
+
` Wraps collects ${pc65.cyan("anonymous usage data")} to improve the CLI.`
|
|
41912
42022
|
);
|
|
41913
42023
|
console.log(
|
|
41914
|
-
` We ${
|
|
42024
|
+
` We ${pc65.bold("never")} collect: domains, AWS credentials, email content, or PII.`
|
|
41915
42025
|
);
|
|
41916
42026
|
console.log(
|
|
41917
|
-
` We ${
|
|
42027
|
+
` We ${pc65.bold("only")} collect: command names, success/failure, CLI version, OS.`
|
|
41918
42028
|
);
|
|
41919
42029
|
console.log();
|
|
41920
|
-
console.log(` Opt-out anytime: ${
|
|
41921
|
-
console.log(` Or set: ${
|
|
41922
|
-
console.log(` Learn more: ${
|
|
42030
|
+
console.log(` Opt-out anytime: ${pc65.cyan("wraps telemetry disable")}`);
|
|
42031
|
+
console.log(` Or set: ${pc65.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
|
|
42032
|
+
console.log(` Learn more: ${pc65.cyan("https://wraps.dev/docs")}`);
|
|
41923
42033
|
console.log();
|
|
41924
42034
|
telemetry.markNotificationShown();
|
|
41925
42035
|
}
|
|
41926
42036
|
trackCommand("interactive:menu", { success: true, duration_ms: 0 });
|
|
41927
|
-
|
|
42037
|
+
clack61.intro(pc65.bold(`WRAPS CLI v${VERSION}`));
|
|
41928
42038
|
console.log(" Deploy AWS infrastructure to your account.\n");
|
|
41929
|
-
const action = await
|
|
42039
|
+
const action = await clack61.select({
|
|
41930
42040
|
message: "What would you like to do?",
|
|
41931
42041
|
options: [
|
|
41932
42042
|
{
|
|
@@ -41976,13 +42086,13 @@ if (!primaryCommand) {
|
|
|
41976
42086
|
}
|
|
41977
42087
|
]
|
|
41978
42088
|
});
|
|
41979
|
-
if (
|
|
42089
|
+
if (clack61.isCancel(action)) {
|
|
41980
42090
|
trackCommand("interactive:cancel", {
|
|
41981
42091
|
success: true,
|
|
41982
42092
|
duration_ms: Date.now() - startTime
|
|
41983
42093
|
});
|
|
41984
42094
|
await telemetry.shutdown();
|
|
41985
|
-
|
|
42095
|
+
clack61.cancel("Operation cancelled.");
|
|
41986
42096
|
process.exit(0);
|
|
41987
42097
|
}
|
|
41988
42098
|
trackCommand(`interactive:${action}`, {
|
|
@@ -42062,20 +42172,20 @@ async function run() {
|
|
|
42062
42172
|
const telemetry = getTelemetryClient();
|
|
42063
42173
|
if (telemetry.shouldShowNotification()) {
|
|
42064
42174
|
console.log();
|
|
42065
|
-
|
|
42175
|
+
clack61.log.info(pc65.bold("Anonymous Telemetry"));
|
|
42066
42176
|
console.log(
|
|
42067
|
-
` Wraps collects ${
|
|
42177
|
+
` Wraps collects ${pc65.cyan("anonymous usage data")} to improve the CLI.`
|
|
42068
42178
|
);
|
|
42069
42179
|
console.log(
|
|
42070
|
-
` We ${
|
|
42180
|
+
` We ${pc65.bold("never")} collect: domains, AWS credentials, email content, or PII.`
|
|
42071
42181
|
);
|
|
42072
42182
|
console.log(
|
|
42073
|
-
` We ${
|
|
42183
|
+
` We ${pc65.bold("only")} collect: command names, success/failure, CLI version, OS.`
|
|
42074
42184
|
);
|
|
42075
42185
|
console.log();
|
|
42076
|
-
console.log(` Opt-out anytime: ${
|
|
42077
|
-
console.log(` Or set: ${
|
|
42078
|
-
console.log(` Learn more: ${
|
|
42186
|
+
console.log(` Opt-out anytime: ${pc65.cyan("wraps telemetry disable")}`);
|
|
42187
|
+
console.log(` Or set: ${pc65.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
|
|
42188
|
+
console.log(` Learn more: ${pc65.cyan("https://wraps.dev/docs")}`);
|
|
42079
42189
|
console.log();
|
|
42080
42190
|
telemetry.markNotificationShown();
|
|
42081
42191
|
}
|
|
@@ -42159,10 +42269,10 @@ async function run() {
|
|
|
42159
42269
|
break;
|
|
42160
42270
|
case "verify": {
|
|
42161
42271
|
if (!flags.domain) {
|
|
42162
|
-
|
|
42272
|
+
clack61.log.error("--domain flag is required");
|
|
42163
42273
|
console.log(
|
|
42164
42274
|
`
|
|
42165
|
-
Usage: ${
|
|
42275
|
+
Usage: ${pc65.cyan("wraps email verify --domain yourapp.com")}
|
|
42166
42276
|
`
|
|
42167
42277
|
);
|
|
42168
42278
|
throw new Error("Missing required flag: --domain");
|
|
@@ -42234,12 +42344,12 @@ Usage: ${pc64.cyan("wraps email verify --domain yourapp.com")}
|
|
|
42234
42344
|
});
|
|
42235
42345
|
break;
|
|
42236
42346
|
default:
|
|
42237
|
-
|
|
42347
|
+
clack61.log.error(
|
|
42238
42348
|
`Unknown inbound command: ${inboundSubCommand || "(none)"}`
|
|
42239
42349
|
);
|
|
42240
42350
|
console.log(
|
|
42241
42351
|
`
|
|
42242
|
-
Available commands: ${
|
|
42352
|
+
Available commands: ${pc65.cyan("init")}, ${pc65.cyan("destroy")}, ${pc65.cyan("status")}, ${pc65.cyan("verify")}, ${pc65.cyan("test")}, ${pc65.cyan("add")}, ${pc65.cyan("remove")}
|
|
42243
42353
|
`
|
|
42244
42354
|
);
|
|
42245
42355
|
throw new Error(
|
|
@@ -42291,12 +42401,12 @@ Available commands: ${pc64.cyan("init")}, ${pc64.cyan("destroy")}, ${pc64.cyan("
|
|
|
42291
42401
|
break;
|
|
42292
42402
|
}
|
|
42293
42403
|
default:
|
|
42294
|
-
|
|
42404
|
+
clack61.log.error(
|
|
42295
42405
|
`Unknown reply command: ${replySubCommand || "(none)"}`
|
|
42296
42406
|
);
|
|
42297
42407
|
console.log(
|
|
42298
42408
|
`
|
|
42299
|
-
Available commands: ${
|
|
42409
|
+
Available commands: ${pc65.cyan("init")}, ${pc65.cyan("rotate")}, ${pc65.cyan("status")}, ${pc65.cyan("destroy")}, ${pc65.cyan("decode")}
|
|
42300
42410
|
`
|
|
42301
42411
|
);
|
|
42302
42412
|
throw new Error(
|
|
@@ -42321,10 +42431,10 @@ Available commands: ${pc64.cyan("init")}, ${pc64.cyan("rotate")}, ${pc64.cyan("s
|
|
|
42321
42431
|
break;
|
|
42322
42432
|
case "verify": {
|
|
42323
42433
|
if (!flags.domain) {
|
|
42324
|
-
|
|
42434
|
+
clack61.log.error("--domain flag is required");
|
|
42325
42435
|
console.log(
|
|
42326
42436
|
`
|
|
42327
|
-
Usage: ${
|
|
42437
|
+
Usage: ${pc65.cyan("wraps email domains verify --domain yourapp.com")}
|
|
42328
42438
|
`
|
|
42329
42439
|
);
|
|
42330
42440
|
throw new Error("Missing required flag: --domain");
|
|
@@ -42334,10 +42444,10 @@ Usage: ${pc64.cyan("wraps email domains verify --domain yourapp.com")}
|
|
|
42334
42444
|
}
|
|
42335
42445
|
case "get-dkim": {
|
|
42336
42446
|
if (!flags.domain) {
|
|
42337
|
-
|
|
42447
|
+
clack61.log.error("--domain flag is required");
|
|
42338
42448
|
console.log(
|
|
42339
42449
|
`
|
|
42340
|
-
Usage: ${
|
|
42450
|
+
Usage: ${pc65.cyan("wraps email domains get-dkim --domain yourapp.com")}
|
|
42341
42451
|
`
|
|
42342
42452
|
);
|
|
42343
42453
|
throw new Error("Missing required flag: --domain");
|
|
@@ -42347,10 +42457,10 @@ Usage: ${pc64.cyan("wraps email domains get-dkim --domain yourapp.com")}
|
|
|
42347
42457
|
}
|
|
42348
42458
|
case "remove": {
|
|
42349
42459
|
if (!flags.domain) {
|
|
42350
|
-
|
|
42460
|
+
clack61.log.error("--domain flag is required");
|
|
42351
42461
|
console.log(
|
|
42352
42462
|
`
|
|
42353
|
-
Usage: ${
|
|
42463
|
+
Usage: ${pc65.cyan("wraps email domains remove --domain yourapp.com --force")}
|
|
42354
42464
|
`
|
|
42355
42465
|
);
|
|
42356
42466
|
throw new Error("Missing required flag: --domain");
|
|
@@ -42380,12 +42490,12 @@ Usage: ${pc64.cyan("wraps email domains remove --domain yourapp.com --force")}
|
|
|
42380
42490
|
break;
|
|
42381
42491
|
}
|
|
42382
42492
|
default:
|
|
42383
|
-
|
|
42493
|
+
clack61.log.error(
|
|
42384
42494
|
`Unknown domains command: ${domainsSubCommand || "(none)"}`
|
|
42385
42495
|
);
|
|
42386
42496
|
console.log(
|
|
42387
42497
|
`
|
|
42388
|
-
Available commands: ${
|
|
42498
|
+
Available commands: ${pc65.cyan("add")}, ${pc65.cyan("list")}, ${pc65.cyan("verify")}, ${pc65.cyan("get-dkim")}, ${pc65.cyan("remove")}, ${pc65.cyan("config")}
|
|
42389
42499
|
`
|
|
42390
42500
|
);
|
|
42391
42501
|
throw new Error(
|
|
@@ -42427,12 +42537,12 @@ Available commands: ${pc64.cyan("add")}, ${pc64.cyan("list")}, ${pc64.cyan("veri
|
|
|
42427
42537
|
});
|
|
42428
42538
|
break;
|
|
42429
42539
|
default:
|
|
42430
|
-
|
|
42540
|
+
clack61.log.error(
|
|
42431
42541
|
`Unknown templates command: ${templatesSubCommand || "(none)"}`
|
|
42432
42542
|
);
|
|
42433
42543
|
console.log(
|
|
42434
42544
|
`
|
|
42435
|
-
Available commands: ${
|
|
42545
|
+
Available commands: ${pc65.cyan("init")}, ${pc65.cyan("push")}, ${pc65.cyan("preview")}
|
|
42436
42546
|
`
|
|
42437
42547
|
);
|
|
42438
42548
|
throw new Error(
|
|
@@ -42471,12 +42581,12 @@ Available commands: ${pc64.cyan("init")}, ${pc64.cyan("push")}, ${pc64.cyan("pre
|
|
|
42471
42581
|
});
|
|
42472
42582
|
break;
|
|
42473
42583
|
default:
|
|
42474
|
-
|
|
42584
|
+
clack61.log.error(
|
|
42475
42585
|
`Unknown workflows command: ${workflowsSubCommand || "(none)"}`
|
|
42476
42586
|
);
|
|
42477
42587
|
console.log(
|
|
42478
42588
|
`
|
|
42479
|
-
Available commands: ${
|
|
42589
|
+
Available commands: ${pc65.cyan("init")}, ${pc65.cyan("validate")}, ${pc65.cyan("push")}
|
|
42480
42590
|
`
|
|
42481
42591
|
);
|
|
42482
42592
|
throw new Error(
|
|
@@ -42501,10 +42611,10 @@ Available commands: ${pc64.cyan("init")}, ${pc64.cyan("validate")}, ${pc64.cyan(
|
|
|
42501
42611
|
});
|
|
42502
42612
|
break;
|
|
42503
42613
|
default:
|
|
42504
|
-
|
|
42614
|
+
clack61.log.error(`Unknown email command: ${subCommand}`);
|
|
42505
42615
|
console.log(
|
|
42506
42616
|
`
|
|
42507
|
-
Run ${
|
|
42617
|
+
Run ${pc65.cyan("wraps --help")} for available commands.
|
|
42508
42618
|
`
|
|
42509
42619
|
);
|
|
42510
42620
|
throw new Error(`Unknown email command: ${subCommand}`);
|
|
@@ -42529,10 +42639,10 @@ Run ${pc64.cyan("wraps --help")} for available commands.
|
|
|
42529
42639
|
});
|
|
42530
42640
|
break;
|
|
42531
42641
|
default:
|
|
42532
|
-
|
|
42642
|
+
clack61.log.error(`Unknown license command: ${subCommand}`);
|
|
42533
42643
|
console.log(
|
|
42534
42644
|
`
|
|
42535
|
-
Run ${
|
|
42645
|
+
Run ${pc65.cyan("wraps --help")} for available commands.
|
|
42536
42646
|
`
|
|
42537
42647
|
);
|
|
42538
42648
|
throw new Error(`Unknown license command: ${subCommand}`);
|
|
@@ -42549,6 +42659,7 @@ Run ${pc64.cyan("wraps --help")} for available commands.
|
|
|
42549
42659
|
case "deploy":
|
|
42550
42660
|
await selfhostDeploy({
|
|
42551
42661
|
region: flags.region,
|
|
42662
|
+
databaseUrl: flags.databaseUrl,
|
|
42552
42663
|
neonApiKey: flags.neonApiKey,
|
|
42553
42664
|
neonOrgId: flags.neonOrgId,
|
|
42554
42665
|
licenseKey: flags.licenseKey,
|
|
@@ -42572,11 +42683,17 @@ Run ${pc64.cyan("wraps --help")} for available commands.
|
|
|
42572
42683
|
json: flags.json
|
|
42573
42684
|
});
|
|
42574
42685
|
break;
|
|
42686
|
+
case "env":
|
|
42687
|
+
await selfhostEnv({
|
|
42688
|
+
region: flags.region,
|
|
42689
|
+
json: flags.json
|
|
42690
|
+
});
|
|
42691
|
+
break;
|
|
42575
42692
|
default:
|
|
42576
|
-
|
|
42693
|
+
clack61.log.error(`Unknown selfhost command: ${subCommand}`);
|
|
42577
42694
|
console.log(
|
|
42578
42695
|
`
|
|
42579
|
-
Run ${
|
|
42696
|
+
Run ${pc65.cyan("wraps --help")} for available commands.
|
|
42580
42697
|
`
|
|
42581
42698
|
);
|
|
42582
42699
|
throw new Error(`Unknown selfhost command: ${subCommand}`);
|
|
@@ -42656,10 +42773,10 @@ Run ${pc64.cyan("wraps --help")} for available commands.
|
|
|
42656
42773
|
});
|
|
42657
42774
|
break;
|
|
42658
42775
|
default:
|
|
42659
|
-
|
|
42776
|
+
clack61.log.error(`Unknown sms command: ${subCommand}`);
|
|
42660
42777
|
console.log(
|
|
42661
42778
|
`
|
|
42662
|
-
Run ${
|
|
42779
|
+
Run ${pc65.cyan("wraps --help")} for available commands.
|
|
42663
42780
|
`
|
|
42664
42781
|
);
|
|
42665
42782
|
throw new Error(`Unknown sms command: ${subCommand}`);
|
|
@@ -42720,10 +42837,10 @@ Run ${pc64.cyan("wraps --help")} for available commands.
|
|
|
42720
42837
|
});
|
|
42721
42838
|
break;
|
|
42722
42839
|
default:
|
|
42723
|
-
|
|
42840
|
+
clack61.log.error(`Unknown cdn command: ${subCommand}`);
|
|
42724
42841
|
console.log(
|
|
42725
42842
|
`
|
|
42726
|
-
Run ${
|
|
42843
|
+
Run ${pc65.cyan("wraps --help")} for available commands.
|
|
42727
42844
|
`
|
|
42728
42845
|
);
|
|
42729
42846
|
throw new Error(`Unknown cdn command: ${subCommand}`);
|
|
@@ -42745,13 +42862,13 @@ Run ${pc64.cyan("wraps --help")} for available commands.
|
|
|
42745
42862
|
});
|
|
42746
42863
|
break;
|
|
42747
42864
|
default:
|
|
42748
|
-
|
|
42865
|
+
clack61.log.error(
|
|
42749
42866
|
`Unknown workflow command: ${subCommand || "(none)"}`
|
|
42750
42867
|
);
|
|
42751
42868
|
console.log(`
|
|
42752
|
-
Available commands: ${
|
|
42869
|
+
Available commands: ${pc65.cyan("init")}
|
|
42753
42870
|
`);
|
|
42754
|
-
console.log(`Run ${
|
|
42871
|
+
console.log(`Run ${pc65.cyan("wraps --help")} for more information.
|
|
42755
42872
|
`);
|
|
42756
42873
|
throw new Error(
|
|
42757
42874
|
`Unknown workflow command: ${subCommand || "(none)"}`
|
|
@@ -42793,14 +42910,14 @@ Available commands: ${pc64.cyan("init")}
|
|
|
42793
42910
|
});
|
|
42794
42911
|
break;
|
|
42795
42912
|
default:
|
|
42796
|
-
|
|
42913
|
+
clack61.log.error(`Unknown platform command: ${subCommand}`);
|
|
42797
42914
|
console.log(
|
|
42798
42915
|
`
|
|
42799
|
-
Available commands: ${
|
|
42916
|
+
Available commands: ${pc65.cyan("connect")}, ${pc65.cyan("update-role")}
|
|
42800
42917
|
`
|
|
42801
42918
|
);
|
|
42802
42919
|
console.log(
|
|
42803
|
-
`Run ${
|
|
42920
|
+
`Run ${pc65.cyan("wraps platform")} for more information.
|
|
42804
42921
|
`
|
|
42805
42922
|
);
|
|
42806
42923
|
throw new Error(`Unknown platform command: ${subCommand}`);
|
|
@@ -42825,10 +42942,10 @@ Available commands: ${pc64.cyan("connect")}, ${pc64.cyan("update-role")}
|
|
|
42825
42942
|
await logout();
|
|
42826
42943
|
break;
|
|
42827
42944
|
default:
|
|
42828
|
-
|
|
42945
|
+
clack61.log.error(`Unknown auth command: ${subCommand || "(none)"}`);
|
|
42829
42946
|
console.log(
|
|
42830
42947
|
`
|
|
42831
|
-
Available commands: ${
|
|
42948
|
+
Available commands: ${pc65.cyan("login")}, ${pc65.cyan("status")}, ${pc65.cyan("logout")}
|
|
42832
42949
|
`
|
|
42833
42950
|
);
|
|
42834
42951
|
throw new Error(`Unknown auth command: ${subCommand || "(none)"}`);
|
|
@@ -42846,13 +42963,13 @@ Available commands: ${pc64.cyan("login")}, ${pc64.cyan("status")}, ${pc64.cyan("
|
|
|
42846
42963
|
await doctor();
|
|
42847
42964
|
break;
|
|
42848
42965
|
default:
|
|
42849
|
-
|
|
42966
|
+
clack61.log.error(`Unknown aws command: ${subCommand}`);
|
|
42850
42967
|
console.log(
|
|
42851
42968
|
`
|
|
42852
|
-
Available commands: ${
|
|
42969
|
+
Available commands: ${pc65.cyan("setup")}, ${pc65.cyan("doctor")}
|
|
42853
42970
|
`
|
|
42854
42971
|
);
|
|
42855
|
-
console.log(`Run ${
|
|
42972
|
+
console.log(`Run ${pc65.cyan("wraps --help")} for more information.
|
|
42856
42973
|
`);
|
|
42857
42974
|
throw new Error(`Unknown aws command: ${subCommand}`);
|
|
42858
42975
|
}
|
|
@@ -42933,10 +43050,10 @@ Available commands: ${pc64.cyan("setup")}, ${pc64.cyan("doctor")}
|
|
|
42933
43050
|
await telemetryStatus();
|
|
42934
43051
|
break;
|
|
42935
43052
|
default:
|
|
42936
|
-
|
|
43053
|
+
clack61.log.error(`Unknown telemetry command: ${subCommand}`);
|
|
42937
43054
|
console.log(
|
|
42938
43055
|
`
|
|
42939
|
-
Available commands: ${
|
|
43056
|
+
Available commands: ${pc65.cyan("enable")}, ${pc65.cyan("disable")}, ${pc65.cyan("status")}
|
|
42940
43057
|
`
|
|
42941
43058
|
);
|
|
42942
43059
|
throw new Error(`Unknown telemetry command: ${subCommand}`);
|
|
@@ -42960,10 +43077,10 @@ Please specify a command for ${primaryCommand} service.
|
|
|
42960
43077
|
showHelp();
|
|
42961
43078
|
break;
|
|
42962
43079
|
default:
|
|
42963
|
-
|
|
43080
|
+
clack61.log.error(`Unknown command: ${primaryCommand}`);
|
|
42964
43081
|
console.log(
|
|
42965
43082
|
`
|
|
42966
|
-
Run ${
|
|
43083
|
+
Run ${pc65.cyan("wraps --help")} for available commands.
|
|
42967
43084
|
`
|
|
42968
43085
|
);
|
|
42969
43086
|
throw new Error(`Unknown command: ${primaryCommand}`);
|