@wraps.dev/cli 2.21.1 → 2.21.5
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 +1078 -894
- 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 +7 -7
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();
|
|
@@ -33289,7 +33432,14 @@ init_events();
|
|
|
33289
33432
|
|
|
33290
33433
|
// src/utils/selfhost/neon.ts
|
|
33291
33434
|
init_esm_shims();
|
|
33292
|
-
async function provisionNeonProject(apiKey, projectName,
|
|
33435
|
+
async function provisionNeonProject(apiKey, projectName, options = {}) {
|
|
33436
|
+
const { region = "aws-us-east-2", orgId } = options;
|
|
33437
|
+
const projectPayload = {
|
|
33438
|
+
name: projectName,
|
|
33439
|
+
pg_version: 16,
|
|
33440
|
+
region_id: region
|
|
33441
|
+
};
|
|
33442
|
+
if (orgId) projectPayload.org_id = orgId;
|
|
33293
33443
|
const response = await fetch("https://console.neon.tech/api/v2/projects", {
|
|
33294
33444
|
method: "POST",
|
|
33295
33445
|
headers: {
|
|
@@ -33297,13 +33447,7 @@ async function provisionNeonProject(apiKey, projectName, region = "aws-us-east-2
|
|
|
33297
33447
|
"Content-Type": "application/json",
|
|
33298
33448
|
Accept: "application/json"
|
|
33299
33449
|
},
|
|
33300
|
-
body: JSON.stringify({
|
|
33301
|
-
project: {
|
|
33302
|
-
name: projectName,
|
|
33303
|
-
pg_version: 16,
|
|
33304
|
-
region_id: region
|
|
33305
|
-
}
|
|
33306
|
-
})
|
|
33450
|
+
body: JSON.stringify({ project: projectPayload })
|
|
33307
33451
|
});
|
|
33308
33452
|
if (!response.ok) {
|
|
33309
33453
|
const body = await response.json().catch(() => ({}));
|
|
@@ -33341,7 +33485,7 @@ var repoRoot = join20(__filename2, "../../../..");
|
|
|
33341
33485
|
async function selfhostDeploy(options) {
|
|
33342
33486
|
const startTime = Date.now();
|
|
33343
33487
|
if (!isJsonMode()) {
|
|
33344
|
-
|
|
33488
|
+
clack43.intro(pc46.bold("Wraps Self-Hosted Control Plane Deploy"));
|
|
33345
33489
|
}
|
|
33346
33490
|
const progress = new DeploymentProgress();
|
|
33347
33491
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -33356,24 +33500,24 @@ async function selfhostDeploy(options) {
|
|
|
33356
33500
|
async () => validateAWSCredentialsWithDetails()
|
|
33357
33501
|
);
|
|
33358
33502
|
const identity = credentialResult.identity;
|
|
33359
|
-
progress.info(`Connected to AWS account: ${
|
|
33503
|
+
progress.info(`Connected to AWS account: ${pc46.cyan(identity.accountId)}`);
|
|
33360
33504
|
for (const warning of credentialResult.warnings) {
|
|
33361
|
-
|
|
33505
|
+
clack43.log.warn(warning);
|
|
33362
33506
|
}
|
|
33363
33507
|
if (credentialResult.credentialSource) {
|
|
33364
33508
|
progress.info(
|
|
33365
|
-
`Using credentials from: ${
|
|
33509
|
+
`Using credentials from: ${pc46.dim(credentialResult.credentialSource)}`
|
|
33366
33510
|
);
|
|
33367
33511
|
}
|
|
33368
33512
|
let region = options.region;
|
|
33369
33513
|
if (!region) {
|
|
33370
|
-
const regionAnswer = await
|
|
33514
|
+
const regionAnswer = await clack43.text({
|
|
33371
33515
|
message: "AWS region to deploy into:",
|
|
33372
33516
|
defaultValue: "us-east-1",
|
|
33373
33517
|
placeholder: "us-east-1"
|
|
33374
33518
|
});
|
|
33375
|
-
if (
|
|
33376
|
-
|
|
33519
|
+
if (clack43.isCancel(regionAnswer)) {
|
|
33520
|
+
clack43.cancel("Operation cancelled.");
|
|
33377
33521
|
process.exit(0);
|
|
33378
33522
|
}
|
|
33379
33523
|
region = regionAnswer || "us-east-1";
|
|
@@ -33383,67 +33527,69 @@ async function selfhostDeploy(options) {
|
|
|
33383
33527
|
region
|
|
33384
33528
|
);
|
|
33385
33529
|
if (existingMetadata?.services?.selfhost) {
|
|
33386
|
-
|
|
33387
|
-
`Self-hosted deployment already exists for account ${
|
|
33530
|
+
clack43.log.warn(
|
|
33531
|
+
`Self-hosted deployment already exists for account ${pc46.cyan(identity.accountId)} in region ${pc46.cyan(region)}`
|
|
33388
33532
|
);
|
|
33389
|
-
|
|
33390
|
-
`API URL: ${
|
|
33533
|
+
clack43.log.info(
|
|
33534
|
+
`API URL: ${pc46.cyan(existingMetadata.services.selfhost.apiUrl)}`
|
|
33391
33535
|
);
|
|
33392
|
-
|
|
33536
|
+
clack43.log.info(
|
|
33393
33537
|
`Deployed: ${existingMetadata.services.selfhost.deployedAt}`
|
|
33394
33538
|
);
|
|
33395
|
-
|
|
33539
|
+
clack43.log.info(`To update: run ${pc46.cyan("wraps selfhost upgrade")}`);
|
|
33396
33540
|
process.exit(0);
|
|
33397
33541
|
}
|
|
33398
33542
|
let neonApiKey = options.neonApiKey;
|
|
33399
33543
|
if (!neonApiKey) {
|
|
33400
|
-
const neonApiKeyAnswer = await
|
|
33544
|
+
const neonApiKeyAnswer = await clack43.password({
|
|
33401
33545
|
message: "Neon API key (create one at console.neon.tech/app/settings/api-keys):"
|
|
33402
33546
|
});
|
|
33403
|
-
if (
|
|
33404
|
-
|
|
33547
|
+
if (clack43.isCancel(neonApiKeyAnswer)) {
|
|
33548
|
+
clack43.cancel("Operation cancelled.");
|
|
33405
33549
|
process.exit(0);
|
|
33406
33550
|
}
|
|
33407
33551
|
neonApiKey = neonApiKeyAnswer;
|
|
33408
33552
|
}
|
|
33553
|
+
const neonOrgId = options.neonOrgId;
|
|
33409
33554
|
let licenseKey = options.licenseKey;
|
|
33410
33555
|
if (!licenseKey) {
|
|
33411
|
-
const licenseKeyAnswer = await
|
|
33556
|
+
const licenseKeyAnswer = await clack43.text({
|
|
33412
33557
|
message: "Wraps enterprise license key:",
|
|
33413
33558
|
placeholder: "wraps_lic_..."
|
|
33414
33559
|
});
|
|
33415
|
-
if (
|
|
33416
|
-
|
|
33560
|
+
if (clack43.isCancel(licenseKeyAnswer)) {
|
|
33561
|
+
clack43.cancel("Operation cancelled.");
|
|
33417
33562
|
process.exit(0);
|
|
33418
33563
|
}
|
|
33419
33564
|
licenseKey = licenseKeyAnswer;
|
|
33420
33565
|
}
|
|
33421
33566
|
let appUrl = options.appUrl;
|
|
33422
33567
|
if (!appUrl) {
|
|
33423
|
-
const appUrlAnswer = await
|
|
33568
|
+
const appUrlAnswer = await clack43.text({
|
|
33424
33569
|
message: "App URL (where your self-hosted dashboard will be served):",
|
|
33425
33570
|
defaultValue: "https://app.wraps.dev",
|
|
33426
33571
|
placeholder: "https://app.yourcompany.com"
|
|
33427
33572
|
});
|
|
33428
|
-
if (
|
|
33429
|
-
|
|
33573
|
+
if (clack43.isCancel(appUrlAnswer)) {
|
|
33574
|
+
clack43.cancel("Operation cancelled.");
|
|
33430
33575
|
process.exit(0);
|
|
33431
33576
|
}
|
|
33432
33577
|
appUrl = appUrlAnswer || "https://app.wraps.dev";
|
|
33433
33578
|
}
|
|
33434
33579
|
if (!(options.yes || options.preview)) {
|
|
33435
|
-
const confirmed = await
|
|
33436
|
-
message: `Deploy self-hosted Wraps API to ${
|
|
33580
|
+
const confirmed = await clack43.confirm({
|
|
33581
|
+
message: `Deploy self-hosted Wraps API to ${pc46.cyan(identity.accountId)} / ${pc46.cyan(region)}?`,
|
|
33437
33582
|
initialValue: true
|
|
33438
33583
|
});
|
|
33439
|
-
if (
|
|
33440
|
-
|
|
33584
|
+
if (clack43.isCancel(confirmed) || !confirmed) {
|
|
33585
|
+
clack43.cancel("Deployment cancelled.");
|
|
33441
33586
|
process.exit(0);
|
|
33442
33587
|
}
|
|
33443
33588
|
}
|
|
33589
|
+
const childStdio = isJsonMode() ? "pipe" : "inherit";
|
|
33444
33590
|
await progress.execute("Building Wraps API", async () => {
|
|
33445
33591
|
execSync2("pnpm --filter @wraps/api build", {
|
|
33446
|
-
stdio:
|
|
33592
|
+
stdio: childStdio,
|
|
33447
33593
|
cwd: repoRoot
|
|
33448
33594
|
});
|
|
33449
33595
|
});
|
|
@@ -33451,17 +33597,18 @@ async function selfhostDeploy(options) {
|
|
|
33451
33597
|
await progress.execute("Packaging Lambda", async () => {
|
|
33452
33598
|
execSync2("/bin/sh -c 'zip -r ../lambda.zip .'", {
|
|
33453
33599
|
cwd: join20(repoRoot, "apps/api/dist"),
|
|
33454
|
-
stdio:
|
|
33600
|
+
stdio: childStdio
|
|
33455
33601
|
});
|
|
33456
33602
|
});
|
|
33457
33603
|
const neonProject = await progress.execute(
|
|
33458
33604
|
"Provisioning Neon PostgreSQL database",
|
|
33459
33605
|
async () => provisionNeonProject(
|
|
33460
33606
|
neonApiKey,
|
|
33461
|
-
buildNeonProjectName(identity.accountId, region)
|
|
33607
|
+
buildNeonProjectName(identity.accountId, region),
|
|
33608
|
+
{ orgId: neonOrgId }
|
|
33462
33609
|
)
|
|
33463
33610
|
);
|
|
33464
|
-
progress.info(`Neon project created: ${
|
|
33611
|
+
progress.info(`Neon project created: ${pc46.cyan(neonProject.name)}`);
|
|
33465
33612
|
const unsubscribeSecret = randomBytes6(32).toString("hex");
|
|
33466
33613
|
const betterAuthSecret = randomBytes6(32).toString("hex");
|
|
33467
33614
|
const selfhostConfig = {
|
|
@@ -33493,7 +33640,7 @@ async function selfhostDeploy(options) {
|
|
|
33493
33640
|
await saveConnectionMetadata(savedMetadata);
|
|
33494
33641
|
await progress.execute("Running database migrations", async () => {
|
|
33495
33642
|
execSync2("pnpm --filter @wraps/db db:migrate", {
|
|
33496
|
-
stdio:
|
|
33643
|
+
stdio: childStdio,
|
|
33497
33644
|
cwd: repoRoot,
|
|
33498
33645
|
env: {
|
|
33499
33646
|
...process.env,
|
|
@@ -33564,8 +33711,8 @@ async function selfhostDeploy(options) {
|
|
|
33564
33711
|
resourceChanges: previewResult.resourceChanges,
|
|
33565
33712
|
commandName: "wraps selfhost deploy"
|
|
33566
33713
|
});
|
|
33567
|
-
|
|
33568
|
-
|
|
33714
|
+
clack43.outro(
|
|
33715
|
+
pc46.green("Preview complete. Run without --preview to deploy.")
|
|
33569
33716
|
);
|
|
33570
33717
|
return;
|
|
33571
33718
|
} catch (error) {
|
|
@@ -33630,23 +33777,23 @@ async function selfhostDeploy(options) {
|
|
|
33630
33777
|
return;
|
|
33631
33778
|
}
|
|
33632
33779
|
console.log("\n");
|
|
33633
|
-
|
|
33780
|
+
clack43.log.success(pc46.green(pc46.bold("Self-hosted Wraps API deployed!")));
|
|
33634
33781
|
console.log("\n");
|
|
33635
|
-
|
|
33782
|
+
clack43.note(
|
|
33636
33783
|
[
|
|
33637
|
-
`${
|
|
33638
|
-
`${
|
|
33639
|
-
`${
|
|
33640
|
-
`${
|
|
33784
|
+
`${pc46.bold("API URL:")} ${pc46.cyan(outputs.apiUrl)}`,
|
|
33785
|
+
`${pc46.bold("Region:")} ${pc46.cyan(region)}`,
|
|
33786
|
+
`${pc46.bold("Lambda ARN:")} ${pc46.dim(outputs.lambdaArn)}`,
|
|
33787
|
+
`${pc46.bold("Neon Project:")} ${pc46.dim(neonProject.id)}`,
|
|
33641
33788
|
"",
|
|
33642
|
-
|
|
33643
|
-
|
|
33644
|
-
|
|
33789
|
+
pc46.dim("Next steps:"),
|
|
33790
|
+
pc46.dim(` Set WRAPS_API_URL=${outputs.apiUrl} in your app`),
|
|
33791
|
+
pc46.dim(" Run: wraps selfhost status")
|
|
33645
33792
|
].join("\n"),
|
|
33646
33793
|
"Self-Hosted Deployment"
|
|
33647
33794
|
);
|
|
33648
|
-
|
|
33649
|
-
|
|
33795
|
+
clack43.outro(
|
|
33796
|
+
pc46.green(`Deployed in ${((Date.now() - startTime) / 1e3).toFixed(1)}s`)
|
|
33650
33797
|
);
|
|
33651
33798
|
}
|
|
33652
33799
|
|
|
@@ -33658,28 +33805,28 @@ init_json_output();
|
|
|
33658
33805
|
init_metadata();
|
|
33659
33806
|
init_output();
|
|
33660
33807
|
init_region_resolver();
|
|
33661
|
-
import * as
|
|
33662
|
-
import
|
|
33808
|
+
import * as clack44 from "@clack/prompts";
|
|
33809
|
+
import pc47 from "picocolors";
|
|
33663
33810
|
function displaySelfhostStatus(options) {
|
|
33664
33811
|
const lines = [];
|
|
33665
|
-
lines.push(
|
|
33812
|
+
lines.push(pc47.bold(pc47.green("Self-Hosted Control Plane Active")));
|
|
33666
33813
|
lines.push("");
|
|
33667
|
-
lines.push(
|
|
33668
|
-
lines.push(` URL: ${
|
|
33669
|
-
lines.push(` Region: ${
|
|
33670
|
-
lines.push(` Deployed: ${
|
|
33814
|
+
lines.push(pc47.bold("API"));
|
|
33815
|
+
lines.push(` URL: ${pc47.cyan(options.apiUrl)}`);
|
|
33816
|
+
lines.push(` Region: ${pc47.cyan(options.region)}`);
|
|
33817
|
+
lines.push(` Deployed: ${pc47.dim(options.deployedAt)}`);
|
|
33671
33818
|
lines.push("");
|
|
33672
|
-
lines.push(
|
|
33673
|
-
lines.push(` App URL: ${
|
|
33674
|
-
lines.push(` License Key: ${
|
|
33675
|
-
lines.push(` Neon Project: ${
|
|
33676
|
-
|
|
33819
|
+
lines.push(pc47.bold("Configuration"));
|
|
33820
|
+
lines.push(` App URL: ${pc47.cyan(options.appUrl)}`);
|
|
33821
|
+
lines.push(` License Key: ${pc47.dim(`${options.licenseKeyPrefix}...`)}`);
|
|
33822
|
+
lines.push(` Neon Project: ${pc47.dim(options.neonProjectId)}`);
|
|
33823
|
+
clack44.note(lines.join("\n"), "Self-Hosted Status");
|
|
33677
33824
|
}
|
|
33678
33825
|
async function selfhostStatus(options) {
|
|
33679
33826
|
const startTime = Date.now();
|
|
33680
33827
|
const progress = new DeploymentProgress();
|
|
33681
33828
|
if (!isJsonMode()) {
|
|
33682
|
-
|
|
33829
|
+
clack44.intro(pc47.bold("Wraps Self-Hosted Status"));
|
|
33683
33830
|
}
|
|
33684
33831
|
const identity = await progress.execute(
|
|
33685
33832
|
"Loading self-hosted status",
|
|
@@ -33694,10 +33841,10 @@ async function selfhostStatus(options) {
|
|
|
33694
33841
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
33695
33842
|
if (!metadata?.services?.selfhost) {
|
|
33696
33843
|
progress.stop();
|
|
33697
|
-
|
|
33844
|
+
clack44.log.error("No self-hosted deployment found");
|
|
33698
33845
|
console.log(
|
|
33699
33846
|
`
|
|
33700
|
-
Run ${
|
|
33847
|
+
Run ${pc47.cyan("wraps selfhost deploy")} to deploy the self-hosted control plane.
|
|
33701
33848
|
`
|
|
33702
33849
|
);
|
|
33703
33850
|
process.exit(1);
|
|
@@ -33719,15 +33866,15 @@ Run ${pc46.cyan("wraps selfhost deploy")} to deploy the self-hosted control plan
|
|
|
33719
33866
|
}
|
|
33720
33867
|
displaySelfhostStatus(statusData);
|
|
33721
33868
|
console.log("");
|
|
33722
|
-
|
|
33869
|
+
clack44.log.info(pc47.bold("Commands:"));
|
|
33723
33870
|
console.log(
|
|
33724
|
-
` ${
|
|
33871
|
+
` ${pc47.cyan("wraps selfhost upgrade")} - Rebuild and redeploy the API Lambda`
|
|
33725
33872
|
);
|
|
33726
33873
|
trackCommand("selfhost:status", {
|
|
33727
33874
|
success: true,
|
|
33728
33875
|
duration_ms: Date.now() - startTime
|
|
33729
33876
|
});
|
|
33730
|
-
|
|
33877
|
+
clack44.outro(pc47.dim("Self-hosted deployment is active"));
|
|
33731
33878
|
}
|
|
33732
33879
|
|
|
33733
33880
|
// src/commands/selfhost/upgrade.ts
|
|
@@ -33735,9 +33882,9 @@ init_esm_shims();
|
|
|
33735
33882
|
import { execSync as execSync3 } from "child_process";
|
|
33736
33883
|
import { join as join21 } from "path";
|
|
33737
33884
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
33738
|
-
import * as
|
|
33885
|
+
import * as clack45 from "@clack/prompts";
|
|
33739
33886
|
import * as pulumi27 from "@pulumi/pulumi";
|
|
33740
|
-
import
|
|
33887
|
+
import pc48 from "picocolors";
|
|
33741
33888
|
init_events();
|
|
33742
33889
|
init_aws();
|
|
33743
33890
|
init_errors();
|
|
@@ -33752,7 +33899,7 @@ var repoRoot2 = join21(__filename3, "../../../..");
|
|
|
33752
33899
|
async function selfhostUpgrade(options) {
|
|
33753
33900
|
const startTime = Date.now();
|
|
33754
33901
|
if (!isJsonMode()) {
|
|
33755
|
-
|
|
33902
|
+
clack45.intro(pc48.bold("Wraps Self-Hosted Control Plane Upgrade"));
|
|
33756
33903
|
}
|
|
33757
33904
|
const progress = new DeploymentProgress();
|
|
33758
33905
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -33767,7 +33914,7 @@ async function selfhostUpgrade(options) {
|
|
|
33767
33914
|
async () => validateAWSCredentialsWithDetails()
|
|
33768
33915
|
);
|
|
33769
33916
|
const identity = credentialResult.identity;
|
|
33770
|
-
progress.info(`Connected to AWS account: ${
|
|
33917
|
+
progress.info(`Connected to AWS account: ${pc48.cyan(identity.accountId)}`);
|
|
33771
33918
|
const region = await resolveRegionForCommand({
|
|
33772
33919
|
accountId: identity.accountId,
|
|
33773
33920
|
optionRegion: options.region,
|
|
@@ -33776,28 +33923,29 @@ async function selfhostUpgrade(options) {
|
|
|
33776
33923
|
});
|
|
33777
33924
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
33778
33925
|
if (!metadata?.services?.selfhost) {
|
|
33779
|
-
|
|
33780
|
-
|
|
33926
|
+
clack45.log.error("No self-hosted deployment found.");
|
|
33927
|
+
clack45.log.info(`Run ${pc48.cyan("wraps selfhost deploy")} first.`);
|
|
33781
33928
|
process.exit(1);
|
|
33782
33929
|
}
|
|
33783
33930
|
const selfhostService = metadata.services.selfhost;
|
|
33784
33931
|
progress.info(`Found deployment from: ${selfhostService.deployedAt}`);
|
|
33785
|
-
progress.info(`API URL: ${
|
|
33932
|
+
progress.info(`API URL: ${pc48.cyan(selfhostService.apiUrl)}`);
|
|
33786
33933
|
if (!(options.yes || options.preview)) {
|
|
33787
|
-
const confirmed = await
|
|
33788
|
-
message: `Upgrade self-hosted deployment in ${
|
|
33934
|
+
const confirmed = await clack45.confirm({
|
|
33935
|
+
message: `Upgrade self-hosted deployment in ${pc48.cyan(identity.accountId)} / ${pc48.cyan(region)}?`,
|
|
33789
33936
|
initialValue: true
|
|
33790
33937
|
});
|
|
33791
|
-
if (
|
|
33792
|
-
|
|
33938
|
+
if (clack45.isCancel(confirmed) || !confirmed) {
|
|
33939
|
+
clack45.cancel("Upgrade cancelled.");
|
|
33793
33940
|
process.exit(0);
|
|
33794
33941
|
}
|
|
33795
33942
|
}
|
|
33796
33943
|
const config2 = selfhostService.config;
|
|
33797
33944
|
const stackName = selfhostService.pulumiStackName || `wraps-selfhost-${identity.accountId}-${region}`;
|
|
33945
|
+
const childStdio = isJsonMode() ? "pipe" : "inherit";
|
|
33798
33946
|
await progress.execute("Building Wraps API", async () => {
|
|
33799
33947
|
execSync3("pnpm --filter @wraps/api build", {
|
|
33800
|
-
stdio:
|
|
33948
|
+
stdio: childStdio,
|
|
33801
33949
|
cwd: repoRoot2
|
|
33802
33950
|
});
|
|
33803
33951
|
});
|
|
@@ -33805,7 +33953,7 @@ async function selfhostUpgrade(options) {
|
|
|
33805
33953
|
await progress.execute("Packaging Lambda", async () => {
|
|
33806
33954
|
execSync3("/bin/sh -c 'zip -r ../lambda.zip .'", {
|
|
33807
33955
|
cwd: join21(repoRoot2, "apps/api/dist"),
|
|
33808
|
-
stdio:
|
|
33956
|
+
stdio: childStdio
|
|
33809
33957
|
});
|
|
33810
33958
|
});
|
|
33811
33959
|
const createStack = async () => {
|
|
@@ -33870,8 +34018,8 @@ async function selfhostUpgrade(options) {
|
|
|
33870
34018
|
resourceChanges: previewResult.resourceChanges,
|
|
33871
34019
|
commandName: "wraps selfhost upgrade"
|
|
33872
34020
|
});
|
|
33873
|
-
|
|
33874
|
-
|
|
34021
|
+
clack45.outro(
|
|
34022
|
+
pc48.green("Preview complete. Run without --preview to upgrade.")
|
|
33875
34023
|
);
|
|
33876
34024
|
return;
|
|
33877
34025
|
} catch (error) {
|
|
@@ -33942,28 +34090,28 @@ async function selfhostUpgrade(options) {
|
|
|
33942
34090
|
}
|
|
33943
34091
|
progress.info("Deployment metadata updated");
|
|
33944
34092
|
console.log("\n");
|
|
33945
|
-
|
|
34093
|
+
clack45.log.success(pc48.green(pc48.bold("Self-hosted Wraps API upgraded!")));
|
|
33946
34094
|
console.log("\n");
|
|
33947
|
-
|
|
34095
|
+
clack45.note(
|
|
33948
34096
|
[
|
|
33949
|
-
`${
|
|
33950
|
-
`${
|
|
33951
|
-
`${
|
|
34097
|
+
`${pc48.bold("API URL:")} ${pc48.cyan(outputs.apiUrl || selfhostService.apiUrl)}`,
|
|
34098
|
+
`${pc48.bold("Region:")} ${pc48.cyan(region)}`,
|
|
34099
|
+
`${pc48.bold("Lambda ARN:")} ${pc48.dim(outputs.lambdaArn)}`
|
|
33952
34100
|
].join("\n"),
|
|
33953
34101
|
"Self-Hosted Deployment"
|
|
33954
34102
|
);
|
|
33955
|
-
|
|
33956
|
-
|
|
34103
|
+
clack45.outro(
|
|
34104
|
+
pc48.green(`Upgraded in ${((Date.now() - startTime) / 1e3).toFixed(1)}s`)
|
|
33957
34105
|
);
|
|
33958
34106
|
}
|
|
33959
34107
|
|
|
33960
34108
|
// src/commands/shared/dashboard.ts
|
|
33961
34109
|
init_esm_shims();
|
|
33962
|
-
import * as
|
|
34110
|
+
import * as clack46 from "@clack/prompts";
|
|
33963
34111
|
import * as pulumi28 from "@pulumi/pulumi";
|
|
33964
34112
|
import getPort from "get-port";
|
|
33965
34113
|
import open2 from "open";
|
|
33966
|
-
import
|
|
34114
|
+
import pc49 from "picocolors";
|
|
33967
34115
|
|
|
33968
34116
|
// src/console/server.ts
|
|
33969
34117
|
init_esm_shims();
|
|
@@ -36617,7 +36765,7 @@ init_output();
|
|
|
36617
36765
|
init_pulumi();
|
|
36618
36766
|
async function dashboard(options) {
|
|
36619
36767
|
await ensurePulumiInstalled();
|
|
36620
|
-
|
|
36768
|
+
clack46.intro(pc49.bold("Wraps Dashboard"));
|
|
36621
36769
|
const progress = new DeploymentProgress();
|
|
36622
36770
|
const identity = await progress.execute(
|
|
36623
36771
|
"Validating AWS credentials",
|
|
@@ -36658,9 +36806,9 @@ async function dashboard(options) {
|
|
|
36658
36806
|
}
|
|
36659
36807
|
} catch (_error) {
|
|
36660
36808
|
progress.stop();
|
|
36661
|
-
|
|
36809
|
+
clack46.log.error("No Wraps infrastructure found");
|
|
36662
36810
|
console.log(
|
|
36663
|
-
`\\nRun ${
|
|
36811
|
+
`\\nRun ${pc49.cyan("wraps email init")}, ${pc49.cyan("wraps sms init")}, or ${pc49.cyan("wraps storage init")} to deploy infrastructure first.\\n`
|
|
36664
36812
|
);
|
|
36665
36813
|
process.exit(1);
|
|
36666
36814
|
}
|
|
@@ -36702,9 +36850,9 @@ async function dashboard(options) {
|
|
|
36702
36850
|
}
|
|
36703
36851
|
const port = options.port || await getPort({ port: [5555, 5556, 5557, 5558, 5559] });
|
|
36704
36852
|
progress.stop();
|
|
36705
|
-
|
|
36853
|
+
clack46.log.success("Starting dashboard server...");
|
|
36706
36854
|
console.log(
|
|
36707
|
-
`${
|
|
36855
|
+
`${pc49.dim("Using current AWS credentials (no role assumption)")}\\n`
|
|
36708
36856
|
);
|
|
36709
36857
|
const { url } = await startConsoleServer({
|
|
36710
36858
|
port,
|
|
@@ -36737,8 +36885,8 @@ async function dashboard(options) {
|
|
|
36737
36885
|
cdnCustomDomain,
|
|
36738
36886
|
cdnCertificateArn
|
|
36739
36887
|
});
|
|
36740
|
-
console.log(`\\n${
|
|
36741
|
-
console.log(`${
|
|
36888
|
+
console.log(`\\n${pc49.bold("Dashboard:")} ${pc49.cyan(url)}`);
|
|
36889
|
+
console.log(`${pc49.dim("Press Ctrl+C to stop")}\\n`);
|
|
36742
36890
|
getTelemetryClient().showFooterOnce();
|
|
36743
36891
|
if (!options.noOpen) {
|
|
36744
36892
|
await open2(url);
|
|
@@ -36759,8 +36907,8 @@ init_aws();
|
|
|
36759
36907
|
init_errors();
|
|
36760
36908
|
init_json_output();
|
|
36761
36909
|
init_metadata();
|
|
36762
|
-
import * as
|
|
36763
|
-
import
|
|
36910
|
+
import * as clack47 from "@clack/prompts";
|
|
36911
|
+
import pc50 from "picocolors";
|
|
36764
36912
|
async function destroy(options) {
|
|
36765
36913
|
trackCommand("destroy", { success: true });
|
|
36766
36914
|
if (isJsonMode() && !options.force) {
|
|
@@ -36771,9 +36919,9 @@ async function destroy(options) {
|
|
|
36771
36919
|
);
|
|
36772
36920
|
}
|
|
36773
36921
|
if (!isJsonMode()) {
|
|
36774
|
-
|
|
36922
|
+
clack47.intro(pc50.bold("Wraps Infrastructure Teardown"));
|
|
36775
36923
|
}
|
|
36776
|
-
const spinner10 =
|
|
36924
|
+
const spinner10 = clack47.spinner();
|
|
36777
36925
|
spinner10.start("Validating AWS credentials");
|
|
36778
36926
|
let identity;
|
|
36779
36927
|
try {
|
|
@@ -36790,17 +36938,17 @@ async function destroy(options) {
|
|
|
36790
36938
|
deployedServices.push("email");
|
|
36791
36939
|
}
|
|
36792
36940
|
if (deployedServices.length === 0) {
|
|
36793
|
-
|
|
36941
|
+
clack47.log.warn("No Wraps services found in this region");
|
|
36794
36942
|
console.log(
|
|
36795
36943
|
`
|
|
36796
|
-
Run ${
|
|
36944
|
+
Run ${pc50.cyan("wraps email init")} to deploy infrastructure.
|
|
36797
36945
|
`
|
|
36798
36946
|
);
|
|
36799
36947
|
process.exit(0);
|
|
36800
36948
|
}
|
|
36801
36949
|
if (deployedServices.length === 1) {
|
|
36802
36950
|
const service = deployedServices[0];
|
|
36803
|
-
|
|
36951
|
+
clack47.log.info(`Found ${pc50.cyan(service)} service deployed`);
|
|
36804
36952
|
if (service === "email") {
|
|
36805
36953
|
await emailDestroy(options);
|
|
36806
36954
|
return;
|
|
@@ -36815,7 +36963,7 @@ Run ${pc49.cyan("wraps email init")} to deploy infrastructure.
|
|
|
36815
36963
|
jsonSuccess("destroy", { destroyed: true });
|
|
36816
36964
|
return;
|
|
36817
36965
|
}
|
|
36818
|
-
const serviceToDestroy = await
|
|
36966
|
+
const serviceToDestroy = await clack47.select({
|
|
36819
36967
|
message: "Which service would you like to destroy?",
|
|
36820
36968
|
options: [
|
|
36821
36969
|
...deployedServices.map((s) => ({
|
|
@@ -36830,15 +36978,15 @@ Run ${pc49.cyan("wraps email init")} to deploy infrastructure.
|
|
|
36830
36978
|
}
|
|
36831
36979
|
]
|
|
36832
36980
|
});
|
|
36833
|
-
if (
|
|
36834
|
-
|
|
36981
|
+
if (clack47.isCancel(serviceToDestroy)) {
|
|
36982
|
+
clack47.cancel("Operation cancelled.");
|
|
36835
36983
|
process.exit(0);
|
|
36836
36984
|
}
|
|
36837
36985
|
if ((serviceToDestroy === "email" || serviceToDestroy === "all") && deployedServices.includes("email")) {
|
|
36838
36986
|
await emailDestroy(options);
|
|
36839
36987
|
}
|
|
36840
36988
|
if (serviceToDestroy === "all") {
|
|
36841
|
-
|
|
36989
|
+
clack47.outro(pc50.green("All Wraps infrastructure has been removed"));
|
|
36842
36990
|
}
|
|
36843
36991
|
}
|
|
36844
36992
|
|
|
@@ -36850,26 +36998,26 @@ init_fs();
|
|
|
36850
36998
|
init_json_output();
|
|
36851
36999
|
init_output();
|
|
36852
37000
|
init_pulumi();
|
|
36853
|
-
import * as
|
|
37001
|
+
import * as clack48 from "@clack/prompts";
|
|
36854
37002
|
import * as pulumi29 from "@pulumi/pulumi";
|
|
36855
|
-
import
|
|
37003
|
+
import pc51 from "picocolors";
|
|
36856
37004
|
async function status(options) {
|
|
36857
37005
|
await ensurePulumiInstalled();
|
|
36858
37006
|
const startTime = Date.now();
|
|
36859
37007
|
const progress = new DeploymentProgress();
|
|
36860
37008
|
if (!isJsonMode()) {
|
|
36861
|
-
|
|
37009
|
+
clack48.intro(pc51.bold("Wraps Infrastructure Status"));
|
|
36862
37010
|
}
|
|
36863
37011
|
const identity = await progress.execute(
|
|
36864
37012
|
"Loading infrastructure status",
|
|
36865
37013
|
async () => validateAWSCredentials()
|
|
36866
37014
|
);
|
|
36867
37015
|
if (!isJsonMode()) {
|
|
36868
|
-
progress.info(`AWS Account: ${
|
|
37016
|
+
progress.info(`AWS Account: ${pc51.cyan(identity.accountId)}`);
|
|
36869
37017
|
}
|
|
36870
37018
|
const region = options.region || await getAWSRegion();
|
|
36871
37019
|
if (!isJsonMode()) {
|
|
36872
|
-
progress.info(`Region: ${
|
|
37020
|
+
progress.info(`Region: ${pc51.cyan(region)}`);
|
|
36873
37021
|
}
|
|
36874
37022
|
const services = [];
|
|
36875
37023
|
try {
|
|
@@ -36921,35 +37069,35 @@ async function status(options) {
|
|
|
36921
37069
|
return;
|
|
36922
37070
|
}
|
|
36923
37071
|
console.log();
|
|
36924
|
-
|
|
37072
|
+
clack48.note(
|
|
36925
37073
|
services.map((s) => {
|
|
36926
37074
|
if (s.status === "deployed") {
|
|
36927
|
-
const details = s.details ?
|
|
36928
|
-
return ` ${
|
|
37075
|
+
const details = s.details ? pc51.dim(` (${s.details})`) : "";
|
|
37076
|
+
return ` ${pc51.green("\u2713")} ${s.name}${details}`;
|
|
36929
37077
|
}
|
|
36930
|
-
return ` ${
|
|
37078
|
+
return ` ${pc51.dim("\u25CB")} ${s.name} ${pc51.dim("(not deployed)")}`;
|
|
36931
37079
|
}).join("\n"),
|
|
36932
37080
|
"Services"
|
|
36933
37081
|
);
|
|
36934
37082
|
const hasDeployedServices = services.some((s) => s.status === "deployed");
|
|
36935
37083
|
if (hasDeployedServices) {
|
|
36936
37084
|
console.log(`
|
|
36937
|
-
${
|
|
37085
|
+
${pc51.bold("Details:")}`);
|
|
36938
37086
|
if (services.find((s) => s.name === "Email")?.status === "deployed") {
|
|
36939
|
-
console.log(` ${
|
|
37087
|
+
console.log(` ${pc51.dim("Email:")} ${pc51.cyan("wraps email status")}`);
|
|
36940
37088
|
}
|
|
36941
37089
|
if (services.find((s) => s.name === "SMS")?.status === "deployed") {
|
|
36942
|
-
console.log(` ${
|
|
37090
|
+
console.log(` ${pc51.dim("SMS:")} ${pc51.cyan("wraps sms status")}`);
|
|
36943
37091
|
}
|
|
36944
37092
|
} else {
|
|
36945
37093
|
console.log(`
|
|
36946
|
-
${
|
|
36947
|
-
console.log(` ${
|
|
36948
|
-
console.log(` ${
|
|
37094
|
+
${pc51.bold("Get started:")}`);
|
|
37095
|
+
console.log(` ${pc51.dim("Deploy email:")} ${pc51.cyan("wraps email init")}`);
|
|
37096
|
+
console.log(` ${pc51.dim("Deploy SMS:")} ${pc51.cyan("wraps sms init")}`);
|
|
36949
37097
|
}
|
|
36950
37098
|
console.log(`
|
|
36951
|
-
${
|
|
36952
|
-
console.log(`${
|
|
37099
|
+
${pc51.bold("Dashboard:")} ${pc51.blue("https://app.wraps.dev")}`);
|
|
37100
|
+
console.log(`${pc51.bold("Docs:")} ${pc51.blue("https://wraps.dev/docs")}
|
|
36953
37101
|
`);
|
|
36954
37102
|
trackCommand("status", {
|
|
36955
37103
|
success: true,
|
|
@@ -36960,9 +37108,9 @@ ${pc50.bold("Dashboard:")} ${pc50.blue("https://app.wraps.dev")}`);
|
|
|
36960
37108
|
|
|
36961
37109
|
// src/commands/sms/destroy.ts
|
|
36962
37110
|
init_esm_shims();
|
|
36963
|
-
import * as
|
|
37111
|
+
import * as clack49 from "@clack/prompts";
|
|
36964
37112
|
import * as pulumi31 from "@pulumi/pulumi";
|
|
36965
|
-
import
|
|
37113
|
+
import pc52 from "picocolors";
|
|
36966
37114
|
|
|
36967
37115
|
// src/infrastructure/sms-stack.ts
|
|
36968
37116
|
init_esm_shims();
|
|
@@ -37653,18 +37801,18 @@ async function createSMSProtectConfigurationWithSDK(configurationSetName, region
|
|
|
37653
37801
|
const existing = await client.send(
|
|
37654
37802
|
new DescribeProtectConfigurationsCommand({})
|
|
37655
37803
|
);
|
|
37656
|
-
for (const
|
|
37657
|
-
if (!(
|
|
37804
|
+
for (const pc65 of existing.ProtectConfigurations || []) {
|
|
37805
|
+
if (!(pc65.ProtectConfigurationArn && pc65.ProtectConfigurationId)) {
|
|
37658
37806
|
continue;
|
|
37659
37807
|
}
|
|
37660
37808
|
const tagsResponse = await client.send(
|
|
37661
37809
|
new ListTagsForResourceCommand({
|
|
37662
|
-
ResourceArn:
|
|
37810
|
+
ResourceArn: pc65.ProtectConfigurationArn
|
|
37663
37811
|
})
|
|
37664
37812
|
);
|
|
37665
37813
|
const nameTag = tagsResponse.Tags?.find((t) => t.Key === "Name");
|
|
37666
37814
|
if (nameTag?.Value === protectConfigName) {
|
|
37667
|
-
existingProtectConfigId =
|
|
37815
|
+
existingProtectConfigId = pc65.ProtectConfigurationId;
|
|
37668
37816
|
break;
|
|
37669
37817
|
}
|
|
37670
37818
|
}
|
|
@@ -37760,13 +37908,13 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
|
|
|
37760
37908
|
new DescribeProtectConfigurationsCommand({})
|
|
37761
37909
|
);
|
|
37762
37910
|
if (existing.ProtectConfigurations) {
|
|
37763
|
-
for (const
|
|
37764
|
-
if (!(
|
|
37911
|
+
for (const pc65 of existing.ProtectConfigurations) {
|
|
37912
|
+
if (!(pc65.ProtectConfigurationArn && pc65.ProtectConfigurationId)) {
|
|
37765
37913
|
continue;
|
|
37766
37914
|
}
|
|
37767
37915
|
const tagsResponse = await client.send(
|
|
37768
37916
|
new ListTagsForResourceCommand({
|
|
37769
|
-
ResourceArn:
|
|
37917
|
+
ResourceArn: pc65.ProtectConfigurationArn
|
|
37770
37918
|
})
|
|
37771
37919
|
);
|
|
37772
37920
|
const isWrapsManaged = tagsResponse.Tags?.some(
|
|
@@ -37775,7 +37923,7 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
|
|
|
37775
37923
|
if (isWrapsManaged) {
|
|
37776
37924
|
await client.send(
|
|
37777
37925
|
new DeleteProtectConfigurationCommand({
|
|
37778
|
-
ProtectConfigurationId:
|
|
37926
|
+
ProtectConfigurationId: pc65.ProtectConfigurationId
|
|
37779
37927
|
})
|
|
37780
37928
|
);
|
|
37781
37929
|
}
|
|
@@ -37810,8 +37958,8 @@ async function smsDestroy(options) {
|
|
|
37810
37958
|
);
|
|
37811
37959
|
}
|
|
37812
37960
|
if (!isJsonMode()) {
|
|
37813
|
-
|
|
37814
|
-
|
|
37961
|
+
clack49.intro(
|
|
37962
|
+
pc52.bold(
|
|
37815
37963
|
options.preview ? "SMS Infrastructure Destruction Preview" : "SMS Infrastructure Teardown"
|
|
37816
37964
|
)
|
|
37817
37965
|
);
|
|
@@ -37837,15 +37985,15 @@ async function smsDestroy(options) {
|
|
|
37837
37985
|
`Available regions: ${smsConnections.map((c) => c.region).join(", ")}`
|
|
37838
37986
|
);
|
|
37839
37987
|
}
|
|
37840
|
-
const selectedRegion = await
|
|
37988
|
+
const selectedRegion = await clack49.select({
|
|
37841
37989
|
message: "Multiple SMS deployments found. Which region to destroy?",
|
|
37842
37990
|
options: smsConnections.map((conn) => ({
|
|
37843
37991
|
value: conn.region,
|
|
37844
37992
|
label: conn.region
|
|
37845
37993
|
}))
|
|
37846
37994
|
});
|
|
37847
|
-
if (
|
|
37848
|
-
|
|
37995
|
+
if (clack49.isCancel(selectedRegion)) {
|
|
37996
|
+
clack49.cancel("Operation cancelled");
|
|
37849
37997
|
process.exit(0);
|
|
37850
37998
|
}
|
|
37851
37999
|
region = selectedRegion;
|
|
@@ -37856,18 +38004,18 @@ async function smsDestroy(options) {
|
|
|
37856
38004
|
const storedStackName = smsService?.pulumiStackName;
|
|
37857
38005
|
if (!smsService) {
|
|
37858
38006
|
progress.stop();
|
|
37859
|
-
|
|
38007
|
+
clack49.log.warn("No SMS infrastructure found");
|
|
37860
38008
|
process.exit(0);
|
|
37861
38009
|
}
|
|
37862
38010
|
if (!(options.force || options.preview)) {
|
|
37863
|
-
const confirmed = await
|
|
37864
|
-
message:
|
|
38011
|
+
const confirmed = await clack49.confirm({
|
|
38012
|
+
message: pc52.red(
|
|
37865
38013
|
"Are you sure you want to destroy all SMS infrastructure?"
|
|
37866
38014
|
),
|
|
37867
38015
|
initialValue: false
|
|
37868
38016
|
});
|
|
37869
|
-
if (
|
|
37870
|
-
|
|
38017
|
+
if (clack49.isCancel(confirmed) || !confirmed) {
|
|
38018
|
+
clack49.cancel("Destruction cancelled.");
|
|
37871
38019
|
process.exit(0);
|
|
37872
38020
|
}
|
|
37873
38021
|
}
|
|
@@ -37899,8 +38047,8 @@ async function smsDestroy(options) {
|
|
|
37899
38047
|
costEstimate: "Monthly cost after destruction: $0.00",
|
|
37900
38048
|
commandName: "wraps sms destroy"
|
|
37901
38049
|
});
|
|
37902
|
-
|
|
37903
|
-
|
|
38050
|
+
clack49.outro(
|
|
38051
|
+
pc52.green("Preview complete. Run without --preview to destroy.")
|
|
37904
38052
|
);
|
|
37905
38053
|
trackServiceRemoved("sms", {
|
|
37906
38054
|
preview: true,
|
|
@@ -37911,7 +38059,7 @@ async function smsDestroy(options) {
|
|
|
37911
38059
|
progress.stop();
|
|
37912
38060
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
37913
38061
|
if (errorMessage.includes("No SMS infrastructure found")) {
|
|
37914
|
-
|
|
38062
|
+
clack49.log.warn("No SMS infrastructure found to preview");
|
|
37915
38063
|
process.exit(0);
|
|
37916
38064
|
}
|
|
37917
38065
|
trackError("PREVIEW_FAILED", "sms destroy", { step: "preview" });
|
|
@@ -37960,7 +38108,7 @@ async function smsDestroy(options) {
|
|
|
37960
38108
|
progress.stop();
|
|
37961
38109
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
37962
38110
|
if (errorMessage.includes("No SMS infrastructure found")) {
|
|
37963
|
-
|
|
38111
|
+
clack49.log.warn("No SMS infrastructure found");
|
|
37964
38112
|
if (metadata) {
|
|
37965
38113
|
removeServiceFromConnection(metadata, "sms");
|
|
37966
38114
|
await saveConnectionMetadata(metadata);
|
|
@@ -37973,7 +38121,7 @@ async function smsDestroy(options) {
|
|
|
37973
38121
|
}
|
|
37974
38122
|
trackError("DESTROY_FAILED", "sms destroy", { step: "destroy" });
|
|
37975
38123
|
destroyFailed = true;
|
|
37976
|
-
|
|
38124
|
+
clack49.log.warn(
|
|
37977
38125
|
"Some resources may not have been fully removed. You can re-run this command or clean up manually in the AWS console."
|
|
37978
38126
|
);
|
|
37979
38127
|
}
|
|
@@ -37996,21 +38144,21 @@ async function smsDestroy(options) {
|
|
|
37996
38144
|
return;
|
|
37997
38145
|
}
|
|
37998
38146
|
if (destroyFailed) {
|
|
37999
|
-
|
|
38000
|
-
|
|
38147
|
+
clack49.outro(
|
|
38148
|
+
pc52.yellow("SMS infrastructure partially removed. Metadata cleaned up.")
|
|
38001
38149
|
);
|
|
38002
38150
|
} else {
|
|
38003
|
-
|
|
38151
|
+
clack49.outro(pc52.green("SMS infrastructure has been removed"));
|
|
38004
38152
|
console.log(`
|
|
38005
|
-
${
|
|
38006
|
-
console.log(` ${
|
|
38007
|
-
console.log(` ${
|
|
38008
|
-
console.log(` ${
|
|
38009
|
-
console.log(` ${
|
|
38153
|
+
${pc52.bold("Cleaned up:")}`);
|
|
38154
|
+
console.log(` ${pc52.green("\u2713")} Phone number released`);
|
|
38155
|
+
console.log(` ${pc52.green("\u2713")} Configuration set deleted`);
|
|
38156
|
+
console.log(` ${pc52.green("\u2713")} Event processing infrastructure removed`);
|
|
38157
|
+
console.log(` ${pc52.green("\u2713")} IAM role deleted`);
|
|
38010
38158
|
}
|
|
38011
38159
|
console.log(
|
|
38012
38160
|
`
|
|
38013
|
-
Run ${
|
|
38161
|
+
Run ${pc52.cyan("wraps sms init")} to deploy infrastructure again.
|
|
38014
38162
|
`
|
|
38015
38163
|
);
|
|
38016
38164
|
trackServiceRemoved("sms", {
|
|
@@ -38022,9 +38170,9 @@ Run ${pc51.cyan("wraps sms init")} to deploy infrastructure again.
|
|
|
38022
38170
|
|
|
38023
38171
|
// src/commands/sms/init.ts
|
|
38024
38172
|
init_esm_shims();
|
|
38025
|
-
import * as
|
|
38173
|
+
import * as clack50 from "@clack/prompts";
|
|
38026
38174
|
import * as pulumi32 from "@pulumi/pulumi";
|
|
38027
|
-
import
|
|
38175
|
+
import pc53 from "picocolors";
|
|
38028
38176
|
init_events();
|
|
38029
38177
|
init_aws();
|
|
38030
38178
|
init_fs();
|
|
@@ -38443,7 +38591,7 @@ function validateSMSConfig(config2) {
|
|
|
38443
38591
|
|
|
38444
38592
|
// src/commands/sms/init.ts
|
|
38445
38593
|
async function promptPhoneNumberType() {
|
|
38446
|
-
const result = await
|
|
38594
|
+
const result = await clack50.select({
|
|
38447
38595
|
message: "Select phone number type:",
|
|
38448
38596
|
options: [
|
|
38449
38597
|
{
|
|
@@ -38463,14 +38611,14 @@ async function promptPhoneNumberType() {
|
|
|
38463
38611
|
}
|
|
38464
38612
|
]
|
|
38465
38613
|
});
|
|
38466
|
-
if (
|
|
38467
|
-
|
|
38614
|
+
if (clack50.isCancel(result)) {
|
|
38615
|
+
clack50.cancel("Operation cancelled.");
|
|
38468
38616
|
process.exit(0);
|
|
38469
38617
|
}
|
|
38470
38618
|
return result;
|
|
38471
38619
|
}
|
|
38472
38620
|
async function promptSMSPreset() {
|
|
38473
|
-
const result = await
|
|
38621
|
+
const result = await clack50.select({
|
|
38474
38622
|
message: "Choose configuration preset:",
|
|
38475
38623
|
options: [
|
|
38476
38624
|
{
|
|
@@ -38495,8 +38643,8 @@ async function promptSMSPreset() {
|
|
|
38495
38643
|
}
|
|
38496
38644
|
]
|
|
38497
38645
|
});
|
|
38498
|
-
if (
|
|
38499
|
-
|
|
38646
|
+
if (clack50.isCancel(result)) {
|
|
38647
|
+
clack50.cancel("Operation cancelled.");
|
|
38500
38648
|
process.exit(0);
|
|
38501
38649
|
}
|
|
38502
38650
|
return result;
|
|
@@ -38516,7 +38664,7 @@ var COMMON_COUNTRIES = [
|
|
|
38516
38664
|
{ code: "IN", name: "India" }
|
|
38517
38665
|
];
|
|
38518
38666
|
async function promptAllowedCountries() {
|
|
38519
|
-
const result = await
|
|
38667
|
+
const result = await clack50.multiselect({
|
|
38520
38668
|
message: "Select countries to allow SMS delivery (blocks all others):",
|
|
38521
38669
|
options: COMMON_COUNTRIES.map((c) => ({
|
|
38522
38670
|
value: c.code,
|
|
@@ -38525,14 +38673,14 @@ async function promptAllowedCountries() {
|
|
|
38525
38673
|
initialValues: ["US"],
|
|
38526
38674
|
required: true
|
|
38527
38675
|
});
|
|
38528
|
-
if (
|
|
38529
|
-
|
|
38676
|
+
if (clack50.isCancel(result)) {
|
|
38677
|
+
clack50.cancel("Operation cancelled.");
|
|
38530
38678
|
process.exit(0);
|
|
38531
38679
|
}
|
|
38532
38680
|
return result;
|
|
38533
38681
|
}
|
|
38534
38682
|
async function promptEstimatedSMSVolume() {
|
|
38535
|
-
const result = await
|
|
38683
|
+
const result = await clack50.select({
|
|
38536
38684
|
message: "Estimated messages per month:",
|
|
38537
38685
|
options: [
|
|
38538
38686
|
{ value: 100, label: "< 100 (Testing)" },
|
|
@@ -38542,8 +38690,8 @@ async function promptEstimatedSMSVolume() {
|
|
|
38542
38690
|
{ value: 1e5, label: "50,000+" }
|
|
38543
38691
|
]
|
|
38544
38692
|
});
|
|
38545
|
-
if (
|
|
38546
|
-
|
|
38693
|
+
if (clack50.isCancel(result)) {
|
|
38694
|
+
clack50.cancel("Operation cancelled.");
|
|
38547
38695
|
process.exit(0);
|
|
38548
38696
|
}
|
|
38549
38697
|
return result;
|
|
@@ -38551,7 +38699,7 @@ async function promptEstimatedSMSVolume() {
|
|
|
38551
38699
|
async function init3(options) {
|
|
38552
38700
|
const startTime = Date.now();
|
|
38553
38701
|
if (!isJsonMode()) {
|
|
38554
|
-
|
|
38702
|
+
clack50.intro(pc53.bold("Wraps SMS Infrastructure Setup"));
|
|
38555
38703
|
}
|
|
38556
38704
|
const progress = new DeploymentProgress();
|
|
38557
38705
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -38565,7 +38713,7 @@ async function init3(options) {
|
|
|
38565
38713
|
"Validating AWS credentials",
|
|
38566
38714
|
async () => validateAWSCredentials()
|
|
38567
38715
|
);
|
|
38568
|
-
progress.info(`Connected to AWS account: ${
|
|
38716
|
+
progress.info(`Connected to AWS account: ${pc53.cyan(identity.accountId)}`);
|
|
38569
38717
|
const provider = options.provider || await promptProvider();
|
|
38570
38718
|
const region = options.region || await promptRegion(await getAWSRegion());
|
|
38571
38719
|
let vercelConfig;
|
|
@@ -38577,10 +38725,10 @@ async function init3(options) {
|
|
|
38577
38725
|
region
|
|
38578
38726
|
);
|
|
38579
38727
|
if (existingConnection?.services?.sms) {
|
|
38580
|
-
|
|
38581
|
-
`SMS already configured for account ${
|
|
38728
|
+
clack50.log.warn(
|
|
38729
|
+
`SMS already configured for account ${pc53.cyan(identity.accountId)} in region ${pc53.cyan(region)}`
|
|
38582
38730
|
);
|
|
38583
|
-
|
|
38731
|
+
clack50.log.info(`Use ${pc53.cyan("wraps sms status")} to view current setup`);
|
|
38584
38732
|
process.exit(0);
|
|
38585
38733
|
}
|
|
38586
38734
|
let preset = options.preset;
|
|
@@ -38597,12 +38745,12 @@ async function init3(options) {
|
|
|
38597
38745
|
optOutManagement: true,
|
|
38598
38746
|
sendingEnabled: true
|
|
38599
38747
|
};
|
|
38600
|
-
const enableEventTracking = await
|
|
38748
|
+
const enableEventTracking = await clack50.confirm({
|
|
38601
38749
|
message: "Enable event tracking (EventBridge + DynamoDB)?",
|
|
38602
38750
|
initialValue: false
|
|
38603
38751
|
});
|
|
38604
|
-
if (
|
|
38605
|
-
|
|
38752
|
+
if (clack50.isCancel(enableEventTracking)) {
|
|
38753
|
+
clack50.cancel("Operation cancelled.");
|
|
38606
38754
|
process.exit(0);
|
|
38607
38755
|
}
|
|
38608
38756
|
if (enableEventTracking) {
|
|
@@ -38622,17 +38770,17 @@ async function init3(options) {
|
|
|
38622
38770
|
}
|
|
38623
38771
|
progress.info(
|
|
38624
38772
|
`
|
|
38625
|
-
${
|
|
38773
|
+
${pc53.bold("Fraud Protection")} - Block SMS to countries where you don't do business`
|
|
38626
38774
|
);
|
|
38627
38775
|
const allowedCountries = await promptAllowedCountries();
|
|
38628
38776
|
let aitFiltering = false;
|
|
38629
38777
|
if (smsConfig.phoneNumberType !== "simulator") {
|
|
38630
|
-
const enableAIT = await
|
|
38778
|
+
const enableAIT = await clack50.confirm({
|
|
38631
38779
|
message: "Enable AIT (Artificially Inflated Traffic) filtering? (adds per-message cost)",
|
|
38632
38780
|
initialValue: false
|
|
38633
38781
|
});
|
|
38634
|
-
if (
|
|
38635
|
-
|
|
38782
|
+
if (clack50.isCancel(enableAIT)) {
|
|
38783
|
+
clack50.cancel("Operation cancelled.");
|
|
38636
38784
|
process.exit(0);
|
|
38637
38785
|
}
|
|
38638
38786
|
aitFiltering = enableAIT;
|
|
@@ -38644,21 +38792,21 @@ ${pc52.bold("Fraud Protection")} - Block SMS to countries where you don't do bus
|
|
|
38644
38792
|
};
|
|
38645
38793
|
const estimatedVolume = await promptEstimatedSMSVolume();
|
|
38646
38794
|
progress.info(`
|
|
38647
|
-
${
|
|
38795
|
+
${pc53.bold("Cost Estimate:")}`);
|
|
38648
38796
|
const costSummary = getSMSCostSummary(smsConfig, estimatedVolume);
|
|
38649
|
-
|
|
38797
|
+
clack50.log.info(costSummary);
|
|
38650
38798
|
const warnings = validateSMSConfig(smsConfig);
|
|
38651
38799
|
if (warnings.length > 0) {
|
|
38652
38800
|
progress.info(`
|
|
38653
|
-
${
|
|
38801
|
+
${pc53.yellow(pc53.bold("Important Notes:"))}`);
|
|
38654
38802
|
for (const warning of warnings) {
|
|
38655
|
-
|
|
38803
|
+
clack50.log.warn(warning);
|
|
38656
38804
|
}
|
|
38657
38805
|
}
|
|
38658
38806
|
if (!(options.yes || options.preview)) {
|
|
38659
38807
|
const confirmed = await confirmDeploy();
|
|
38660
38808
|
if (!confirmed) {
|
|
38661
|
-
|
|
38809
|
+
clack50.cancel("Deployment cancelled.");
|
|
38662
38810
|
process.exit(0);
|
|
38663
38811
|
}
|
|
38664
38812
|
}
|
|
@@ -38718,8 +38866,8 @@ ${pc52.yellow(pc52.bold("Important Notes:"))}`);
|
|
|
38718
38866
|
costEstimate: getSMSCostSummary(smsConfig, 0),
|
|
38719
38867
|
commandName: "wraps sms init"
|
|
38720
38868
|
});
|
|
38721
|
-
|
|
38722
|
-
|
|
38869
|
+
clack50.outro(
|
|
38870
|
+
pc53.green("Preview complete. Run without --preview to deploy.")
|
|
38723
38871
|
);
|
|
38724
38872
|
trackServiceInit("sms", true, {
|
|
38725
38873
|
provider,
|
|
@@ -38768,9 +38916,9 @@ ${pc52.yellow(pc52.bold("Important Notes:"))}`);
|
|
|
38768
38916
|
} catch (sdkError) {
|
|
38769
38917
|
sdkResourceWarning = true;
|
|
38770
38918
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
38771
|
-
|
|
38772
|
-
|
|
38773
|
-
`Run ${
|
|
38919
|
+
clack50.log.warn(`Phone pool creation failed: ${msg}`);
|
|
38920
|
+
clack50.log.info(
|
|
38921
|
+
`Run ${pc53.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
38774
38922
|
);
|
|
38775
38923
|
}
|
|
38776
38924
|
}
|
|
@@ -38786,9 +38934,9 @@ ${pc52.yellow(pc52.bold("Important Notes:"))}`);
|
|
|
38786
38934
|
} catch (sdkError) {
|
|
38787
38935
|
sdkResourceWarning = true;
|
|
38788
38936
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
38789
|
-
|
|
38790
|
-
|
|
38791
|
-
`Run ${
|
|
38937
|
+
clack50.log.warn(`Event destination creation failed: ${msg}`);
|
|
38938
|
+
clack50.log.info(
|
|
38939
|
+
`Run ${pc53.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
38792
38940
|
);
|
|
38793
38941
|
}
|
|
38794
38942
|
}
|
|
@@ -38807,14 +38955,14 @@ ${pc52.yellow(pc52.bold("Important Notes:"))}`);
|
|
|
38807
38955
|
} catch (sdkError) {
|
|
38808
38956
|
sdkResourceWarning = true;
|
|
38809
38957
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
38810
|
-
|
|
38811
|
-
|
|
38812
|
-
`Run ${
|
|
38958
|
+
clack50.log.warn(`Protect configuration creation failed: ${msg}`);
|
|
38959
|
+
clack50.log.info(
|
|
38960
|
+
`Run ${pc53.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
38813
38961
|
);
|
|
38814
38962
|
}
|
|
38815
38963
|
}
|
|
38816
38964
|
if (sdkResourceWarning) {
|
|
38817
|
-
|
|
38965
|
+
clack50.log.warn(
|
|
38818
38966
|
"Some SDK resources failed to create. Core infrastructure is deployed."
|
|
38819
38967
|
);
|
|
38820
38968
|
}
|
|
@@ -38859,47 +39007,47 @@ ${pc52.yellow(pc52.bold("Important Notes:"))}`);
|
|
|
38859
39007
|
return;
|
|
38860
39008
|
}
|
|
38861
39009
|
console.log("\n");
|
|
38862
|
-
|
|
39010
|
+
clack50.log.success(pc53.green(pc53.bold("SMS infrastructure deployed!")));
|
|
38863
39011
|
console.log("\n");
|
|
38864
|
-
|
|
39012
|
+
clack50.note(
|
|
38865
39013
|
[
|
|
38866
|
-
`${
|
|
38867
|
-
`${
|
|
38868
|
-
`${
|
|
38869
|
-
`${
|
|
38870
|
-
outputs.tableName ? `${
|
|
39014
|
+
`${pc53.bold("Phone Number:")} ${pc53.cyan(outputs.phoneNumber || "Provisioning...")}`,
|
|
39015
|
+
`${pc53.bold("Phone Type:")} ${pc53.cyan(smsConfig.phoneNumberType || "simulator")}`,
|
|
39016
|
+
`${pc53.bold("Config Set:")} ${pc53.cyan(outputs.configSetName || "wraps-sms-config")}`,
|
|
39017
|
+
`${pc53.bold("Region:")} ${pc53.cyan(outputs.region)}`,
|
|
39018
|
+
outputs.tableName ? `${pc53.bold("History Table:")} ${pc53.cyan(outputs.tableName)}` : "",
|
|
38871
39019
|
"",
|
|
38872
|
-
|
|
38873
|
-
|
|
39020
|
+
pc53.dim("IAM Role:"),
|
|
39021
|
+
pc53.dim(` ${outputs.roleArn}`)
|
|
38874
39022
|
].filter(Boolean).join("\n"),
|
|
38875
39023
|
"SMS Infrastructure"
|
|
38876
39024
|
);
|
|
38877
39025
|
const nextSteps = [];
|
|
38878
39026
|
if (smsConfig.phoneNumberType === "toll-free") {
|
|
38879
39027
|
nextSteps.push(
|
|
38880
|
-
`${
|
|
39028
|
+
`${pc53.cyan("wraps sms register")} - Submit toll-free registration (required before sending)`
|
|
38881
39029
|
);
|
|
38882
39030
|
}
|
|
38883
39031
|
nextSteps.push(
|
|
38884
|
-
`${
|
|
39032
|
+
`${pc53.cyan("wraps sms test --to +1234567890")} - Send a test message`
|
|
38885
39033
|
);
|
|
38886
|
-
nextSteps.push(`${
|
|
39034
|
+
nextSteps.push(`${pc53.cyan("wraps sms status")} - View SMS configuration`);
|
|
38887
39035
|
console.log("\n");
|
|
38888
|
-
|
|
39036
|
+
clack50.log.info(pc53.bold("Next steps:"));
|
|
38889
39037
|
for (const step of nextSteps) {
|
|
38890
39038
|
console.log(` ${step}`);
|
|
38891
39039
|
}
|
|
38892
39040
|
console.log("\n");
|
|
38893
|
-
|
|
38894
|
-
console.log(
|
|
39041
|
+
clack50.log.info(pc53.bold("SDK Usage:"));
|
|
39042
|
+
console.log(pc53.dim(" npm install @wraps.dev/sms"));
|
|
38895
39043
|
console.log("");
|
|
38896
|
-
console.log(
|
|
38897
|
-
console.log(
|
|
38898
|
-
console.log(
|
|
38899
|
-
console.log(
|
|
38900
|
-
console.log(
|
|
38901
|
-
console.log(
|
|
38902
|
-
|
|
39044
|
+
console.log(pc53.dim(" import { Wraps } from '@wraps.dev/sms';"));
|
|
39045
|
+
console.log(pc53.dim(" const wraps = new Wraps();"));
|
|
39046
|
+
console.log(pc53.dim(" await wraps.sms.send({"));
|
|
39047
|
+
console.log(pc53.dim(" to: '+14155551234',"));
|
|
39048
|
+
console.log(pc53.dim(" message: 'Your code is 123456',"));
|
|
39049
|
+
console.log(pc53.dim(" });"));
|
|
39050
|
+
clack50.outro(pc53.green("Setup complete!"));
|
|
38903
39051
|
const duration = Date.now() - startTime;
|
|
38904
39052
|
const enabledFeatures = [];
|
|
38905
39053
|
if (smsConfig.tracking?.enabled) {
|
|
@@ -38935,8 +39083,8 @@ init_aws();
|
|
|
38935
39083
|
init_json_output();
|
|
38936
39084
|
init_metadata();
|
|
38937
39085
|
init_output();
|
|
38938
|
-
import * as
|
|
38939
|
-
import
|
|
39086
|
+
import * as clack51 from "@clack/prompts";
|
|
39087
|
+
import pc54 from "picocolors";
|
|
38940
39088
|
async function getPhoneNumberDetails(region) {
|
|
38941
39089
|
const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePhoneNumbersCommand: DescribePhoneNumbersCommand2 } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
|
|
38942
39090
|
const client = new PinpointSMSVoiceV2Client5({ region });
|
|
@@ -38956,7 +39104,7 @@ async function getPhoneNumberDetails(region) {
|
|
|
38956
39104
|
return null;
|
|
38957
39105
|
} catch (error) {
|
|
38958
39106
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
38959
|
-
|
|
39107
|
+
clack51.log.error(`Error fetching phone number: ${errorMessage}`);
|
|
38960
39108
|
return null;
|
|
38961
39109
|
}
|
|
38962
39110
|
}
|
|
@@ -38977,7 +39125,7 @@ async function getRegistrationStatus(region, registrationId) {
|
|
|
38977
39125
|
async function smsRegister(options) {
|
|
38978
39126
|
const startTime = Date.now();
|
|
38979
39127
|
if (!isJsonMode()) {
|
|
38980
|
-
|
|
39128
|
+
clack51.intro(pc54.bold("Wraps SMS - Toll-Free Registration"));
|
|
38981
39129
|
}
|
|
38982
39130
|
const progress = new DeploymentProgress();
|
|
38983
39131
|
const identity = await progress.execute(
|
|
@@ -38990,8 +39138,8 @@ async function smsRegister(options) {
|
|
|
38990
39138
|
}
|
|
38991
39139
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
38992
39140
|
if (!metadata?.services?.sms) {
|
|
38993
|
-
|
|
38994
|
-
|
|
39141
|
+
clack51.log.error("No SMS infrastructure found.");
|
|
39142
|
+
clack51.log.info(`Run ${pc54.cyan("wraps sms init")} first.`);
|
|
38995
39143
|
process.exit(1);
|
|
38996
39144
|
}
|
|
38997
39145
|
const phoneDetails = await progress.execute(
|
|
@@ -38999,7 +39147,7 @@ async function smsRegister(options) {
|
|
|
38999
39147
|
async () => getPhoneNumberDetails(region)
|
|
39000
39148
|
);
|
|
39001
39149
|
if (!phoneDetails) {
|
|
39002
|
-
|
|
39150
|
+
clack51.log.error("No phone number found.");
|
|
39003
39151
|
process.exit(1);
|
|
39004
39152
|
}
|
|
39005
39153
|
let registrationStatus = null;
|
|
@@ -39025,53 +39173,53 @@ async function smsRegister(options) {
|
|
|
39025
39173
|
}
|
|
39026
39174
|
console.log("");
|
|
39027
39175
|
console.log(
|
|
39028
|
-
`${
|
|
39176
|
+
`${pc54.bold("Phone Number:")} ${pc54.cyan(phoneDetails.phoneNumber)}`
|
|
39029
39177
|
);
|
|
39030
|
-
console.log(`${
|
|
39178
|
+
console.log(`${pc54.bold("Type:")} ${pc54.cyan(phoneDetails.type)}`);
|
|
39031
39179
|
console.log(
|
|
39032
|
-
`${
|
|
39180
|
+
`${pc54.bold("Status:")} ${phoneDetails.status === "ACTIVE" ? pc54.green(phoneDetails.status) : pc54.yellow(phoneDetails.status)}`
|
|
39033
39181
|
);
|
|
39034
39182
|
if (registrationStatus) {
|
|
39035
|
-
console.log(`${
|
|
39183
|
+
console.log(`${pc54.bold("Registration:")} ${pc54.cyan(registrationStatus)}`);
|
|
39036
39184
|
}
|
|
39037
39185
|
console.log("");
|
|
39038
39186
|
if (phoneDetails.status === "ACTIVE") {
|
|
39039
|
-
|
|
39187
|
+
clack51.log.success("Your phone number is already ACTIVE and ready to use!");
|
|
39040
39188
|
const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePoolsCommand } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
|
|
39041
39189
|
const client = new PinpointSMSVoiceV2Client5({ region });
|
|
39042
39190
|
const pools = await client.send(new DescribePoolsCommand({}));
|
|
39043
39191
|
if (!pools.Pools?.length) {
|
|
39044
|
-
|
|
39192
|
+
clack51.log.info("Run `wraps sms sync` to create the phone pool.");
|
|
39045
39193
|
}
|
|
39046
39194
|
process.exit(0);
|
|
39047
39195
|
}
|
|
39048
39196
|
if (phoneDetails.type !== "TOLL_FREE") {
|
|
39049
|
-
|
|
39050
|
-
|
|
39197
|
+
clack51.log.info("Only toll-free numbers require registration.");
|
|
39198
|
+
clack51.log.info(`Your ${phoneDetails.type} number should be ready to use.`);
|
|
39051
39199
|
process.exit(0);
|
|
39052
39200
|
}
|
|
39053
|
-
console.log(
|
|
39201
|
+
console.log(pc54.bold("Toll-Free Registration Required"));
|
|
39054
39202
|
console.log("");
|
|
39055
39203
|
console.log(
|
|
39056
|
-
|
|
39204
|
+
pc54.dim("To send SMS at scale, you must register your toll-free number.")
|
|
39057
39205
|
);
|
|
39058
|
-
console.log(
|
|
39206
|
+
console.log(pc54.dim("This process typically takes 1-15 business days."));
|
|
39059
39207
|
console.log("");
|
|
39060
|
-
console.log(
|
|
39061
|
-
console.log(` ${
|
|
39208
|
+
console.log(pc54.bold("You'll need to provide:"));
|
|
39209
|
+
console.log(` ${pc54.dim("\u2022")} Business name and address`);
|
|
39062
39210
|
console.log(
|
|
39063
|
-
` ${
|
|
39211
|
+
` ${pc54.dim("\u2022")} Use case description (what messages you're sending)`
|
|
39064
39212
|
);
|
|
39065
|
-
console.log(` ${
|
|
39066
|
-
console.log(` ${
|
|
39067
|
-
console.log(` ${
|
|
39213
|
+
console.log(` ${pc54.dim("\u2022")} Sample messages (2-3 examples)`);
|
|
39214
|
+
console.log(` ${pc54.dim("\u2022")} How users opt-in to receive messages`);
|
|
39215
|
+
console.log(` ${pc54.dim("\u2022")} Expected monthly message volume`);
|
|
39068
39216
|
console.log("");
|
|
39069
|
-
const openConsole = await
|
|
39217
|
+
const openConsole = await clack51.confirm({
|
|
39070
39218
|
message: "Open AWS Console to start registration?",
|
|
39071
39219
|
initialValue: true
|
|
39072
39220
|
});
|
|
39073
|
-
if (
|
|
39074
|
-
|
|
39221
|
+
if (clack51.isCancel(openConsole)) {
|
|
39222
|
+
clack51.cancel("Registration cancelled.");
|
|
39075
39223
|
process.exit(0);
|
|
39076
39224
|
}
|
|
39077
39225
|
if (openConsole) {
|
|
@@ -39081,41 +39229,41 @@ async function smsRegister(options) {
|
|
|
39081
39229
|
const execAsync2 = promisify2(exec2);
|
|
39082
39230
|
try {
|
|
39083
39231
|
await execAsync2(`open "${consoleUrl}"`);
|
|
39084
|
-
|
|
39232
|
+
clack51.log.success("Opened AWS Console in your browser.");
|
|
39085
39233
|
} catch {
|
|
39086
39234
|
try {
|
|
39087
39235
|
await execAsync2(`xdg-open "${consoleUrl}"`);
|
|
39088
|
-
|
|
39236
|
+
clack51.log.success("Opened AWS Console in your browser.");
|
|
39089
39237
|
} catch {
|
|
39090
|
-
|
|
39238
|
+
clack51.log.info("Open this URL in your browser:");
|
|
39091
39239
|
console.log(`
|
|
39092
|
-
${
|
|
39240
|
+
${pc54.cyan(consoleUrl)}
|
|
39093
39241
|
`);
|
|
39094
39242
|
}
|
|
39095
39243
|
}
|
|
39096
39244
|
console.log("");
|
|
39097
|
-
console.log(
|
|
39245
|
+
console.log(pc54.bold("Next Steps:"));
|
|
39098
39246
|
console.log(
|
|
39099
|
-
` 1. Click ${
|
|
39247
|
+
` 1. Click ${pc54.cyan("Create registration")} in the AWS Console`
|
|
39100
39248
|
);
|
|
39101
|
-
console.log(` 2. Select ${
|
|
39249
|
+
console.log(` 2. Select ${pc54.cyan("Toll-free number registration")}`);
|
|
39102
39250
|
console.log(" 3. Fill out the business information form");
|
|
39103
39251
|
console.log(" 4. Submit and wait for approval (1-15 business days)");
|
|
39104
39252
|
console.log("");
|
|
39105
39253
|
console.log(
|
|
39106
|
-
|
|
39254
|
+
pc54.dim("Once approved, run `wraps sms sync` to complete setup.")
|
|
39107
39255
|
);
|
|
39108
39256
|
} else {
|
|
39109
39257
|
const consoleUrl = `https://${region}.console.aws.amazon.com/sms-voice/home?region=${region}#/registrations`;
|
|
39110
39258
|
console.log("");
|
|
39111
39259
|
console.log("When you're ready, go to:");
|
|
39112
|
-
console.log(` ${
|
|
39260
|
+
console.log(` ${pc54.cyan(consoleUrl)}`);
|
|
39113
39261
|
}
|
|
39114
39262
|
trackCommand("sms:register", {
|
|
39115
39263
|
success: true,
|
|
39116
39264
|
duration_ms: Date.now() - startTime
|
|
39117
39265
|
});
|
|
39118
|
-
|
|
39266
|
+
clack51.outro(pc54.dim("Good luck with your registration!"));
|
|
39119
39267
|
}
|
|
39120
39268
|
|
|
39121
39269
|
// src/commands/sms/status.ts
|
|
@@ -39128,54 +39276,54 @@ init_metadata();
|
|
|
39128
39276
|
init_output();
|
|
39129
39277
|
init_pulumi();
|
|
39130
39278
|
init_region_resolver();
|
|
39131
|
-
import * as
|
|
39279
|
+
import * as clack52 from "@clack/prompts";
|
|
39132
39280
|
import * as pulumi33 from "@pulumi/pulumi";
|
|
39133
|
-
import
|
|
39281
|
+
import pc55 from "picocolors";
|
|
39134
39282
|
function displaySMSStatus(options) {
|
|
39135
39283
|
const lines = [];
|
|
39136
|
-
lines.push(
|
|
39284
|
+
lines.push(pc55.bold(pc55.green("SMS Infrastructure Active")));
|
|
39137
39285
|
lines.push("");
|
|
39138
|
-
lines.push(
|
|
39286
|
+
lines.push(pc55.bold("Phone Number"));
|
|
39139
39287
|
if (options.phoneNumber) {
|
|
39140
|
-
lines.push(` Number: ${
|
|
39288
|
+
lines.push(` Number: ${pc55.cyan(options.phoneNumber)}`);
|
|
39141
39289
|
} else {
|
|
39142
|
-
lines.push(` Number: ${
|
|
39290
|
+
lines.push(` Number: ${pc55.yellow("Provisioning...")}`);
|
|
39143
39291
|
}
|
|
39144
|
-
lines.push(` Type: ${
|
|
39292
|
+
lines.push(` Type: ${pc55.cyan(options.phoneNumberType || "simulator")}`);
|
|
39145
39293
|
lines.push("");
|
|
39146
|
-
lines.push(
|
|
39147
|
-
lines.push(` Region: ${
|
|
39294
|
+
lines.push(pc55.bold("Configuration"));
|
|
39295
|
+
lines.push(` Region: ${pc55.cyan(options.region)}`);
|
|
39148
39296
|
if (options.preset) {
|
|
39149
|
-
lines.push(` Preset: ${
|
|
39297
|
+
lines.push(` Preset: ${pc55.cyan(options.preset)}`);
|
|
39150
39298
|
}
|
|
39151
39299
|
if (options.configSetName) {
|
|
39152
|
-
lines.push(` Config Set: ${
|
|
39300
|
+
lines.push(` Config Set: ${pc55.cyan(options.configSetName)}`);
|
|
39153
39301
|
}
|
|
39154
39302
|
lines.push("");
|
|
39155
|
-
lines.push(
|
|
39303
|
+
lines.push(pc55.bold("Features"));
|
|
39156
39304
|
lines.push(
|
|
39157
|
-
` Event Tracking: ${options.eventTracking ?
|
|
39305
|
+
` Event Tracking: ${options.eventTracking ? pc55.green("Enabled") : pc55.dim("Disabled")}`
|
|
39158
39306
|
);
|
|
39159
39307
|
if (options.tableName) {
|
|
39160
|
-
lines.push(` Message History: ${
|
|
39161
|
-
lines.push(` Table: ${
|
|
39308
|
+
lines.push(` Message History: ${pc55.green("Enabled")}`);
|
|
39309
|
+
lines.push(` Table: ${pc55.dim(options.tableName)}`);
|
|
39162
39310
|
}
|
|
39163
39311
|
if (options.queueUrl) {
|
|
39164
|
-
lines.push(` Event Queue: ${
|
|
39312
|
+
lines.push(` Event Queue: ${pc55.green("Enabled")}`);
|
|
39165
39313
|
}
|
|
39166
39314
|
lines.push("");
|
|
39167
39315
|
if (options.roleArn) {
|
|
39168
|
-
lines.push(
|
|
39169
|
-
lines.push(` ${
|
|
39316
|
+
lines.push(pc55.bold("IAM Role"));
|
|
39317
|
+
lines.push(` ${pc55.dim(options.roleArn)}`);
|
|
39170
39318
|
}
|
|
39171
|
-
|
|
39319
|
+
clack52.note(lines.join("\n"), "SMS Status");
|
|
39172
39320
|
}
|
|
39173
39321
|
async function smsStatus(options) {
|
|
39174
39322
|
await ensurePulumiInstalled();
|
|
39175
39323
|
const startTime = Date.now();
|
|
39176
39324
|
const progress = new DeploymentProgress();
|
|
39177
39325
|
if (!isJsonMode()) {
|
|
39178
|
-
|
|
39326
|
+
clack52.intro(pc55.bold("Wraps SMS Status"));
|
|
39179
39327
|
}
|
|
39180
39328
|
const identity = await progress.execute(
|
|
39181
39329
|
"Loading SMS infrastructure status",
|
|
@@ -39190,10 +39338,10 @@ async function smsStatus(options) {
|
|
|
39190
39338
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
39191
39339
|
if (!metadata?.services?.sms) {
|
|
39192
39340
|
progress.stop();
|
|
39193
|
-
|
|
39341
|
+
clack52.log.error("No SMS infrastructure found");
|
|
39194
39342
|
console.log(
|
|
39195
39343
|
`
|
|
39196
|
-
Run ${
|
|
39344
|
+
Run ${pc55.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
39197
39345
|
`
|
|
39198
39346
|
);
|
|
39199
39347
|
process.exit(1);
|
|
@@ -39229,25 +39377,25 @@ Run ${pc54.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39229
39377
|
}
|
|
39230
39378
|
displaySMSStatus(smsStatusData);
|
|
39231
39379
|
console.log("");
|
|
39232
|
-
|
|
39380
|
+
clack52.log.info(pc55.bold("Commands:"));
|
|
39233
39381
|
console.log(
|
|
39234
|
-
` ${
|
|
39382
|
+
` ${pc55.cyan("wraps sms test --to +1234567890")} - Send a test message`
|
|
39235
39383
|
);
|
|
39236
|
-
console.log(` ${
|
|
39384
|
+
console.log(` ${pc55.cyan("wraps sms destroy")} - Remove SMS infrastructure`);
|
|
39237
39385
|
trackCommand("sms:status", {
|
|
39238
39386
|
success: true,
|
|
39239
39387
|
phone_type: smsConfig?.phoneNumberType,
|
|
39240
39388
|
event_tracking: smsConfig?.eventTracking?.enabled,
|
|
39241
39389
|
duration_ms: Date.now() - startTime
|
|
39242
39390
|
});
|
|
39243
|
-
|
|
39391
|
+
clack52.outro(pc55.dim("SMS infrastructure is ready"));
|
|
39244
39392
|
}
|
|
39245
39393
|
|
|
39246
39394
|
// src/commands/sms/sync.ts
|
|
39247
39395
|
init_esm_shims();
|
|
39248
|
-
import * as
|
|
39396
|
+
import * as clack53 from "@clack/prompts";
|
|
39249
39397
|
import * as pulumi34 from "@pulumi/pulumi";
|
|
39250
|
-
import
|
|
39398
|
+
import pc56 from "picocolors";
|
|
39251
39399
|
init_events();
|
|
39252
39400
|
init_aws();
|
|
39253
39401
|
init_errors();
|
|
@@ -39260,7 +39408,7 @@ async function smsSync(options) {
|
|
|
39260
39408
|
await ensurePulumiInstalled();
|
|
39261
39409
|
const startTime = Date.now();
|
|
39262
39410
|
if (!isJsonMode()) {
|
|
39263
|
-
|
|
39411
|
+
clack53.intro(pc56.bold("Wraps SMS Infrastructure Sync"));
|
|
39264
39412
|
}
|
|
39265
39413
|
const progress = new DeploymentProgress();
|
|
39266
39414
|
const identity = await progress.execute(
|
|
@@ -39272,10 +39420,10 @@ async function smsSync(options) {
|
|
|
39272
39420
|
const smsService = metadata?.services?.sms;
|
|
39273
39421
|
if (!smsService?.config) {
|
|
39274
39422
|
progress.stop();
|
|
39275
|
-
|
|
39423
|
+
clack53.log.error("No SMS infrastructure found to sync");
|
|
39276
39424
|
console.log(
|
|
39277
39425
|
`
|
|
39278
|
-
Run ${
|
|
39426
|
+
Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
39279
39427
|
`
|
|
39280
39428
|
);
|
|
39281
39429
|
process.exit(1);
|
|
@@ -39284,18 +39432,18 @@ Run ${pc55.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
39284
39432
|
const storedStackName = smsService.pulumiStackName;
|
|
39285
39433
|
progress.info("Found existing SMS configuration");
|
|
39286
39434
|
progress.info(
|
|
39287
|
-
`Phone type: ${
|
|
39435
|
+
`Phone type: ${pc56.cyan(smsConfig.phoneNumberType || "simulator")}`
|
|
39288
39436
|
);
|
|
39289
39437
|
progress.info(
|
|
39290
|
-
`Event tracking: ${
|
|
39438
|
+
`Event tracking: ${pc56.cyan(smsConfig.eventTracking?.enabled ? "enabled" : "disabled")}`
|
|
39291
39439
|
);
|
|
39292
39440
|
if (!options.yes) {
|
|
39293
|
-
const confirmed = await
|
|
39441
|
+
const confirmed = await clack53.confirm({
|
|
39294
39442
|
message: "Sync SMS infrastructure? This will update Lambda code and recreate any missing resources.",
|
|
39295
39443
|
initialValue: true
|
|
39296
39444
|
});
|
|
39297
|
-
if (
|
|
39298
|
-
|
|
39445
|
+
if (clack53.isCancel(confirmed) || !confirmed) {
|
|
39446
|
+
clack53.cancel("Sync cancelled.");
|
|
39299
39447
|
process.exit(0);
|
|
39300
39448
|
}
|
|
39301
39449
|
}
|
|
@@ -39400,7 +39548,7 @@ Run ${pc55.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
39400
39548
|
throw errors.stackLocked();
|
|
39401
39549
|
}
|
|
39402
39550
|
trackError("SYNC_FAILED", "sms:sync", { step: "sync" });
|
|
39403
|
-
|
|
39551
|
+
clack53.log.error(`SMS sync failed: ${errorMessage}`);
|
|
39404
39552
|
process.exit(1);
|
|
39405
39553
|
}
|
|
39406
39554
|
if (metadata && smsService) {
|
|
@@ -39420,7 +39568,7 @@ Run ${pc55.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
39420
39568
|
return;
|
|
39421
39569
|
}
|
|
39422
39570
|
console.log("\n");
|
|
39423
|
-
|
|
39571
|
+
clack53.log.success(pc56.green("SMS infrastructure synced successfully!"));
|
|
39424
39572
|
const changes = [];
|
|
39425
39573
|
if (outputs.lambdaFunctions?.length) {
|
|
39426
39574
|
changes.push("Lambda functions updated");
|
|
@@ -39428,13 +39576,13 @@ Run ${pc55.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
39428
39576
|
changes.push("SDK resources verified");
|
|
39429
39577
|
console.log("");
|
|
39430
39578
|
for (const change of changes) {
|
|
39431
|
-
console.log(` ${
|
|
39579
|
+
console.log(` ${pc56.green("\u2713")} ${change}`);
|
|
39432
39580
|
}
|
|
39433
39581
|
trackCommand("sms:sync", {
|
|
39434
39582
|
success: true,
|
|
39435
39583
|
duration_ms: Date.now() - startTime
|
|
39436
39584
|
});
|
|
39437
|
-
|
|
39585
|
+
clack53.outro(pc56.green("Sync complete!"));
|
|
39438
39586
|
}
|
|
39439
39587
|
|
|
39440
39588
|
// src/commands/sms/test.ts
|
|
@@ -39449,8 +39597,8 @@ import {
|
|
|
39449
39597
|
PinpointSMSVoiceV2Client as PinpointSMSVoiceV2Client3,
|
|
39450
39598
|
SendTextMessageCommand
|
|
39451
39599
|
} from "@aws-sdk/client-pinpoint-sms-voice-v2";
|
|
39452
|
-
import * as
|
|
39453
|
-
import
|
|
39600
|
+
import * as clack54 from "@clack/prompts";
|
|
39601
|
+
import pc57 from "picocolors";
|
|
39454
39602
|
|
|
39455
39603
|
// src/utils/sms/validation.ts
|
|
39456
39604
|
init_esm_shims();
|
|
@@ -39473,7 +39621,7 @@ async function smsTest(options) {
|
|
|
39473
39621
|
const startTime = Date.now();
|
|
39474
39622
|
const progress = new DeploymentProgress();
|
|
39475
39623
|
if (!isJsonMode()) {
|
|
39476
|
-
|
|
39624
|
+
clack54.intro(pc57.bold("Wraps SMS Test"));
|
|
39477
39625
|
}
|
|
39478
39626
|
const identity = await progress.execute(
|
|
39479
39627
|
"Validating AWS credentials",
|
|
@@ -39483,10 +39631,10 @@ async function smsTest(options) {
|
|
|
39483
39631
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
39484
39632
|
if (!metadata?.services?.sms) {
|
|
39485
39633
|
progress.stop();
|
|
39486
|
-
|
|
39634
|
+
clack54.log.error("No SMS infrastructure found");
|
|
39487
39635
|
console.log(
|
|
39488
39636
|
`
|
|
39489
|
-
Run ${
|
|
39637
|
+
Run ${pc57.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
39490
39638
|
`
|
|
39491
39639
|
);
|
|
39492
39640
|
process.exit(1);
|
|
@@ -39500,7 +39648,7 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39500
39648
|
);
|
|
39501
39649
|
}
|
|
39502
39650
|
if (!toNumber) {
|
|
39503
|
-
const destinationType = await
|
|
39651
|
+
const destinationType = await clack54.select({
|
|
39504
39652
|
message: "Choose destination number:",
|
|
39505
39653
|
options: [
|
|
39506
39654
|
{
|
|
@@ -39515,25 +39663,25 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39515
39663
|
}
|
|
39516
39664
|
]
|
|
39517
39665
|
});
|
|
39518
|
-
if (
|
|
39519
|
-
|
|
39666
|
+
if (clack54.isCancel(destinationType)) {
|
|
39667
|
+
clack54.cancel("Operation cancelled.");
|
|
39520
39668
|
process.exit(0);
|
|
39521
39669
|
}
|
|
39522
39670
|
if (destinationType === "simulator") {
|
|
39523
|
-
const simResult = await
|
|
39671
|
+
const simResult = await clack54.select({
|
|
39524
39672
|
message: "Select simulator destination:",
|
|
39525
39673
|
options: SIMULATOR_DESTINATIONS.map((sim) => ({
|
|
39526
39674
|
value: sim.number,
|
|
39527
39675
|
label: `${sim.number} | ${sim.country}`
|
|
39528
39676
|
}))
|
|
39529
39677
|
});
|
|
39530
|
-
if (
|
|
39531
|
-
|
|
39678
|
+
if (clack54.isCancel(simResult)) {
|
|
39679
|
+
clack54.cancel("Operation cancelled.");
|
|
39532
39680
|
process.exit(0);
|
|
39533
39681
|
}
|
|
39534
39682
|
toNumber = simResult;
|
|
39535
39683
|
} else {
|
|
39536
|
-
const result = await
|
|
39684
|
+
const result = await clack54.text({
|
|
39537
39685
|
message: "Enter destination phone number (E.164 format):",
|
|
39538
39686
|
placeholder: "+14155551234",
|
|
39539
39687
|
validate: (value) => {
|
|
@@ -39546,22 +39694,22 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39546
39694
|
return;
|
|
39547
39695
|
}
|
|
39548
39696
|
});
|
|
39549
|
-
if (
|
|
39550
|
-
|
|
39697
|
+
if (clack54.isCancel(result)) {
|
|
39698
|
+
clack54.cancel("Operation cancelled.");
|
|
39551
39699
|
process.exit(0);
|
|
39552
39700
|
}
|
|
39553
39701
|
toNumber = result;
|
|
39554
39702
|
}
|
|
39555
39703
|
} else if (!isValidPhoneNumber(toNumber)) {
|
|
39556
39704
|
progress.stop();
|
|
39557
|
-
|
|
39705
|
+
clack54.log.error(
|
|
39558
39706
|
`Invalid phone number format: ${toNumber}. Use E.164 format (e.g., +14155551234)`
|
|
39559
39707
|
);
|
|
39560
39708
|
process.exit(1);
|
|
39561
39709
|
}
|
|
39562
39710
|
let message = options.message;
|
|
39563
39711
|
if (!message) {
|
|
39564
|
-
const result = await
|
|
39712
|
+
const result = await clack54.text({
|
|
39565
39713
|
message: "Enter test message:",
|
|
39566
39714
|
placeholder: "Hello from Wraps SMS!",
|
|
39567
39715
|
defaultValue: "Hello from Wraps SMS! This is a test message.",
|
|
@@ -39575,8 +39723,8 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39575
39723
|
return;
|
|
39576
39724
|
}
|
|
39577
39725
|
});
|
|
39578
|
-
if (
|
|
39579
|
-
|
|
39726
|
+
if (clack54.isCancel(result)) {
|
|
39727
|
+
clack54.cancel("Operation cancelled.");
|
|
39580
39728
|
process.exit(0);
|
|
39581
39729
|
}
|
|
39582
39730
|
message = result;
|
|
@@ -39615,16 +39763,16 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39615
39763
|
return;
|
|
39616
39764
|
}
|
|
39617
39765
|
console.log("\n");
|
|
39618
|
-
|
|
39766
|
+
clack54.log.success(pc57.green("Test SMS sent successfully!"));
|
|
39619
39767
|
console.log("");
|
|
39620
|
-
|
|
39768
|
+
clack54.note(
|
|
39621
39769
|
[
|
|
39622
|
-
`${
|
|
39623
|
-
`${
|
|
39624
|
-
`${
|
|
39625
|
-
`${
|
|
39770
|
+
`${pc57.bold("Message ID:")} ${pc57.cyan(messageId || "unknown")}`,
|
|
39771
|
+
`${pc57.bold("To:")} ${pc57.cyan(toNumber)}`,
|
|
39772
|
+
`${pc57.bold("Message:")} ${message}`,
|
|
39773
|
+
`${pc57.bold("Type:")} ${pc57.cyan(smsConfig?.phoneNumberType || "simulator")}`,
|
|
39626
39774
|
"",
|
|
39627
|
-
|
|
39775
|
+
pc57.dim(
|
|
39628
39776
|
smsConfig?.phoneNumberType === "simulator" ? "Note: Simulator messages are not actually delivered" : "Check your phone for the message!"
|
|
39629
39777
|
)
|
|
39630
39778
|
].join("\n"),
|
|
@@ -39632,11 +39780,11 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39632
39780
|
);
|
|
39633
39781
|
if (smsConfig?.eventTracking?.enabled) {
|
|
39634
39782
|
console.log("");
|
|
39635
|
-
|
|
39636
|
-
|
|
39783
|
+
clack54.log.info(
|
|
39784
|
+
pc57.dim("Event tracking is enabled. Check DynamoDB for delivery status.")
|
|
39637
39785
|
);
|
|
39638
39786
|
}
|
|
39639
|
-
|
|
39787
|
+
clack54.outro(pc57.green("Test complete!"));
|
|
39640
39788
|
} catch (error) {
|
|
39641
39789
|
progress.stop();
|
|
39642
39790
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -39648,33 +39796,33 @@ Run ${pc56.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
39648
39796
|
});
|
|
39649
39797
|
const errorName = error instanceof Error ? error.name : "";
|
|
39650
39798
|
if (errorName === "ConflictException" || errorMessage.includes("opt-out")) {
|
|
39651
|
-
|
|
39799
|
+
clack54.log.error("Destination number has opted out of messages");
|
|
39652
39800
|
console.log("\nThe recipient has opted out of receiving SMS messages.\n");
|
|
39653
39801
|
} else if (errorName === "ThrottlingException" || errorMessage.includes("spending limit")) {
|
|
39654
|
-
|
|
39802
|
+
clack54.log.error("SMS rate or spending limit reached");
|
|
39655
39803
|
console.log(
|
|
39656
39804
|
"\nCheck your AWS account SMS spending limits in the console.\n"
|
|
39657
39805
|
);
|
|
39658
39806
|
} else if (errorName === "ValidationException") {
|
|
39659
|
-
|
|
39807
|
+
clack54.log.error(`Invalid request: ${errorMessage}`);
|
|
39660
39808
|
} else if (errorMessage.includes("not verified") || errorMessage.includes("not registered")) {
|
|
39661
|
-
|
|
39809
|
+
clack54.log.error("Toll-free number registration is not complete");
|
|
39662
39810
|
console.log(
|
|
39663
39811
|
`
|
|
39664
|
-
Run ${
|
|
39812
|
+
Run ${pc57.cyan("wraps sms register")} to check registration status.
|
|
39665
39813
|
`
|
|
39666
39814
|
);
|
|
39667
39815
|
} else if (errorName === "AccessDeniedException") {
|
|
39668
|
-
|
|
39816
|
+
clack54.log.error(
|
|
39669
39817
|
"Permission denied \u2014 IAM role may be missing SMS send permissions"
|
|
39670
39818
|
);
|
|
39671
39819
|
console.log(
|
|
39672
39820
|
`
|
|
39673
|
-
Run ${
|
|
39821
|
+
Run ${pc57.cyan("wraps sms upgrade")} to update IAM policies.
|
|
39674
39822
|
`
|
|
39675
39823
|
);
|
|
39676
39824
|
} else {
|
|
39677
|
-
|
|
39825
|
+
clack54.log.error(`Failed to send SMS: ${errorMessage}`);
|
|
39678
39826
|
}
|
|
39679
39827
|
process.exit(1);
|
|
39680
39828
|
}
|
|
@@ -39682,9 +39830,9 @@ Run ${pc56.cyan("wraps sms upgrade")} to update IAM policies.
|
|
|
39682
39830
|
|
|
39683
39831
|
// src/commands/sms/upgrade.ts
|
|
39684
39832
|
init_esm_shims();
|
|
39685
|
-
import * as
|
|
39833
|
+
import * as clack55 from "@clack/prompts";
|
|
39686
39834
|
import * as pulumi35 from "@pulumi/pulumi";
|
|
39687
|
-
import
|
|
39835
|
+
import pc58 from "picocolors";
|
|
39688
39836
|
init_events();
|
|
39689
39837
|
init_aws();
|
|
39690
39838
|
init_errors();
|
|
@@ -39699,7 +39847,7 @@ async function smsUpgrade(options) {
|
|
|
39699
39847
|
const startTime = Date.now();
|
|
39700
39848
|
let upgradeAction = "";
|
|
39701
39849
|
if (!isJsonMode()) {
|
|
39702
|
-
|
|
39850
|
+
clack55.intro(pc58.bold("Wraps SMS Upgrade - Enhance Your SMS Infrastructure"));
|
|
39703
39851
|
}
|
|
39704
39852
|
const progress = new DeploymentProgress();
|
|
39705
39853
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -39713,7 +39861,7 @@ async function smsUpgrade(options) {
|
|
|
39713
39861
|
"Validating AWS credentials",
|
|
39714
39862
|
async () => validateAWSCredentials()
|
|
39715
39863
|
);
|
|
39716
|
-
progress.info(`Connected to AWS account: ${
|
|
39864
|
+
progress.info(`Connected to AWS account: ${pc58.cyan(identity.accountId)}`);
|
|
39717
39865
|
const region = await resolveRegionForCommand({
|
|
39718
39866
|
accountId: identity.accountId,
|
|
39719
39867
|
optionRegion: options.region,
|
|
@@ -39722,35 +39870,35 @@ async function smsUpgrade(options) {
|
|
|
39722
39870
|
});
|
|
39723
39871
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
39724
39872
|
if (!metadata) {
|
|
39725
|
-
|
|
39726
|
-
`No Wraps connection found for account ${
|
|
39873
|
+
clack55.log.error(
|
|
39874
|
+
`No Wraps connection found for account ${pc58.cyan(identity.accountId)} in region ${pc58.cyan(region)}`
|
|
39727
39875
|
);
|
|
39728
|
-
|
|
39729
|
-
`Use ${
|
|
39876
|
+
clack55.log.info(
|
|
39877
|
+
`Use ${pc58.cyan("wraps sms init")} to create new infrastructure.`
|
|
39730
39878
|
);
|
|
39731
39879
|
process.exit(1);
|
|
39732
39880
|
}
|
|
39733
39881
|
if (!metadata.services.sms) {
|
|
39734
|
-
|
|
39735
|
-
|
|
39736
|
-
`Use ${
|
|
39882
|
+
clack55.log.error("No SMS infrastructure found");
|
|
39883
|
+
clack55.log.info(
|
|
39884
|
+
`Use ${pc58.cyan("wraps sms init")} to deploy SMS infrastructure.`
|
|
39737
39885
|
);
|
|
39738
39886
|
process.exit(1);
|
|
39739
39887
|
}
|
|
39740
39888
|
progress.info(`Found existing connection created: ${metadata.timestamp}`);
|
|
39741
39889
|
console.log(`
|
|
39742
|
-
${
|
|
39890
|
+
${pc58.bold("Current Configuration:")}
|
|
39743
39891
|
`);
|
|
39744
39892
|
if (metadata.services.sms.preset) {
|
|
39745
|
-
console.log(` Preset: ${
|
|
39893
|
+
console.log(` Preset: ${pc58.cyan(metadata.services.sms.preset)}`);
|
|
39746
39894
|
} else {
|
|
39747
|
-
console.log(` Preset: ${
|
|
39895
|
+
console.log(` Preset: ${pc58.cyan("custom")}`);
|
|
39748
39896
|
}
|
|
39749
39897
|
const config2 = metadata.services.sms.config;
|
|
39750
39898
|
if (!config2) {
|
|
39751
|
-
|
|
39752
|
-
|
|
39753
|
-
`Use ${
|
|
39899
|
+
clack55.log.error("No SMS configuration found in metadata");
|
|
39900
|
+
clack55.log.info(
|
|
39901
|
+
`Use ${pc58.cyan("wraps sms init")} to create new infrastructure.`
|
|
39754
39902
|
);
|
|
39755
39903
|
process.exit(1);
|
|
39756
39904
|
}
|
|
@@ -39762,45 +39910,45 @@ ${pc57.bold("Current Configuration:")}
|
|
|
39762
39910
|
"short-code": "Short code ($995+/mo, 100+ MPS)"
|
|
39763
39911
|
};
|
|
39764
39912
|
console.log(
|
|
39765
|
-
` Phone Type: ${
|
|
39913
|
+
` Phone Type: ${pc58.cyan(phoneTypeLabels2[config2.phoneNumberType] || config2.phoneNumberType)}`
|
|
39766
39914
|
);
|
|
39767
39915
|
}
|
|
39768
39916
|
if (config2.tracking?.enabled) {
|
|
39769
|
-
console.log(` ${
|
|
39917
|
+
console.log(` ${pc58.green("\u2713")} Delivery Tracking`);
|
|
39770
39918
|
if (config2.tracking.linkTracking) {
|
|
39771
|
-
console.log(` ${
|
|
39919
|
+
console.log(` ${pc58.dim("\u2514\u2500")} Link click tracking enabled`);
|
|
39772
39920
|
}
|
|
39773
39921
|
}
|
|
39774
39922
|
if (config2.eventTracking?.enabled) {
|
|
39775
|
-
console.log(` ${
|
|
39923
|
+
console.log(` ${pc58.green("\u2713")} Event Tracking (SNS)`);
|
|
39776
39924
|
if (config2.eventTracking.dynamoDBHistory) {
|
|
39777
39925
|
console.log(
|
|
39778
|
-
` ${
|
|
39926
|
+
` ${pc58.dim("\u2514\u2500")} Message History: ${pc58.cyan(config2.eventTracking.archiveRetention || "90days")}`
|
|
39779
39927
|
);
|
|
39780
39928
|
}
|
|
39781
39929
|
}
|
|
39782
39930
|
if (config2.messageArchiving?.enabled) {
|
|
39783
39931
|
console.log(
|
|
39784
|
-
` ${
|
|
39932
|
+
` ${pc58.green("\u2713")} Message Archiving (${config2.messageArchiving.retention})`
|
|
39785
39933
|
);
|
|
39786
39934
|
}
|
|
39787
39935
|
if (config2.optOutManagement) {
|
|
39788
|
-
console.log(` ${
|
|
39936
|
+
console.log(` ${pc58.green("\u2713")} Opt-out Management`);
|
|
39789
39937
|
}
|
|
39790
39938
|
if (config2.protectConfiguration?.enabled) {
|
|
39791
39939
|
const countries = config2.protectConfiguration.allowedCountries?.join(", ") || "US";
|
|
39792
|
-
console.log(` ${
|
|
39793
|
-
console.log(` ${
|
|
39940
|
+
console.log(` ${pc58.green("\u2713")} Fraud Protection`);
|
|
39941
|
+
console.log(` ${pc58.dim("\u2514\u2500")} Allowed countries: ${pc58.cyan(countries)}`);
|
|
39794
39942
|
if (config2.protectConfiguration.aitFiltering) {
|
|
39795
|
-
console.log(` ${
|
|
39943
|
+
console.log(` ${pc58.dim("\u2514\u2500")} AIT filtering: ${pc58.cyan("enabled")}`);
|
|
39796
39944
|
}
|
|
39797
39945
|
} else {
|
|
39798
|
-
console.log(` ${
|
|
39946
|
+
console.log(` ${pc58.dim("\u25CB")} Fraud Protection (not configured)`);
|
|
39799
39947
|
}
|
|
39800
39948
|
const currentCostData = calculateSMSCosts(config2, 1e4);
|
|
39801
39949
|
console.log(
|
|
39802
39950
|
`
|
|
39803
|
-
Estimated Cost: ${
|
|
39951
|
+
Estimated Cost: ${pc58.cyan(`~${formatCost3(currentCostData.total.monthly)}/mo`)}`
|
|
39804
39952
|
);
|
|
39805
39953
|
console.log("");
|
|
39806
39954
|
const phoneTypeLabels = {
|
|
@@ -39809,7 +39957,7 @@ ${pc57.bold("Current Configuration:")}
|
|
|
39809
39957
|
"10dlc": "10DLC",
|
|
39810
39958
|
"short-code": "Short code"
|
|
39811
39959
|
};
|
|
39812
|
-
upgradeAction = await
|
|
39960
|
+
upgradeAction = await clack55.select({
|
|
39813
39961
|
message: "What would you like to do?",
|
|
39814
39962
|
options: [
|
|
39815
39963
|
{
|
|
@@ -39849,8 +39997,8 @@ ${pc57.bold("Current Configuration:")}
|
|
|
39849
39997
|
}
|
|
39850
39998
|
]
|
|
39851
39999
|
});
|
|
39852
|
-
if (
|
|
39853
|
-
|
|
40000
|
+
if (clack55.isCancel(upgradeAction)) {
|
|
40001
|
+
clack55.cancel("Upgrade cancelled.");
|
|
39854
40002
|
process.exit(0);
|
|
39855
40003
|
}
|
|
39856
40004
|
let updatedConfig = { ...config2 };
|
|
@@ -39891,65 +40039,65 @@ ${pc57.bold("Current Configuration:")}
|
|
|
39891
40039
|
hint: p.hint
|
|
39892
40040
|
}));
|
|
39893
40041
|
if (availableTypes.length === 0) {
|
|
39894
|
-
|
|
40042
|
+
clack55.log.warn(
|
|
39895
40043
|
"Already on highest phone number tier. Contact AWS for dedicated short codes."
|
|
39896
40044
|
);
|
|
39897
40045
|
process.exit(0);
|
|
39898
40046
|
}
|
|
39899
|
-
const selectedType = await
|
|
40047
|
+
const selectedType = await clack55.select({
|
|
39900
40048
|
message: "Select new phone number type:",
|
|
39901
40049
|
options: availableTypes
|
|
39902
40050
|
});
|
|
39903
|
-
if (
|
|
39904
|
-
|
|
40051
|
+
if (clack55.isCancel(selectedType)) {
|
|
40052
|
+
clack55.cancel("Upgrade cancelled.");
|
|
39905
40053
|
process.exit(0);
|
|
39906
40054
|
}
|
|
39907
40055
|
if (selectedType === "toll-free") {
|
|
39908
40056
|
console.log(
|
|
39909
40057
|
`
|
|
39910
|
-
${
|
|
40058
|
+
${pc58.yellow("\u26A0")} ${pc58.bold("Toll-free Registration Required")}
|
|
39911
40059
|
`
|
|
39912
40060
|
);
|
|
39913
40061
|
console.log(
|
|
39914
|
-
|
|
40062
|
+
pc58.dim("Toll-free numbers require carrier registration before")
|
|
39915
40063
|
);
|
|
39916
40064
|
console.log(
|
|
39917
|
-
|
|
40065
|
+
pc58.dim("they can send messages at scale. After deployment:\n")
|
|
39918
40066
|
);
|
|
39919
40067
|
console.log(
|
|
39920
|
-
` 1. Run ${
|
|
40068
|
+
` 1. Run ${pc58.cyan("wraps sms register")} to start registration`
|
|
39921
40069
|
);
|
|
39922
40070
|
console.log(" 2. Submit your business use case information");
|
|
39923
40071
|
console.log(" 3. Wait for carrier verification (1-5 business days)");
|
|
39924
40072
|
console.log(
|
|
39925
|
-
|
|
40073
|
+
pc58.dim("\nUntil verified, sending is limited to low volume.\n")
|
|
39926
40074
|
);
|
|
39927
|
-
const confirmTollFree = await
|
|
40075
|
+
const confirmTollFree = await clack55.confirm({
|
|
39928
40076
|
message: "Continue with toll-free number request?",
|
|
39929
40077
|
initialValue: true
|
|
39930
40078
|
});
|
|
39931
|
-
if (
|
|
39932
|
-
|
|
40079
|
+
if (clack55.isCancel(confirmTollFree) || !confirmTollFree) {
|
|
40080
|
+
clack55.cancel("Upgrade cancelled.");
|
|
39933
40081
|
process.exit(0);
|
|
39934
40082
|
}
|
|
39935
40083
|
}
|
|
39936
40084
|
if (selectedType === "10dlc") {
|
|
39937
40085
|
console.log(
|
|
39938
40086
|
`
|
|
39939
|
-
${
|
|
40087
|
+
${pc58.yellow("\u26A0")} ${pc58.bold("10DLC Campaign Registration Required")}
|
|
39940
40088
|
`
|
|
39941
40089
|
);
|
|
39942
|
-
console.log(
|
|
40090
|
+
console.log(pc58.dim("10DLC requires brand and campaign registration:"));
|
|
39943
40091
|
console.log(" \u2022 Brand registration: one-time $4 fee");
|
|
39944
40092
|
console.log(" \u2022 Campaign registration: $15/mo per campaign");
|
|
39945
40093
|
console.log(" \u2022 Verification takes 1-7 business days");
|
|
39946
40094
|
console.log("");
|
|
39947
|
-
const confirm10DLC = await
|
|
40095
|
+
const confirm10DLC = await clack55.confirm({
|
|
39948
40096
|
message: "Continue with 10DLC number request?",
|
|
39949
40097
|
initialValue: true
|
|
39950
40098
|
});
|
|
39951
|
-
if (
|
|
39952
|
-
|
|
40099
|
+
if (clack55.isCancel(confirm10DLC) || !confirm10DLC) {
|
|
40100
|
+
clack55.cancel("Upgrade cancelled.");
|
|
39953
40101
|
process.exit(0);
|
|
39954
40102
|
}
|
|
39955
40103
|
}
|
|
@@ -39974,15 +40122,15 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
39974
40122
|
disabled: currentPresetIdx >= 0 && idx <= currentPresetIdx ? "Current or lower tier" : void 0
|
|
39975
40123
|
})).filter((p) => !p.disabled && p.value !== "custom");
|
|
39976
40124
|
if (availablePresets.length === 0) {
|
|
39977
|
-
|
|
40125
|
+
clack55.log.warn("Already on highest preset (Enterprise)");
|
|
39978
40126
|
process.exit(0);
|
|
39979
40127
|
}
|
|
39980
|
-
const selectedPreset = await
|
|
40128
|
+
const selectedPreset = await clack55.select({
|
|
39981
40129
|
message: "Select new preset:",
|
|
39982
40130
|
options: availablePresets
|
|
39983
40131
|
});
|
|
39984
|
-
if (
|
|
39985
|
-
|
|
40132
|
+
if (clack55.isCancel(selectedPreset)) {
|
|
40133
|
+
clack55.cancel("Upgrade cancelled.");
|
|
39986
40134
|
process.exit(0);
|
|
39987
40135
|
}
|
|
39988
40136
|
const presetConfig = getSMSPreset(selectedPreset);
|
|
@@ -39998,7 +40146,7 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
39998
40146
|
}
|
|
39999
40147
|
case "event-tracking": {
|
|
40000
40148
|
if (config2.eventTracking?.enabled) {
|
|
40001
|
-
const eventAction = await
|
|
40149
|
+
const eventAction = await clack55.select({
|
|
40002
40150
|
message: "What would you like to do with event tracking?",
|
|
40003
40151
|
options: [
|
|
40004
40152
|
{
|
|
@@ -40013,17 +40161,17 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40013
40161
|
}
|
|
40014
40162
|
]
|
|
40015
40163
|
});
|
|
40016
|
-
if (
|
|
40017
|
-
|
|
40164
|
+
if (clack55.isCancel(eventAction)) {
|
|
40165
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40018
40166
|
process.exit(0);
|
|
40019
40167
|
}
|
|
40020
40168
|
if (eventAction === "disable") {
|
|
40021
|
-
const confirmDisable = await
|
|
40169
|
+
const confirmDisable = await clack55.confirm({
|
|
40022
40170
|
message: "Are you sure? Existing history will remain, but new events won't be tracked.",
|
|
40023
40171
|
initialValue: false
|
|
40024
40172
|
});
|
|
40025
|
-
if (
|
|
40026
|
-
|
|
40173
|
+
if (clack55.isCancel(confirmDisable) || !confirmDisable) {
|
|
40174
|
+
clack55.cancel("Event tracking not disabled.");
|
|
40027
40175
|
process.exit(0);
|
|
40028
40176
|
}
|
|
40029
40177
|
updatedConfig = {
|
|
@@ -40033,7 +40181,7 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40033
40181
|
}
|
|
40034
40182
|
};
|
|
40035
40183
|
} else {
|
|
40036
|
-
const retention = await
|
|
40184
|
+
const retention = await clack55.select({
|
|
40037
40185
|
message: "Message history retention period:",
|
|
40038
40186
|
options: [
|
|
40039
40187
|
{ value: "7days", label: "7 days", hint: "Minimal storage cost" },
|
|
@@ -40060,8 +40208,8 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40060
40208
|
],
|
|
40061
40209
|
initialValue: config2.eventTracking.archiveRetention || "90days"
|
|
40062
40210
|
});
|
|
40063
|
-
if (
|
|
40064
|
-
|
|
40211
|
+
if (clack55.isCancel(retention)) {
|
|
40212
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40065
40213
|
process.exit(0);
|
|
40066
40214
|
}
|
|
40067
40215
|
updatedConfig = {
|
|
@@ -40073,19 +40221,19 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40073
40221
|
};
|
|
40074
40222
|
}
|
|
40075
40223
|
} else {
|
|
40076
|
-
const enableTracking = await
|
|
40224
|
+
const enableTracking = await clack55.confirm({
|
|
40077
40225
|
message: "Enable event tracking? (Track SMS events with history)",
|
|
40078
40226
|
initialValue: true
|
|
40079
40227
|
});
|
|
40080
|
-
if (
|
|
40081
|
-
|
|
40228
|
+
if (clack55.isCancel(enableTracking)) {
|
|
40229
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40082
40230
|
process.exit(0);
|
|
40083
40231
|
}
|
|
40084
40232
|
if (!enableTracking) {
|
|
40085
|
-
|
|
40233
|
+
clack55.log.info("Event tracking not enabled.");
|
|
40086
40234
|
process.exit(0);
|
|
40087
40235
|
}
|
|
40088
|
-
const retention = await
|
|
40236
|
+
const retention = await clack55.select({
|
|
40089
40237
|
message: "Message history retention period:",
|
|
40090
40238
|
options: [
|
|
40091
40239
|
{ value: "7days", label: "7 days", hint: "Minimal storage cost" },
|
|
@@ -40108,8 +40256,8 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40108
40256
|
],
|
|
40109
40257
|
initialValue: "90days"
|
|
40110
40258
|
});
|
|
40111
|
-
if (
|
|
40112
|
-
|
|
40259
|
+
if (clack55.isCancel(retention)) {
|
|
40260
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40113
40261
|
process.exit(0);
|
|
40114
40262
|
}
|
|
40115
40263
|
updatedConfig = {
|
|
@@ -40128,12 +40276,12 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40128
40276
|
}
|
|
40129
40277
|
case "retention": {
|
|
40130
40278
|
if (!config2.eventTracking?.enabled) {
|
|
40131
|
-
|
|
40279
|
+
clack55.log.error(
|
|
40132
40280
|
"Event tracking is not enabled. Enable it first to change retention."
|
|
40133
40281
|
);
|
|
40134
40282
|
process.exit(1);
|
|
40135
40283
|
}
|
|
40136
|
-
const retention = await
|
|
40284
|
+
const retention = await clack55.select({
|
|
40137
40285
|
message: "Message history retention period (event data in DynamoDB):",
|
|
40138
40286
|
options: [
|
|
40139
40287
|
{ value: "7days", label: "7 days", hint: "Minimal storage cost" },
|
|
@@ -40152,8 +40300,8 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40152
40300
|
],
|
|
40153
40301
|
initialValue: config2.eventTracking.archiveRetention || "90days"
|
|
40154
40302
|
});
|
|
40155
|
-
if (
|
|
40156
|
-
|
|
40303
|
+
if (clack55.isCancel(retention)) {
|
|
40304
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40157
40305
|
process.exit(0);
|
|
40158
40306
|
}
|
|
40159
40307
|
updatedConfig = {
|
|
@@ -40171,21 +40319,21 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40171
40319
|
case "link-tracking": {
|
|
40172
40320
|
const enableLinkTracking = !config2.tracking?.linkTracking;
|
|
40173
40321
|
if (enableLinkTracking) {
|
|
40174
|
-
|
|
40175
|
-
|
|
40322
|
+
clack55.log.info(
|
|
40323
|
+
pc58.dim(
|
|
40176
40324
|
"Link tracking will track clicks on URLs in your SMS messages."
|
|
40177
40325
|
)
|
|
40178
40326
|
);
|
|
40179
|
-
|
|
40180
|
-
|
|
40327
|
+
clack55.log.info(
|
|
40328
|
+
pc58.dim("URLs will be rewritten to go through a tracking endpoint.")
|
|
40181
40329
|
);
|
|
40182
40330
|
}
|
|
40183
|
-
const confirmed = await
|
|
40331
|
+
const confirmed = await clack55.confirm({
|
|
40184
40332
|
message: enableLinkTracking ? "Enable link click tracking?" : "Disable link click tracking?",
|
|
40185
40333
|
initialValue: enableLinkTracking
|
|
40186
40334
|
});
|
|
40187
|
-
if (
|
|
40188
|
-
|
|
40335
|
+
if (clack55.isCancel(confirmed) || !confirmed) {
|
|
40336
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40189
40337
|
process.exit(0);
|
|
40190
40338
|
}
|
|
40191
40339
|
updatedConfig = {
|
|
@@ -40202,7 +40350,7 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40202
40350
|
}
|
|
40203
40351
|
case "archiving": {
|
|
40204
40352
|
if (config2.messageArchiving?.enabled) {
|
|
40205
|
-
const archivingAction = await
|
|
40353
|
+
const archivingAction = await clack55.select({
|
|
40206
40354
|
message: "What would you like to do with message archiving?",
|
|
40207
40355
|
options: [
|
|
40208
40356
|
{
|
|
@@ -40217,17 +40365,17 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40217
40365
|
}
|
|
40218
40366
|
]
|
|
40219
40367
|
});
|
|
40220
|
-
if (
|
|
40221
|
-
|
|
40368
|
+
if (clack55.isCancel(archivingAction)) {
|
|
40369
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40222
40370
|
process.exit(0);
|
|
40223
40371
|
}
|
|
40224
40372
|
if (archivingAction === "disable") {
|
|
40225
|
-
const confirmDisable = await
|
|
40373
|
+
const confirmDisable = await clack55.confirm({
|
|
40226
40374
|
message: "Are you sure? Existing archived messages will remain, but new messages won't be archived.",
|
|
40227
40375
|
initialValue: false
|
|
40228
40376
|
});
|
|
40229
|
-
if (
|
|
40230
|
-
|
|
40377
|
+
if (clack55.isCancel(confirmDisable) || !confirmDisable) {
|
|
40378
|
+
clack55.cancel("Archiving not disabled.");
|
|
40231
40379
|
process.exit(0);
|
|
40232
40380
|
}
|
|
40233
40381
|
updatedConfig = {
|
|
@@ -40238,7 +40386,7 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40238
40386
|
}
|
|
40239
40387
|
};
|
|
40240
40388
|
} else {
|
|
40241
|
-
const retention = await
|
|
40389
|
+
const retention = await clack55.select({
|
|
40242
40390
|
message: "Message archive retention period:",
|
|
40243
40391
|
options: [
|
|
40244
40392
|
{
|
|
@@ -40269,8 +40417,8 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40269
40417
|
],
|
|
40270
40418
|
initialValue: config2.messageArchiving.retention
|
|
40271
40419
|
});
|
|
40272
|
-
if (
|
|
40273
|
-
|
|
40420
|
+
if (clack55.isCancel(retention)) {
|
|
40421
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40274
40422
|
process.exit(0);
|
|
40275
40423
|
}
|
|
40276
40424
|
updatedConfig = {
|
|
@@ -40282,19 +40430,19 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40282
40430
|
};
|
|
40283
40431
|
}
|
|
40284
40432
|
} else {
|
|
40285
|
-
const enableArchiving = await
|
|
40433
|
+
const enableArchiving = await clack55.confirm({
|
|
40286
40434
|
message: "Enable message archiving? (Store full message content for viewing)",
|
|
40287
40435
|
initialValue: true
|
|
40288
40436
|
});
|
|
40289
|
-
if (
|
|
40290
|
-
|
|
40437
|
+
if (clack55.isCancel(enableArchiving)) {
|
|
40438
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40291
40439
|
process.exit(0);
|
|
40292
40440
|
}
|
|
40293
40441
|
if (!enableArchiving) {
|
|
40294
|
-
|
|
40442
|
+
clack55.log.info("Message archiving not enabled.");
|
|
40295
40443
|
process.exit(0);
|
|
40296
40444
|
}
|
|
40297
|
-
const retention = await
|
|
40445
|
+
const retention = await clack55.select({
|
|
40298
40446
|
message: "Message archive retention period:",
|
|
40299
40447
|
options: [
|
|
40300
40448
|
{ value: "7days", label: "7 days", hint: "~$1-2/mo for 10k msgs" },
|
|
@@ -40321,8 +40469,8 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40321
40469
|
],
|
|
40322
40470
|
initialValue: "90days"
|
|
40323
40471
|
});
|
|
40324
|
-
if (
|
|
40325
|
-
|
|
40472
|
+
if (clack55.isCancel(retention)) {
|
|
40473
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40326
40474
|
process.exit(0);
|
|
40327
40475
|
}
|
|
40328
40476
|
updatedConfig = {
|
|
@@ -40354,7 +40502,7 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40354
40502
|
const currentAllowed = config2.protectConfiguration?.allowedCountries || [
|
|
40355
40503
|
"US"
|
|
40356
40504
|
];
|
|
40357
|
-
const selectedCountries = await
|
|
40505
|
+
const selectedCountries = await clack55.multiselect({
|
|
40358
40506
|
message: "Select countries to allow SMS delivery (all others blocked):",
|
|
40359
40507
|
options: commonCountries.map((c) => ({
|
|
40360
40508
|
value: c.code,
|
|
@@ -40363,16 +40511,16 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40363
40511
|
initialValues: currentAllowed,
|
|
40364
40512
|
required: true
|
|
40365
40513
|
});
|
|
40366
|
-
if (
|
|
40367
|
-
|
|
40514
|
+
if (clack55.isCancel(selectedCountries)) {
|
|
40515
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40368
40516
|
process.exit(0);
|
|
40369
40517
|
}
|
|
40370
|
-
const enableAIT = await
|
|
40518
|
+
const enableAIT = await clack55.confirm({
|
|
40371
40519
|
message: "Enable AIT (Artificially Inflated Traffic) filtering? (adds per-message cost)",
|
|
40372
40520
|
initialValue: config2.protectConfiguration?.aitFiltering ?? false
|
|
40373
40521
|
});
|
|
40374
|
-
if (
|
|
40375
|
-
|
|
40522
|
+
if (clack55.isCancel(enableAIT)) {
|
|
40523
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40376
40524
|
process.exit(0);
|
|
40377
40525
|
}
|
|
40378
40526
|
updatedConfig = {
|
|
@@ -40390,28 +40538,28 @@ ${pc57.yellow("\u26A0")} ${pc57.bold("10DLC Campaign Registration Required")}
|
|
|
40390
40538
|
const newCostData = calculateSMSCosts(updatedConfig, 1e4);
|
|
40391
40539
|
const costDiff = newCostData.total.monthly - currentCostData.total.monthly;
|
|
40392
40540
|
console.log(`
|
|
40393
|
-
${
|
|
40541
|
+
${pc58.bold("Cost Impact:")}`);
|
|
40394
40542
|
console.log(
|
|
40395
|
-
` Current: ${
|
|
40543
|
+
` Current: ${pc58.cyan(`${formatCost3(currentCostData.total.monthly)}/mo`)}`
|
|
40396
40544
|
);
|
|
40397
40545
|
console.log(
|
|
40398
|
-
` New: ${
|
|
40546
|
+
` New: ${pc58.cyan(`${formatCost3(newCostData.total.monthly)}/mo`)}`
|
|
40399
40547
|
);
|
|
40400
40548
|
if (costDiff > 0) {
|
|
40401
|
-
console.log(` Change: ${
|
|
40549
|
+
console.log(` Change: ${pc58.yellow(`+${formatCost3(costDiff)}/mo`)}`);
|
|
40402
40550
|
} else if (costDiff < 0) {
|
|
40403
40551
|
console.log(
|
|
40404
|
-
` Change: ${
|
|
40552
|
+
` Change: ${pc58.green(`-${formatCost3(Math.abs(costDiff))}/mo`)}`
|
|
40405
40553
|
);
|
|
40406
40554
|
}
|
|
40407
40555
|
console.log("");
|
|
40408
40556
|
if (!(options.yes || options.preview)) {
|
|
40409
|
-
const confirmed = await
|
|
40557
|
+
const confirmed = await clack55.confirm({
|
|
40410
40558
|
message: "Proceed with upgrade?",
|
|
40411
40559
|
initialValue: true
|
|
40412
40560
|
});
|
|
40413
|
-
if (
|
|
40414
|
-
|
|
40561
|
+
if (clack55.isCancel(confirmed) || !confirmed) {
|
|
40562
|
+
clack55.cancel("Upgrade cancelled.");
|
|
40415
40563
|
process.exit(0);
|
|
40416
40564
|
}
|
|
40417
40565
|
}
|
|
@@ -40480,8 +40628,8 @@ ${pc57.bold("Cost Impact:")}`);
|
|
|
40480
40628
|
resourceChanges: previewResult.resourceChanges,
|
|
40481
40629
|
commandName: "wraps sms upgrade"
|
|
40482
40630
|
});
|
|
40483
|
-
|
|
40484
|
-
|
|
40631
|
+
clack55.outro(
|
|
40632
|
+
pc58.green("Preview complete. Run without --preview to upgrade.")
|
|
40485
40633
|
);
|
|
40486
40634
|
trackServiceUpgrade("sms", {
|
|
40487
40635
|
region,
|
|
@@ -40586,43 +40734,43 @@ ${pc57.bold("Cost Impact:")}`);
|
|
|
40586
40734
|
}
|
|
40587
40735
|
progress.info("Connection metadata updated");
|
|
40588
40736
|
console.log("\n");
|
|
40589
|
-
|
|
40737
|
+
clack55.log.success(pc58.green(pc58.bold("SMS infrastructure upgraded!")));
|
|
40590
40738
|
console.log("\n");
|
|
40591
|
-
|
|
40739
|
+
clack55.note(
|
|
40592
40740
|
[
|
|
40593
|
-
`${
|
|
40594
|
-
`${
|
|
40595
|
-
`${
|
|
40596
|
-
`${
|
|
40597
|
-
outputs.tableName ? `${
|
|
40741
|
+
`${pc58.bold("Phone Number:")} ${pc58.cyan(outputs.phoneNumber || "Provisioning...")}`,
|
|
40742
|
+
`${pc58.bold("Phone Type:")} ${pc58.cyan(updatedConfig.phoneNumberType || "simulator")}`,
|
|
40743
|
+
`${pc58.bold("Config Set:")} ${pc58.cyan(outputs.configSetName || "wraps-sms-config")}`,
|
|
40744
|
+
`${pc58.bold("Region:")} ${pc58.cyan(outputs.region)}`,
|
|
40745
|
+
outputs.tableName ? `${pc58.bold("History Table:")} ${pc58.cyan(outputs.tableName)}` : "",
|
|
40598
40746
|
"",
|
|
40599
|
-
|
|
40600
|
-
|
|
40747
|
+
pc58.dim("IAM Role:"),
|
|
40748
|
+
pc58.dim(` ${outputs.roleArn}`)
|
|
40601
40749
|
].filter(Boolean).join("\n"),
|
|
40602
40750
|
"SMS Infrastructure"
|
|
40603
40751
|
);
|
|
40604
40752
|
console.log(`
|
|
40605
|
-
${
|
|
40753
|
+
${pc58.green("\u2713")} ${pc58.bold("Upgrade complete!")}
|
|
40606
40754
|
`);
|
|
40607
40755
|
if (upgradeAction === "phone-number") {
|
|
40608
40756
|
console.log(
|
|
40609
|
-
`Upgraded to ${
|
|
40757
|
+
`Upgraded to ${pc58.cyan(updatedConfig.phoneNumberType)} number (${pc58.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
40610
40758
|
`
|
|
40611
40759
|
);
|
|
40612
40760
|
if (updatedConfig.phoneNumberType === "toll-free") {
|
|
40613
|
-
console.log(`${
|
|
40761
|
+
console.log(`${pc58.bold("Next Steps:")}`);
|
|
40614
40762
|
console.log(
|
|
40615
|
-
` 1. Run ${
|
|
40763
|
+
` 1. Run ${pc58.cyan("wraps sms register")} to start toll-free registration`
|
|
40616
40764
|
);
|
|
40617
40765
|
console.log(" 2. Submit your business information and use case");
|
|
40618
40766
|
console.log(" 3. Wait for carrier verification (1-5 business days)");
|
|
40619
40767
|
console.log("");
|
|
40620
40768
|
console.log(
|
|
40621
|
-
|
|
40769
|
+
pc58.dim("Until verified, your number can only send limited messages.")
|
|
40622
40770
|
);
|
|
40623
40771
|
console.log("");
|
|
40624
40772
|
} else if (updatedConfig.phoneNumberType === "10dlc") {
|
|
40625
|
-
console.log(`${
|
|
40773
|
+
console.log(`${pc58.bold("Next Steps:")}`);
|
|
40626
40774
|
console.log(" 1. Register your brand in the AWS Console");
|
|
40627
40775
|
console.log(" 2. Create a 10DLC campaign for your use case");
|
|
40628
40776
|
console.log(" 3. Wait for campaign approval (1-7 business days)");
|
|
@@ -40630,16 +40778,16 @@ ${pc57.green("\u2713")} ${pc57.bold("Upgrade complete!")}
|
|
|
40630
40778
|
}
|
|
40631
40779
|
} else if (upgradeAction === "preset" && newPreset) {
|
|
40632
40780
|
console.log(
|
|
40633
|
-
`Upgraded to ${
|
|
40781
|
+
`Upgraded to ${pc58.cyan(newPreset)} preset (${pc58.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
40634
40782
|
`
|
|
40635
40783
|
);
|
|
40636
40784
|
} else {
|
|
40637
40785
|
console.log(
|
|
40638
|
-
`Updated configuration (${
|
|
40786
|
+
`Updated configuration (${pc58.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
40639
40787
|
`
|
|
40640
40788
|
);
|
|
40641
40789
|
}
|
|
40642
|
-
console.log(
|
|
40790
|
+
console.log(pc58.dim(getSMSCostSummary(updatedConfig, 1e4)));
|
|
40643
40791
|
const enabledFeatures = [];
|
|
40644
40792
|
if (updatedConfig.tracking?.enabled) {
|
|
40645
40793
|
enabledFeatures.push("tracking");
|
|
@@ -40663,7 +40811,7 @@ ${pc57.green("\u2713")} ${pc57.bold("Upgrade complete!")}
|
|
|
40663
40811
|
action: typeof upgradeAction === "string" ? upgradeAction : void 0,
|
|
40664
40812
|
duration_ms: Date.now() - startTime
|
|
40665
40813
|
});
|
|
40666
|
-
|
|
40814
|
+
clack55.outro(pc58.green("Upgrade complete!"));
|
|
40667
40815
|
}
|
|
40668
40816
|
|
|
40669
40817
|
// src/commands/sms/verify-number.ts
|
|
@@ -40682,13 +40830,13 @@ import {
|
|
|
40682
40830
|
SendDestinationNumberVerificationCodeCommand,
|
|
40683
40831
|
VerifyDestinationNumberCommand
|
|
40684
40832
|
} from "@aws-sdk/client-pinpoint-sms-voice-v2";
|
|
40685
|
-
import * as
|
|
40686
|
-
import
|
|
40833
|
+
import * as clack56 from "@clack/prompts";
|
|
40834
|
+
import pc59 from "picocolors";
|
|
40687
40835
|
async function smsVerifyNumber(options) {
|
|
40688
40836
|
const startTime = Date.now();
|
|
40689
40837
|
const progress = new DeploymentProgress();
|
|
40690
40838
|
if (!isJsonMode()) {
|
|
40691
|
-
|
|
40839
|
+
clack56.intro(pc59.bold("Wraps SMS - Verify Destination Number"));
|
|
40692
40840
|
}
|
|
40693
40841
|
const identity = await progress.execute(
|
|
40694
40842
|
"Validating AWS credentials",
|
|
@@ -40698,10 +40846,10 @@ async function smsVerifyNumber(options) {
|
|
|
40698
40846
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
40699
40847
|
if (!metadata?.services?.sms) {
|
|
40700
40848
|
progress.stop();
|
|
40701
|
-
|
|
40849
|
+
clack56.log.error("No SMS infrastructure found");
|
|
40702
40850
|
console.log(
|
|
40703
40851
|
`
|
|
40704
|
-
Run ${
|
|
40852
|
+
Run ${pc59.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
40705
40853
|
`
|
|
40706
40854
|
);
|
|
40707
40855
|
process.exit(1);
|
|
@@ -40715,19 +40863,19 @@ Run ${pc58.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
40715
40863
|
);
|
|
40716
40864
|
progress.stop();
|
|
40717
40865
|
if (!response.VerifiedDestinationNumbers || response.VerifiedDestinationNumbers.length === 0) {
|
|
40718
|
-
|
|
40866
|
+
clack56.log.info("No verified destination numbers found");
|
|
40719
40867
|
console.log(
|
|
40720
40868
|
`
|
|
40721
|
-
Run ${
|
|
40869
|
+
Run ${pc59.cyan("wraps sms verify-number")} to verify a number.
|
|
40722
40870
|
`
|
|
40723
40871
|
);
|
|
40724
40872
|
} else {
|
|
40725
40873
|
console.log("\n");
|
|
40726
|
-
|
|
40874
|
+
clack56.log.info(pc59.bold("Verified Destination Numbers:"));
|
|
40727
40875
|
console.log("");
|
|
40728
40876
|
for (const num of response.VerifiedDestinationNumbers) {
|
|
40729
|
-
const status2 = num.Status === "VERIFIED" ?
|
|
40730
|
-
console.log(` ${
|
|
40877
|
+
const status2 = num.Status === "VERIFIED" ? pc59.green("\u2713 Verified") : pc59.yellow("\u29D6 Pending");
|
|
40878
|
+
console.log(` ${pc59.cyan(num.DestinationPhoneNumber)} - ${status2}`);
|
|
40731
40879
|
}
|
|
40732
40880
|
console.log("");
|
|
40733
40881
|
}
|
|
@@ -40745,7 +40893,7 @@ Run ${pc58.cyan("wraps sms verify-number")} to verify a number.
|
|
|
40745
40893
|
});
|
|
40746
40894
|
return;
|
|
40747
40895
|
}
|
|
40748
|
-
|
|
40896
|
+
clack56.outro(pc59.green("Done!"));
|
|
40749
40897
|
return;
|
|
40750
40898
|
} catch (error) {
|
|
40751
40899
|
progress.stop();
|
|
@@ -40753,7 +40901,7 @@ Run ${pc58.cyan("wraps sms verify-number")} to verify a number.
|
|
|
40753
40901
|
trackError("SMS_LIST_VERIFIED_FAILED", "sms:verify-number:list", {
|
|
40754
40902
|
error: errorMessage
|
|
40755
40903
|
});
|
|
40756
|
-
|
|
40904
|
+
clack56.log.error(`Failed to list verified numbers: ${errorMessage}`);
|
|
40757
40905
|
process.exit(1);
|
|
40758
40906
|
}
|
|
40759
40907
|
}
|
|
@@ -40761,10 +40909,10 @@ Run ${pc58.cyan("wraps sms verify-number")} to verify a number.
|
|
|
40761
40909
|
const phoneNumber2 = options.phoneNumber;
|
|
40762
40910
|
if (!phoneNumber2) {
|
|
40763
40911
|
progress.stop();
|
|
40764
|
-
|
|
40912
|
+
clack56.log.error("Phone number is required for deletion");
|
|
40765
40913
|
console.log(
|
|
40766
40914
|
`
|
|
40767
|
-
Usage: ${
|
|
40915
|
+
Usage: ${pc59.cyan("wraps sms verify-number --delete --phone-number +14155551234")}
|
|
40768
40916
|
`
|
|
40769
40917
|
);
|
|
40770
40918
|
process.exit(1);
|
|
@@ -40778,7 +40926,7 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40778
40926
|
const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
|
|
40779
40927
|
if (!verifiedNumber?.VerifiedDestinationNumberId) {
|
|
40780
40928
|
progress.stop();
|
|
40781
|
-
|
|
40929
|
+
clack56.log.error(`Number ${phoneNumber2} is not in verified list`);
|
|
40782
40930
|
process.exit(1);
|
|
40783
40931
|
}
|
|
40784
40932
|
await progress.execute(`Removing ${phoneNumber2}`, async () => {
|
|
@@ -40789,7 +40937,7 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40789
40937
|
);
|
|
40790
40938
|
});
|
|
40791
40939
|
progress.stop();
|
|
40792
|
-
|
|
40940
|
+
clack56.log.success(`Removed ${pc59.cyan(phoneNumber2)} from verified list`);
|
|
40793
40941
|
trackCommand("sms:verify-number:delete", {
|
|
40794
40942
|
success: true,
|
|
40795
40943
|
duration_ms: Date.now() - startTime
|
|
@@ -40801,7 +40949,7 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40801
40949
|
});
|
|
40802
40950
|
return;
|
|
40803
40951
|
}
|
|
40804
|
-
|
|
40952
|
+
clack56.outro(pc59.green("Done!"));
|
|
40805
40953
|
return;
|
|
40806
40954
|
} catch (error) {
|
|
40807
40955
|
progress.stop();
|
|
@@ -40809,7 +40957,7 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40809
40957
|
trackError("SMS_DELETE_VERIFIED_FAILED", "sms:verify-number:delete", {
|
|
40810
40958
|
error: errorMessage
|
|
40811
40959
|
});
|
|
40812
|
-
|
|
40960
|
+
clack56.log.error(`Failed to delete verified number: ${errorMessage}`);
|
|
40813
40961
|
process.exit(1);
|
|
40814
40962
|
}
|
|
40815
40963
|
}
|
|
@@ -40822,7 +40970,7 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40822
40970
|
);
|
|
40823
40971
|
}
|
|
40824
40972
|
if (!phoneNumber) {
|
|
40825
|
-
const result = await
|
|
40973
|
+
const result = await clack56.text({
|
|
40826
40974
|
message: "Enter phone number to verify (E.164 format):",
|
|
40827
40975
|
placeholder: "+14155551234",
|
|
40828
40976
|
validate: (value) => {
|
|
@@ -40835,14 +40983,14 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40835
40983
|
return;
|
|
40836
40984
|
}
|
|
40837
40985
|
});
|
|
40838
|
-
if (
|
|
40839
|
-
|
|
40986
|
+
if (clack56.isCancel(result)) {
|
|
40987
|
+
clack56.cancel("Operation cancelled.");
|
|
40840
40988
|
process.exit(0);
|
|
40841
40989
|
}
|
|
40842
40990
|
phoneNumber = result;
|
|
40843
40991
|
} else if (!isValidPhoneNumber(phoneNumber)) {
|
|
40844
40992
|
progress.stop();
|
|
40845
|
-
|
|
40993
|
+
clack56.log.error(
|
|
40846
40994
|
`Invalid phone number format: ${phoneNumber}. Use E.164 format (e.g., +14155551234)`
|
|
40847
40995
|
);
|
|
40848
40996
|
process.exit(1);
|
|
@@ -40857,7 +41005,7 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40857
41005
|
const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
|
|
40858
41006
|
if (!verifiedNumber?.VerifiedDestinationNumberId) {
|
|
40859
41007
|
progress.stop();
|
|
40860
|
-
|
|
41008
|
+
clack56.log.error(
|
|
40861
41009
|
`Number ${phoneNumber} not found. Run without --code first.`
|
|
40862
41010
|
);
|
|
40863
41011
|
process.exit(1);
|
|
@@ -40872,12 +41020,12 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40872
41020
|
});
|
|
40873
41021
|
progress.stop();
|
|
40874
41022
|
console.log("\n");
|
|
40875
|
-
|
|
40876
|
-
|
|
41023
|
+
clack56.log.success(
|
|
41024
|
+
pc59.green(`Phone number ${pc59.cyan(phoneNumber)} verified!`)
|
|
40877
41025
|
);
|
|
40878
41026
|
console.log("");
|
|
40879
41027
|
console.log(
|
|
40880
|
-
`You can now send test messages to this number with ${
|
|
41028
|
+
`You can now send test messages to this number with ${pc59.cyan("wraps sms test")}`
|
|
40881
41029
|
);
|
|
40882
41030
|
trackCommand("sms:verify-number:confirm", {
|
|
40883
41031
|
success: true,
|
|
@@ -40890,23 +41038,23 @@ Usage: ${pc58.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
40890
41038
|
});
|
|
40891
41039
|
return;
|
|
40892
41040
|
}
|
|
40893
|
-
|
|
41041
|
+
clack56.outro(pc59.green("Verification complete!"));
|
|
40894
41042
|
return;
|
|
40895
41043
|
} catch (error) {
|
|
40896
41044
|
progress.stop();
|
|
40897
41045
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
40898
41046
|
if (errorMessage.includes("Invalid verification code")) {
|
|
40899
|
-
|
|
41047
|
+
clack56.log.error("Invalid verification code. Please try again.");
|
|
40900
41048
|
console.log(
|
|
40901
41049
|
`
|
|
40902
|
-
Run ${
|
|
41050
|
+
Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
|
|
40903
41051
|
`
|
|
40904
41052
|
);
|
|
40905
41053
|
} else {
|
|
40906
41054
|
trackError("SMS_VERIFY_CODE_FAILED", "sms:verify-number:confirm", {
|
|
40907
41055
|
error: errorMessage
|
|
40908
41056
|
});
|
|
40909
|
-
|
|
41057
|
+
clack56.log.error(`Verification failed: ${errorMessage}`);
|
|
40910
41058
|
}
|
|
40911
41059
|
process.exit(1);
|
|
40912
41060
|
}
|
|
@@ -40921,7 +41069,7 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
40921
41069
|
const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
|
|
40922
41070
|
if (!verifiedNumber?.VerifiedDestinationNumberId) {
|
|
40923
41071
|
progress.stop();
|
|
40924
|
-
|
|
41072
|
+
clack56.log.error(
|
|
40925
41073
|
`Number ${phoneNumber} not found. Run without --resend first.`
|
|
40926
41074
|
);
|
|
40927
41075
|
process.exit(1);
|
|
@@ -40935,11 +41083,11 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
40935
41083
|
);
|
|
40936
41084
|
});
|
|
40937
41085
|
progress.stop();
|
|
40938
|
-
|
|
41086
|
+
clack56.log.success(`Verification code resent to ${pc59.cyan(phoneNumber)}`);
|
|
40939
41087
|
console.log("");
|
|
40940
41088
|
console.log(
|
|
40941
41089
|
`Once you receive the code, run:
|
|
40942
|
-
${
|
|
41090
|
+
${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
|
|
40943
41091
|
);
|
|
40944
41092
|
trackCommand("sms:verify-number:resend", {
|
|
40945
41093
|
success: true,
|
|
@@ -40952,7 +41100,7 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
40952
41100
|
});
|
|
40953
41101
|
return;
|
|
40954
41102
|
}
|
|
40955
|
-
|
|
41103
|
+
clack56.outro(pc59.green("Code sent!"));
|
|
40956
41104
|
return;
|
|
40957
41105
|
} catch (error) {
|
|
40958
41106
|
progress.stop();
|
|
@@ -40960,7 +41108,7 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
40960
41108
|
trackError("SMS_RESEND_CODE_FAILED", "sms:verify-number:resend", {
|
|
40961
41109
|
error: errorMessage
|
|
40962
41110
|
});
|
|
40963
|
-
|
|
41111
|
+
clack56.log.error(`Failed to resend code: ${errorMessage}`);
|
|
40964
41112
|
process.exit(1);
|
|
40965
41113
|
}
|
|
40966
41114
|
}
|
|
@@ -40980,10 +41128,10 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
40980
41128
|
});
|
|
40981
41129
|
return;
|
|
40982
41130
|
}
|
|
40983
|
-
|
|
40984
|
-
`Number ${
|
|
41131
|
+
clack56.log.info(
|
|
41132
|
+
`Number ${pc59.cyan(phoneNumber)} is already verified and ready to use!`
|
|
40985
41133
|
);
|
|
40986
|
-
|
|
41134
|
+
clack56.outro(pc59.green("Done!"));
|
|
40987
41135
|
return;
|
|
40988
41136
|
}
|
|
40989
41137
|
if (existingNumber?.Status === "PENDING") {
|
|
@@ -41007,15 +41155,15 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41007
41155
|
});
|
|
41008
41156
|
return;
|
|
41009
41157
|
}
|
|
41010
|
-
|
|
41011
|
-
`Verification already in progress. New code sent to ${
|
|
41158
|
+
clack56.log.info(
|
|
41159
|
+
`Verification already in progress. New code sent to ${pc59.cyan(phoneNumber)}`
|
|
41012
41160
|
);
|
|
41013
41161
|
console.log("");
|
|
41014
41162
|
console.log(
|
|
41015
41163
|
`Once you receive the code, run:
|
|
41016
|
-
${
|
|
41164
|
+
${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
|
|
41017
41165
|
);
|
|
41018
|
-
|
|
41166
|
+
clack56.outro(pc59.green("Code sent!"));
|
|
41019
41167
|
return;
|
|
41020
41168
|
}
|
|
41021
41169
|
const createResponse = await progress.execute(
|
|
@@ -41036,18 +41184,18 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41036
41184
|
});
|
|
41037
41185
|
progress.stop();
|
|
41038
41186
|
console.log("\n");
|
|
41039
|
-
|
|
41040
|
-
`Verification code sent to ${
|
|
41187
|
+
clack56.log.success(
|
|
41188
|
+
`Verification code sent to ${pc59.cyan(phoneNumber)} via SMS`
|
|
41041
41189
|
);
|
|
41042
41190
|
console.log("");
|
|
41043
|
-
|
|
41191
|
+
clack56.note(
|
|
41044
41192
|
[
|
|
41045
41193
|
"1. Check your phone for the verification code",
|
|
41046
41194
|
"",
|
|
41047
41195
|
"2. Complete verification with:",
|
|
41048
|
-
` ${
|
|
41196
|
+
` ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`,
|
|
41049
41197
|
"",
|
|
41050
|
-
|
|
41198
|
+
pc59.dim("The code expires in 24 hours")
|
|
41051
41199
|
].join("\n"),
|
|
41052
41200
|
"Next Steps"
|
|
41053
41201
|
);
|
|
@@ -41063,22 +41211,22 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41063
41211
|
});
|
|
41064
41212
|
return;
|
|
41065
41213
|
}
|
|
41066
|
-
|
|
41214
|
+
clack56.outro(pc59.green("Verification started!"));
|
|
41067
41215
|
} catch (error) {
|
|
41068
41216
|
progress.stop();
|
|
41069
41217
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
41070
41218
|
if (errorMessage.includes("already exists")) {
|
|
41071
|
-
|
|
41219
|
+
clack56.log.error("This number is already being verified");
|
|
41072
41220
|
console.log(
|
|
41073
41221
|
`
|
|
41074
|
-
Run ${
|
|
41222
|
+
Run ${pc59.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
|
|
41075
41223
|
`
|
|
41076
41224
|
);
|
|
41077
41225
|
} else {
|
|
41078
41226
|
trackError("SMS_CREATE_VERIFIED_FAILED", "sms:verify-number:start", {
|
|
41079
41227
|
error: errorMessage
|
|
41080
41228
|
});
|
|
41081
|
-
|
|
41229
|
+
clack56.log.error(`Failed to start verification: ${errorMessage}`);
|
|
41082
41230
|
}
|
|
41083
41231
|
process.exit(1);
|
|
41084
41232
|
}
|
|
@@ -41087,88 +41235,88 @@ Run ${pc58.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
41087
41235
|
// src/commands/support.ts
|
|
41088
41236
|
init_esm_shims();
|
|
41089
41237
|
init_events();
|
|
41090
|
-
import * as
|
|
41091
|
-
import
|
|
41238
|
+
import * as clack57 from "@clack/prompts";
|
|
41239
|
+
import pc60 from "picocolors";
|
|
41092
41240
|
async function support() {
|
|
41093
41241
|
trackCommand("support", { success: true });
|
|
41094
|
-
|
|
41242
|
+
clack57.intro(pc60.bold("Get Help with Wraps"));
|
|
41095
41243
|
console.log();
|
|
41096
|
-
console.log(` ${
|
|
41244
|
+
console.log(` ${pc60.bold("Email:")} ${pc60.cyan("hey@wraps.sh")}`);
|
|
41097
41245
|
console.log(
|
|
41098
|
-
` ${
|
|
41246
|
+
` ${pc60.bold("GitHub:")} ${pc60.cyan("https://github.com/wraps-dev/wraps/issues")}`
|
|
41099
41247
|
);
|
|
41100
|
-
console.log(` ${
|
|
41248
|
+
console.log(` ${pc60.bold("Docs:")} ${pc60.cyan("https://wraps.dev/docs")}`);
|
|
41101
41249
|
console.log();
|
|
41102
|
-
console.log(
|
|
41250
|
+
console.log(pc60.dim(" Response time: Usually within 24 hours"));
|
|
41103
41251
|
console.log();
|
|
41104
41252
|
}
|
|
41105
41253
|
|
|
41106
41254
|
// src/commands/telemetry.ts
|
|
41107
41255
|
init_esm_shims();
|
|
41108
41256
|
init_client();
|
|
41109
|
-
import * as
|
|
41110
|
-
import
|
|
41257
|
+
import * as clack58 from "@clack/prompts";
|
|
41258
|
+
import pc61 from "picocolors";
|
|
41111
41259
|
async function telemetryEnable() {
|
|
41112
41260
|
const client = getTelemetryClient();
|
|
41113
41261
|
const override = client.enable();
|
|
41114
41262
|
if (override) {
|
|
41115
|
-
|
|
41263
|
+
clack58.log.warn(
|
|
41116
41264
|
"Telemetry enabled in config, but overridden by environment"
|
|
41117
41265
|
);
|
|
41118
|
-
console.log(` Reason: ${
|
|
41119
|
-
console.log(` Config: ${
|
|
41266
|
+
console.log(` Reason: ${pc61.yellow(override)}`);
|
|
41267
|
+
console.log(` Config: ${pc61.dim(client.getConfigPath())}`);
|
|
41120
41268
|
console.log();
|
|
41121
41269
|
} else {
|
|
41122
|
-
|
|
41123
|
-
console.log(` Config: ${
|
|
41270
|
+
clack58.log.success(pc61.green("Telemetry enabled"));
|
|
41271
|
+
console.log(` Config: ${pc61.dim(client.getConfigPath())}`);
|
|
41124
41272
|
console.log(`
|
|
41125
|
-
${
|
|
41273
|
+
${pc61.dim("Thank you for helping improve Wraps!")}
|
|
41126
41274
|
`);
|
|
41127
41275
|
}
|
|
41128
41276
|
}
|
|
41129
41277
|
async function telemetryDisable() {
|
|
41130
41278
|
const client = getTelemetryClient();
|
|
41131
41279
|
client.disable();
|
|
41132
|
-
|
|
41133
|
-
console.log(` Config: ${
|
|
41280
|
+
clack58.log.success(pc61.green("Telemetry disabled"));
|
|
41281
|
+
console.log(` Config: ${pc61.dim(client.getConfigPath())}`);
|
|
41134
41282
|
console.log(
|
|
41135
41283
|
`
|
|
41136
|
-
${
|
|
41284
|
+
${pc61.dim("You can re-enable with:")} wraps telemetry enable
|
|
41137
41285
|
`
|
|
41138
41286
|
);
|
|
41139
41287
|
}
|
|
41140
41288
|
async function telemetryStatus() {
|
|
41141
41289
|
const client = getTelemetryClient();
|
|
41142
|
-
|
|
41290
|
+
clack58.intro(pc61.bold("Telemetry Status"));
|
|
41143
41291
|
const override = client.getEnvOverride();
|
|
41144
|
-
const status2 = client.isEnabled() ?
|
|
41292
|
+
const status2 = client.isEnabled() ? pc61.green("Enabled") : pc61.red("Disabled");
|
|
41145
41293
|
console.log();
|
|
41146
|
-
console.log(` ${
|
|
41294
|
+
console.log(` ${pc61.bold("Status:")} ${status2}`);
|
|
41147
41295
|
if (!client.isEnabled() && override) {
|
|
41148
|
-
console.log(` ${
|
|
41296
|
+
console.log(` ${pc61.bold("Reason:")} ${pc61.yellow(override)}`);
|
|
41149
41297
|
}
|
|
41150
|
-
console.log(` ${
|
|
41298
|
+
console.log(` ${pc61.bold("Config file:")} ${pc61.dim(client.getConfigPath())}`);
|
|
41151
41299
|
if (client.isEnabled()) {
|
|
41152
41300
|
console.log();
|
|
41153
|
-
console.log(
|
|
41154
|
-
console.log(` ${
|
|
41301
|
+
console.log(pc61.bold(" How to opt-out:"));
|
|
41302
|
+
console.log(` ${pc61.cyan("wraps telemetry disable")}`);
|
|
41155
41303
|
console.log(
|
|
41156
|
-
` ${
|
|
41304
|
+
` ${pc61.dim("Or set:")} ${pc61.cyan("WRAPS_TELEMETRY_DISABLED=1")}`
|
|
41157
41305
|
);
|
|
41158
|
-
console.log(` ${
|
|
41306
|
+
console.log(` ${pc61.dim("Or set:")} ${pc61.cyan("DO_NOT_TRACK=1")}`);
|
|
41159
41307
|
} else {
|
|
41160
41308
|
console.log();
|
|
41161
|
-
console.log(
|
|
41162
|
-
console.log(` ${
|
|
41309
|
+
console.log(pc61.bold(" How to opt-in:"));
|
|
41310
|
+
console.log(` ${pc61.cyan("wraps telemetry enable")}`);
|
|
41163
41311
|
}
|
|
41164
41312
|
console.log();
|
|
41165
|
-
console.log(
|
|
41313
|
+
console.log(pc61.bold(" Debug mode:"));
|
|
41166
41314
|
console.log(
|
|
41167
|
-
` ${
|
|
41315
|
+
` ${pc61.dim("See what would be sent:")} ${pc61.cyan("WRAPS_TELEMETRY_DEBUG=1 wraps <command>")}`
|
|
41168
41316
|
);
|
|
41169
41317
|
console.log();
|
|
41170
41318
|
console.log(
|
|
41171
|
-
` ${
|
|
41319
|
+
` ${pc61.dim("Learn more:")} ${pc61.cyan("https://wraps.dev/docs/telemetry")}`
|
|
41172
41320
|
);
|
|
41173
41321
|
console.log();
|
|
41174
41322
|
}
|
|
@@ -41177,8 +41325,8 @@ async function telemetryStatus() {
|
|
|
41177
41325
|
init_esm_shims();
|
|
41178
41326
|
import { existsSync as existsSync18, mkdirSync as mkdirSync2, writeFileSync } from "fs";
|
|
41179
41327
|
import { join as join22 } from "path";
|
|
41180
|
-
import * as
|
|
41181
|
-
import
|
|
41328
|
+
import * as clack59 from "@clack/prompts";
|
|
41329
|
+
import pc62 from "picocolors";
|
|
41182
41330
|
var EXAMPLE_CASCADE_WORKFLOW = `import {
|
|
41183
41331
|
defineWorkflow,
|
|
41184
41332
|
sendEmail,
|
|
@@ -41273,30 +41421,30 @@ export default defineConfig({
|
|
|
41273
41421
|
});
|
|
41274
41422
|
`;
|
|
41275
41423
|
async function workflowInit(options = {}) {
|
|
41276
|
-
|
|
41424
|
+
clack59.intro(pc62.bgCyan(pc62.black(" wraps workflow init ")));
|
|
41277
41425
|
const wrapsDir = join22(process.cwd(), "wraps");
|
|
41278
41426
|
const workflowsDir = join22(wrapsDir, "workflows");
|
|
41279
41427
|
const configPath = join22(wrapsDir, "wraps.config.ts");
|
|
41280
41428
|
if (existsSync18(workflowsDir)) {
|
|
41281
|
-
|
|
41282
|
-
`Workflows directory already exists at ${
|
|
41429
|
+
clack59.log.info(
|
|
41430
|
+
`Workflows directory already exists at ${pc62.cyan("wraps/workflows/")}`
|
|
41283
41431
|
);
|
|
41284
41432
|
const files = existsSync18(join22(workflowsDir, "cart-recovery.ts")) || existsSync18(join22(workflowsDir, "welcome-sequence.ts"));
|
|
41285
41433
|
if (files && !options.yes) {
|
|
41286
|
-
const shouldContinue = await
|
|
41434
|
+
const shouldContinue = await clack59.confirm({
|
|
41287
41435
|
message: "Example files may already exist. Overwrite them?",
|
|
41288
41436
|
initialValue: false
|
|
41289
41437
|
});
|
|
41290
|
-
if (
|
|
41291
|
-
|
|
41438
|
+
if (clack59.isCancel(shouldContinue) || !shouldContinue) {
|
|
41439
|
+
clack59.log.info("Skipping file creation.");
|
|
41292
41440
|
showNextSteps2();
|
|
41293
|
-
|
|
41441
|
+
clack59.outro("Done!");
|
|
41294
41442
|
return;
|
|
41295
41443
|
}
|
|
41296
41444
|
}
|
|
41297
41445
|
}
|
|
41298
41446
|
try {
|
|
41299
|
-
const s =
|
|
41447
|
+
const s = clack59.spinner();
|
|
41300
41448
|
s.start("Creating workflows directory...");
|
|
41301
41449
|
mkdirSync2(workflowsDir, { recursive: true });
|
|
41302
41450
|
s.stop("Created wraps/workflows/");
|
|
@@ -41314,34 +41462,34 @@ async function workflowInit(options = {}) {
|
|
|
41314
41462
|
s.stop("Created 2 example workflows");
|
|
41315
41463
|
if (!existsSync18(configPath)) {
|
|
41316
41464
|
writeFileSync(configPath, EXAMPLE_CONFIG, "utf-8");
|
|
41317
|
-
|
|
41465
|
+
clack59.log.info(`Created ${pc62.cyan("wraps/wraps.config.ts")}`);
|
|
41318
41466
|
}
|
|
41319
|
-
|
|
41320
|
-
`${
|
|
41321
|
-
${
|
|
41322
|
-
${
|
|
41323
|
-
${
|
|
41467
|
+
clack59.log.success(
|
|
41468
|
+
`${pc62.bold("Workflows scaffolded!")} Created:
|
|
41469
|
+
${pc62.cyan("wraps/wraps.config.ts")} \u2014 Project config
|
|
41470
|
+
${pc62.cyan("wraps/workflows/cart-recovery.ts")} \u2014 Cross-channel cascade example
|
|
41471
|
+
${pc62.cyan("wraps/workflows/welcome-sequence.ts")} \u2014 Welcome series example`
|
|
41324
41472
|
);
|
|
41325
41473
|
showNextSteps2();
|
|
41326
|
-
|
|
41474
|
+
clack59.outro(pc62.green("Happy orchestrating!"));
|
|
41327
41475
|
} catch (error) {
|
|
41328
|
-
|
|
41476
|
+
clack59.log.error(
|
|
41329
41477
|
`Failed to scaffold workflows: ${error instanceof Error ? error.message : String(error)}`
|
|
41330
41478
|
);
|
|
41331
|
-
|
|
41479
|
+
clack59.outro(pc62.red("Scaffolding failed."));
|
|
41332
41480
|
process.exitCode = 1;
|
|
41333
41481
|
}
|
|
41334
41482
|
}
|
|
41335
41483
|
function showNextSteps2() {
|
|
41336
|
-
|
|
41337
|
-
`${
|
|
41484
|
+
clack59.log.info(
|
|
41485
|
+
`${pc62.bold("Next steps:")}
|
|
41338
41486
|
|
|
41339
|
-
1. Edit ${
|
|
41340
|
-
2. Edit your workflows in ${
|
|
41341
|
-
3. Validate: ${
|
|
41342
|
-
4. Push: ${
|
|
41487
|
+
1. Edit ${pc62.cyan("wraps/wraps.config.ts")} with your org slug and domain
|
|
41488
|
+
2. Edit your workflows in ${pc62.cyan("wraps/workflows/")}
|
|
41489
|
+
3. Validate: ${pc62.cyan("wraps email workflows validate")}
|
|
41490
|
+
4. Push: ${pc62.cyan("wraps email workflows push")}
|
|
41343
41491
|
|
|
41344
|
-
${
|
|
41492
|
+
${pc62.dim("Docs:")} ${pc62.underline("https://wraps.dev/docs/guides/orchestration")}`
|
|
41345
41493
|
);
|
|
41346
41494
|
}
|
|
41347
41495
|
|
|
@@ -41373,7 +41521,13 @@ var STRING_FLAGS = [
|
|
|
41373
41521
|
"template",
|
|
41374
41522
|
"workflow",
|
|
41375
41523
|
"org",
|
|
41376
|
-
"subdomain"
|
|
41524
|
+
"subdomain",
|
|
41525
|
+
"tier",
|
|
41526
|
+
"expires",
|
|
41527
|
+
"neon-api-key",
|
|
41528
|
+
"neon-org-id",
|
|
41529
|
+
"license-key",
|
|
41530
|
+
"app-url"
|
|
41377
41531
|
];
|
|
41378
41532
|
var BOOLEAN_FLAGS = [
|
|
41379
41533
|
"yes",
|
|
@@ -41529,205 +41683,208 @@ function showVersion() {
|
|
|
41529
41683
|
process.exit(0);
|
|
41530
41684
|
}
|
|
41531
41685
|
function showHelp() {
|
|
41532
|
-
|
|
41686
|
+
clack60.intro(pc64.bold(`WRAPS CLI v${VERSION}`));
|
|
41533
41687
|
console.log("Deploy AWS infrastructure to your account\n");
|
|
41534
41688
|
console.log("Usage: wraps [service] <command> [options]\n");
|
|
41535
41689
|
console.log("Services:");
|
|
41536
|
-
console.log(` ${
|
|
41690
|
+
console.log(` ${pc64.cyan("email")} Email infrastructure (AWS SES)`);
|
|
41691
|
+
console.log(
|
|
41692
|
+
` ${pc64.cyan("sms")} SMS infrastructure (AWS End User Messaging)`
|
|
41693
|
+
);
|
|
41537
41694
|
console.log(
|
|
41538
|
-
` ${
|
|
41695
|
+
` ${pc64.cyan("cdn")} CDN infrastructure (AWS S3 + CloudFront)`
|
|
41539
41696
|
);
|
|
41540
41697
|
console.log(
|
|
41541
|
-
` ${
|
|
41698
|
+
` ${pc64.cyan("selfhost")} Self-hosted Wraps control plane (enterprise)`
|
|
41542
41699
|
);
|
|
41543
41700
|
console.log(
|
|
41544
|
-
` ${
|
|
41701
|
+
` ${pc64.cyan("license")} License key management (Wraps team only)
|
|
41545
41702
|
`
|
|
41546
41703
|
);
|
|
41547
41704
|
console.log("Email Commands:");
|
|
41548
41705
|
console.log(
|
|
41549
|
-
` ${
|
|
41706
|
+
` ${pc64.cyan("email init")} Deploy new email infrastructure`
|
|
41550
41707
|
);
|
|
41551
41708
|
console.log(
|
|
41552
|
-
` ${
|
|
41709
|
+
` ${pc64.cyan("email check")} Check email deliverability for a domain`
|
|
41553
41710
|
);
|
|
41554
41711
|
console.log(
|
|
41555
|
-
` ${
|
|
41712
|
+
` ${pc64.cyan("email connect")} Connect to existing AWS SES`
|
|
41556
41713
|
);
|
|
41557
41714
|
console.log(
|
|
41558
|
-
` ${
|
|
41715
|
+
` ${pc64.cyan("email status")} Show email infrastructure details`
|
|
41559
41716
|
);
|
|
41560
|
-
console.log(` ${
|
|
41561
|
-
console.log(` ${
|
|
41717
|
+
console.log(` ${pc64.cyan("email test")} Send a test email`);
|
|
41718
|
+
console.log(` ${pc64.cyan("email verify")} Verify domain DNS records`);
|
|
41562
41719
|
console.log(
|
|
41563
|
-
` ${
|
|
41720
|
+
` ${pc64.cyan("email sync")} Apply CLI updates to infrastructure`
|
|
41564
41721
|
);
|
|
41565
|
-
console.log(` ${
|
|
41722
|
+
console.log(` ${pc64.cyan("email upgrade")} Add features`);
|
|
41566
41723
|
console.log(
|
|
41567
|
-
` ${
|
|
41724
|
+
` ${pc64.cyan("email restore")} Restore original configuration`
|
|
41568
41725
|
);
|
|
41569
41726
|
console.log(
|
|
41570
|
-
` ${
|
|
41727
|
+
` ${pc64.cyan("email destroy")} Remove email infrastructure`
|
|
41571
41728
|
);
|
|
41572
41729
|
console.log(
|
|
41573
|
-
` ${
|
|
41730
|
+
` ${pc64.cyan("email doctor")} Diagnose and clean up email infrastructure`
|
|
41574
41731
|
);
|
|
41575
|
-
console.log(` ${
|
|
41576
|
-
console.log(` ${
|
|
41577
|
-
console.log(` ${
|
|
41732
|
+
console.log(` ${pc64.cyan("email domains add")} Add a domain to SES`);
|
|
41733
|
+
console.log(` ${pc64.cyan("email domains list")} List all domains`);
|
|
41734
|
+
console.log(` ${pc64.cyan("email domains remove")} Remove a domain`);
|
|
41578
41735
|
console.log(
|
|
41579
|
-
` ${
|
|
41736
|
+
` ${pc64.cyan("email inbound init")} Enable inbound email receiving`
|
|
41580
41737
|
);
|
|
41581
|
-
console.log(` ${
|
|
41738
|
+
console.log(` ${pc64.cyan("email inbound status")} Show inbound email status`);
|
|
41582
41739
|
console.log(
|
|
41583
|
-
` ${
|
|
41740
|
+
` ${pc64.cyan("email inbound verify")} Verify inbound DNS records`
|
|
41584
41741
|
);
|
|
41585
41742
|
console.log(
|
|
41586
|
-
` ${
|
|
41743
|
+
` ${pc64.cyan("email inbound test")} Send test email and verify receipt`
|
|
41587
41744
|
);
|
|
41588
41745
|
console.log(
|
|
41589
|
-
` ${
|
|
41746
|
+
` ${pc64.cyan("email inbound destroy")} Remove inbound email infrastructure
|
|
41590
41747
|
`
|
|
41591
41748
|
);
|
|
41592
41749
|
console.log("Template Commands:");
|
|
41593
41750
|
console.log(
|
|
41594
|
-
` ${
|
|
41751
|
+
` ${pc64.cyan("email templates init")} Initialize templates-as-code`
|
|
41595
41752
|
);
|
|
41596
41753
|
console.log(
|
|
41597
|
-
` ${
|
|
41754
|
+
` ${pc64.cyan("email templates push")} Push templates to SES + dashboard`
|
|
41598
41755
|
);
|
|
41599
41756
|
console.log(
|
|
41600
|
-
` ${
|
|
41757
|
+
` ${pc64.cyan("email templates preview")} Preview templates in browser`
|
|
41601
41758
|
);
|
|
41602
41759
|
console.log(
|
|
41603
|
-
` ${
|
|
41760
|
+
` ${pc64.cyan("push")} ${pc64.dim("(alias for email templates push)")}
|
|
41604
41761
|
`
|
|
41605
41762
|
);
|
|
41606
41763
|
console.log("Workflow Commands:");
|
|
41607
41764
|
console.log(
|
|
41608
|
-
` ${
|
|
41765
|
+
` ${pc64.cyan("email workflows init")} Initialize workflows-as-code`
|
|
41609
41766
|
);
|
|
41610
41767
|
console.log(
|
|
41611
|
-
` ${
|
|
41768
|
+
` ${pc64.cyan("email workflows validate")} Validate workflow files`
|
|
41612
41769
|
);
|
|
41613
41770
|
console.log(
|
|
41614
|
-
` ${
|
|
41771
|
+
` ${pc64.cyan("email workflows push")} Push workflows to dashboard
|
|
41615
41772
|
`
|
|
41616
41773
|
);
|
|
41617
41774
|
console.log("SMS Commands:");
|
|
41618
|
-
console.log(` ${
|
|
41775
|
+
console.log(` ${pc64.cyan("sms init")} Deploy SMS infrastructure`);
|
|
41619
41776
|
console.log(
|
|
41620
|
-
` ${
|
|
41777
|
+
` ${pc64.cyan("sms status")} Show SMS infrastructure details`
|
|
41621
41778
|
);
|
|
41622
|
-
console.log(` ${
|
|
41779
|
+
console.log(` ${pc64.cyan("sms test")} Send a test SMS message`);
|
|
41623
41780
|
console.log(
|
|
41624
|
-
` ${
|
|
41781
|
+
` ${pc64.cyan("sms verify-number")} Verify a destination phone number`
|
|
41625
41782
|
);
|
|
41626
41783
|
console.log(
|
|
41627
|
-
` ${
|
|
41784
|
+
` ${pc64.cyan("sms sync")} Sync infrastructure (update Lambda, etc.)`
|
|
41628
41785
|
);
|
|
41629
|
-
console.log(` ${
|
|
41630
|
-
console.log(` ${
|
|
41786
|
+
console.log(` ${pc64.cyan("sms upgrade")} Upgrade SMS features`);
|
|
41787
|
+
console.log(` ${pc64.cyan("sms register")} Register toll-free number`);
|
|
41631
41788
|
console.log(
|
|
41632
|
-
` ${
|
|
41789
|
+
` ${pc64.cyan("sms destroy")} Remove SMS infrastructure
|
|
41633
41790
|
`
|
|
41634
41791
|
);
|
|
41635
41792
|
console.log("CDN Commands:");
|
|
41636
41793
|
console.log(
|
|
41637
|
-
` ${
|
|
41794
|
+
` ${pc64.cyan("cdn init")} Deploy CDN infrastructure (S3 + CloudFront)`
|
|
41638
41795
|
);
|
|
41639
41796
|
console.log(
|
|
41640
|
-
` ${
|
|
41797
|
+
` ${pc64.cyan("cdn status")} Show CDN infrastructure details`
|
|
41641
41798
|
);
|
|
41642
41799
|
console.log(
|
|
41643
|
-
` ${
|
|
41800
|
+
` ${pc64.cyan("cdn verify")} Check DNS and certificate status`
|
|
41644
41801
|
);
|
|
41645
41802
|
console.log(
|
|
41646
|
-
` ${
|
|
41803
|
+
` ${pc64.cyan("cdn upgrade")} Add custom domain after cert validation`
|
|
41647
41804
|
);
|
|
41648
41805
|
console.log(
|
|
41649
|
-
` ${
|
|
41806
|
+
` ${pc64.cyan("cdn sync")} Sync infrastructure with current config`
|
|
41650
41807
|
);
|
|
41651
41808
|
console.log(
|
|
41652
|
-
` ${
|
|
41809
|
+
` ${pc64.cyan("cdn destroy")} Remove CDN infrastructure
|
|
41653
41810
|
`
|
|
41654
41811
|
);
|
|
41655
41812
|
console.log("Self-Hosted Commands:");
|
|
41656
41813
|
console.log(
|
|
41657
|
-
` ${
|
|
41814
|
+
` ${pc64.cyan("selfhost deploy")} Deploy Wraps API to your AWS account`
|
|
41658
41815
|
);
|
|
41659
41816
|
console.log(
|
|
41660
|
-
` ${
|
|
41817
|
+
` ${pc64.cyan("selfhost upgrade")} Rebuild and redeploy the self-hosted API`
|
|
41661
41818
|
);
|
|
41662
41819
|
console.log(
|
|
41663
|
-
` ${
|
|
41820
|
+
` ${pc64.cyan("selfhost status")} Show self-hosted deployment details
|
|
41664
41821
|
`
|
|
41665
41822
|
);
|
|
41666
41823
|
console.log("Local Development:");
|
|
41667
41824
|
console.log(
|
|
41668
|
-
` ${
|
|
41825
|
+
` ${pc64.cyan("console")} Start local web console
|
|
41669
41826
|
`
|
|
41670
41827
|
);
|
|
41671
41828
|
console.log("Platform:");
|
|
41672
41829
|
console.log(
|
|
41673
|
-
` ${
|
|
41830
|
+
` ${pc64.cyan("platform")} Show platform info and pricing`
|
|
41674
41831
|
);
|
|
41675
41832
|
console.log(
|
|
41676
|
-
` ${
|
|
41833
|
+
` ${pc64.cyan("platform connect")} Connect to Wraps Platform (events + IAM)`
|
|
41677
41834
|
);
|
|
41678
41835
|
console.log(
|
|
41679
|
-
` ${
|
|
41836
|
+
` ${pc64.cyan("platform update-role")} Update platform IAM permissions
|
|
41680
41837
|
`
|
|
41681
41838
|
);
|
|
41682
41839
|
console.log("Auth:");
|
|
41683
41840
|
console.log(
|
|
41684
|
-
` ${
|
|
41841
|
+
` ${pc64.cyan("auth login")} Sign in to wraps.dev (device flow)`
|
|
41685
41842
|
);
|
|
41686
|
-
console.log(` ${
|
|
41843
|
+
console.log(` ${pc64.cyan("auth status")} Show current auth state`);
|
|
41687
41844
|
console.log(
|
|
41688
|
-
` ${
|
|
41845
|
+
` ${pc64.cyan("auth logout")} Sign out and remove stored token
|
|
41689
41846
|
`
|
|
41690
41847
|
);
|
|
41691
41848
|
console.log("AWS Setup:");
|
|
41692
41849
|
console.log(
|
|
41693
|
-
` ${
|
|
41850
|
+
` ${pc64.cyan("aws setup")} Interactive AWS setup wizard`
|
|
41694
41851
|
);
|
|
41695
41852
|
console.log(
|
|
41696
|
-
` ${
|
|
41853
|
+
` ${pc64.cyan("aws doctor")} Diagnose AWS configuration issues
|
|
41697
41854
|
`
|
|
41698
41855
|
);
|
|
41699
41856
|
console.log("Global Commands:");
|
|
41700
|
-
console.log(` ${
|
|
41701
|
-
console.log(` ${
|
|
41702
|
-
console.log(` ${
|
|
41703
|
-
console.log(` ${
|
|
41857
|
+
console.log(` ${pc64.cyan("status")} Show overview of all services`);
|
|
41858
|
+
console.log(` ${pc64.cyan("destroy")} Remove deployed infrastructure`);
|
|
41859
|
+
console.log(` ${pc64.cyan("permissions")} Show required AWS IAM permissions`);
|
|
41860
|
+
console.log(` ${pc64.cyan("completion")} Generate shell completion script`);
|
|
41704
41861
|
console.log(
|
|
41705
|
-
` ${
|
|
41862
|
+
` ${pc64.cyan("telemetry")} Manage anonymous telemetry settings`
|
|
41706
41863
|
);
|
|
41707
|
-
console.log(` ${
|
|
41708
|
-
console.log(` ${
|
|
41864
|
+
console.log(` ${pc64.cyan("update")} Update CLI to latest version`);
|
|
41865
|
+
console.log(` ${pc64.cyan("news")} Show recent Wraps updates`);
|
|
41709
41866
|
console.log(
|
|
41710
|
-
` ${
|
|
41867
|
+
` ${pc64.cyan("support")} Get help and support contact info
|
|
41711
41868
|
`
|
|
41712
41869
|
);
|
|
41713
41870
|
console.log("Options:");
|
|
41714
41871
|
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(` ${
|
|
41872
|
+
` ${pc64.dim("-p, --provider")} Hosting provider (vercel, aws, railway, other)`
|
|
41873
|
+
);
|
|
41874
|
+
console.log(` ${pc64.dim("-r, --region")} AWS region`);
|
|
41875
|
+
console.log(` ${pc64.dim("-d, --domain")} Domain name`);
|
|
41876
|
+
console.log(` ${pc64.dim("--account")} AWS account ID or alias`);
|
|
41877
|
+
console.log(` ${pc64.dim("--preset")} Configuration preset`);
|
|
41878
|
+
console.log(` ${pc64.dim("--token")} API key or token for auth`);
|
|
41879
|
+
console.log(` ${pc64.dim("-y, --yes")} Skip confirmation prompts`);
|
|
41880
|
+
console.log(` ${pc64.dim("-f, --force")} Force destructive operations`);
|
|
41724
41881
|
console.log(
|
|
41725
|
-
` ${
|
|
41882
|
+
` ${pc64.dim("--preview")} Preview changes without deploying`
|
|
41726
41883
|
);
|
|
41727
|
-
console.log(` ${
|
|
41884
|
+
console.log(` ${pc64.dim("-v, --version")} Show version number
|
|
41728
41885
|
`);
|
|
41729
41886
|
console.log(
|
|
41730
|
-
`Run ${
|
|
41887
|
+
`Run ${pc64.cyan("wraps <service> <command> --help")} for more information.
|
|
41731
41888
|
`
|
|
41732
41889
|
);
|
|
41733
41890
|
}
|
|
@@ -41749,27 +41906,27 @@ if (!primaryCommand) {
|
|
|
41749
41906
|
const telemetry = getTelemetryClient();
|
|
41750
41907
|
if (telemetry.shouldShowNotification()) {
|
|
41751
41908
|
console.log();
|
|
41752
|
-
|
|
41909
|
+
clack60.log.info(pc64.bold("Anonymous Telemetry"));
|
|
41753
41910
|
console.log(
|
|
41754
|
-
` Wraps collects ${
|
|
41911
|
+
` Wraps collects ${pc64.cyan("anonymous usage data")} to improve the CLI.`
|
|
41755
41912
|
);
|
|
41756
41913
|
console.log(
|
|
41757
|
-
` We ${
|
|
41914
|
+
` We ${pc64.bold("never")} collect: domains, AWS credentials, email content, or PII.`
|
|
41758
41915
|
);
|
|
41759
41916
|
console.log(
|
|
41760
|
-
` We ${
|
|
41917
|
+
` We ${pc64.bold("only")} collect: command names, success/failure, CLI version, OS.`
|
|
41761
41918
|
);
|
|
41762
41919
|
console.log();
|
|
41763
|
-
console.log(` Opt-out anytime: ${
|
|
41764
|
-
console.log(` Or set: ${
|
|
41765
|
-
console.log(` Learn more: ${
|
|
41920
|
+
console.log(` Opt-out anytime: ${pc64.cyan("wraps telemetry disable")}`);
|
|
41921
|
+
console.log(` Or set: ${pc64.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
|
|
41922
|
+
console.log(` Learn more: ${pc64.cyan("https://wraps.dev/docs")}`);
|
|
41766
41923
|
console.log();
|
|
41767
41924
|
telemetry.markNotificationShown();
|
|
41768
41925
|
}
|
|
41769
41926
|
trackCommand("interactive:menu", { success: true, duration_ms: 0 });
|
|
41770
|
-
|
|
41927
|
+
clack60.intro(pc64.bold(`WRAPS CLI v${VERSION}`));
|
|
41771
41928
|
console.log(" Deploy AWS infrastructure to your account.\n");
|
|
41772
|
-
const action = await
|
|
41929
|
+
const action = await clack60.select({
|
|
41773
41930
|
message: "What would you like to do?",
|
|
41774
41931
|
options: [
|
|
41775
41932
|
{
|
|
@@ -41819,13 +41976,13 @@ if (!primaryCommand) {
|
|
|
41819
41976
|
}
|
|
41820
41977
|
]
|
|
41821
41978
|
});
|
|
41822
|
-
if (
|
|
41979
|
+
if (clack60.isCancel(action)) {
|
|
41823
41980
|
trackCommand("interactive:cancel", {
|
|
41824
41981
|
success: true,
|
|
41825
41982
|
duration_ms: Date.now() - startTime
|
|
41826
41983
|
});
|
|
41827
41984
|
await telemetry.shutdown();
|
|
41828
|
-
|
|
41985
|
+
clack60.cancel("Operation cancelled.");
|
|
41829
41986
|
process.exit(0);
|
|
41830
41987
|
}
|
|
41831
41988
|
trackCommand(`interactive:${action}`, {
|
|
@@ -41905,20 +42062,20 @@ async function run() {
|
|
|
41905
42062
|
const telemetry = getTelemetryClient();
|
|
41906
42063
|
if (telemetry.shouldShowNotification()) {
|
|
41907
42064
|
console.log();
|
|
41908
|
-
|
|
42065
|
+
clack60.log.info(pc64.bold("Anonymous Telemetry"));
|
|
41909
42066
|
console.log(
|
|
41910
|
-
` Wraps collects ${
|
|
42067
|
+
` Wraps collects ${pc64.cyan("anonymous usage data")} to improve the CLI.`
|
|
41911
42068
|
);
|
|
41912
42069
|
console.log(
|
|
41913
|
-
` We ${
|
|
42070
|
+
` We ${pc64.bold("never")} collect: domains, AWS credentials, email content, or PII.`
|
|
41914
42071
|
);
|
|
41915
42072
|
console.log(
|
|
41916
|
-
` We ${
|
|
42073
|
+
` We ${pc64.bold("only")} collect: command names, success/failure, CLI version, OS.`
|
|
41917
42074
|
);
|
|
41918
42075
|
console.log();
|
|
41919
|
-
console.log(` Opt-out anytime: ${
|
|
41920
|
-
console.log(` Or set: ${
|
|
41921
|
-
console.log(` Learn more: ${
|
|
42076
|
+
console.log(` Opt-out anytime: ${pc64.cyan("wraps telemetry disable")}`);
|
|
42077
|
+
console.log(` Or set: ${pc64.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
|
|
42078
|
+
console.log(` Learn more: ${pc64.cyan("https://wraps.dev/docs")}`);
|
|
41922
42079
|
console.log();
|
|
41923
42080
|
telemetry.markNotificationShown();
|
|
41924
42081
|
}
|
|
@@ -42002,10 +42159,10 @@ async function run() {
|
|
|
42002
42159
|
break;
|
|
42003
42160
|
case "verify": {
|
|
42004
42161
|
if (!flags.domain) {
|
|
42005
|
-
|
|
42162
|
+
clack60.log.error("--domain flag is required");
|
|
42006
42163
|
console.log(
|
|
42007
42164
|
`
|
|
42008
|
-
Usage: ${
|
|
42165
|
+
Usage: ${pc64.cyan("wraps email verify --domain yourapp.com")}
|
|
42009
42166
|
`
|
|
42010
42167
|
);
|
|
42011
42168
|
throw new Error("Missing required flag: --domain");
|
|
@@ -42077,12 +42234,12 @@ Usage: ${pc63.cyan("wraps email verify --domain yourapp.com")}
|
|
|
42077
42234
|
});
|
|
42078
42235
|
break;
|
|
42079
42236
|
default:
|
|
42080
|
-
|
|
42237
|
+
clack60.log.error(
|
|
42081
42238
|
`Unknown inbound command: ${inboundSubCommand || "(none)"}`
|
|
42082
42239
|
);
|
|
42083
42240
|
console.log(
|
|
42084
42241
|
`
|
|
42085
|
-
Available commands: ${
|
|
42242
|
+
Available commands: ${pc64.cyan("init")}, ${pc64.cyan("destroy")}, ${pc64.cyan("status")}, ${pc64.cyan("verify")}, ${pc64.cyan("test")}, ${pc64.cyan("add")}, ${pc64.cyan("remove")}
|
|
42086
42243
|
`
|
|
42087
42244
|
);
|
|
42088
42245
|
throw new Error(
|
|
@@ -42134,12 +42291,12 @@ Available commands: ${pc63.cyan("init")}, ${pc63.cyan("destroy")}, ${pc63.cyan("
|
|
|
42134
42291
|
break;
|
|
42135
42292
|
}
|
|
42136
42293
|
default:
|
|
42137
|
-
|
|
42294
|
+
clack60.log.error(
|
|
42138
42295
|
`Unknown reply command: ${replySubCommand || "(none)"}`
|
|
42139
42296
|
);
|
|
42140
42297
|
console.log(
|
|
42141
42298
|
`
|
|
42142
|
-
Available commands: ${
|
|
42299
|
+
Available commands: ${pc64.cyan("init")}, ${pc64.cyan("rotate")}, ${pc64.cyan("status")}, ${pc64.cyan("destroy")}, ${pc64.cyan("decode")}
|
|
42143
42300
|
`
|
|
42144
42301
|
);
|
|
42145
42302
|
throw new Error(
|
|
@@ -42164,10 +42321,10 @@ Available commands: ${pc63.cyan("init")}, ${pc63.cyan("rotate")}, ${pc63.cyan("s
|
|
|
42164
42321
|
break;
|
|
42165
42322
|
case "verify": {
|
|
42166
42323
|
if (!flags.domain) {
|
|
42167
|
-
|
|
42324
|
+
clack60.log.error("--domain flag is required");
|
|
42168
42325
|
console.log(
|
|
42169
42326
|
`
|
|
42170
|
-
Usage: ${
|
|
42327
|
+
Usage: ${pc64.cyan("wraps email domains verify --domain yourapp.com")}
|
|
42171
42328
|
`
|
|
42172
42329
|
);
|
|
42173
42330
|
throw new Error("Missing required flag: --domain");
|
|
@@ -42177,10 +42334,10 @@ Usage: ${pc63.cyan("wraps email domains verify --domain yourapp.com")}
|
|
|
42177
42334
|
}
|
|
42178
42335
|
case "get-dkim": {
|
|
42179
42336
|
if (!flags.domain) {
|
|
42180
|
-
|
|
42337
|
+
clack60.log.error("--domain flag is required");
|
|
42181
42338
|
console.log(
|
|
42182
42339
|
`
|
|
42183
|
-
Usage: ${
|
|
42340
|
+
Usage: ${pc64.cyan("wraps email domains get-dkim --domain yourapp.com")}
|
|
42184
42341
|
`
|
|
42185
42342
|
);
|
|
42186
42343
|
throw new Error("Missing required flag: --domain");
|
|
@@ -42190,10 +42347,10 @@ Usage: ${pc63.cyan("wraps email domains get-dkim --domain yourapp.com")}
|
|
|
42190
42347
|
}
|
|
42191
42348
|
case "remove": {
|
|
42192
42349
|
if (!flags.domain) {
|
|
42193
|
-
|
|
42350
|
+
clack60.log.error("--domain flag is required");
|
|
42194
42351
|
console.log(
|
|
42195
42352
|
`
|
|
42196
|
-
Usage: ${
|
|
42353
|
+
Usage: ${pc64.cyan("wraps email domains remove --domain yourapp.com --force")}
|
|
42197
42354
|
`
|
|
42198
42355
|
);
|
|
42199
42356
|
throw new Error("Missing required flag: --domain");
|
|
@@ -42223,12 +42380,12 @@ Usage: ${pc63.cyan("wraps email domains remove --domain yourapp.com --force")}
|
|
|
42223
42380
|
break;
|
|
42224
42381
|
}
|
|
42225
42382
|
default:
|
|
42226
|
-
|
|
42383
|
+
clack60.log.error(
|
|
42227
42384
|
`Unknown domains command: ${domainsSubCommand || "(none)"}`
|
|
42228
42385
|
);
|
|
42229
42386
|
console.log(
|
|
42230
42387
|
`
|
|
42231
|
-
Available commands: ${
|
|
42388
|
+
Available commands: ${pc64.cyan("add")}, ${pc64.cyan("list")}, ${pc64.cyan("verify")}, ${pc64.cyan("get-dkim")}, ${pc64.cyan("remove")}, ${pc64.cyan("config")}
|
|
42232
42389
|
`
|
|
42233
42390
|
);
|
|
42234
42391
|
throw new Error(
|
|
@@ -42270,12 +42427,12 @@ Available commands: ${pc63.cyan("add")}, ${pc63.cyan("list")}, ${pc63.cyan("veri
|
|
|
42270
42427
|
});
|
|
42271
42428
|
break;
|
|
42272
42429
|
default:
|
|
42273
|
-
|
|
42430
|
+
clack60.log.error(
|
|
42274
42431
|
`Unknown templates command: ${templatesSubCommand || "(none)"}`
|
|
42275
42432
|
);
|
|
42276
42433
|
console.log(
|
|
42277
42434
|
`
|
|
42278
|
-
Available commands: ${
|
|
42435
|
+
Available commands: ${pc64.cyan("init")}, ${pc64.cyan("push")}, ${pc64.cyan("preview")}
|
|
42279
42436
|
`
|
|
42280
42437
|
);
|
|
42281
42438
|
throw new Error(
|
|
@@ -42314,12 +42471,12 @@ Available commands: ${pc63.cyan("init")}, ${pc63.cyan("push")}, ${pc63.cyan("pre
|
|
|
42314
42471
|
});
|
|
42315
42472
|
break;
|
|
42316
42473
|
default:
|
|
42317
|
-
|
|
42474
|
+
clack60.log.error(
|
|
42318
42475
|
`Unknown workflows command: ${workflowsSubCommand || "(none)"}`
|
|
42319
42476
|
);
|
|
42320
42477
|
console.log(
|
|
42321
42478
|
`
|
|
42322
|
-
Available commands: ${
|
|
42479
|
+
Available commands: ${pc64.cyan("init")}, ${pc64.cyan("validate")}, ${pc64.cyan("push")}
|
|
42323
42480
|
`
|
|
42324
42481
|
);
|
|
42325
42482
|
throw new Error(
|
|
@@ -42344,10 +42501,10 @@ Available commands: ${pc63.cyan("init")}, ${pc63.cyan("validate")}, ${pc63.cyan(
|
|
|
42344
42501
|
});
|
|
42345
42502
|
break;
|
|
42346
42503
|
default:
|
|
42347
|
-
|
|
42504
|
+
clack60.log.error(`Unknown email command: ${subCommand}`);
|
|
42348
42505
|
console.log(
|
|
42349
42506
|
`
|
|
42350
|
-
Run ${
|
|
42507
|
+
Run ${pc64.cyan("wraps --help")} for available commands.
|
|
42351
42508
|
`
|
|
42352
42509
|
);
|
|
42353
42510
|
throw new Error(`Unknown email command: ${subCommand}`);
|
|
@@ -42361,14 +42518,41 @@ Run ${pc63.cyan("wraps --help")} for available commands.
|
|
|
42361
42518
|
});
|
|
42362
42519
|
return;
|
|
42363
42520
|
}
|
|
42521
|
+
if (primaryCommand === "license" && subCommand) {
|
|
42522
|
+
switch (subCommand) {
|
|
42523
|
+
case "generate":
|
|
42524
|
+
await licenseGenerate({
|
|
42525
|
+
// baseline:allow-no-region
|
|
42526
|
+
tier: flags.tier,
|
|
42527
|
+
expires: flags.expires,
|
|
42528
|
+
json: flags.json
|
|
42529
|
+
});
|
|
42530
|
+
break;
|
|
42531
|
+
default:
|
|
42532
|
+
clack60.log.error(`Unknown license command: ${subCommand}`);
|
|
42533
|
+
console.log(
|
|
42534
|
+
`
|
|
42535
|
+
Run ${pc64.cyan("wraps --help")} for available commands.
|
|
42536
|
+
`
|
|
42537
|
+
);
|
|
42538
|
+
throw new Error(`Unknown license command: ${subCommand}`);
|
|
42539
|
+
}
|
|
42540
|
+
trackCommand(`license:${subCommand}`, {
|
|
42541
|
+
success: true,
|
|
42542
|
+
duration_ms: Date.now() - startTime,
|
|
42543
|
+
service: "license"
|
|
42544
|
+
});
|
|
42545
|
+
return;
|
|
42546
|
+
}
|
|
42364
42547
|
if (primaryCommand === "selfhost" && subCommand) {
|
|
42365
42548
|
switch (subCommand) {
|
|
42366
42549
|
case "deploy":
|
|
42367
42550
|
await selfhostDeploy({
|
|
42368
42551
|
region: flags.region,
|
|
42369
|
-
neonApiKey: flags
|
|
42370
|
-
|
|
42371
|
-
|
|
42552
|
+
neonApiKey: flags.neonApiKey,
|
|
42553
|
+
neonOrgId: flags.neonOrgId,
|
|
42554
|
+
licenseKey: flags.licenseKey,
|
|
42555
|
+
appUrl: flags.appUrl,
|
|
42372
42556
|
yes: flags.yes,
|
|
42373
42557
|
preview: flags.preview,
|
|
42374
42558
|
json: flags.json
|
|
@@ -42389,10 +42573,10 @@ Run ${pc63.cyan("wraps --help")} for available commands.
|
|
|
42389
42573
|
});
|
|
42390
42574
|
break;
|
|
42391
42575
|
default:
|
|
42392
|
-
|
|
42576
|
+
clack60.log.error(`Unknown selfhost command: ${subCommand}`);
|
|
42393
42577
|
console.log(
|
|
42394
42578
|
`
|
|
42395
|
-
Run ${
|
|
42579
|
+
Run ${pc64.cyan("wraps --help")} for available commands.
|
|
42396
42580
|
`
|
|
42397
42581
|
);
|
|
42398
42582
|
throw new Error(`Unknown selfhost command: ${subCommand}`);
|
|
@@ -42472,10 +42656,10 @@ Run ${pc63.cyan("wraps --help")} for available commands.
|
|
|
42472
42656
|
});
|
|
42473
42657
|
break;
|
|
42474
42658
|
default:
|
|
42475
|
-
|
|
42659
|
+
clack60.log.error(`Unknown sms command: ${subCommand}`);
|
|
42476
42660
|
console.log(
|
|
42477
42661
|
`
|
|
42478
|
-
Run ${
|
|
42662
|
+
Run ${pc64.cyan("wraps --help")} for available commands.
|
|
42479
42663
|
`
|
|
42480
42664
|
);
|
|
42481
42665
|
throw new Error(`Unknown sms command: ${subCommand}`);
|
|
@@ -42536,10 +42720,10 @@ Run ${pc63.cyan("wraps --help")} for available commands.
|
|
|
42536
42720
|
});
|
|
42537
42721
|
break;
|
|
42538
42722
|
default:
|
|
42539
|
-
|
|
42723
|
+
clack60.log.error(`Unknown cdn command: ${subCommand}`);
|
|
42540
42724
|
console.log(
|
|
42541
42725
|
`
|
|
42542
|
-
Run ${
|
|
42726
|
+
Run ${pc64.cyan("wraps --help")} for available commands.
|
|
42543
42727
|
`
|
|
42544
42728
|
);
|
|
42545
42729
|
throw new Error(`Unknown cdn command: ${subCommand}`);
|
|
@@ -42561,13 +42745,13 @@ Run ${pc63.cyan("wraps --help")} for available commands.
|
|
|
42561
42745
|
});
|
|
42562
42746
|
break;
|
|
42563
42747
|
default:
|
|
42564
|
-
|
|
42748
|
+
clack60.log.error(
|
|
42565
42749
|
`Unknown workflow command: ${subCommand || "(none)"}`
|
|
42566
42750
|
);
|
|
42567
42751
|
console.log(`
|
|
42568
|
-
Available commands: ${
|
|
42752
|
+
Available commands: ${pc64.cyan("init")}
|
|
42569
42753
|
`);
|
|
42570
|
-
console.log(`Run ${
|
|
42754
|
+
console.log(`Run ${pc64.cyan("wraps --help")} for more information.
|
|
42571
42755
|
`);
|
|
42572
42756
|
throw new Error(
|
|
42573
42757
|
`Unknown workflow command: ${subCommand || "(none)"}`
|
|
@@ -42609,14 +42793,14 @@ Available commands: ${pc63.cyan("init")}
|
|
|
42609
42793
|
});
|
|
42610
42794
|
break;
|
|
42611
42795
|
default:
|
|
42612
|
-
|
|
42796
|
+
clack60.log.error(`Unknown platform command: ${subCommand}`);
|
|
42613
42797
|
console.log(
|
|
42614
42798
|
`
|
|
42615
|
-
Available commands: ${
|
|
42799
|
+
Available commands: ${pc64.cyan("connect")}, ${pc64.cyan("update-role")}
|
|
42616
42800
|
`
|
|
42617
42801
|
);
|
|
42618
42802
|
console.log(
|
|
42619
|
-
`Run ${
|
|
42803
|
+
`Run ${pc64.cyan("wraps platform")} for more information.
|
|
42620
42804
|
`
|
|
42621
42805
|
);
|
|
42622
42806
|
throw new Error(`Unknown platform command: ${subCommand}`);
|
|
@@ -42641,10 +42825,10 @@ Available commands: ${pc63.cyan("connect")}, ${pc63.cyan("update-role")}
|
|
|
42641
42825
|
await logout();
|
|
42642
42826
|
break;
|
|
42643
42827
|
default:
|
|
42644
|
-
|
|
42828
|
+
clack60.log.error(`Unknown auth command: ${subCommand || "(none)"}`);
|
|
42645
42829
|
console.log(
|
|
42646
42830
|
`
|
|
42647
|
-
Available commands: ${
|
|
42831
|
+
Available commands: ${pc64.cyan("login")}, ${pc64.cyan("status")}, ${pc64.cyan("logout")}
|
|
42648
42832
|
`
|
|
42649
42833
|
);
|
|
42650
42834
|
throw new Error(`Unknown auth command: ${subCommand || "(none)"}`);
|
|
@@ -42662,13 +42846,13 @@ Available commands: ${pc63.cyan("login")}, ${pc63.cyan("status")}, ${pc63.cyan("
|
|
|
42662
42846
|
await doctor();
|
|
42663
42847
|
break;
|
|
42664
42848
|
default:
|
|
42665
|
-
|
|
42849
|
+
clack60.log.error(`Unknown aws command: ${subCommand}`);
|
|
42666
42850
|
console.log(
|
|
42667
42851
|
`
|
|
42668
|
-
Available commands: ${
|
|
42852
|
+
Available commands: ${pc64.cyan("setup")}, ${pc64.cyan("doctor")}
|
|
42669
42853
|
`
|
|
42670
42854
|
);
|
|
42671
|
-
console.log(`Run ${
|
|
42855
|
+
console.log(`Run ${pc64.cyan("wraps --help")} for more information.
|
|
42672
42856
|
`);
|
|
42673
42857
|
throw new Error(`Unknown aws command: ${subCommand}`);
|
|
42674
42858
|
}
|
|
@@ -42749,10 +42933,10 @@ Available commands: ${pc63.cyan("setup")}, ${pc63.cyan("doctor")}
|
|
|
42749
42933
|
await telemetryStatus();
|
|
42750
42934
|
break;
|
|
42751
42935
|
default:
|
|
42752
|
-
|
|
42936
|
+
clack60.log.error(`Unknown telemetry command: ${subCommand}`);
|
|
42753
42937
|
console.log(
|
|
42754
42938
|
`
|
|
42755
|
-
Available commands: ${
|
|
42939
|
+
Available commands: ${pc64.cyan("enable")}, ${pc64.cyan("disable")}, ${pc64.cyan("status")}
|
|
42756
42940
|
`
|
|
42757
42941
|
);
|
|
42758
42942
|
throw new Error(`Unknown telemetry command: ${subCommand}`);
|
|
@@ -42776,10 +42960,10 @@ Please specify a command for ${primaryCommand} service.
|
|
|
42776
42960
|
showHelp();
|
|
42777
42961
|
break;
|
|
42778
42962
|
default:
|
|
42779
|
-
|
|
42963
|
+
clack60.log.error(`Unknown command: ${primaryCommand}`);
|
|
42780
42964
|
console.log(
|
|
42781
42965
|
`
|
|
42782
|
-
Run ${
|
|
42966
|
+
Run ${pc64.cyan("wraps --help")} for available commands.
|
|
42783
42967
|
`
|
|
42784
42968
|
);
|
|
42785
42969
|
throw new Error(`Unknown command: ${primaryCommand}`);
|