@wraps.dev/cli 2.21.1 → 2.21.4
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 +1051 -877
- package/dist/cli.js.map +1 -1
- package/dist/console/assets/{index-XbwVYQLu.js → index-e_Wzcxes.js} +2 -2
- package/dist/console/index.html +1 -1
- package/dist/lambda/event-processor/.bundled +1 -1
- package/dist/lambda/inbound-processor/.bundled +1 -1
- package/dist/lambda/inbound-processor/index.js +62 -58
- package/dist/lambda/sms-event-processor/.bundled +1 -1
- package/package.json +5 -5
package/dist/cli.js
CHANGED
|
@@ -9,12 +9,12 @@ var __export = (target, all6) => {
|
|
|
9
9
|
__defProp(target, name, { get: all6[name], enumerable: true });
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.
|
|
12
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.14_tsx@4.20.6_typescript@5.9.3_yaml@2.8.4/node_modules/tsup/assets/esm_shims.js
|
|
13
13
|
import path from "path";
|
|
14
14
|
import { fileURLToPath } from "url";
|
|
15
15
|
var getFilename, getDirname, __dirname;
|
|
16
16
|
var init_esm_shims = __esm({
|
|
17
|
-
"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.
|
|
17
|
+
"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.14_tsx@4.20.6_typescript@5.9.3_yaml@2.8.4/node_modules/tsup/assets/esm_shims.js"() {
|
|
18
18
|
"use strict";
|
|
19
19
|
getFilename = () => fileURLToPath(import.meta.url);
|
|
20
20
|
getDirname = () => path.dirname(getFilename());
|
|
@@ -1748,8 +1748,8 @@ async function ensurePulumiWorkDir(options) {
|
|
|
1748
1748
|
);
|
|
1749
1749
|
return;
|
|
1750
1750
|
} catch (error) {
|
|
1751
|
-
const
|
|
1752
|
-
|
|
1751
|
+
const clack61 = await import("@clack/prompts");
|
|
1752
|
+
clack61.log.warn(
|
|
1753
1753
|
`S3 state backend unavailable (${error instanceof Error ? error.message : error}). Using local state.`
|
|
1754
1754
|
);
|
|
1755
1755
|
}
|
|
@@ -6854,23 +6854,23 @@ async function withLockRetry(fn, options) {
|
|
|
6854
6854
|
if (parsed.code !== "STACK_LOCKED") {
|
|
6855
6855
|
throw error;
|
|
6856
6856
|
}
|
|
6857
|
-
const
|
|
6858
|
-
const
|
|
6857
|
+
const clack61 = await import("@clack/prompts");
|
|
6858
|
+
const pc65 = (await import("picocolors")).default;
|
|
6859
6859
|
if (options.autoConfirm) {
|
|
6860
|
-
|
|
6860
|
+
clack61.log.warn(
|
|
6861
6861
|
"Stack is locked from a previous interrupted run. Auto-clearing..."
|
|
6862
6862
|
);
|
|
6863
6863
|
} else {
|
|
6864
|
-
const shouldClear = await
|
|
6865
|
-
message: `Stack is locked from a previous interrupted run. ${
|
|
6864
|
+
const shouldClear = await clack61.confirm({
|
|
6865
|
+
message: `Stack is locked from a previous interrupted run. ${pc65.yellow("Clear the stale lock and retry?")}`,
|
|
6866
6866
|
initialValue: true
|
|
6867
6867
|
});
|
|
6868
|
-
if (
|
|
6868
|
+
if (clack61.isCancel(shouldClear) || !shouldClear) {
|
|
6869
6869
|
throw errors.stackLocked();
|
|
6870
6870
|
}
|
|
6871
6871
|
}
|
|
6872
6872
|
const cleared = await clearStackLocks(options.accountId, options.region);
|
|
6873
|
-
|
|
6873
|
+
clack61.log.info(
|
|
6874
6874
|
`Cleared ${cleared} lock file${cleared === 1 ? "" : "s"}. Retrying...`
|
|
6875
6875
|
);
|
|
6876
6876
|
return fn();
|
|
@@ -6980,6 +6980,7 @@ __export(dist_exports, {
|
|
|
6980
6980
|
DEFAULT_MAIL_FROM_SUBDOMAIN: () => DEFAULT_MAIL_FROM_SUBDOMAIN,
|
|
6981
6981
|
DEFAULT_SUPPRESSION_REASONS: () => DEFAULT_SUPPRESSION_REASONS,
|
|
6982
6982
|
DEFAULT_TAGS: () => DEFAULT_TAGS,
|
|
6983
|
+
EXTERNAL_ID_PREFIX: () => EXTERNAL_ID_PREFIX,
|
|
6983
6984
|
LAMBDA_EVENT_PROCESSOR_PATH: () => LAMBDA_EVENT_PROCESSOR_PATH,
|
|
6984
6985
|
LAMBDA_SMS_EVENT_PROCESSOR_PATH: () => LAMBDA_SMS_EVENT_PROCESSOR_PATH,
|
|
6985
6986
|
REPLY_TOKEN_VERSION: () => REPLY_TOKEN_VERSION,
|
|
@@ -7225,7 +7226,7 @@ function resolvePackagePath(relativePath) {
|
|
|
7225
7226
|
const dir = typeof __dirname !== "undefined" ? __dirname : dirname3(fileURLToPath3(import.meta.url));
|
|
7226
7227
|
return join8(dir, "..", relativePath);
|
|
7227
7228
|
}
|
|
7228
|
-
var DEFAULT_EVENT_TYPES, ALL_EVENT_TYPES, DEFAULT_SUPPRESSION_REASONS, DEFAULT_CONFIG_SET_NAME, DEFAULT_MAIL_FROM_SUBDOMAIN, DEFAULT_HISTORY_RETENTION, VERCEL_OIDC_URL, VERCEL_OIDC_THUMBPRINT, RESOURCE_PREFIX, DEFAULT_TAGS, REPLY_TOKEN_VERSION, PAYLOAD_LEN, HMAC_LEN, TOKEN_LEN, LAMBDA_EVENT_PROCESSOR_PATH, LAMBDA_SMS_EVENT_PROCESSOR_PATH;
|
|
7229
|
+
var DEFAULT_EVENT_TYPES, ALL_EVENT_TYPES, DEFAULT_SUPPRESSION_REASONS, DEFAULT_CONFIG_SET_NAME, DEFAULT_MAIL_FROM_SUBDOMAIN, DEFAULT_HISTORY_RETENTION, VERCEL_OIDC_URL, VERCEL_OIDC_THUMBPRINT, RESOURCE_PREFIX, DEFAULT_TAGS, EXTERNAL_ID_PREFIX, REPLY_TOKEN_VERSION, PAYLOAD_LEN, HMAC_LEN, TOKEN_LEN, LAMBDA_EVENT_PROCESSOR_PATH, LAMBDA_SMS_EVENT_PROCESSOR_PATH;
|
|
7229
7230
|
var init_dist = __esm({
|
|
7230
7231
|
"../core/dist/index.js"() {
|
|
7231
7232
|
"use strict";
|
|
@@ -7263,6 +7264,7 @@ var init_dist = __esm({
|
|
|
7263
7264
|
DEFAULT_TAGS = {
|
|
7264
7265
|
ManagedBy: "wraps"
|
|
7265
7266
|
};
|
|
7267
|
+
EXTERNAL_ID_PREFIX = "wraps_";
|
|
7266
7268
|
REPLY_TOKEN_VERSION = 1;
|
|
7267
7269
|
PAYLOAD_LEN = 22;
|
|
7268
7270
|
HMAC_LEN = 16;
|
|
@@ -10202,8 +10204,8 @@ import { homedir as homedir4, tmpdir as tmpdir2 } from "os";
|
|
|
10202
10204
|
import { join as join23 } from "path";
|
|
10203
10205
|
import { Readable } from "stream";
|
|
10204
10206
|
import { pipeline } from "stream/promises";
|
|
10205
|
-
import { cancel as
|
|
10206
|
-
import
|
|
10207
|
+
import { cancel as cancel35, confirm as confirm29, intro as intro56, isCancel as isCancel40, log as log54 } from "@clack/prompts";
|
|
10208
|
+
import pc63 from "picocolors";
|
|
10207
10209
|
function isStandaloneInstall() {
|
|
10208
10210
|
return process.execPath.includes(".wraps/runtime");
|
|
10209
10211
|
}
|
|
@@ -10232,7 +10234,7 @@ function detectPlatformArch() {
|
|
|
10232
10234
|
return { platform: platform2, arch };
|
|
10233
10235
|
}
|
|
10234
10236
|
async function update(currentVersion) {
|
|
10235
|
-
|
|
10237
|
+
intro56(pc63.bold("Wraps CLI Update"));
|
|
10236
10238
|
const progress = new DeploymentProgress();
|
|
10237
10239
|
const result = await progress.execute(
|
|
10238
10240
|
"Checking for updates...",
|
|
@@ -10244,28 +10246,28 @@ async function update(currentVersion) {
|
|
|
10244
10246
|
}
|
|
10245
10247
|
const { version: latestVersion, release } = result;
|
|
10246
10248
|
if (currentVersion === latestVersion) {
|
|
10247
|
-
progress.succeed(`Already up to date ${
|
|
10249
|
+
progress.succeed(`Already up to date ${pc63.dim(`(v${currentVersion})`)}`);
|
|
10248
10250
|
return;
|
|
10249
10251
|
}
|
|
10250
10252
|
console.log();
|
|
10251
10253
|
log54.info(
|
|
10252
|
-
`Current version: ${
|
|
10253
|
-
Latest version: ${
|
|
10254
|
+
`Current version: ${pc63.dim(`v${currentVersion}`)}
|
|
10255
|
+
Latest version: ${pc63.cyan(`v${latestVersion}`)}`
|
|
10254
10256
|
);
|
|
10255
10257
|
console.log();
|
|
10256
10258
|
if (!isStandaloneInstall()) {
|
|
10257
10259
|
log54.info(
|
|
10258
10260
|
`You installed Wraps via npm. Update with:
|
|
10259
10261
|
|
|
10260
|
-
${
|
|
10262
|
+
${pc63.cyan("npm update -g @wraps.dev/cli")}`
|
|
10261
10263
|
);
|
|
10262
10264
|
return;
|
|
10263
10265
|
}
|
|
10264
10266
|
const shouldUpdate = await confirm29({
|
|
10265
10267
|
message: `Update to v${latestVersion}?`
|
|
10266
10268
|
});
|
|
10267
|
-
if (
|
|
10268
|
-
|
|
10269
|
+
if (isCancel40(shouldUpdate) || !shouldUpdate) {
|
|
10270
|
+
cancel35("Update cancelled.");
|
|
10269
10271
|
return;
|
|
10270
10272
|
}
|
|
10271
10273
|
const { platform: platform2, arch } = detectPlatformArch();
|
|
@@ -10332,7 +10334,7 @@ async function update(currentVersion) {
|
|
|
10332
10334
|
});
|
|
10333
10335
|
console.log();
|
|
10334
10336
|
progress.succeed(
|
|
10335
|
-
`Updated to ${
|
|
10337
|
+
`Updated to ${pc63.cyan(`v${latestVersion}`)} successfully!`
|
|
10336
10338
|
);
|
|
10337
10339
|
} finally {
|
|
10338
10340
|
rmSync(tmp, { recursive: true, force: true });
|
|
@@ -10355,8 +10357,8 @@ init_esm_shims();
|
|
|
10355
10357
|
import { readFileSync as readFileSync3 } from "fs";
|
|
10356
10358
|
import { dirname as dirname5, join as join24 } from "path";
|
|
10357
10359
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
10358
|
-
import * as
|
|
10359
|
-
import
|
|
10360
|
+
import * as clack60 from "@clack/prompts";
|
|
10361
|
+
import pc64 from "picocolors";
|
|
10360
10362
|
|
|
10361
10363
|
// src/commands/auth/login.ts
|
|
10362
10364
|
init_esm_shims();
|
|
@@ -26607,7 +26609,7 @@ init_esm_shims();
|
|
|
26607
26609
|
// src/utils/email/template-mustache-case.ts
|
|
26608
26610
|
init_esm_shims();
|
|
26609
26611
|
var HANDLEBARS_BLOCK_HELPERS = /* @__PURE__ */ new Set(["if", "unless", "each", "with"]);
|
|
26610
|
-
function normalizePlainTextMustaches(
|
|
26612
|
+
function normalizePlainTextMustaches(text12, canonicalVars) {
|
|
26611
26613
|
const canonicalByLower = /* @__PURE__ */ new Map();
|
|
26612
26614
|
for (const name of canonicalVars) {
|
|
26613
26615
|
canonicalByLower.set(name.toLowerCase(), name);
|
|
@@ -26615,7 +26617,7 @@ function normalizePlainTextMustaches(text11, canonicalVars) {
|
|
|
26615
26617
|
function restoreIdentifier(name) {
|
|
26616
26618
|
return canonicalByLower.get(name.toLowerCase()) ?? name;
|
|
26617
26619
|
}
|
|
26618
|
-
return
|
|
26620
|
+
return text12.replace(
|
|
26619
26621
|
/\{\{([#/]?)([A-Z][A-Z0-9_]*(?:\.[A-Z0-9_]+)*)((?:\s+[A-Z0-9_.]+)*)\s*\}\}/g,
|
|
26620
26622
|
(match, sigil, name, args) => {
|
|
26621
26623
|
const lower = name.toLowerCase();
|
|
@@ -26665,8 +26667,8 @@ async function renderTemplateWithProxy(Component) {
|
|
|
26665
26667
|
match = regex.exec(html);
|
|
26666
26668
|
}
|
|
26667
26669
|
const canonicalVars = /* @__PURE__ */ new Set([...htmlVarNames, ...accessedProps]);
|
|
26668
|
-
const
|
|
26669
|
-
return { html, text:
|
|
26670
|
+
const text12 = normalizePlainTextMustaches(rawText, canonicalVars);
|
|
26671
|
+
return { html, text: text12, accessedProps };
|
|
26670
26672
|
}
|
|
26671
26673
|
|
|
26672
26674
|
// src/commands/email/templates/push.ts
|
|
@@ -26905,11 +26907,11 @@ async function compileTemplate(filePath, slug, source, sourceHash, wrapsDir) {
|
|
|
26905
26907
|
"Template must have a default export (React component function)"
|
|
26906
26908
|
);
|
|
26907
26909
|
}
|
|
26908
|
-
const { html, text:
|
|
26910
|
+
const { html, text: text12, accessedProps } = await renderTemplateWithProxy(Component);
|
|
26909
26911
|
const variables = mergeVariables(extractVariables(html), accessedProps);
|
|
26910
26912
|
const sesSubject = transformVariablesForSes(subject);
|
|
26911
26913
|
const sesHtml = transformVariablesForSes(html);
|
|
26912
|
-
const sesText = transformVariablesForSes(
|
|
26914
|
+
const sesText = transformVariablesForSes(text12);
|
|
26913
26915
|
const sesTemplateName = slug.replace(/[^a-zA-Z0-9-_]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").substring(0, 64);
|
|
26914
26916
|
return {
|
|
26915
26917
|
slug,
|
|
@@ -31259,22 +31261,106 @@ async function workflowsValidate(options) {
|
|
|
31259
31261
|
});
|
|
31260
31262
|
}
|
|
31261
31263
|
|
|
31262
|
-
// src/commands/
|
|
31264
|
+
// src/commands/license/generate.ts
|
|
31263
31265
|
init_esm_shims();
|
|
31264
|
-
init_events();
|
|
31265
31266
|
import * as clack39 from "@clack/prompts";
|
|
31266
31267
|
import pc40 from "picocolors";
|
|
31268
|
+
|
|
31269
|
+
// src/utils/license.ts
|
|
31270
|
+
init_esm_shims();
|
|
31271
|
+
import { sign } from "crypto";
|
|
31272
|
+
var VALID_TIERS = ["starter", "growth", "scale"];
|
|
31273
|
+
function generateLicenseKey(tier, expires) {
|
|
31274
|
+
if (!VALID_TIERS.includes(tier)) {
|
|
31275
|
+
throw new Error(
|
|
31276
|
+
`Invalid tier "${tier}". Valid tiers: ${VALID_TIERS.join(", ")}`
|
|
31277
|
+
);
|
|
31278
|
+
}
|
|
31279
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
31280
|
+
if (expires <= today) {
|
|
31281
|
+
throw new Error(
|
|
31282
|
+
`Expiry date must be in the future (got "${expires}", today is "${today}")`
|
|
31283
|
+
);
|
|
31284
|
+
}
|
|
31285
|
+
const privateKeyPem = process.env.WRAPS_LICENSE_PRIVATE_KEY;
|
|
31286
|
+
if (!privateKeyPem) {
|
|
31287
|
+
throw new Error("WRAPS_LICENSE_PRIVATE_KEY is not set");
|
|
31288
|
+
}
|
|
31289
|
+
const payload = `v1.${tier}.${expires}`;
|
|
31290
|
+
const sig = sign(null, Buffer.from(payload), privateKeyPem);
|
|
31291
|
+
return `${payload}.${sig.toString("hex")}`;
|
|
31292
|
+
}
|
|
31293
|
+
|
|
31294
|
+
// src/commands/license/generate.ts
|
|
31295
|
+
init_json_output();
|
|
31296
|
+
var VALID_TIERS2 = ["starter", "growth", "scale"];
|
|
31297
|
+
async function licenseGenerate(options) {
|
|
31298
|
+
if (!isJsonMode()) {
|
|
31299
|
+
clack39.intro(pc40.bold("Wraps License Key Generator"));
|
|
31300
|
+
}
|
|
31301
|
+
let tier = options.tier;
|
|
31302
|
+
if (!tier) {
|
|
31303
|
+
const answer = await clack39.select({
|
|
31304
|
+
message: "License tier:",
|
|
31305
|
+
options: VALID_TIERS2.map((t) => ({ value: t, label: t }))
|
|
31306
|
+
});
|
|
31307
|
+
if (clack39.isCancel(answer)) {
|
|
31308
|
+
clack39.cancel("Cancelled.");
|
|
31309
|
+
process.exit(0);
|
|
31310
|
+
}
|
|
31311
|
+
tier = answer;
|
|
31312
|
+
}
|
|
31313
|
+
let expires = options.expires;
|
|
31314
|
+
if (!expires) {
|
|
31315
|
+
const answer = await clack39.text({
|
|
31316
|
+
message: "Expiry date (YYYY-MM-DD):",
|
|
31317
|
+
placeholder: "2027-05-13",
|
|
31318
|
+
validate: (v) => {
|
|
31319
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(v)) return "Use YYYY-MM-DD format";
|
|
31320
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
31321
|
+
if (v <= today) return "Expiry date must be in the future";
|
|
31322
|
+
}
|
|
31323
|
+
});
|
|
31324
|
+
if (clack39.isCancel(answer)) {
|
|
31325
|
+
clack39.cancel("Cancelled.");
|
|
31326
|
+
process.exit(0);
|
|
31327
|
+
}
|
|
31328
|
+
expires = answer;
|
|
31329
|
+
}
|
|
31330
|
+
const key = generateLicenseKey(tier, expires);
|
|
31331
|
+
if (isJsonMode()) {
|
|
31332
|
+
jsonSuccess("license.generate", { key, tier, expires });
|
|
31333
|
+
return;
|
|
31334
|
+
}
|
|
31335
|
+
clack39.note(
|
|
31336
|
+
[
|
|
31337
|
+
`${pc40.bold("Key:")} ${pc40.cyan(key)}`,
|
|
31338
|
+
`${pc40.bold("Tier:")} ${pc40.dim(tier)}`,
|
|
31339
|
+
`${pc40.bold("Expires:")} ${pc40.dim(expires)}`
|
|
31340
|
+
].join("\n"),
|
|
31341
|
+
"Generated License Key"
|
|
31342
|
+
);
|
|
31343
|
+
clack39.outro(
|
|
31344
|
+
pc40.dim("Set WRAPS_LICENSE_KEY=<key> in the self-hosted deployment")
|
|
31345
|
+
);
|
|
31346
|
+
}
|
|
31347
|
+
|
|
31348
|
+
// src/commands/news.ts
|
|
31349
|
+
init_esm_shims();
|
|
31350
|
+
init_events();
|
|
31351
|
+
import * as clack40 from "@clack/prompts";
|
|
31352
|
+
import pc41 from "picocolors";
|
|
31267
31353
|
async function news() {
|
|
31268
31354
|
trackCommand("news", { success: true });
|
|
31269
|
-
|
|
31355
|
+
clack40.intro(pc41.bold("What's New in Wraps"));
|
|
31270
31356
|
console.log();
|
|
31271
31357
|
console.log(" See the latest updates, features, and improvements:");
|
|
31272
31358
|
console.log();
|
|
31273
31359
|
console.log(
|
|
31274
|
-
` ${
|
|
31360
|
+
` ${pc41.cyan("\u2192")} ${pc41.bold("Changelog:")} ${pc41.cyan("https://wraps.dev/changelog")}`
|
|
31275
31361
|
);
|
|
31276
31362
|
console.log();
|
|
31277
|
-
console.log(
|
|
31363
|
+
console.log(pc41.dim(" Subscribe to get notified about new releases."));
|
|
31278
31364
|
console.log();
|
|
31279
31365
|
}
|
|
31280
31366
|
|
|
@@ -31282,8 +31368,8 @@ async function news() {
|
|
|
31282
31368
|
init_esm_shims();
|
|
31283
31369
|
init_events();
|
|
31284
31370
|
init_json_output();
|
|
31285
|
-
import * as
|
|
31286
|
-
import
|
|
31371
|
+
import * as clack41 from "@clack/prompts";
|
|
31372
|
+
import pc42 from "picocolors";
|
|
31287
31373
|
function getBaseStatements() {
|
|
31288
31374
|
return [
|
|
31289
31375
|
{
|
|
@@ -31674,74 +31760,74 @@ function buildPolicy(service, preset) {
|
|
|
31674
31760
|
};
|
|
31675
31761
|
}
|
|
31676
31762
|
function displaySummary(service, preset) {
|
|
31677
|
-
|
|
31763
|
+
clack41.intro(pc42.bold("Wraps Required AWS Permissions"));
|
|
31678
31764
|
const serviceLabel = service ? service.toUpperCase() : "All Services";
|
|
31679
31765
|
const presetLabel = preset ? preset.charAt(0).toUpperCase() + preset.slice(1) : "All Features";
|
|
31680
31766
|
console.log(`
|
|
31681
|
-
${
|
|
31682
|
-
console.log(`${
|
|
31767
|
+
${pc42.dim("Service:")} ${pc42.cyan(serviceLabel)}`);
|
|
31768
|
+
console.log(`${pc42.dim("Preset:")} ${pc42.cyan(presetLabel)}
|
|
31683
31769
|
`);
|
|
31684
|
-
console.log(
|
|
31685
|
-
console.log(` ${
|
|
31686
|
-
console.log(` ${
|
|
31687
|
-
console.log(` ${
|
|
31770
|
+
console.log(pc42.bold("Required AWS Services:\n"));
|
|
31771
|
+
console.log(` ${pc42.green("+")} ${pc42.bold("IAM")} - Role management`);
|
|
31772
|
+
console.log(` ${pc42.green("+")} ${pc42.bold("STS")} - Credential validation`);
|
|
31773
|
+
console.log(` ${pc42.green("+")} ${pc42.bold("CloudWatch")} - Metrics access`);
|
|
31688
31774
|
console.log(
|
|
31689
|
-
` ${
|
|
31775
|
+
` ${pc42.green("+")} ${pc42.bold("S3")} - State management ${pc42.dim("(wraps-state-* buckets)")}`
|
|
31690
31776
|
);
|
|
31691
31777
|
if (!service || service === "email") {
|
|
31692
31778
|
console.log(
|
|
31693
|
-
` ${
|
|
31779
|
+
` ${pc42.green("+")} ${pc42.bold("SES")} - Email sending & configuration`
|
|
31694
31780
|
);
|
|
31695
31781
|
if (!preset || preset === "production" || preset === "enterprise") {
|
|
31696
31782
|
console.log(
|
|
31697
|
-
` ${
|
|
31783
|
+
` ${pc42.green("+")} ${pc42.bold("EventBridge")} - Event routing (Production+)`
|
|
31698
31784
|
);
|
|
31699
31785
|
console.log(
|
|
31700
|
-
` ${
|
|
31786
|
+
` ${pc42.green("+")} ${pc42.bold("SQS")} - Event queuing (Production+)`
|
|
31701
31787
|
);
|
|
31702
31788
|
console.log(
|
|
31703
|
-
` ${
|
|
31789
|
+
` ${pc42.green("+")} ${pc42.bold("Lambda")} - Event processing (Production+)`
|
|
31704
31790
|
);
|
|
31705
31791
|
console.log(
|
|
31706
|
-
` ${
|
|
31792
|
+
` ${pc42.green("+")} ${pc42.bold("DynamoDB")} - Email history (Production+)`
|
|
31707
31793
|
);
|
|
31708
31794
|
}
|
|
31709
31795
|
console.log(
|
|
31710
|
-
` ${
|
|
31796
|
+
` ${pc42.yellow("?")} ${pc42.bold("Route53")} - Auto DNS ${pc42.dim("(optional)")}`
|
|
31711
31797
|
);
|
|
31712
31798
|
console.log(
|
|
31713
|
-
` ${
|
|
31799
|
+
` ${pc42.yellow("?")} ${pc42.bold("IAM OIDC")} - Vercel integration ${pc42.dim("(if using Vercel)")}`
|
|
31714
31800
|
);
|
|
31715
31801
|
}
|
|
31716
31802
|
if (!service || service === "sms") {
|
|
31717
31803
|
console.log(
|
|
31718
|
-
` ${
|
|
31804
|
+
` ${pc42.green("+")} ${pc42.bold("SMS Voice")} - SMS sending & management`
|
|
31719
31805
|
);
|
|
31720
|
-
console.log(` ${
|
|
31721
|
-
console.log(` ${
|
|
31806
|
+
console.log(` ${pc42.green("+")} ${pc42.bold("DynamoDB")} - Message history`);
|
|
31807
|
+
console.log(` ${pc42.green("+")} ${pc42.bold("Lambda")} - Event processing`);
|
|
31722
31808
|
}
|
|
31723
31809
|
if (!service || service === "cdn") {
|
|
31724
|
-
console.log(` ${
|
|
31810
|
+
console.log(` ${pc42.green("+")} ${pc42.bold("S3")} - Asset storage`);
|
|
31725
31811
|
console.log(
|
|
31726
|
-
` ${
|
|
31812
|
+
` ${pc42.green("+")} ${pc42.bold("CloudFront")} - CDN distribution`
|
|
31727
31813
|
);
|
|
31728
|
-
console.log(` ${
|
|
31814
|
+
console.log(` ${pc42.green("+")} ${pc42.bold("ACM")} - SSL certificates`);
|
|
31729
31815
|
console.log(
|
|
31730
|
-
` ${
|
|
31816
|
+
` ${pc42.yellow("?")} ${pc42.bold("Route53")} - DNS management ${pc42.dim("(optional)")}`
|
|
31731
31817
|
);
|
|
31732
31818
|
}
|
|
31733
31819
|
console.log(`
|
|
31734
|
-
${
|
|
31735
|
-
console.log(` ${
|
|
31820
|
+
${pc42.dim("Get full IAM policy JSON:")}`);
|
|
31821
|
+
console.log(` ${pc42.cyan("wraps permissions --json")}`);
|
|
31736
31822
|
if (service) {
|
|
31737
31823
|
console.log(`
|
|
31738
|
-
${
|
|
31739
|
-
console.log(` ${
|
|
31824
|
+
${pc42.dim("Get permissions for all services:")}`);
|
|
31825
|
+
console.log(` ${pc42.cyan("wraps permissions")}`);
|
|
31740
31826
|
}
|
|
31741
31827
|
console.log(`
|
|
31742
|
-
${
|
|
31828
|
+
${pc42.dim("Documentation:")}`);
|
|
31743
31829
|
console.log(
|
|
31744
|
-
` ${
|
|
31830
|
+
` ${pc42.blue("https://wraps.dev/docs/guides/aws-setup/permissions")}
|
|
31745
31831
|
`
|
|
31746
31832
|
);
|
|
31747
31833
|
}
|
|
@@ -31759,17 +31845,17 @@ async function permissions(options) {
|
|
|
31759
31845
|
});
|
|
31760
31846
|
} else {
|
|
31761
31847
|
displaySummary(options.service, options.preset);
|
|
31762
|
-
console.log(
|
|
31848
|
+
console.log(pc42.bold("Quick Setup:\n"));
|
|
31763
31849
|
console.log("1. Copy the IAM policy:");
|
|
31764
31850
|
console.log(
|
|
31765
|
-
` ${
|
|
31851
|
+
` ${pc42.cyan("wraps permissions --json > wraps-policy.json")}
|
|
31766
31852
|
`
|
|
31767
31853
|
);
|
|
31768
31854
|
console.log("2. Create the policy in AWS Console:");
|
|
31769
31855
|
console.log(" IAM > Policies > Create Policy > JSON\n");
|
|
31770
31856
|
console.log("3. Attach to your IAM user/role\n");
|
|
31771
|
-
|
|
31772
|
-
|
|
31857
|
+
clack41.outro(
|
|
31858
|
+
pc42.green("Run with --json to get the full IAM policy document")
|
|
31773
31859
|
);
|
|
31774
31860
|
}
|
|
31775
31861
|
trackCommand("permissions", {
|
|
@@ -31784,11 +31870,12 @@ import {
|
|
|
31784
31870
|
CreateRoleCommand,
|
|
31785
31871
|
GetRoleCommand,
|
|
31786
31872
|
IAMClient as IAMClient3,
|
|
31787
|
-
PutRolePolicyCommand
|
|
31873
|
+
PutRolePolicyCommand,
|
|
31874
|
+
UpdateAssumeRolePolicyCommand
|
|
31788
31875
|
} from "@aws-sdk/client-iam";
|
|
31789
|
-
import { confirm as confirm19, intro as
|
|
31876
|
+
import { confirm as confirm19, intro as intro36, isCancel as isCancel27, log as log37, outro as outro24, select as select19 } from "@clack/prompts";
|
|
31790
31877
|
import * as pulumi24 from "@pulumi/pulumi";
|
|
31791
|
-
import
|
|
31878
|
+
import pc43 from "picocolors";
|
|
31792
31879
|
init_events();
|
|
31793
31880
|
init_aws();
|
|
31794
31881
|
init_config();
|
|
@@ -31975,7 +32062,7 @@ async function validateAndLoadMetadata(options, progress) {
|
|
|
31975
32062
|
"Validating AWS credentials",
|
|
31976
32063
|
async () => validateAWSCredentials()
|
|
31977
32064
|
);
|
|
31978
|
-
progress.info(`Connected to AWS account: ${
|
|
32065
|
+
progress.info(`Connected to AWS account: ${pc43.cyan(identity.accountId)}`);
|
|
31979
32066
|
const region = await resolveRegionForCommand({
|
|
31980
32067
|
accountId: identity.accountId,
|
|
31981
32068
|
optionRegion: options.region,
|
|
@@ -31985,11 +32072,11 @@ async function validateAndLoadMetadata(options, progress) {
|
|
|
31985
32072
|
if (!metadata) {
|
|
31986
32073
|
progress.stop();
|
|
31987
32074
|
log37.error(
|
|
31988
|
-
`No Wraps deployment found for account ${
|
|
32075
|
+
`No Wraps deployment found for account ${pc43.cyan(identity.accountId)} in region ${pc43.cyan(region)}`
|
|
31989
32076
|
);
|
|
31990
32077
|
console.log(
|
|
31991
32078
|
`
|
|
31992
|
-
Run ${
|
|
32079
|
+
Run ${pc43.cyan("wraps email init")} to deploy infrastructure first.
|
|
31993
32080
|
`
|
|
31994
32081
|
);
|
|
31995
32082
|
process.exit(1);
|
|
@@ -32001,7 +32088,7 @@ Run ${pc42.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
32001
32088
|
log37.error("No services deployed in this region.");
|
|
32002
32089
|
console.log(
|
|
32003
32090
|
`
|
|
32004
|
-
Run ${
|
|
32091
|
+
Run ${pc43.cyan("wraps email init")} or ${pc43.cyan("wraps sms init")} first.
|
|
32005
32092
|
`
|
|
32006
32093
|
);
|
|
32007
32094
|
process.exit(1);
|
|
@@ -32084,6 +32171,33 @@ async function updatePlatformRole(metadata, progress, externalId) {
|
|
|
32084
32171
|
})
|
|
32085
32172
|
);
|
|
32086
32173
|
});
|
|
32174
|
+
if (externalId) {
|
|
32175
|
+
const trustPolicy = {
|
|
32176
|
+
Version: "2012-10-17",
|
|
32177
|
+
Statement: [
|
|
32178
|
+
{
|
|
32179
|
+
Effect: "Allow",
|
|
32180
|
+
Principal: {
|
|
32181
|
+
AWS: `arn:aws:iam::${WRAPS_PLATFORM_ACCOUNT_ID}:root`
|
|
32182
|
+
},
|
|
32183
|
+
Action: "sts:AssumeRole",
|
|
32184
|
+
Condition: {
|
|
32185
|
+
StringEquals: {
|
|
32186
|
+
"sts:ExternalId": externalId
|
|
32187
|
+
}
|
|
32188
|
+
}
|
|
32189
|
+
}
|
|
32190
|
+
]
|
|
32191
|
+
};
|
|
32192
|
+
await progress.execute("Repairing trust policy", async () => {
|
|
32193
|
+
await iam11.send(
|
|
32194
|
+
new UpdateAssumeRolePolicyCommand({
|
|
32195
|
+
RoleName: roleName,
|
|
32196
|
+
PolicyDocument: JSON.stringify(trustPolicy)
|
|
32197
|
+
})
|
|
32198
|
+
);
|
|
32199
|
+
});
|
|
32200
|
+
}
|
|
32087
32201
|
progress.succeed("Platform access role updated");
|
|
32088
32202
|
} else if (externalId) {
|
|
32089
32203
|
await progress.execute("Creating platform access role", async () => {
|
|
@@ -32126,7 +32240,7 @@ async function updatePlatformRole(metadata, progress, externalId) {
|
|
|
32126
32240
|
progress.succeed("Platform access role created");
|
|
32127
32241
|
} else {
|
|
32128
32242
|
progress.info(
|
|
32129
|
-
`IAM role ${
|
|
32243
|
+
`IAM role ${pc43.cyan(roleName)} will be created when you add your AWS account in the dashboard`
|
|
32130
32244
|
);
|
|
32131
32245
|
}
|
|
32132
32246
|
}
|
|
@@ -32139,7 +32253,7 @@ async function resolveOrganization() {
|
|
|
32139
32253
|
if (orgs.length === 1) {
|
|
32140
32254
|
return orgs[0];
|
|
32141
32255
|
}
|
|
32142
|
-
const selected = await
|
|
32256
|
+
const selected = await select19({
|
|
32143
32257
|
message: "Which organization should this AWS account connect to?",
|
|
32144
32258
|
options: orgs.map((org) => ({
|
|
32145
32259
|
value: org.id,
|
|
@@ -32147,8 +32261,8 @@ async function resolveOrganization() {
|
|
|
32147
32261
|
hint: org.slug
|
|
32148
32262
|
}))
|
|
32149
32263
|
});
|
|
32150
|
-
if (
|
|
32151
|
-
|
|
32264
|
+
if (isCancel27(selected)) {
|
|
32265
|
+
outro24("Operation cancelled");
|
|
32152
32266
|
process.exit(0);
|
|
32153
32267
|
}
|
|
32154
32268
|
return orgs.find((o) => o.id === selected) || null;
|
|
@@ -32180,7 +32294,7 @@ async function registerConnection(params) {
|
|
|
32180
32294
|
async function authenticatedConnect(token, options) {
|
|
32181
32295
|
const startTime = Date.now();
|
|
32182
32296
|
if (!isJsonMode()) {
|
|
32183
|
-
|
|
32297
|
+
intro36(pc43.bold("Connect to Wraps Platform"));
|
|
32184
32298
|
}
|
|
32185
32299
|
const progress = new DeploymentProgress();
|
|
32186
32300
|
try {
|
|
@@ -32198,7 +32312,7 @@ async function authenticatedConnect(token, options) {
|
|
|
32198
32312
|
process.exit(1);
|
|
32199
32313
|
}
|
|
32200
32314
|
if (!isJsonMode()) {
|
|
32201
|
-
progress.info(`Organization: ${
|
|
32315
|
+
progress.info(`Organization: ${pc43.cyan(org.name)}`);
|
|
32202
32316
|
}
|
|
32203
32317
|
if (hasEmail) {
|
|
32204
32318
|
const emailConfig = metadata.services.email?.config;
|
|
@@ -32213,8 +32327,8 @@ async function authenticatedConnect(token, options) {
|
|
|
32213
32327
|
message: "Enable event tracking now?",
|
|
32214
32328
|
initialValue: true
|
|
32215
32329
|
});
|
|
32216
|
-
if (
|
|
32217
|
-
|
|
32330
|
+
if (isCancel27(enableTracking) || !enableTracking) {
|
|
32331
|
+
outro24("Platform connection cancelled.");
|
|
32218
32332
|
process.exit(0);
|
|
32219
32333
|
}
|
|
32220
32334
|
metadata.services.email.config = {
|
|
@@ -32260,7 +32374,7 @@ async function authenticatedConnect(token, options) {
|
|
|
32260
32374
|
);
|
|
32261
32375
|
console.log(
|
|
32262
32376
|
`
|
|
32263
|
-
You can try the manual flow: ${
|
|
32377
|
+
You can try the manual flow: ${pc43.cyan("wraps auth logout")} then ${pc43.cyan("wraps platform connect")}
|
|
32264
32378
|
`
|
|
32265
32379
|
);
|
|
32266
32380
|
process.exit(1);
|
|
@@ -32290,8 +32404,8 @@ You can try the manual flow: ${pc42.cyan("wraps auth logout")} then ${pc42.cyan(
|
|
|
32290
32404
|
const errMsg = error instanceof Error ? error.message : String(error);
|
|
32291
32405
|
log37.warn(
|
|
32292
32406
|
`Could not create/update IAM role (${errName}): ${errMsg}
|
|
32293
|
-
You may need ${
|
|
32294
|
-
Run ${
|
|
32407
|
+
You may need ${pc43.cyan("iam:GetRole")}, ${pc43.cyan("iam:CreateRole")}, and ${pc43.cyan("iam:PutRolePolicy")} permissions.
|
|
32408
|
+
Run ${pc43.cyan("wraps platform update-role")} to retry.`
|
|
32295
32409
|
);
|
|
32296
32410
|
}
|
|
32297
32411
|
await saveConnectionMetadata(metadata);
|
|
@@ -32305,14 +32419,14 @@ You can try the manual flow: ${pc42.cyan("wraps auth logout")} then ${pc42.cyan(
|
|
|
32305
32419
|
webhookConnected: true
|
|
32306
32420
|
});
|
|
32307
32421
|
} else {
|
|
32308
|
-
|
|
32422
|
+
outro24(pc43.green("Platform connection complete!"));
|
|
32309
32423
|
console.log();
|
|
32310
32424
|
console.log(
|
|
32311
|
-
|
|
32425
|
+
pc43.dim(
|
|
32312
32426
|
"Events from your AWS infrastructure will stream to the dashboard."
|
|
32313
32427
|
)
|
|
32314
32428
|
);
|
|
32315
|
-
console.log(` Dashboard: ${
|
|
32429
|
+
console.log(` Dashboard: ${pc43.cyan("https://app.wraps.dev")}`);
|
|
32316
32430
|
console.log();
|
|
32317
32431
|
}
|
|
32318
32432
|
const duration = Date.now() - startTime;
|
|
@@ -32343,7 +32457,7 @@ async function connect3(options) {
|
|
|
32343
32457
|
return;
|
|
32344
32458
|
}
|
|
32345
32459
|
const startTime = Date.now();
|
|
32346
|
-
|
|
32460
|
+
intro36(pc43.bold("Connect to Wraps Platform"));
|
|
32347
32461
|
const progress = new DeploymentProgress();
|
|
32348
32462
|
try {
|
|
32349
32463
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -32357,7 +32471,7 @@ async function connect3(options) {
|
|
|
32357
32471
|
"Validating AWS credentials",
|
|
32358
32472
|
async () => validateAWSCredentials()
|
|
32359
32473
|
);
|
|
32360
|
-
progress.info(`Connected to AWS account: ${
|
|
32474
|
+
progress.info(`Connected to AWS account: ${pc43.cyan(identity.accountId)}`);
|
|
32361
32475
|
const region = await resolveRegionForCommand({
|
|
32362
32476
|
accountId: identity.accountId,
|
|
32363
32477
|
optionRegion: options.region,
|
|
@@ -32367,11 +32481,11 @@ async function connect3(options) {
|
|
|
32367
32481
|
if (!metadata) {
|
|
32368
32482
|
progress.stop();
|
|
32369
32483
|
log37.error(
|
|
32370
|
-
`No Wraps deployment found for account ${
|
|
32484
|
+
`No Wraps deployment found for account ${pc43.cyan(identity.accountId)} in region ${pc43.cyan(region)}`
|
|
32371
32485
|
);
|
|
32372
32486
|
console.log(
|
|
32373
32487
|
`
|
|
32374
|
-
Run ${
|
|
32488
|
+
Run ${pc43.cyan("wraps email init")} to deploy infrastructure first.
|
|
32375
32489
|
`
|
|
32376
32490
|
);
|
|
32377
32491
|
process.exit(1);
|
|
@@ -32383,7 +32497,7 @@ Run ${pc42.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
32383
32497
|
log37.error("No services deployed in this region.");
|
|
32384
32498
|
console.log(
|
|
32385
32499
|
`
|
|
32386
|
-
Run ${
|
|
32500
|
+
Run ${pc43.cyan("wraps email init")} or ${pc43.cyan("wraps sms init")} first.
|
|
32387
32501
|
`
|
|
32388
32502
|
);
|
|
32389
32503
|
process.exit(1);
|
|
@@ -32408,8 +32522,8 @@ Run ${pc42.cyan("wraps email init")} or ${pc42.cyan("wraps sms init")} first.
|
|
|
32408
32522
|
message: "Enable event tracking now?",
|
|
32409
32523
|
initialValue: true
|
|
32410
32524
|
});
|
|
32411
|
-
if (
|
|
32412
|
-
|
|
32525
|
+
if (isCancel27(enableEventTracking) || !enableEventTracking) {
|
|
32526
|
+
outro24("Platform connection cancelled.");
|
|
32413
32527
|
process.exit(0);
|
|
32414
32528
|
}
|
|
32415
32529
|
metadata.services.email.config = {
|
|
@@ -32434,9 +32548,9 @@ Run ${pc42.cyan("wraps email init")} or ${pc42.cyan("wraps sms init")} first.
|
|
|
32434
32548
|
if (existingSecret) {
|
|
32435
32549
|
progress.stop();
|
|
32436
32550
|
log37.info(
|
|
32437
|
-
`Already connected to Wraps Platform (AWS Account: ${
|
|
32551
|
+
`Already connected to Wraps Platform (AWS Account: ${pc43.cyan(metadata.accountId)})`
|
|
32438
32552
|
);
|
|
32439
|
-
const action = await
|
|
32553
|
+
const action = await select19({
|
|
32440
32554
|
message: "What would you like to do?",
|
|
32441
32555
|
options: [
|
|
32442
32556
|
{
|
|
@@ -32456,8 +32570,8 @@ Run ${pc42.cyan("wraps email init")} or ${pc42.cyan("wraps sms init")} first.
|
|
|
32456
32570
|
}
|
|
32457
32571
|
]
|
|
32458
32572
|
});
|
|
32459
|
-
if (
|
|
32460
|
-
|
|
32573
|
+
if (isCancel27(action)) {
|
|
32574
|
+
outro24("Operation cancelled");
|
|
32461
32575
|
process.exit(0);
|
|
32462
32576
|
}
|
|
32463
32577
|
if (action === "keep") {
|
|
@@ -32467,8 +32581,8 @@ Run ${pc42.cyan("wraps email init")} or ${pc42.cyan("wraps sms init")} first.
|
|
|
32467
32581
|
message: "Are you sure? Events will no longer be sent to the Wraps Platform.",
|
|
32468
32582
|
initialValue: false
|
|
32469
32583
|
});
|
|
32470
|
-
if (
|
|
32471
|
-
|
|
32584
|
+
if (isCancel27(confirmDisconnect) || !confirmDisconnect) {
|
|
32585
|
+
outro24("Disconnect cancelled");
|
|
32472
32586
|
process.exit(0);
|
|
32473
32587
|
}
|
|
32474
32588
|
metadata.services.email.webhookSecret = void 0;
|
|
@@ -32561,36 +32675,36 @@ Run ${pc42.cyan("wraps email init")} or ${pc42.cyan("wraps sms init")} first.
|
|
|
32561
32675
|
progress.succeed("Platform access role updated");
|
|
32562
32676
|
} else {
|
|
32563
32677
|
progress.info(
|
|
32564
|
-
`IAM role ${
|
|
32678
|
+
`IAM role ${pc43.cyan(roleName)} will be created when you add your AWS account in the dashboard`
|
|
32565
32679
|
);
|
|
32566
32680
|
}
|
|
32567
32681
|
await saveConnectionMetadata(metadata);
|
|
32568
32682
|
progress.stop();
|
|
32569
|
-
|
|
32683
|
+
outro24(pc43.green("Platform connection complete!"));
|
|
32570
32684
|
if (webhookSecret && needsDeployment) {
|
|
32571
32685
|
console.log(`
|
|
32572
|
-
${
|
|
32573
|
-
console.log(
|
|
32574
|
-
console.log(` ${
|
|
32575
|
-
console.log(
|
|
32686
|
+
${pc43.bold("Webhook Secret")} ${pc43.dim("(save this!)")}`);
|
|
32687
|
+
console.log(pc43.dim("\u2500".repeat(60)));
|
|
32688
|
+
console.log(` ${pc43.cyan(webhookSecret)}`);
|
|
32689
|
+
console.log(pc43.dim("\u2500".repeat(60)));
|
|
32576
32690
|
} else if (metadata.services.email?.webhookSecret && !needsDeployment) {
|
|
32577
32691
|
console.log(`
|
|
32578
|
-
${
|
|
32579
|
-
console.log(
|
|
32580
|
-
console.log(` ${
|
|
32581
|
-
console.log(
|
|
32692
|
+
${pc43.bold("Existing Webhook Secret:")}`);
|
|
32693
|
+
console.log(pc43.dim("\u2500".repeat(60)));
|
|
32694
|
+
console.log(` ${pc43.cyan(metadata.services.email.webhookSecret)}`);
|
|
32695
|
+
console.log(pc43.dim("\u2500".repeat(60)));
|
|
32582
32696
|
}
|
|
32583
32697
|
console.log(`
|
|
32584
|
-
${
|
|
32585
|
-
console.log(` 1. Go to ${
|
|
32586
|
-
console.log(` 2. Navigate to ${
|
|
32587
|
-
console.log(` 3. Add your AWS account: ${
|
|
32698
|
+
${pc43.bold("Next Steps:")}`);
|
|
32699
|
+
console.log(` 1. Go to ${pc43.cyan("https://app.wraps.dev")}`);
|
|
32700
|
+
console.log(` 2. Navigate to ${pc43.dim("Settings \u2192 AWS Accounts")}`);
|
|
32701
|
+
console.log(` 3. Add your AWS account: ${pc43.cyan(identity.accountId)}`);
|
|
32588
32702
|
if (webhookSecret) {
|
|
32589
32703
|
console.log(" 4. Paste the webhook secret shown above");
|
|
32590
32704
|
}
|
|
32591
32705
|
console.log();
|
|
32592
32706
|
console.log(
|
|
32593
|
-
|
|
32707
|
+
pc43.dim(
|
|
32594
32708
|
"Events from your AWS infrastructure will stream to the dashboard."
|
|
32595
32709
|
)
|
|
32596
32710
|
);
|
|
@@ -32617,52 +32731,52 @@ ${pc42.bold("Next Steps:")}`);
|
|
|
32617
32731
|
|
|
32618
32732
|
// src/commands/platform/index.ts
|
|
32619
32733
|
init_esm_shims();
|
|
32620
|
-
import * as
|
|
32621
|
-
import
|
|
32734
|
+
import * as clack42 from "@clack/prompts";
|
|
32735
|
+
import pc44 from "picocolors";
|
|
32622
32736
|
async function platform() {
|
|
32623
|
-
|
|
32737
|
+
clack42.intro(pc44.bold("Wraps Platform"));
|
|
32624
32738
|
console.log();
|
|
32625
32739
|
console.log(
|
|
32626
32740
|
" The Wraps Platform extends the free CLI with hosted features:"
|
|
32627
32741
|
);
|
|
32628
32742
|
console.log();
|
|
32629
|
-
console.log(` ${
|
|
32630
|
-
console.log(` ${
|
|
32631
|
-
console.log(` ${
|
|
32632
|
-
console.log(` ${
|
|
32633
|
-
console.log(` ${
|
|
32634
|
-
console.log(` ${
|
|
32635
|
-
console.log(` ${
|
|
32743
|
+
console.log(` ${pc44.bold("Features:")}`);
|
|
32744
|
+
console.log(` ${pc44.green("\u2713")} Visual email template editor`);
|
|
32745
|
+
console.log(` ${pc44.green("\u2713")} Broadcast campaigns & scheduling`);
|
|
32746
|
+
console.log(` ${pc44.green("\u2713")} Contact management & segments`);
|
|
32747
|
+
console.log(` ${pc44.green("\u2713")} Workflow automations`);
|
|
32748
|
+
console.log(` ${pc44.green("\u2713")} Analytics dashboard`);
|
|
32749
|
+
console.log(` ${pc44.green("\u2713")} Team collaboration`);
|
|
32636
32750
|
console.log();
|
|
32637
|
-
console.log(` ${
|
|
32638
|
-
console.log(` ${
|
|
32639
|
-
console.log(` ${
|
|
32640
|
-
console.log(` ${
|
|
32641
|
-
console.log(` ${
|
|
32751
|
+
console.log(` ${pc44.bold("Pricing:")}`);
|
|
32752
|
+
console.log(` ${pc44.cyan("Starter")} $10/mo 5,000 contacts`);
|
|
32753
|
+
console.log(` ${pc44.cyan("Growth")} $25/mo 25,000 contacts`);
|
|
32754
|
+
console.log(` ${pc44.cyan("Scale")} $50/mo 100,000 contacts`);
|
|
32755
|
+
console.log(` ${pc44.cyan("Enterprise")} Custom Unlimited contacts`);
|
|
32642
32756
|
console.log();
|
|
32643
32757
|
console.log(
|
|
32644
|
-
|
|
32758
|
+
pc44.dim(" + AWS costs at $0.10 per 1,000 emails (paid directly to AWS)")
|
|
32645
32759
|
);
|
|
32646
32760
|
console.log();
|
|
32647
32761
|
console.log(
|
|
32648
|
-
` ${
|
|
32762
|
+
` ${pc44.bold("Learn more:")} ${pc44.cyan("https://wraps.dev/platform")}`
|
|
32649
32763
|
);
|
|
32650
32764
|
console.log();
|
|
32651
|
-
console.log(
|
|
32765
|
+
console.log(pc44.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
32652
32766
|
console.log();
|
|
32653
|
-
console.log(` ${
|
|
32767
|
+
console.log(` ${pc44.bold("Platform Commands:")}`);
|
|
32654
32768
|
console.log();
|
|
32655
32769
|
console.log(
|
|
32656
|
-
` ${
|
|
32770
|
+
` ${pc44.cyan("wraps platform connect")} Connect infrastructure to Wraps Platform`
|
|
32657
32771
|
);
|
|
32658
32772
|
console.log(
|
|
32659
|
-
` ${
|
|
32773
|
+
` ${pc44.cyan("wraps platform update-role")} Update IAM permissions for dashboard`
|
|
32660
32774
|
);
|
|
32661
32775
|
console.log();
|
|
32662
32776
|
console.log(
|
|
32663
|
-
|
|
32777
|
+
pc44.dim(" The connect command sets up event streaming and IAM permissions")
|
|
32664
32778
|
);
|
|
32665
|
-
console.log(
|
|
32779
|
+
console.log(pc44.dim(" in one step. Run it after deploying infrastructure."));
|
|
32666
32780
|
console.log();
|
|
32667
32781
|
}
|
|
32668
32782
|
|
|
@@ -32677,14 +32791,15 @@ init_region_resolver();
|
|
|
32677
32791
|
import {
|
|
32678
32792
|
CreateRoleCommand as CreateRoleCommand2,
|
|
32679
32793
|
GetRoleCommand as GetRoleCommand2,
|
|
32680
|
-
IAMClient as IAMClient4
|
|
32794
|
+
IAMClient as IAMClient4,
|
|
32795
|
+
UpdateAssumeRolePolicyCommand as UpdateAssumeRolePolicyCommand2
|
|
32681
32796
|
} from "@aws-sdk/client-iam";
|
|
32682
|
-
import { confirm as confirm20, intro as
|
|
32683
|
-
import
|
|
32797
|
+
import { confirm as confirm20, intro as intro38, isCancel as isCancel28, log as log38, outro as outro25 } from "@clack/prompts";
|
|
32798
|
+
import pc45 from "picocolors";
|
|
32684
32799
|
async function updateRole(options) {
|
|
32685
32800
|
const startTime = Date.now();
|
|
32686
32801
|
if (!isJsonMode()) {
|
|
32687
|
-
|
|
32802
|
+
intro38(pc45.bold("Update Platform Access Role"));
|
|
32688
32803
|
}
|
|
32689
32804
|
const progress = new DeploymentProgress();
|
|
32690
32805
|
const identity = await progress.execute(
|
|
@@ -32700,11 +32815,11 @@ async function updateRole(options) {
|
|
|
32700
32815
|
if (!metadata) {
|
|
32701
32816
|
progress.stop();
|
|
32702
32817
|
log38.error(
|
|
32703
|
-
`No Wraps deployment found for account ${
|
|
32818
|
+
`No Wraps deployment found for account ${pc45.cyan(identity.accountId)} in region ${pc45.cyan(region)}`
|
|
32704
32819
|
);
|
|
32705
32820
|
console.log(
|
|
32706
32821
|
`
|
|
32707
|
-
Run ${
|
|
32822
|
+
Run ${pc45.cyan("wraps email init")} to deploy infrastructure first.
|
|
32708
32823
|
`
|
|
32709
32824
|
);
|
|
32710
32825
|
process.exit(1);
|
|
@@ -32724,32 +32839,32 @@ Run ${pc44.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
32724
32839
|
const externalId = metadata.platform?.externalId;
|
|
32725
32840
|
if (!(roleExists2 || externalId)) {
|
|
32726
32841
|
progress.stop();
|
|
32727
|
-
log38.warn(`IAM role ${
|
|
32842
|
+
log38.warn(`IAM role ${pc45.cyan(roleName)} does not exist`);
|
|
32728
32843
|
console.log(
|
|
32729
32844
|
"\nThis role is created when you connect AWS accounts through the Wraps Platform."
|
|
32730
32845
|
);
|
|
32731
32846
|
console.log(
|
|
32732
|
-
`Run ${
|
|
32847
|
+
`Run ${pc45.cyan("wraps platform connect")} while logged in to create the role automatically.
|
|
32733
32848
|
`
|
|
32734
32849
|
);
|
|
32735
32850
|
process.exit(0);
|
|
32736
32851
|
}
|
|
32737
32852
|
if (roleExists2) {
|
|
32738
|
-
progress.info(`Found IAM role: ${
|
|
32853
|
+
progress.info(`Found IAM role: ${pc45.cyan(roleName)}`);
|
|
32739
32854
|
} else {
|
|
32740
32855
|
progress.info(
|
|
32741
|
-
`IAM role ${
|
|
32856
|
+
`IAM role ${pc45.cyan(roleName)} not found \u2014 will create it using stored externalId`
|
|
32742
32857
|
);
|
|
32743
32858
|
}
|
|
32744
32859
|
if (!options.force) {
|
|
32745
32860
|
progress.stop();
|
|
32746
32861
|
const actionLabel = roleExists2 ? "Update" : "Create";
|
|
32747
32862
|
const shouldContinue = await confirm20({
|
|
32748
|
-
message: `${actionLabel} IAM role ${
|
|
32863
|
+
message: `${actionLabel} IAM role ${pc45.cyan(roleName)} with latest permissions?`,
|
|
32749
32864
|
initialValue: true
|
|
32750
32865
|
});
|
|
32751
|
-
if (
|
|
32752
|
-
|
|
32866
|
+
if (isCancel28(shouldContinue) || !shouldContinue) {
|
|
32867
|
+
outro25(`${actionLabel} cancelled`);
|
|
32753
32868
|
process.exit(0);
|
|
32754
32869
|
}
|
|
32755
32870
|
}
|
|
@@ -32813,6 +32928,34 @@ Run ${pc44.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
32813
32928
|
})
|
|
32814
32929
|
);
|
|
32815
32930
|
});
|
|
32931
|
+
if (externalId) {
|
|
32932
|
+
const WRAPS_PLATFORM_ACCOUNT_ID2 = "905130073023";
|
|
32933
|
+
const trustPolicy = {
|
|
32934
|
+
Version: "2012-10-17",
|
|
32935
|
+
Statement: [
|
|
32936
|
+
{
|
|
32937
|
+
Effect: "Allow",
|
|
32938
|
+
Principal: {
|
|
32939
|
+
AWS: `arn:aws:iam::${WRAPS_PLATFORM_ACCOUNT_ID2}:root`
|
|
32940
|
+
},
|
|
32941
|
+
Action: "sts:AssumeRole",
|
|
32942
|
+
Condition: {
|
|
32943
|
+
StringEquals: {
|
|
32944
|
+
"sts:ExternalId": externalId
|
|
32945
|
+
}
|
|
32946
|
+
}
|
|
32947
|
+
}
|
|
32948
|
+
]
|
|
32949
|
+
};
|
|
32950
|
+
await progress.execute("Repairing trust policy", async () => {
|
|
32951
|
+
await iam11.send(
|
|
32952
|
+
new UpdateAssumeRolePolicyCommand2({
|
|
32953
|
+
RoleName: roleName,
|
|
32954
|
+
PolicyDocument: JSON.stringify(trustPolicy)
|
|
32955
|
+
})
|
|
32956
|
+
);
|
|
32957
|
+
});
|
|
32958
|
+
}
|
|
32816
32959
|
}
|
|
32817
32960
|
progress.stop();
|
|
32818
32961
|
const actionVerb = roleExists2 ? "updated" : "created";
|
|
@@ -32829,51 +32972,51 @@ Run ${pc44.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
32829
32972
|
});
|
|
32830
32973
|
return;
|
|
32831
32974
|
}
|
|
32832
|
-
|
|
32975
|
+
outro25(pc45.green(`\u2713 Platform access role ${actionVerb} successfully`));
|
|
32833
32976
|
console.log(`
|
|
32834
|
-
${
|
|
32977
|
+
${pc45.bold("Permissions:")}`);
|
|
32835
32978
|
console.log(`
|
|
32836
|
-
${
|
|
32979
|
+
${pc45.bold(pc45.cyan("Email:"))}`);
|
|
32837
32980
|
console.log(
|
|
32838
|
-
` ${
|
|
32981
|
+
` ${pc45.green("\u2713")} SES metrics and identity verification (always enabled)`
|
|
32839
32982
|
);
|
|
32840
|
-
console.log(` ${
|
|
32841
|
-
console.log(` ${
|
|
32983
|
+
console.log(` ${pc45.green("\u2713")} SES template management (always enabled)`);
|
|
32984
|
+
console.log(` ${pc45.green("\u2713")} Inbound bucket detection (always enabled)`);
|
|
32842
32985
|
if (sendingEnabled) {
|
|
32843
|
-
console.log(` ${
|
|
32986
|
+
console.log(` ${pc45.green("\u2713")} Email sending via SES`);
|
|
32844
32987
|
}
|
|
32845
32988
|
console.log(
|
|
32846
|
-
` ${
|
|
32989
|
+
` ${pc45.green("\u2713")} DynamoDB read access (including DescribeTable)`
|
|
32847
32990
|
);
|
|
32848
32991
|
if (eventTracking?.enabled) {
|
|
32849
|
-
console.log(` ${
|
|
32992
|
+
console.log(` ${pc45.green("\u2713")} EventBridge and SQS access`);
|
|
32850
32993
|
}
|
|
32851
32994
|
if (emailArchiving?.enabled) {
|
|
32852
|
-
console.log(` ${
|
|
32995
|
+
console.log(` ${pc45.green("\u2713")} Mail Manager Archive access`);
|
|
32853
32996
|
}
|
|
32854
32997
|
const inbound = emailConfig?.inbound;
|
|
32855
32998
|
if (inbound?.enabled) {
|
|
32856
|
-
console.log(` ${
|
|
32999
|
+
console.log(` ${pc45.green("\u2713")} S3 access for inbound email`);
|
|
32857
33000
|
}
|
|
32858
33001
|
if (smsEnabled) {
|
|
32859
33002
|
console.log(`
|
|
32860
|
-
${
|
|
33003
|
+
${pc45.bold(pc45.cyan("SMS:"))}`);
|
|
32861
33004
|
console.log(
|
|
32862
|
-
` ${
|
|
33005
|
+
` ${pc45.green("\u2713")} SMS Voice V2 read access (phone numbers, config, registrations)`
|
|
32863
33006
|
);
|
|
32864
33007
|
if (smsSendingEnabled) {
|
|
32865
|
-
console.log(` ${
|
|
33008
|
+
console.log(` ${pc45.green("\u2713")} SMS sending via SMS Voice V2`);
|
|
32866
33009
|
}
|
|
32867
33010
|
if (smsEventTracking?.dynamoDBHistory) {
|
|
32868
|
-
console.log(` ${
|
|
33011
|
+
console.log(` ${pc45.green("\u2713")} DynamoDB read access for SMS history`);
|
|
32869
33012
|
}
|
|
32870
33013
|
if (smsEventTracking?.enabled) {
|
|
32871
|
-
console.log(` ${
|
|
33014
|
+
console.log(` ${pc45.green("\u2713")} SNS topic access for SMS events`);
|
|
32872
33015
|
}
|
|
32873
33016
|
}
|
|
32874
33017
|
console.log(
|
|
32875
33018
|
`
|
|
32876
|
-
${
|
|
33019
|
+
${pc45.dim(`The Wraps Platform will now have ${actionVerb} permissions for feature detection.`)}
|
|
32877
33020
|
`
|
|
32878
33021
|
);
|
|
32879
33022
|
}
|
|
@@ -33071,9 +33214,9 @@ import { execSync as execSync2 } from "child_process";
|
|
|
33071
33214
|
import { randomBytes as randomBytes6 } from "crypto";
|
|
33072
33215
|
import { join as join20 } from "path";
|
|
33073
33216
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
33074
|
-
import * as
|
|
33217
|
+
import * as clack43 from "@clack/prompts";
|
|
33075
33218
|
import * as pulumi26 from "@pulumi/pulumi";
|
|
33076
|
-
import
|
|
33219
|
+
import pc46 from "picocolors";
|
|
33077
33220
|
|
|
33078
33221
|
// src/infrastructure/selfhost-stack.ts
|
|
33079
33222
|
init_esm_shims();
|
|
@@ -33341,7 +33484,7 @@ var repoRoot = join20(__filename2, "../../../..");
|
|
|
33341
33484
|
async function selfhostDeploy(options) {
|
|
33342
33485
|
const startTime = Date.now();
|
|
33343
33486
|
if (!isJsonMode()) {
|
|
33344
|
-
|
|
33487
|
+
clack43.intro(pc46.bold("Wraps Self-Hosted Control Plane Deploy"));
|
|
33345
33488
|
}
|
|
33346
33489
|
const progress = new DeploymentProgress();
|
|
33347
33490
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -33356,24 +33499,24 @@ async function selfhostDeploy(options) {
|
|
|
33356
33499
|
async () => validateAWSCredentialsWithDetails()
|
|
33357
33500
|
);
|
|
33358
33501
|
const identity = credentialResult.identity;
|
|
33359
|
-
progress.info(`Connected to AWS account: ${
|
|
33502
|
+
progress.info(`Connected to AWS account: ${pc46.cyan(identity.accountId)}`);
|
|
33360
33503
|
for (const warning of credentialResult.warnings) {
|
|
33361
|
-
|
|
33504
|
+
clack43.log.warn(warning);
|
|
33362
33505
|
}
|
|
33363
33506
|
if (credentialResult.credentialSource) {
|
|
33364
33507
|
progress.info(
|
|
33365
|
-
`Using credentials from: ${
|
|
33508
|
+
`Using credentials from: ${pc46.dim(credentialResult.credentialSource)}`
|
|
33366
33509
|
);
|
|
33367
33510
|
}
|
|
33368
33511
|
let region = options.region;
|
|
33369
33512
|
if (!region) {
|
|
33370
|
-
const regionAnswer = await
|
|
33513
|
+
const regionAnswer = await clack43.text({
|
|
33371
33514
|
message: "AWS region to deploy into:",
|
|
33372
33515
|
defaultValue: "us-east-1",
|
|
33373
33516
|
placeholder: "us-east-1"
|
|
33374
33517
|
});
|
|
33375
|
-
if (
|
|
33376
|
-
|
|
33518
|
+
if (clack43.isCancel(regionAnswer)) {
|
|
33519
|
+
clack43.cancel("Operation cancelled.");
|
|
33377
33520
|
process.exit(0);
|
|
33378
33521
|
}
|
|
33379
33522
|
region = regionAnswer || "us-east-1";
|
|
@@ -33383,61 +33526,61 @@ async function selfhostDeploy(options) {
|
|
|
33383
33526
|
region
|
|
33384
33527
|
);
|
|
33385
33528
|
if (existingMetadata?.services?.selfhost) {
|
|
33386
|
-
|
|
33387
|
-
`Self-hosted deployment already exists for account ${
|
|
33529
|
+
clack43.log.warn(
|
|
33530
|
+
`Self-hosted deployment already exists for account ${pc46.cyan(identity.accountId)} in region ${pc46.cyan(region)}`
|
|
33388
33531
|
);
|
|
33389
|
-
|
|
33390
|
-
`API URL: ${
|
|
33532
|
+
clack43.log.info(
|
|
33533
|
+
`API URL: ${pc46.cyan(existingMetadata.services.selfhost.apiUrl)}`
|
|
33391
33534
|
);
|
|
33392
|
-
|
|
33535
|
+
clack43.log.info(
|
|
33393
33536
|
`Deployed: ${existingMetadata.services.selfhost.deployedAt}`
|
|
33394
33537
|
);
|
|
33395
|
-
|
|
33538
|
+
clack43.log.info(`To update: run ${pc46.cyan("wraps selfhost upgrade")}`);
|
|
33396
33539
|
process.exit(0);
|
|
33397
33540
|
}
|
|
33398
33541
|
let neonApiKey = options.neonApiKey;
|
|
33399
33542
|
if (!neonApiKey) {
|
|
33400
|
-
const neonApiKeyAnswer = await
|
|
33543
|
+
const neonApiKeyAnswer = await clack43.password({
|
|
33401
33544
|
message: "Neon API key (create one at console.neon.tech/app/settings/api-keys):"
|
|
33402
33545
|
});
|
|
33403
|
-
if (
|
|
33404
|
-
|
|
33546
|
+
if (clack43.isCancel(neonApiKeyAnswer)) {
|
|
33547
|
+
clack43.cancel("Operation cancelled.");
|
|
33405
33548
|
process.exit(0);
|
|
33406
33549
|
}
|
|
33407
33550
|
neonApiKey = neonApiKeyAnswer;
|
|
33408
33551
|
}
|
|
33409
33552
|
let licenseKey = options.licenseKey;
|
|
33410
33553
|
if (!licenseKey) {
|
|
33411
|
-
const licenseKeyAnswer = await
|
|
33554
|
+
const licenseKeyAnswer = await clack43.text({
|
|
33412
33555
|
message: "Wraps enterprise license key:",
|
|
33413
33556
|
placeholder: "wraps_lic_..."
|
|
33414
33557
|
});
|
|
33415
|
-
if (
|
|
33416
|
-
|
|
33558
|
+
if (clack43.isCancel(licenseKeyAnswer)) {
|
|
33559
|
+
clack43.cancel("Operation cancelled.");
|
|
33417
33560
|
process.exit(0);
|
|
33418
33561
|
}
|
|
33419
33562
|
licenseKey = licenseKeyAnswer;
|
|
33420
33563
|
}
|
|
33421
33564
|
let appUrl = options.appUrl;
|
|
33422
33565
|
if (!appUrl) {
|
|
33423
|
-
const appUrlAnswer = await
|
|
33566
|
+
const appUrlAnswer = await clack43.text({
|
|
33424
33567
|
message: "App URL (where your self-hosted dashboard will be served):",
|
|
33425
33568
|
defaultValue: "https://app.wraps.dev",
|
|
33426
33569
|
placeholder: "https://app.yourcompany.com"
|
|
33427
33570
|
});
|
|
33428
|
-
if (
|
|
33429
|
-
|
|
33571
|
+
if (clack43.isCancel(appUrlAnswer)) {
|
|
33572
|
+
clack43.cancel("Operation cancelled.");
|
|
33430
33573
|
process.exit(0);
|
|
33431
33574
|
}
|
|
33432
33575
|
appUrl = appUrlAnswer || "https://app.wraps.dev";
|
|
33433
33576
|
}
|
|
33434
33577
|
if (!(options.yes || options.preview)) {
|
|
33435
|
-
const confirmed = await
|
|
33436
|
-
message: `Deploy self-hosted Wraps API to ${
|
|
33578
|
+
const confirmed = await clack43.confirm({
|
|
33579
|
+
message: `Deploy self-hosted Wraps API to ${pc46.cyan(identity.accountId)} / ${pc46.cyan(region)}?`,
|
|
33437
33580
|
initialValue: true
|
|
33438
33581
|
});
|
|
33439
|
-
if (
|
|
33440
|
-
|
|
33582
|
+
if (clack43.isCancel(confirmed) || !confirmed) {
|
|
33583
|
+
clack43.cancel("Deployment cancelled.");
|
|
33441
33584
|
process.exit(0);
|
|
33442
33585
|
}
|
|
33443
33586
|
}
|
|
@@ -33461,7 +33604,7 @@ async function selfhostDeploy(options) {
|
|
|
33461
33604
|
buildNeonProjectName(identity.accountId, region)
|
|
33462
33605
|
)
|
|
33463
33606
|
);
|
|
33464
|
-
progress.info(`Neon project created: ${
|
|
33607
|
+
progress.info(`Neon project created: ${pc46.cyan(neonProject.name)}`);
|
|
33465
33608
|
const unsubscribeSecret = randomBytes6(32).toString("hex");
|
|
33466
33609
|
const betterAuthSecret = randomBytes6(32).toString("hex");
|
|
33467
33610
|
const selfhostConfig = {
|
|
@@ -33564,8 +33707,8 @@ async function selfhostDeploy(options) {
|
|
|
33564
33707
|
resourceChanges: previewResult.resourceChanges,
|
|
33565
33708
|
commandName: "wraps selfhost deploy"
|
|
33566
33709
|
});
|
|
33567
|
-
|
|
33568
|
-
|
|
33710
|
+
clack43.outro(
|
|
33711
|
+
pc46.green("Preview complete. Run without --preview to deploy.")
|
|
33569
33712
|
);
|
|
33570
33713
|
return;
|
|
33571
33714
|
} catch (error) {
|
|
@@ -33630,23 +33773,23 @@ async function selfhostDeploy(options) {
|
|
|
33630
33773
|
return;
|
|
33631
33774
|
}
|
|
33632
33775
|
console.log("\n");
|
|
33633
|
-
|
|
33776
|
+
clack43.log.success(pc46.green(pc46.bold("Self-hosted Wraps API deployed!")));
|
|
33634
33777
|
console.log("\n");
|
|
33635
|
-
|
|
33778
|
+
clack43.note(
|
|
33636
33779
|
[
|
|
33637
|
-
`${
|
|
33638
|
-
`${
|
|
33639
|
-
`${
|
|
33640
|
-
`${
|
|
33780
|
+
`${pc46.bold("API URL:")} ${pc46.cyan(outputs.apiUrl)}`,
|
|
33781
|
+
`${pc46.bold("Region:")} ${pc46.cyan(region)}`,
|
|
33782
|
+
`${pc46.bold("Lambda ARN:")} ${pc46.dim(outputs.lambdaArn)}`,
|
|
33783
|
+
`${pc46.bold("Neon Project:")} ${pc46.dim(neonProject.id)}`,
|
|
33641
33784
|
"",
|
|
33642
|
-
|
|
33643
|
-
|
|
33644
|
-
|
|
33785
|
+
pc46.dim("Next steps:"),
|
|
33786
|
+
pc46.dim(` Set WRAPS_API_URL=${outputs.apiUrl} in your app`),
|
|
33787
|
+
pc46.dim(" Run: wraps selfhost status")
|
|
33645
33788
|
].join("\n"),
|
|
33646
33789
|
"Self-Hosted Deployment"
|
|
33647
33790
|
);
|
|
33648
|
-
|
|
33649
|
-
|
|
33791
|
+
clack43.outro(
|
|
33792
|
+
pc46.green(`Deployed in ${((Date.now() - startTime) / 1e3).toFixed(1)}s`)
|
|
33650
33793
|
);
|
|
33651
33794
|
}
|
|
33652
33795
|
|
|
@@ -33658,28 +33801,28 @@ init_json_output();
|
|
|
33658
33801
|
init_metadata();
|
|
33659
33802
|
init_output();
|
|
33660
33803
|
init_region_resolver();
|
|
33661
|
-
import * as
|
|
33662
|
-
import
|
|
33804
|
+
import * as clack44 from "@clack/prompts";
|
|
33805
|
+
import pc47 from "picocolors";
|
|
33663
33806
|
function displaySelfhostStatus(options) {
|
|
33664
33807
|
const lines = [];
|
|
33665
|
-
lines.push(
|
|
33808
|
+
lines.push(pc47.bold(pc47.green("Self-Hosted Control Plane Active")));
|
|
33666
33809
|
lines.push("");
|
|
33667
|
-
lines.push(
|
|
33668
|
-
lines.push(` URL: ${
|
|
33669
|
-
lines.push(` Region: ${
|
|
33670
|
-
lines.push(` Deployed: ${
|
|
33810
|
+
lines.push(pc47.bold("API"));
|
|
33811
|
+
lines.push(` URL: ${pc47.cyan(options.apiUrl)}`);
|
|
33812
|
+
lines.push(` Region: ${pc47.cyan(options.region)}`);
|
|
33813
|
+
lines.push(` Deployed: ${pc47.dim(options.deployedAt)}`);
|
|
33671
33814
|
lines.push("");
|
|
33672
|
-
lines.push(
|
|
33673
|
-
lines.push(` App URL: ${
|
|
33674
|
-
lines.push(` License Key: ${
|
|
33675
|
-
lines.push(` Neon Project: ${
|
|
33676
|
-
|
|
33815
|
+
lines.push(pc47.bold("Configuration"));
|
|
33816
|
+
lines.push(` App URL: ${pc47.cyan(options.appUrl)}`);
|
|
33817
|
+
lines.push(` License Key: ${pc47.dim(`${options.licenseKeyPrefix}...`)}`);
|
|
33818
|
+
lines.push(` Neon Project: ${pc47.dim(options.neonProjectId)}`);
|
|
33819
|
+
clack44.note(lines.join("\n"), "Self-Hosted Status");
|
|
33677
33820
|
}
|
|
33678
33821
|
async function selfhostStatus(options) {
|
|
33679
33822
|
const startTime = Date.now();
|
|
33680
33823
|
const progress = new DeploymentProgress();
|
|
33681
33824
|
if (!isJsonMode()) {
|
|
33682
|
-
|
|
33825
|
+
clack44.intro(pc47.bold("Wraps Self-Hosted Status"));
|
|
33683
33826
|
}
|
|
33684
33827
|
const identity = await progress.execute(
|
|
33685
33828
|
"Loading self-hosted status",
|
|
@@ -33694,10 +33837,10 @@ async function selfhostStatus(options) {
|
|
|
33694
33837
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
33695
33838
|
if (!metadata?.services?.selfhost) {
|
|
33696
33839
|
progress.stop();
|
|
33697
|
-
|
|
33840
|
+
clack44.log.error("No self-hosted deployment found");
|
|
33698
33841
|
console.log(
|
|
33699
33842
|
`
|
|
33700
|
-
Run ${
|
|
33843
|
+
Run ${pc47.cyan("wraps selfhost deploy")} to deploy the self-hosted control plane.
|
|
33701
33844
|
`
|
|
33702
33845
|
);
|
|
33703
33846
|
process.exit(1);
|
|
@@ -33719,15 +33862,15 @@ Run ${pc46.cyan("wraps selfhost deploy")} to deploy the self-hosted control plan
|
|
|
33719
33862
|
}
|
|
33720
33863
|
displaySelfhostStatus(statusData);
|
|
33721
33864
|
console.log("");
|
|
33722
|
-
|
|
33865
|
+
clack44.log.info(pc47.bold("Commands:"));
|
|
33723
33866
|
console.log(
|
|
33724
|
-
` ${
|
|
33867
|
+
` ${pc47.cyan("wraps selfhost upgrade")} - Rebuild and redeploy the API Lambda`
|
|
33725
33868
|
);
|
|
33726
33869
|
trackCommand("selfhost:status", {
|
|
33727
33870
|
success: true,
|
|
33728
33871
|
duration_ms: Date.now() - startTime
|
|
33729
33872
|
});
|
|
33730
|
-
|
|
33873
|
+
clack44.outro(pc47.dim("Self-hosted deployment is active"));
|
|
33731
33874
|
}
|
|
33732
33875
|
|
|
33733
33876
|
// src/commands/selfhost/upgrade.ts
|
|
@@ -33735,9 +33878,9 @@ init_esm_shims();
|
|
|
33735
33878
|
import { execSync as execSync3 } from "child_process";
|
|
33736
33879
|
import { join as join21 } from "path";
|
|
33737
33880
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
33738
|
-
import * as
|
|
33881
|
+
import * as clack45 from "@clack/prompts";
|
|
33739
33882
|
import * as pulumi27 from "@pulumi/pulumi";
|
|
33740
|
-
import
|
|
33883
|
+
import pc48 from "picocolors";
|
|
33741
33884
|
init_events();
|
|
33742
33885
|
init_aws();
|
|
33743
33886
|
init_errors();
|
|
@@ -33752,7 +33895,7 @@ var repoRoot2 = join21(__filename3, "../../../..");
|
|
|
33752
33895
|
async function selfhostUpgrade(options) {
|
|
33753
33896
|
const startTime = Date.now();
|
|
33754
33897
|
if (!isJsonMode()) {
|
|
33755
|
-
|
|
33898
|
+
clack45.intro(pc48.bold("Wraps Self-Hosted Control Plane Upgrade"));
|
|
33756
33899
|
}
|
|
33757
33900
|
const progress = new DeploymentProgress();
|
|
33758
33901
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -33767,7 +33910,7 @@ async function selfhostUpgrade(options) {
|
|
|
33767
33910
|
async () => validateAWSCredentialsWithDetails()
|
|
33768
33911
|
);
|
|
33769
33912
|
const identity = credentialResult.identity;
|
|
33770
|
-
progress.info(`Connected to AWS account: ${
|
|
33913
|
+
progress.info(`Connected to AWS account: ${pc48.cyan(identity.accountId)}`);
|
|
33771
33914
|
const region = await resolveRegionForCommand({
|
|
33772
33915
|
accountId: identity.accountId,
|
|
33773
33916
|
optionRegion: options.region,
|
|
@@ -33776,20 +33919,20 @@ async function selfhostUpgrade(options) {
|
|
|
33776
33919
|
});
|
|
33777
33920
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
33778
33921
|
if (!metadata?.services?.selfhost) {
|
|
33779
|
-
|
|
33780
|
-
|
|
33922
|
+
clack45.log.error("No self-hosted deployment found.");
|
|
33923
|
+
clack45.log.info(`Run ${pc48.cyan("wraps selfhost deploy")} first.`);
|
|
33781
33924
|
process.exit(1);
|
|
33782
33925
|
}
|
|
33783
33926
|
const selfhostService = metadata.services.selfhost;
|
|
33784
33927
|
progress.info(`Found deployment from: ${selfhostService.deployedAt}`);
|
|
33785
|
-
progress.info(`API URL: ${
|
|
33928
|
+
progress.info(`API URL: ${pc48.cyan(selfhostService.apiUrl)}`);
|
|
33786
33929
|
if (!(options.yes || options.preview)) {
|
|
33787
|
-
const confirmed = await
|
|
33788
|
-
message: `Upgrade self-hosted deployment in ${
|
|
33930
|
+
const confirmed = await clack45.confirm({
|
|
33931
|
+
message: `Upgrade self-hosted deployment in ${pc48.cyan(identity.accountId)} / ${pc48.cyan(region)}?`,
|
|
33789
33932
|
initialValue: true
|
|
33790
33933
|
});
|
|
33791
|
-
if (
|
|
33792
|
-
|
|
33934
|
+
if (clack45.isCancel(confirmed) || !confirmed) {
|
|
33935
|
+
clack45.cancel("Upgrade cancelled.");
|
|
33793
33936
|
process.exit(0);
|
|
33794
33937
|
}
|
|
33795
33938
|
}
|
|
@@ -33870,8 +34013,8 @@ async function selfhostUpgrade(options) {
|
|
|
33870
34013
|
resourceChanges: previewResult.resourceChanges,
|
|
33871
34014
|
commandName: "wraps selfhost upgrade"
|
|
33872
34015
|
});
|
|
33873
|
-
|
|
33874
|
-
|
|
34016
|
+
clack45.outro(
|
|
34017
|
+
pc48.green("Preview complete. Run without --preview to upgrade.")
|
|
33875
34018
|
);
|
|
33876
34019
|
return;
|
|
33877
34020
|
} catch (error) {
|
|
@@ -33942,28 +34085,28 @@ async function selfhostUpgrade(options) {
|
|
|
33942
34085
|
}
|
|
33943
34086
|
progress.info("Deployment metadata updated");
|
|
33944
34087
|
console.log("\n");
|
|
33945
|
-
|
|
34088
|
+
clack45.log.success(pc48.green(pc48.bold("Self-hosted Wraps API upgraded!")));
|
|
33946
34089
|
console.log("\n");
|
|
33947
|
-
|
|
34090
|
+
clack45.note(
|
|
33948
34091
|
[
|
|
33949
|
-
`${
|
|
33950
|
-
`${
|
|
33951
|
-
`${
|
|
34092
|
+
`${pc48.bold("API URL:")} ${pc48.cyan(outputs.apiUrl || selfhostService.apiUrl)}`,
|
|
34093
|
+
`${pc48.bold("Region:")} ${pc48.cyan(region)}`,
|
|
34094
|
+
`${pc48.bold("Lambda ARN:")} ${pc48.dim(outputs.lambdaArn)}`
|
|
33952
34095
|
].join("\n"),
|
|
33953
34096
|
"Self-Hosted Deployment"
|
|
33954
34097
|
);
|
|
33955
|
-
|
|
33956
|
-
|
|
34098
|
+
clack45.outro(
|
|
34099
|
+
pc48.green(`Upgraded in ${((Date.now() - startTime) / 1e3).toFixed(1)}s`)
|
|
33957
34100
|
);
|
|
33958
34101
|
}
|
|
33959
34102
|
|
|
33960
34103
|
// src/commands/shared/dashboard.ts
|
|
33961
34104
|
init_esm_shims();
|
|
33962
|
-
import * as
|
|
34105
|
+
import * as clack46 from "@clack/prompts";
|
|
33963
34106
|
import * as pulumi28 from "@pulumi/pulumi";
|
|
33964
34107
|
import getPort from "get-port";
|
|
33965
34108
|
import open2 from "open";
|
|
33966
|
-
import
|
|
34109
|
+
import pc49 from "picocolors";
|
|
33967
34110
|
|
|
33968
34111
|
// src/console/server.ts
|
|
33969
34112
|
init_esm_shims();
|
|
@@ -36617,7 +36760,7 @@ init_output();
|
|
|
36617
36760
|
init_pulumi();
|
|
36618
36761
|
async function dashboard(options) {
|
|
36619
36762
|
await ensurePulumiInstalled();
|
|
36620
|
-
|
|
36763
|
+
clack46.intro(pc49.bold("Wraps Dashboard"));
|
|
36621
36764
|
const progress = new DeploymentProgress();
|
|
36622
36765
|
const identity = await progress.execute(
|
|
36623
36766
|
"Validating AWS credentials",
|
|
@@ -36658,9 +36801,9 @@ async function dashboard(options) {
|
|
|
36658
36801
|
}
|
|
36659
36802
|
} catch (_error) {
|
|
36660
36803
|
progress.stop();
|
|
36661
|
-
|
|
36804
|
+
clack46.log.error("No Wraps infrastructure found");
|
|
36662
36805
|
console.log(
|
|
36663
|
-
`\\nRun ${
|
|
36806
|
+
`\\nRun ${pc49.cyan("wraps email init")}, ${pc49.cyan("wraps sms init")}, or ${pc49.cyan("wraps storage init")} to deploy infrastructure first.\\n`
|
|
36664
36807
|
);
|
|
36665
36808
|
process.exit(1);
|
|
36666
36809
|
}
|
|
@@ -36702,9 +36845,9 @@ async function dashboard(options) {
|
|
|
36702
36845
|
}
|
|
36703
36846
|
const port = options.port || await getPort({ port: [5555, 5556, 5557, 5558, 5559] });
|
|
36704
36847
|
progress.stop();
|
|
36705
|
-
|
|
36848
|
+
clack46.log.success("Starting dashboard server...");
|
|
36706
36849
|
console.log(
|
|
36707
|
-
`${
|
|
36850
|
+
`${pc49.dim("Using current AWS credentials (no role assumption)")}\\n`
|
|
36708
36851
|
);
|
|
36709
36852
|
const { url } = await startConsoleServer({
|
|
36710
36853
|
port,
|
|
@@ -36737,8 +36880,8 @@ async function dashboard(options) {
|
|
|
36737
36880
|
cdnCustomDomain,
|
|
36738
36881
|
cdnCertificateArn
|
|
36739
36882
|
});
|
|
36740
|
-
console.log(`\\n${
|
|
36741
|
-
console.log(`${
|
|
36883
|
+
console.log(`\\n${pc49.bold("Dashboard:")} ${pc49.cyan(url)}`);
|
|
36884
|
+
console.log(`${pc49.dim("Press Ctrl+C to stop")}\\n`);
|
|
36742
36885
|
getTelemetryClient().showFooterOnce();
|
|
36743
36886
|
if (!options.noOpen) {
|
|
36744
36887
|
await open2(url);
|
|
@@ -36759,8 +36902,8 @@ init_aws();
|
|
|
36759
36902
|
init_errors();
|
|
36760
36903
|
init_json_output();
|
|
36761
36904
|
init_metadata();
|
|
36762
|
-
import * as
|
|
36763
|
-
import
|
|
36905
|
+
import * as clack47 from "@clack/prompts";
|
|
36906
|
+
import pc50 from "picocolors";
|
|
36764
36907
|
async function destroy(options) {
|
|
36765
36908
|
trackCommand("destroy", { success: true });
|
|
36766
36909
|
if (isJsonMode() && !options.force) {
|
|
@@ -36771,9 +36914,9 @@ async function destroy(options) {
|
|
|
36771
36914
|
);
|
|
36772
36915
|
}
|
|
36773
36916
|
if (!isJsonMode()) {
|
|
36774
|
-
|
|
36917
|
+
clack47.intro(pc50.bold("Wraps Infrastructure Teardown"));
|
|
36775
36918
|
}
|
|
36776
|
-
const spinner10 =
|
|
36919
|
+
const spinner10 = clack47.spinner();
|
|
36777
36920
|
spinner10.start("Validating AWS credentials");
|
|
36778
36921
|
let identity;
|
|
36779
36922
|
try {
|
|
@@ -36790,17 +36933,17 @@ async function destroy(options) {
|
|
|
36790
36933
|
deployedServices.push("email");
|
|
36791
36934
|
}
|
|
36792
36935
|
if (deployedServices.length === 0) {
|
|
36793
|
-
|
|
36936
|
+
clack47.log.warn("No Wraps services found in this region");
|
|
36794
36937
|
console.log(
|
|
36795
36938
|
`
|
|
36796
|
-
Run ${
|
|
36939
|
+
Run ${pc50.cyan("wraps email init")} to deploy infrastructure.
|
|
36797
36940
|
`
|
|
36798
36941
|
);
|
|
36799
36942
|
process.exit(0);
|
|
36800
36943
|
}
|
|
36801
36944
|
if (deployedServices.length === 1) {
|
|
36802
36945
|
const service = deployedServices[0];
|
|
36803
|
-
|
|
36946
|
+
clack47.log.info(`Found ${pc50.cyan(service)} service deployed`);
|
|
36804
36947
|
if (service === "email") {
|
|
36805
36948
|
await emailDestroy(options);
|
|
36806
36949
|
return;
|
|
@@ -36815,7 +36958,7 @@ Run ${pc49.cyan("wraps email init")} to deploy infrastructure.
|
|
|
36815
36958
|
jsonSuccess("destroy", { destroyed: true });
|
|
36816
36959
|
return;
|
|
36817
36960
|
}
|
|
36818
|
-
const serviceToDestroy = await
|
|
36961
|
+
const serviceToDestroy = await clack47.select({
|
|
36819
36962
|
message: "Which service would you like to destroy?",
|
|
36820
36963
|
options: [
|
|
36821
36964
|
...deployedServices.map((s) => ({
|
|
@@ -36830,15 +36973,15 @@ Run ${pc49.cyan("wraps email init")} to deploy infrastructure.
|
|
|
36830
36973
|
}
|
|
36831
36974
|
]
|
|
36832
36975
|
});
|
|
36833
|
-
if (
|
|
36834
|
-
|
|
36976
|
+
if (clack47.isCancel(serviceToDestroy)) {
|
|
36977
|
+
clack47.cancel("Operation cancelled.");
|
|
36835
36978
|
process.exit(0);
|
|
36836
36979
|
}
|
|
36837
36980
|
if ((serviceToDestroy === "email" || serviceToDestroy === "all") && deployedServices.includes("email")) {
|
|
36838
36981
|
await emailDestroy(options);
|
|
36839
36982
|
}
|
|
36840
36983
|
if (serviceToDestroy === "all") {
|
|
36841
|
-
|
|
36984
|
+
clack47.outro(pc50.green("All Wraps infrastructure has been removed"));
|
|
36842
36985
|
}
|
|
36843
36986
|
}
|
|
36844
36987
|
|
|
@@ -36850,26 +36993,26 @@ init_fs();
|
|
|
36850
36993
|
init_json_output();
|
|
36851
36994
|
init_output();
|
|
36852
36995
|
init_pulumi();
|
|
36853
|
-
import * as
|
|
36996
|
+
import * as clack48 from "@clack/prompts";
|
|
36854
36997
|
import * as pulumi29 from "@pulumi/pulumi";
|
|
36855
|
-
import
|
|
36998
|
+
import pc51 from "picocolors";
|
|
36856
36999
|
async function status(options) {
|
|
36857
37000
|
await ensurePulumiInstalled();
|
|
36858
37001
|
const startTime = Date.now();
|
|
36859
37002
|
const progress = new DeploymentProgress();
|
|
36860
37003
|
if (!isJsonMode()) {
|
|
36861
|
-
|
|
37004
|
+
clack48.intro(pc51.bold("Wraps Infrastructure Status"));
|
|
36862
37005
|
}
|
|
36863
37006
|
const identity = await progress.execute(
|
|
36864
37007
|
"Loading infrastructure status",
|
|
36865
37008
|
async () => validateAWSCredentials()
|
|
36866
37009
|
);
|
|
36867
37010
|
if (!isJsonMode()) {
|
|
36868
|
-
progress.info(`AWS Account: ${
|
|
37011
|
+
progress.info(`AWS Account: ${pc51.cyan(identity.accountId)}`);
|
|
36869
37012
|
}
|
|
36870
37013
|
const region = options.region || await getAWSRegion();
|
|
36871
37014
|
if (!isJsonMode()) {
|
|
36872
|
-
progress.info(`Region: ${
|
|
37015
|
+
progress.info(`Region: ${pc51.cyan(region)}`);
|
|
36873
37016
|
}
|
|
36874
37017
|
const services = [];
|
|
36875
37018
|
try {
|
|
@@ -36921,35 +37064,35 @@ async function status(options) {
|
|
|
36921
37064
|
return;
|
|
36922
37065
|
}
|
|
36923
37066
|
console.log();
|
|
36924
|
-
|
|
37067
|
+
clack48.note(
|
|
36925
37068
|
services.map((s) => {
|
|
36926
37069
|
if (s.status === "deployed") {
|
|
36927
|
-
const details = s.details ?
|
|
36928
|
-
return ` ${
|
|
37070
|
+
const details = s.details ? pc51.dim(` (${s.details})`) : "";
|
|
37071
|
+
return ` ${pc51.green("\u2713")} ${s.name}${details}`;
|
|
36929
37072
|
}
|
|
36930
|
-
return ` ${
|
|
37073
|
+
return ` ${pc51.dim("\u25CB")} ${s.name} ${pc51.dim("(not deployed)")}`;
|
|
36931
37074
|
}).join("\n"),
|
|
36932
37075
|
"Services"
|
|
36933
37076
|
);
|
|
36934
37077
|
const hasDeployedServices = services.some((s) => s.status === "deployed");
|
|
36935
37078
|
if (hasDeployedServices) {
|
|
36936
37079
|
console.log(`
|
|
36937
|
-
${
|
|
37080
|
+
${pc51.bold("Details:")}`);
|
|
36938
37081
|
if (services.find((s) => s.name === "Email")?.status === "deployed") {
|
|
36939
|
-
console.log(` ${
|
|
37082
|
+
console.log(` ${pc51.dim("Email:")} ${pc51.cyan("wraps email status")}`);
|
|
36940
37083
|
}
|
|
36941
37084
|
if (services.find((s) => s.name === "SMS")?.status === "deployed") {
|
|
36942
|
-
console.log(` ${
|
|
37085
|
+
console.log(` ${pc51.dim("SMS:")} ${pc51.cyan("wraps sms status")}`);
|
|
36943
37086
|
}
|
|
36944
37087
|
} else {
|
|
36945
37088
|
console.log(`
|
|
36946
|
-
${
|
|
36947
|
-
console.log(` ${
|
|
36948
|
-
console.log(` ${
|
|
37089
|
+
${pc51.bold("Get started:")}`);
|
|
37090
|
+
console.log(` ${pc51.dim("Deploy email:")} ${pc51.cyan("wraps email init")}`);
|
|
37091
|
+
console.log(` ${pc51.dim("Deploy SMS:")} ${pc51.cyan("wraps sms init")}`);
|
|
36949
37092
|
}
|
|
36950
37093
|
console.log(`
|
|
36951
|
-
${
|
|
36952
|
-
console.log(`${
|
|
37094
|
+
${pc51.bold("Dashboard:")} ${pc51.blue("https://app.wraps.dev")}`);
|
|
37095
|
+
console.log(`${pc51.bold("Docs:")} ${pc51.blue("https://wraps.dev/docs")}
|
|
36953
37096
|
`);
|
|
36954
37097
|
trackCommand("status", {
|
|
36955
37098
|
success: true,
|
|
@@ -36960,9 +37103,9 @@ ${pc50.bold("Dashboard:")} ${pc50.blue("https://app.wraps.dev")}`);
|
|
|
36960
37103
|
|
|
36961
37104
|
// src/commands/sms/destroy.ts
|
|
36962
37105
|
init_esm_shims();
|
|
36963
|
-
import * as
|
|
37106
|
+
import * as clack49 from "@clack/prompts";
|
|
36964
37107
|
import * as pulumi31 from "@pulumi/pulumi";
|
|
36965
|
-
import
|
|
37108
|
+
import pc52 from "picocolors";
|
|
36966
37109
|
|
|
36967
37110
|
// src/infrastructure/sms-stack.ts
|
|
36968
37111
|
init_esm_shims();
|
|
@@ -37653,18 +37796,18 @@ async function createSMSProtectConfigurationWithSDK(configurationSetName, region
|
|
|
37653
37796
|
const existing = await client.send(
|
|
37654
37797
|
new DescribeProtectConfigurationsCommand({})
|
|
37655
37798
|
);
|
|
37656
|
-
for (const
|
|
37657
|
-
if (!(
|
|
37799
|
+
for (const pc65 of existing.ProtectConfigurations || []) {
|
|
37800
|
+
if (!(pc65.ProtectConfigurationArn && pc65.ProtectConfigurationId)) {
|
|
37658
37801
|
continue;
|
|
37659
37802
|
}
|
|
37660
37803
|
const tagsResponse = await client.send(
|
|
37661
37804
|
new ListTagsForResourceCommand({
|
|
37662
|
-
ResourceArn:
|
|
37805
|
+
ResourceArn: pc65.ProtectConfigurationArn
|
|
37663
37806
|
})
|
|
37664
37807
|
);
|
|
37665
37808
|
const nameTag = tagsResponse.Tags?.find((t) => t.Key === "Name");
|
|
37666
37809
|
if (nameTag?.Value === protectConfigName) {
|
|
37667
|
-
existingProtectConfigId =
|
|
37810
|
+
existingProtectConfigId = pc65.ProtectConfigurationId;
|
|
37668
37811
|
break;
|
|
37669
37812
|
}
|
|
37670
37813
|
}
|
|
@@ -37760,13 +37903,13 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
|
|
|
37760
37903
|
new DescribeProtectConfigurationsCommand({})
|
|
37761
37904
|
);
|
|
37762
37905
|
if (existing.ProtectConfigurations) {
|
|
37763
|
-
for (const
|
|
37764
|
-
if (!(
|
|
37906
|
+
for (const pc65 of existing.ProtectConfigurations) {
|
|
37907
|
+
if (!(pc65.ProtectConfigurationArn && pc65.ProtectConfigurationId)) {
|
|
37765
37908
|
continue;
|
|
37766
37909
|
}
|
|
37767
37910
|
const tagsResponse = await client.send(
|
|
37768
37911
|
new ListTagsForResourceCommand({
|
|
37769
|
-
ResourceArn:
|
|
37912
|
+
ResourceArn: pc65.ProtectConfigurationArn
|
|
37770
37913
|
})
|
|
37771
37914
|
);
|
|
37772
37915
|
const isWrapsManaged = tagsResponse.Tags?.some(
|
|
@@ -37775,7 +37918,7 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
|
|
|
37775
37918
|
if (isWrapsManaged) {
|
|
37776
37919
|
await client.send(
|
|
37777
37920
|
new DeleteProtectConfigurationCommand({
|
|
37778
|
-
ProtectConfigurationId:
|
|
37921
|
+
ProtectConfigurationId: pc65.ProtectConfigurationId
|
|
37779
37922
|
})
|
|
37780
37923
|
);
|
|
37781
37924
|
}
|
|
@@ -37810,8 +37953,8 @@ async function smsDestroy(options) {
|
|
|
37810
37953
|
);
|
|
37811
37954
|
}
|
|
37812
37955
|
if (!isJsonMode()) {
|
|
37813
|
-
|
|
37814
|
-
|
|
37956
|
+
clack49.intro(
|
|
37957
|
+
pc52.bold(
|
|
37815
37958
|
options.preview ? "SMS Infrastructure Destruction Preview" : "SMS Infrastructure Teardown"
|
|
37816
37959
|
)
|
|
37817
37960
|
);
|
|
@@ -37837,15 +37980,15 @@ async function smsDestroy(options) {
|
|
|
37837
37980
|
`Available regions: ${smsConnections.map((c) => c.region).join(", ")}`
|
|
37838
37981
|
);
|
|
37839
37982
|
}
|
|
37840
|
-
const selectedRegion = await
|
|
37983
|
+
const selectedRegion = await clack49.select({
|
|
37841
37984
|
message: "Multiple SMS deployments found. Which region to destroy?",
|
|
37842
37985
|
options: smsConnections.map((conn) => ({
|
|
37843
37986
|
value: conn.region,
|
|
37844
37987
|
label: conn.region
|
|
37845
37988
|
}))
|
|
37846
37989
|
});
|
|
37847
|
-
if (
|
|
37848
|
-
|
|
37990
|
+
if (clack49.isCancel(selectedRegion)) {
|
|
37991
|
+
clack49.cancel("Operation cancelled");
|
|
37849
37992
|
process.exit(0);
|
|
37850
37993
|
}
|
|
37851
37994
|
region = selectedRegion;
|
|
@@ -37856,18 +37999,18 @@ async function smsDestroy(options) {
|
|
|
37856
37999
|
const storedStackName = smsService?.pulumiStackName;
|
|
37857
38000
|
if (!smsService) {
|
|
37858
38001
|
progress.stop();
|
|
37859
|
-
|
|
38002
|
+
clack49.log.warn("No SMS infrastructure found");
|
|
37860
38003
|
process.exit(0);
|
|
37861
38004
|
}
|
|
37862
38005
|
if (!(options.force || options.preview)) {
|
|
37863
|
-
const confirmed = await
|
|
37864
|
-
message:
|
|
38006
|
+
const confirmed = await clack49.confirm({
|
|
38007
|
+
message: pc52.red(
|
|
37865
38008
|
"Are you sure you want to destroy all SMS infrastructure?"
|
|
37866
38009
|
),
|
|
37867
38010
|
initialValue: false
|
|
37868
38011
|
});
|
|
37869
|
-
if (
|
|
37870
|
-
|
|
38012
|
+
if (clack49.isCancel(confirmed) || !confirmed) {
|
|
38013
|
+
clack49.cancel("Destruction cancelled.");
|
|
37871
38014
|
process.exit(0);
|
|
37872
38015
|
}
|
|
37873
38016
|
}
|
|
@@ -37899,8 +38042,8 @@ async function smsDestroy(options) {
|
|
|
37899
38042
|
costEstimate: "Monthly cost after destruction: $0.00",
|
|
37900
38043
|
commandName: "wraps sms destroy"
|
|
37901
38044
|
});
|
|
37902
|
-
|
|
37903
|
-
|
|
38045
|
+
clack49.outro(
|
|
38046
|
+
pc52.green("Preview complete. Run without --preview to destroy.")
|
|
37904
38047
|
);
|
|
37905
38048
|
trackServiceRemoved("sms", {
|
|
37906
38049
|
preview: true,
|
|
@@ -37911,7 +38054,7 @@ async function smsDestroy(options) {
|
|
|
37911
38054
|
progress.stop();
|
|
37912
38055
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
37913
38056
|
if (errorMessage.includes("No SMS infrastructure found")) {
|
|
37914
|
-
|
|
38057
|
+
clack49.log.warn("No SMS infrastructure found to preview");
|
|
37915
38058
|
process.exit(0);
|
|
37916
38059
|
}
|
|
37917
38060
|
trackError("PREVIEW_FAILED", "sms destroy", { step: "preview" });
|
|
@@ -37960,7 +38103,7 @@ async function smsDestroy(options) {
|
|
|
37960
38103
|
progress.stop();
|
|
37961
38104
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
37962
38105
|
if (errorMessage.includes("No SMS infrastructure found")) {
|
|
37963
|
-
|
|
38106
|
+
clack49.log.warn("No SMS infrastructure found");
|
|
37964
38107
|
if (metadata) {
|
|
37965
38108
|
removeServiceFromConnection(metadata, "sms");
|
|
37966
38109
|
await saveConnectionMetadata(metadata);
|
|
@@ -37973,7 +38116,7 @@ async function smsDestroy(options) {
|
|
|
37973
38116
|
}
|
|
37974
38117
|
trackError("DESTROY_FAILED", "sms destroy", { step: "destroy" });
|
|
37975
38118
|
destroyFailed = true;
|
|
37976
|
-
|
|
38119
|
+
clack49.log.warn(
|
|
37977
38120
|
"Some resources may not have been fully removed. You can re-run this command or clean up manually in the AWS console."
|
|
37978
38121
|
);
|
|
37979
38122
|
}
|
|
@@ -37996,21 +38139,21 @@ async function smsDestroy(options) {
|
|
|
37996
38139
|
return;
|
|
37997
38140
|
}
|
|
37998
38141
|
if (destroyFailed) {
|
|
37999
|
-
|
|
38000
|
-
|
|
38142
|
+
clack49.outro(
|
|
38143
|
+
pc52.yellow("SMS infrastructure partially removed. Metadata cleaned up.")
|
|
38001
38144
|
);
|
|
38002
38145
|
} else {
|
|
38003
|
-
|
|
38146
|
+
clack49.outro(pc52.green("SMS infrastructure has been removed"));
|
|
38004
38147
|
console.log(`
|
|
38005
|
-
${
|
|
38006
|
-
console.log(` ${
|
|
38007
|
-
console.log(` ${
|
|
38008
|
-
console.log(` ${
|
|
38009
|
-
console.log(` ${
|
|
38148
|
+
${pc52.bold("Cleaned up:")}`);
|
|
38149
|
+
console.log(` ${pc52.green("\u2713")} Phone number released`);
|
|
38150
|
+
console.log(` ${pc52.green("\u2713")} Configuration set deleted`);
|
|
38151
|
+
console.log(` ${pc52.green("\u2713")} Event processing infrastructure removed`);
|
|
38152
|
+
console.log(` ${pc52.green("\u2713")} IAM role deleted`);
|
|
38010
38153
|
}
|
|
38011
38154
|
console.log(
|
|
38012
38155
|
`
|
|
38013
|
-
Run ${
|
|
38156
|
+
Run ${pc52.cyan("wraps sms init")} to deploy infrastructure again.
|
|
38014
38157
|
`
|
|
38015
38158
|
);
|
|
38016
38159
|
trackServiceRemoved("sms", {
|
|
@@ -38022,9 +38165,9 @@ Run ${pc51.cyan("wraps sms init")} to deploy infrastructure again.
|
|
|
38022
38165
|
|
|
38023
38166
|
// src/commands/sms/init.ts
|
|
38024
38167
|
init_esm_shims();
|
|
38025
|
-
import * as
|
|
38168
|
+
import * as clack50 from "@clack/prompts";
|
|
38026
38169
|
import * as pulumi32 from "@pulumi/pulumi";
|
|
38027
|
-
import
|
|
38170
|
+
import pc53 from "picocolors";
|
|
38028
38171
|
init_events();
|
|
38029
38172
|
init_aws();
|
|
38030
38173
|
init_fs();
|
|
@@ -38443,7 +38586,7 @@ function validateSMSConfig(config2) {
|
|
|
38443
38586
|
|
|
38444
38587
|
// src/commands/sms/init.ts
|
|
38445
38588
|
async function promptPhoneNumberType() {
|
|
38446
|
-
const result = await
|
|
38589
|
+
const result = await clack50.select({
|
|
38447
38590
|
message: "Select phone number type:",
|
|
38448
38591
|
options: [
|
|
38449
38592
|
{
|
|
@@ -38463,14 +38606,14 @@ async function promptPhoneNumberType() {
|
|
|
38463
38606
|
}
|
|
38464
38607
|
]
|
|
38465
38608
|
});
|
|
38466
|
-
if (
|
|
38467
|
-
|
|
38609
|
+
if (clack50.isCancel(result)) {
|
|
38610
|
+
clack50.cancel("Operation cancelled.");
|
|
38468
38611
|
process.exit(0);
|
|
38469
38612
|
}
|
|
38470
38613
|
return result;
|
|
38471
38614
|
}
|
|
38472
38615
|
async function promptSMSPreset() {
|
|
38473
|
-
const result = await
|
|
38616
|
+
const result = await clack50.select({
|
|
38474
38617
|
message: "Choose configuration preset:",
|
|
38475
38618
|
options: [
|
|
38476
38619
|
{
|
|
@@ -38495,8 +38638,8 @@ async function promptSMSPreset() {
|
|
|
38495
38638
|
}
|
|
38496
38639
|
]
|
|
38497
38640
|
});
|
|
38498
|
-
if (
|
|
38499
|
-
|
|
38641
|
+
if (clack50.isCancel(result)) {
|
|
38642
|
+
clack50.cancel("Operation cancelled.");
|
|
38500
38643
|
process.exit(0);
|
|
38501
38644
|
}
|
|
38502
38645
|
return result;
|
|
@@ -38516,7 +38659,7 @@ var COMMON_COUNTRIES = [
|
|
|
38516
38659
|
{ code: "IN", name: "India" }
|
|
38517
38660
|
];
|
|
38518
38661
|
async function promptAllowedCountries() {
|
|
38519
|
-
const result = await
|
|
38662
|
+
const result = await clack50.multiselect({
|
|
38520
38663
|
message: "Select countries to allow SMS delivery (blocks all others):",
|
|
38521
38664
|
options: COMMON_COUNTRIES.map((c) => ({
|
|
38522
38665
|
value: c.code,
|
|
@@ -38525,14 +38668,14 @@ async function promptAllowedCountries() {
|
|
|
38525
38668
|
initialValues: ["US"],
|
|
38526
38669
|
required: true
|
|
38527
38670
|
});
|
|
38528
|
-
if (
|
|
38529
|
-
|
|
38671
|
+
if (clack50.isCancel(result)) {
|
|
38672
|
+
clack50.cancel("Operation cancelled.");
|
|
38530
38673
|
process.exit(0);
|
|
38531
38674
|
}
|
|
38532
38675
|
return result;
|
|
38533
38676
|
}
|
|
38534
38677
|
async function promptEstimatedSMSVolume() {
|
|
38535
|
-
const result = await
|
|
38678
|
+
const result = await clack50.select({
|
|
38536
38679
|
message: "Estimated messages per month:",
|
|
38537
38680
|
options: [
|
|
38538
38681
|
{ value: 100, label: "< 100 (Testing)" },
|
|
@@ -38542,8 +38685,8 @@ async function promptEstimatedSMSVolume() {
|
|
|
38542
38685
|
{ value: 1e5, label: "50,000+" }
|
|
38543
38686
|
]
|
|
38544
38687
|
});
|
|
38545
|
-
if (
|
|
38546
|
-
|
|
38688
|
+
if (clack50.isCancel(result)) {
|
|
38689
|
+
clack50.cancel("Operation cancelled.");
|
|
38547
38690
|
process.exit(0);
|
|
38548
38691
|
}
|
|
38549
38692
|
return result;
|
|
@@ -38551,7 +38694,7 @@ async function promptEstimatedSMSVolume() {
|
|
|
38551
38694
|
async function init3(options) {
|
|
38552
38695
|
const startTime = Date.now();
|
|
38553
38696
|
if (!isJsonMode()) {
|
|
38554
|
-
|
|
38697
|
+
clack50.intro(pc53.bold("Wraps SMS Infrastructure Setup"));
|
|
38555
38698
|
}
|
|
38556
38699
|
const progress = new DeploymentProgress();
|
|
38557
38700
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -38565,7 +38708,7 @@ async function init3(options) {
|
|
|
38565
38708
|
"Validating AWS credentials",
|
|
38566
38709
|
async () => validateAWSCredentials()
|
|
38567
38710
|
);
|
|
38568
|
-
progress.info(`Connected to AWS account: ${
|
|
38711
|
+
progress.info(`Connected to AWS account: ${pc53.cyan(identity.accountId)}`);
|
|
38569
38712
|
const provider = options.provider || await promptProvider();
|
|
38570
38713
|
const region = options.region || await promptRegion(await getAWSRegion());
|
|
38571
38714
|
let vercelConfig;
|
|
@@ -38577,10 +38720,10 @@ async function init3(options) {
|
|
|
38577
38720
|
region
|
|
38578
38721
|
);
|
|
38579
38722
|
if (existingConnection?.services?.sms) {
|
|
38580
|
-
|
|
38581
|
-
`SMS already configured for account ${
|
|
38723
|
+
clack50.log.warn(
|
|
38724
|
+
`SMS already configured for account ${pc53.cyan(identity.accountId)} in region ${pc53.cyan(region)}`
|
|
38582
38725
|
);
|
|
38583
|
-
|
|
38726
|
+
clack50.log.info(`Use ${pc53.cyan("wraps sms status")} to view current setup`);
|
|
38584
38727
|
process.exit(0);
|
|
38585
38728
|
}
|
|
38586
38729
|
let preset = options.preset;
|
|
@@ -38597,12 +38740,12 @@ async function init3(options) {
|
|
|
38597
38740
|
optOutManagement: true,
|
|
38598
38741
|
sendingEnabled: true
|
|
38599
38742
|
};
|
|
38600
|
-
const enableEventTracking = await
|
|
38743
|
+
const enableEventTracking = await clack50.confirm({
|
|
38601
38744
|
message: "Enable event tracking (EventBridge + DynamoDB)?",
|
|
38602
38745
|
initialValue: false
|
|
38603
38746
|
});
|
|
38604
|
-
if (
|
|
38605
|
-
|
|
38747
|
+
if (clack50.isCancel(enableEventTracking)) {
|
|
38748
|
+
clack50.cancel("Operation cancelled.");
|
|
38606
38749
|
process.exit(0);
|
|
38607
38750
|
}
|
|
38608
38751
|
if (enableEventTracking) {
|
|
@@ -38622,17 +38765,17 @@ async function init3(options) {
|
|
|
38622
38765
|
}
|
|
38623
38766
|
progress.info(
|
|
38624
38767
|
`
|
|
38625
|
-
${
|
|
38768
|
+
${pc53.bold("Fraud Protection")} - Block SMS to countries where you don't do business`
|
|
38626
38769
|
);
|
|
38627
38770
|
const allowedCountries = await promptAllowedCountries();
|
|
38628
38771
|
let aitFiltering = false;
|
|
38629
38772
|
if (smsConfig.phoneNumberType !== "simulator") {
|
|
38630
|
-
const enableAIT = await
|
|
38773
|
+
const enableAIT = await clack50.confirm({
|
|
38631
38774
|
message: "Enable AIT (Artificially Inflated Traffic) filtering? (adds per-message cost)",
|
|
38632
38775
|
initialValue: false
|
|
38633
38776
|
});
|
|
38634
|
-
if (
|
|
38635
|
-
|
|
38777
|
+
if (clack50.isCancel(enableAIT)) {
|
|
38778
|
+
clack50.cancel("Operation cancelled.");
|
|
38636
38779
|
process.exit(0);
|
|
38637
38780
|
}
|
|
38638
38781
|
aitFiltering = enableAIT;
|
|
@@ -38644,21 +38787,21 @@ ${pc52.bold("Fraud Protection")} - Block SMS to countries where you don't do bus
|
|
|
38644
38787
|
};
|
|
38645
38788
|
const estimatedVolume = await promptEstimatedSMSVolume();
|
|
38646
38789
|
progress.info(`
|
|
38647
|
-
${
|
|
38790
|
+
${pc53.bold("Cost Estimate:")}`);
|
|
38648
38791
|
const costSummary = getSMSCostSummary(smsConfig, estimatedVolume);
|
|
38649
|
-
|
|
38792
|
+
clack50.log.info(costSummary);
|
|
38650
38793
|
const warnings = validateSMSConfig(smsConfig);
|
|
38651
38794
|
if (warnings.length > 0) {
|
|
38652
38795
|
progress.info(`
|
|
38653
|
-
${
|
|
38796
|
+
${pc53.yellow(pc53.bold("Important Notes:"))}`);
|
|
38654
38797
|
for (const warning of warnings) {
|
|
38655
|
-
|
|
38798
|
+
clack50.log.warn(warning);
|
|
38656
38799
|
}
|
|
38657
38800
|
}
|
|
38658
38801
|
if (!(options.yes || options.preview)) {
|
|
38659
38802
|
const confirmed = await confirmDeploy();
|
|
38660
38803
|
if (!confirmed) {
|
|
38661
|
-
|
|
38804
|
+
clack50.cancel("Deployment cancelled.");
|
|
38662
38805
|
process.exit(0);
|
|
38663
38806
|
}
|
|
38664
38807
|
}
|
|
@@ -38718,8 +38861,8 @@ ${pc52.yellow(pc52.bold("Important Notes:"))}`);
|
|
|
38718
38861
|
costEstimate: getSMSCostSummary(smsConfig, 0),
|
|
38719
38862
|
commandName: "wraps sms init"
|
|
38720
38863
|
});
|
|
38721
|
-
|
|
38722
|
-
|
|
38864
|
+
clack50.outro(
|
|
38865
|
+
pc53.green("Preview complete. Run without --preview to deploy.")
|
|
38723
38866
|
);
|
|
38724
38867
|
trackServiceInit("sms", true, {
|
|
38725
38868
|
provider,
|
|
@@ -38768,9 +38911,9 @@ ${pc52.yellow(pc52.bold("Important Notes:"))}`);
|
|
|
38768
38911
|
} catch (sdkError) {
|
|
38769
38912
|
sdkResourceWarning = true;
|
|
38770
38913
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
38771
|
-
|
|
38772
|
-
|
|
38773
|
-
`Run ${
|
|
38914
|
+
clack50.log.warn(`Phone pool creation failed: ${msg}`);
|
|
38915
|
+
clack50.log.info(
|
|
38916
|
+
`Run ${pc53.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
38774
38917
|
);
|
|
38775
38918
|
}
|
|
38776
38919
|
}
|
|
@@ -38786,9 +38929,9 @@ ${pc52.yellow(pc52.bold("Important Notes:"))}`);
|
|
|
38786
38929
|
} catch (sdkError) {
|
|
38787
38930
|
sdkResourceWarning = true;
|
|
38788
38931
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
38789
|
-
|
|
38790
|
-
|
|
38791
|
-
`Run ${
|
|
38932
|
+
clack50.log.warn(`Event destination creation failed: ${msg}`);
|
|
38933
|
+
clack50.log.info(
|
|
38934
|
+
`Run ${pc53.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
38792
38935
|
);
|
|
38793
38936
|
}
|
|
38794
38937
|
}
|
|
@@ -38807,14 +38950,14 @@ ${pc52.yellow(pc52.bold("Important Notes:"))}`);
|
|
|
38807
38950
|
} catch (sdkError) {
|
|
38808
38951
|
sdkResourceWarning = true;
|
|
38809
38952
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
38810
|
-
|
|
38811
|
-
|
|
38812
|
-
`Run ${
|
|
38953
|
+
clack50.log.warn(`Protect configuration creation failed: ${msg}`);
|
|
38954
|
+
clack50.log.info(
|
|
38955
|
+
`Run ${pc53.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
38813
38956
|
);
|
|
38814
38957
|
}
|
|
38815
38958
|
}
|
|
38816
38959
|
if (sdkResourceWarning) {
|
|
38817
|
-
|
|
38960
|
+
clack50.log.warn(
|
|
38818
38961
|
"Some SDK resources failed to create. Core infrastructure is deployed."
|
|
38819
38962
|
);
|
|
38820
38963
|
}
|
|
@@ -38859,47 +39002,47 @@ ${pc52.yellow(pc52.bold("Important Notes:"))}`);
|
|
|
38859
39002
|
return;
|
|
38860
39003
|
}
|
|
38861
39004
|
console.log("\n");
|
|
38862
|
-
|
|
39005
|
+
clack50.log.success(pc53.green(pc53.bold("SMS infrastructure deployed!")));
|
|
38863
39006
|
console.log("\n");
|
|
38864
|
-
|
|
39007
|
+
clack50.note(
|
|
38865
39008
|
[
|
|
38866
|
-
`${
|
|
38867
|
-
`${
|
|
38868
|
-
`${
|
|
38869
|
-
`${
|
|
38870
|
-
outputs.tableName ? `${
|
|
39009
|
+
`${pc53.bold("Phone Number:")} ${pc53.cyan(outputs.phoneNumber || "Provisioning...")}`,
|
|
39010
|
+
`${pc53.bold("Phone Type:")} ${pc53.cyan(smsConfig.phoneNumberType || "simulator")}`,
|
|
39011
|
+
`${pc53.bold("Config Set:")} ${pc53.cyan(outputs.configSetName || "wraps-sms-config")}`,
|
|
39012
|
+
`${pc53.bold("Region:")} ${pc53.cyan(outputs.region)}`,
|
|
39013
|
+
outputs.tableName ? `${pc53.bold("History Table:")} ${pc53.cyan(outputs.tableName)}` : "",
|
|
38871
39014
|
"",
|
|
38872
|
-
|
|
38873
|
-
|
|
39015
|
+
pc53.dim("IAM Role:"),
|
|
39016
|
+
pc53.dim(` ${outputs.roleArn}`)
|
|
38874
39017
|
].filter(Boolean).join("\n"),
|
|
38875
39018
|
"SMS Infrastructure"
|
|
38876
39019
|
);
|
|
38877
39020
|
const nextSteps = [];
|
|
38878
39021
|
if (smsConfig.phoneNumberType === "toll-free") {
|
|
38879
39022
|
nextSteps.push(
|
|
38880
|
-
`${
|
|
39023
|
+
`${pc53.cyan("wraps sms register")} - Submit toll-free registration (required before sending)`
|
|
38881
39024
|
);
|
|
38882
39025
|
}
|
|
38883
39026
|
nextSteps.push(
|
|
38884
|
-
`${
|
|
39027
|
+
`${pc53.cyan("wraps sms test --to +1234567890")} - Send a test message`
|
|
38885
39028
|
);
|
|
38886
|
-
nextSteps.push(`${
|
|
39029
|
+
nextSteps.push(`${pc53.cyan("wraps sms status")} - View SMS configuration`);
|
|
38887
39030
|
console.log("\n");
|
|
38888
|
-
|
|
39031
|
+
clack50.log.info(pc53.bold("Next steps:"));
|
|
38889
39032
|
for (const step of nextSteps) {
|
|
38890
39033
|
console.log(` ${step}`);
|
|
38891
39034
|
}
|
|
38892
39035
|
console.log("\n");
|
|
38893
|
-
|
|
38894
|
-
console.log(
|
|
39036
|
+
clack50.log.info(pc53.bold("SDK Usage:"));
|
|
39037
|
+
console.log(pc53.dim(" npm install @wraps.dev/sms"));
|
|
38895
39038
|
console.log("");
|
|
38896
|
-
console.log(
|
|
38897
|
-
console.log(
|
|
38898
|
-
console.log(
|
|
38899
|
-
console.log(
|
|
38900
|
-
console.log(
|
|
38901
|
-
console.log(
|
|
38902
|
-
|
|
39039
|
+
console.log(pc53.dim(" import { Wraps } from '@wraps.dev/sms';"));
|
|
39040
|
+
console.log(pc53.dim(" const wraps = new Wraps();"));
|
|
39041
|
+
console.log(pc53.dim(" await wraps.sms.send({"));
|
|
39042
|
+
console.log(pc53.dim(" to: '+14155551234',"));
|
|
39043
|
+
console.log(pc53.dim(" message: 'Your code is 123456',"));
|
|
39044
|
+
console.log(pc53.dim(" });"));
|
|
39045
|
+
clack50.outro(pc53.green("Setup complete!"));
|
|
38903
39046
|
const duration = Date.now() - startTime;
|
|
38904
39047
|
const enabledFeatures = [];
|
|
38905
39048
|
if (smsConfig.tracking?.enabled) {
|
|
@@ -38935,8 +39078,8 @@ init_aws();
|
|
|
38935
39078
|
init_json_output();
|
|
38936
39079
|
init_metadata();
|
|
38937
39080
|
init_output();
|
|
38938
|
-
import * as
|
|
38939
|
-
import
|
|
39081
|
+
import * as clack51 from "@clack/prompts";
|
|
39082
|
+
import pc54 from "picocolors";
|
|
38940
39083
|
async function getPhoneNumberDetails(region) {
|
|
38941
39084
|
const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePhoneNumbersCommand: DescribePhoneNumbersCommand2 } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
|
|
38942
39085
|
const client = new PinpointSMSVoiceV2Client5({ region });
|
|
@@ -38956,7 +39099,7 @@ async function getPhoneNumberDetails(region) {
|
|
|
38956
39099
|
return null;
|
|
38957
39100
|
} catch (error) {
|
|
38958
39101
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
38959
|
-
|
|
39102
|
+
clack51.log.error(`Error fetching phone number: ${errorMessage}`);
|
|
38960
39103
|
return null;
|
|
38961
39104
|
}
|
|
38962
39105
|
}
|
|
@@ -38977,7 +39120,7 @@ async function getRegistrationStatus(region, registrationId) {
|
|
|
38977
39120
|
async function smsRegister(options) {
|
|
38978
39121
|
const startTime = Date.now();
|
|
38979
39122
|
if (!isJsonMode()) {
|
|
38980
|
-
|
|
39123
|
+
clack51.intro(pc54.bold("Wraps SMS - Toll-Free Registration"));
|
|
38981
39124
|
}
|
|
38982
39125
|
const progress = new DeploymentProgress();
|
|
38983
39126
|
const identity = await progress.execute(
|
|
@@ -38990,8 +39133,8 @@ async function smsRegister(options) {
|
|
|
38990
39133
|
}
|
|
38991
39134
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
38992
39135
|
if (!metadata?.services?.sms) {
|
|
38993
|
-
|
|
38994
|
-
|
|
39136
|
+
clack51.log.error("No SMS infrastructure found.");
|
|
39137
|
+
clack51.log.info(`Run ${pc54.cyan("wraps sms init")} first.`);
|
|
38995
39138
|
process.exit(1);
|
|
38996
39139
|
}
|
|
38997
39140
|
const phoneDetails = await progress.execute(
|
|
@@ -38999,7 +39142,7 @@ async function smsRegister(options) {
|
|
|
38999
39142
|
async () => getPhoneNumberDetails(region)
|
|
39000
39143
|
);
|
|
39001
39144
|
if (!phoneDetails) {
|
|
39002
|
-
|
|
39145
|
+
clack51.log.error("No phone number found.");
|
|
39003
39146
|
process.exit(1);
|
|
39004
39147
|
}
|
|
39005
39148
|
let registrationStatus = null;
|
|
@@ -39025,53 +39168,53 @@ async function smsRegister(options) {
|
|
|
39025
39168
|
}
|
|
39026
39169
|
console.log("");
|
|
39027
39170
|
console.log(
|
|
39028
|
-
`${
|
|
39171
|
+
`${pc54.bold("Phone Number:")} ${pc54.cyan(phoneDetails.phoneNumber)}`
|
|
39029
39172
|
);
|
|
39030
|
-
console.log(`${
|
|
39173
|
+
console.log(`${pc54.bold("Type:")} ${pc54.cyan(phoneDetails.type)}`);
|
|
39031
39174
|
console.log(
|
|
39032
|
-
`${
|
|
39175
|
+
`${pc54.bold("Status:")} ${phoneDetails.status === "ACTIVE" ? pc54.green(phoneDetails.status) : pc54.yellow(phoneDetails.status)}`
|
|
39033
39176
|
);
|
|
39034
39177
|
if (registrationStatus) {
|
|
39035
|
-
console.log(`${
|
|
39178
|
+
console.log(`${pc54.bold("Registration:")} ${pc54.cyan(registrationStatus)}`);
|
|
39036
39179
|
}
|
|
39037
39180
|
console.log("");
|
|
39038
39181
|
if (phoneDetails.status === "ACTIVE") {
|
|
39039
|
-
|
|
39182
|
+
clack51.log.success("Your phone number is already ACTIVE and ready to use!");
|
|
39040
39183
|
const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePoolsCommand } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
|
|
39041
39184
|
const client = new PinpointSMSVoiceV2Client5({ region });
|
|
39042
39185
|
const pools = await client.send(new DescribePoolsCommand({}));
|
|
39043
39186
|
if (!pools.Pools?.length) {
|
|
39044
|
-
|
|
39187
|
+
clack51.log.info("Run `wraps sms sync` to create the phone pool.");
|
|
39045
39188
|
}
|
|
39046
39189
|
process.exit(0);
|
|
39047
39190
|
}
|
|
39048
39191
|
if (phoneDetails.type !== "TOLL_FREE") {
|
|
39049
|
-
|
|
39050
|
-
|
|
39192
|
+
clack51.log.info("Only toll-free numbers require registration.");
|
|
39193
|
+
clack51.log.info(`Your ${phoneDetails.type} number should be ready to use.`);
|
|
39051
39194
|
process.exit(0);
|
|
39052
39195
|
}
|
|
39053
|
-
console.log(
|
|
39196
|
+
console.log(pc54.bold("Toll-Free Registration Required"));
|
|
39054
39197
|
console.log("");
|
|
39055
39198
|
console.log(
|
|
39056
|
-
|
|
39199
|
+
pc54.dim("To send SMS at scale, you must register your toll-free number.")
|
|
39057
39200
|
);
|
|
39058
|
-
console.log(
|
|
39201
|
+
console.log(pc54.dim("This process typically takes 1-15 business days."));
|
|
39059
39202
|
console.log("");
|
|
39060
|
-
console.log(
|
|
39061
|
-
console.log(` ${
|
|
39203
|
+
console.log(pc54.bold("You'll need to provide:"));
|
|
39204
|
+
console.log(` ${pc54.dim("\u2022")} Business name and address`);
|
|
39062
39205
|
console.log(
|
|
39063
|
-
` ${
|
|
39206
|
+
` ${pc54.dim("\u2022")} Use case description (what messages you're sending)`
|
|
39064
39207
|
);
|
|
39065
|
-
console.log(` ${
|
|
39066
|
-
console.log(` ${
|
|
39067
|
-
console.log(` ${
|
|
39208
|
+
console.log(` ${pc54.dim("\u2022")} Sample messages (2-3 examples)`);
|
|
39209
|
+
console.log(` ${pc54.dim("\u2022")} How users opt-in to receive messages`);
|
|
39210
|
+
console.log(` ${pc54.dim("\u2022")} Expected monthly message volume`);
|
|
39068
39211
|
console.log("");
|
|
39069
|
-
const openConsole = await
|
|
39212
|
+
const openConsole = await clack51.confirm({
|
|
39070
39213
|
message: "Open AWS Console to start registration?",
|
|
39071
39214
|
initialValue: true
|
|
39072
39215
|
});
|
|
39073
|
-
if (
|
|
39074
|
-
|
|
39216
|
+
if (clack51.isCancel(openConsole)) {
|
|
39217
|
+
clack51.cancel("Registration cancelled.");
|
|
39075
39218
|
process.exit(0);
|
|
39076
39219
|
}
|
|
39077
39220
|
if (openConsole) {
|
|
@@ -39081,41 +39224,41 @@ async function smsRegister(options) {
|
|
|
39081
39224
|
const execAsync2 = promisify2(exec2);
|
|
39082
39225
|
try {
|
|
39083
39226
|
await execAsync2(`open "${consoleUrl}"`);
|
|
39084
|
-
|
|
39227
|
+
clack51.log.success("Opened AWS Console in your browser.");
|
|
39085
39228
|
} catch {
|
|
39086
39229
|
try {
|
|
39087
39230
|
await execAsync2(`xdg-open "${consoleUrl}"`);
|
|
39088
|
-
|
|
39231
|
+
clack51.log.success("Opened AWS Console in your browser.");
|
|
39089
39232
|
} catch {
|
|
39090
|
-
|
|
39233
|
+
clack51.log.info("Open this URL in your browser:");
|
|
39091
39234
|
console.log(`
|
|
39092
|
-
${
|
|
39235
|
+
${pc54.cyan(consoleUrl)}
|
|
39093
39236
|
`);
|
|
39094
39237
|
}
|
|
39095
39238
|
}
|
|
39096
39239
|
console.log("");
|
|
39097
|
-
console.log(
|
|
39240
|
+
console.log(pc54.bold("Next Steps:"));
|
|
39098
39241
|
console.log(
|
|
39099
|
-
` 1. Click ${
|
|
39242
|
+
` 1. Click ${pc54.cyan("Create registration")} in the AWS Console`
|
|
39100
39243
|
);
|
|
39101
|
-
console.log(` 2. Select ${
|
|
39244
|
+
console.log(` 2. Select ${pc54.cyan("Toll-free number registration")}`);
|
|
39102
39245
|
console.log(" 3. Fill out the business information form");
|
|
39103
39246
|
console.log(" 4. Submit and wait for approval (1-15 business days)");
|
|
39104
39247
|
console.log("");
|
|
39105
39248
|
console.log(
|
|
39106
|
-
|
|
39249
|
+
pc54.dim("Once approved, run `wraps sms sync` to complete setup.")
|
|
39107
39250
|
);
|
|
39108
39251
|
} else {
|
|
39109
39252
|
const consoleUrl = `https://${region}.console.aws.amazon.com/sms-voice/home?region=${region}#/registrations`;
|
|
39110
39253
|
console.log("");
|
|
39111
39254
|
console.log("When you're ready, go to:");
|
|
39112
|
-
console.log(` ${
|
|
39255
|
+
console.log(` ${pc54.cyan(consoleUrl)}`);
|
|
39113
39256
|
}
|
|
39114
39257
|
trackCommand("sms:register", {
|
|
39115
39258
|
success: true,
|
|
39116
39259
|
duration_ms: Date.now() - startTime
|
|
39117
39260
|
});
|
|
39118
|
-
|
|
39261
|
+
clack51.outro(pc54.dim("Good luck with your registration!"));
|
|
39119
39262
|
}
|
|
39120
39263
|
|
|
39121
39264
|
// src/commands/sms/status.ts
|
|
@@ -39128,54 +39271,54 @@ init_metadata();
|
|
|
39128
39271
|
init_output();
|
|
39129
39272
|
init_pulumi();
|
|
39130
39273
|
init_region_resolver();
|
|
39131
|
-
import * as
|
|
39274
|
+
import * as clack52 from "@clack/prompts";
|
|
39132
39275
|
import * as pulumi33 from "@pulumi/pulumi";
|
|
39133
|
-
import
|
|
39276
|
+
import pc55 from "picocolors";
|
|
39134
39277
|
function displaySMSStatus(options) {
|
|
39135
39278
|
const lines = [];
|
|
39136
|
-
lines.push(
|
|
39279
|
+
lines.push(pc55.bold(pc55.green("SMS Infrastructure Active")));
|
|
39137
39280
|
lines.push("");
|
|
39138
|
-
lines.push(
|
|
39281
|
+
lines.push(pc55.bold("Phone Number"));
|
|
39139
39282
|
if (options.phoneNumber) {
|
|
39140
|
-
lines.push(` Number: ${
|
|
39283
|
+
lines.push(` Number: ${pc55.cyan(options.phoneNumber)}`);
|
|
39141
39284
|
} else {
|
|
39142
|
-
lines.push(` Number: ${
|
|
39285
|
+
lines.push(` Number: ${pc55.yellow("Provisioning...")}`);
|
|
39143
39286
|
}
|
|
39144
|
-
lines.push(` Type: ${
|
|
39287
|
+
lines.push(` Type: ${pc55.cyan(options.phoneNumberType || "simulator")}`);
|
|
39145
39288
|
lines.push("");
|
|
39146
|
-
lines.push(
|
|
39147
|
-
lines.push(` Region: ${
|
|
39289
|
+
lines.push(pc55.bold("Configuration"));
|
|
39290
|
+
lines.push(` Region: ${pc55.cyan(options.region)}`);
|
|
39148
39291
|
if (options.preset) {
|
|
39149
|
-
lines.push(` Preset: ${
|
|
39292
|
+
lines.push(` Preset: ${pc55.cyan(options.preset)}`);
|
|
39150
39293
|
}
|
|
39151
39294
|
if (options.configSetName) {
|
|
39152
|
-
lines.push(` Config Set: ${
|
|
39295
|
+
lines.push(` Config Set: ${pc55.cyan(options.configSetName)}`);
|
|
39153
39296
|
}
|
|
39154
39297
|
lines.push("");
|
|
39155
|
-
lines.push(
|
|
39298
|
+
lines.push(pc55.bold("Features"));
|
|
39156
39299
|
lines.push(
|
|
39157
|
-
` Event Tracking: ${options.eventTracking ?
|
|
39300
|
+
` Event Tracking: ${options.eventTracking ? pc55.green("Enabled") : pc55.dim("Disabled")}`
|
|
39158
39301
|
);
|
|
39159
39302
|
if (options.tableName) {
|
|
39160
|
-
lines.push(` Message History: ${
|
|
39161
|
-
lines.push(` Table: ${
|
|
39303
|
+
lines.push(` Message History: ${pc55.green("Enabled")}`);
|
|
39304
|
+
lines.push(` Table: ${pc55.dim(options.tableName)}`);
|
|
39162
39305
|
}
|
|
39163
39306
|
if (options.queueUrl) {
|
|
39164
|
-
lines.push(` Event Queue: ${
|
|
39307
|
+
lines.push(` Event Queue: ${pc55.green("Enabled")}`);
|
|
39165
39308
|
}
|
|
39166
39309
|
lines.push("");
|
|
39167
39310
|
if (options.roleArn) {
|
|
39168
|
-
lines.push(
|
|
39169
|
-
lines.push(` ${
|
|
39311
|
+
lines.push(pc55.bold("IAM Role"));
|
|
39312
|
+
lines.push(` ${pc55.dim(options.roleArn)}`);
|
|
39170
39313
|
}
|
|
39171
|
-
|
|
39314
|
+
clack52.note(lines.join("\n"), "SMS Status");
|
|
39172
39315
|
}
|
|
39173
39316
|
async function smsStatus(options) {
|
|
39174
39317
|
await ensurePulumiInstalled();
|
|
39175
39318
|
const startTime = Date.now();
|
|
39176
39319
|
const progress = new DeploymentProgress();
|
|
39177
39320
|
if (!isJsonMode()) {
|
|
39178
|
-
|
|
39321
|
+
clack52.intro(pc55.bold("Wraps SMS Status"));
|
|
39179
39322
|
}
|
|
39180
39323
|
const identity = await progress.execute(
|
|
39181
39324
|
"Loading SMS infrastructure status",
|
|
@@ -39190,10 +39333,10 @@ async function smsStatus(options) {
|
|
|
39190
39333
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
39191
39334
|
if (!metadata?.services?.sms) {
|
|
39192
39335
|
progress.stop();
|
|
39193
|
-
|
|
39336
|
+
clack52.log.error("No SMS infrastructure found");
|
|
39194
39337
|
console.log(
|
|
39195
39338
|
`
|
|
39196
|
-
Run ${
|
|
39339
|
+
Run ${pc55.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
39197
39340
|
`
|
|
39198
39341
|
);
|
|
39199
39342
|
process.exit(1);
|
|
@@ -39229,25 +39372,25 @@ Run ${pc54.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39229
39372
|
}
|
|
39230
39373
|
displaySMSStatus(smsStatusData);
|
|
39231
39374
|
console.log("");
|
|
39232
|
-
|
|
39375
|
+
clack52.log.info(pc55.bold("Commands:"));
|
|
39233
39376
|
console.log(
|
|
39234
|
-
` ${
|
|
39377
|
+
` ${pc55.cyan("wraps sms test --to +1234567890")} - Send a test message`
|
|
39235
39378
|
);
|
|
39236
|
-
console.log(` ${
|
|
39379
|
+
console.log(` ${pc55.cyan("wraps sms destroy")} - Remove SMS infrastructure`);
|
|
39237
39380
|
trackCommand("sms:status", {
|
|
39238
39381
|
success: true,
|
|
39239
39382
|
phone_type: smsConfig?.phoneNumberType,
|
|
39240
39383
|
event_tracking: smsConfig?.eventTracking?.enabled,
|
|
39241
39384
|
duration_ms: Date.now() - startTime
|
|
39242
39385
|
});
|
|
39243
|
-
|
|
39386
|
+
clack52.outro(pc55.dim("SMS infrastructure is ready"));
|
|
39244
39387
|
}
|
|
39245
39388
|
|
|
39246
39389
|
// src/commands/sms/sync.ts
|
|
39247
39390
|
init_esm_shims();
|
|
39248
|
-
import * as
|
|
39391
|
+
import * as clack53 from "@clack/prompts";
|
|
39249
39392
|
import * as pulumi34 from "@pulumi/pulumi";
|
|
39250
|
-
import
|
|
39393
|
+
import pc56 from "picocolors";
|
|
39251
39394
|
init_events();
|
|
39252
39395
|
init_aws();
|
|
39253
39396
|
init_errors();
|
|
@@ -39260,7 +39403,7 @@ async function smsSync(options) {
|
|
|
39260
39403
|
await ensurePulumiInstalled();
|
|
39261
39404
|
const startTime = Date.now();
|
|
39262
39405
|
if (!isJsonMode()) {
|
|
39263
|
-
|
|
39406
|
+
clack53.intro(pc56.bold("Wraps SMS Infrastructure Sync"));
|
|
39264
39407
|
}
|
|
39265
39408
|
const progress = new DeploymentProgress();
|
|
39266
39409
|
const identity = await progress.execute(
|
|
@@ -39272,10 +39415,10 @@ async function smsSync(options) {
|
|
|
39272
39415
|
const smsService = metadata?.services?.sms;
|
|
39273
39416
|
if (!smsService?.config) {
|
|
39274
39417
|
progress.stop();
|
|
39275
|
-
|
|
39418
|
+
clack53.log.error("No SMS infrastructure found to sync");
|
|
39276
39419
|
console.log(
|
|
39277
39420
|
`
|
|
39278
|
-
Run ${
|
|
39421
|
+
Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
39279
39422
|
`
|
|
39280
39423
|
);
|
|
39281
39424
|
process.exit(1);
|
|
@@ -39284,18 +39427,18 @@ Run ${pc55.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
39284
39427
|
const storedStackName = smsService.pulumiStackName;
|
|
39285
39428
|
progress.info("Found existing SMS configuration");
|
|
39286
39429
|
progress.info(
|
|
39287
|
-
`Phone type: ${
|
|
39430
|
+
`Phone type: ${pc56.cyan(smsConfig.phoneNumberType || "simulator")}`
|
|
39288
39431
|
);
|
|
39289
39432
|
progress.info(
|
|
39290
|
-
`Event tracking: ${
|
|
39433
|
+
`Event tracking: ${pc56.cyan(smsConfig.eventTracking?.enabled ? "enabled" : "disabled")}`
|
|
39291
39434
|
);
|
|
39292
39435
|
if (!options.yes) {
|
|
39293
|
-
const confirmed = await
|
|
39436
|
+
const confirmed = await clack53.confirm({
|
|
39294
39437
|
message: "Sync SMS infrastructure? This will update Lambda code and recreate any missing resources.",
|
|
39295
39438
|
initialValue: true
|
|
39296
39439
|
});
|
|
39297
|
-
if (
|
|
39298
|
-
|
|
39440
|
+
if (clack53.isCancel(confirmed) || !confirmed) {
|
|
39441
|
+
clack53.cancel("Sync cancelled.");
|
|
39299
39442
|
process.exit(0);
|
|
39300
39443
|
}
|
|
39301
39444
|
}
|
|
@@ -39400,7 +39543,7 @@ Run ${pc55.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
39400
39543
|
throw errors.stackLocked();
|
|
39401
39544
|
}
|
|
39402
39545
|
trackError("SYNC_FAILED", "sms:sync", { step: "sync" });
|
|
39403
|
-
|
|
39546
|
+
clack53.log.error(`SMS sync failed: ${errorMessage}`);
|
|
39404
39547
|
process.exit(1);
|
|
39405
39548
|
}
|
|
39406
39549
|
if (metadata && smsService) {
|
|
@@ -39420,7 +39563,7 @@ Run ${pc55.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
39420
39563
|
return;
|
|
39421
39564
|
}
|
|
39422
39565
|
console.log("\n");
|
|
39423
|
-
|
|
39566
|
+
clack53.log.success(pc56.green("SMS infrastructure synced successfully!"));
|
|
39424
39567
|
const changes = [];
|
|
39425
39568
|
if (outputs.lambdaFunctions?.length) {
|
|
39426
39569
|
changes.push("Lambda functions updated");
|
|
@@ -39428,13 +39571,13 @@ Run ${pc55.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
39428
39571
|
changes.push("SDK resources verified");
|
|
39429
39572
|
console.log("");
|
|
39430
39573
|
for (const change of changes) {
|
|
39431
|
-
console.log(` ${
|
|
39574
|
+
console.log(` ${pc56.green("\u2713")} ${change}`);
|
|
39432
39575
|
}
|
|
39433
39576
|
trackCommand("sms:sync", {
|
|
39434
39577
|
success: true,
|
|
39435
39578
|
duration_ms: Date.now() - startTime
|
|
39436
39579
|
});
|
|
39437
|
-
|
|
39580
|
+
clack53.outro(pc56.green("Sync complete!"));
|
|
39438
39581
|
}
|
|
39439
39582
|
|
|
39440
39583
|
// src/commands/sms/test.ts
|
|
@@ -39449,8 +39592,8 @@ import {
|
|
|
39449
39592
|
PinpointSMSVoiceV2Client as PinpointSMSVoiceV2Client3,
|
|
39450
39593
|
SendTextMessageCommand
|
|
39451
39594
|
} from "@aws-sdk/client-pinpoint-sms-voice-v2";
|
|
39452
|
-
import * as
|
|
39453
|
-
import
|
|
39595
|
+
import * as clack54 from "@clack/prompts";
|
|
39596
|
+
import pc57 from "picocolors";
|
|
39454
39597
|
|
|
39455
39598
|
// src/utils/sms/validation.ts
|
|
39456
39599
|
init_esm_shims();
|
|
@@ -39473,7 +39616,7 @@ async function smsTest(options) {
|
|
|
39473
39616
|
const startTime = Date.now();
|
|
39474
39617
|
const progress = new DeploymentProgress();
|
|
39475
39618
|
if (!isJsonMode()) {
|
|
39476
|
-
|
|
39619
|
+
clack54.intro(pc57.bold("Wraps SMS Test"));
|
|
39477
39620
|
}
|
|
39478
39621
|
const identity = await progress.execute(
|
|
39479
39622
|
"Validating AWS credentials",
|
|
@@ -39483,10 +39626,10 @@ async function smsTest(options) {
|
|
|
39483
39626
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
39484
39627
|
if (!metadata?.services?.sms) {
|
|
39485
39628
|
progress.stop();
|
|
39486
|
-
|
|
39629
|
+
clack54.log.error("No SMS infrastructure found");
|
|
39487
39630
|
console.log(
|
|
39488
39631
|
`
|
|
39489
|
-
Run ${
|
|
39632
|
+
Run ${pc57.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
39490
39633
|
`
|
|
39491
39634
|
);
|
|
39492
39635
|
process.exit(1);
|
|
@@ -39500,7 +39643,7 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39500
39643
|
);
|
|
39501
39644
|
}
|
|
39502
39645
|
if (!toNumber) {
|
|
39503
|
-
const destinationType = await
|
|
39646
|
+
const destinationType = await clack54.select({
|
|
39504
39647
|
message: "Choose destination number:",
|
|
39505
39648
|
options: [
|
|
39506
39649
|
{
|
|
@@ -39515,25 +39658,25 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39515
39658
|
}
|
|
39516
39659
|
]
|
|
39517
39660
|
});
|
|
39518
|
-
if (
|
|
39519
|
-
|
|
39661
|
+
if (clack54.isCancel(destinationType)) {
|
|
39662
|
+
clack54.cancel("Operation cancelled.");
|
|
39520
39663
|
process.exit(0);
|
|
39521
39664
|
}
|
|
39522
39665
|
if (destinationType === "simulator") {
|
|
39523
|
-
const simResult = await
|
|
39666
|
+
const simResult = await clack54.select({
|
|
39524
39667
|
message: "Select simulator destination:",
|
|
39525
39668
|
options: SIMULATOR_DESTINATIONS.map((sim) => ({
|
|
39526
39669
|
value: sim.number,
|
|
39527
39670
|
label: `${sim.number} | ${sim.country}`
|
|
39528
39671
|
}))
|
|
39529
39672
|
});
|
|
39530
|
-
if (
|
|
39531
|
-
|
|
39673
|
+
if (clack54.isCancel(simResult)) {
|
|
39674
|
+
clack54.cancel("Operation cancelled.");
|
|
39532
39675
|
process.exit(0);
|
|
39533
39676
|
}
|
|
39534
39677
|
toNumber = simResult;
|
|
39535
39678
|
} else {
|
|
39536
|
-
const result = await
|
|
39679
|
+
const result = await clack54.text({
|
|
39537
39680
|
message: "Enter destination phone number (E.164 format):",
|
|
39538
39681
|
placeholder: "+14155551234",
|
|
39539
39682
|
validate: (value) => {
|
|
@@ -39546,22 +39689,22 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39546
39689
|
return;
|
|
39547
39690
|
}
|
|
39548
39691
|
});
|
|
39549
|
-
if (
|
|
39550
|
-
|
|
39692
|
+
if (clack54.isCancel(result)) {
|
|
39693
|
+
clack54.cancel("Operation cancelled.");
|
|
39551
39694
|
process.exit(0);
|
|
39552
39695
|
}
|
|
39553
39696
|
toNumber = result;
|
|
39554
39697
|
}
|
|
39555
39698
|
} else if (!isValidPhoneNumber(toNumber)) {
|
|
39556
39699
|
progress.stop();
|
|
39557
|
-
|
|
39700
|
+
clack54.log.error(
|
|
39558
39701
|
`Invalid phone number format: ${toNumber}. Use E.164 format (e.g., +14155551234)`
|
|
39559
39702
|
);
|
|
39560
39703
|
process.exit(1);
|
|
39561
39704
|
}
|
|
39562
39705
|
let message = options.message;
|
|
39563
39706
|
if (!message) {
|
|
39564
|
-
const result = await
|
|
39707
|
+
const result = await clack54.text({
|
|
39565
39708
|
message: "Enter test message:",
|
|
39566
39709
|
placeholder: "Hello from Wraps SMS!",
|
|
39567
39710
|
defaultValue: "Hello from Wraps SMS! This is a test message.",
|
|
@@ -39575,8 +39718,8 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39575
39718
|
return;
|
|
39576
39719
|
}
|
|
39577
39720
|
});
|
|
39578
|
-
if (
|
|
39579
|
-
|
|
39721
|
+
if (clack54.isCancel(result)) {
|
|
39722
|
+
clack54.cancel("Operation cancelled.");
|
|
39580
39723
|
process.exit(0);
|
|
39581
39724
|
}
|
|
39582
39725
|
message = result;
|
|
@@ -39615,16 +39758,16 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39615
39758
|
return;
|
|
39616
39759
|
}
|
|
39617
39760
|
console.log("\n");
|
|
39618
|
-
|
|
39761
|
+
clack54.log.success(pc57.green("Test SMS sent successfully!"));
|
|
39619
39762
|
console.log("");
|
|
39620
|
-
|
|
39763
|
+
clack54.note(
|
|
39621
39764
|
[
|
|
39622
|
-
`${
|
|
39623
|
-
`${
|
|
39624
|
-
`${
|
|
39625
|
-
`${
|
|
39765
|
+
`${pc57.bold("Message ID:")} ${pc57.cyan(messageId || "unknown")}`,
|
|
39766
|
+
`${pc57.bold("To:")} ${pc57.cyan(toNumber)}`,
|
|
39767
|
+
`${pc57.bold("Message:")} ${message}`,
|
|
39768
|
+
`${pc57.bold("Type:")} ${pc57.cyan(smsConfig?.phoneNumberType || "simulator")}`,
|
|
39626
39769
|
"",
|
|
39627
|
-
|
|
39770
|
+
pc57.dim(
|
|
39628
39771
|
smsConfig?.phoneNumberType === "simulator" ? "Note: Simulator messages are not actually delivered" : "Check your phone for the message!"
|
|
39629
39772
|
)
|
|
39630
39773
|
].join("\n"),
|
|
@@ -39632,11 +39775,11 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39632
39775
|
);
|
|
39633
39776
|
if (smsConfig?.eventTracking?.enabled) {
|
|
39634
39777
|
console.log("");
|
|
39635
|
-
|
|
39636
|
-
|
|
39778
|
+
clack54.log.info(
|
|
39779
|
+
pc57.dim("Event tracking is enabled. Check DynamoDB for delivery status.")
|
|
39637
39780
|
);
|
|
39638
39781
|
}
|
|
39639
|
-
|
|
39782
|
+
clack54.outro(pc57.green("Test complete!"));
|
|
39640
39783
|
} catch (error) {
|
|
39641
39784
|
progress.stop();
|
|
39642
39785
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -39648,33 +39791,33 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39648
39791
|
});
|
|
39649
39792
|
const errorName = error instanceof Error ? error.name : "";
|
|
39650
39793
|
if (errorName === "ConflictException" || errorMessage.includes("opt-out")) {
|
|
39651
|
-
|
|
39794
|
+
clack54.log.error("Destination number has opted out of messages");
|
|
39652
39795
|
console.log("\nThe recipient has opted out of receiving SMS messages.\n");
|
|
39653
39796
|
} else if (errorName === "ThrottlingException" || errorMessage.includes("spending limit")) {
|
|
39654
|
-
|
|
39797
|
+
clack54.log.error("SMS rate or spending limit reached");
|
|
39655
39798
|
console.log(
|
|
39656
39799
|
"\nCheck your AWS account SMS spending limits in the console.\n"
|
|
39657
39800
|
);
|
|
39658
39801
|
} else if (errorName === "ValidationException") {
|
|
39659
|
-
|
|
39802
|
+
clack54.log.error(`Invalid request: ${errorMessage}`);
|
|
39660
39803
|
} else if (errorMessage.includes("not verified") || errorMessage.includes("not registered")) {
|
|
39661
|
-
|
|
39804
|
+
clack54.log.error("Toll-free number registration is not complete");
|
|
39662
39805
|
console.log(
|
|
39663
39806
|
`
|
|
39664
|
-
Run ${
|
|
39807
|
+
Run ${pc57.cyan("wraps sms register")} to check registration status.
|
|
39665
39808
|
`
|
|
39666
39809
|
);
|
|
39667
39810
|
} else if (errorName === "AccessDeniedException") {
|
|
39668
|
-
|
|
39811
|
+
clack54.log.error(
|
|
39669
39812
|
"Permission denied \u2014 IAM role may be missing SMS send permissions"
|
|
39670
39813
|
);
|
|
39671
39814
|
console.log(
|
|
39672
39815
|
`
|
|
39673
|
-
Run ${
|
|
39816
|
+
Run ${pc57.cyan("wraps sms upgrade")} to update IAM policies.
|
|
39674
39817
|
`
|
|
39675
39818
|
);
|
|
39676
39819
|
} else {
|
|
39677
|
-
|
|
39820
|
+
clack54.log.error(`Failed to send SMS: ${errorMessage}`);
|
|
39678
39821
|
}
|
|
39679
39822
|
process.exit(1);
|
|
39680
39823
|
}
|
|
@@ -39682,9 +39825,9 @@ Run ${pc56.cyan("wraps sms upgrade")} to update IAM policies.
|
|
|
39682
39825
|
|
|
39683
39826
|
// src/commands/sms/upgrade.ts
|
|
39684
39827
|
init_esm_shims();
|
|
39685
|
-
import * as
|
|
39828
|
+
import * as clack55 from "@clack/prompts";
|
|
39686
39829
|
import * as pulumi35 from "@pulumi/pulumi";
|
|
39687
|
-
import
|
|
39830
|
+
import pc58 from "picocolors";
|
|
39688
39831
|
init_events();
|
|
39689
39832
|
init_aws();
|
|
39690
39833
|
init_errors();
|
|
@@ -39699,7 +39842,7 @@ async function smsUpgrade(options) {
|
|
|
39699
39842
|
const startTime = Date.now();
|
|
39700
39843
|
let upgradeAction = "";
|
|
39701
39844
|
if (!isJsonMode()) {
|
|
39702
|
-
|
|
39845
|
+
clack55.intro(pc58.bold("Wraps SMS Upgrade - Enhance Your SMS Infrastructure"));
|
|
39703
39846
|
}
|
|
39704
39847
|
const progress = new DeploymentProgress();
|
|
39705
39848
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -39713,7 +39856,7 @@ async function smsUpgrade(options) {
|
|
|
39713
39856
|
"Validating AWS credentials",
|
|
39714
39857
|
async () => validateAWSCredentials()
|
|
39715
39858
|
);
|
|
39716
|
-
progress.info(`Connected to AWS account: ${
|
|
39859
|
+
progress.info(`Connected to AWS account: ${pc58.cyan(identity.accountId)}`);
|
|
39717
39860
|
const region = await resolveRegionForCommand({
|
|
39718
39861
|
accountId: identity.accountId,
|
|
39719
39862
|
optionRegion: options.region,
|
|
@@ -39722,35 +39865,35 @@ async function smsUpgrade(options) {
|
|
|
39722
39865
|
});
|
|
39723
39866
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
39724
39867
|
if (!metadata) {
|
|
39725
|
-
|
|
39726
|
-
`No Wraps connection found for account ${
|
|
39868
|
+
clack55.log.error(
|
|
39869
|
+
`No Wraps connection found for account ${pc58.cyan(identity.accountId)} in region ${pc58.cyan(region)}`
|
|
39727
39870
|
);
|
|
39728
|
-
|
|
39729
|
-
`Use ${
|
|
39871
|
+
clack55.log.info(
|
|
39872
|
+
`Use ${pc58.cyan("wraps sms init")} to create new infrastructure.`
|
|
39730
39873
|
);
|
|
39731
39874
|
process.exit(1);
|
|
39732
39875
|
}
|
|
39733
39876
|
if (!metadata.services.sms) {
|
|
39734
|
-
|
|
39735
|
-
|
|
39736
|
-
`Use ${
|
|
39877
|
+
clack55.log.error("No SMS infrastructure found");
|
|
39878
|
+
clack55.log.info(
|
|
39879
|
+
`Use ${pc58.cyan("wraps sms init")} to deploy SMS infrastructure.`
|
|
39737
39880
|
);
|
|
39738
39881
|
process.exit(1);
|
|
39739
39882
|
}
|
|
39740
39883
|
progress.info(`Found existing connection created: ${metadata.timestamp}`);
|
|
39741
39884
|
console.log(`
|
|
39742
|
-
${
|
|
39885
|
+
${pc58.bold("Current Configuration:")}
|
|
39743
39886
|
`);
|
|
39744
39887
|
if (metadata.services.sms.preset) {
|
|
39745
|
-
console.log(` Preset: ${
|
|
39888
|
+
console.log(` Preset: ${pc58.cyan(metadata.services.sms.preset)}`);
|
|
39746
39889
|
} else {
|
|
39747
|
-
console.log(` Preset: ${
|
|
39890
|
+
console.log(` Preset: ${pc58.cyan("custom")}`);
|
|
39748
39891
|
}
|
|
39749
39892
|
const config2 = metadata.services.sms.config;
|
|
39750
39893
|
if (!config2) {
|
|
39751
|
-
|
|
39752
|
-
|
|
39753
|
-
`Use ${
|
|
39894
|
+
clack55.log.error("No SMS configuration found in metadata");
|
|
39895
|
+
clack55.log.info(
|
|
39896
|
+
`Use ${pc58.cyan("wraps sms init")} to create new infrastructure.`
|
|
39754
39897
|
);
|
|
39755
39898
|
process.exit(1);
|
|
39756
39899
|
}
|
|
@@ -39762,45 +39905,45 @@ ${pc57.bold("Current Configuration:")}
|
|
|
39762
39905
|
"short-code": "Short code ($995+/mo, 100+ MPS)"
|
|
39763
39906
|
};
|
|
39764
39907
|
console.log(
|
|
39765
|
-
` Phone Type: ${
|
|
39908
|
+
` Phone Type: ${pc58.cyan(phoneTypeLabels2[config2.phoneNumberType] || config2.phoneNumberType)}`
|
|
39766
39909
|
);
|
|
39767
39910
|
}
|
|
39768
39911
|
if (config2.tracking?.enabled) {
|
|
39769
|
-
console.log(` ${
|
|
39912
|
+
console.log(` ${pc58.green("\u2713")} Delivery Tracking`);
|
|
39770
39913
|
if (config2.tracking.linkTracking) {
|
|
39771
|
-
console.log(` ${
|
|
39914
|
+
console.log(` ${pc58.dim("\u2514\u2500")} Link click tracking enabled`);
|
|
39772
39915
|
}
|
|
39773
39916
|
}
|
|
39774
39917
|
if (config2.eventTracking?.enabled) {
|
|
39775
|
-
console.log(` ${
|
|
39918
|
+
console.log(` ${pc58.green("\u2713")} Event Tracking (SNS)`);
|
|
39776
39919
|
if (config2.eventTracking.dynamoDBHistory) {
|
|
39777
39920
|
console.log(
|
|
39778
|
-
` ${
|
|
39921
|
+
` ${pc58.dim("\u2514\u2500")} Message History: ${pc58.cyan(config2.eventTracking.archiveRetention || "90days")}`
|
|
39779
39922
|
);
|
|
39780
39923
|
}
|
|
39781
39924
|
}
|
|
39782
39925
|
if (config2.messageArchiving?.enabled) {
|
|
39783
39926
|
console.log(
|
|
39784
|
-
` ${
|
|
39927
|
+
` ${pc58.green("\u2713")} Message Archiving (${config2.messageArchiving.retention})`
|
|
39785
39928
|
);
|
|
39786
39929
|
}
|
|
39787
39930
|
if (config2.optOutManagement) {
|
|
39788
|
-
console.log(` ${
|
|
39931
|
+
console.log(` ${pc58.green("\u2713")} Opt-out Management`);
|
|
39789
39932
|
}
|
|
39790
39933
|
if (config2.protectConfiguration?.enabled) {
|
|
39791
39934
|
const countries = config2.protectConfiguration.allowedCountries?.join(", ") || "US";
|
|
39792
|
-
console.log(` ${
|
|
39793
|
-
console.log(` ${
|
|
39935
|
+
console.log(` ${pc58.green("\u2713")} Fraud Protection`);
|
|
39936
|
+
console.log(` ${pc58.dim("\u2514\u2500")} Allowed countries: ${pc58.cyan(countries)}`);
|
|
39794
39937
|
if (config2.protectConfiguration.aitFiltering) {
|
|
39795
|
-
console.log(` ${
|
|
39938
|
+
console.log(` ${pc58.dim("\u2514\u2500")} AIT filtering: ${pc58.cyan("enabled")}`);
|
|
39796
39939
|
}
|
|
39797
39940
|
} else {
|
|
39798
|
-
console.log(` ${
|
|
39941
|
+
console.log(` ${pc58.dim("\u25CB")} Fraud Protection (not configured)`);
|
|
39799
39942
|
}
|
|
39800
39943
|
const currentCostData = calculateSMSCosts(config2, 1e4);
|
|
39801
39944
|
console.log(
|
|
39802
39945
|
`
|
|
39803
|
-
Estimated Cost: ${
|
|
39946
|
+
Estimated Cost: ${pc58.cyan(`~${formatCost3(currentCostData.total.monthly)}/mo`)}`
|
|
39804
39947
|
);
|
|
39805
39948
|
console.log("");
|
|
39806
39949
|
const phoneTypeLabels = {
|
|
@@ -39809,7 +39952,7 @@ ${pc57.bold("Current Configuration:")}
|
|
|
39809
39952
|
"10dlc": "10DLC",
|
|
39810
39953
|
"short-code": "Short code"
|
|
39811
39954
|
};
|
|
39812
|
-
upgradeAction = await
|
|
39955
|
+
upgradeAction = await clack55.select({
|
|
39813
39956
|
message: "What would you like to do?",
|
|
39814
39957
|
options: [
|
|
39815
39958
|
{
|
|
@@ -39849,8 +39992,8 @@ ${pc57.bold("Current Configuration:")}
|
|
|
39849
39992
|
}
|
|
39850
39993
|
]
|
|
39851
39994
|
});
|
|
39852
|
-
if (
|
|
39853
|
-
|
|
39995
|
+
if (clack55.isCancel(upgradeAction)) {
|
|
39996
|
+
clack55.cancel("Upgrade cancelled.");
|
|
39854
39997
|
process.exit(0);
|
|
39855
39998
|
}
|
|
39856
39999
|
let updatedConfig = { ...config2 };
|
|
@@ -39891,65 +40034,65 @@ ${pc57.bold("Current Configuration:")}
|
|
|
39891
40034
|
hint: p.hint
|
|
39892
40035
|
}));
|
|
39893
40036
|
if (availableTypes.length === 0) {
|
|
39894
|
-
|
|
40037
|
+
clack55.log.warn(
|
|
39895
40038
|
"Already on highest phone number tier. Contact AWS for dedicated short codes."
|
|
39896
40039
|
);
|
|
39897
40040
|
process.exit(0);
|
|
39898
40041
|
}
|
|
39899
|
-
const selectedType = await
|
|
40042
|
+
const selectedType = await clack55.select({
|
|
39900
40043
|
message: "Select new phone number type:",
|
|
39901
40044
|
options: availableTypes
|
|
39902
40045
|
});
|
|
39903
|
-
if (
|
|
39904
|
-
|
|
40046
|
+
if (clack55.isCancel(selectedType)) {
|
|
40047
|
+
clack55.cancel("Upgrade cancelled.");
|
|
39905
40048
|
process.exit(0);
|
|
39906
40049
|
}
|
|
39907
40050
|
if (selectedType === "toll-free") {
|
|
39908
40051
|
console.log(
|
|
39909
40052
|
`
|
|
39910
|
-
${
|
|
40053
|
+
${pc58.yellow("\u26A0")} ${pc58.bold("Toll-free Registration Required")}
|
|
39911
40054
|
`
|
|
39912
40055
|
);
|
|
39913
40056
|
console.log(
|
|
39914
|
-
|
|
40057
|
+
pc58.dim("Toll-free numbers require carrier registration before")
|
|
39915
40058
|
);
|
|
39916
40059
|
console.log(
|
|
39917
|
-
|
|
40060
|
+
pc58.dim("they can send messages at scale. After deployment:\n")
|
|
39918
40061
|
);
|
|
39919
40062
|
console.log(
|
|
39920
|
-
` 1. Run ${
|
|
40063
|
+
` 1. Run ${pc58.cyan("wraps sms register")} to start registration`
|
|
39921
40064
|
);
|
|
39922
40065
|
console.log(" 2. Submit your business use case information");
|
|
39923
40066
|
console.log(" 3. Wait for carrier verification (1-5 business days)");
|
|
39924
40067
|
console.log(
|
|
39925
|
-
|
|
40068
|
+
pc58.dim("\nUntil verified, sending is limited to low volume.\n")
|
|
39926
40069
|
);
|
|
39927
|
-
const confirmTollFree = await
|
|
40070
|
+
const confirmTollFree = await clack55.confirm({
|
|
39928
40071
|
message: "Continue with toll-free number request?",
|
|
39929
40072
|
initialValue: true
|
|
39930
40073
|
});
|
|
39931
|
-
if (
|
|
39932
|
-
|
|
40074
|
+
if (clack55.isCancel(confirmTollFree) || !confirmTollFree) {
|
|
40075
|
+
clack55.cancel("Upgrade cancelled.");
|
|
39933
40076
|
process.exit(0);
|
|
39934
40077
|
}
|
|
39935
40078
|
}
|
|
39936
40079
|
if (selectedType === "10dlc") {
|
|
39937
40080
|
console.log(
|
|
39938
40081
|
`
|
|
39939
|
-
${
|
|
40082
|
+
${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
39940
40083
|
`
|
|
39941
40084
|
);
|
|
39942
|
-
console.log(
|
|
40085
|
+
console.log(pc58.dim("10DLC requires brand and campaign registration:"));
|
|
39943
40086
|
console.log(" \u2022 Brand registration: one-time $4 fee");
|
|
39944
40087
|
console.log(" \u2022 Campaign registration: $15/mo per campaign");
|
|
39945
40088
|
console.log(" \u2022 Verification takes 1-7 business days");
|
|
39946
40089
|
console.log("");
|
|
39947
|
-
const confirm10DLC = await
|
|
40090
|
+
const confirm10DLC = await clack55.confirm({
|
|
39948
40091
|
message: "Continue with 10DLC number request?",
|
|
39949
40092
|
initialValue: true
|
|
39950
40093
|
});
|
|
39951
|
-
if (
|
|
39952
|
-
|
|
40094
|
+
if (clack55.isCancel(confirm10DLC) || !confirm10DLC) {
|
|
40095
|
+
clack55.cancel("Upgrade cancelled.");
|
|
39953
40096
|
process.exit(0);
|
|
39954
40097
|
}
|
|
39955
40098
|
}
|
|
@@ -39974,15 +40117,15 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
39974
40117
|
disabled: currentPresetIdx >= 0 && idx <= currentPresetIdx ? "Current or lower tier" : void 0
|
|
39975
40118
|
})).filter((p) => !p.disabled && p.value !== "custom");
|
|
39976
40119
|
if (availablePresets.length === 0) {
|
|
39977
|
-
|
|
40120
|
+
clack55.log.warn("Already on highest preset (Enterprise)");
|
|
39978
40121
|
process.exit(0);
|
|
39979
40122
|
}
|
|
39980
|
-
const selectedPreset = await
|
|
40123
|
+
const selectedPreset = await clack55.select({
|
|
39981
40124
|
message: "Select new preset:",
|
|
39982
40125
|
options: availablePresets
|
|
39983
40126
|
});
|
|
39984
|
-
if (
|
|
39985
|
-
|
|
40127
|
+
if (clack55.isCancel(selectedPreset)) {
|
|
40128
|
+
clack55.cancel("Upgrade cancelled.");
|
|
39986
40129
|
process.exit(0);
|
|
39987
40130
|
}
|
|
39988
40131
|
const presetConfig = getSMSPreset(selectedPreset);
|
|
@@ -39998,7 +40141,7 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
39998
40141
|
}
|
|
39999
40142
|
case "event-tracking": {
|
|
40000
40143
|
if (config2.eventTracking?.enabled) {
|
|
40001
|
-
const eventAction = await
|
|
40144
|
+
const eventAction = await clack55.select({
|
|
40002
40145
|
message: "What would you like to do with event tracking?",
|
|
40003
40146
|
options: [
|
|
40004
40147
|
{
|
|
@@ -40013,17 +40156,17 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40013
40156
|
}
|
|
40014
40157
|
]
|
|
40015
40158
|
});
|
|
40016
|
-
if (
|
|
40017
|
-
|
|
40159
|
+
if (clack55.isCancel(eventAction)) {
|
|
40160
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40018
40161
|
process.exit(0);
|
|
40019
40162
|
}
|
|
40020
40163
|
if (eventAction === "disable") {
|
|
40021
|
-
const confirmDisable = await
|
|
40164
|
+
const confirmDisable = await clack55.confirm({
|
|
40022
40165
|
message: "Are you sure? Existing history will remain, but new events won't be tracked.",
|
|
40023
40166
|
initialValue: false
|
|
40024
40167
|
});
|
|
40025
|
-
if (
|
|
40026
|
-
|
|
40168
|
+
if (clack55.isCancel(confirmDisable) || !confirmDisable) {
|
|
40169
|
+
clack55.cancel("Event tracking not disabled.");
|
|
40027
40170
|
process.exit(0);
|
|
40028
40171
|
}
|
|
40029
40172
|
updatedConfig = {
|
|
@@ -40033,7 +40176,7 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40033
40176
|
}
|
|
40034
40177
|
};
|
|
40035
40178
|
} else {
|
|
40036
|
-
const retention = await
|
|
40179
|
+
const retention = await clack55.select({
|
|
40037
40180
|
message: "Message history retention period:",
|
|
40038
40181
|
options: [
|
|
40039
40182
|
{ value: "7days", label: "7 days", hint: "Minimal storage cost" },
|
|
@@ -40060,8 +40203,8 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40060
40203
|
],
|
|
40061
40204
|
initialValue: config2.eventTracking.archiveRetention || "90days"
|
|
40062
40205
|
});
|
|
40063
|
-
if (
|
|
40064
|
-
|
|
40206
|
+
if (clack55.isCancel(retention)) {
|
|
40207
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40065
40208
|
process.exit(0);
|
|
40066
40209
|
}
|
|
40067
40210
|
updatedConfig = {
|
|
@@ -40073,19 +40216,19 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40073
40216
|
};
|
|
40074
40217
|
}
|
|
40075
40218
|
} else {
|
|
40076
|
-
const enableTracking = await
|
|
40219
|
+
const enableTracking = await clack55.confirm({
|
|
40077
40220
|
message: "Enable event tracking? (Track SMS events with history)",
|
|
40078
40221
|
initialValue: true
|
|
40079
40222
|
});
|
|
40080
|
-
if (
|
|
40081
|
-
|
|
40223
|
+
if (clack55.isCancel(enableTracking)) {
|
|
40224
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40082
40225
|
process.exit(0);
|
|
40083
40226
|
}
|
|
40084
40227
|
if (!enableTracking) {
|
|
40085
|
-
|
|
40228
|
+
clack55.log.info("Event tracking not enabled.");
|
|
40086
40229
|
process.exit(0);
|
|
40087
40230
|
}
|
|
40088
|
-
const retention = await
|
|
40231
|
+
const retention = await clack55.select({
|
|
40089
40232
|
message: "Message history retention period:",
|
|
40090
40233
|
options: [
|
|
40091
40234
|
{ value: "7days", label: "7 days", hint: "Minimal storage cost" },
|
|
@@ -40108,8 +40251,8 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40108
40251
|
],
|
|
40109
40252
|
initialValue: "90days"
|
|
40110
40253
|
});
|
|
40111
|
-
if (
|
|
40112
|
-
|
|
40254
|
+
if (clack55.isCancel(retention)) {
|
|
40255
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40113
40256
|
process.exit(0);
|
|
40114
40257
|
}
|
|
40115
40258
|
updatedConfig = {
|
|
@@ -40128,12 +40271,12 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40128
40271
|
}
|
|
40129
40272
|
case "retention": {
|
|
40130
40273
|
if (!config2.eventTracking?.enabled) {
|
|
40131
|
-
|
|
40274
|
+
clack55.log.error(
|
|
40132
40275
|
"Event tracking is not enabled. Enable it first to change retention."
|
|
40133
40276
|
);
|
|
40134
40277
|
process.exit(1);
|
|
40135
40278
|
}
|
|
40136
|
-
const retention = await
|
|
40279
|
+
const retention = await clack55.select({
|
|
40137
40280
|
message: "Message history retention period (event data in DynamoDB):",
|
|
40138
40281
|
options: [
|
|
40139
40282
|
{ value: "7days", label: "7 days", hint: "Minimal storage cost" },
|
|
@@ -40152,8 +40295,8 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40152
40295
|
],
|
|
40153
40296
|
initialValue: config2.eventTracking.archiveRetention || "90days"
|
|
40154
40297
|
});
|
|
40155
|
-
if (
|
|
40156
|
-
|
|
40298
|
+
if (clack55.isCancel(retention)) {
|
|
40299
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40157
40300
|
process.exit(0);
|
|
40158
40301
|
}
|
|
40159
40302
|
updatedConfig = {
|
|
@@ -40171,21 +40314,21 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40171
40314
|
case "link-tracking": {
|
|
40172
40315
|
const enableLinkTracking = !config2.tracking?.linkTracking;
|
|
40173
40316
|
if (enableLinkTracking) {
|
|
40174
|
-
|
|
40175
|
-
|
|
40317
|
+
clack55.log.info(
|
|
40318
|
+
pc58.dim(
|
|
40176
40319
|
"Link tracking will track clicks on URLs in your SMS messages."
|
|
40177
40320
|
)
|
|
40178
40321
|
);
|
|
40179
|
-
|
|
40180
|
-
|
|
40322
|
+
clack55.log.info(
|
|
40323
|
+
pc58.dim("URLs will be rewritten to go through a tracking endpoint.")
|
|
40181
40324
|
);
|
|
40182
40325
|
}
|
|
40183
|
-
const confirmed = await
|
|
40326
|
+
const confirmed = await clack55.confirm({
|
|
40184
40327
|
message: enableLinkTracking ? "Enable link click tracking?" : "Disable link click tracking?",
|
|
40185
40328
|
initialValue: enableLinkTracking
|
|
40186
40329
|
});
|
|
40187
|
-
if (
|
|
40188
|
-
|
|
40330
|
+
if (clack55.isCancel(confirmed) || !confirmed) {
|
|
40331
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40189
40332
|
process.exit(0);
|
|
40190
40333
|
}
|
|
40191
40334
|
updatedConfig = {
|
|
@@ -40202,7 +40345,7 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40202
40345
|
}
|
|
40203
40346
|
case "archiving": {
|
|
40204
40347
|
if (config2.messageArchiving?.enabled) {
|
|
40205
|
-
const archivingAction = await
|
|
40348
|
+
const archivingAction = await clack55.select({
|
|
40206
40349
|
message: "What would you like to do with message archiving?",
|
|
40207
40350
|
options: [
|
|
40208
40351
|
{
|
|
@@ -40217,17 +40360,17 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40217
40360
|
}
|
|
40218
40361
|
]
|
|
40219
40362
|
});
|
|
40220
|
-
if (
|
|
40221
|
-
|
|
40363
|
+
if (clack55.isCancel(archivingAction)) {
|
|
40364
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40222
40365
|
process.exit(0);
|
|
40223
40366
|
}
|
|
40224
40367
|
if (archivingAction === "disable") {
|
|
40225
|
-
const confirmDisable = await
|
|
40368
|
+
const confirmDisable = await clack55.confirm({
|
|
40226
40369
|
message: "Are you sure? Existing archived messages will remain, but new messages won't be archived.",
|
|
40227
40370
|
initialValue: false
|
|
40228
40371
|
});
|
|
40229
|
-
if (
|
|
40230
|
-
|
|
40372
|
+
if (clack55.isCancel(confirmDisable) || !confirmDisable) {
|
|
40373
|
+
clack55.cancel("Archiving not disabled.");
|
|
40231
40374
|
process.exit(0);
|
|
40232
40375
|
}
|
|
40233
40376
|
updatedConfig = {
|
|
@@ -40238,7 +40381,7 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40238
40381
|
}
|
|
40239
40382
|
};
|
|
40240
40383
|
} else {
|
|
40241
|
-
const retention = await
|
|
40384
|
+
const retention = await clack55.select({
|
|
40242
40385
|
message: "Message archive retention period:",
|
|
40243
40386
|
options: [
|
|
40244
40387
|
{
|
|
@@ -40269,8 +40412,8 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40269
40412
|
],
|
|
40270
40413
|
initialValue: config2.messageArchiving.retention
|
|
40271
40414
|
});
|
|
40272
|
-
if (
|
|
40273
|
-
|
|
40415
|
+
if (clack55.isCancel(retention)) {
|
|
40416
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40274
40417
|
process.exit(0);
|
|
40275
40418
|
}
|
|
40276
40419
|
updatedConfig = {
|
|
@@ -40282,19 +40425,19 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40282
40425
|
};
|
|
40283
40426
|
}
|
|
40284
40427
|
} else {
|
|
40285
|
-
const enableArchiving = await
|
|
40428
|
+
const enableArchiving = await clack55.confirm({
|
|
40286
40429
|
message: "Enable message archiving? (Store full message content for viewing)",
|
|
40287
40430
|
initialValue: true
|
|
40288
40431
|
});
|
|
40289
|
-
if (
|
|
40290
|
-
|
|
40432
|
+
if (clack55.isCancel(enableArchiving)) {
|
|
40433
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40291
40434
|
process.exit(0);
|
|
40292
40435
|
}
|
|
40293
40436
|
if (!enableArchiving) {
|
|
40294
|
-
|
|
40437
|
+
clack55.log.info("Message archiving not enabled.");
|
|
40295
40438
|
process.exit(0);
|
|
40296
40439
|
}
|
|
40297
|
-
const retention = await
|
|
40440
|
+
const retention = await clack55.select({
|
|
40298
40441
|
message: "Message archive retention period:",
|
|
40299
40442
|
options: [
|
|
40300
40443
|
{ value: "7days", label: "7 days", hint: "~$1-2/mo for 10k msgs" },
|
|
@@ -40321,8 +40464,8 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40321
40464
|
],
|
|
40322
40465
|
initialValue: "90days"
|
|
40323
40466
|
});
|
|
40324
|
-
if (
|
|
40325
|
-
|
|
40467
|
+
if (clack55.isCancel(retention)) {
|
|
40468
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40326
40469
|
process.exit(0);
|
|
40327
40470
|
}
|
|
40328
40471
|
updatedConfig = {
|
|
@@ -40354,7 +40497,7 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40354
40497
|
const currentAllowed = config2.protectConfiguration?.allowedCountries || [
|
|
40355
40498
|
"US"
|
|
40356
40499
|
];
|
|
40357
|
-
const selectedCountries = await
|
|
40500
|
+
const selectedCountries = await clack55.multiselect({
|
|
40358
40501
|
message: "Select countries to allow SMS delivery (all others blocked):",
|
|
40359
40502
|
options: commonCountries.map((c) => ({
|
|
40360
40503
|
value: c.code,
|
|
@@ -40363,16 +40506,16 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40363
40506
|
initialValues: currentAllowed,
|
|
40364
40507
|
required: true
|
|
40365
40508
|
});
|
|
40366
|
-
if (
|
|
40367
|
-
|
|
40509
|
+
if (clack55.isCancel(selectedCountries)) {
|
|
40510
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40368
40511
|
process.exit(0);
|
|
40369
40512
|
}
|
|
40370
|
-
const enableAIT = await
|
|
40513
|
+
const enableAIT = await clack55.confirm({
|
|
40371
40514
|
message: "Enable AIT (Artificially Inflated Traffic) filtering? (adds per-message cost)",
|
|
40372
40515
|
initialValue: config2.protectConfiguration?.aitFiltering ?? false
|
|
40373
40516
|
});
|
|
40374
|
-
if (
|
|
40375
|
-
|
|
40517
|
+
if (clack55.isCancel(enableAIT)) {
|
|
40518
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40376
40519
|
process.exit(0);
|
|
40377
40520
|
}
|
|
40378
40521
|
updatedConfig = {
|
|
@@ -40390,28 +40533,28 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40390
40533
|
const newCostData = calculateSMSCosts(updatedConfig, 1e4);
|
|
40391
40534
|
const costDiff = newCostData.total.monthly - currentCostData.total.monthly;
|
|
40392
40535
|
console.log(`
|
|
40393
|
-
${
|
|
40536
|
+
${pc58.bold("Cost Impact:")}`);
|
|
40394
40537
|
console.log(
|
|
40395
|
-
` Current: ${
|
|
40538
|
+
` Current: ${pc58.cyan(`${formatCost3(currentCostData.total.monthly)}/mo`)}`
|
|
40396
40539
|
);
|
|
40397
40540
|
console.log(
|
|
40398
|
-
` New: ${
|
|
40541
|
+
` New: ${pc58.cyan(`${formatCost3(newCostData.total.monthly)}/mo`)}`
|
|
40399
40542
|
);
|
|
40400
40543
|
if (costDiff > 0) {
|
|
40401
|
-
console.log(` Change: ${
|
|
40544
|
+
console.log(` Change: ${pc58.yellow(`+${formatCost3(costDiff)}/mo`)}`);
|
|
40402
40545
|
} else if (costDiff < 0) {
|
|
40403
40546
|
console.log(
|
|
40404
|
-
` Change: ${
|
|
40547
|
+
` Change: ${pc58.green(`-${formatCost3(Math.abs(costDiff))}/mo`)}`
|
|
40405
40548
|
);
|
|
40406
40549
|
}
|
|
40407
40550
|
console.log("");
|
|
40408
40551
|
if (!(options.yes || options.preview)) {
|
|
40409
|
-
const confirmed = await
|
|
40552
|
+
const confirmed = await clack55.confirm({
|
|
40410
40553
|
message: "Proceed with upgrade?",
|
|
40411
40554
|
initialValue: true
|
|
40412
40555
|
});
|
|
40413
|
-
if (
|
|
40414
|
-
|
|
40556
|
+
if (clack55.isCancel(confirmed) || !confirmed) {
|
|
40557
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40415
40558
|
process.exit(0);
|
|
40416
40559
|
}
|
|
40417
40560
|
}
|
|
@@ -40480,8 +40623,8 @@ ${pc57.bold("Cost Impact:")}`);
|
|
|
40480
40623
|
resourceChanges: previewResult.resourceChanges,
|
|
40481
40624
|
commandName: "wraps sms upgrade"
|
|
40482
40625
|
});
|
|
40483
|
-
|
|
40484
|
-
|
|
40626
|
+
clack55.outro(
|
|
40627
|
+
pc58.green("Preview complete. Run without --preview to upgrade.")
|
|
40485
40628
|
);
|
|
40486
40629
|
trackServiceUpgrade("sms", {
|
|
40487
40630
|
region,
|
|
@@ -40586,43 +40729,43 @@ ${pc57.bold("Cost Impact:")}`);
|
|
|
40586
40729
|
}
|
|
40587
40730
|
progress.info("Connection metadata updated");
|
|
40588
40731
|
console.log("\n");
|
|
40589
|
-
|
|
40732
|
+
clack55.log.success(pc58.green(pc58.bold("SMS infrastructure upgraded!")));
|
|
40590
40733
|
console.log("\n");
|
|
40591
|
-
|
|
40734
|
+
clack55.note(
|
|
40592
40735
|
[
|
|
40593
|
-
`${
|
|
40594
|
-
`${
|
|
40595
|
-
`${
|
|
40596
|
-
`${
|
|
40597
|
-
outputs.tableName ? `${
|
|
40736
|
+
`${pc58.bold("Phone Number:")} ${pc58.cyan(outputs.phoneNumber || "Provisioning...")}`,
|
|
40737
|
+
`${pc58.bold("Phone Type:")} ${pc58.cyan(updatedConfig.phoneNumberType || "simulator")}`,
|
|
40738
|
+
`${pc58.bold("Config Set:")} ${pc58.cyan(outputs.configSetName || "wraps-sms-config")}`,
|
|
40739
|
+
`${pc58.bold("Region:")} ${pc58.cyan(outputs.region)}`,
|
|
40740
|
+
outputs.tableName ? `${pc58.bold("History Table:")} ${pc58.cyan(outputs.tableName)}` : "",
|
|
40598
40741
|
"",
|
|
40599
|
-
|
|
40600
|
-
|
|
40742
|
+
pc58.dim("IAM Role:"),
|
|
40743
|
+
pc58.dim(` ${outputs.roleArn}`)
|
|
40601
40744
|
].filter(Boolean).join("\n"),
|
|
40602
40745
|
"SMS Infrastructure"
|
|
40603
40746
|
);
|
|
40604
40747
|
console.log(`
|
|
40605
|
-
${
|
|
40748
|
+
${pc58.green("\u2713")} ${pc58.bold("Upgrade complete!")}
|
|
40606
40749
|
`);
|
|
40607
40750
|
if (upgradeAction === "phone-number") {
|
|
40608
40751
|
console.log(
|
|
40609
|
-
`Upgraded to ${
|
|
40752
|
+
`Upgraded to ${pc58.cyan(updatedConfig.phoneNumberType)} number (${pc58.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
40610
40753
|
`
|
|
40611
40754
|
);
|
|
40612
40755
|
if (updatedConfig.phoneNumberType === "toll-free") {
|
|
40613
|
-
console.log(`${
|
|
40756
|
+
console.log(`${pc58.bold("Next Steps:")}`);
|
|
40614
40757
|
console.log(
|
|
40615
|
-
` 1. Run ${
|
|
40758
|
+
` 1. Run ${pc58.cyan("wraps sms register")} to start toll-free registration`
|
|
40616
40759
|
);
|
|
40617
40760
|
console.log(" 2. Submit your business information and use case");
|
|
40618
40761
|
console.log(" 3. Wait for carrier verification (1-5 business days)");
|
|
40619
40762
|
console.log("");
|
|
40620
40763
|
console.log(
|
|
40621
|
-
|
|
40764
|
+
pc58.dim("Until verified, your number can only send limited messages.")
|
|
40622
40765
|
);
|
|
40623
40766
|
console.log("");
|
|
40624
40767
|
} else if (updatedConfig.phoneNumberType === "10dlc") {
|
|
40625
|
-
console.log(`${
|
|
40768
|
+
console.log(`${pc58.bold("Next Steps:")}`);
|
|
40626
40769
|
console.log(" 1. Register your brand in the AWS Console");
|
|
40627
40770
|
console.log(" 2. Create a 10DLC campaign for your use case");
|
|
40628
40771
|
console.log(" 3. Wait for campaign approval (1-7 business days)");
|
|
@@ -40630,16 +40773,16 @@ ${pc57.green("\u2713")} ${pc57.bold("Upgrade complete!")}
|
|
|
40630
40773
|
}
|
|
40631
40774
|
} else if (upgradeAction === "preset" && newPreset) {
|
|
40632
40775
|
console.log(
|
|
40633
|
-
`Upgraded to ${
|
|
40776
|
+
`Upgraded to ${pc58.cyan(newPreset)} preset (${pc58.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
40634
40777
|
`
|
|
40635
40778
|
);
|
|
40636
40779
|
} else {
|
|
40637
40780
|
console.log(
|
|
40638
|
-
`Updated configuration (${
|
|
40781
|
+
`Updated configuration (${pc58.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
40639
40782
|
`
|
|
40640
40783
|
);
|
|
40641
40784
|
}
|
|
40642
|
-
console.log(
|
|
40785
|
+
console.log(pc58.dim(getSMSCostSummary(updatedConfig, 1e4)));
|
|
40643
40786
|
const enabledFeatures = [];
|
|
40644
40787
|
if (updatedConfig.tracking?.enabled) {
|
|
40645
40788
|
enabledFeatures.push("tracking");
|
|
@@ -40663,7 +40806,7 @@ ${pc57.green("\u2713")} ${pc57.bold("Upgrade complete!")}
|
|
|
40663
40806
|
action: typeof upgradeAction === "string" ? upgradeAction : void 0,
|
|
40664
40807
|
duration_ms: Date.now() - startTime
|
|
40665
40808
|
});
|
|
40666
|
-
|
|
40809
|
+
clack55.outro(pc58.green("Upgrade complete!"));
|
|
40667
40810
|
}
|
|
40668
40811
|
|
|
40669
40812
|
// src/commands/sms/verify-number.ts
|
|
@@ -40682,13 +40825,13 @@ import {
|
|
|
40682
40825
|
SendDestinationNumberVerificationCodeCommand,
|
|
40683
40826
|
VerifyDestinationNumberCommand
|
|
40684
40827
|
} from "@aws-sdk/client-pinpoint-sms-voice-v2";
|
|
40685
|
-
import * as
|
|
40686
|
-
import
|
|
40828
|
+
import * as clack56 from "@clack/prompts";
|
|
40829
|
+
import pc59 from "picocolors";
|
|
40687
40830
|
async function smsVerifyNumber(options) {
|
|
40688
40831
|
const startTime = Date.now();
|
|
40689
40832
|
const progress = new DeploymentProgress();
|
|
40690
40833
|
if (!isJsonMode()) {
|
|
40691
|
-
|
|
40834
|
+
clack56.intro(pc59.bold("Wraps SMS - Verify Destination Number"));
|
|
40692
40835
|
}
|
|
40693
40836
|
const identity = await progress.execute(
|
|
40694
40837
|
"Validating AWS credentials",
|
|
@@ -40698,10 +40841,10 @@ async function smsVerifyNumber(options) {
|
|
|
40698
40841
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
40699
40842
|
if (!metadata?.services?.sms) {
|
|
40700
40843
|
progress.stop();
|
|
40701
|
-
|
|
40844
|
+
clack56.log.error("No SMS infrastructure found");
|
|
40702
40845
|
console.log(
|
|
40703
40846
|
`
|
|
40704
|
-
Run ${
|
|
40847
|
+
Run ${pc59.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
40705
40848
|
`
|
|
40706
40849
|
);
|
|
40707
40850
|
process.exit(1);
|
|
@@ -40715,19 +40858,19 @@ Run ${pc58.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
40715
40858
|
);
|
|
40716
40859
|
progress.stop();
|
|
40717
40860
|
if (!response.VerifiedDestinationNumbers || response.VerifiedDestinationNumbers.length === 0) {
|
|
40718
|
-
|
|
40861
|
+
clack56.log.info("No verified destination numbers found");
|
|
40719
40862
|
console.log(
|
|
40720
40863
|
`
|
|
40721
|
-
Run ${
|
|
40864
|
+
Run ${pc59.cyan("wraps sms verify-number")} to verify a number.
|
|
40722
40865
|
`
|
|
40723
40866
|
);
|
|
40724
40867
|
} else {
|
|
40725
40868
|
console.log("\n");
|
|
40726
|
-
|
|
40869
|
+
clack56.log.info(pc59.bold("Verified Destination Numbers:"));
|
|
40727
40870
|
console.log("");
|
|
40728
40871
|
for (const num of response.VerifiedDestinationNumbers) {
|
|
40729
|
-
const status2 = num.Status === "VERIFIED" ?
|
|
40730
|
-
console.log(` ${
|
|
40872
|
+
const status2 = num.Status === "VERIFIED" ? pc59.green("\u2713 Verified") : pc59.yellow("\u29D6 Pending");
|
|
40873
|
+
console.log(` ${pc59.cyan(num.DestinationPhoneNumber)} - ${status2}`);
|
|
40731
40874
|
}
|
|
40732
40875
|
console.log("");
|
|
40733
40876
|
}
|
|
@@ -40745,7 +40888,7 @@ Run ${pc58.cyan("wraps sms verify-number")} to verify a number.
|
|
|
40745
40888
|
});
|
|
40746
40889
|
return;
|
|
40747
40890
|
}
|
|
40748
|
-
|
|
40891
|
+
clack56.outro(pc59.green("Done!"));
|
|
40749
40892
|
return;
|
|
40750
40893
|
} catch (error) {
|
|
40751
40894
|
progress.stop();
|
|
@@ -40753,7 +40896,7 @@ Run ${pc58.cyan("wraps sms verify-number")} to verify a number.
|
|
|
40753
40896
|
trackError("SMS_LIST_VERIFIED_FAILED", "sms:verify-number:list", {
|
|
40754
40897
|
error: errorMessage
|
|
40755
40898
|
});
|
|
40756
|
-
|
|
40899
|
+
clack56.log.error(`Failed to list verified numbers: ${errorMessage}`);
|
|
40757
40900
|
process.exit(1);
|
|
40758
40901
|
}
|
|
40759
40902
|
}
|
|
@@ -40761,10 +40904,10 @@ Run ${pc58.cyan("wraps sms verify-number")} to verify a number.
|
|
|
40761
40904
|
const phoneNumber2 = options.phoneNumber;
|
|
40762
40905
|
if (!phoneNumber2) {
|
|
40763
40906
|
progress.stop();
|
|
40764
|
-
|
|
40907
|
+
clack56.log.error("Phone number is required for deletion");
|
|
40765
40908
|
console.log(
|
|
40766
40909
|
`
|
|
40767
|
-
Usage: ${
|
|
40910
|
+
Usage: ${pc59.cyan("wraps sms verify-number --delete --phone-number +14155551234")}
|
|
40768
40911
|
`
|
|
40769
40912
|
);
|
|
40770
40913
|
process.exit(1);
|
|
@@ -40778,7 +40921,7 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40778
40921
|
const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
|
|
40779
40922
|
if (!verifiedNumber?.VerifiedDestinationNumberId) {
|
|
40780
40923
|
progress.stop();
|
|
40781
|
-
|
|
40924
|
+
clack56.log.error(`Number ${phoneNumber2} is not in verified list`);
|
|
40782
40925
|
process.exit(1);
|
|
40783
40926
|
}
|
|
40784
40927
|
await progress.execute(`Removing ${phoneNumber2}`, async () => {
|
|
@@ -40789,7 +40932,7 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40789
40932
|
);
|
|
40790
40933
|
});
|
|
40791
40934
|
progress.stop();
|
|
40792
|
-
|
|
40935
|
+
clack56.log.success(`Removed ${pc59.cyan(phoneNumber2)} from verified list`);
|
|
40793
40936
|
trackCommand("sms:verify-number:delete", {
|
|
40794
40937
|
success: true,
|
|
40795
40938
|
duration_ms: Date.now() - startTime
|
|
@@ -40801,7 +40944,7 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40801
40944
|
});
|
|
40802
40945
|
return;
|
|
40803
40946
|
}
|
|
40804
|
-
|
|
40947
|
+
clack56.outro(pc59.green("Done!"));
|
|
40805
40948
|
return;
|
|
40806
40949
|
} catch (error) {
|
|
40807
40950
|
progress.stop();
|
|
@@ -40809,7 +40952,7 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40809
40952
|
trackError("SMS_DELETE_VERIFIED_FAILED", "sms:verify-number:delete", {
|
|
40810
40953
|
error: errorMessage
|
|
40811
40954
|
});
|
|
40812
|
-
|
|
40955
|
+
clack56.log.error(`Failed to delete verified number: ${errorMessage}`);
|
|
40813
40956
|
process.exit(1);
|
|
40814
40957
|
}
|
|
40815
40958
|
}
|
|
@@ -40822,7 +40965,7 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40822
40965
|
);
|
|
40823
40966
|
}
|
|
40824
40967
|
if (!phoneNumber) {
|
|
40825
|
-
const result = await
|
|
40968
|
+
const result = await clack56.text({
|
|
40826
40969
|
message: "Enter phone number to verify (E.164 format):",
|
|
40827
40970
|
placeholder: "+14155551234",
|
|
40828
40971
|
validate: (value) => {
|
|
@@ -40835,14 +40978,14 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40835
40978
|
return;
|
|
40836
40979
|
}
|
|
40837
40980
|
});
|
|
40838
|
-
if (
|
|
40839
|
-
|
|
40981
|
+
if (clack56.isCancel(result)) {
|
|
40982
|
+
clack56.cancel("Operation cancelled.");
|
|
40840
40983
|
process.exit(0);
|
|
40841
40984
|
}
|
|
40842
40985
|
phoneNumber = result;
|
|
40843
40986
|
} else if (!isValidPhoneNumber(phoneNumber)) {
|
|
40844
40987
|
progress.stop();
|
|
40845
|
-
|
|
40988
|
+
clack56.log.error(
|
|
40846
40989
|
`Invalid phone number format: ${phoneNumber}. Use E.164 format (e.g., +14155551234)`
|
|
40847
40990
|
);
|
|
40848
40991
|
process.exit(1);
|
|
@@ -40857,7 +41000,7 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40857
41000
|
const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
|
|
40858
41001
|
if (!verifiedNumber?.VerifiedDestinationNumberId) {
|
|
40859
41002
|
progress.stop();
|
|
40860
|
-
|
|
41003
|
+
clack56.log.error(
|
|
40861
41004
|
`Number ${phoneNumber} not found. Run without --code first.`
|
|
40862
41005
|
);
|
|
40863
41006
|
process.exit(1);
|
|
@@ -40872,12 +41015,12 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40872
41015
|
});
|
|
40873
41016
|
progress.stop();
|
|
40874
41017
|
console.log("\n");
|
|
40875
|
-
|
|
40876
|
-
|
|
41018
|
+
clack56.log.success(
|
|
41019
|
+
pc59.green(`Phone number ${pc59.cyan(phoneNumber)} verified!`)
|
|
40877
41020
|
);
|
|
40878
41021
|
console.log("");
|
|
40879
41022
|
console.log(
|
|
40880
|
-
`You can now send test messages to this number with ${
|
|
41023
|
+
`You can now send test messages to this number with ${pc59.cyan("wraps sms test")}`
|
|
40881
41024
|
);
|
|
40882
41025
|
trackCommand("sms:verify-number:confirm", {
|
|
40883
41026
|
success: true,
|
|
@@ -40890,23 +41033,23 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40890
41033
|
});
|
|
40891
41034
|
return;
|
|
40892
41035
|
}
|
|
40893
|
-
|
|
41036
|
+
clack56.outro(pc59.green("Verification complete!"));
|
|
40894
41037
|
return;
|
|
40895
41038
|
} catch (error) {
|
|
40896
41039
|
progress.stop();
|
|
40897
41040
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
40898
41041
|
if (errorMessage.includes("Invalid verification code")) {
|
|
40899
|
-
|
|
41042
|
+
clack56.log.error("Invalid verification code. Please try again.");
|
|
40900
41043
|
console.log(
|
|
40901
41044
|
`
|
|
40902
|
-
Run ${
|
|
41045
|
+
Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
|
|
40903
41046
|
`
|
|
40904
41047
|
);
|
|
40905
41048
|
} else {
|
|
40906
41049
|
trackError("SMS_VERIFY_CODE_FAILED", "sms:verify-number:confirm", {
|
|
40907
41050
|
error: errorMessage
|
|
40908
41051
|
});
|
|
40909
|
-
|
|
41052
|
+
clack56.log.error(`Verification failed: ${errorMessage}`);
|
|
40910
41053
|
}
|
|
40911
41054
|
process.exit(1);
|
|
40912
41055
|
}
|
|
@@ -40921,7 +41064,7 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
40921
41064
|
const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
|
|
40922
41065
|
if (!verifiedNumber?.VerifiedDestinationNumberId) {
|
|
40923
41066
|
progress.stop();
|
|
40924
|
-
|
|
41067
|
+
clack56.log.error(
|
|
40925
41068
|
`Number ${phoneNumber} not found. Run without --resend first.`
|
|
40926
41069
|
);
|
|
40927
41070
|
process.exit(1);
|
|
@@ -40935,11 +41078,11 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
40935
41078
|
);
|
|
40936
41079
|
});
|
|
40937
41080
|
progress.stop();
|
|
40938
|
-
|
|
41081
|
+
clack56.log.success(`Verification code resent to ${pc59.cyan(phoneNumber)}`);
|
|
40939
41082
|
console.log("");
|
|
40940
41083
|
console.log(
|
|
40941
41084
|
`Once you receive the code, run:
|
|
40942
|
-
${
|
|
41085
|
+
${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
|
|
40943
41086
|
);
|
|
40944
41087
|
trackCommand("sms:verify-number:resend", {
|
|
40945
41088
|
success: true,
|
|
@@ -40952,7 +41095,7 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
40952
41095
|
});
|
|
40953
41096
|
return;
|
|
40954
41097
|
}
|
|
40955
|
-
|
|
41098
|
+
clack56.outro(pc59.green("Code sent!"));
|
|
40956
41099
|
return;
|
|
40957
41100
|
} catch (error) {
|
|
40958
41101
|
progress.stop();
|
|
@@ -40960,7 +41103,7 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
40960
41103
|
trackError("SMS_RESEND_CODE_FAILED", "sms:verify-number:resend", {
|
|
40961
41104
|
error: errorMessage
|
|
40962
41105
|
});
|
|
40963
|
-
|
|
41106
|
+
clack56.log.error(`Failed to resend code: ${errorMessage}`);
|
|
40964
41107
|
process.exit(1);
|
|
40965
41108
|
}
|
|
40966
41109
|
}
|
|
@@ -40980,10 +41123,10 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
40980
41123
|
});
|
|
40981
41124
|
return;
|
|
40982
41125
|
}
|
|
40983
|
-
|
|
40984
|
-
`Number ${
|
|
41126
|
+
clack56.log.info(
|
|
41127
|
+
`Number ${pc59.cyan(phoneNumber)} is already verified and ready to use!`
|
|
40985
41128
|
);
|
|
40986
|
-
|
|
41129
|
+
clack56.outro(pc59.green("Done!"));
|
|
40987
41130
|
return;
|
|
40988
41131
|
}
|
|
40989
41132
|
if (existingNumber?.Status === "PENDING") {
|
|
@@ -41007,15 +41150,15 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41007
41150
|
});
|
|
41008
41151
|
return;
|
|
41009
41152
|
}
|
|
41010
|
-
|
|
41011
|
-
`Verification already in progress. New code sent to ${
|
|
41153
|
+
clack56.log.info(
|
|
41154
|
+
`Verification already in progress. New code sent to ${pc59.cyan(phoneNumber)}`
|
|
41012
41155
|
);
|
|
41013
41156
|
console.log("");
|
|
41014
41157
|
console.log(
|
|
41015
41158
|
`Once you receive the code, run:
|
|
41016
|
-
${
|
|
41159
|
+
${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
|
|
41017
41160
|
);
|
|
41018
|
-
|
|
41161
|
+
clack56.outro(pc59.green("Code sent!"));
|
|
41019
41162
|
return;
|
|
41020
41163
|
}
|
|
41021
41164
|
const createResponse = await progress.execute(
|
|
@@ -41036,18 +41179,18 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41036
41179
|
});
|
|
41037
41180
|
progress.stop();
|
|
41038
41181
|
console.log("\n");
|
|
41039
|
-
|
|
41040
|
-
`Verification code sent to ${
|
|
41182
|
+
clack56.log.success(
|
|
41183
|
+
`Verification code sent to ${pc59.cyan(phoneNumber)} via SMS`
|
|
41041
41184
|
);
|
|
41042
41185
|
console.log("");
|
|
41043
|
-
|
|
41186
|
+
clack56.note(
|
|
41044
41187
|
[
|
|
41045
41188
|
"1. Check your phone for the verification code",
|
|
41046
41189
|
"",
|
|
41047
41190
|
"2. Complete verification with:",
|
|
41048
|
-
` ${
|
|
41191
|
+
` ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`,
|
|
41049
41192
|
"",
|
|
41050
|
-
|
|
41193
|
+
pc59.dim("The code expires in 24 hours")
|
|
41051
41194
|
].join("\n"),
|
|
41052
41195
|
"Next Steps"
|
|
41053
41196
|
);
|
|
@@ -41063,22 +41206,22 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41063
41206
|
});
|
|
41064
41207
|
return;
|
|
41065
41208
|
}
|
|
41066
|
-
|
|
41209
|
+
clack56.outro(pc59.green("Verification started!"));
|
|
41067
41210
|
} catch (error) {
|
|
41068
41211
|
progress.stop();
|
|
41069
41212
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
41070
41213
|
if (errorMessage.includes("already exists")) {
|
|
41071
|
-
|
|
41214
|
+
clack56.log.error("This number is already being verified");
|
|
41072
41215
|
console.log(
|
|
41073
41216
|
`
|
|
41074
|
-
Run ${
|
|
41217
|
+
Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
|
|
41075
41218
|
`
|
|
41076
41219
|
);
|
|
41077
41220
|
} else {
|
|
41078
41221
|
trackError("SMS_CREATE_VERIFIED_FAILED", "sms:verify-number:start", {
|
|
41079
41222
|
error: errorMessage
|
|
41080
41223
|
});
|
|
41081
|
-
|
|
41224
|
+
clack56.log.error(`Failed to start verification: ${errorMessage}`);
|
|
41082
41225
|
}
|
|
41083
41226
|
process.exit(1);
|
|
41084
41227
|
}
|
|
@@ -41087,88 +41230,88 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41087
41230
|
// src/commands/support.ts
|
|
41088
41231
|
init_esm_shims();
|
|
41089
41232
|
init_events();
|
|
41090
|
-
import * as
|
|
41091
|
-
import
|
|
41233
|
+
import * as clack57 from "@clack/prompts";
|
|
41234
|
+
import pc60 from "picocolors";
|
|
41092
41235
|
async function support() {
|
|
41093
41236
|
trackCommand("support", { success: true });
|
|
41094
|
-
|
|
41237
|
+
clack57.intro(pc60.bold("Get Help with Wraps"));
|
|
41095
41238
|
console.log();
|
|
41096
|
-
console.log(` ${
|
|
41239
|
+
console.log(` ${pc60.bold("Email:")} ${pc60.cyan("hey@wraps.sh")}`);
|
|
41097
41240
|
console.log(
|
|
41098
|
-
` ${
|
|
41241
|
+
` ${pc60.bold("GitHub:")} ${pc60.cyan("https://github.com/wraps-dev/wraps/issues")}`
|
|
41099
41242
|
);
|
|
41100
|
-
console.log(` ${
|
|
41243
|
+
console.log(` ${pc60.bold("Docs:")} ${pc60.cyan("https://wraps.dev/docs")}`);
|
|
41101
41244
|
console.log();
|
|
41102
|
-
console.log(
|
|
41245
|
+
console.log(pc60.dim(" Response time: Usually within 24 hours"));
|
|
41103
41246
|
console.log();
|
|
41104
41247
|
}
|
|
41105
41248
|
|
|
41106
41249
|
// src/commands/telemetry.ts
|
|
41107
41250
|
init_esm_shims();
|
|
41108
41251
|
init_client();
|
|
41109
|
-
import * as
|
|
41110
|
-
import
|
|
41252
|
+
import * as clack58 from "@clack/prompts";
|
|
41253
|
+
import pc61 from "picocolors";
|
|
41111
41254
|
async function telemetryEnable() {
|
|
41112
41255
|
const client = getTelemetryClient();
|
|
41113
41256
|
const override = client.enable();
|
|
41114
41257
|
if (override) {
|
|
41115
|
-
|
|
41258
|
+
clack58.log.warn(
|
|
41116
41259
|
"Telemetry enabled in config, but overridden by environment"
|
|
41117
41260
|
);
|
|
41118
|
-
console.log(` Reason: ${
|
|
41119
|
-
console.log(` Config: ${
|
|
41261
|
+
console.log(` Reason: ${pc61.yellow(override)}`);
|
|
41262
|
+
console.log(` Config: ${pc61.dim(client.getConfigPath())}`);
|
|
41120
41263
|
console.log();
|
|
41121
41264
|
} else {
|
|
41122
|
-
|
|
41123
|
-
console.log(` Config: ${
|
|
41265
|
+
clack58.log.success(pc61.green("Telemetry enabled"));
|
|
41266
|
+
console.log(` Config: ${pc61.dim(client.getConfigPath())}`);
|
|
41124
41267
|
console.log(`
|
|
41125
|
-
${
|
|
41268
|
+
${pc61.dim("Thank you for helping improve Wraps!")}
|
|
41126
41269
|
`);
|
|
41127
41270
|
}
|
|
41128
41271
|
}
|
|
41129
41272
|
async function telemetryDisable() {
|
|
41130
41273
|
const client = getTelemetryClient();
|
|
41131
41274
|
client.disable();
|
|
41132
|
-
|
|
41133
|
-
console.log(` Config: ${
|
|
41275
|
+
clack58.log.success(pc61.green("Telemetry disabled"));
|
|
41276
|
+
console.log(` Config: ${pc61.dim(client.getConfigPath())}`);
|
|
41134
41277
|
console.log(
|
|
41135
41278
|
`
|
|
41136
|
-
${
|
|
41279
|
+
${pc61.dim("You can re-enable with:")} wraps telemetry enable
|
|
41137
41280
|
`
|
|
41138
41281
|
);
|
|
41139
41282
|
}
|
|
41140
41283
|
async function telemetryStatus() {
|
|
41141
41284
|
const client = getTelemetryClient();
|
|
41142
|
-
|
|
41285
|
+
clack58.intro(pc61.bold("Telemetry Status"));
|
|
41143
41286
|
const override = client.getEnvOverride();
|
|
41144
|
-
const status2 = client.isEnabled() ?
|
|
41287
|
+
const status2 = client.isEnabled() ? pc61.green("Enabled") : pc61.red("Disabled");
|
|
41145
41288
|
console.log();
|
|
41146
|
-
console.log(` ${
|
|
41289
|
+
console.log(` ${pc61.bold("Status:")} ${status2}`);
|
|
41147
41290
|
if (!client.isEnabled() && override) {
|
|
41148
|
-
console.log(` ${
|
|
41291
|
+
console.log(` ${pc61.bold("Reason:")} ${pc61.yellow(override)}`);
|
|
41149
41292
|
}
|
|
41150
|
-
console.log(` ${
|
|
41293
|
+
console.log(` ${pc61.bold("Config file:")} ${pc61.dim(client.getConfigPath())}`);
|
|
41151
41294
|
if (client.isEnabled()) {
|
|
41152
41295
|
console.log();
|
|
41153
|
-
console.log(
|
|
41154
|
-
console.log(` ${
|
|
41296
|
+
console.log(pc61.bold(" How to opt-out:"));
|
|
41297
|
+
console.log(` ${pc61.cyan("wraps telemetry disable")}`);
|
|
41155
41298
|
console.log(
|
|
41156
|
-
` ${
|
|
41299
|
+
` ${pc61.dim("Or set:")} ${pc61.cyan("WRAPS_TELEMETRY_DISABLED=1")}`
|
|
41157
41300
|
);
|
|
41158
|
-
console.log(` ${
|
|
41301
|
+
console.log(` ${pc61.dim("Or set:")} ${pc61.cyan("DO_NOT_TRACK=1")}`);
|
|
41159
41302
|
} else {
|
|
41160
41303
|
console.log();
|
|
41161
|
-
console.log(
|
|
41162
|
-
console.log(` ${
|
|
41304
|
+
console.log(pc61.bold(" How to opt-in:"));
|
|
41305
|
+
console.log(` ${pc61.cyan("wraps telemetry enable")}`);
|
|
41163
41306
|
}
|
|
41164
41307
|
console.log();
|
|
41165
|
-
console.log(
|
|
41308
|
+
console.log(pc61.bold(" Debug mode:"));
|
|
41166
41309
|
console.log(
|
|
41167
|
-
` ${
|
|
41310
|
+
` ${pc61.dim("See what would be sent:")} ${pc61.cyan("WRAPS_TELEMETRY_DEBUG=1 wraps <command>")}`
|
|
41168
41311
|
);
|
|
41169
41312
|
console.log();
|
|
41170
41313
|
console.log(
|
|
41171
|
-
` ${
|
|
41314
|
+
` ${pc61.dim("Learn more:")} ${pc61.cyan("https://wraps.dev/docs/telemetry")}`
|
|
41172
41315
|
);
|
|
41173
41316
|
console.log();
|
|
41174
41317
|
}
|
|
@@ -41177,8 +41320,8 @@ async function telemetryStatus() {
|
|
|
41177
41320
|
init_esm_shims();
|
|
41178
41321
|
import { existsSync as existsSync18, mkdirSync as mkdirSync2, writeFileSync } from "fs";
|
|
41179
41322
|
import { join as join22 } from "path";
|
|
41180
|
-
import * as
|
|
41181
|
-
import
|
|
41323
|
+
import * as clack59 from "@clack/prompts";
|
|
41324
|
+
import pc62 from "picocolors";
|
|
41182
41325
|
var EXAMPLE_CASCADE_WORKFLOW = `import {
|
|
41183
41326
|
defineWorkflow,
|
|
41184
41327
|
sendEmail,
|
|
@@ -41273,30 +41416,30 @@ export default defineConfig({
|
|
|
41273
41416
|
});
|
|
41274
41417
|
`;
|
|
41275
41418
|
async function workflowInit(options = {}) {
|
|
41276
|
-
|
|
41419
|
+
clack59.intro(pc62.bgCyan(pc62.black(" wraps workflow init ")));
|
|
41277
41420
|
const wrapsDir = join22(process.cwd(), "wraps");
|
|
41278
41421
|
const workflowsDir = join22(wrapsDir, "workflows");
|
|
41279
41422
|
const configPath = join22(wrapsDir, "wraps.config.ts");
|
|
41280
41423
|
if (existsSync18(workflowsDir)) {
|
|
41281
|
-
|
|
41282
|
-
`Workflows directory already exists at ${
|
|
41424
|
+
clack59.log.info(
|
|
41425
|
+
`Workflows directory already exists at ${pc62.cyan("wraps/workflows/")}`
|
|
41283
41426
|
);
|
|
41284
41427
|
const files = existsSync18(join22(workflowsDir, "cart-recovery.ts")) || existsSync18(join22(workflowsDir, "welcome-sequence.ts"));
|
|
41285
41428
|
if (files && !options.yes) {
|
|
41286
|
-
const shouldContinue = await
|
|
41429
|
+
const shouldContinue = await clack59.confirm({
|
|
41287
41430
|
message: "Example files may already exist. Overwrite them?",
|
|
41288
41431
|
initialValue: false
|
|
41289
41432
|
});
|
|
41290
|
-
if (
|
|
41291
|
-
|
|
41433
|
+
if (clack59.isCancel(shouldContinue) || !shouldContinue) {
|
|
41434
|
+
clack59.log.info("Skipping file creation.");
|
|
41292
41435
|
showNextSteps2();
|
|
41293
|
-
|
|
41436
|
+
clack59.outro("Done!");
|
|
41294
41437
|
return;
|
|
41295
41438
|
}
|
|
41296
41439
|
}
|
|
41297
41440
|
}
|
|
41298
41441
|
try {
|
|
41299
|
-
const s =
|
|
41442
|
+
const s = clack59.spinner();
|
|
41300
41443
|
s.start("Creating workflows directory...");
|
|
41301
41444
|
mkdirSync2(workflowsDir, { recursive: true });
|
|
41302
41445
|
s.stop("Created wraps/workflows/");
|
|
@@ -41314,34 +41457,34 @@ async function workflowInit(options = {}) {
|
|
|
41314
41457
|
s.stop("Created 2 example workflows");
|
|
41315
41458
|
if (!existsSync18(configPath)) {
|
|
41316
41459
|
writeFileSync(configPath, EXAMPLE_CONFIG, "utf-8");
|
|
41317
|
-
|
|
41460
|
+
clack59.log.info(`Created ${pc62.cyan("wraps/wraps.config.ts")}`);
|
|
41318
41461
|
}
|
|
41319
|
-
|
|
41320
|
-
`${
|
|
41321
|
-
${
|
|
41322
|
-
${
|
|
41323
|
-
${
|
|
41462
|
+
clack59.log.success(
|
|
41463
|
+
`${pc62.bold("Workflows scaffolded!")} Created:
|
|
41464
|
+
${pc62.cyan("wraps/wraps.config.ts")} \u2014 Project config
|
|
41465
|
+
${pc62.cyan("wraps/workflows/cart-recovery.ts")} \u2014 Cross-channel cascade example
|
|
41466
|
+
${pc62.cyan("wraps/workflows/welcome-sequence.ts")} \u2014 Welcome series example`
|
|
41324
41467
|
);
|
|
41325
41468
|
showNextSteps2();
|
|
41326
|
-
|
|
41469
|
+
clack59.outro(pc62.green("Happy orchestrating!"));
|
|
41327
41470
|
} catch (error) {
|
|
41328
|
-
|
|
41471
|
+
clack59.log.error(
|
|
41329
41472
|
`Failed to scaffold workflows: ${error instanceof Error ? error.message : String(error)}`
|
|
41330
41473
|
);
|
|
41331
|
-
|
|
41474
|
+
clack59.outro(pc62.red("Scaffolding failed."));
|
|
41332
41475
|
process.exitCode = 1;
|
|
41333
41476
|
}
|
|
41334
41477
|
}
|
|
41335
41478
|
function showNextSteps2() {
|
|
41336
|
-
|
|
41337
|
-
`${
|
|
41479
|
+
clack59.log.info(
|
|
41480
|
+
`${pc62.bold("Next steps:")}
|
|
41338
41481
|
|
|
41339
|
-
1. Edit ${
|
|
41340
|
-
2. Edit your workflows in ${
|
|
41341
|
-
3. Validate: ${
|
|
41342
|
-
4. Push: ${
|
|
41482
|
+
1. Edit ${pc62.cyan("wraps/wraps.config.ts")} with your org slug and domain
|
|
41483
|
+
2. Edit your workflows in ${pc62.cyan("wraps/workflows/")}
|
|
41484
|
+
3. Validate: ${pc62.cyan("wraps email workflows validate")}
|
|
41485
|
+
4. Push: ${pc62.cyan("wraps email workflows push")}
|
|
41343
41486
|
|
|
41344
|
-
${
|
|
41487
|
+
${pc62.dim("Docs:")} ${pc62.underline("https://wraps.dev/docs/guides/orchestration")}`
|
|
41345
41488
|
);
|
|
41346
41489
|
}
|
|
41347
41490
|
|
|
@@ -41373,7 +41516,9 @@ var STRING_FLAGS = [
|
|
|
41373
41516
|
"template",
|
|
41374
41517
|
"workflow",
|
|
41375
41518
|
"org",
|
|
41376
|
-
"subdomain"
|
|
41519
|
+
"subdomain",
|
|
41520
|
+
"tier",
|
|
41521
|
+
"expires"
|
|
41377
41522
|
];
|
|
41378
41523
|
var BOOLEAN_FLAGS = [
|
|
41379
41524
|
"yes",
|
|
@@ -41529,205 +41674,208 @@ function showVersion() {
|
|
|
41529
41674
|
process.exit(0);
|
|
41530
41675
|
}
|
|
41531
41676
|
function showHelp() {
|
|
41532
|
-
|
|
41677
|
+
clack60.intro(pc64.bold(`WRAPS CLI v${VERSION}`));
|
|
41533
41678
|
console.log("Deploy AWS infrastructure to your account\n");
|
|
41534
41679
|
console.log("Usage: wraps [service] <command> [options]\n");
|
|
41535
41680
|
console.log("Services:");
|
|
41536
|
-
console.log(` ${
|
|
41681
|
+
console.log(` ${pc64.cyan("email")} Email infrastructure (AWS SES)`);
|
|
41682
|
+
console.log(
|
|
41683
|
+
` ${pc64.cyan("sms")} SMS infrastructure (AWS End User Messaging)`
|
|
41684
|
+
);
|
|
41537
41685
|
console.log(
|
|
41538
|
-
` ${
|
|
41686
|
+
` ${pc64.cyan("cdn")} CDN infrastructure (AWS S3 + CloudFront)`
|
|
41539
41687
|
);
|
|
41540
41688
|
console.log(
|
|
41541
|
-
` ${
|
|
41689
|
+
` ${pc64.cyan("selfhost")} Self-hosted Wraps control plane (enterprise)`
|
|
41542
41690
|
);
|
|
41543
41691
|
console.log(
|
|
41544
|
-
` ${
|
|
41692
|
+
` ${pc64.cyan("license")} License key management (Wraps team only)
|
|
41545
41693
|
`
|
|
41546
41694
|
);
|
|
41547
41695
|
console.log("Email Commands:");
|
|
41548
41696
|
console.log(
|
|
41549
|
-
` ${
|
|
41697
|
+
` ${pc64.cyan("email init")} Deploy new email infrastructure`
|
|
41550
41698
|
);
|
|
41551
41699
|
console.log(
|
|
41552
|
-
` ${
|
|
41700
|
+
` ${pc64.cyan("email check")} Check email deliverability for a domain`
|
|
41553
41701
|
);
|
|
41554
41702
|
console.log(
|
|
41555
|
-
` ${
|
|
41703
|
+
` ${pc64.cyan("email connect")} Connect to existing AWS SES`
|
|
41556
41704
|
);
|
|
41557
41705
|
console.log(
|
|
41558
|
-
` ${
|
|
41706
|
+
` ${pc64.cyan("email status")} Show email infrastructure details`
|
|
41559
41707
|
);
|
|
41560
|
-
console.log(` ${
|
|
41561
|
-
console.log(` ${
|
|
41708
|
+
console.log(` ${pc64.cyan("email test")} Send a test email`);
|
|
41709
|
+
console.log(` ${pc64.cyan("email verify")} Verify domain DNS records`);
|
|
41562
41710
|
console.log(
|
|
41563
|
-
` ${
|
|
41711
|
+
` ${pc64.cyan("email sync")} Apply CLI updates to infrastructure`
|
|
41564
41712
|
);
|
|
41565
|
-
console.log(` ${
|
|
41713
|
+
console.log(` ${pc64.cyan("email upgrade")} Add features`);
|
|
41566
41714
|
console.log(
|
|
41567
|
-
` ${
|
|
41715
|
+
` ${pc64.cyan("email restore")} Restore original configuration`
|
|
41568
41716
|
);
|
|
41569
41717
|
console.log(
|
|
41570
|
-
` ${
|
|
41718
|
+
` ${pc64.cyan("email destroy")} Remove email infrastructure`
|
|
41571
41719
|
);
|
|
41572
41720
|
console.log(
|
|
41573
|
-
` ${
|
|
41721
|
+
` ${pc64.cyan("email doctor")} Diagnose and clean up email infrastructure`
|
|
41574
41722
|
);
|
|
41575
|
-
console.log(` ${
|
|
41576
|
-
console.log(` ${
|
|
41577
|
-
console.log(` ${
|
|
41723
|
+
console.log(` ${pc64.cyan("email domains add")} Add a domain to SES`);
|
|
41724
|
+
console.log(` ${pc64.cyan("email domains list")} List all domains`);
|
|
41725
|
+
console.log(` ${pc64.cyan("email domains remove")} Remove a domain`);
|
|
41578
41726
|
console.log(
|
|
41579
|
-
` ${
|
|
41727
|
+
` ${pc64.cyan("email inbound init")} Enable inbound email receiving`
|
|
41580
41728
|
);
|
|
41581
|
-
console.log(` ${
|
|
41729
|
+
console.log(` ${pc64.cyan("email inbound status")} Show inbound email status`);
|
|
41582
41730
|
console.log(
|
|
41583
|
-
` ${
|
|
41731
|
+
` ${pc64.cyan("email inbound verify")} Verify inbound DNS records`
|
|
41584
41732
|
);
|
|
41585
41733
|
console.log(
|
|
41586
|
-
` ${
|
|
41734
|
+
` ${pc64.cyan("email inbound test")} Send test email and verify receipt`
|
|
41587
41735
|
);
|
|
41588
41736
|
console.log(
|
|
41589
|
-
` ${
|
|
41737
|
+
` ${pc64.cyan("email inbound destroy")} Remove inbound email infrastructure
|
|
41590
41738
|
`
|
|
41591
41739
|
);
|
|
41592
41740
|
console.log("Template Commands:");
|
|
41593
41741
|
console.log(
|
|
41594
|
-
` ${
|
|
41742
|
+
` ${pc64.cyan("email templates init")} Initialize templates-as-code`
|
|
41595
41743
|
);
|
|
41596
41744
|
console.log(
|
|
41597
|
-
` ${
|
|
41745
|
+
` ${pc64.cyan("email templates push")} Push templates to SES + dashboard`
|
|
41598
41746
|
);
|
|
41599
41747
|
console.log(
|
|
41600
|
-
` ${
|
|
41748
|
+
` ${pc64.cyan("email templates preview")} Preview templates in browser`
|
|
41601
41749
|
);
|
|
41602
41750
|
console.log(
|
|
41603
|
-
` ${
|
|
41751
|
+
` ${pc64.cyan("push")} ${pc64.dim("(alias for email templates push)")}
|
|
41604
41752
|
`
|
|
41605
41753
|
);
|
|
41606
41754
|
console.log("Workflow Commands:");
|
|
41607
41755
|
console.log(
|
|
41608
|
-
` ${
|
|
41756
|
+
` ${pc64.cyan("email workflows init")} Initialize workflows-as-code`
|
|
41609
41757
|
);
|
|
41610
41758
|
console.log(
|
|
41611
|
-
` ${
|
|
41759
|
+
` ${pc64.cyan("email workflows validate")} Validate workflow files`
|
|
41612
41760
|
);
|
|
41613
41761
|
console.log(
|
|
41614
|
-
` ${
|
|
41762
|
+
` ${pc64.cyan("email workflows push")} Push workflows to dashboard
|
|
41615
41763
|
`
|
|
41616
41764
|
);
|
|
41617
41765
|
console.log("SMS Commands:");
|
|
41618
|
-
console.log(` ${
|
|
41766
|
+
console.log(` ${pc64.cyan("sms init")} Deploy SMS infrastructure`);
|
|
41619
41767
|
console.log(
|
|
41620
|
-
` ${
|
|
41768
|
+
` ${pc64.cyan("sms status")} Show SMS infrastructure details`
|
|
41621
41769
|
);
|
|
41622
|
-
console.log(` ${
|
|
41770
|
+
console.log(` ${pc64.cyan("sms test")} Send a test SMS message`);
|
|
41623
41771
|
console.log(
|
|
41624
|
-
` ${
|
|
41772
|
+
` ${pc64.cyan("sms verify-number")} Verify a destination phone number`
|
|
41625
41773
|
);
|
|
41626
41774
|
console.log(
|
|
41627
|
-
` ${
|
|
41775
|
+
` ${pc64.cyan("sms sync")} Sync infrastructure (update Lambda, etc.)`
|
|
41628
41776
|
);
|
|
41629
|
-
console.log(` ${
|
|
41630
|
-
console.log(` ${
|
|
41777
|
+
console.log(` ${pc64.cyan("sms upgrade")} Upgrade SMS features`);
|
|
41778
|
+
console.log(` ${pc64.cyan("sms register")} Register toll-free number`);
|
|
41631
41779
|
console.log(
|
|
41632
|
-
` ${
|
|
41780
|
+
` ${pc64.cyan("sms destroy")} Remove SMS infrastructure
|
|
41633
41781
|
`
|
|
41634
41782
|
);
|
|
41635
41783
|
console.log("CDN Commands:");
|
|
41636
41784
|
console.log(
|
|
41637
|
-
` ${
|
|
41785
|
+
` ${pc64.cyan("cdn init")} Deploy CDN infrastructure (S3 + CloudFront)`
|
|
41638
41786
|
);
|
|
41639
41787
|
console.log(
|
|
41640
|
-
` ${
|
|
41788
|
+
` ${pc64.cyan("cdn status")} Show CDN infrastructure details`
|
|
41641
41789
|
);
|
|
41642
41790
|
console.log(
|
|
41643
|
-
` ${
|
|
41791
|
+
` ${pc64.cyan("cdn verify")} Check DNS and certificate status`
|
|
41644
41792
|
);
|
|
41645
41793
|
console.log(
|
|
41646
|
-
` ${
|
|
41794
|
+
` ${pc64.cyan("cdn upgrade")} Add custom domain after cert validation`
|
|
41647
41795
|
);
|
|
41648
41796
|
console.log(
|
|
41649
|
-
` ${
|
|
41797
|
+
` ${pc64.cyan("cdn sync")} Sync infrastructure with current config`
|
|
41650
41798
|
);
|
|
41651
41799
|
console.log(
|
|
41652
|
-
` ${
|
|
41800
|
+
` ${pc64.cyan("cdn destroy")} Remove CDN infrastructure
|
|
41653
41801
|
`
|
|
41654
41802
|
);
|
|
41655
41803
|
console.log("Self-Hosted Commands:");
|
|
41656
41804
|
console.log(
|
|
41657
|
-
` ${
|
|
41805
|
+
` ${pc64.cyan("selfhost deploy")} Deploy Wraps API to your AWS account`
|
|
41658
41806
|
);
|
|
41659
41807
|
console.log(
|
|
41660
|
-
` ${
|
|
41808
|
+
` ${pc64.cyan("selfhost upgrade")} Rebuild and redeploy the self-hosted API`
|
|
41661
41809
|
);
|
|
41662
41810
|
console.log(
|
|
41663
|
-
` ${
|
|
41811
|
+
` ${pc64.cyan("selfhost status")} Show self-hosted deployment details
|
|
41664
41812
|
`
|
|
41665
41813
|
);
|
|
41666
41814
|
console.log("Local Development:");
|
|
41667
41815
|
console.log(
|
|
41668
|
-
` ${
|
|
41816
|
+
` ${pc64.cyan("console")} Start local web console
|
|
41669
41817
|
`
|
|
41670
41818
|
);
|
|
41671
41819
|
console.log("Platform:");
|
|
41672
41820
|
console.log(
|
|
41673
|
-
` ${
|
|
41821
|
+
` ${pc64.cyan("platform")} Show platform info and pricing`
|
|
41674
41822
|
);
|
|
41675
41823
|
console.log(
|
|
41676
|
-
` ${
|
|
41824
|
+
` ${pc64.cyan("platform connect")} Connect to Wraps Platform (events + IAM)`
|
|
41677
41825
|
);
|
|
41678
41826
|
console.log(
|
|
41679
|
-
` ${
|
|
41827
|
+
` ${pc64.cyan("platform update-role")} Update platform IAM permissions
|
|
41680
41828
|
`
|
|
41681
41829
|
);
|
|
41682
41830
|
console.log("Auth:");
|
|
41683
41831
|
console.log(
|
|
41684
|
-
` ${
|
|
41832
|
+
` ${pc64.cyan("auth login")} Sign in to wraps.dev (device flow)`
|
|
41685
41833
|
);
|
|
41686
|
-
console.log(` ${
|
|
41834
|
+
console.log(` ${pc64.cyan("auth status")} Show current auth state`);
|
|
41687
41835
|
console.log(
|
|
41688
|
-
` ${
|
|
41836
|
+
` ${pc64.cyan("auth logout")} Sign out and remove stored token
|
|
41689
41837
|
`
|
|
41690
41838
|
);
|
|
41691
41839
|
console.log("AWS Setup:");
|
|
41692
41840
|
console.log(
|
|
41693
|
-
` ${
|
|
41841
|
+
` ${pc64.cyan("aws setup")} Interactive AWS setup wizard`
|
|
41694
41842
|
);
|
|
41695
41843
|
console.log(
|
|
41696
|
-
` ${
|
|
41844
|
+
` ${pc64.cyan("aws doctor")} Diagnose AWS configuration issues
|
|
41697
41845
|
`
|
|
41698
41846
|
);
|
|
41699
41847
|
console.log("Global Commands:");
|
|
41700
|
-
console.log(` ${
|
|
41701
|
-
console.log(` ${
|
|
41702
|
-
console.log(` ${
|
|
41703
|
-
console.log(` ${
|
|
41848
|
+
console.log(` ${pc64.cyan("status")} Show overview of all services`);
|
|
41849
|
+
console.log(` ${pc64.cyan("destroy")} Remove deployed infrastructure`);
|
|
41850
|
+
console.log(` ${pc64.cyan("permissions")} Show required AWS IAM permissions`);
|
|
41851
|
+
console.log(` ${pc64.cyan("completion")} Generate shell completion script`);
|
|
41704
41852
|
console.log(
|
|
41705
|
-
` ${
|
|
41853
|
+
` ${pc64.cyan("telemetry")} Manage anonymous telemetry settings`
|
|
41706
41854
|
);
|
|
41707
|
-
console.log(` ${
|
|
41708
|
-
console.log(` ${
|
|
41855
|
+
console.log(` ${pc64.cyan("update")} Update CLI to latest version`);
|
|
41856
|
+
console.log(` ${pc64.cyan("news")} Show recent Wraps updates`);
|
|
41709
41857
|
console.log(
|
|
41710
|
-
` ${
|
|
41858
|
+
` ${pc64.cyan("support")} Get help and support contact info
|
|
41711
41859
|
`
|
|
41712
41860
|
);
|
|
41713
41861
|
console.log("Options:");
|
|
41714
41862
|
console.log(
|
|
41715
|
-
` ${
|
|
41716
|
-
);
|
|
41717
|
-
console.log(` ${
|
|
41718
|
-
console.log(` ${
|
|
41719
|
-
console.log(` ${
|
|
41720
|
-
console.log(` ${
|
|
41721
|
-
console.log(` ${
|
|
41722
|
-
console.log(` ${
|
|
41723
|
-
console.log(` ${
|
|
41863
|
+
` ${pc64.dim("-p, --provider")} Hosting provider (vercel, aws, railway, other)`
|
|
41864
|
+
);
|
|
41865
|
+
console.log(` ${pc64.dim("-r, --region")} AWS region`);
|
|
41866
|
+
console.log(` ${pc64.dim("-d, --domain")} Domain name`);
|
|
41867
|
+
console.log(` ${pc64.dim("--account")} AWS account ID or alias`);
|
|
41868
|
+
console.log(` ${pc64.dim("--preset")} Configuration preset`);
|
|
41869
|
+
console.log(` ${pc64.dim("--token")} API key or token for auth`);
|
|
41870
|
+
console.log(` ${pc64.dim("-y, --yes")} Skip confirmation prompts`);
|
|
41871
|
+
console.log(` ${pc64.dim("-f, --force")} Force destructive operations`);
|
|
41724
41872
|
console.log(
|
|
41725
|
-
` ${
|
|
41873
|
+
` ${pc64.dim("--preview")} Preview changes without deploying`
|
|
41726
41874
|
);
|
|
41727
|
-
console.log(` ${
|
|
41875
|
+
console.log(` ${pc64.dim("-v, --version")} Show version number
|
|
41728
41876
|
`);
|
|
41729
41877
|
console.log(
|
|
41730
|
-
`Run ${
|
|
41878
|
+
`Run ${pc64.cyan("wraps <service> <command> --help")} for more information.
|
|
41731
41879
|
`
|
|
41732
41880
|
);
|
|
41733
41881
|
}
|
|
@@ -41749,27 +41897,27 @@ if (!primaryCommand) {
|
|
|
41749
41897
|
const telemetry = getTelemetryClient();
|
|
41750
41898
|
if (telemetry.shouldShowNotification()) {
|
|
41751
41899
|
console.log();
|
|
41752
|
-
|
|
41900
|
+
clack60.log.info(pc64.bold("Anonymous Telemetry"));
|
|
41753
41901
|
console.log(
|
|
41754
|
-
` Wraps collects ${
|
|
41902
|
+
` Wraps collects ${pc64.cyan("anonymous usage data")} to improve the CLI.`
|
|
41755
41903
|
);
|
|
41756
41904
|
console.log(
|
|
41757
|
-
` We ${
|
|
41905
|
+
` We ${pc64.bold("never")} collect: domains, AWS credentials, email content, or PII.`
|
|
41758
41906
|
);
|
|
41759
41907
|
console.log(
|
|
41760
|
-
` We ${
|
|
41908
|
+
` We ${pc64.bold("only")} collect: command names, success/failure, CLI version, OS.`
|
|
41761
41909
|
);
|
|
41762
41910
|
console.log();
|
|
41763
|
-
console.log(` Opt-out anytime: ${
|
|
41764
|
-
console.log(` Or set: ${
|
|
41765
|
-
console.log(` Learn more: ${
|
|
41911
|
+
console.log(` Opt-out anytime: ${pc64.cyan("wraps telemetry disable")}`);
|
|
41912
|
+
console.log(` Or set: ${pc64.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
|
|
41913
|
+
console.log(` Learn more: ${pc64.cyan("https://wraps.dev/docs")}`);
|
|
41766
41914
|
console.log();
|
|
41767
41915
|
telemetry.markNotificationShown();
|
|
41768
41916
|
}
|
|
41769
41917
|
trackCommand("interactive:menu", { success: true, duration_ms: 0 });
|
|
41770
|
-
|
|
41918
|
+
clack60.intro(pc64.bold(`WRAPS CLI v${VERSION}`));
|
|
41771
41919
|
console.log(" Deploy AWS infrastructure to your account.\n");
|
|
41772
|
-
const action = await
|
|
41920
|
+
const action = await clack60.select({
|
|
41773
41921
|
message: "What would you like to do?",
|
|
41774
41922
|
options: [
|
|
41775
41923
|
{
|
|
@@ -41819,13 +41967,13 @@ if (!primaryCommand) {
|
|
|
41819
41967
|
}
|
|
41820
41968
|
]
|
|
41821
41969
|
});
|
|
41822
|
-
if (
|
|
41970
|
+
if (clack60.isCancel(action)) {
|
|
41823
41971
|
trackCommand("interactive:cancel", {
|
|
41824
41972
|
success: true,
|
|
41825
41973
|
duration_ms: Date.now() - startTime
|
|
41826
41974
|
});
|
|
41827
41975
|
await telemetry.shutdown();
|
|
41828
|
-
|
|
41976
|
+
clack60.cancel("Operation cancelled.");
|
|
41829
41977
|
process.exit(0);
|
|
41830
41978
|
}
|
|
41831
41979
|
trackCommand(`interactive:${action}`, {
|
|
@@ -41905,20 +42053,20 @@ async function run() {
|
|
|
41905
42053
|
const telemetry = getTelemetryClient();
|
|
41906
42054
|
if (telemetry.shouldShowNotification()) {
|
|
41907
42055
|
console.log();
|
|
41908
|
-
|
|
42056
|
+
clack60.log.info(pc64.bold("Anonymous Telemetry"));
|
|
41909
42057
|
console.log(
|
|
41910
|
-
` Wraps collects ${
|
|
42058
|
+
` Wraps collects ${pc64.cyan("anonymous usage data")} to improve the CLI.`
|
|
41911
42059
|
);
|
|
41912
42060
|
console.log(
|
|
41913
|
-
` We ${
|
|
42061
|
+
` We ${pc64.bold("never")} collect: domains, AWS credentials, email content, or PII.`
|
|
41914
42062
|
);
|
|
41915
42063
|
console.log(
|
|
41916
|
-
` We ${
|
|
42064
|
+
` We ${pc64.bold("only")} collect: command names, success/failure, CLI version, OS.`
|
|
41917
42065
|
);
|
|
41918
42066
|
console.log();
|
|
41919
|
-
console.log(` Opt-out anytime: ${
|
|
41920
|
-
console.log(` Or set: ${
|
|
41921
|
-
console.log(` Learn more: ${
|
|
42067
|
+
console.log(` Opt-out anytime: ${pc64.cyan("wraps telemetry disable")}`);
|
|
42068
|
+
console.log(` Or set: ${pc64.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
|
|
42069
|
+
console.log(` Learn more: ${pc64.cyan("https://wraps.dev/docs")}`);
|
|
41922
42070
|
console.log();
|
|
41923
42071
|
telemetry.markNotificationShown();
|
|
41924
42072
|
}
|
|
@@ -42002,10 +42150,10 @@ async function run() {
|
|
|
42002
42150
|
break;
|
|
42003
42151
|
case "verify": {
|
|
42004
42152
|
if (!flags.domain) {
|
|
42005
|
-
|
|
42153
|
+
clack60.log.error("--domain flag is required");
|
|
42006
42154
|
console.log(
|
|
42007
42155
|
`
|
|
42008
|
-
Usage: ${
|
|
42156
|
+
Usage: ${pc64.cyan("wraps email verify --domain yourapp.com")}
|
|
42009
42157
|
`
|
|
42010
42158
|
);
|
|
42011
42159
|
throw new Error("Missing required flag: --domain");
|
|
@@ -42077,12 +42225,12 @@ Usage: ${pc63.cyan("wraps email verify --domain yourapp.com")}
|
|
|
42077
42225
|
});
|
|
42078
42226
|
break;
|
|
42079
42227
|
default:
|
|
42080
|
-
|
|
42228
|
+
clack60.log.error(
|
|
42081
42229
|
`Unknown inbound command: ${inboundSubCommand || "(none)"}`
|
|
42082
42230
|
);
|
|
42083
42231
|
console.log(
|
|
42084
42232
|
`
|
|
42085
|
-
Available commands: ${
|
|
42233
|
+
Available commands: ${pc64.cyan("init")}, ${pc64.cyan("destroy")}, ${pc64.cyan("status")}, ${pc64.cyan("verify")}, ${pc64.cyan("test")}, ${pc64.cyan("add")}, ${pc64.cyan("remove")}
|
|
42086
42234
|
`
|
|
42087
42235
|
);
|
|
42088
42236
|
throw new Error(
|
|
@@ -42134,12 +42282,12 @@ Available commands: ${pc63.cyan("init")}, ${pc63.cyan("destroy")}, ${pc63.cyan("
|
|
|
42134
42282
|
break;
|
|
42135
42283
|
}
|
|
42136
42284
|
default:
|
|
42137
|
-
|
|
42285
|
+
clack60.log.error(
|
|
42138
42286
|
`Unknown reply command: ${replySubCommand || "(none)"}`
|
|
42139
42287
|
);
|
|
42140
42288
|
console.log(
|
|
42141
42289
|
`
|
|
42142
|
-
Available commands: ${
|
|
42290
|
+
Available commands: ${pc64.cyan("init")}, ${pc64.cyan("rotate")}, ${pc64.cyan("status")}, ${pc64.cyan("destroy")}, ${pc64.cyan("decode")}
|
|
42143
42291
|
`
|
|
42144
42292
|
);
|
|
42145
42293
|
throw new Error(
|
|
@@ -42164,10 +42312,10 @@ Available commands: ${pc63.cyan("init")}, ${pc63.cyan("rotate")}, ${pc63.cyan("s
|
|
|
42164
42312
|
break;
|
|
42165
42313
|
case "verify": {
|
|
42166
42314
|
if (!flags.domain) {
|
|
42167
|
-
|
|
42315
|
+
clack60.log.error("--domain flag is required");
|
|
42168
42316
|
console.log(
|
|
42169
42317
|
`
|
|
42170
|
-
Usage: ${
|
|
42318
|
+
Usage: ${pc64.cyan("wraps email domains verify --domain yourapp.com")}
|
|
42171
42319
|
`
|
|
42172
42320
|
);
|
|
42173
42321
|
throw new Error("Missing required flag: --domain");
|
|
@@ -42177,10 +42325,10 @@ Usage: ${pc63.cyan("wraps email domains verify --domain yourapp.com")}
|
|
|
42177
42325
|
}
|
|
42178
42326
|
case "get-dkim": {
|
|
42179
42327
|
if (!flags.domain) {
|
|
42180
|
-
|
|
42328
|
+
clack60.log.error("--domain flag is required");
|
|
42181
42329
|
console.log(
|
|
42182
42330
|
`
|
|
42183
|
-
Usage: ${
|
|
42331
|
+
Usage: ${pc64.cyan("wraps email domains get-dkim --domain yourapp.com")}
|
|
42184
42332
|
`
|
|
42185
42333
|
);
|
|
42186
42334
|
throw new Error("Missing required flag: --domain");
|
|
@@ -42190,10 +42338,10 @@ Usage: ${pc63.cyan("wraps email domains get-dkim --domain yourapp.com")}
|
|
|
42190
42338
|
}
|
|
42191
42339
|
case "remove": {
|
|
42192
42340
|
if (!flags.domain) {
|
|
42193
|
-
|
|
42341
|
+
clack60.log.error("--domain flag is required");
|
|
42194
42342
|
console.log(
|
|
42195
42343
|
`
|
|
42196
|
-
Usage: ${
|
|
42344
|
+
Usage: ${pc64.cyan("wraps email domains remove --domain yourapp.com --force")}
|
|
42197
42345
|
`
|
|
42198
42346
|
);
|
|
42199
42347
|
throw new Error("Missing required flag: --domain");
|
|
@@ -42223,12 +42371,12 @@ Usage: ${pc63.cyan("wraps email domains remove --domain yourapp.com --force")}
|
|
|
42223
42371
|
break;
|
|
42224
42372
|
}
|
|
42225
42373
|
default:
|
|
42226
|
-
|
|
42374
|
+
clack60.log.error(
|
|
42227
42375
|
`Unknown domains command: ${domainsSubCommand || "(none)"}`
|
|
42228
42376
|
);
|
|
42229
42377
|
console.log(
|
|
42230
42378
|
`
|
|
42231
|
-
Available commands: ${
|
|
42379
|
+
Available commands: ${pc64.cyan("add")}, ${pc64.cyan("list")}, ${pc64.cyan("verify")}, ${pc64.cyan("get-dkim")}, ${pc64.cyan("remove")}, ${pc64.cyan("config")}
|
|
42232
42380
|
`
|
|
42233
42381
|
);
|
|
42234
42382
|
throw new Error(
|
|
@@ -42270,12 +42418,12 @@ Available commands: ${pc63.cyan("add")}, ${pc63.cyan("list")}, ${pc63.cyan("veri
|
|
|
42270
42418
|
});
|
|
42271
42419
|
break;
|
|
42272
42420
|
default:
|
|
42273
|
-
|
|
42421
|
+
clack60.log.error(
|
|
42274
42422
|
`Unknown templates command: ${templatesSubCommand || "(none)"}`
|
|
42275
42423
|
);
|
|
42276
42424
|
console.log(
|
|
42277
42425
|
`
|
|
42278
|
-
Available commands: ${
|
|
42426
|
+
Available commands: ${pc64.cyan("init")}, ${pc64.cyan("push")}, ${pc64.cyan("preview")}
|
|
42279
42427
|
`
|
|
42280
42428
|
);
|
|
42281
42429
|
throw new Error(
|
|
@@ -42314,12 +42462,12 @@ Available commands: ${pc63.cyan("init")}, ${pc63.cyan("push")}, ${pc63.cyan("pre
|
|
|
42314
42462
|
});
|
|
42315
42463
|
break;
|
|
42316
42464
|
default:
|
|
42317
|
-
|
|
42465
|
+
clack60.log.error(
|
|
42318
42466
|
`Unknown workflows command: ${workflowsSubCommand || "(none)"}`
|
|
42319
42467
|
);
|
|
42320
42468
|
console.log(
|
|
42321
42469
|
`
|
|
42322
|
-
Available commands: ${
|
|
42470
|
+
Available commands: ${pc64.cyan("init")}, ${pc64.cyan("validate")}, ${pc64.cyan("push")}
|
|
42323
42471
|
`
|
|
42324
42472
|
);
|
|
42325
42473
|
throw new Error(
|
|
@@ -42344,10 +42492,10 @@ Available commands: ${pc63.cyan("init")}, ${pc63.cyan("validate")}, ${pc63.cyan(
|
|
|
42344
42492
|
});
|
|
42345
42493
|
break;
|
|
42346
42494
|
default:
|
|
42347
|
-
|
|
42495
|
+
clack60.log.error(`Unknown email command: ${subCommand}`);
|
|
42348
42496
|
console.log(
|
|
42349
42497
|
`
|
|
42350
|
-
Run ${
|
|
42498
|
+
Run ${pc64.cyan("wraps --help")} for available commands.
|
|
42351
42499
|
`
|
|
42352
42500
|
);
|
|
42353
42501
|
throw new Error(`Unknown email command: ${subCommand}`);
|
|
@@ -42361,6 +42509,32 @@ Run ${pc63.cyan("wraps --help")} for available commands.
|
|
|
42361
42509
|
});
|
|
42362
42510
|
return;
|
|
42363
42511
|
}
|
|
42512
|
+
if (primaryCommand === "license" && subCommand) {
|
|
42513
|
+
switch (subCommand) {
|
|
42514
|
+
case "generate":
|
|
42515
|
+
await licenseGenerate({
|
|
42516
|
+
// baseline:allow-no-region
|
|
42517
|
+
tier: flags.tier,
|
|
42518
|
+
expires: flags.expires,
|
|
42519
|
+
json: flags.json
|
|
42520
|
+
});
|
|
42521
|
+
break;
|
|
42522
|
+
default:
|
|
42523
|
+
clack60.log.error(`Unknown license command: ${subCommand}`);
|
|
42524
|
+
console.log(
|
|
42525
|
+
`
|
|
42526
|
+
Run ${pc64.cyan("wraps --help")} for available commands.
|
|
42527
|
+
`
|
|
42528
|
+
);
|
|
42529
|
+
throw new Error(`Unknown license command: ${subCommand}`);
|
|
42530
|
+
}
|
|
42531
|
+
trackCommand(`license:${subCommand}`, {
|
|
42532
|
+
success: true,
|
|
42533
|
+
duration_ms: Date.now() - startTime,
|
|
42534
|
+
service: "license"
|
|
42535
|
+
});
|
|
42536
|
+
return;
|
|
42537
|
+
}
|
|
42364
42538
|
if (primaryCommand === "selfhost" && subCommand) {
|
|
42365
42539
|
switch (subCommand) {
|
|
42366
42540
|
case "deploy":
|
|
@@ -42389,10 +42563,10 @@ Run ${pc63.cyan("wraps --help")} for available commands.
|
|
|
42389
42563
|
});
|
|
42390
42564
|
break;
|
|
42391
42565
|
default:
|
|
42392
|
-
|
|
42566
|
+
clack60.log.error(`Unknown selfhost command: ${subCommand}`);
|
|
42393
42567
|
console.log(
|
|
42394
42568
|
`
|
|
42395
|
-
Run ${
|
|
42569
|
+
Run ${pc64.cyan("wraps --help")} for available commands.
|
|
42396
42570
|
`
|
|
42397
42571
|
);
|
|
42398
42572
|
throw new Error(`Unknown selfhost command: ${subCommand}`);
|
|
@@ -42472,10 +42646,10 @@ Run ${pc63.cyan("wraps --help")} for available commands.
|
|
|
42472
42646
|
});
|
|
42473
42647
|
break;
|
|
42474
42648
|
default:
|
|
42475
|
-
|
|
42649
|
+
clack60.log.error(`Unknown sms command: ${subCommand}`);
|
|
42476
42650
|
console.log(
|
|
42477
42651
|
`
|
|
42478
|
-
Run ${
|
|
42652
|
+
Run ${pc64.cyan("wraps --help")} for available commands.
|
|
42479
42653
|
`
|
|
42480
42654
|
);
|
|
42481
42655
|
throw new Error(`Unknown sms command: ${subCommand}`);
|
|
@@ -42536,10 +42710,10 @@ Run ${pc63.cyan("wraps --help")} for available commands.
|
|
|
42536
42710
|
});
|
|
42537
42711
|
break;
|
|
42538
42712
|
default:
|
|
42539
|
-
|
|
42713
|
+
clack60.log.error(`Unknown cdn command: ${subCommand}`);
|
|
42540
42714
|
console.log(
|
|
42541
42715
|
`
|
|
42542
|
-
Run ${
|
|
42716
|
+
Run ${pc64.cyan("wraps --help")} for available commands.
|
|
42543
42717
|
`
|
|
42544
42718
|
);
|
|
42545
42719
|
throw new Error(`Unknown cdn command: ${subCommand}`);
|
|
@@ -42561,13 +42735,13 @@ Run ${pc63.cyan("wraps --help")} for available commands.
|
|
|
42561
42735
|
});
|
|
42562
42736
|
break;
|
|
42563
42737
|
default:
|
|
42564
|
-
|
|
42738
|
+
clack60.log.error(
|
|
42565
42739
|
`Unknown workflow command: ${subCommand || "(none)"}`
|
|
42566
42740
|
);
|
|
42567
42741
|
console.log(`
|
|
42568
|
-
Available commands: ${
|
|
42742
|
+
Available commands: ${pc64.cyan("init")}
|
|
42569
42743
|
`);
|
|
42570
|
-
console.log(`Run ${
|
|
42744
|
+
console.log(`Run ${pc64.cyan("wraps --help")} for more information.
|
|
42571
42745
|
`);
|
|
42572
42746
|
throw new Error(
|
|
42573
42747
|
`Unknown workflow command: ${subCommand || "(none)"}`
|
|
@@ -42609,14 +42783,14 @@ Available commands: ${pc63.cyan("init")}
|
|
|
42609
42783
|
});
|
|
42610
42784
|
break;
|
|
42611
42785
|
default:
|
|
42612
|
-
|
|
42786
|
+
clack60.log.error(`Unknown platform command: ${subCommand}`);
|
|
42613
42787
|
console.log(
|
|
42614
42788
|
`
|
|
42615
|
-
Available commands: ${
|
|
42789
|
+
Available commands: ${pc64.cyan("connect")}, ${pc64.cyan("update-role")}
|
|
42616
42790
|
`
|
|
42617
42791
|
);
|
|
42618
42792
|
console.log(
|
|
42619
|
-
`Run ${
|
|
42793
|
+
`Run ${pc64.cyan("wraps platform")} for more information.
|
|
42620
42794
|
`
|
|
42621
42795
|
);
|
|
42622
42796
|
throw new Error(`Unknown platform command: ${subCommand}`);
|
|
@@ -42641,10 +42815,10 @@ Available commands: ${pc63.cyan("connect")}, ${pc63.cyan("update-role")}
|
|
|
42641
42815
|
await logout();
|
|
42642
42816
|
break;
|
|
42643
42817
|
default:
|
|
42644
|
-
|
|
42818
|
+
clack60.log.error(`Unknown auth command: ${subCommand || "(none)"}`);
|
|
42645
42819
|
console.log(
|
|
42646
42820
|
`
|
|
42647
|
-
Available commands: ${
|
|
42821
|
+
Available commands: ${pc64.cyan("login")}, ${pc64.cyan("status")}, ${pc64.cyan("logout")}
|
|
42648
42822
|
`
|
|
42649
42823
|
);
|
|
42650
42824
|
throw new Error(`Unknown auth command: ${subCommand || "(none)"}`);
|
|
@@ -42662,13 +42836,13 @@ Available commands: ${pc63.cyan("login")}, ${pc63.cyan("status")}, ${pc63.cyan("
|
|
|
42662
42836
|
await doctor();
|
|
42663
42837
|
break;
|
|
42664
42838
|
default:
|
|
42665
|
-
|
|
42839
|
+
clack60.log.error(`Unknown aws command: ${subCommand}`);
|
|
42666
42840
|
console.log(
|
|
42667
42841
|
`
|
|
42668
|
-
Available commands: ${
|
|
42842
|
+
Available commands: ${pc64.cyan("setup")}, ${pc64.cyan("doctor")}
|
|
42669
42843
|
`
|
|
42670
42844
|
);
|
|
42671
|
-
console.log(`Run ${
|
|
42845
|
+
console.log(`Run ${pc64.cyan("wraps --help")} for more information.
|
|
42672
42846
|
`);
|
|
42673
42847
|
throw new Error(`Unknown aws command: ${subCommand}`);
|
|
42674
42848
|
}
|
|
@@ -42749,10 +42923,10 @@ Available commands: ${pc63.cyan("setup")}, ${pc63.cyan("doctor")}
|
|
|
42749
42923
|
await telemetryStatus();
|
|
42750
42924
|
break;
|
|
42751
42925
|
default:
|
|
42752
|
-
|
|
42926
|
+
clack60.log.error(`Unknown telemetry command: ${subCommand}`);
|
|
42753
42927
|
console.log(
|
|
42754
42928
|
`
|
|
42755
|
-
Available commands: ${
|
|
42929
|
+
Available commands: ${pc64.cyan("enable")}, ${pc64.cyan("disable")}, ${pc64.cyan("status")}
|
|
42756
42930
|
`
|
|
42757
42931
|
);
|
|
42758
42932
|
throw new Error(`Unknown telemetry command: ${subCommand}`);
|
|
@@ -42776,10 +42950,10 @@ Please specify a command for ${primaryCommand} service.
|
|
|
42776
42950
|
showHelp();
|
|
42777
42951
|
break;
|
|
42778
42952
|
default:
|
|
42779
|
-
|
|
42953
|
+
clack60.log.error(`Unknown command: ${primaryCommand}`);
|
|
42780
42954
|
console.log(
|
|
42781
42955
|
`
|
|
42782
|
-
Run ${
|
|
42956
|
+
Run ${pc64.cyan("wraps --help")} for available commands.
|
|
42783
42957
|
`
|
|
42784
42958
|
);
|
|
42785
42959
|
throw new Error(`Unknown command: ${primaryCommand}`);
|