@wraps.dev/cli 2.19.0 → 2.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -820,6 +820,18 @@ To remove: wraps destroy --stack ${stackName}`,
820
820
  "Use a valid AWS region like: us-east-1, eu-west-1, ap-southeast-1",
821
821
  "https://docs.aws.amazon.com/general/latest/gr/rande.html"
822
822
  ),
823
+ // The accountId parameter is kept in the signature so callers don't
824
+ // have to change, but it is deliberately not included in the output —
825
+ // the user ran the command so they know their own account, and keeping
826
+ // IDs out of error text matches the `sanitizeErrorMessage` posture used
827
+ // elsewhere in the error system.
828
+ regionRequired: (_accountId, savedRegions) => new WrapsError(
829
+ "Region is required and could not be determined",
830
+ "REGION_REQUIRED",
831
+ savedRegions.length > 0 ? `Pass --region or set AWS_REGION.
832
+ Saved regions: ${savedRegions.join(", ")}` : "Pass --region or set AWS_REGION.\nNo saved Wraps deployments found.",
833
+ "https://wraps.dev/docs/cli-reference"
834
+ ),
823
835
  pulumiError: (message) => new WrapsError(
824
836
  `Infrastructure deployment failed: ${message}`,
825
837
  "PULUMI_ERROR",
@@ -842,7 +854,7 @@ To remove: wraps destroy --stack ${stackName}`,
842
854
  "The Pulumi stack is locked from a previous run",
843
855
  "STACK_LOCKED",
844
856
  "This happens when a previous deployment was interrupted.\n\nFor local state, run:\n rm -rf ~/.wraps/pulumi/.pulumi/locks\n\nFor S3 state, delete the lock object in your wraps-state-* bucket under .pulumi/locks/\n\nThen try your command again.",
845
- "https://wraps.dev/docs/guides/aws-setup/permissions/troubleshooting"
857
+ "https://wraps.dev/docs/guides/aws-setup/troubleshooting"
846
858
  ),
847
859
  // SMS-specific errors
848
860
  smsNotConfigured: () => new WrapsError(
@@ -958,7 +970,7 @@ View required SES permissions:
958
970
  `SES rejected the message: ${detail}`,
959
971
  "SES_MESSAGE_REJECTED",
960
972
  "Common causes:\n \u2022 Account is in the SES sandbox and the recipient is not a verified address\n \u2022 Sender identity (domain or email) is not verified for sending\n \u2022 The sender domain is verified for receiving but not for sending\n\nCheck status:\n wraps email status\n wraps email doctor\n\nRequest production access (exit sandbox):\n https://docs.aws.amazon.com/ses/latest/dg/request-production-access.html",
961
- "https://wraps.dev/docs/guides/email/troubleshooting"
973
+ "https://wraps.dev/docs/guides/aws-setup/troubleshooting"
962
974
  ),
963
975
  sesMailFromNotVerified: (detail) => new WrapsError(
964
976
  `SES MAIL FROM domain is not verified: ${detail}`,
@@ -1088,25 +1100,25 @@ You may need to merge your existing rules into the wraps rule set.`,
1088
1100
  "wraps/wraps.config.ts not found",
1089
1101
  "WRAPS_CONFIG_NOT_FOUND",
1090
1102
  "Initialize templates first:\n wraps email templates init",
1091
- "https://wraps.dev/docs/templates-as-code"
1103
+ "https://wraps.dev/docs/guides/templates"
1092
1104
  ),
1093
1105
  templateCompilationFailed: (name, error) => new WrapsError(
1094
1106
  `Failed to compile template "${name}": ${error}`,
1095
1107
  "TEMPLATE_COMPILATION_FAILED",
1096
1108
  "Check your template for syntax errors and ensure all imports are valid.",
1097
- "https://wraps.dev/docs/templates-as-code"
1109
+ "https://wraps.dev/docs/guides/templates"
1098
1110
  ),
1099
1111
  notAuthenticated: () => new WrapsError(
1100
1112
  "Not authenticated to Wraps Platform",
1101
1113
  "NOT_AUTHENTICATED",
1102
1114
  "Sign in first:\n wraps auth login\n\nOr provide an API key:\n wraps push --token wraps_...\n WRAPS_API_KEY=wraps_... wraps push",
1103
- "https://wraps.dev/docs/auth"
1115
+ "https://wraps.dev/docs/cli-reference/auth"
1104
1116
  ),
1105
1117
  templatePushFailed: (name, error) => new WrapsError(
1106
1118
  `Failed to push template "${name}": ${error}`,
1107
1119
  "TEMPLATE_PUSH_FAILED",
1108
1120
  "Check your API key and network connection.",
1109
- "https://wraps.dev/docs/templates-as-code"
1121
+ "https://wraps.dev/docs/guides/templates"
1110
1122
  )
1111
1123
  };
1112
1124
  }
@@ -1195,8 +1207,8 @@ async function validateAWSCredentialsWithDetails() {
1195
1207
  }
1196
1208
  }
1197
1209
  async function resolveAWSCredentialsToEnv() {
1198
- delete process.env.AWS_PROFILE;
1199
1210
  if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) {
1211
+ delete process.env.AWS_PROFILE;
1200
1212
  return;
1201
1213
  }
1202
1214
  const sts = new STSClient2({});
@@ -1223,6 +1235,7 @@ async function resolveAWSCredentialsToEnv() {
1223
1235
  if (creds.sessionToken) {
1224
1236
  process.env.AWS_SESSION_TOKEN = creds.sessionToken;
1225
1237
  }
1238
+ delete process.env.AWS_PROFILE;
1226
1239
  }
1227
1240
  async function checkRegion(region) {
1228
1241
  return SES_REGIONS.includes(region);
@@ -1702,8 +1715,8 @@ async function ensurePulumiWorkDir(options) {
1702
1715
  );
1703
1716
  return;
1704
1717
  } catch (error) {
1705
- const clack55 = await import("@clack/prompts");
1706
- clack55.log.warn(
1718
+ const clack56 = await import("@clack/prompts");
1719
+ clack56.log.warn(
1707
1720
  `S3 state backend unavailable (${error instanceof Error ? error.message : error}). Using local state.`
1708
1721
  );
1709
1722
  }
@@ -4423,6 +4436,7 @@ __export(prompts_exports, {
4423
4436
  confirmConnect: () => confirmConnect,
4424
4437
  confirmDeploy: () => confirmDeploy,
4425
4438
  getAvailableFeatures: () => getAvailableFeatures,
4439
+ isInteractive: () => isInteractive,
4426
4440
  promptConfigPreset: () => promptConfigPreset,
4427
4441
  promptConflictResolution: () => promptConflictResolution,
4428
4442
  promptContinueManualDNS: () => promptContinueManualDNS,
@@ -4448,6 +4462,9 @@ __export(prompts_exports, {
4448
4462
  });
4449
4463
  import * as clack6 from "@clack/prompts";
4450
4464
  import pc8 from "picocolors";
4465
+ function isInteractive() {
4466
+ return process.stdin.isTTY === true && process.stdout.isTTY === true && !process.env.CI;
4467
+ }
4451
4468
  async function promptProvider() {
4452
4469
  const provider = await clack6.select({
4453
4470
  message: "Where is your app hosted?",
@@ -6783,23 +6800,23 @@ async function withLockRetry(fn, options) {
6783
6800
  if (parsed.code !== "STACK_LOCKED") {
6784
6801
  throw error;
6785
6802
  }
6786
- const clack55 = await import("@clack/prompts");
6803
+ const clack56 = await import("@clack/prompts");
6787
6804
  const pc60 = (await import("picocolors")).default;
6788
6805
  if (options.autoConfirm) {
6789
- clack55.log.warn(
6806
+ clack56.log.warn(
6790
6807
  "Stack is locked from a previous interrupted run. Auto-clearing..."
6791
6808
  );
6792
6809
  } else {
6793
- const shouldClear = await clack55.confirm({
6810
+ const shouldClear = await clack56.confirm({
6794
6811
  message: `Stack is locked from a previous interrupted run. ${pc60.yellow("Clear the stale lock and retry?")}`,
6795
6812
  initialValue: true
6796
6813
  });
6797
- if (clack55.isCancel(shouldClear) || !shouldClear) {
6814
+ if (clack56.isCancel(shouldClear) || !shouldClear) {
6798
6815
  throw errors.stackLocked();
6799
6816
  }
6800
6817
  }
6801
6818
  const cleared = await clearStackLocks(options.accountId, options.region);
6802
- clack55.log.info(
6819
+ clack56.log.info(
6803
6820
  `Cleared ${cleared} lock file${cleared === 1 ? "" : "s"}. Retrying...`
6804
6821
  );
6805
6822
  return fn();
@@ -6815,26 +6832,11 @@ var init_pulumi = __esm({
6815
6832
  }
6816
6833
  });
6817
6834
 
6818
- // src/constants.ts
6819
- function getDefaultRegion() {
6820
- return process.env.AWS_REGION || DEFAULT_AWS_REGION;
6821
- }
6822
- var DEFAULT_AWS_REGION;
6823
- var init_constants = __esm({
6824
- "src/constants.ts"() {
6825
- "use strict";
6826
- init_esm_shims();
6827
- DEFAULT_AWS_REGION = "us-east-1";
6828
- }
6829
- });
6830
-
6831
6835
  // src/infrastructure/shared/resource-checks.ts
6832
6836
  async function roleExists(roleName) {
6833
6837
  try {
6834
6838
  const { IAMClient: IAMClient5, GetRoleCommand: GetRoleCommand3 } = await import("@aws-sdk/client-iam");
6835
- const iam10 = new IAMClient5({
6836
- region: getDefaultRegion()
6837
- });
6839
+ const iam10 = new IAMClient5({ region: "us-east-1" });
6838
6840
  await iam10.send(new GetRoleCommand3({ RoleName: roleName }));
6839
6841
  return true;
6840
6842
  } catch (error) {
@@ -6845,12 +6847,10 @@ async function roleExists(roleName) {
6845
6847
  return false;
6846
6848
  }
6847
6849
  }
6848
- async function tableExists(tableName) {
6850
+ async function tableExists(tableName, region) {
6849
6851
  try {
6850
6852
  const { DynamoDBClient: DynamoDBClient7, DescribeTableCommand: DescribeTableCommand2 } = await import("@aws-sdk/client-dynamodb");
6851
- const dynamodb3 = new DynamoDBClient7({
6852
- region: getDefaultRegion()
6853
- });
6853
+ const dynamodb3 = new DynamoDBClient7({ region });
6854
6854
  await dynamodb3.send(new DescribeTableCommand2({ TableName: tableName }));
6855
6855
  return true;
6856
6856
  } catch (error) {
@@ -6861,12 +6861,10 @@ async function tableExists(tableName) {
6861
6861
  return false;
6862
6862
  }
6863
6863
  }
6864
- async function sqsQueueExists(queueName) {
6864
+ async function sqsQueueExists(queueName, region) {
6865
6865
  try {
6866
6866
  const { SQSClient, GetQueueUrlCommand } = await import("@aws-sdk/client-sqs");
6867
- const sqs5 = new SQSClient({
6868
- region: getDefaultRegion()
6869
- });
6867
+ const sqs5 = new SQSClient({ region });
6870
6868
  const response = await sqs5.send(
6871
6869
  new GetQueueUrlCommand({ QueueName: queueName })
6872
6870
  );
@@ -6875,12 +6873,10 @@ async function sqsQueueExists(queueName) {
6875
6873
  return null;
6876
6874
  }
6877
6875
  }
6878
- async function snsTopicExists(topicName) {
6876
+ async function snsTopicExists(topicName, region) {
6879
6877
  try {
6880
6878
  const { SNSClient: SNSClient3, ListTopicsCommand: ListTopicsCommand2 } = await import("@aws-sdk/client-sns");
6881
- const sns3 = new SNSClient3({
6882
- region: getDefaultRegion()
6883
- });
6879
+ const sns3 = new SNSClient3({ region });
6884
6880
  let nextToken;
6885
6881
  do {
6886
6882
  const response = await sns3.send(
@@ -6899,12 +6895,10 @@ async function snsTopicExists(topicName) {
6899
6895
  return null;
6900
6896
  }
6901
6897
  }
6902
- async function lambdaFunctionExists(functionName) {
6898
+ async function lambdaFunctionExists(functionName, region) {
6903
6899
  try {
6904
6900
  const { LambdaClient: LambdaClient3, GetFunctionCommand } = await import("@aws-sdk/client-lambda");
6905
- const lambda4 = new LambdaClient3({
6906
- region: getDefaultRegion()
6907
- });
6901
+ const lambda4 = new LambdaClient3({ region });
6908
6902
  await lambda4.send(new GetFunctionCommand({ FunctionName: functionName }));
6909
6903
  return true;
6910
6904
  } catch (error) {
@@ -6919,7 +6913,6 @@ var init_resource_checks = __esm({
6919
6913
  "src/infrastructure/shared/resource-checks.ts"() {
6920
6914
  "use strict";
6921
6915
  init_esm_shims();
6922
- init_constants();
6923
6916
  }
6924
6917
  });
6925
6918
 
@@ -7350,12 +7343,10 @@ function getPackageRoot() {
7350
7343
  }
7351
7344
  throw new Error("Could not find package.json");
7352
7345
  }
7353
- async function findEventSourceMapping(functionName, queueArn) {
7346
+ async function findEventSourceMapping(functionName, queueArn, region) {
7354
7347
  try {
7355
7348
  const { LambdaClient: LambdaClient3, ListEventSourceMappingsCommand } = await import("@aws-sdk/client-lambda");
7356
- const lambda4 = new LambdaClient3({
7357
- region: getDefaultRegion()
7358
- });
7349
+ const lambda4 = new LambdaClient3({ region });
7359
7350
  const response = await lambda4.send(
7360
7351
  new ListEventSourceMappingsCommand({
7361
7352
  FunctionName: functionName,
@@ -7464,7 +7455,7 @@ async function deployLambdaFunctions(config2) {
7464
7455
  )
7465
7456
  });
7466
7457
  const functionName = "wraps-email-event-processor";
7467
- const exists = await lambdaFunctionExists(functionName);
7458
+ const exists = await lambdaFunctionExists(functionName, config2.region);
7468
7459
  const lambdaEnvironment = {
7469
7460
  variables: {
7470
7461
  TABLE_NAME: config2.tableName,
@@ -7512,7 +7503,8 @@ async function deployLambdaFunctions(config2) {
7512
7503
  const queueArnValue = `arn:aws:sqs:${config2.region}:${config2.accountId}:wraps-email-events`;
7513
7504
  const existingMappingUuid = await findEventSourceMapping(
7514
7505
  functionName,
7515
- queueArnValue
7506
+ queueArnValue,
7507
+ config2.region
7516
7508
  );
7517
7509
  const mappingConfig = {
7518
7510
  eventSourceArn: config2.queueArn,
@@ -7545,7 +7537,6 @@ var init_lambda = __esm({
7545
7537
  "src/infrastructure/resources/lambda.ts"() {
7546
7538
  "use strict";
7547
7539
  init_esm_shims();
7548
- init_constants();
7549
7540
  init_resource_checks();
7550
7541
  nodeBuiltins = builtinModules.flatMap((m) => [m, `node:${m}`]);
7551
7542
  }
@@ -7893,7 +7884,7 @@ function retentionToAWSPeriod2(retention) {
7893
7884
  }
7894
7885
  }
7895
7886
  async function createMailManagerArchive(config2) {
7896
- const region = config2.region || getDefaultRegion();
7887
+ const region = config2.region;
7897
7888
  const archiveName = `wraps-${config2.name}-archive`;
7898
7889
  const mailManagerClient = new MailManagerClient({ region });
7899
7890
  const sesClient = new SESv2Client3({ region });
@@ -7995,7 +7986,6 @@ var init_mail_manager = __esm({
7995
7986
  "src/infrastructure/resources/mail-manager.ts"() {
7996
7987
  "use strict";
7997
7988
  init_esm_shims();
7998
- init_constants();
7999
7989
  }
8000
7990
  });
8001
7991
 
@@ -9675,6 +9665,60 @@ var init_test = __esm({
9675
9665
  }
9676
9666
  });
9677
9667
 
9668
+ // src/utils/shared/region-resolver.ts
9669
+ var region_resolver_exports = {};
9670
+ __export(region_resolver_exports, {
9671
+ resolveRegionForCommand: () => resolveRegionForCommand
9672
+ });
9673
+ import * as clack28 from "@clack/prompts";
9674
+ async function resolveRegionForCommand(opts) {
9675
+ const { accountId, optionRegion, service, label = "deployment" } = opts;
9676
+ if (optionRegion) {
9677
+ return optionRegion;
9678
+ }
9679
+ const envRegion = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION;
9680
+ if (envRegion) {
9681
+ return envRegion;
9682
+ }
9683
+ const connections = (service ? await findConnectionsWithService(accountId, service) : await findConnectionsForAccount(accountId)) ?? [];
9684
+ if (connections.length === 1) {
9685
+ return connections[0].region;
9686
+ }
9687
+ const savedRegions = connections.map((c) => c.region);
9688
+ if (connections.length === 0) {
9689
+ return getAWSRegion();
9690
+ }
9691
+ if (!isInteractive() || isJsonMode()) {
9692
+ throw errors.regionRequired(accountId, savedRegions);
9693
+ }
9694
+ const selected = await clack28.select({
9695
+ message: `Multiple ${label}s found. Which region?`,
9696
+ options: connections.map((conn) => ({
9697
+ value: conn.region,
9698
+ label: conn.region
9699
+ }))
9700
+ });
9701
+ if (clack28.isCancel(selected)) {
9702
+ throw new WrapsError(
9703
+ "Operation cancelled",
9704
+ "OPERATION_CANCELLED",
9705
+ `Pass --region to skip the prompt. Saved regions: ${savedRegions.join(", ")}`
9706
+ );
9707
+ }
9708
+ return selected;
9709
+ }
9710
+ var init_region_resolver = __esm({
9711
+ "src/utils/shared/region-resolver.ts"() {
9712
+ "use strict";
9713
+ init_esm_shims();
9714
+ init_aws();
9715
+ init_errors();
9716
+ init_json_output();
9717
+ init_metadata();
9718
+ init_prompts();
9719
+ }
9720
+ });
9721
+
9678
9722
  // src/utils/dns/caa.ts
9679
9723
  var caa_exports = {};
9680
9724
  __export(caa_exports, {
@@ -10080,7 +10124,7 @@ import { homedir as homedir4, tmpdir as tmpdir2 } from "os";
10080
10124
  import { join as join21 } from "path";
10081
10125
  import { Readable } from "stream";
10082
10126
  import { pipeline } from "stream/promises";
10083
- import { cancel as cancel31, confirm as confirm26, intro as intro51, isCancel as isCancel35, log as log50 } from "@clack/prompts";
10127
+ import { cancel as cancel31, confirm as confirm26, intro as intro51, isCancel as isCancel36, log as log50 } from "@clack/prompts";
10084
10128
  import pc58 from "picocolors";
10085
10129
  function isStandaloneInstall() {
10086
10130
  return process.execPath.includes(".wraps/runtime");
@@ -10142,7 +10186,7 @@ async function update(currentVersion) {
10142
10186
  const shouldUpdate = await confirm26({
10143
10187
  message: `Update to v${latestVersion}?`
10144
10188
  });
10145
- if (isCancel35(shouldUpdate) || !shouldUpdate) {
10189
+ if (isCancel36(shouldUpdate) || !shouldUpdate) {
10146
10190
  cancel31("Update cancelled.");
10147
10191
  return;
10148
10192
  }
@@ -10233,7 +10277,7 @@ init_esm_shims();
10233
10277
  import { readFileSync as readFileSync3 } from "fs";
10234
10278
  import { dirname as dirname5, join as join22 } from "path";
10235
10279
  import { fileURLToPath as fileURLToPath6 } from "url";
10236
- import * as clack54 from "@clack/prompts";
10280
+ import * as clack55 from "@clack/prompts";
10237
10281
  import pc59 from "picocolors";
10238
10282
 
10239
10283
  // src/commands/auth/login.ts
@@ -10648,26 +10692,30 @@ async function runDiagnostics(state) {
10648
10692
  }
10649
10693
  }
10650
10694
  if (state.credentialsConfigured) {
10695
+ const regionUsed = state.region || "us-east-1";
10696
+ const regionNote = state.region ? `Region: ${regionUsed}` : `No AWS_REGION set \u2014 defaulted to ${regionUsed}. Set AWS_REGION if your deployment lives elsewhere.`;
10651
10697
  try {
10652
- const region = state.region || "us-east-1";
10653
- const sandbox = await isSESSandbox(region);
10698
+ const sandbox = await isSESSandbox(regionUsed);
10654
10699
  if (sandbox) {
10655
10700
  results.push({
10656
10701
  status: "warn",
10657
10702
  message: "SES is in sandbox mode",
10658
- details: "You can only send to verified emails. Request production access in AWS console."
10703
+ details: `You can only send to verified emails. Request production access in AWS console.
10704
+ ${regionNote}`
10659
10705
  });
10660
10706
  } else {
10661
10707
  results.push({
10662
10708
  status: "pass",
10663
- message: "SES has production access"
10709
+ message: "SES has production access",
10710
+ details: regionNote
10664
10711
  });
10665
10712
  }
10666
10713
  } catch {
10667
10714
  results.push({
10668
10715
  status: "info",
10669
10716
  message: "Could not check SES status",
10670
- details: "SES may not be enabled in this region"
10717
+ details: `SES may not be enabled in this region.
10718
+ ${regionNote}`
10671
10719
  });
10672
10720
  }
10673
10721
  }
@@ -11812,6 +11860,7 @@ async function createCdnBucket(config2) {
11812
11860
  const corsOrigins = [
11813
11861
  "https://wraps.dev",
11814
11862
  "https://*.wraps.dev",
11863
+ "https://*.wraps.localhost",
11815
11864
  "http://localhost:3000",
11816
11865
  "http://localhost:3001",
11817
11866
  "http://localhost:3002",
@@ -12201,8 +12250,16 @@ async function createServiceIAMRole(config2) {
12201
12250
 
12202
12251
  // src/infrastructure/vercel-oidc.ts
12203
12252
  init_esm_shims();
12204
- init_constants();
12205
12253
  import * as aws3 from "@pulumi/aws";
12254
+
12255
+ // src/constants.ts
12256
+ init_esm_shims();
12257
+ var DEFAULT_AWS_REGION = "us-east-1";
12258
+ function getDefaultRegion() {
12259
+ return process.env.AWS_REGION || DEFAULT_AWS_REGION;
12260
+ }
12261
+
12262
+ // src/infrastructure/vercel-oidc.ts
12206
12263
  async function getExistingOIDCProviderArn(url) {
12207
12264
  try {
12208
12265
  const { IAMClient: IAMClient5, ListOpenIDConnectProvidersCommand } = await import("@aws-sdk/client-iam");
@@ -17508,9 +17565,9 @@ async function createAlertingResources(config2) {
17508
17565
  init_esm_shims();
17509
17566
  init_resource_checks();
17510
17567
  import * as aws5 from "@pulumi/aws";
17511
- async function createDynamoDBTables(_config) {
17568
+ async function createDynamoDBTables(config2) {
17512
17569
  const tableName = "wraps-email-history";
17513
- const exists = await tableExists(tableName);
17570
+ const exists = await tableExists(tableName, config2.region);
17514
17571
  const emailHistory = exists ? new aws5.dynamodb.Table(
17515
17572
  tableName,
17516
17573
  {
@@ -18048,7 +18105,6 @@ async function createSESResources(config2) {
18048
18105
 
18049
18106
  // src/infrastructure/resources/smtp-credentials.ts
18050
18107
  init_esm_shims();
18051
- init_constants();
18052
18108
  import { createHmac as createHmac3 } from "crypto";
18053
18109
  import * as aws10 from "@pulumi/aws";
18054
18110
  function convertToSMTPPassword2(secretAccessKey, region) {
@@ -18138,11 +18194,11 @@ import * as aws11 from "@pulumi/aws";
18138
18194
  var SQS_TIMEOUTS = {
18139
18195
  customTimeouts: { create: "2m", update: "2m", delete: "2m" }
18140
18196
  };
18141
- async function createSQSResources() {
18197
+ async function createSQSResources(config2) {
18142
18198
  const dlqName = "wraps-email-events-dlq";
18143
18199
  const queueName = "wraps-email-events";
18144
- const dlqUrl = await sqsQueueExists(dlqName);
18145
- const queueUrl = await sqsQueueExists(queueName);
18200
+ const dlqUrl = await sqsQueueExists(dlqName, config2.region);
18201
+ const queueUrl = await sqsQueueExists(queueName, config2.region);
18146
18202
  const dlqConfig = {
18147
18203
  name: dlqName,
18148
18204
  messageRetentionSeconds: 1209600,
@@ -18281,12 +18337,13 @@ async function deployEmailStack(config2) {
18281
18337
  let dynamoTables;
18282
18338
  if (emailConfig.eventTracking?.dynamoDBHistory) {
18283
18339
  dynamoTables = await createDynamoDBTables({
18340
+ region: config2.region,
18284
18341
  retention: emailConfig.eventTracking.archiveRetention
18285
18342
  });
18286
18343
  }
18287
18344
  let sqsResources;
18288
18345
  if (emailConfig.eventTracking?.enabled) {
18289
- sqsResources = await createSQSResources();
18346
+ sqsResources = await createSQSResources({ region: config2.region });
18290
18347
  }
18291
18348
  if (emailConfig.eventTracking?.enabled && sesResources && sqsResources) {
18292
18349
  await createEventBridgeResources({
@@ -21245,6 +21302,8 @@ async function inboundInit(options) {
21245
21302
  subdomain,
21246
21303
  bucketName: `wraps-inbound-${identity.accountId}-${region}`,
21247
21304
  webhookUrl: webhookUrl || null,
21305
+ webhookSecret: webhookUrl ? webhookSecret : null,
21306
+ webhookHeader: webhookUrl ? "X-Wraps-Inbound-Key" : null,
21248
21307
  dnsAutoCreated,
21249
21308
  region
21250
21309
  });
@@ -21263,6 +21322,27 @@ async function inboundInit(options) {
21263
21322
  if (dnsAutoCreated) {
21264
21323
  console.log(` ${pc24.dim("DNS:")} ${pc24.green("Auto-created")}`);
21265
21324
  }
21325
+ if (webhookUrl) {
21326
+ const setupLines = [
21327
+ `EventBridge will POST every ${pc24.cyan("email.received")} event to:`,
21328
+ ` ${pc24.cyan(webhookUrl)}`,
21329
+ "",
21330
+ "Verify the request by checking this header on every POST:",
21331
+ ` ${pc24.bold("X-Wraps-Inbound-Key")}: ${pc24.yellow(webhookSecret)}`,
21332
+ "",
21333
+ pc24.bold("Save this secret now \u2014 it is only shown once."),
21334
+ `Retrieve it later with: ${pc24.cyan("wraps email inbound status --reveal-secret")}`,
21335
+ "",
21336
+ "Body shape (JSON):",
21337
+ pc24.dim(
21338
+ ' { "emailId", "from", "to", "subject", "html", "text", "attachments", "headers", ... }'
21339
+ ),
21340
+ "",
21341
+ `Docs: ${pc24.cyan("https://wraps.dev/docs/quickstart/email/inbound")}`
21342
+ ].join("\n");
21343
+ console.log();
21344
+ clack22.note(setupLines, "Webhook setup");
21345
+ }
21266
21346
  console.log();
21267
21347
  console.log(pc24.bold("Next steps:"));
21268
21348
  if (dnsAutoCreated) {
@@ -21413,6 +21493,8 @@ Enable it: ${pc24.cyan("wraps email inbound init")}
21413
21493
  bucketName: inbound.bucketName || "",
21414
21494
  region,
21415
21495
  webhookUrl: inbound.webhookUrl || null,
21496
+ webhookHeader: inbound.webhookUrl ? "X-Wraps-Inbound-Key" : null,
21497
+ webhookSecret: options.revealSecret && inbound.webhookUrl ? inbound.webhookSecret || null : null,
21416
21498
  receiptRuleSetActive: activeRuleSet === RULE_SET_NAME,
21417
21499
  retention: inbound.retention || null
21418
21500
  });
@@ -21436,6 +21518,20 @@ Enable it: ${pc24.cyan("wraps email inbound init")}
21436
21518
  console.log(
21437
21519
  ` ${pc24.dim("Webhook URL:")} ${inbound.webhookUrl ? pc24.cyan(inbound.webhookUrl) : pc24.dim("not configured")}`
21438
21520
  );
21521
+ if (inbound.webhookUrl) {
21522
+ console.log(
21523
+ ` ${pc24.dim("Webhook header:")} ${pc24.cyan("X-Wraps-Inbound-Key")}`
21524
+ );
21525
+ if (options.revealSecret) {
21526
+ console.log(
21527
+ ` ${pc24.dim("Webhook secret:")} ${inbound.webhookSecret ? pc24.yellow(inbound.webhookSecret) : pc24.dim("not set")}`
21528
+ );
21529
+ } else {
21530
+ console.log(
21531
+ ` ${pc24.dim("Webhook secret:")} ${pc24.dim("hidden \u2014 pass --reveal-secret to show")}`
21532
+ );
21533
+ }
21534
+ }
21439
21535
  console.log(
21440
21536
  ` ${pc24.dim("Receipt rule set:")} ${activeRuleSet === RULE_SET_NAME ? pc24.green("active") : pc24.yellow("inactive")}`
21441
21537
  );
@@ -21571,7 +21667,7 @@ function mapInboundTestSendError(error, ctx) {
21571
21667
  `Failed to send inbound test email to ${ctx.recipient}`,
21572
21668
  "INBOUND_TEST_SEND_FAILED",
21573
21669
  "An unexpected error occurred while sending the test email.\n\nCheck infrastructure status:\n wraps email status\n wraps email doctor",
21574
- "https://wraps.dev/docs/guides/email/troubleshooting"
21670
+ "https://wraps.dev/docs/guides/aws-setup/troubleshooting"
21575
21671
  );
21576
21672
  }
21577
21673
  const name = error.name;
@@ -21608,7 +21704,7 @@ Or remove the custom MAIL FROM domain in the SES console and retry.`,
21608
21704
  "Exit the SES sandbox to send to any address:",
21609
21705
  " https://docs.aws.amazon.com/ses/latest/dg/request-production-access.html"
21610
21706
  ].join("\n"),
21611
- "https://wraps.dev/docs/guides/email/troubleshooting"
21707
+ "https://wraps.dev/docs/guides/aws-setup/troubleshooting"
21612
21708
  );
21613
21709
  }
21614
21710
  if (name === "AccountSendingPausedException" || name === "ConfigurationSetSendingPausedException") {
@@ -23049,7 +23145,7 @@ async function replyInitForSingleDomain(params) {
23049
23145
  `The Pulumi deploy completed but the SSM parameter ${ssmParameterName(domain)} was not found. Run:
23050
23146
  wraps email reply status
23051
23147
  to diagnose, or retry the init.`,
23052
- "https://wraps.dev/docs/guides/email/reply-threading"
23148
+ "https://wraps.dev/docs/guides/reply-threading"
23053
23149
  );
23054
23150
  }
23055
23151
  const finalEntry = {
@@ -23162,7 +23258,7 @@ async function replyInit(options) {
23162
23258
  "Reply threading requires inbound email infrastructure",
23163
23259
  "REPLY_REQUIRES_INBOUND",
23164
23260
  "Deploy inbound first:\n wraps email inbound init\n\nThen enable reply threading:\n wraps email reply init --domain yourapp.com",
23165
- "https://wraps.dev/docs/guides/email/reply-threading"
23261
+ "https://wraps.dev/docs/guides/reply-threading"
23166
23262
  );
23167
23263
  }
23168
23264
  const emailService = metadata.services.email;
@@ -23178,7 +23274,7 @@ async function replyInit(options) {
23178
23274
  "No inbound domains configured",
23179
23275
  "REPLY_NO_INBOUND_DOMAINS",
23180
23276
  "Add an inbound domain first:\n wraps email inbound add --domain yourapp.com",
23181
- "https://wraps.dev/docs/guides/email/reply-threading"
23277
+ "https://wraps.dev/docs/guides/reply-threading"
23182
23278
  );
23183
23279
  }
23184
23280
  let targetDomains;
@@ -23207,7 +23303,7 @@ async function replyInit(options) {
23207
23303
  "REPLY_INBOUND_DOMAIN_NOT_FOUND",
23208
23304
  `Add it to inbound first:
23209
23305
  wraps email inbound add ${target}`,
23210
- "https://wraps.dev/docs/guides/email/reply-threading"
23306
+ "https://wraps.dev/docs/guides/reply-threading"
23211
23307
  );
23212
23308
  }
23213
23309
  if (isReplyEnabledFor(metadata, target)) {
@@ -23216,7 +23312,7 @@ async function replyInit(options) {
23216
23312
  "REPLY_ALREADY_ENABLED",
23217
23313
  `To rotate the signing secret, run:
23218
23314
  wraps email reply rotate --domain ${target}`,
23219
- "https://wraps.dev/docs/guides/email/reply-threading"
23315
+ "https://wraps.dev/docs/guides/reply-threading"
23220
23316
  );
23221
23317
  }
23222
23318
  targetDomains = [target];
@@ -23225,7 +23321,7 @@ async function replyInit(options) {
23225
23321
  "Specify a domain or use --all",
23226
23322
  "REPLY_MISSING_DOMAIN",
23227
23323
  "Use one of:\n wraps email reply init --domain yourapp.com\n wraps email reply init --all",
23228
- "https://wraps.dev/docs/guides/email/reply-threading"
23324
+ "https://wraps.dev/docs/guides/reply-threading"
23229
23325
  );
23230
23326
  }
23231
23327
  const stackName = emailService.pulumiStackName || `wraps-${identity.accountId}-${region}`;
@@ -23277,7 +23373,7 @@ async function replyRotate(options) {
23277
23373
  "--domain is required for rotate",
23278
23374
  "REPLY_ROTATE_MISSING_DOMAIN",
23279
23375
  "Usage:\n wraps email reply rotate --domain yourapp.com",
23280
- "https://wraps.dev/docs/guides/email/reply-threading"
23376
+ "https://wraps.dev/docs/guides/reply-threading"
23281
23377
  );
23282
23378
  }
23283
23379
  const identity = await progress.execute(
@@ -23291,7 +23387,7 @@ async function replyRotate(options) {
23291
23387
  "Reply threading is not enabled",
23292
23388
  "REPLY_NOT_ENABLED",
23293
23389
  "Enable it first:\n wraps email reply init --domain yourapp.com",
23294
- "https://wraps.dev/docs/guides/email/reply-threading"
23390
+ "https://wraps.dev/docs/guides/reply-threading"
23295
23391
  );
23296
23392
  }
23297
23393
  const rt = metadata.services.email.config.replyThreading;
@@ -23302,7 +23398,7 @@ async function replyRotate(options) {
23302
23398
  "REPLY_DOMAIN_NOT_ENABLED",
23303
23399
  `Enable it first:
23304
23400
  wraps email reply init --domain ${options.domain}`,
23305
- "https://wraps.dev/docs/guides/email/reply-threading"
23401
+ "https://wraps.dev/docs/guides/reply-threading"
23306
23402
  );
23307
23403
  }
23308
23404
  const parameterName = entry.parameterName || ssmParameterName(options.domain);
@@ -23327,7 +23423,7 @@ async function replyRotate(options) {
23327
23423
  "REPLY_SECRET_PARAMETER_MISSING",
23328
23424
  `The signing secret for ${options.domain} has not been created yet. Run:
23329
23425
  wraps email reply init --domain ${options.domain}`,
23330
- "https://wraps.dev/docs/guides/email/reply-threading"
23426
+ "https://wraps.dev/docs/guides/reply-threading"
23331
23427
  );
23332
23428
  }
23333
23429
  throw error;
@@ -23567,7 +23663,7 @@ async function replyDestroy(options) {
23567
23663
  "Specify a domain or use --all",
23568
23664
  "REPLY_DESTROY_MISSING_DOMAIN",
23569
23665
  "Usage:\n wraps email reply destroy --domain yourapp.com\n wraps email reply destroy --all",
23570
- "https://wraps.dev/docs/guides/email/reply-threading"
23666
+ "https://wraps.dev/docs/guides/reply-threading"
23571
23667
  );
23572
23668
  }
23573
23669
  if (!(options.force || isJsonMode())) {
@@ -23622,7 +23718,7 @@ async function replyDecode(addressInput, options) {
23622
23718
  "Usage: wraps email reply decode <token>@r.mail.yourapp.com",
23623
23719
  "REPLY_DECODE_MISSING_ADDRESS",
23624
23720
  "Provide a signed reply address like:\n wraps email reply decode abcDEF123@r.mail.yourapp.com",
23625
- "https://wraps.dev/docs/guides/email/reply-threading"
23721
+ "https://wraps.dev/docs/guides/reply-threading"
23626
23722
  );
23627
23723
  }
23628
23724
  const at = addressInput.lastIndexOf("@");
@@ -23632,7 +23728,7 @@ async function replyDecode(addressInput, options) {
23632
23728
  "Address must be in the form <token>@r.mail.example.com",
23633
23729
  "REPLY_DECODE_MALFORMED_ADDRESS",
23634
23730
  "Pass a full signed reply address:\n wraps email reply decode abcDEF123@r.mail.yourapp.com",
23635
- "https://wraps.dev/docs/guides/email/reply-threading"
23731
+ "https://wraps.dev/docs/guides/reply-threading"
23636
23732
  );
23637
23733
  }
23638
23734
  const local = addressInput.slice(0, at);
@@ -23683,7 +23779,8 @@ init_json_output();
23683
23779
  init_metadata();
23684
23780
  init_output();
23685
23781
  init_pulumi();
23686
- import * as clack28 from "@clack/prompts";
23782
+ init_region_resolver();
23783
+ import * as clack29 from "@clack/prompts";
23687
23784
  import * as pulumi21 from "@pulumi/pulumi";
23688
23785
  import pc30 from "picocolors";
23689
23786
  async function restore(options) {
@@ -23696,15 +23793,15 @@ async function restore(options) {
23696
23793
  );
23697
23794
  }
23698
23795
  if (!isJsonMode()) {
23699
- clack28.intro(
23796
+ clack29.intro(
23700
23797
  pc30.bold(
23701
23798
  options.preview ? "Wraps Restore Preview" : "Wraps Restore - Remove Wraps Infrastructure"
23702
23799
  )
23703
23800
  );
23704
- clack28.log.info(
23801
+ clack29.log.info(
23705
23802
  `${pc30.yellow("Note:")} This will remove all Wraps-managed infrastructure.`
23706
23803
  );
23707
- clack28.log.info(
23804
+ clack29.log.info(
23708
23805
  "Your original AWS resources remain untouched (Wraps never modifies them).\n"
23709
23806
  );
23710
23807
  }
@@ -23715,17 +23812,18 @@ async function restore(options) {
23715
23812
  async () => validateAWSCredentials()
23716
23813
  );
23717
23814
  progress.info(`Connected to AWS account: ${pc30.cyan(identity.accountId)}`);
23718
- let region = options.region;
23719
- if (!region) {
23720
- const defaultRegion = await getAWSRegion();
23721
- region = defaultRegion;
23722
- }
23815
+ const region = await resolveRegionForCommand({
23816
+ accountId: identity.accountId,
23817
+ optionRegion: options.region,
23818
+ service: "email",
23819
+ label: "email deployment"
23820
+ });
23723
23821
  const metadata = await loadConnectionMetadata(identity.accountId, region);
23724
23822
  if (!metadata) {
23725
- clack28.log.error(
23823
+ clack29.log.error(
23726
23824
  `No Wraps connection found for account ${pc30.cyan(identity.accountId)} in region ${pc30.cyan(region)}`
23727
23825
  );
23728
- clack28.log.info(
23826
+ clack29.log.info(
23729
23827
  `Use ${pc30.cyan("wraps email init")} or ${pc30.cyan("wraps email connect")} to create a connection first.`
23730
23828
  );
23731
23829
  process.exit(1);
@@ -23750,12 +23848,12 @@ ${pc30.bold("The following Wraps resources will be removed:")}
23750
23848
  console.log(` ${pc30.cyan("\u2713")} IAM Role (wraps-email-role)`);
23751
23849
  console.log("");
23752
23850
  if (!(options.force || options.preview)) {
23753
- const confirmed = await clack28.confirm({
23851
+ const confirmed = await clack29.confirm({
23754
23852
  message: "Proceed with removal? This cannot be undone.",
23755
23853
  initialValue: false
23756
23854
  });
23757
- if (clack28.isCancel(confirmed) || !confirmed) {
23758
- clack28.cancel("Removal cancelled.");
23855
+ if (clack29.isCancel(confirmed) || !confirmed) {
23856
+ clack29.cancel("Removal cancelled.");
23759
23857
  process.exit(0);
23760
23858
  }
23761
23859
  }
@@ -23795,7 +23893,7 @@ ${pc30.bold("The following Wraps resources will be removed:")}
23795
23893
  costEstimate: "Monthly cost after removal: $0.00",
23796
23894
  commandName: "wraps email restore"
23797
23895
  });
23798
- clack28.outro(
23896
+ clack29.outro(
23799
23897
  pc30.green(
23800
23898
  "Preview complete. Run without --preview to remove infrastructure."
23801
23899
  )
@@ -23888,7 +23986,7 @@ init_json_output();
23888
23986
  init_metadata();
23889
23987
  init_output();
23890
23988
  init_pulumi();
23891
- import * as clack29 from "@clack/prompts";
23989
+ import * as clack30 from "@clack/prompts";
23892
23990
  import * as pulumi22 from "@pulumi/pulumi";
23893
23991
  import pc31 from "picocolors";
23894
23992
  async function emailStatus(options) {
@@ -23896,7 +23994,7 @@ async function emailStatus(options) {
23896
23994
  const startTime = Date.now();
23897
23995
  const progress = new DeploymentProgress();
23898
23996
  if (!isJsonMode()) {
23899
- clack29.intro(pc31.bold("Wraps Email Status"));
23997
+ clack30.intro(pc31.bold("Wraps Email Status"));
23900
23998
  }
23901
23999
  const identity = await progress.execute(
23902
24000
  "Loading email infrastructure status",
@@ -23911,15 +24009,15 @@ async function emailStatus(options) {
23911
24009
  if (emailConnections.length === 1) {
23912
24010
  region = emailConnections[0].region;
23913
24011
  } else if (emailConnections.length > 1) {
23914
- const selectedRegion = await clack29.select({
24012
+ const selectedRegion = await clack30.select({
23915
24013
  message: "Multiple email deployments found. Which region?",
23916
24014
  options: emailConnections.map((conn) => ({
23917
24015
  value: conn.region,
23918
24016
  label: conn.region
23919
24017
  }))
23920
24018
  });
23921
- if (clack29.isCancel(selectedRegion)) {
23922
- clack29.cancel("Operation cancelled");
24019
+ if (clack30.isCancel(selectedRegion)) {
24020
+ clack30.cancel("Operation cancelled");
23923
24021
  process.exit(0);
23924
24022
  }
23925
24023
  region = selectedRegion;
@@ -23935,7 +24033,7 @@ async function emailStatus(options) {
23935
24033
  stackOutputs = await stack.outputs();
23936
24034
  } catch (_error) {
23937
24035
  progress.stop();
23938
- clack29.log.error("No email infrastructure found");
24036
+ clack30.log.error("No email infrastructure found");
23939
24037
  console.log(
23940
24038
  `
23941
24039
  Run ${pc31.cyan("wraps email init")} to deploy email infrastructure.
@@ -24031,7 +24129,7 @@ init_output();
24031
24129
  import { existsSync as existsSync9 } from "fs";
24032
24130
  import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
24033
24131
  import { join as join11 } from "path";
24034
- import * as clack30 from "@clack/prompts";
24132
+ import * as clack31 from "@clack/prompts";
24035
24133
  import pc32 from "picocolors";
24036
24134
 
24037
24135
  // src/utils/shared/scaffold-claude.ts
@@ -24478,7 +24576,7 @@ async function templatesInit(options) {
24478
24576
  const cwd = process.cwd();
24479
24577
  const wrapsDir = join11(cwd, "wraps");
24480
24578
  if (!isJsonMode()) {
24481
- clack30.intro(pc32.bold("Templates as Code"));
24579
+ clack31.intro(pc32.bold("Templates as Code"));
24482
24580
  }
24483
24581
  const progress = new DeploymentProgress();
24484
24582
  if (existsSync9(wrapsDir) && !options.force) {
@@ -24495,12 +24593,12 @@ async function templatesInit(options) {
24495
24593
  if (orgs?.length === 1) {
24496
24594
  orgSlug = orgs[0].slug;
24497
24595
  } else if (orgs && orgs.length > 1 && !isJsonMode()) {
24498
- const selected = await clack30.select({
24596
+ const selected = await clack31.select({
24499
24597
  message: "Which organization?",
24500
24598
  options: orgs.map((o) => ({ value: o.slug, label: o.name }))
24501
24599
  });
24502
- if (clack30.isCancel(selected)) {
24503
- clack30.cancel("Operation cancelled.");
24600
+ if (clack31.isCancel(selected)) {
24601
+ clack31.cancel("Operation cancelled.");
24504
24602
  process.exit(0);
24505
24603
  }
24506
24604
  orgSlug = selected;
@@ -24634,7 +24732,7 @@ wraps/.wraps/
24634
24732
  duration_ms: Date.now() - startTime
24635
24733
  });
24636
24734
  console.log();
24637
- clack30.log.success(pc32.green("Templates as Code initialized!"));
24735
+ clack31.log.success(pc32.green("Templates as Code initialized!"));
24638
24736
  console.log();
24639
24737
  console.log(` ${pc32.dim("Directory:")} ${pc32.cyan("wraps/")}`);
24640
24738
  console.log(` ${pc32.dim("Config:")} ${pc32.cyan("wraps/wraps.config.ts")}`);
@@ -24847,7 +24945,7 @@ init_esm_shims();
24847
24945
  init_events();
24848
24946
  import { existsSync as existsSync11, watch } from "fs";
24849
24947
  import { join as join13 } from "path";
24850
- import * as clack31 from "@clack/prompts";
24948
+ import * as clack32 from "@clack/prompts";
24851
24949
  import pc33 from "picocolors";
24852
24950
 
24853
24951
  // src/utils/email/template-compiler.ts
@@ -24972,7 +25070,7 @@ async function templatesPreview(options) {
24972
25070
  if (!existsSync11(configPath)) {
24973
25071
  throw errors.wrapsConfigNotFound();
24974
25072
  }
24975
- clack31.intro(pc33.bold("Preview Templates"));
25073
+ clack32.intro(pc33.bold("Preview Templates"));
24976
25074
  const config2 = await loadWrapsConfig(wrapsDir);
24977
25075
  const templatesDir = join13(wrapsDir, config2.templatesDir || "./templates");
24978
25076
  if (!existsSync11(templatesDir)) {
@@ -24980,7 +25078,7 @@ async function templatesPreview(options) {
24980
25078
  }
24981
25079
  const templateFiles = await discoverTemplates(templatesDir, options.template);
24982
25080
  if (templateFiles.length === 0) {
24983
- clack31.log.info("No templates found.");
25081
+ clack32.log.info("No templates found.");
24984
25082
  return;
24985
25083
  }
24986
25084
  const cache = /* @__PURE__ */ new Map();
@@ -25095,11 +25193,11 @@ async function templatesPreview(options) {
25095
25193
  success: true,
25096
25194
  template_count: templateFiles.length
25097
25195
  });
25098
- clack31.log.success(`Preview server running at ${pc33.cyan(url)}`);
25196
+ clack32.log.success(`Preview server running at ${pc33.cyan(url)}`);
25099
25197
  if (options.template) {
25100
- clack31.log.info(`Previewing: ${pc33.cyan(options.template)}`);
25198
+ clack32.log.info(`Previewing: ${pc33.cyan(options.template)}`);
25101
25199
  } else {
25102
- clack31.log.info(
25200
+ clack32.log.info(
25103
25201
  `${templateFiles.length} template${templateFiles.length === 1 ? "" : "s"} available`
25104
25202
  );
25105
25203
  }
@@ -25299,7 +25397,7 @@ import { createHash } from "crypto";
25299
25397
  import { existsSync as existsSync13 } from "fs";
25300
25398
  import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile8 } from "fs/promises";
25301
25399
  import { join as join15 } from "path";
25302
- import * as clack32 from "@clack/prompts";
25400
+ import * as clack33 from "@clack/prompts";
25303
25401
  import pc34 from "picocolors";
25304
25402
 
25305
25403
  // src/utils/email/template-render.ts
@@ -25420,7 +25518,7 @@ async function templatesPush(options) {
25420
25518
  throw errors.wrapsConfigNotFound();
25421
25519
  }
25422
25520
  if (!isJsonMode()) {
25423
- clack32.intro(pc34.bold("Push Templates"));
25521
+ clack33.intro(pc34.bold("Push Templates"));
25424
25522
  }
25425
25523
  const progress = new DeploymentProgress();
25426
25524
  progress.start("Loading configuration");
@@ -25433,7 +25531,7 @@ async function templatesPush(options) {
25433
25531
  const templateFiles = await discoverTemplates(templatesDir, options.template);
25434
25532
  if (templateFiles.length === 0) {
25435
25533
  if (!isJsonMode()) {
25436
- clack32.log.info("No templates found to push.");
25534
+ clack33.log.info("No templates found to push.");
25437
25535
  }
25438
25536
  return;
25439
25537
  }
@@ -25479,7 +25577,7 @@ async function templatesPush(options) {
25479
25577
  errors: []
25480
25578
  });
25481
25579
  } else {
25482
- clack32.log.info(
25580
+ clack33.log.info(
25483
25581
  `${unchanged.length} template${unchanged.length === 1 ? "" : "s"} unchanged. Use --force to re-push.`
25484
25582
  );
25485
25583
  }
@@ -25500,7 +25598,7 @@ async function templatesPush(options) {
25500
25598
  });
25501
25599
  } else {
25502
25600
  console.log();
25503
- clack32.log.info(pc34.bold("Dry run \u2014 no changes made"));
25601
+ clack33.log.info(pc34.bold("Dry run \u2014 no changes made"));
25504
25602
  console.log();
25505
25603
  for (const t of compiled) {
25506
25604
  console.log(
@@ -25552,16 +25650,16 @@ async function templatesPush(options) {
25552
25650
  });
25553
25651
  } else {
25554
25652
  console.log();
25555
- clack32.log.success(
25653
+ clack33.log.success(
25556
25654
  pc34.green(
25557
25655
  `${compiled.length} template${compiled.length === 1 ? "" : "s"} pushed`
25558
25656
  )
25559
25657
  );
25560
25658
  if (unchanged.length > 0) {
25561
- clack32.log.info(`${unchanged.length} unchanged (use --force to re-push)`);
25659
+ clack33.log.info(`${unchanged.length} unchanged (use --force to re-push)`);
25562
25660
  }
25563
25661
  if (compileErrors.length > 0) {
25564
- clack32.log.error(`${compileErrors.length} failed to compile`);
25662
+ clack33.log.error(`${compileErrors.length} failed to compile`);
25565
25663
  }
25566
25664
  console.log();
25567
25665
  }
@@ -25696,20 +25794,21 @@ function transformVariablesForSes(content) {
25696
25794
  }
25697
25795
  async function pushToSES(templates, progress) {
25698
25796
  const results = [];
25699
- let hasAWSCredentials = false;
25700
- let region = "us-east-1";
25797
+ const { validateAWSCredentialsWithDetails: validateAWSCredentialsWithDetails2 } = await Promise.resolve().then(() => (init_aws(), aws_exports));
25798
+ let identity;
25701
25799
  try {
25702
- const { validateAWSCredentialsWithDetails: validateAWSCredentialsWithDetails2, getAWSRegion: getAWSRegion2 } = await Promise.resolve().then(() => (init_aws(), aws_exports));
25703
- await validateAWSCredentialsWithDetails2();
25704
- hasAWSCredentials = true;
25705
- region = await getAWSRegion2();
25800
+ const result = await validateAWSCredentialsWithDetails2();
25801
+ identity = result.identity;
25706
25802
  } catch {
25707
25803
  progress.info("No AWS credentials \u2014 skipping SES push");
25708
25804
  return templates.map((t) => ({ slug: t.slug, success: false }));
25709
25805
  }
25710
- if (!hasAWSCredentials) {
25711
- return templates.map((t) => ({ slug: t.slug, success: false }));
25712
- }
25806
+ const { resolveRegionForCommand: resolveRegionForCommand2 } = await Promise.resolve().then(() => (init_region_resolver(), region_resolver_exports));
25807
+ const region = await resolveRegionForCommand2({
25808
+ accountId: identity.accountId,
25809
+ service: "email",
25810
+ label: "email deployment"
25811
+ });
25713
25812
  const {
25714
25813
  SESv2Client: SESv2Client9,
25715
25814
  CreateEmailTemplateCommand,
@@ -25939,7 +26038,7 @@ init_test();
25939
26038
 
25940
26039
  // src/commands/email/upgrade.ts
25941
26040
  init_esm_shims();
25942
- import * as clack33 from "@clack/prompts";
26041
+ import * as clack34 from "@clack/prompts";
25943
26042
  import * as pulumi23 from "@pulumi/pulumi";
25944
26043
  import pc35 from "picocolors";
25945
26044
  init_events();
@@ -25955,11 +26054,12 @@ init_metadata();
25955
26054
  init_output();
25956
26055
  init_prompts();
25957
26056
  init_pulumi();
26057
+ init_region_resolver();
25958
26058
  async function upgrade(options) {
25959
26059
  const startTime = Date.now();
25960
26060
  let upgradeAction = "";
25961
26061
  if (!isJsonMode()) {
25962
- clack33.intro(
26062
+ clack34.intro(
25963
26063
  pc35.bold(
25964
26064
  options.preview ? "Wraps Upgrade Preview" : "Wraps Upgrade - Enhance Your Email Infrastructure"
25965
26065
  )
@@ -25978,17 +26078,18 @@ async function upgrade(options) {
25978
26078
  async () => validateAWSCredentials()
25979
26079
  );
25980
26080
  progress.info(`Connected to AWS account: ${pc35.cyan(identity.accountId)}`);
25981
- let region = options.region;
25982
- if (!region) {
25983
- const defaultRegion = await getAWSRegion();
25984
- region = defaultRegion;
25985
- }
26081
+ const region = await resolveRegionForCommand({
26082
+ accountId: identity.accountId,
26083
+ optionRegion: options.region,
26084
+ service: "email",
26085
+ label: "email deployment"
26086
+ });
25986
26087
  const metadata = await loadConnectionMetadata(identity.accountId, region);
25987
26088
  if (!metadata) {
25988
- clack33.log.error(
26089
+ clack34.log.error(
25989
26090
  `No Wraps connection found for account ${pc35.cyan(identity.accountId)} in region ${pc35.cyan(region)}`
25990
26091
  );
25991
- clack33.log.info(
26092
+ clack34.log.info(
25992
26093
  `Use ${pc35.cyan("wraps email init")} to create new infrastructure or ${pc35.cyan("wraps email connect")} to connect existing.`
25993
26094
  );
25994
26095
  process.exit(1);
@@ -26004,8 +26105,8 @@ ${pc35.bold("Current Configuration:")}
26004
26105
  }
26005
26106
  const config2 = metadata.services.email?.config;
26006
26107
  if (!config2) {
26007
- clack33.log.error("No email configuration found in metadata");
26008
- clack33.log.info(
26108
+ clack34.log.error("No email configuration found in metadata");
26109
+ clack34.log.info(
26009
26110
  `Use ${pc35.cyan("wraps email init")} to create new infrastructure.`
26010
26111
  );
26011
26112
  process.exit(1);
@@ -26158,12 +26259,12 @@ ${pc35.bold("Current Configuration:")}
26158
26259
  if (options.action) {
26159
26260
  upgradeAction = options.action;
26160
26261
  } else {
26161
- upgradeAction = await clack33.select({
26262
+ upgradeAction = await clack34.select({
26162
26263
  message: "What would you like to do?",
26163
26264
  options: upgradeOptions
26164
26265
  });
26165
- if (clack33.isCancel(upgradeAction)) {
26166
- clack33.cancel("Upgrade cancelled.");
26266
+ if (clack34.isCancel(upgradeAction)) {
26267
+ clack34.cancel("Upgrade cancelled.");
26167
26268
  process.exit(0);
26168
26269
  }
26169
26270
  }
@@ -26171,7 +26272,7 @@ ${pc35.bold("Current Configuration:")}
26171
26272
  let newPreset = metadata.services.email?.preset;
26172
26273
  switch (upgradeAction) {
26173
26274
  case "finish-tracking-domain": {
26174
- clack33.log.info(
26275
+ clack34.log.info(
26175
26276
  `Checking certificate status for ${pc35.cyan(config2.tracking?.customRedirectDomain ?? "")}...`
26176
26277
  );
26177
26278
  updatedConfig = { ...config2 };
@@ -26192,19 +26293,19 @@ ${pc35.bold("Current Configuration:")}
26192
26293
  disabled: currentPresetIdx >= 0 && idx <= currentPresetIdx ? "Current or lower tier" : void 0
26193
26294
  })).filter((p) => !p.disabled);
26194
26295
  if (availablePresets.length === 0) {
26195
- clack33.log.warn("Already on highest preset (Enterprise)");
26296
+ clack34.log.warn("Already on highest preset (Enterprise)");
26196
26297
  process.exit(0);
26197
26298
  }
26198
26299
  let selectedPreset;
26199
26300
  if (options.preset) {
26200
26301
  selectedPreset = options.preset;
26201
26302
  } else {
26202
- selectedPreset = await clack33.select({
26303
+ selectedPreset = await clack34.select({
26203
26304
  message: "Select new preset:",
26204
26305
  options: availablePresets
26205
26306
  });
26206
- if (clack33.isCancel(selectedPreset)) {
26207
- clack33.cancel("Upgrade cancelled.");
26307
+ if (clack34.isCancel(selectedPreset)) {
26308
+ clack34.cancel("Upgrade cancelled.");
26208
26309
  process.exit(0);
26209
26310
  }
26210
26311
  }
@@ -26215,7 +26316,7 @@ ${pc35.bold("Current Configuration:")}
26215
26316
  }
26216
26317
  case "archiving": {
26217
26318
  if (config2.emailArchiving?.enabled) {
26218
- const archivingAction = await clack33.select({
26319
+ const archivingAction = await clack34.select({
26219
26320
  message: "What would you like to do with email archiving?",
26220
26321
  options: [
26221
26322
  {
@@ -26230,17 +26331,17 @@ ${pc35.bold("Current Configuration:")}
26230
26331
  }
26231
26332
  ]
26232
26333
  });
26233
- if (clack33.isCancel(archivingAction)) {
26234
- clack33.cancel("Upgrade cancelled.");
26334
+ if (clack34.isCancel(archivingAction)) {
26335
+ clack34.cancel("Upgrade cancelled.");
26235
26336
  process.exit(0);
26236
26337
  }
26237
26338
  if (archivingAction === "disable") {
26238
- const confirmDisable = await clack33.confirm({
26339
+ const confirmDisable = await clack34.confirm({
26239
26340
  message: "Are you sure? Existing archived emails will remain, but new emails won't be archived.",
26240
26341
  initialValue: false
26241
26342
  });
26242
- if (clack33.isCancel(confirmDisable) || !confirmDisable) {
26243
- clack33.cancel("Archiving not disabled.");
26343
+ if (clack34.isCancel(confirmDisable) || !confirmDisable) {
26344
+ clack34.cancel("Archiving not disabled.");
26244
26345
  process.exit(0);
26245
26346
  }
26246
26347
  updatedConfig = {
@@ -26251,7 +26352,7 @@ ${pc35.bold("Current Configuration:")}
26251
26352
  }
26252
26353
  };
26253
26354
  } else {
26254
- const retention = await clack33.select({
26355
+ const retention = await clack34.select({
26255
26356
  message: "Email archive retention period:",
26256
26357
  options: [
26257
26358
  {
@@ -26287,8 +26388,8 @@ ${pc35.bold("Current Configuration:")}
26287
26388
  ],
26288
26389
  initialValue: config2.emailArchiving.retention
26289
26390
  });
26290
- if (clack33.isCancel(retention)) {
26291
- clack33.cancel("Upgrade cancelled.");
26391
+ if (clack34.isCancel(retention)) {
26392
+ clack34.cancel("Upgrade cancelled.");
26292
26393
  process.exit(0);
26293
26394
  }
26294
26395
  updatedConfig = {
@@ -26300,19 +26401,19 @@ ${pc35.bold("Current Configuration:")}
26300
26401
  };
26301
26402
  }
26302
26403
  } else {
26303
- const enableArchiving = await clack33.confirm({
26404
+ const enableArchiving = await clack34.confirm({
26304
26405
  message: "Enable email archiving? (Store full email content with HTML for viewing)",
26305
26406
  initialValue: true
26306
26407
  });
26307
- if (clack33.isCancel(enableArchiving)) {
26308
- clack33.cancel("Upgrade cancelled.");
26408
+ if (clack34.isCancel(enableArchiving)) {
26409
+ clack34.cancel("Upgrade cancelled.");
26309
26410
  process.exit(0);
26310
26411
  }
26311
26412
  if (!enableArchiving) {
26312
- clack33.log.info("Email archiving not enabled.");
26413
+ clack34.log.info("Email archiving not enabled.");
26313
26414
  process.exit(0);
26314
26415
  }
26315
- const retention = await clack33.select({
26416
+ const retention = await clack34.select({
26316
26417
  message: "Email archive retention period:",
26317
26418
  options: [
26318
26419
  {
@@ -26348,16 +26449,16 @@ ${pc35.bold("Current Configuration:")}
26348
26449
  ],
26349
26450
  initialValue: "90days"
26350
26451
  });
26351
- if (clack33.isCancel(retention)) {
26352
- clack33.cancel("Upgrade cancelled.");
26452
+ if (clack34.isCancel(retention)) {
26453
+ clack34.cancel("Upgrade cancelled.");
26353
26454
  process.exit(0);
26354
26455
  }
26355
- clack33.log.info(
26456
+ clack34.log.info(
26356
26457
  pc35.dim(
26357
26458
  "Archiving stores full RFC 822 emails with HTML, attachments, and headers"
26358
26459
  )
26359
26460
  );
26360
- clack33.log.info(
26461
+ clack34.log.info(
26361
26462
  pc35.dim(
26362
26463
  "Cost: $2/GB ingestion + $0.19/GB/month storage (~50KB per email)"
26363
26464
  )
@@ -26375,10 +26476,10 @@ ${pc35.bold("Current Configuration:")}
26375
26476
  }
26376
26477
  case "tracking-domain": {
26377
26478
  if (!config2.domain) {
26378
- clack33.log.error(
26479
+ clack34.log.error(
26379
26480
  "No sending domain configured. You must configure a sending domain before adding a custom tracking domain."
26380
26481
  );
26381
- clack33.log.info(
26482
+ clack34.log.info(
26382
26483
  `Use ${pc35.cyan("wraps email init")} to set up a sending domain first.`
26383
26484
  );
26384
26485
  process.exit(1);
@@ -26390,13 +26491,13 @@ ${pc35.bold("Current Configuration:")}
26390
26491
  );
26391
26492
  const sendingDomain = domains.find((d) => d.domain === config2.domain);
26392
26493
  if (!sendingDomain?.verified) {
26393
- clack33.log.error(
26494
+ clack34.log.error(
26394
26495
  `Sending domain ${pc35.cyan(config2.domain)} is not verified.`
26395
26496
  );
26396
- clack33.log.info(
26497
+ clack34.log.info(
26397
26498
  "You must verify your sending domain before adding a custom tracking domain."
26398
26499
  );
26399
- clack33.log.info(
26500
+ clack34.log.info(
26400
26501
  `Use ${pc35.cyan("wraps email verify")} to check DNS records and complete verification.`
26401
26502
  );
26402
26503
  process.exit(1);
@@ -26404,7 +26505,7 @@ ${pc35.bold("Current Configuration:")}
26404
26505
  progress.info(
26405
26506
  `Sending domain ${pc35.cyan(config2.domain)} is verified ${pc35.green("\u2713")}`
26406
26507
  );
26407
- const trackingDomain = await clack33.text({
26508
+ const trackingDomain = await clack34.text({
26408
26509
  message: "Custom tracking redirect domain:",
26409
26510
  placeholder: "track.yourdomain.com",
26410
26511
  initialValue: config2.tracking?.customRedirectDomain || "",
@@ -26414,25 +26515,25 @@ ${pc35.bold("Current Configuration:")}
26414
26515
  }
26415
26516
  }
26416
26517
  });
26417
- if (clack33.isCancel(trackingDomain)) {
26418
- clack33.cancel("Upgrade cancelled.");
26518
+ if (clack34.isCancel(trackingDomain)) {
26519
+ clack34.cancel("Upgrade cancelled.");
26419
26520
  process.exit(0);
26420
26521
  }
26421
- const enableHttps = await clack33.confirm({
26522
+ const enableHttps = await clack34.confirm({
26422
26523
  message: "Enable HTTPS tracking with CloudFront + SSL certificate?",
26423
26524
  initialValue: true
26424
26525
  });
26425
- if (clack33.isCancel(enableHttps)) {
26426
- clack33.cancel("Upgrade cancelled.");
26526
+ if (clack34.isCancel(enableHttps)) {
26527
+ clack34.cancel("Upgrade cancelled.");
26427
26528
  process.exit(0);
26428
26529
  }
26429
26530
  if (enableHttps) {
26430
- clack33.log.info(
26531
+ clack34.log.info(
26431
26532
  pc35.dim(
26432
26533
  "HTTPS tracking creates a CloudFront distribution with an SSL certificate."
26433
26534
  )
26434
26535
  );
26435
- clack33.log.info(
26536
+ clack34.log.info(
26436
26537
  pc35.dim(
26437
26538
  "This ensures all tracking links use secure HTTPS connections."
26438
26539
  )
@@ -26463,32 +26564,32 @@ ${pc35.bold("Current Configuration:")}
26463
26564
  progress.info(
26464
26565
  `Found ${pc35.cyan(getDNSProviderDisplayName(detectedProvider.provider))} ${pc35.green("\u2713")}`
26465
26566
  );
26466
- clack33.log.info(
26567
+ clack34.log.info(
26467
26568
  pc35.dim(
26468
26569
  "DNS records (SSL certificate validation + CloudFront) will be created automatically."
26469
26570
  )
26470
26571
  );
26471
26572
  } else {
26472
26573
  canAutomateDNS = false;
26473
- clack33.log.warn(
26574
+ clack34.log.warn(
26474
26575
  `No automatic DNS provider detected for ${pc35.cyan(trackingDomain || config2.domain)}`
26475
26576
  );
26476
- clack33.log.info(
26577
+ clack34.log.info(
26477
26578
  pc35.dim(
26478
26579
  "You'll need to manually create DNS records for SSL certificate validation and CloudFront."
26479
26580
  )
26480
26581
  );
26481
- clack33.log.info(
26582
+ clack34.log.info(
26482
26583
  pc35.dim("DNS record details will be shown after deployment.")
26483
26584
  );
26484
26585
  }
26485
26586
  }
26486
- const confirmHttps = await clack33.confirm({
26587
+ const confirmHttps = await clack34.confirm({
26487
26588
  message: canAutomateDNS ? "Proceed with automatic HTTPS setup?" : "Proceed with manual HTTPS setup (requires DNS configuration)?",
26488
26589
  initialValue: true
26489
26590
  });
26490
- if (clack33.isCancel(confirmHttps) || !confirmHttps) {
26491
- clack33.log.info("HTTPS tracking not enabled. Using HTTP tracking.");
26591
+ if (clack34.isCancel(confirmHttps) || !confirmHttps) {
26592
+ clack34.log.info("HTTPS tracking not enabled. Using HTTP tracking.");
26492
26593
  updatedConfig = {
26493
26594
  ...config2,
26494
26595
  tracking: {
@@ -26510,7 +26611,7 @@ ${pc35.bold("Current Configuration:")}
26510
26611
  };
26511
26612
  }
26512
26613
  } else {
26513
- clack33.log.info(
26614
+ clack34.log.info(
26514
26615
  pc35.dim(
26515
26616
  "Using HTTP tracking (standard). Links will use http:// protocol."
26516
26617
  )
@@ -26529,7 +26630,7 @@ ${pc35.bold("Current Configuration:")}
26529
26630
  break;
26530
26631
  }
26531
26632
  case "retention": {
26532
- const retention = await clack33.select({
26633
+ const retention = await clack34.select({
26533
26634
  message: "Email history retention period (event data in DynamoDB):",
26534
26635
  options: [
26535
26636
  { value: "7days", label: "7 days", hint: "Minimal storage cost" },
@@ -26553,16 +26654,16 @@ ${pc35.bold("Current Configuration:")}
26553
26654
  ],
26554
26655
  initialValue: config2.eventTracking?.archiveRetention || "90days"
26555
26656
  });
26556
- if (clack33.isCancel(retention)) {
26557
- clack33.cancel("Upgrade cancelled.");
26657
+ if (clack34.isCancel(retention)) {
26658
+ clack34.cancel("Upgrade cancelled.");
26558
26659
  process.exit(0);
26559
26660
  }
26560
- clack33.log.info(
26661
+ clack34.log.info(
26561
26662
  pc35.dim(
26562
26663
  "Note: This is for event data (sent, delivered, opened, etc.) stored in DynamoDB."
26563
26664
  )
26564
26665
  );
26565
- clack33.log.info(
26666
+ clack34.log.info(
26566
26667
  pc35.dim(
26567
26668
  "For full email content storage, use 'Enable email archiving' option."
26568
26669
  )
@@ -26580,7 +26681,7 @@ ${pc35.bold("Current Configuration:")}
26580
26681
  break;
26581
26682
  }
26582
26683
  case "events": {
26583
- const selectedEvents = await clack33.multiselect({
26684
+ const selectedEvents = await clack34.multiselect({
26584
26685
  message: "Select SES event types to track:",
26585
26686
  options: [
26586
26687
  { value: "SEND", label: "Send", hint: "Email sent to SES" },
@@ -26624,8 +26725,8 @@ ${pc35.bold("Current Configuration:")}
26624
26725
  ],
26625
26726
  required: true
26626
26727
  });
26627
- if (clack33.isCancel(selectedEvents)) {
26628
- clack33.cancel("Upgrade cancelled.");
26728
+ if (clack34.isCancel(selectedEvents)) {
26729
+ clack34.cancel("Upgrade cancelled.");
26629
26730
  process.exit(0);
26630
26731
  }
26631
26732
  updatedConfig = {
@@ -26640,16 +26741,16 @@ ${pc35.bold("Current Configuration:")}
26640
26741
  break;
26641
26742
  }
26642
26743
  case "dedicated-ip": {
26643
- const confirmed = await clack33.confirm({
26744
+ const confirmed = await clack34.confirm({
26644
26745
  message: "Enable dedicated IP? (Requires 100k+ emails/day, adds ~$50-100/mo)",
26645
26746
  initialValue: false
26646
26747
  });
26647
- if (clack33.isCancel(confirmed)) {
26648
- clack33.cancel("Upgrade cancelled.");
26748
+ if (clack34.isCancel(confirmed)) {
26749
+ clack34.cancel("Upgrade cancelled.");
26649
26750
  process.exit(0);
26650
26751
  }
26651
26752
  if (!confirmed) {
26652
- clack33.log.info("Dedicated IP not enabled.");
26753
+ clack34.log.info("Dedicated IP not enabled.");
26653
26754
  process.exit(0);
26654
26755
  }
26655
26756
  updatedConfig = {
@@ -26661,16 +26762,16 @@ ${pc35.bold("Current Configuration:")}
26661
26762
  }
26662
26763
  case "alerts": {
26663
26764
  if (!config2.reputationMetrics) {
26664
- clack33.log.warn("Reputation metrics must be enabled to use alerting.");
26665
- clack33.log.info(
26765
+ clack34.log.warn("Reputation metrics must be enabled to use alerting.");
26766
+ clack34.log.info(
26666
26767
  "This requires the Production or Enterprise preset, or enabling reputation metrics manually."
26667
26768
  );
26668
- const enableReputationMetrics = await clack33.confirm({
26769
+ const enableReputationMetrics = await clack34.confirm({
26669
26770
  message: "Enable reputation metrics now?",
26670
26771
  initialValue: true
26671
26772
  });
26672
- if (clack33.isCancel(enableReputationMetrics) || !enableReputationMetrics) {
26673
- clack33.cancel("Alerting not enabled.");
26773
+ if (clack34.isCancel(enableReputationMetrics) || !enableReputationMetrics) {
26774
+ clack34.cancel("Alerting not enabled.");
26674
26775
  process.exit(0);
26675
26776
  }
26676
26777
  updatedConfig = {
@@ -26679,13 +26780,13 @@ ${pc35.bold("Current Configuration:")}
26679
26780
  };
26680
26781
  }
26681
26782
  if (config2.alerts?.enabled) {
26682
- clack33.log.info(`Alerting is currently ${pc35.green("enabled")}`);
26783
+ clack34.log.info(`Alerting is currently ${pc35.green("enabled")}`);
26683
26784
  if (config2.alerts.notificationEmail) {
26684
- clack33.log.info(
26785
+ clack34.log.info(
26685
26786
  ` Notification email: ${pc35.cyan(config2.alerts.notificationEmail)}`
26686
26787
  );
26687
26788
  }
26688
- const alertsAction = await clack33.select({
26789
+ const alertsAction = await clack34.select({
26689
26790
  message: "What would you like to do?",
26690
26791
  options: [
26691
26792
  {
@@ -26705,17 +26806,17 @@ ${pc35.bold("Current Configuration:")}
26705
26806
  }
26706
26807
  ]
26707
26808
  });
26708
- if (clack33.isCancel(alertsAction)) {
26709
- clack33.cancel("Upgrade cancelled.");
26809
+ if (clack34.isCancel(alertsAction)) {
26810
+ clack34.cancel("Upgrade cancelled.");
26710
26811
  process.exit(0);
26711
26812
  }
26712
26813
  if (alertsAction === "disable") {
26713
- const confirmDisable = await clack33.confirm({
26814
+ const confirmDisable = await clack34.confirm({
26714
26815
  message: "Are you sure? You won't be notified if your reputation degrades.",
26715
26816
  initialValue: false
26716
26817
  });
26717
- if (clack33.isCancel(confirmDisable) || !confirmDisable) {
26718
- clack33.log.info("Alerting not disabled.");
26818
+ if (clack34.isCancel(confirmDisable) || !confirmDisable) {
26819
+ clack34.log.info("Alerting not disabled.");
26719
26820
  process.exit(0);
26720
26821
  }
26721
26822
  updatedConfig = {
@@ -26723,7 +26824,7 @@ ${pc35.bold("Current Configuration:")}
26723
26824
  alerts: { enabled: false }
26724
26825
  };
26725
26826
  } else if (alertsAction === "change-email") {
26726
- const notificationEmail = await clack33.text({
26827
+ const notificationEmail = await clack34.text({
26727
26828
  message: "Notification email address:",
26728
26829
  placeholder: "alerts@yourcompany.com",
26729
26830
  initialValue: config2.alerts.notificationEmail || "",
@@ -26733,8 +26834,8 @@ ${pc35.bold("Current Configuration:")}
26733
26834
  }
26734
26835
  }
26735
26836
  });
26736
- if (clack33.isCancel(notificationEmail)) {
26737
- clack33.cancel("Upgrade cancelled.");
26837
+ if (clack34.isCancel(notificationEmail)) {
26838
+ clack34.cancel("Upgrade cancelled.");
26738
26839
  process.exit(0);
26739
26840
  }
26740
26841
  updatedConfig = {
@@ -26746,14 +26847,14 @@ ${pc35.bold("Current Configuration:")}
26746
26847
  }
26747
26848
  };
26748
26849
  } else if (alertsAction === "change-thresholds") {
26749
- clack33.log.info(`
26850
+ clack34.log.info(`
26750
26851
  ${pc35.bold("Alert Thresholds")}`);
26751
- clack33.log.info(
26852
+ clack34.log.info(
26752
26853
  pc35.dim("These thresholds warn you BEFORE AWS takes action:")
26753
26854
  );
26754
- clack33.log.info(pc35.dim(" AWS warns at 5% bounce, 0.1% complaint"));
26755
- clack33.log.info(pc35.dim(" Gmail blocks at 0.3% complaint rate\n"));
26756
- const thresholdPreset = await clack33.select({
26855
+ clack34.log.info(pc35.dim(" AWS warns at 5% bounce, 0.1% complaint"));
26856
+ clack34.log.info(pc35.dim(" Gmail blocks at 0.3% complaint rate\n"));
26857
+ const thresholdPreset = await clack34.select({
26757
26858
  message: "Choose threshold sensitivity:",
26758
26859
  options: [
26759
26860
  {
@@ -26773,8 +26874,8 @@ ${pc35.bold("Alert Thresholds")}`);
26773
26874
  }
26774
26875
  ]
26775
26876
  });
26776
- if (clack33.isCancel(thresholdPreset)) {
26777
- clack33.cancel("Upgrade cancelled.");
26877
+ if (clack34.isCancel(thresholdPreset)) {
26878
+ clack34.cancel("Upgrade cancelled.");
26778
26879
  process.exit(0);
26779
26880
  }
26780
26881
  const thresholdConfigs = {
@@ -26807,27 +26908,27 @@ ${pc35.bold("Alert Thresholds")}`);
26807
26908
  };
26808
26909
  }
26809
26910
  } else {
26810
- clack33.log.info(`
26911
+ clack34.log.info(`
26811
26912
  ${pc35.bold("Reputation Alerts")}
26812
26913
  `);
26813
- clack33.log.info(
26914
+ clack34.log.info(
26814
26915
  pc35.dim("Get notified when your email reputation is at risk:")
26815
26916
  );
26816
- clack33.log.info(pc35.dim(" - Bounce rate warnings (before AWS review)"));
26817
- clack33.log.info(
26917
+ clack34.log.info(pc35.dim(" - Bounce rate warnings (before AWS review)"));
26918
+ clack34.log.info(
26818
26919
  pc35.dim(" - Complaint rate warnings (before Gmail blocks you)")
26819
26920
  );
26820
- clack33.log.info(pc35.dim(" - DLQ alerts (event processing failures)"));
26821
- clack33.log.info(pc35.dim("\nCost: ~$0.50/mo (5 CloudWatch alarms)\n"));
26822
- const enableAlerts = await clack33.confirm({
26921
+ clack34.log.info(pc35.dim(" - DLQ alerts (event processing failures)"));
26922
+ clack34.log.info(pc35.dim("\nCost: ~$0.50/mo (5 CloudWatch alarms)\n"));
26923
+ const enableAlerts = await clack34.confirm({
26823
26924
  message: "Enable reputation alerts?",
26824
26925
  initialValue: true
26825
26926
  });
26826
- if (clack33.isCancel(enableAlerts) || !enableAlerts) {
26827
- clack33.log.info("Alerting not enabled.");
26927
+ if (clack34.isCancel(enableAlerts) || !enableAlerts) {
26928
+ clack34.log.info("Alerting not enabled.");
26828
26929
  process.exit(0);
26829
26930
  }
26830
- const notificationEmail = await clack33.text({
26931
+ const notificationEmail = await clack34.text({
26831
26932
  message: "Notification email address:",
26832
26933
  placeholder: "alerts@yourcompany.com",
26833
26934
  validate: (value) => {
@@ -26839,11 +26940,11 @@ ${pc35.bold("Reputation Alerts")}
26839
26940
  }
26840
26941
  }
26841
26942
  });
26842
- if (clack33.isCancel(notificationEmail)) {
26843
- clack33.cancel("Upgrade cancelled.");
26943
+ if (clack34.isCancel(notificationEmail)) {
26944
+ clack34.cancel("Upgrade cancelled.");
26844
26945
  process.exit(0);
26845
26946
  }
26846
- clack33.log.info(
26947
+ clack34.log.info(
26847
26948
  pc35.dim("\nYou'll receive an email to confirm your subscription.")
26848
26949
  );
26849
26950
  updatedConfig = {
@@ -26870,18 +26971,18 @@ ${pc35.bold("Reputation Alerts")}
26870
26971
  }
26871
26972
  case "wraps-dashboard": {
26872
26973
  if (!config2.eventTracking?.enabled) {
26873
- clack33.log.warn(
26974
+ clack34.log.warn(
26874
26975
  "Event tracking must be enabled to connect to Wraps Dashboard."
26875
26976
  );
26876
- clack33.log.info(
26977
+ clack34.log.info(
26877
26978
  "Enabling event tracking will allow SES events to be sent to the dashboard."
26878
26979
  );
26879
- const enableEventTracking = await clack33.confirm({
26980
+ const enableEventTracking = await clack34.confirm({
26880
26981
  message: "Enable event tracking now?",
26881
26982
  initialValue: true
26882
26983
  });
26883
- if (clack33.isCancel(enableEventTracking) || !enableEventTracking) {
26884
- clack33.cancel("Dashboard connection cancelled.");
26984
+ if (clack34.isCancel(enableEventTracking) || !enableEventTracking) {
26985
+ clack34.cancel("Dashboard connection cancelled.");
26885
26986
  process.exit(0);
26886
26987
  }
26887
26988
  updatedConfig = {
@@ -26904,10 +27005,10 @@ ${pc35.bold("Reputation Alerts")}
26904
27005
  }
26905
27006
  const existingSecret = metadata.services.email?.webhookSecret;
26906
27007
  if (existingSecret) {
26907
- clack33.log.info(
27008
+ clack34.log.info(
26908
27009
  `Currently connected to Wraps Dashboard (AWS Account: ${pc35.cyan(metadata.accountId)})`
26909
27010
  );
26910
- const action = await clack33.select({
27011
+ const action = await clack34.select({
26911
27012
  message: "What would you like to do?",
26912
27013
  options: [
26913
27014
  {
@@ -26927,17 +27028,17 @@ ${pc35.bold("Reputation Alerts")}
26927
27028
  }
26928
27029
  ]
26929
27030
  });
26930
- if (clack33.isCancel(action) || action === "cancel") {
26931
- clack33.log.info("No changes made.");
27031
+ if (clack34.isCancel(action) || action === "cancel") {
27032
+ clack34.log.info("No changes made.");
26932
27033
  process.exit(0);
26933
27034
  }
26934
27035
  if (action === "disconnect") {
26935
- const confirmDisconnect = await clack33.confirm({
27036
+ const confirmDisconnect = await clack34.confirm({
26936
27037
  message: "Are you sure? Events will no longer be sent to the Wraps Dashboard.",
26937
27038
  initialValue: false
26938
27039
  });
26939
- if (clack33.isCancel(confirmDisconnect) || !confirmDisconnect) {
26940
- clack33.log.info("Disconnect cancelled.");
27040
+ if (clack34.isCancel(confirmDisconnect) || !confirmDisconnect) {
27041
+ clack34.log.info("Disconnect cancelled.");
26941
27042
  process.exit(0);
26942
27043
  }
26943
27044
  if (metadata.services.email) {
@@ -26949,12 +27050,12 @@ ${pc35.bold("Reputation Alerts")}
26949
27050
  }
26950
27051
  }
26951
27052
  const webhookSecret = generateWebhookSecret();
26952
- clack33.log.info(`
27053
+ clack34.log.info(`
26953
27054
  ${pc35.bold("Webhook Configuration:")}`);
26954
- clack33.log.info(
27055
+ clack34.log.info(
26955
27056
  pc35.dim("A secure webhook secret has been generated for authentication.")
26956
27057
  );
26957
- clack33.log.info(
27058
+ clack34.log.info(
26958
27059
  pc35.dim(
26959
27060
  "After deployment, you'll need to register this secret in the dashboard.\n"
26960
27061
  )
@@ -27000,18 +27101,18 @@ ${pc35.bold("Webhook Configuration:")}`);
27000
27101
  }
27001
27102
  };
27002
27103
  if (!config2.eventTracking?.enabled) {
27003
- clack33.log.warn(
27104
+ clack34.log.warn(
27004
27105
  "Event tracking must be enabled to configure a webhook endpoint."
27005
27106
  );
27006
- clack33.log.info(
27107
+ clack34.log.info(
27007
27108
  "Enabling event tracking will allow SES events to be sent to your endpoint."
27008
27109
  );
27009
- const enableEventTracking = await clack33.confirm({
27110
+ const enableEventTracking = await clack34.confirm({
27010
27111
  message: "Enable event tracking now?",
27011
27112
  initialValue: true
27012
27113
  });
27013
- if (clack33.isCancel(enableEventTracking) || !enableEventTracking) {
27014
- clack33.cancel("Webhook configuration cancelled.");
27114
+ if (clack34.isCancel(enableEventTracking) || !enableEventTracking) {
27115
+ clack34.cancel("Webhook configuration cancelled.");
27015
27116
  process.exit(0);
27016
27117
  }
27017
27118
  updatedConfig = {
@@ -27033,10 +27134,10 @@ ${pc35.bold("Webhook Configuration:")}`);
27033
27134
  };
27034
27135
  }
27035
27136
  if (config2.userWebhook?.enabled) {
27036
- clack33.log.info(
27137
+ clack34.log.info(
27037
27138
  `Webhook endpoint currently sending events to: ${pc35.cyan(config2.userWebhook.url)}`
27038
27139
  );
27039
- const action = await clack33.select({
27140
+ const action = await clack34.select({
27040
27141
  message: "What would you like to do?",
27041
27142
  options: [
27042
27143
  {
@@ -27061,17 +27162,17 @@ ${pc35.bold("Webhook Configuration:")}`);
27061
27162
  }
27062
27163
  ]
27063
27164
  });
27064
- if (clack33.isCancel(action) || action === "cancel") {
27065
- clack33.log.info("No changes made.");
27165
+ if (clack34.isCancel(action) || action === "cancel") {
27166
+ clack34.log.info("No changes made.");
27066
27167
  process.exit(0);
27067
27168
  }
27068
27169
  if (action === "disable") {
27069
- const confirmDisable = await clack33.confirm({
27170
+ const confirmDisable = await clack34.confirm({
27070
27171
  message: "Are you sure? Events will no longer be sent to your webhook endpoint.",
27071
27172
  initialValue: false
27072
27173
  });
27073
- if (clack33.isCancel(confirmDisable) || !confirmDisable) {
27074
- clack33.log.info("Webhook not disabled.");
27174
+ if (clack34.isCancel(confirmDisable) || !confirmDisable) {
27175
+ clack34.log.info("Webhook not disabled.");
27075
27176
  process.exit(0);
27076
27177
  }
27077
27178
  updatedConfig = {
@@ -27082,13 +27183,13 @@ ${pc35.bold("Webhook Configuration:")}`);
27082
27183
  break;
27083
27184
  }
27084
27185
  if (action === "change-url") {
27085
- const newUrl = await clack33.text({
27186
+ const newUrl = await clack34.text({
27086
27187
  message: "New webhook URL:",
27087
27188
  placeholder: "https://your-app.com/webhooks/email-events",
27088
27189
  validate: validateWebhookUrl
27089
27190
  });
27090
- if (clack33.isCancel(newUrl)) {
27091
- clack33.cancel("Webhook configuration cancelled.");
27191
+ if (clack34.isCancel(newUrl)) {
27192
+ clack34.cancel("Webhook configuration cancelled.");
27092
27193
  process.exit(0);
27093
27194
  }
27094
27195
  updatedConfig = {
@@ -27116,20 +27217,20 @@ ${pc35.bold("Webhook Configuration:")}`);
27116
27217
  break;
27117
27218
  }
27118
27219
  } else {
27119
- clack33.log.info(`
27220
+ clack34.log.info(`
27120
27221
  ${pc35.bold("Webhook Endpoint")}
27121
27222
  `);
27122
- clack33.log.info(
27223
+ clack34.log.info(
27123
27224
  pc35.dim("Send SES events (send, delivery, open, click, bounce, etc.)")
27124
27225
  );
27125
- clack33.log.info(pc35.dim("to your own HTTP endpoint in real-time.\n"));
27126
- const webhookUrl = await clack33.text({
27226
+ clack34.log.info(pc35.dim("to your own HTTP endpoint in real-time.\n"));
27227
+ const webhookUrl = await clack34.text({
27127
27228
  message: "Webhook URL (must be HTTPS):",
27128
27229
  placeholder: "https://your-app.com/webhooks/email-events",
27129
27230
  validate: validateWebhookUrl
27130
27231
  });
27131
- if (clack33.isCancel(webhookUrl)) {
27132
- clack33.cancel("Webhook configuration cancelled.");
27232
+ if (clack34.isCancel(webhookUrl)) {
27233
+ clack34.cancel("Webhook configuration cancelled.");
27133
27234
  process.exit(0);
27134
27235
  }
27135
27236
  const secret2 = generateWebhookSecret();
@@ -27147,10 +27248,10 @@ ${pc35.bold("Webhook Endpoint")}
27147
27248
  }
27148
27249
  case "smtp-credentials": {
27149
27250
  if (metadata.services.email?.smtpCredentials?.enabled) {
27150
- clack33.log.info(
27251
+ clack34.log.info(
27151
27252
  `SMTP credentials are currently ${pc35.green("enabled")} (created ${metadata.services.email.smtpCredentials.createdAt})`
27152
27253
  );
27153
- const smtpAction = await clack33.select({
27254
+ const smtpAction = await clack34.select({
27154
27255
  message: "What would you like to do?",
27155
27256
  options: [
27156
27257
  {
@@ -27170,17 +27271,17 @@ ${pc35.bold("Webhook Endpoint")}
27170
27271
  }
27171
27272
  ]
27172
27273
  });
27173
- if (clack33.isCancel(smtpAction) || smtpAction === "cancel") {
27174
- clack33.log.info("No changes made.");
27274
+ if (clack34.isCancel(smtpAction) || smtpAction === "cancel") {
27275
+ clack34.log.info("No changes made.");
27175
27276
  process.exit(0);
27176
27277
  }
27177
27278
  if (smtpAction === "disable") {
27178
- const confirmDisable = await clack33.confirm({
27279
+ const confirmDisable = await clack34.confirm({
27179
27280
  message: "Are you sure? Any systems using these credentials will stop working immediately.",
27180
27281
  initialValue: false
27181
27282
  });
27182
- if (clack33.isCancel(confirmDisable) || !confirmDisable) {
27183
- clack33.log.info("SMTP credentials not disabled.");
27283
+ if (clack34.isCancel(confirmDisable) || !confirmDisable) {
27284
+ clack34.log.info("SMTP credentials not disabled.");
27184
27285
  process.exit(0);
27185
27286
  }
27186
27287
  updatedConfig = {
@@ -27193,43 +27294,43 @@ ${pc35.bold("Webhook Endpoint")}
27193
27294
  newPreset = void 0;
27194
27295
  break;
27195
27296
  }
27196
- clack33.log.info(
27297
+ clack34.log.info(
27197
27298
  "\nRotating credentials will invalidate your current SMTP password."
27198
27299
  );
27199
- clack33.log.warn(
27300
+ clack34.log.warn(
27200
27301
  "You will need to update all systems using the old credentials."
27201
27302
  );
27202
- const confirmRotate = await clack33.confirm({
27303
+ const confirmRotate = await clack34.confirm({
27203
27304
  message: "Generate new SMTP credentials?",
27204
27305
  initialValue: false
27205
27306
  });
27206
- if (clack33.isCancel(confirmRotate) || !confirmRotate) {
27207
- clack33.log.info("Credential rotation cancelled.");
27307
+ if (clack34.isCancel(confirmRotate) || !confirmRotate) {
27308
+ clack34.log.info("Credential rotation cancelled.");
27208
27309
  process.exit(0);
27209
27310
  }
27210
27311
  }
27211
- clack33.log.info(`
27312
+ clack34.log.info(`
27212
27313
  ${pc35.bold("SMTP Credentials for Legacy Systems")}
27213
27314
  `);
27214
- clack33.log.info(
27315
+ clack34.log.info(
27215
27316
  pc35.dim("Generate SMTP username/password that works with:")
27216
27317
  );
27217
- clack33.log.info(pc35.dim(" - PHP mail() and PHPMailer"));
27218
- clack33.log.info(pc35.dim(" - WordPress (WP Mail SMTP plugin)"));
27219
- clack33.log.info(pc35.dim(" - Nodemailer and other SMTP libraries"));
27220
- clack33.log.info(pc35.dim(" - Any SMTP-compatible email client"));
27318
+ clack34.log.info(pc35.dim(" - PHP mail() and PHPMailer"));
27319
+ clack34.log.info(pc35.dim(" - WordPress (WP Mail SMTP plugin)"));
27320
+ clack34.log.info(pc35.dim(" - Nodemailer and other SMTP libraries"));
27321
+ clack34.log.info(pc35.dim(" - Any SMTP-compatible email client"));
27221
27322
  console.log("");
27222
- clack33.log.warn(
27323
+ clack34.log.warn(
27223
27324
  "Credentials will be shown ONCE after deployment - save them immediately!"
27224
27325
  );
27225
27326
  console.log("");
27226
27327
  if (!options.yes) {
27227
- const confirmCreate = await clack33.confirm({
27328
+ const confirmCreate = await clack34.confirm({
27228
27329
  message: "Create SMTP credentials?",
27229
27330
  initialValue: true
27230
27331
  });
27231
- if (clack33.isCancel(confirmCreate) || !confirmCreate) {
27232
- clack33.log.info("SMTP credentials not created.");
27332
+ if (clack34.isCancel(confirmCreate) || !confirmCreate) {
27333
+ clack34.log.info("SMTP credentials not created.");
27233
27334
  process.exit(0);
27234
27335
  }
27235
27336
  }
@@ -27244,7 +27345,7 @@ ${pc35.bold("SMTP Credentials for Legacy Systems")}
27244
27345
  break;
27245
27346
  }
27246
27347
  case "hosting-provider": {
27247
- const newProvider = await clack33.select({
27348
+ const newProvider = await clack34.select({
27248
27349
  message: "Where is your app hosted?",
27249
27350
  options: [
27250
27351
  {
@@ -27269,12 +27370,12 @@ ${pc35.bold("SMTP Credentials for Legacy Systems")}
27269
27370
  }
27270
27371
  ]
27271
27372
  });
27272
- if (clack33.isCancel(newProvider)) {
27273
- clack33.cancel("Upgrade cancelled.");
27373
+ if (clack34.isCancel(newProvider)) {
27374
+ clack34.cancel("Upgrade cancelled.");
27274
27375
  process.exit(0);
27275
27376
  }
27276
27377
  if (newProvider === metadata.provider) {
27277
- clack33.log.info("Provider unchanged \u2014 no changes needed.");
27378
+ clack34.log.info("Provider unchanged \u2014 no changes needed.");
27278
27379
  process.exit(0);
27279
27380
  }
27280
27381
  metadata.provider = newProvider;
@@ -27305,12 +27406,12 @@ ${pc35.bold("Cost Impact:")}`);
27305
27406
  }
27306
27407
  console.log("");
27307
27408
  if (!(options.yes || options.preview)) {
27308
- const confirmed = await clack33.confirm({
27409
+ const confirmed = await clack34.confirm({
27309
27410
  message: "Proceed with upgrade?",
27310
27411
  initialValue: true
27311
27412
  });
27312
- if (clack33.isCancel(confirmed) || !confirmed) {
27313
- clack33.cancel("Upgrade cancelled.");
27413
+ if (clack34.isCancel(confirmed) || !confirmed) {
27414
+ clack34.cancel("Upgrade cancelled.");
27314
27415
  process.exit(0);
27315
27416
  }
27316
27417
  }
@@ -27357,15 +27458,15 @@ ${pc35.bold("Cost Impact:")}`);
27357
27458
  );
27358
27459
  await new Promise((resolve) => setTimeout(resolve, 2e3));
27359
27460
  } else if (!caaResult.success) {
27360
- clack33.log.warn(
27461
+ clack34.log.warn(
27361
27462
  `Could not verify CAA records: ${caaResult.error || "Unknown error"}`
27362
27463
  );
27363
- clack33.log.info(
27464
+ clack34.log.info(
27364
27465
  pc35.dim(
27365
27466
  "If certificate issuance fails, you may need to add a CAA record manually:"
27366
27467
  )
27367
27468
  );
27368
- clack33.log.info(pc35.dim(` ${parentDomain} CAA 0 issue "amazon.com"`));
27469
+ clack34.log.info(pc35.dim(` ${parentDomain} CAA 0 issue "amazon.com"`));
27369
27470
  }
27370
27471
  }
27371
27472
  }
@@ -27429,7 +27530,7 @@ ${pc35.bold("Cost Impact:")}`);
27429
27530
  costEstimate: costComparison,
27430
27531
  commandName: "wraps email upgrade"
27431
27532
  });
27432
- clack33.outro(
27533
+ clack34.outro(
27433
27534
  pc35.green("Preview complete. Run without --preview to upgrade.")
27434
27535
  );
27435
27536
  trackServiceUpgrade("email", {
@@ -27607,7 +27708,7 @@ ${pc35.bold("Cost Impact:")}`);
27607
27708
  );
27608
27709
  }
27609
27710
  } else {
27610
- clack33.log.warn(
27711
+ clack34.log.warn(
27611
27712
  credResult.error || `Unable to validate ${getDNSProviderDisplayName(dnsProvider)} credentials`
27612
27713
  );
27613
27714
  }
@@ -27623,7 +27724,7 @@ ${pc35.bold("Cost Impact:")}`);
27623
27724
  };
27624
27725
  const dnsRecords = buildEmailDNSRecords(dnsData);
27625
27726
  console.log();
27626
- clack33.note(
27727
+ clack34.note(
27627
27728
  formatManualDNSInstructions(dnsRecords),
27628
27729
  "DNS Records \u2014 Add these to your DNS provider"
27629
27730
  );
@@ -27933,7 +28034,7 @@ init_output();
27933
28034
  import { existsSync as existsSync14 } from "fs";
27934
28035
  import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile9 } from "fs/promises";
27935
28036
  import { join as join16 } from "path";
27936
- import * as clack34 from "@clack/prompts";
28037
+ import * as clack35 from "@clack/prompts";
27937
28038
  import pc36 from "picocolors";
27938
28039
 
27939
28040
  // src/commands/email/workflows/claude-content.ts
@@ -28325,7 +28426,7 @@ async function workflowsInit(options) {
28325
28426
  const cwd = process.cwd();
28326
28427
  const workflowsDir = join16(cwd, "wraps", "workflows");
28327
28428
  if (!isJsonMode()) {
28328
- clack34.intro(pc36.bold("Workflows as Code"));
28429
+ clack35.intro(pc36.bold("Workflows as Code"));
28329
28430
  }
28330
28431
  const progress = new DeploymentProgress();
28331
28432
  if (existsSync14(workflowsDir) && !options.force) {
@@ -28335,7 +28436,7 @@ async function workflowsInit(options) {
28335
28436
  (f) => f.endsWith(".ts") && !f.startsWith("_")
28336
28437
  );
28337
28438
  if (tsFiles.length > 0 && !options.force && !isJsonMode()) {
28338
- clack34.log.warn(
28439
+ clack35.log.warn(
28339
28440
  `${pc36.cyan("wraps/workflows/")} already contains ${tsFiles.length} workflow file(s). Use ${pc36.bold("--force")} to overwrite.`
28340
28441
  );
28341
28442
  }
@@ -28402,7 +28503,7 @@ async function workflowsInit(options) {
28402
28503
  return;
28403
28504
  }
28404
28505
  console.log();
28405
- clack34.log.success(pc36.green("Workflows as Code initialized!"));
28506
+ clack35.log.success(pc36.green("Workflows as Code initialized!"));
28406
28507
  console.log();
28407
28508
  console.log(` ${pc36.dim("Directory:")} ${pc36.cyan("wraps/workflows/")}`);
28408
28509
  if (!options.noExample) {
@@ -28445,7 +28546,7 @@ init_esm_shims();
28445
28546
  init_events();
28446
28547
  import { existsSync as existsSync16 } from "fs";
28447
28548
  import { join as join18 } from "path";
28448
- import * as clack35 from "@clack/prompts";
28549
+ import * as clack36 from "@clack/prompts";
28449
28550
  import pc37 from "picocolors";
28450
28551
 
28451
28552
  // src/utils/email/workflow-transform.ts
@@ -29296,7 +29397,7 @@ async function workflowsPush(options) {
29296
29397
  throw errors.wrapsConfigNotFound();
29297
29398
  }
29298
29399
  if (!isJsonMode()) {
29299
- clack35.intro(pc37.bold("Push Workflows"));
29400
+ clack36.intro(pc37.bold("Push Workflows"));
29300
29401
  }
29301
29402
  const progress = new DeploymentProgress();
29302
29403
  progress.start("Loading configuration");
@@ -29311,7 +29412,7 @@ async function workflowsPush(options) {
29311
29412
  errors: []
29312
29413
  });
29313
29414
  } else {
29314
- clack35.log.info("No workflows/ directory found.");
29415
+ clack36.log.info("No workflows/ directory found.");
29315
29416
  }
29316
29417
  return;
29317
29418
  }
@@ -29324,7 +29425,7 @@ async function workflowsPush(options) {
29324
29425
  errors: []
29325
29426
  });
29326
29427
  } else {
29327
- clack35.log.info("No workflows found to push.");
29428
+ clack36.log.info("No workflows found to push.");
29328
29429
  }
29329
29430
  return;
29330
29431
  }
@@ -29393,7 +29494,7 @@ async function workflowsPush(options) {
29393
29494
  });
29394
29495
  } else {
29395
29496
  console.log();
29396
- clack35.log.error(
29497
+ clack36.log.error(
29397
29498
  pc37.red("Cannot push due to validation errors. Fix errors and retry.")
29398
29499
  );
29399
29500
  console.log();
@@ -29408,7 +29509,7 @@ async function workflowsPush(options) {
29408
29509
  errors: []
29409
29510
  });
29410
29511
  } else {
29411
- clack35.log.info(
29512
+ clack36.log.info(
29412
29513
  `${unchanged.length} workflow(s) unchanged. Use --force to re-push.`
29413
29514
  );
29414
29515
  }
@@ -29429,7 +29530,7 @@ async function workflowsPush(options) {
29429
29530
  });
29430
29531
  } else {
29431
29532
  console.log();
29432
- clack35.log.info(pc37.bold("Dry run \u2014 no changes made"));
29533
+ clack36.log.info(pc37.bold("Dry run \u2014 no changes made"));
29433
29534
  console.log();
29434
29535
  for (const w of toProcess) {
29435
29536
  console.log(
@@ -29486,20 +29587,20 @@ async function workflowsPush(options) {
29486
29587
  } else {
29487
29588
  console.log();
29488
29589
  if (enabled.length > 0) {
29489
- clack35.log.success(
29590
+ clack36.log.success(
29490
29591
  pc37.green(`${enabled.length} workflow(s) pushed and enabled`)
29491
29592
  );
29492
29593
  }
29493
29594
  if (drafts.length > 0) {
29494
- clack35.log.success(
29595
+ clack36.log.success(
29495
29596
  pc37.green(`${drafts.length} workflow(s) pushed as draft`)
29496
29597
  );
29497
29598
  }
29498
29599
  if (unchanged.length > 0) {
29499
- clack35.log.info(`${unchanged.length} unchanged (use --force to re-push)`);
29600
+ clack36.log.info(`${unchanged.length} unchanged (use --force to re-push)`);
29500
29601
  }
29501
29602
  if (conflicts.length > 0) {
29502
- clack35.log.error(
29603
+ clack36.log.error(
29503
29604
  `${conflicts.length} workflow(s) skipped due to dashboard edits. Use --force to overwrite.`
29504
29605
  );
29505
29606
  for (const c of conflicts) {
@@ -29663,7 +29764,7 @@ init_esm_shims();
29663
29764
  init_events();
29664
29765
  import { existsSync as existsSync17 } from "fs";
29665
29766
  import { join as join19 } from "path";
29666
- import * as clack36 from "@clack/prompts";
29767
+ import * as clack37 from "@clack/prompts";
29667
29768
  import pc38 from "picocolors";
29668
29769
  init_errors();
29669
29770
  init_json_output();
@@ -29677,7 +29778,7 @@ async function workflowsValidate(options) {
29677
29778
  throw errors.wrapsConfigNotFound();
29678
29779
  }
29679
29780
  if (!isJsonMode()) {
29680
- clack36.intro(pc38.bold("Validate Workflows"));
29781
+ clack37.intro(pc38.bold("Validate Workflows"));
29681
29782
  }
29682
29783
  const progress = new DeploymentProgress();
29683
29784
  progress.start("Loading configuration");
@@ -29688,7 +29789,7 @@ async function workflowsValidate(options) {
29688
29789
  if (isJsonMode()) {
29689
29790
  jsonSuccess("email.workflows.validate", { workflows: [], errors: [] });
29690
29791
  } else {
29691
- clack36.log.info("No workflows/ directory found.");
29792
+ clack37.log.info("No workflows/ directory found.");
29692
29793
  }
29693
29794
  return;
29694
29795
  }
@@ -29697,7 +29798,7 @@ async function workflowsValidate(options) {
29697
29798
  if (isJsonMode()) {
29698
29799
  jsonSuccess("email.workflows.validate", { workflows: [], errors: [] });
29699
29800
  } else {
29700
- clack36.log.info("No workflows found to validate.");
29801
+ clack37.log.info("No workflows found to validate.");
29701
29802
  }
29702
29803
  return;
29703
29804
  }
@@ -29774,18 +29875,18 @@ async function workflowsValidate(options) {
29774
29875
  const invalidCount = validationResults.filter((r) => !r.valid).length;
29775
29876
  const parseErrorCount = parseErrors.length;
29776
29877
  if (parseErrorCount === 0 && invalidCount === 0) {
29777
- clack36.log.success(
29878
+ clack37.log.success(
29778
29879
  pc38.green(`${validCount} workflow(s) validated successfully`)
29779
29880
  );
29780
29881
  } else {
29781
29882
  if (validCount > 0) {
29782
- clack36.log.success(pc38.green(`${validCount} workflow(s) valid`));
29883
+ clack37.log.success(pc38.green(`${validCount} workflow(s) valid`));
29783
29884
  }
29784
29885
  if (invalidCount > 0) {
29785
- clack36.log.error(pc38.red(`${invalidCount} workflow(s) have errors`));
29886
+ clack37.log.error(pc38.red(`${invalidCount} workflow(s) have errors`));
29786
29887
  }
29787
29888
  if (parseErrorCount > 0) {
29788
- clack36.log.error(
29889
+ clack37.log.error(
29789
29890
  pc38.red(`${parseErrorCount} workflow(s) failed to parse`)
29790
29891
  );
29791
29892
  }
@@ -29819,11 +29920,11 @@ async function workflowsValidate(options) {
29819
29920
  // src/commands/news.ts
29820
29921
  init_esm_shims();
29821
29922
  init_events();
29822
- import * as clack37 from "@clack/prompts";
29923
+ import * as clack38 from "@clack/prompts";
29823
29924
  import pc39 from "picocolors";
29824
29925
  async function news() {
29825
29926
  trackCommand("news", { success: true });
29826
- clack37.intro(pc39.bold("What's New in Wraps"));
29927
+ clack38.intro(pc39.bold("What's New in Wraps"));
29827
29928
  console.log();
29828
29929
  console.log(" See the latest updates, features, and improvements:");
29829
29930
  console.log();
@@ -29839,7 +29940,7 @@ async function news() {
29839
29940
  init_esm_shims();
29840
29941
  init_events();
29841
29942
  init_json_output();
29842
- import * as clack38 from "@clack/prompts";
29943
+ import * as clack39 from "@clack/prompts";
29843
29944
  import pc40 from "picocolors";
29844
29945
  function getBaseStatements() {
29845
29946
  return [
@@ -30231,7 +30332,7 @@ function buildPolicy(service, preset) {
30231
30332
  };
30232
30333
  }
30233
30334
  function displaySummary(service, preset) {
30234
- clack38.intro(pc40.bold("Wraps Required AWS Permissions"));
30335
+ clack39.intro(pc40.bold("Wraps Required AWS Permissions"));
30235
30336
  const serviceLabel = service ? service.toUpperCase() : "All Services";
30236
30337
  const presetLabel = preset ? preset.charAt(0).toUpperCase() + preset.slice(1) : "All Features";
30237
30338
  console.log(`
@@ -30325,7 +30426,7 @@ async function permissions(options) {
30325
30426
  console.log("2. Create the policy in AWS Console:");
30326
30427
  console.log(" IAM > Policies > Create Policy > JSON\n");
30327
30428
  console.log("3. Attach to your IAM user/role\n");
30328
- clack38.outro(
30429
+ clack39.outro(
30329
30430
  pc40.green("Run with --json to get the full IAM policy document")
30330
30431
  );
30331
30432
  }
@@ -30343,7 +30444,7 @@ import {
30343
30444
  IAMClient as IAMClient3,
30344
30445
  PutRolePolicyCommand
30345
30446
  } from "@aws-sdk/client-iam";
30346
- import { confirm as confirm18, intro as intro34, isCancel as isCancel24, log as log36, outro as outro20, select as select16 } from "@clack/prompts";
30447
+ import { confirm as confirm18, intro as intro34, isCancel as isCancel25, log as log36, outro as outro20, select as select17 } from "@clack/prompts";
30347
30448
  import * as pulumi24 from "@pulumi/pulumi";
30348
30449
  import pc41 from "picocolors";
30349
30450
  init_events();
@@ -30356,6 +30457,7 @@ init_metadata();
30356
30457
  init_output();
30357
30458
  init_prompts();
30358
30459
  init_pulumi();
30460
+ init_region_resolver();
30359
30461
  function buildConsolePolicyDocument(emailConfig, smsConfig) {
30360
30462
  const statements = [];
30361
30463
  statements.push({
@@ -30532,10 +30634,11 @@ async function validateAndLoadMetadata(options, progress) {
30532
30634
  async () => validateAWSCredentials()
30533
30635
  );
30534
30636
  progress.info(`Connected to AWS account: ${pc41.cyan(identity.accountId)}`);
30535
- let region = options.region;
30536
- if (!region) {
30537
- region = await getAWSRegion();
30538
- }
30637
+ const region = await resolveRegionForCommand({
30638
+ accountId: identity.accountId,
30639
+ optionRegion: options.region,
30640
+ label: "connection"
30641
+ });
30539
30642
  const metadata = await loadConnectionMetadata(identity.accountId, region);
30540
30643
  if (!metadata) {
30541
30644
  progress.stop();
@@ -30694,7 +30797,7 @@ async function resolveOrganization() {
30694
30797
  if (orgs.length === 1) {
30695
30798
  return orgs[0];
30696
30799
  }
30697
- const selected = await select16({
30800
+ const selected = await select17({
30698
30801
  message: "Which organization should this AWS account connect to?",
30699
30802
  options: orgs.map((org) => ({
30700
30803
  value: org.id,
@@ -30702,7 +30805,7 @@ async function resolveOrganization() {
30702
30805
  hint: org.slug
30703
30806
  }))
30704
30807
  });
30705
- if (isCancel24(selected)) {
30808
+ if (isCancel25(selected)) {
30706
30809
  outro20("Operation cancelled");
30707
30810
  process.exit(0);
30708
30811
  }
@@ -30768,7 +30871,7 @@ async function authenticatedConnect(token, options) {
30768
30871
  message: "Enable event tracking now?",
30769
30872
  initialValue: true
30770
30873
  });
30771
- if (isCancel24(enableTracking) || !enableTracking) {
30874
+ if (isCancel25(enableTracking) || !enableTracking) {
30772
30875
  outro20("Platform connection cancelled.");
30773
30876
  process.exit(0);
30774
30877
  }
@@ -30913,10 +31016,11 @@ async function connect3(options) {
30913
31016
  async () => validateAWSCredentials()
30914
31017
  );
30915
31018
  progress.info(`Connected to AWS account: ${pc41.cyan(identity.accountId)}`);
30916
- let region = options.region;
30917
- if (!region) {
30918
- region = await getAWSRegion();
30919
- }
31019
+ const region = await resolveRegionForCommand({
31020
+ accountId: identity.accountId,
31021
+ optionRegion: options.region,
31022
+ label: "connection"
31023
+ });
30920
31024
  const metadata = await loadConnectionMetadata(identity.accountId, region);
30921
31025
  if (!metadata) {
30922
31026
  progress.stop();
@@ -30962,7 +31066,7 @@ Run ${pc41.cyan("wraps email init")} or ${pc41.cyan("wraps sms init")} first.
30962
31066
  message: "Enable event tracking now?",
30963
31067
  initialValue: true
30964
31068
  });
30965
- if (isCancel24(enableEventTracking) || !enableEventTracking) {
31069
+ if (isCancel25(enableEventTracking) || !enableEventTracking) {
30966
31070
  outro20("Platform connection cancelled.");
30967
31071
  process.exit(0);
30968
31072
  }
@@ -30990,7 +31094,7 @@ Run ${pc41.cyan("wraps email init")} or ${pc41.cyan("wraps sms init")} first.
30990
31094
  log36.info(
30991
31095
  `Already connected to Wraps Platform (AWS Account: ${pc41.cyan(metadata.accountId)})`
30992
31096
  );
30993
- const action = await select16({
31097
+ const action = await select17({
30994
31098
  message: "What would you like to do?",
30995
31099
  options: [
30996
31100
  {
@@ -31010,7 +31114,7 @@ Run ${pc41.cyan("wraps email init")} or ${pc41.cyan("wraps sms init")} first.
31010
31114
  }
31011
31115
  ]
31012
31116
  });
31013
- if (isCancel24(action)) {
31117
+ if (isCancel25(action)) {
31014
31118
  outro20("Operation cancelled");
31015
31119
  process.exit(0);
31016
31120
  }
@@ -31021,7 +31125,7 @@ Run ${pc41.cyan("wraps email init")} or ${pc41.cyan("wraps sms init")} first.
31021
31125
  message: "Are you sure? Events will no longer be sent to the Wraps Platform.",
31022
31126
  initialValue: false
31023
31127
  });
31024
- if (isCancel24(confirmDisconnect) || !confirmDisconnect) {
31128
+ if (isCancel25(confirmDisconnect) || !confirmDisconnect) {
31025
31129
  outro20("Disconnect cancelled");
31026
31130
  process.exit(0);
31027
31131
  }
@@ -31171,10 +31275,10 @@ ${pc41.bold("Next Steps:")}`);
31171
31275
 
31172
31276
  // src/commands/platform/index.ts
31173
31277
  init_esm_shims();
31174
- import * as clack39 from "@clack/prompts";
31278
+ import * as clack40 from "@clack/prompts";
31175
31279
  import pc42 from "picocolors";
31176
31280
  async function platform() {
31177
- clack39.intro(pc42.bold("Wraps Platform"));
31281
+ clack40.intro(pc42.bold("Wraps Platform"));
31178
31282
  console.log();
31179
31283
  console.log(
31180
31284
  " The Wraps Platform extends the free CLI with hosted features:"
@@ -31227,12 +31331,13 @@ init_aws();
31227
31331
  init_json_output();
31228
31332
  init_metadata();
31229
31333
  init_output();
31334
+ init_region_resolver();
31230
31335
  import {
31231
31336
  CreateRoleCommand as CreateRoleCommand2,
31232
31337
  GetRoleCommand as GetRoleCommand2,
31233
31338
  IAMClient as IAMClient4
31234
31339
  } from "@aws-sdk/client-iam";
31235
- import { confirm as confirm19, intro as intro36, isCancel as isCancel25, log as log37, outro as outro21 } from "@clack/prompts";
31340
+ import { confirm as confirm19, intro as intro36, isCancel as isCancel26, log as log37, outro as outro21 } from "@clack/prompts";
31236
31341
  import pc43 from "picocolors";
31237
31342
  async function updateRole(options) {
31238
31343
  const startTime = Date.now();
@@ -31244,7 +31349,11 @@ async function updateRole(options) {
31244
31349
  "Validating AWS credentials",
31245
31350
  async () => validateAWSCredentials()
31246
31351
  );
31247
- const region = options.region || await getAWSRegion();
31352
+ const region = await resolveRegionForCommand({
31353
+ accountId: identity.accountId,
31354
+ optionRegion: options.region,
31355
+ label: "connection"
31356
+ });
31248
31357
  const metadata = await loadConnectionMetadata(identity.accountId, region);
31249
31358
  if (!metadata) {
31250
31359
  progress.stop();
@@ -31297,7 +31406,7 @@ Run ${pc43.cyan("wraps email init")} to deploy infrastructure first.
31297
31406
  message: `${actionLabel} IAM role ${pc43.cyan(roleName)} with latest permissions?`,
31298
31407
  initialValue: true
31299
31408
  });
31300
- if (isCancel25(shouldContinue) || !shouldContinue) {
31409
+ if (isCancel26(shouldContinue) || !shouldContinue) {
31301
31410
  outro21(`${actionLabel} cancelled`);
31302
31411
  process.exit(0);
31303
31412
  }
@@ -31616,7 +31725,7 @@ function buildConsolePolicyDocument2(emailConfig, smsConfig) {
31616
31725
 
31617
31726
  // src/commands/shared/dashboard.ts
31618
31727
  init_esm_shims();
31619
- import * as clack40 from "@clack/prompts";
31728
+ import * as clack41 from "@clack/prompts";
31620
31729
  import * as pulumi25 from "@pulumi/pulumi";
31621
31730
  import getPort from "get-port";
31622
31731
  import open2 from "open";
@@ -34267,7 +34376,7 @@ init_output();
34267
34376
  init_pulumi();
34268
34377
  async function dashboard(options) {
34269
34378
  await ensurePulumiInstalled();
34270
- clack40.intro(pc44.bold("Wraps Dashboard"));
34379
+ clack41.intro(pc44.bold("Wraps Dashboard"));
34271
34380
  const progress = new DeploymentProgress();
34272
34381
  const identity = await progress.execute(
34273
34382
  "Validating AWS credentials",
@@ -34308,7 +34417,7 @@ async function dashboard(options) {
34308
34417
  }
34309
34418
  } catch (_error) {
34310
34419
  progress.stop();
34311
- clack40.log.error("No Wraps infrastructure found");
34420
+ clack41.log.error("No Wraps infrastructure found");
34312
34421
  console.log(
34313
34422
  `\\nRun ${pc44.cyan("wraps email init")}, ${pc44.cyan("wraps sms init")}, or ${pc44.cyan("wraps storage init")} to deploy infrastructure first.\\n`
34314
34423
  );
@@ -34352,7 +34461,7 @@ async function dashboard(options) {
34352
34461
  }
34353
34462
  const port = options.port || await getPort({ port: [5555, 5556, 5557, 5558, 5559] });
34354
34463
  progress.stop();
34355
- clack40.log.success("Starting dashboard server...");
34464
+ clack41.log.success("Starting dashboard server...");
34356
34465
  console.log(
34357
34466
  `${pc44.dim("Using current AWS credentials (no role assumption)")}\\n`
34358
34467
  );
@@ -34409,7 +34518,7 @@ init_aws();
34409
34518
  init_errors();
34410
34519
  init_json_output();
34411
34520
  init_metadata();
34412
- import * as clack41 from "@clack/prompts";
34521
+ import * as clack42 from "@clack/prompts";
34413
34522
  import pc45 from "picocolors";
34414
34523
  async function destroy(options) {
34415
34524
  trackCommand("destroy", { success: true });
@@ -34421,9 +34530,9 @@ async function destroy(options) {
34421
34530
  );
34422
34531
  }
34423
34532
  if (!isJsonMode()) {
34424
- clack41.intro(pc45.bold("Wraps Infrastructure Teardown"));
34533
+ clack42.intro(pc45.bold("Wraps Infrastructure Teardown"));
34425
34534
  }
34426
- const spinner10 = clack41.spinner();
34535
+ const spinner10 = clack42.spinner();
34427
34536
  spinner10.start("Validating AWS credentials");
34428
34537
  let identity;
34429
34538
  try {
@@ -34440,7 +34549,7 @@ async function destroy(options) {
34440
34549
  deployedServices.push("email");
34441
34550
  }
34442
34551
  if (deployedServices.length === 0) {
34443
- clack41.log.warn("No Wraps services found in this region");
34552
+ clack42.log.warn("No Wraps services found in this region");
34444
34553
  console.log(
34445
34554
  `
34446
34555
  Run ${pc45.cyan("wraps email init")} to deploy infrastructure.
@@ -34450,7 +34559,7 @@ Run ${pc45.cyan("wraps email init")} to deploy infrastructure.
34450
34559
  }
34451
34560
  if (deployedServices.length === 1) {
34452
34561
  const service = deployedServices[0];
34453
- clack41.log.info(`Found ${pc45.cyan(service)} service deployed`);
34562
+ clack42.log.info(`Found ${pc45.cyan(service)} service deployed`);
34454
34563
  if (service === "email") {
34455
34564
  await emailDestroy(options);
34456
34565
  return;
@@ -34465,7 +34574,7 @@ Run ${pc45.cyan("wraps email init")} to deploy infrastructure.
34465
34574
  jsonSuccess("destroy", { destroyed: true });
34466
34575
  return;
34467
34576
  }
34468
- const serviceToDestroy = await clack41.select({
34577
+ const serviceToDestroy = await clack42.select({
34469
34578
  message: "Which service would you like to destroy?",
34470
34579
  options: [
34471
34580
  ...deployedServices.map((s) => ({
@@ -34480,15 +34589,15 @@ Run ${pc45.cyan("wraps email init")} to deploy infrastructure.
34480
34589
  }
34481
34590
  ]
34482
34591
  });
34483
- if (clack41.isCancel(serviceToDestroy)) {
34484
- clack41.cancel("Operation cancelled.");
34592
+ if (clack42.isCancel(serviceToDestroy)) {
34593
+ clack42.cancel("Operation cancelled.");
34485
34594
  process.exit(0);
34486
34595
  }
34487
34596
  if ((serviceToDestroy === "email" || serviceToDestroy === "all") && deployedServices.includes("email")) {
34488
34597
  await emailDestroy(options);
34489
34598
  }
34490
34599
  if (serviceToDestroy === "all") {
34491
- clack41.outro(pc45.green("All Wraps infrastructure has been removed"));
34600
+ clack42.outro(pc45.green("All Wraps infrastructure has been removed"));
34492
34601
  }
34493
34602
  }
34494
34603
 
@@ -34500,7 +34609,7 @@ init_fs();
34500
34609
  init_json_output();
34501
34610
  init_output();
34502
34611
  init_pulumi();
34503
- import * as clack42 from "@clack/prompts";
34612
+ import * as clack43 from "@clack/prompts";
34504
34613
  import * as pulumi26 from "@pulumi/pulumi";
34505
34614
  import pc46 from "picocolors";
34506
34615
  async function status(_options) {
@@ -34508,7 +34617,7 @@ async function status(_options) {
34508
34617
  const startTime = Date.now();
34509
34618
  const progress = new DeploymentProgress();
34510
34619
  if (!isJsonMode()) {
34511
- clack42.intro(pc46.bold("Wraps Infrastructure Status"));
34620
+ clack43.intro(pc46.bold("Wraps Infrastructure Status"));
34512
34621
  }
34513
34622
  const identity = await progress.execute(
34514
34623
  "Loading infrastructure status",
@@ -34571,7 +34680,7 @@ async function status(_options) {
34571
34680
  return;
34572
34681
  }
34573
34682
  console.log();
34574
- clack42.note(
34683
+ clack43.note(
34575
34684
  services.map((s) => {
34576
34685
  if (s.status === "deployed") {
34577
34686
  const details = s.details ? pc46.dim(` (${s.details})`) : "";
@@ -34610,13 +34719,12 @@ ${pc46.bold("Dashboard:")} ${pc46.blue("https://app.wraps.dev")}`);
34610
34719
 
34611
34720
  // src/commands/sms/destroy.ts
34612
34721
  init_esm_shims();
34613
- import * as clack43 from "@clack/prompts";
34722
+ import * as clack44 from "@clack/prompts";
34614
34723
  import * as pulumi28 from "@pulumi/pulumi";
34615
34724
  import pc47 from "picocolors";
34616
34725
 
34617
34726
  // src/infrastructure/sms-stack.ts
34618
34727
  init_esm_shims();
34619
- init_constants();
34620
34728
  import * as aws20 from "@pulumi/aws";
34621
34729
  import * as pulumi27 from "@pulumi/pulumi";
34622
34730
  init_resource_checks();
@@ -34732,12 +34840,10 @@ function createSMSOptOutList() {
34732
34840
  }
34733
34841
  });
34734
34842
  }
34735
- async function findExistingPhoneNumber(phoneNumberType) {
34843
+ async function findExistingPhoneNumber(phoneNumberType, region) {
34736
34844
  try {
34737
34845
  const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePhoneNumbersCommand: DescribePhoneNumbersCommand2 } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
34738
- const client = new PinpointSMSVoiceV2Client5({
34739
- region: getDefaultRegion()
34740
- });
34846
+ const client = new PinpointSMSVoiceV2Client5({ region });
34741
34847
  const numberTypeMap = {
34742
34848
  simulator: "SIMULATOR",
34743
34849
  "toll-free": "TOLL_FREE",
@@ -34771,14 +34877,14 @@ async function findExistingPhoneNumber(phoneNumberType) {
34771
34877
  throw error;
34772
34878
  }
34773
34879
  }
34774
- async function createSMSPhoneNumber(phoneNumberType, optOutList) {
34880
+ async function createSMSPhoneNumber(phoneNumberType, optOutList, region) {
34775
34881
  const numberTypeMap = {
34776
34882
  simulator: "SIMULATOR",
34777
34883
  "toll-free": "TOLL_FREE",
34778
34884
  "10dlc": "TEN_DLC",
34779
34885
  "short-code": "SHORT_CODE"
34780
34886
  };
34781
- const existingArn = await findExistingPhoneNumber(phoneNumberType);
34887
+ const existingArn = await findExistingPhoneNumber(phoneNumberType, region);
34782
34888
  const phoneConfig = {
34783
34889
  isoCountryCode: "US",
34784
34890
  messageType: "TRANSACTIONAL",
@@ -34815,11 +34921,11 @@ async function createSMSPhoneNumber(phoneNumberType, optOutList) {
34815
34921
  }
34816
34922
  );
34817
34923
  }
34818
- async function createSMSSQSResources() {
34924
+ async function createSMSSQSResources(config2) {
34819
34925
  const dlqName = "wraps-sms-events-dlq";
34820
34926
  const queueName = "wraps-sms-events";
34821
- const dlqUrl = await sqsQueueExists(dlqName);
34822
- const queueUrl = await sqsQueueExists(queueName);
34927
+ const dlqUrl = await sqsQueueExists(dlqName, config2.region);
34928
+ const queueUrl = await sqsQueueExists(queueName, config2.region);
34823
34929
  const dlqConfig = {
34824
34930
  name: dlqName,
34825
34931
  messageRetentionSeconds: 1209600,
@@ -34866,7 +34972,7 @@ async function createSMSSQSResources() {
34866
34972
  }
34867
34973
  async function createSMSSNSResources(config2) {
34868
34974
  const topicName = "wraps-sms-events";
34869
- const topicArn = await snsTopicExists(topicName);
34975
+ const topicArn = await snsTopicExists(topicName, config2.region);
34870
34976
  const topicConfig = {
34871
34977
  name: topicName,
34872
34978
  tags: {
@@ -34929,9 +35035,9 @@ async function createSMSSNSResources(config2) {
34929
35035
  );
34930
35036
  return { topic, subscription };
34931
35037
  }
34932
- async function createSMSDynamoDBTable() {
35038
+ async function createSMSDynamoDBTable(config2) {
34933
35039
  const tableName = "wraps-sms-history";
34934
- const exists = await tableExists(tableName);
35040
+ const exists = await tableExists(tableName, config2.region);
34935
35041
  const tableConfig = {
34936
35042
  name: tableName,
34937
35043
  billingMode: "PAY_PER_REQUEST",
@@ -35096,23 +35202,25 @@ async function deploySMSStack(config2) {
35096
35202
  if (smsConfig.phoneNumberType) {
35097
35203
  phoneNumber = await createSMSPhoneNumber(
35098
35204
  smsConfig.phoneNumberType,
35099
- optOutList
35205
+ optOutList,
35206
+ config2.region
35100
35207
  );
35101
35208
  }
35102
35209
  let sqsResources;
35103
35210
  if (smsConfig.eventTracking?.enabled) {
35104
- sqsResources = await createSMSSQSResources();
35211
+ sqsResources = await createSMSSQSResources({ region: config2.region });
35105
35212
  }
35106
35213
  let snsResources;
35107
35214
  if (smsConfig.eventTracking?.enabled && sqsResources) {
35108
35215
  snsResources = await createSMSSNSResources({
35109
35216
  queueArn: sqsResources.queue.arn,
35110
- queueUrl: sqsResources.queue.url
35217
+ queueUrl: sqsResources.queue.url,
35218
+ region: config2.region
35111
35219
  });
35112
35220
  }
35113
35221
  let dynamoTable;
35114
35222
  if (smsConfig.eventTracking?.dynamoDBHistory) {
35115
- dynamoTable = await createSMSDynamoDBTable();
35223
+ dynamoTable = await createSMSDynamoDBTable({ region: config2.region });
35116
35224
  }
35117
35225
  let lambdaFunction;
35118
35226
  if (smsConfig.eventTracking?.dynamoDBHistory && dynamoTable && sqsResources) {
@@ -35461,7 +35569,7 @@ async function smsDestroy(options) {
35461
35569
  );
35462
35570
  }
35463
35571
  if (!isJsonMode()) {
35464
- clack43.intro(
35572
+ clack44.intro(
35465
35573
  pc47.bold(
35466
35574
  options.preview ? "SMS Infrastructure Destruction Preview" : "SMS Infrastructure Teardown"
35467
35575
  )
@@ -35488,15 +35596,15 @@ async function smsDestroy(options) {
35488
35596
  `Available regions: ${smsConnections.map((c) => c.region).join(", ")}`
35489
35597
  );
35490
35598
  }
35491
- const selectedRegion = await clack43.select({
35599
+ const selectedRegion = await clack44.select({
35492
35600
  message: "Multiple SMS deployments found. Which region to destroy?",
35493
35601
  options: smsConnections.map((conn) => ({
35494
35602
  value: conn.region,
35495
35603
  label: conn.region
35496
35604
  }))
35497
35605
  });
35498
- if (clack43.isCancel(selectedRegion)) {
35499
- clack43.cancel("Operation cancelled");
35606
+ if (clack44.isCancel(selectedRegion)) {
35607
+ clack44.cancel("Operation cancelled");
35500
35608
  process.exit(0);
35501
35609
  }
35502
35610
  region = selectedRegion;
@@ -35507,18 +35615,18 @@ async function smsDestroy(options) {
35507
35615
  const storedStackName = smsService?.pulumiStackName;
35508
35616
  if (!smsService) {
35509
35617
  progress.stop();
35510
- clack43.log.warn("No SMS infrastructure found");
35618
+ clack44.log.warn("No SMS infrastructure found");
35511
35619
  process.exit(0);
35512
35620
  }
35513
35621
  if (!(options.force || options.preview)) {
35514
- const confirmed = await clack43.confirm({
35622
+ const confirmed = await clack44.confirm({
35515
35623
  message: pc47.red(
35516
35624
  "Are you sure you want to destroy all SMS infrastructure?"
35517
35625
  ),
35518
35626
  initialValue: false
35519
35627
  });
35520
- if (clack43.isCancel(confirmed) || !confirmed) {
35521
- clack43.cancel("Destruction cancelled.");
35628
+ if (clack44.isCancel(confirmed) || !confirmed) {
35629
+ clack44.cancel("Destruction cancelled.");
35522
35630
  process.exit(0);
35523
35631
  }
35524
35632
  }
@@ -35550,7 +35658,7 @@ async function smsDestroy(options) {
35550
35658
  costEstimate: "Monthly cost after destruction: $0.00",
35551
35659
  commandName: "wraps sms destroy"
35552
35660
  });
35553
- clack43.outro(
35661
+ clack44.outro(
35554
35662
  pc47.green("Preview complete. Run without --preview to destroy.")
35555
35663
  );
35556
35664
  trackServiceRemoved("sms", {
@@ -35562,7 +35670,7 @@ async function smsDestroy(options) {
35562
35670
  progress.stop();
35563
35671
  const errorMessage = error instanceof Error ? error.message : String(error);
35564
35672
  if (errorMessage.includes("No SMS infrastructure found")) {
35565
- clack43.log.warn("No SMS infrastructure found to preview");
35673
+ clack44.log.warn("No SMS infrastructure found to preview");
35566
35674
  process.exit(0);
35567
35675
  }
35568
35676
  trackError("PREVIEW_FAILED", "sms destroy", { step: "preview" });
@@ -35611,7 +35719,7 @@ async function smsDestroy(options) {
35611
35719
  progress.stop();
35612
35720
  const errorMessage = error instanceof Error ? error.message : String(error);
35613
35721
  if (errorMessage.includes("No SMS infrastructure found")) {
35614
- clack43.log.warn("No SMS infrastructure found");
35722
+ clack44.log.warn("No SMS infrastructure found");
35615
35723
  if (metadata) {
35616
35724
  removeServiceFromConnection(metadata, "sms");
35617
35725
  await saveConnectionMetadata(metadata);
@@ -35624,7 +35732,7 @@ async function smsDestroy(options) {
35624
35732
  }
35625
35733
  trackError("DESTROY_FAILED", "sms destroy", { step: "destroy" });
35626
35734
  destroyFailed = true;
35627
- clack43.log.warn(
35735
+ clack44.log.warn(
35628
35736
  "Some resources may not have been fully removed. You can re-run this command or clean up manually in the AWS console."
35629
35737
  );
35630
35738
  }
@@ -35647,11 +35755,11 @@ async function smsDestroy(options) {
35647
35755
  return;
35648
35756
  }
35649
35757
  if (destroyFailed) {
35650
- clack43.outro(
35758
+ clack44.outro(
35651
35759
  pc47.yellow("SMS infrastructure partially removed. Metadata cleaned up.")
35652
35760
  );
35653
35761
  } else {
35654
- clack43.outro(pc47.green("SMS infrastructure has been removed"));
35762
+ clack44.outro(pc47.green("SMS infrastructure has been removed"));
35655
35763
  console.log(`
35656
35764
  ${pc47.bold("Cleaned up:")}`);
35657
35765
  console.log(` ${pc47.green("\u2713")} Phone number released`);
@@ -35673,7 +35781,7 @@ Run ${pc47.cyan("wraps sms init")} to deploy infrastructure again.
35673
35781
 
35674
35782
  // src/commands/sms/init.ts
35675
35783
  init_esm_shims();
35676
- import * as clack44 from "@clack/prompts";
35784
+ import * as clack45 from "@clack/prompts";
35677
35785
  import * as pulumi29 from "@pulumi/pulumi";
35678
35786
  import pc48 from "picocolors";
35679
35787
  init_events();
@@ -36094,7 +36202,7 @@ function validateSMSConfig(config2) {
36094
36202
 
36095
36203
  // src/commands/sms/init.ts
36096
36204
  async function promptPhoneNumberType() {
36097
- const result = await clack44.select({
36205
+ const result = await clack45.select({
36098
36206
  message: "Select phone number type:",
36099
36207
  options: [
36100
36208
  {
@@ -36114,14 +36222,14 @@ async function promptPhoneNumberType() {
36114
36222
  }
36115
36223
  ]
36116
36224
  });
36117
- if (clack44.isCancel(result)) {
36118
- clack44.cancel("Operation cancelled.");
36225
+ if (clack45.isCancel(result)) {
36226
+ clack45.cancel("Operation cancelled.");
36119
36227
  process.exit(0);
36120
36228
  }
36121
36229
  return result;
36122
36230
  }
36123
36231
  async function promptSMSPreset() {
36124
- const result = await clack44.select({
36232
+ const result = await clack45.select({
36125
36233
  message: "Choose configuration preset:",
36126
36234
  options: [
36127
36235
  {
@@ -36146,8 +36254,8 @@ async function promptSMSPreset() {
36146
36254
  }
36147
36255
  ]
36148
36256
  });
36149
- if (clack44.isCancel(result)) {
36150
- clack44.cancel("Operation cancelled.");
36257
+ if (clack45.isCancel(result)) {
36258
+ clack45.cancel("Operation cancelled.");
36151
36259
  process.exit(0);
36152
36260
  }
36153
36261
  return result;
@@ -36167,7 +36275,7 @@ var COMMON_COUNTRIES = [
36167
36275
  { code: "IN", name: "India" }
36168
36276
  ];
36169
36277
  async function promptAllowedCountries() {
36170
- const result = await clack44.multiselect({
36278
+ const result = await clack45.multiselect({
36171
36279
  message: "Select countries to allow SMS delivery (blocks all others):",
36172
36280
  options: COMMON_COUNTRIES.map((c) => ({
36173
36281
  value: c.code,
@@ -36176,14 +36284,14 @@ async function promptAllowedCountries() {
36176
36284
  initialValues: ["US"],
36177
36285
  required: true
36178
36286
  });
36179
- if (clack44.isCancel(result)) {
36180
- clack44.cancel("Operation cancelled.");
36287
+ if (clack45.isCancel(result)) {
36288
+ clack45.cancel("Operation cancelled.");
36181
36289
  process.exit(0);
36182
36290
  }
36183
36291
  return result;
36184
36292
  }
36185
36293
  async function promptEstimatedSMSVolume() {
36186
- const result = await clack44.select({
36294
+ const result = await clack45.select({
36187
36295
  message: "Estimated messages per month:",
36188
36296
  options: [
36189
36297
  { value: 100, label: "< 100 (Testing)" },
@@ -36193,8 +36301,8 @@ async function promptEstimatedSMSVolume() {
36193
36301
  { value: 1e5, label: "50,000+" }
36194
36302
  ]
36195
36303
  });
36196
- if (clack44.isCancel(result)) {
36197
- clack44.cancel("Operation cancelled.");
36304
+ if (clack45.isCancel(result)) {
36305
+ clack45.cancel("Operation cancelled.");
36198
36306
  process.exit(0);
36199
36307
  }
36200
36308
  return result;
@@ -36202,7 +36310,7 @@ async function promptEstimatedSMSVolume() {
36202
36310
  async function init3(options) {
36203
36311
  const startTime = Date.now();
36204
36312
  if (!isJsonMode()) {
36205
- clack44.intro(pc48.bold("Wraps SMS Infrastructure Setup"));
36313
+ clack45.intro(pc48.bold("Wraps SMS Infrastructure Setup"));
36206
36314
  }
36207
36315
  const progress = new DeploymentProgress();
36208
36316
  const wasAutoInstalled = await progress.execute(
@@ -36228,10 +36336,10 @@ async function init3(options) {
36228
36336
  region
36229
36337
  );
36230
36338
  if (existingConnection?.services?.sms) {
36231
- clack44.log.warn(
36339
+ clack45.log.warn(
36232
36340
  `SMS already configured for account ${pc48.cyan(identity.accountId)} in region ${pc48.cyan(region)}`
36233
36341
  );
36234
- clack44.log.info(`Use ${pc48.cyan("wraps sms status")} to view current setup`);
36342
+ clack45.log.info(`Use ${pc48.cyan("wraps sms status")} to view current setup`);
36235
36343
  process.exit(0);
36236
36344
  }
36237
36345
  let preset = options.preset;
@@ -36248,12 +36356,12 @@ async function init3(options) {
36248
36356
  optOutManagement: true,
36249
36357
  sendingEnabled: true
36250
36358
  };
36251
- const enableEventTracking = await clack44.confirm({
36359
+ const enableEventTracking = await clack45.confirm({
36252
36360
  message: "Enable event tracking (EventBridge + DynamoDB)?",
36253
36361
  initialValue: false
36254
36362
  });
36255
- if (clack44.isCancel(enableEventTracking)) {
36256
- clack44.cancel("Operation cancelled.");
36363
+ if (clack45.isCancel(enableEventTracking)) {
36364
+ clack45.cancel("Operation cancelled.");
36257
36365
  process.exit(0);
36258
36366
  }
36259
36367
  if (enableEventTracking) {
@@ -36278,12 +36386,12 @@ ${pc48.bold("Fraud Protection")} - Block SMS to countries where you don't do bus
36278
36386
  const allowedCountries = await promptAllowedCountries();
36279
36387
  let aitFiltering = false;
36280
36388
  if (smsConfig.phoneNumberType !== "simulator") {
36281
- const enableAIT = await clack44.confirm({
36389
+ const enableAIT = await clack45.confirm({
36282
36390
  message: "Enable AIT (Artificially Inflated Traffic) filtering? (adds per-message cost)",
36283
36391
  initialValue: false
36284
36392
  });
36285
- if (clack44.isCancel(enableAIT)) {
36286
- clack44.cancel("Operation cancelled.");
36393
+ if (clack45.isCancel(enableAIT)) {
36394
+ clack45.cancel("Operation cancelled.");
36287
36395
  process.exit(0);
36288
36396
  }
36289
36397
  aitFiltering = enableAIT;
@@ -36297,19 +36405,19 @@ ${pc48.bold("Fraud Protection")} - Block SMS to countries where you don't do bus
36297
36405
  progress.info(`
36298
36406
  ${pc48.bold("Cost Estimate:")}`);
36299
36407
  const costSummary = getSMSCostSummary(smsConfig, estimatedVolume);
36300
- clack44.log.info(costSummary);
36408
+ clack45.log.info(costSummary);
36301
36409
  const warnings = validateSMSConfig(smsConfig);
36302
36410
  if (warnings.length > 0) {
36303
36411
  progress.info(`
36304
36412
  ${pc48.yellow(pc48.bold("Important Notes:"))}`);
36305
36413
  for (const warning of warnings) {
36306
- clack44.log.warn(warning);
36414
+ clack45.log.warn(warning);
36307
36415
  }
36308
36416
  }
36309
36417
  if (!options.yes) {
36310
36418
  const confirmed = await confirmDeploy();
36311
36419
  if (!confirmed) {
36312
- clack44.cancel("Deployment cancelled.");
36420
+ clack45.cancel("Deployment cancelled.");
36313
36421
  process.exit(0);
36314
36422
  }
36315
36423
  }
@@ -36385,8 +36493,8 @@ ${pc48.yellow(pc48.bold("Important Notes:"))}`);
36385
36493
  } catch (sdkError) {
36386
36494
  sdkResourceWarning = true;
36387
36495
  const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
36388
- clack44.log.warn(`Phone pool creation failed: ${msg}`);
36389
- clack44.log.info(
36496
+ clack45.log.warn(`Phone pool creation failed: ${msg}`);
36497
+ clack45.log.info(
36390
36498
  `Run ${pc48.cyan("wraps sms sync")} to retry SDK resource creation.`
36391
36499
  );
36392
36500
  }
@@ -36403,8 +36511,8 @@ ${pc48.yellow(pc48.bold("Important Notes:"))}`);
36403
36511
  } catch (sdkError) {
36404
36512
  sdkResourceWarning = true;
36405
36513
  const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
36406
- clack44.log.warn(`Event destination creation failed: ${msg}`);
36407
- clack44.log.info(
36514
+ clack45.log.warn(`Event destination creation failed: ${msg}`);
36515
+ clack45.log.info(
36408
36516
  `Run ${pc48.cyan("wraps sms sync")} to retry SDK resource creation.`
36409
36517
  );
36410
36518
  }
@@ -36424,14 +36532,14 @@ ${pc48.yellow(pc48.bold("Important Notes:"))}`);
36424
36532
  } catch (sdkError) {
36425
36533
  sdkResourceWarning = true;
36426
36534
  const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
36427
- clack44.log.warn(`Protect configuration creation failed: ${msg}`);
36428
- clack44.log.info(
36535
+ clack45.log.warn(`Protect configuration creation failed: ${msg}`);
36536
+ clack45.log.info(
36429
36537
  `Run ${pc48.cyan("wraps sms sync")} to retry SDK resource creation.`
36430
36538
  );
36431
36539
  }
36432
36540
  }
36433
36541
  if (sdkResourceWarning) {
36434
- clack44.log.warn(
36542
+ clack45.log.warn(
36435
36543
  "Some SDK resources failed to create. Core infrastructure is deployed."
36436
36544
  );
36437
36545
  }
@@ -36476,9 +36584,9 @@ ${pc48.yellow(pc48.bold("Important Notes:"))}`);
36476
36584
  return;
36477
36585
  }
36478
36586
  console.log("\n");
36479
- clack44.log.success(pc48.green(pc48.bold("SMS infrastructure deployed!")));
36587
+ clack45.log.success(pc48.green(pc48.bold("SMS infrastructure deployed!")));
36480
36588
  console.log("\n");
36481
- clack44.note(
36589
+ clack45.note(
36482
36590
  [
36483
36591
  `${pc48.bold("Phone Number:")} ${pc48.cyan(outputs.phoneNumber || "Provisioning...")}`,
36484
36592
  `${pc48.bold("Phone Type:")} ${pc48.cyan(smsConfig.phoneNumberType || "simulator")}`,
@@ -36502,12 +36610,12 @@ ${pc48.yellow(pc48.bold("Important Notes:"))}`);
36502
36610
  );
36503
36611
  nextSteps.push(`${pc48.cyan("wraps sms status")} - View SMS configuration`);
36504
36612
  console.log("\n");
36505
- clack44.log.info(pc48.bold("Next steps:"));
36613
+ clack45.log.info(pc48.bold("Next steps:"));
36506
36614
  for (const step of nextSteps) {
36507
36615
  console.log(` ${step}`);
36508
36616
  }
36509
36617
  console.log("\n");
36510
- clack44.log.info(pc48.bold("SDK Usage:"));
36618
+ clack45.log.info(pc48.bold("SDK Usage:"));
36511
36619
  console.log(pc48.dim(" npm install @wraps.dev/sms"));
36512
36620
  console.log("");
36513
36621
  console.log(pc48.dim(" import { Wraps } from '@wraps.dev/sms';"));
@@ -36516,7 +36624,7 @@ ${pc48.yellow(pc48.bold("Important Notes:"))}`);
36516
36624
  console.log(pc48.dim(" to: '+14155551234',"));
36517
36625
  console.log(pc48.dim(" message: 'Your code is 123456',"));
36518
36626
  console.log(pc48.dim(" });"));
36519
- clack44.outro(pc48.green("Setup complete!"));
36627
+ clack45.outro(pc48.green("Setup complete!"));
36520
36628
  const duration = Date.now() - startTime;
36521
36629
  const enabledFeatures = [];
36522
36630
  if (smsConfig.tracking?.enabled) {
@@ -36552,7 +36660,7 @@ init_aws();
36552
36660
  init_json_output();
36553
36661
  init_metadata();
36554
36662
  init_output();
36555
- import * as clack45 from "@clack/prompts";
36663
+ import * as clack46 from "@clack/prompts";
36556
36664
  import pc49 from "picocolors";
36557
36665
  async function getPhoneNumberDetails(region) {
36558
36666
  const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePhoneNumbersCommand: DescribePhoneNumbersCommand2 } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
@@ -36573,7 +36681,7 @@ async function getPhoneNumberDetails(region) {
36573
36681
  return null;
36574
36682
  } catch (error) {
36575
36683
  const errorMessage = error instanceof Error ? error.message : String(error);
36576
- clack45.log.error(`Error fetching phone number: ${errorMessage}`);
36684
+ clack46.log.error(`Error fetching phone number: ${errorMessage}`);
36577
36685
  return null;
36578
36686
  }
36579
36687
  }
@@ -36594,7 +36702,7 @@ async function getRegistrationStatus(region, registrationId) {
36594
36702
  async function smsRegister(options) {
36595
36703
  const startTime = Date.now();
36596
36704
  if (!isJsonMode()) {
36597
- clack45.intro(pc49.bold("Wraps SMS - Toll-Free Registration"));
36705
+ clack46.intro(pc49.bold("Wraps SMS - Toll-Free Registration"));
36598
36706
  }
36599
36707
  const progress = new DeploymentProgress();
36600
36708
  const identity = await progress.execute(
@@ -36607,8 +36715,8 @@ async function smsRegister(options) {
36607
36715
  }
36608
36716
  const metadata = await loadConnectionMetadata(identity.accountId, region);
36609
36717
  if (!metadata?.services?.sms) {
36610
- clack45.log.error("No SMS infrastructure found.");
36611
- clack45.log.info(`Run ${pc49.cyan("wraps sms init")} first.`);
36718
+ clack46.log.error("No SMS infrastructure found.");
36719
+ clack46.log.info(`Run ${pc49.cyan("wraps sms init")} first.`);
36612
36720
  process.exit(1);
36613
36721
  }
36614
36722
  const phoneDetails = await progress.execute(
@@ -36616,7 +36724,7 @@ async function smsRegister(options) {
36616
36724
  async () => getPhoneNumberDetails(region)
36617
36725
  );
36618
36726
  if (!phoneDetails) {
36619
- clack45.log.error("No phone number found.");
36727
+ clack46.log.error("No phone number found.");
36620
36728
  process.exit(1);
36621
36729
  }
36622
36730
  let registrationStatus = null;
@@ -36653,18 +36761,18 @@ async function smsRegister(options) {
36653
36761
  }
36654
36762
  console.log("");
36655
36763
  if (phoneDetails.status === "ACTIVE") {
36656
- clack45.log.success("Your phone number is already ACTIVE and ready to use!");
36764
+ clack46.log.success("Your phone number is already ACTIVE and ready to use!");
36657
36765
  const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePoolsCommand } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
36658
36766
  const client = new PinpointSMSVoiceV2Client5({ region });
36659
36767
  const pools = await client.send(new DescribePoolsCommand({}));
36660
36768
  if (!pools.Pools?.length) {
36661
- clack45.log.info("Run `wraps sms sync` to create the phone pool.");
36769
+ clack46.log.info("Run `wraps sms sync` to create the phone pool.");
36662
36770
  }
36663
36771
  process.exit(0);
36664
36772
  }
36665
36773
  if (phoneDetails.type !== "TOLL_FREE") {
36666
- clack45.log.info("Only toll-free numbers require registration.");
36667
- clack45.log.info(`Your ${phoneDetails.type} number should be ready to use.`);
36774
+ clack46.log.info("Only toll-free numbers require registration.");
36775
+ clack46.log.info(`Your ${phoneDetails.type} number should be ready to use.`);
36668
36776
  process.exit(0);
36669
36777
  }
36670
36778
  console.log(pc49.bold("Toll-Free Registration Required"));
@@ -36683,12 +36791,12 @@ async function smsRegister(options) {
36683
36791
  console.log(` ${pc49.dim("\u2022")} How users opt-in to receive messages`);
36684
36792
  console.log(` ${pc49.dim("\u2022")} Expected monthly message volume`);
36685
36793
  console.log("");
36686
- const openConsole = await clack45.confirm({
36794
+ const openConsole = await clack46.confirm({
36687
36795
  message: "Open AWS Console to start registration?",
36688
36796
  initialValue: true
36689
36797
  });
36690
- if (clack45.isCancel(openConsole)) {
36691
- clack45.cancel("Registration cancelled.");
36798
+ if (clack46.isCancel(openConsole)) {
36799
+ clack46.cancel("Registration cancelled.");
36692
36800
  process.exit(0);
36693
36801
  }
36694
36802
  if (openConsole) {
@@ -36698,13 +36806,13 @@ async function smsRegister(options) {
36698
36806
  const execAsync2 = promisify2(exec2);
36699
36807
  try {
36700
36808
  await execAsync2(`open "${consoleUrl}"`);
36701
- clack45.log.success("Opened AWS Console in your browser.");
36809
+ clack46.log.success("Opened AWS Console in your browser.");
36702
36810
  } catch {
36703
36811
  try {
36704
36812
  await execAsync2(`xdg-open "${consoleUrl}"`);
36705
- clack45.log.success("Opened AWS Console in your browser.");
36813
+ clack46.log.success("Opened AWS Console in your browser.");
36706
36814
  } catch {
36707
- clack45.log.info("Open this URL in your browser:");
36815
+ clack46.log.info("Open this URL in your browser:");
36708
36816
  console.log(`
36709
36817
  ${pc49.cyan(consoleUrl)}
36710
36818
  `);
@@ -36732,7 +36840,7 @@ async function smsRegister(options) {
36732
36840
  success: true,
36733
36841
  duration_ms: Date.now() - startTime
36734
36842
  });
36735
- clack45.outro(pc49.dim("Good luck with your registration!"));
36843
+ clack46.outro(pc49.dim("Good luck with your registration!"));
36736
36844
  }
36737
36845
 
36738
36846
  // src/commands/sms/status.ts
@@ -36744,7 +36852,8 @@ init_json_output();
36744
36852
  init_metadata();
36745
36853
  init_output();
36746
36854
  init_pulumi();
36747
- import * as clack46 from "@clack/prompts";
36855
+ init_region_resolver();
36856
+ import * as clack47 from "@clack/prompts";
36748
36857
  import * as pulumi30 from "@pulumi/pulumi";
36749
36858
  import pc50 from "picocolors";
36750
36859
  function displaySMSStatus(options) {
@@ -36784,24 +36893,29 @@ function displaySMSStatus(options) {
36784
36893
  lines.push(pc50.bold("IAM Role"));
36785
36894
  lines.push(` ${pc50.dim(options.roleArn)}`);
36786
36895
  }
36787
- clack46.note(lines.join("\n"), "SMS Status");
36896
+ clack47.note(lines.join("\n"), "SMS Status");
36788
36897
  }
36789
- async function smsStatus(_options) {
36898
+ async function smsStatus(options) {
36790
36899
  await ensurePulumiInstalled();
36791
36900
  const startTime = Date.now();
36792
36901
  const progress = new DeploymentProgress();
36793
36902
  if (!isJsonMode()) {
36794
- clack46.intro(pc50.bold("Wraps SMS Status"));
36903
+ clack47.intro(pc50.bold("Wraps SMS Status"));
36795
36904
  }
36796
36905
  const identity = await progress.execute(
36797
36906
  "Loading SMS infrastructure status",
36798
36907
  async () => validateAWSCredentials()
36799
36908
  );
36800
- const region = await getAWSRegion();
36909
+ const region = await resolveRegionForCommand({
36910
+ accountId: identity.accountId,
36911
+ optionRegion: options.region,
36912
+ service: "sms",
36913
+ label: "SMS deployment"
36914
+ });
36801
36915
  const metadata = await loadConnectionMetadata(identity.accountId, region);
36802
36916
  if (!metadata?.services?.sms) {
36803
36917
  progress.stop();
36804
- clack46.log.error("No SMS infrastructure found");
36918
+ clack47.log.error("No SMS infrastructure found");
36805
36919
  console.log(
36806
36920
  `
36807
36921
  Run ${pc50.cyan("wraps sms init")} to deploy SMS infrastructure.
@@ -36840,7 +36954,7 @@ Run ${pc50.cyan("wraps sms init")} to deploy SMS infrastructure.
36840
36954
  }
36841
36955
  displaySMSStatus(smsStatusData);
36842
36956
  console.log("");
36843
- clack46.log.info(pc50.bold("Commands:"));
36957
+ clack47.log.info(pc50.bold("Commands:"));
36844
36958
  console.log(
36845
36959
  ` ${pc50.cyan("wraps sms test --to +1234567890")} - Send a test message`
36846
36960
  );
@@ -36851,12 +36965,12 @@ Run ${pc50.cyan("wraps sms init")} to deploy SMS infrastructure.
36851
36965
  event_tracking: smsConfig?.eventTracking?.enabled,
36852
36966
  duration_ms: Date.now() - startTime
36853
36967
  });
36854
- clack46.outro(pc50.dim("SMS infrastructure is ready"));
36968
+ clack47.outro(pc50.dim("SMS infrastructure is ready"));
36855
36969
  }
36856
36970
 
36857
36971
  // src/commands/sms/sync.ts
36858
36972
  init_esm_shims();
36859
- import * as clack47 from "@clack/prompts";
36973
+ import * as clack48 from "@clack/prompts";
36860
36974
  import * as pulumi31 from "@pulumi/pulumi";
36861
36975
  import pc51 from "picocolors";
36862
36976
  init_events();
@@ -36871,7 +36985,7 @@ async function smsSync(options) {
36871
36985
  await ensurePulumiInstalled();
36872
36986
  const startTime = Date.now();
36873
36987
  if (!isJsonMode()) {
36874
- clack47.intro(pc51.bold("Wraps SMS Infrastructure Sync"));
36988
+ clack48.intro(pc51.bold("Wraps SMS Infrastructure Sync"));
36875
36989
  }
36876
36990
  const progress = new DeploymentProgress();
36877
36991
  const identity = await progress.execute(
@@ -36883,7 +36997,7 @@ async function smsSync(options) {
36883
36997
  const smsService = metadata?.services?.sms;
36884
36998
  if (!smsService?.config) {
36885
36999
  progress.stop();
36886
- clack47.log.error("No SMS infrastructure found to sync");
37000
+ clack48.log.error("No SMS infrastructure found to sync");
36887
37001
  console.log(
36888
37002
  `
36889
37003
  Run ${pc51.cyan("wraps sms init")} to deploy SMS infrastructure first.
@@ -36901,12 +37015,12 @@ Run ${pc51.cyan("wraps sms init")} to deploy SMS infrastructure first.
36901
37015
  `Event tracking: ${pc51.cyan(smsConfig.eventTracking?.enabled ? "enabled" : "disabled")}`
36902
37016
  );
36903
37017
  if (!options.yes) {
36904
- const confirmed = await clack47.confirm({
37018
+ const confirmed = await clack48.confirm({
36905
37019
  message: "Sync SMS infrastructure? This will update Lambda code and recreate any missing resources.",
36906
37020
  initialValue: true
36907
37021
  });
36908
- if (clack47.isCancel(confirmed) || !confirmed) {
36909
- clack47.cancel("Sync cancelled.");
37022
+ if (clack48.isCancel(confirmed) || !confirmed) {
37023
+ clack48.cancel("Sync cancelled.");
36910
37024
  process.exit(0);
36911
37025
  }
36912
37026
  }
@@ -37011,7 +37125,7 @@ Run ${pc51.cyan("wraps sms init")} to deploy SMS infrastructure first.
37011
37125
  throw errors.stackLocked();
37012
37126
  }
37013
37127
  trackError("SYNC_FAILED", "sms:sync", { step: "sync" });
37014
- clack47.log.error(`SMS sync failed: ${errorMessage}`);
37128
+ clack48.log.error(`SMS sync failed: ${errorMessage}`);
37015
37129
  process.exit(1);
37016
37130
  }
37017
37131
  if (metadata && smsService) {
@@ -37031,7 +37145,7 @@ Run ${pc51.cyan("wraps sms init")} to deploy SMS infrastructure first.
37031
37145
  return;
37032
37146
  }
37033
37147
  console.log("\n");
37034
- clack47.log.success(pc51.green("SMS infrastructure synced successfully!"));
37148
+ clack48.log.success(pc51.green("SMS infrastructure synced successfully!"));
37035
37149
  const changes = [];
37036
37150
  if (outputs.lambdaFunctions?.length) {
37037
37151
  changes.push("Lambda functions updated");
@@ -37045,7 +37159,7 @@ Run ${pc51.cyan("wraps sms init")} to deploy SMS infrastructure first.
37045
37159
  success: true,
37046
37160
  duration_ms: Date.now() - startTime
37047
37161
  });
37048
- clack47.outro(pc51.green("Sync complete!"));
37162
+ clack48.outro(pc51.green("Sync complete!"));
37049
37163
  }
37050
37164
 
37051
37165
  // src/commands/sms/test.ts
@@ -37060,7 +37174,7 @@ import {
37060
37174
  PinpointSMSVoiceV2Client as PinpointSMSVoiceV2Client3,
37061
37175
  SendTextMessageCommand
37062
37176
  } from "@aws-sdk/client-pinpoint-sms-voice-v2";
37063
- import * as clack48 from "@clack/prompts";
37177
+ import * as clack49 from "@clack/prompts";
37064
37178
  import pc52 from "picocolors";
37065
37179
 
37066
37180
  // src/utils/sms/validation.ts
@@ -37084,7 +37198,7 @@ async function smsTest(options) {
37084
37198
  const startTime = Date.now();
37085
37199
  const progress = new DeploymentProgress();
37086
37200
  if (!isJsonMode()) {
37087
- clack48.intro(pc52.bold("Wraps SMS Test"));
37201
+ clack49.intro(pc52.bold("Wraps SMS Test"));
37088
37202
  }
37089
37203
  const identity = await progress.execute(
37090
37204
  "Validating AWS credentials",
@@ -37094,7 +37208,7 @@ async function smsTest(options) {
37094
37208
  const metadata = await loadConnectionMetadata(identity.accountId, region);
37095
37209
  if (!metadata?.services?.sms) {
37096
37210
  progress.stop();
37097
- clack48.log.error("No SMS infrastructure found");
37211
+ clack49.log.error("No SMS infrastructure found");
37098
37212
  console.log(
37099
37213
  `
37100
37214
  Run ${pc52.cyan("wraps sms init")} to deploy SMS infrastructure.
@@ -37111,7 +37225,7 @@ Run ${pc52.cyan("wraps sms init")} to deploy SMS infrastructure.
37111
37225
  );
37112
37226
  }
37113
37227
  if (!toNumber) {
37114
- const destinationType = await clack48.select({
37228
+ const destinationType = await clack49.select({
37115
37229
  message: "Choose destination number:",
37116
37230
  options: [
37117
37231
  {
@@ -37126,25 +37240,25 @@ Run ${pc52.cyan("wraps sms init")} to deploy SMS infrastructure.
37126
37240
  }
37127
37241
  ]
37128
37242
  });
37129
- if (clack48.isCancel(destinationType)) {
37130
- clack48.cancel("Operation cancelled.");
37243
+ if (clack49.isCancel(destinationType)) {
37244
+ clack49.cancel("Operation cancelled.");
37131
37245
  process.exit(0);
37132
37246
  }
37133
37247
  if (destinationType === "simulator") {
37134
- const simResult = await clack48.select({
37248
+ const simResult = await clack49.select({
37135
37249
  message: "Select simulator destination:",
37136
37250
  options: SIMULATOR_DESTINATIONS.map((sim) => ({
37137
37251
  value: sim.number,
37138
37252
  label: `${sim.number} | ${sim.country}`
37139
37253
  }))
37140
37254
  });
37141
- if (clack48.isCancel(simResult)) {
37142
- clack48.cancel("Operation cancelled.");
37255
+ if (clack49.isCancel(simResult)) {
37256
+ clack49.cancel("Operation cancelled.");
37143
37257
  process.exit(0);
37144
37258
  }
37145
37259
  toNumber = simResult;
37146
37260
  } else {
37147
- const result = await clack48.text({
37261
+ const result = await clack49.text({
37148
37262
  message: "Enter destination phone number (E.164 format):",
37149
37263
  placeholder: "+14155551234",
37150
37264
  validate: (value) => {
@@ -37157,22 +37271,22 @@ Run ${pc52.cyan("wraps sms init")} to deploy SMS infrastructure.
37157
37271
  return;
37158
37272
  }
37159
37273
  });
37160
- if (clack48.isCancel(result)) {
37161
- clack48.cancel("Operation cancelled.");
37274
+ if (clack49.isCancel(result)) {
37275
+ clack49.cancel("Operation cancelled.");
37162
37276
  process.exit(0);
37163
37277
  }
37164
37278
  toNumber = result;
37165
37279
  }
37166
37280
  } else if (!isValidPhoneNumber(toNumber)) {
37167
37281
  progress.stop();
37168
- clack48.log.error(
37282
+ clack49.log.error(
37169
37283
  `Invalid phone number format: ${toNumber}. Use E.164 format (e.g., +14155551234)`
37170
37284
  );
37171
37285
  process.exit(1);
37172
37286
  }
37173
37287
  let message = options.message;
37174
37288
  if (!message) {
37175
- const result = await clack48.text({
37289
+ const result = await clack49.text({
37176
37290
  message: "Enter test message:",
37177
37291
  placeholder: "Hello from Wraps SMS!",
37178
37292
  defaultValue: "Hello from Wraps SMS! This is a test message.",
@@ -37186,8 +37300,8 @@ Run ${pc52.cyan("wraps sms init")} to deploy SMS infrastructure.
37186
37300
  return;
37187
37301
  }
37188
37302
  });
37189
- if (clack48.isCancel(result)) {
37190
- clack48.cancel("Operation cancelled.");
37303
+ if (clack49.isCancel(result)) {
37304
+ clack49.cancel("Operation cancelled.");
37191
37305
  process.exit(0);
37192
37306
  }
37193
37307
  message = result;
@@ -37226,9 +37340,9 @@ Run ${pc52.cyan("wraps sms init")} to deploy SMS infrastructure.
37226
37340
  return;
37227
37341
  }
37228
37342
  console.log("\n");
37229
- clack48.log.success(pc52.green("Test SMS sent successfully!"));
37343
+ clack49.log.success(pc52.green("Test SMS sent successfully!"));
37230
37344
  console.log("");
37231
- clack48.note(
37345
+ clack49.note(
37232
37346
  [
37233
37347
  `${pc52.bold("Message ID:")} ${pc52.cyan(messageId || "unknown")}`,
37234
37348
  `${pc52.bold("To:")} ${pc52.cyan(toNumber)}`,
@@ -37243,11 +37357,11 @@ Run ${pc52.cyan("wraps sms init")} to deploy SMS infrastructure.
37243
37357
  );
37244
37358
  if (smsConfig?.eventTracking?.enabled) {
37245
37359
  console.log("");
37246
- clack48.log.info(
37360
+ clack49.log.info(
37247
37361
  pc52.dim("Event tracking is enabled. Check DynamoDB for delivery status.")
37248
37362
  );
37249
37363
  }
37250
- clack48.outro(pc52.green("Test complete!"));
37364
+ clack49.outro(pc52.green("Test complete!"));
37251
37365
  } catch (error) {
37252
37366
  progress.stop();
37253
37367
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -37259,24 +37373,24 @@ Run ${pc52.cyan("wraps sms init")} to deploy SMS infrastructure.
37259
37373
  });
37260
37374
  const errorName = error instanceof Error ? error.name : "";
37261
37375
  if (errorName === "ConflictException" || errorMessage.includes("opt-out")) {
37262
- clack48.log.error("Destination number has opted out of messages");
37376
+ clack49.log.error("Destination number has opted out of messages");
37263
37377
  console.log("\nThe recipient has opted out of receiving SMS messages.\n");
37264
37378
  } else if (errorName === "ThrottlingException" || errorMessage.includes("spending limit")) {
37265
- clack48.log.error("SMS rate or spending limit reached");
37379
+ clack49.log.error("SMS rate or spending limit reached");
37266
37380
  console.log(
37267
37381
  "\nCheck your AWS account SMS spending limits in the console.\n"
37268
37382
  );
37269
37383
  } else if (errorName === "ValidationException") {
37270
- clack48.log.error(`Invalid request: ${errorMessage}`);
37384
+ clack49.log.error(`Invalid request: ${errorMessage}`);
37271
37385
  } else if (errorMessage.includes("not verified") || errorMessage.includes("not registered")) {
37272
- clack48.log.error("Toll-free number registration is not complete");
37386
+ clack49.log.error("Toll-free number registration is not complete");
37273
37387
  console.log(
37274
37388
  `
37275
37389
  Run ${pc52.cyan("wraps sms register")} to check registration status.
37276
37390
  `
37277
37391
  );
37278
37392
  } else if (errorName === "AccessDeniedException") {
37279
- clack48.log.error(
37393
+ clack49.log.error(
37280
37394
  "Permission denied \u2014 IAM role may be missing SMS send permissions"
37281
37395
  );
37282
37396
  console.log(
@@ -37285,7 +37399,7 @@ Run ${pc52.cyan("wraps sms upgrade")} to update IAM policies.
37285
37399
  `
37286
37400
  );
37287
37401
  } else {
37288
- clack48.log.error(`Failed to send SMS: ${errorMessage}`);
37402
+ clack49.log.error(`Failed to send SMS: ${errorMessage}`);
37289
37403
  }
37290
37404
  process.exit(1);
37291
37405
  }
@@ -37293,7 +37407,7 @@ Run ${pc52.cyan("wraps sms upgrade")} to update IAM policies.
37293
37407
 
37294
37408
  // src/commands/sms/upgrade.ts
37295
37409
  init_esm_shims();
37296
- import * as clack49 from "@clack/prompts";
37410
+ import * as clack50 from "@clack/prompts";
37297
37411
  import * as pulumi32 from "@pulumi/pulumi";
37298
37412
  import pc53 from "picocolors";
37299
37413
  init_events();
@@ -37305,11 +37419,12 @@ init_metadata();
37305
37419
  init_output();
37306
37420
  init_prompts();
37307
37421
  init_pulumi();
37422
+ init_region_resolver();
37308
37423
  async function smsUpgrade(options) {
37309
37424
  const startTime = Date.now();
37310
37425
  let upgradeAction = "";
37311
37426
  if (!isJsonMode()) {
37312
- clack49.intro(pc53.bold("Wraps SMS Upgrade - Enhance Your SMS Infrastructure"));
37427
+ clack50.intro(pc53.bold("Wraps SMS Upgrade - Enhance Your SMS Infrastructure"));
37313
37428
  }
37314
37429
  const progress = new DeploymentProgress();
37315
37430
  const wasAutoInstalled = await progress.execute(
@@ -37324,24 +37439,25 @@ async function smsUpgrade(options) {
37324
37439
  async () => validateAWSCredentials()
37325
37440
  );
37326
37441
  progress.info(`Connected to AWS account: ${pc53.cyan(identity.accountId)}`);
37327
- let region = options.region;
37328
- if (!region) {
37329
- const defaultRegion = await getAWSRegion();
37330
- region = defaultRegion;
37331
- }
37442
+ const region = await resolveRegionForCommand({
37443
+ accountId: identity.accountId,
37444
+ optionRegion: options.region,
37445
+ service: "sms",
37446
+ label: "SMS deployment"
37447
+ });
37332
37448
  const metadata = await loadConnectionMetadata(identity.accountId, region);
37333
37449
  if (!metadata) {
37334
- clack49.log.error(
37450
+ clack50.log.error(
37335
37451
  `No Wraps connection found for account ${pc53.cyan(identity.accountId)} in region ${pc53.cyan(region)}`
37336
37452
  );
37337
- clack49.log.info(
37453
+ clack50.log.info(
37338
37454
  `Use ${pc53.cyan("wraps sms init")} to create new infrastructure.`
37339
37455
  );
37340
37456
  process.exit(1);
37341
37457
  }
37342
37458
  if (!metadata.services.sms) {
37343
- clack49.log.error("No SMS infrastructure found");
37344
- clack49.log.info(
37459
+ clack50.log.error("No SMS infrastructure found");
37460
+ clack50.log.info(
37345
37461
  `Use ${pc53.cyan("wraps sms init")} to deploy SMS infrastructure.`
37346
37462
  );
37347
37463
  process.exit(1);
@@ -37357,8 +37473,8 @@ ${pc53.bold("Current Configuration:")}
37357
37473
  }
37358
37474
  const config2 = metadata.services.sms.config;
37359
37475
  if (!config2) {
37360
- clack49.log.error("No SMS configuration found in metadata");
37361
- clack49.log.info(
37476
+ clack50.log.error("No SMS configuration found in metadata");
37477
+ clack50.log.info(
37362
37478
  `Use ${pc53.cyan("wraps sms init")} to create new infrastructure.`
37363
37479
  );
37364
37480
  process.exit(1);
@@ -37418,7 +37534,7 @@ ${pc53.bold("Current Configuration:")}
37418
37534
  "10dlc": "10DLC",
37419
37535
  "short-code": "Short code"
37420
37536
  };
37421
- upgradeAction = await clack49.select({
37537
+ upgradeAction = await clack50.select({
37422
37538
  message: "What would you like to do?",
37423
37539
  options: [
37424
37540
  {
@@ -37458,8 +37574,8 @@ ${pc53.bold("Current Configuration:")}
37458
37574
  }
37459
37575
  ]
37460
37576
  });
37461
- if (clack49.isCancel(upgradeAction)) {
37462
- clack49.cancel("Upgrade cancelled.");
37577
+ if (clack50.isCancel(upgradeAction)) {
37578
+ clack50.cancel("Upgrade cancelled.");
37463
37579
  process.exit(0);
37464
37580
  }
37465
37581
  let updatedConfig = { ...config2 };
@@ -37500,17 +37616,17 @@ ${pc53.bold("Current Configuration:")}
37500
37616
  hint: p.hint
37501
37617
  }));
37502
37618
  if (availableTypes.length === 0) {
37503
- clack49.log.warn(
37619
+ clack50.log.warn(
37504
37620
  "Already on highest phone number tier. Contact AWS for dedicated short codes."
37505
37621
  );
37506
37622
  process.exit(0);
37507
37623
  }
37508
- const selectedType = await clack49.select({
37624
+ const selectedType = await clack50.select({
37509
37625
  message: "Select new phone number type:",
37510
37626
  options: availableTypes
37511
37627
  });
37512
- if (clack49.isCancel(selectedType)) {
37513
- clack49.cancel("Upgrade cancelled.");
37628
+ if (clack50.isCancel(selectedType)) {
37629
+ clack50.cancel("Upgrade cancelled.");
37514
37630
  process.exit(0);
37515
37631
  }
37516
37632
  if (selectedType === "toll-free") {
@@ -37533,12 +37649,12 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("Toll-free Registration Required")}
37533
37649
  console.log(
37534
37650
  pc53.dim("\nUntil verified, sending is limited to low volume.\n")
37535
37651
  );
37536
- const confirmTollFree = await clack49.confirm({
37652
+ const confirmTollFree = await clack50.confirm({
37537
37653
  message: "Continue with toll-free number request?",
37538
37654
  initialValue: true
37539
37655
  });
37540
- if (clack49.isCancel(confirmTollFree) || !confirmTollFree) {
37541
- clack49.cancel("Upgrade cancelled.");
37656
+ if (clack50.isCancel(confirmTollFree) || !confirmTollFree) {
37657
+ clack50.cancel("Upgrade cancelled.");
37542
37658
  process.exit(0);
37543
37659
  }
37544
37660
  }
@@ -37553,12 +37669,12 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37553
37669
  console.log(" \u2022 Campaign registration: $15/mo per campaign");
37554
37670
  console.log(" \u2022 Verification takes 1-7 business days");
37555
37671
  console.log("");
37556
- const confirm10DLC = await clack49.confirm({
37672
+ const confirm10DLC = await clack50.confirm({
37557
37673
  message: "Continue with 10DLC number request?",
37558
37674
  initialValue: true
37559
37675
  });
37560
- if (clack49.isCancel(confirm10DLC) || !confirm10DLC) {
37561
- clack49.cancel("Upgrade cancelled.");
37676
+ if (clack50.isCancel(confirm10DLC) || !confirm10DLC) {
37677
+ clack50.cancel("Upgrade cancelled.");
37562
37678
  process.exit(0);
37563
37679
  }
37564
37680
  }
@@ -37583,15 +37699,15 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37583
37699
  disabled: currentPresetIdx >= 0 && idx <= currentPresetIdx ? "Current or lower tier" : void 0
37584
37700
  })).filter((p) => !p.disabled && p.value !== "custom");
37585
37701
  if (availablePresets.length === 0) {
37586
- clack49.log.warn("Already on highest preset (Enterprise)");
37702
+ clack50.log.warn("Already on highest preset (Enterprise)");
37587
37703
  process.exit(0);
37588
37704
  }
37589
- const selectedPreset = await clack49.select({
37705
+ const selectedPreset = await clack50.select({
37590
37706
  message: "Select new preset:",
37591
37707
  options: availablePresets
37592
37708
  });
37593
- if (clack49.isCancel(selectedPreset)) {
37594
- clack49.cancel("Upgrade cancelled.");
37709
+ if (clack50.isCancel(selectedPreset)) {
37710
+ clack50.cancel("Upgrade cancelled.");
37595
37711
  process.exit(0);
37596
37712
  }
37597
37713
  const presetConfig = getSMSPreset(selectedPreset);
@@ -37607,7 +37723,7 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37607
37723
  }
37608
37724
  case "event-tracking": {
37609
37725
  if (config2.eventTracking?.enabled) {
37610
- const eventAction = await clack49.select({
37726
+ const eventAction = await clack50.select({
37611
37727
  message: "What would you like to do with event tracking?",
37612
37728
  options: [
37613
37729
  {
@@ -37622,17 +37738,17 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37622
37738
  }
37623
37739
  ]
37624
37740
  });
37625
- if (clack49.isCancel(eventAction)) {
37626
- clack49.cancel("Upgrade cancelled.");
37741
+ if (clack50.isCancel(eventAction)) {
37742
+ clack50.cancel("Upgrade cancelled.");
37627
37743
  process.exit(0);
37628
37744
  }
37629
37745
  if (eventAction === "disable") {
37630
- const confirmDisable = await clack49.confirm({
37746
+ const confirmDisable = await clack50.confirm({
37631
37747
  message: "Are you sure? Existing history will remain, but new events won't be tracked.",
37632
37748
  initialValue: false
37633
37749
  });
37634
- if (clack49.isCancel(confirmDisable) || !confirmDisable) {
37635
- clack49.cancel("Event tracking not disabled.");
37750
+ if (clack50.isCancel(confirmDisable) || !confirmDisable) {
37751
+ clack50.cancel("Event tracking not disabled.");
37636
37752
  process.exit(0);
37637
37753
  }
37638
37754
  updatedConfig = {
@@ -37642,7 +37758,7 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37642
37758
  }
37643
37759
  };
37644
37760
  } else {
37645
- const retention = await clack49.select({
37761
+ const retention = await clack50.select({
37646
37762
  message: "Message history retention period:",
37647
37763
  options: [
37648
37764
  { value: "7days", label: "7 days", hint: "Minimal storage cost" },
@@ -37669,8 +37785,8 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37669
37785
  ],
37670
37786
  initialValue: config2.eventTracking.archiveRetention || "90days"
37671
37787
  });
37672
- if (clack49.isCancel(retention)) {
37673
- clack49.cancel("Upgrade cancelled.");
37788
+ if (clack50.isCancel(retention)) {
37789
+ clack50.cancel("Upgrade cancelled.");
37674
37790
  process.exit(0);
37675
37791
  }
37676
37792
  updatedConfig = {
@@ -37682,19 +37798,19 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37682
37798
  };
37683
37799
  }
37684
37800
  } else {
37685
- const enableTracking = await clack49.confirm({
37801
+ const enableTracking = await clack50.confirm({
37686
37802
  message: "Enable event tracking? (Track SMS events with history)",
37687
37803
  initialValue: true
37688
37804
  });
37689
- if (clack49.isCancel(enableTracking)) {
37690
- clack49.cancel("Upgrade cancelled.");
37805
+ if (clack50.isCancel(enableTracking)) {
37806
+ clack50.cancel("Upgrade cancelled.");
37691
37807
  process.exit(0);
37692
37808
  }
37693
37809
  if (!enableTracking) {
37694
- clack49.log.info("Event tracking not enabled.");
37810
+ clack50.log.info("Event tracking not enabled.");
37695
37811
  process.exit(0);
37696
37812
  }
37697
- const retention = await clack49.select({
37813
+ const retention = await clack50.select({
37698
37814
  message: "Message history retention period:",
37699
37815
  options: [
37700
37816
  { value: "7days", label: "7 days", hint: "Minimal storage cost" },
@@ -37717,8 +37833,8 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37717
37833
  ],
37718
37834
  initialValue: "90days"
37719
37835
  });
37720
- if (clack49.isCancel(retention)) {
37721
- clack49.cancel("Upgrade cancelled.");
37836
+ if (clack50.isCancel(retention)) {
37837
+ clack50.cancel("Upgrade cancelled.");
37722
37838
  process.exit(0);
37723
37839
  }
37724
37840
  updatedConfig = {
@@ -37737,12 +37853,12 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37737
37853
  }
37738
37854
  case "retention": {
37739
37855
  if (!config2.eventTracking?.enabled) {
37740
- clack49.log.error(
37856
+ clack50.log.error(
37741
37857
  "Event tracking is not enabled. Enable it first to change retention."
37742
37858
  );
37743
37859
  process.exit(1);
37744
37860
  }
37745
- const retention = await clack49.select({
37861
+ const retention = await clack50.select({
37746
37862
  message: "Message history retention period (event data in DynamoDB):",
37747
37863
  options: [
37748
37864
  { value: "7days", label: "7 days", hint: "Minimal storage cost" },
@@ -37761,8 +37877,8 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37761
37877
  ],
37762
37878
  initialValue: config2.eventTracking.archiveRetention || "90days"
37763
37879
  });
37764
- if (clack49.isCancel(retention)) {
37765
- clack49.cancel("Upgrade cancelled.");
37880
+ if (clack50.isCancel(retention)) {
37881
+ clack50.cancel("Upgrade cancelled.");
37766
37882
  process.exit(0);
37767
37883
  }
37768
37884
  updatedConfig = {
@@ -37780,21 +37896,21 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37780
37896
  case "link-tracking": {
37781
37897
  const enableLinkTracking = !config2.tracking?.linkTracking;
37782
37898
  if (enableLinkTracking) {
37783
- clack49.log.info(
37899
+ clack50.log.info(
37784
37900
  pc53.dim(
37785
37901
  "Link tracking will track clicks on URLs in your SMS messages."
37786
37902
  )
37787
37903
  );
37788
- clack49.log.info(
37904
+ clack50.log.info(
37789
37905
  pc53.dim("URLs will be rewritten to go through a tracking endpoint.")
37790
37906
  );
37791
37907
  }
37792
- const confirmed = await clack49.confirm({
37908
+ const confirmed = await clack50.confirm({
37793
37909
  message: enableLinkTracking ? "Enable link click tracking?" : "Disable link click tracking?",
37794
37910
  initialValue: enableLinkTracking
37795
37911
  });
37796
- if (clack49.isCancel(confirmed) || !confirmed) {
37797
- clack49.cancel("Upgrade cancelled.");
37912
+ if (clack50.isCancel(confirmed) || !confirmed) {
37913
+ clack50.cancel("Upgrade cancelled.");
37798
37914
  process.exit(0);
37799
37915
  }
37800
37916
  updatedConfig = {
@@ -37811,7 +37927,7 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37811
37927
  }
37812
37928
  case "archiving": {
37813
37929
  if (config2.messageArchiving?.enabled) {
37814
- const archivingAction = await clack49.select({
37930
+ const archivingAction = await clack50.select({
37815
37931
  message: "What would you like to do with message archiving?",
37816
37932
  options: [
37817
37933
  {
@@ -37826,17 +37942,17 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37826
37942
  }
37827
37943
  ]
37828
37944
  });
37829
- if (clack49.isCancel(archivingAction)) {
37830
- clack49.cancel("Upgrade cancelled.");
37945
+ if (clack50.isCancel(archivingAction)) {
37946
+ clack50.cancel("Upgrade cancelled.");
37831
37947
  process.exit(0);
37832
37948
  }
37833
37949
  if (archivingAction === "disable") {
37834
- const confirmDisable = await clack49.confirm({
37950
+ const confirmDisable = await clack50.confirm({
37835
37951
  message: "Are you sure? Existing archived messages will remain, but new messages won't be archived.",
37836
37952
  initialValue: false
37837
37953
  });
37838
- if (clack49.isCancel(confirmDisable) || !confirmDisable) {
37839
- clack49.cancel("Archiving not disabled.");
37954
+ if (clack50.isCancel(confirmDisable) || !confirmDisable) {
37955
+ clack50.cancel("Archiving not disabled.");
37840
37956
  process.exit(0);
37841
37957
  }
37842
37958
  updatedConfig = {
@@ -37847,7 +37963,7 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37847
37963
  }
37848
37964
  };
37849
37965
  } else {
37850
- const retention = await clack49.select({
37966
+ const retention = await clack50.select({
37851
37967
  message: "Message archive retention period:",
37852
37968
  options: [
37853
37969
  {
@@ -37878,8 +37994,8 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37878
37994
  ],
37879
37995
  initialValue: config2.messageArchiving.retention
37880
37996
  });
37881
- if (clack49.isCancel(retention)) {
37882
- clack49.cancel("Upgrade cancelled.");
37997
+ if (clack50.isCancel(retention)) {
37998
+ clack50.cancel("Upgrade cancelled.");
37883
37999
  process.exit(0);
37884
38000
  }
37885
38001
  updatedConfig = {
@@ -37891,19 +38007,19 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37891
38007
  };
37892
38008
  }
37893
38009
  } else {
37894
- const enableArchiving = await clack49.confirm({
38010
+ const enableArchiving = await clack50.confirm({
37895
38011
  message: "Enable message archiving? (Store full message content for viewing)",
37896
38012
  initialValue: true
37897
38013
  });
37898
- if (clack49.isCancel(enableArchiving)) {
37899
- clack49.cancel("Upgrade cancelled.");
38014
+ if (clack50.isCancel(enableArchiving)) {
38015
+ clack50.cancel("Upgrade cancelled.");
37900
38016
  process.exit(0);
37901
38017
  }
37902
38018
  if (!enableArchiving) {
37903
- clack49.log.info("Message archiving not enabled.");
38019
+ clack50.log.info("Message archiving not enabled.");
37904
38020
  process.exit(0);
37905
38021
  }
37906
- const retention = await clack49.select({
38022
+ const retention = await clack50.select({
37907
38023
  message: "Message archive retention period:",
37908
38024
  options: [
37909
38025
  { value: "7days", label: "7 days", hint: "~$1-2/mo for 10k msgs" },
@@ -37930,8 +38046,8 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37930
38046
  ],
37931
38047
  initialValue: "90days"
37932
38048
  });
37933
- if (clack49.isCancel(retention)) {
37934
- clack49.cancel("Upgrade cancelled.");
38049
+ if (clack50.isCancel(retention)) {
38050
+ clack50.cancel("Upgrade cancelled.");
37935
38051
  process.exit(0);
37936
38052
  }
37937
38053
  updatedConfig = {
@@ -37963,7 +38079,7 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37963
38079
  const currentAllowed = config2.protectConfiguration?.allowedCountries || [
37964
38080
  "US"
37965
38081
  ];
37966
- const selectedCountries = await clack49.multiselect({
38082
+ const selectedCountries = await clack50.multiselect({
37967
38083
  message: "Select countries to allow SMS delivery (all others blocked):",
37968
38084
  options: commonCountries.map((c) => ({
37969
38085
  value: c.code,
@@ -37972,16 +38088,16 @@ ${pc53.yellow("\u26A0")} ${pc53.bold("10DLC Campaign Registration Required")}
37972
38088
  initialValues: currentAllowed,
37973
38089
  required: true
37974
38090
  });
37975
- if (clack49.isCancel(selectedCountries)) {
37976
- clack49.cancel("Upgrade cancelled.");
38091
+ if (clack50.isCancel(selectedCountries)) {
38092
+ clack50.cancel("Upgrade cancelled.");
37977
38093
  process.exit(0);
37978
38094
  }
37979
- const enableAIT = await clack49.confirm({
38095
+ const enableAIT = await clack50.confirm({
37980
38096
  message: "Enable AIT (Artificially Inflated Traffic) filtering? (adds per-message cost)",
37981
38097
  initialValue: config2.protectConfiguration?.aitFiltering ?? false
37982
38098
  });
37983
- if (clack49.isCancel(enableAIT)) {
37984
- clack49.cancel("Upgrade cancelled.");
38099
+ if (clack50.isCancel(enableAIT)) {
38100
+ clack50.cancel("Upgrade cancelled.");
37985
38101
  process.exit(0);
37986
38102
  }
37987
38103
  updatedConfig = {
@@ -38015,12 +38131,12 @@ ${pc53.bold("Cost Impact:")}`);
38015
38131
  }
38016
38132
  console.log("");
38017
38133
  if (!options.yes) {
38018
- const confirmed = await clack49.confirm({
38134
+ const confirmed = await clack50.confirm({
38019
38135
  message: "Proceed with upgrade?",
38020
38136
  initialValue: true
38021
38137
  });
38022
- if (clack49.isCancel(confirmed) || !confirmed) {
38023
- clack49.cancel("Upgrade cancelled.");
38138
+ if (clack50.isCancel(confirmed) || !confirmed) {
38139
+ clack50.cancel("Upgrade cancelled.");
38024
38140
  process.exit(0);
38025
38141
  }
38026
38142
  }
@@ -38162,9 +38278,9 @@ ${pc53.bold("Cost Impact:")}`);
38162
38278
  }
38163
38279
  progress.info("Connection metadata updated");
38164
38280
  console.log("\n");
38165
- clack49.log.success(pc53.green(pc53.bold("SMS infrastructure upgraded!")));
38281
+ clack50.log.success(pc53.green(pc53.bold("SMS infrastructure upgraded!")));
38166
38282
  console.log("\n");
38167
- clack49.note(
38283
+ clack50.note(
38168
38284
  [
38169
38285
  `${pc53.bold("Phone Number:")} ${pc53.cyan(outputs.phoneNumber || "Provisioning...")}`,
38170
38286
  `${pc53.bold("Phone Type:")} ${pc53.cyan(updatedConfig.phoneNumberType || "simulator")}`,
@@ -38239,7 +38355,7 @@ ${pc53.green("\u2713")} ${pc53.bold("Upgrade complete!")}
38239
38355
  action: typeof upgradeAction === "string" ? upgradeAction : void 0,
38240
38356
  duration_ms: Date.now() - startTime
38241
38357
  });
38242
- clack49.outro(pc53.green("Upgrade complete!"));
38358
+ clack50.outro(pc53.green("Upgrade complete!"));
38243
38359
  }
38244
38360
 
38245
38361
  // src/commands/sms/verify-number.ts
@@ -38258,13 +38374,13 @@ import {
38258
38374
  SendDestinationNumberVerificationCodeCommand,
38259
38375
  VerifyDestinationNumberCommand
38260
38376
  } from "@aws-sdk/client-pinpoint-sms-voice-v2";
38261
- import * as clack50 from "@clack/prompts";
38377
+ import * as clack51 from "@clack/prompts";
38262
38378
  import pc54 from "picocolors";
38263
38379
  async function smsVerifyNumber(options) {
38264
38380
  const startTime = Date.now();
38265
38381
  const progress = new DeploymentProgress();
38266
38382
  if (!isJsonMode()) {
38267
- clack50.intro(pc54.bold("Wraps SMS - Verify Destination Number"));
38383
+ clack51.intro(pc54.bold("Wraps SMS - Verify Destination Number"));
38268
38384
  }
38269
38385
  const identity = await progress.execute(
38270
38386
  "Validating AWS credentials",
@@ -38274,7 +38390,7 @@ async function smsVerifyNumber(options) {
38274
38390
  const metadata = await loadConnectionMetadata(identity.accountId, region);
38275
38391
  if (!metadata?.services?.sms) {
38276
38392
  progress.stop();
38277
- clack50.log.error("No SMS infrastructure found");
38393
+ clack51.log.error("No SMS infrastructure found");
38278
38394
  console.log(
38279
38395
  `
38280
38396
  Run ${pc54.cyan("wraps sms init")} to deploy SMS infrastructure.
@@ -38291,7 +38407,7 @@ Run ${pc54.cyan("wraps sms init")} to deploy SMS infrastructure.
38291
38407
  );
38292
38408
  progress.stop();
38293
38409
  if (!response.VerifiedDestinationNumbers || response.VerifiedDestinationNumbers.length === 0) {
38294
- clack50.log.info("No verified destination numbers found");
38410
+ clack51.log.info("No verified destination numbers found");
38295
38411
  console.log(
38296
38412
  `
38297
38413
  Run ${pc54.cyan("wraps sms verify-number")} to verify a number.
@@ -38299,7 +38415,7 @@ Run ${pc54.cyan("wraps sms verify-number")} to verify a number.
38299
38415
  );
38300
38416
  } else {
38301
38417
  console.log("\n");
38302
- clack50.log.info(pc54.bold("Verified Destination Numbers:"));
38418
+ clack51.log.info(pc54.bold("Verified Destination Numbers:"));
38303
38419
  console.log("");
38304
38420
  for (const num of response.VerifiedDestinationNumbers) {
38305
38421
  const status2 = num.Status === "VERIFIED" ? pc54.green("\u2713 Verified") : pc54.yellow("\u29D6 Pending");
@@ -38321,7 +38437,7 @@ Run ${pc54.cyan("wraps sms verify-number")} to verify a number.
38321
38437
  });
38322
38438
  return;
38323
38439
  }
38324
- clack50.outro(pc54.green("Done!"));
38440
+ clack51.outro(pc54.green("Done!"));
38325
38441
  return;
38326
38442
  } catch (error) {
38327
38443
  progress.stop();
@@ -38329,7 +38445,7 @@ Run ${pc54.cyan("wraps sms verify-number")} to verify a number.
38329
38445
  trackError("SMS_LIST_VERIFIED_FAILED", "sms:verify-number:list", {
38330
38446
  error: errorMessage
38331
38447
  });
38332
- clack50.log.error(`Failed to list verified numbers: ${errorMessage}`);
38448
+ clack51.log.error(`Failed to list verified numbers: ${errorMessage}`);
38333
38449
  process.exit(1);
38334
38450
  }
38335
38451
  }
@@ -38337,7 +38453,7 @@ Run ${pc54.cyan("wraps sms verify-number")} to verify a number.
38337
38453
  const phoneNumber2 = options.phoneNumber;
38338
38454
  if (!phoneNumber2) {
38339
38455
  progress.stop();
38340
- clack50.log.error("Phone number is required for deletion");
38456
+ clack51.log.error("Phone number is required for deletion");
38341
38457
  console.log(
38342
38458
  `
38343
38459
  Usage: ${pc54.cyan("wraps sms verify-number --delete --phone-number +14155551234")}
@@ -38354,7 +38470,7 @@ Usage: ${pc54.cyan("wraps sms verify-number --delete --phone-number +14155551234
38354
38470
  const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
38355
38471
  if (!verifiedNumber?.VerifiedDestinationNumberId) {
38356
38472
  progress.stop();
38357
- clack50.log.error(`Number ${phoneNumber2} is not in verified list`);
38473
+ clack51.log.error(`Number ${phoneNumber2} is not in verified list`);
38358
38474
  process.exit(1);
38359
38475
  }
38360
38476
  await progress.execute(`Removing ${phoneNumber2}`, async () => {
@@ -38365,7 +38481,7 @@ Usage: ${pc54.cyan("wraps sms verify-number --delete --phone-number +14155551234
38365
38481
  );
38366
38482
  });
38367
38483
  progress.stop();
38368
- clack50.log.success(`Removed ${pc54.cyan(phoneNumber2)} from verified list`);
38484
+ clack51.log.success(`Removed ${pc54.cyan(phoneNumber2)} from verified list`);
38369
38485
  trackCommand("sms:verify-number:delete", {
38370
38486
  success: true,
38371
38487
  duration_ms: Date.now() - startTime
@@ -38377,7 +38493,7 @@ Usage: ${pc54.cyan("wraps sms verify-number --delete --phone-number +14155551234
38377
38493
  });
38378
38494
  return;
38379
38495
  }
38380
- clack50.outro(pc54.green("Done!"));
38496
+ clack51.outro(pc54.green("Done!"));
38381
38497
  return;
38382
38498
  } catch (error) {
38383
38499
  progress.stop();
@@ -38385,7 +38501,7 @@ Usage: ${pc54.cyan("wraps sms verify-number --delete --phone-number +14155551234
38385
38501
  trackError("SMS_DELETE_VERIFIED_FAILED", "sms:verify-number:delete", {
38386
38502
  error: errorMessage
38387
38503
  });
38388
- clack50.log.error(`Failed to delete verified number: ${errorMessage}`);
38504
+ clack51.log.error(`Failed to delete verified number: ${errorMessage}`);
38389
38505
  process.exit(1);
38390
38506
  }
38391
38507
  }
@@ -38398,7 +38514,7 @@ Usage: ${pc54.cyan("wraps sms verify-number --delete --phone-number +14155551234
38398
38514
  );
38399
38515
  }
38400
38516
  if (!phoneNumber) {
38401
- const result = await clack50.text({
38517
+ const result = await clack51.text({
38402
38518
  message: "Enter phone number to verify (E.164 format):",
38403
38519
  placeholder: "+14155551234",
38404
38520
  validate: (value) => {
@@ -38411,14 +38527,14 @@ Usage: ${pc54.cyan("wraps sms verify-number --delete --phone-number +14155551234
38411
38527
  return;
38412
38528
  }
38413
38529
  });
38414
- if (clack50.isCancel(result)) {
38415
- clack50.cancel("Operation cancelled.");
38530
+ if (clack51.isCancel(result)) {
38531
+ clack51.cancel("Operation cancelled.");
38416
38532
  process.exit(0);
38417
38533
  }
38418
38534
  phoneNumber = result;
38419
38535
  } else if (!isValidPhoneNumber(phoneNumber)) {
38420
38536
  progress.stop();
38421
- clack50.log.error(
38537
+ clack51.log.error(
38422
38538
  `Invalid phone number format: ${phoneNumber}. Use E.164 format (e.g., +14155551234)`
38423
38539
  );
38424
38540
  process.exit(1);
@@ -38433,7 +38549,7 @@ Usage: ${pc54.cyan("wraps sms verify-number --delete --phone-number +14155551234
38433
38549
  const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
38434
38550
  if (!verifiedNumber?.VerifiedDestinationNumberId) {
38435
38551
  progress.stop();
38436
- clack50.log.error(
38552
+ clack51.log.error(
38437
38553
  `Number ${phoneNumber} not found. Run without --code first.`
38438
38554
  );
38439
38555
  process.exit(1);
@@ -38448,7 +38564,7 @@ Usage: ${pc54.cyan("wraps sms verify-number --delete --phone-number +14155551234
38448
38564
  });
38449
38565
  progress.stop();
38450
38566
  console.log("\n");
38451
- clack50.log.success(
38567
+ clack51.log.success(
38452
38568
  pc54.green(`Phone number ${pc54.cyan(phoneNumber)} verified!`)
38453
38569
  );
38454
38570
  console.log("");
@@ -38466,13 +38582,13 @@ Usage: ${pc54.cyan("wraps sms verify-number --delete --phone-number +14155551234
38466
38582
  });
38467
38583
  return;
38468
38584
  }
38469
- clack50.outro(pc54.green("Verification complete!"));
38585
+ clack51.outro(pc54.green("Verification complete!"));
38470
38586
  return;
38471
38587
  } catch (error) {
38472
38588
  progress.stop();
38473
38589
  const errorMessage = error instanceof Error ? error.message : String(error);
38474
38590
  if (errorMessage.includes("Invalid verification code")) {
38475
- clack50.log.error("Invalid verification code. Please try again.");
38591
+ clack51.log.error("Invalid verification code. Please try again.");
38476
38592
  console.log(
38477
38593
  `
38478
38594
  Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
@@ -38482,7 +38598,7 @@ Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
38482
38598
  trackError("SMS_VERIFY_CODE_FAILED", "sms:verify-number:confirm", {
38483
38599
  error: errorMessage
38484
38600
  });
38485
- clack50.log.error(`Verification failed: ${errorMessage}`);
38601
+ clack51.log.error(`Verification failed: ${errorMessage}`);
38486
38602
  }
38487
38603
  process.exit(1);
38488
38604
  }
@@ -38497,7 +38613,7 @@ Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
38497
38613
  const verifiedNumber = listResponse.VerifiedDestinationNumbers?.[0];
38498
38614
  if (!verifiedNumber?.VerifiedDestinationNumberId) {
38499
38615
  progress.stop();
38500
- clack50.log.error(
38616
+ clack51.log.error(
38501
38617
  `Number ${phoneNumber} not found. Run without --resend first.`
38502
38618
  );
38503
38619
  process.exit(1);
@@ -38511,7 +38627,7 @@ Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
38511
38627
  );
38512
38628
  });
38513
38629
  progress.stop();
38514
- clack50.log.success(`Verification code resent to ${pc54.cyan(phoneNumber)}`);
38630
+ clack51.log.success(`Verification code resent to ${pc54.cyan(phoneNumber)}`);
38515
38631
  console.log("");
38516
38632
  console.log(
38517
38633
  `Once you receive the code, run:
@@ -38528,7 +38644,7 @@ Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
38528
38644
  });
38529
38645
  return;
38530
38646
  }
38531
- clack50.outro(pc54.green("Code sent!"));
38647
+ clack51.outro(pc54.green("Code sent!"));
38532
38648
  return;
38533
38649
  } catch (error) {
38534
38650
  progress.stop();
@@ -38536,7 +38652,7 @@ Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
38536
38652
  trackError("SMS_RESEND_CODE_FAILED", "sms:verify-number:resend", {
38537
38653
  error: errorMessage
38538
38654
  });
38539
- clack50.log.error(`Failed to resend code: ${errorMessage}`);
38655
+ clack51.log.error(`Failed to resend code: ${errorMessage}`);
38540
38656
  process.exit(1);
38541
38657
  }
38542
38658
  }
@@ -38556,10 +38672,10 @@ Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
38556
38672
  });
38557
38673
  return;
38558
38674
  }
38559
- clack50.log.info(
38675
+ clack51.log.info(
38560
38676
  `Number ${pc54.cyan(phoneNumber)} is already verified and ready to use!`
38561
38677
  );
38562
- clack50.outro(pc54.green("Done!"));
38678
+ clack51.outro(pc54.green("Done!"));
38563
38679
  return;
38564
38680
  }
38565
38681
  if (existingNumber?.Status === "PENDING") {
@@ -38583,7 +38699,7 @@ Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
38583
38699
  });
38584
38700
  return;
38585
38701
  }
38586
- clack50.log.info(
38702
+ clack51.log.info(
38587
38703
  `Verification already in progress. New code sent to ${pc54.cyan(phoneNumber)}`
38588
38704
  );
38589
38705
  console.log("");
@@ -38591,7 +38707,7 @@ Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
38591
38707
  `Once you receive the code, run:
38592
38708
  ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
38593
38709
  );
38594
- clack50.outro(pc54.green("Code sent!"));
38710
+ clack51.outro(pc54.green("Code sent!"));
38595
38711
  return;
38596
38712
  }
38597
38713
  const createResponse = await progress.execute(
@@ -38612,11 +38728,11 @@ Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
38612
38728
  });
38613
38729
  progress.stop();
38614
38730
  console.log("\n");
38615
- clack50.log.success(
38731
+ clack51.log.success(
38616
38732
  `Verification code sent to ${pc54.cyan(phoneNumber)} via SMS`
38617
38733
  );
38618
38734
  console.log("");
38619
- clack50.note(
38735
+ clack51.note(
38620
38736
  [
38621
38737
  "1. Check your phone for the verification code",
38622
38738
  "",
@@ -38639,12 +38755,12 @@ Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
38639
38755
  });
38640
38756
  return;
38641
38757
  }
38642
- clack50.outro(pc54.green("Verification started!"));
38758
+ clack51.outro(pc54.green("Verification started!"));
38643
38759
  } catch (error) {
38644
38760
  progress.stop();
38645
38761
  const errorMessage = error instanceof Error ? error.message : String(error);
38646
38762
  if (errorMessage.includes("already exists")) {
38647
- clack50.log.error("This number is already being verified");
38763
+ clack51.log.error("This number is already being verified");
38648
38764
  console.log(
38649
38765
  `
38650
38766
  Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
@@ -38654,7 +38770,7 @@ Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
38654
38770
  trackError("SMS_CREATE_VERIFIED_FAILED", "sms:verify-number:start", {
38655
38771
  error: errorMessage
38656
38772
  });
38657
- clack50.log.error(`Failed to start verification: ${errorMessage}`);
38773
+ clack51.log.error(`Failed to start verification: ${errorMessage}`);
38658
38774
  }
38659
38775
  process.exit(1);
38660
38776
  }
@@ -38663,11 +38779,11 @@ Run ${pc54.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
38663
38779
  // src/commands/support.ts
38664
38780
  init_esm_shims();
38665
38781
  init_events();
38666
- import * as clack51 from "@clack/prompts";
38782
+ import * as clack52 from "@clack/prompts";
38667
38783
  import pc55 from "picocolors";
38668
38784
  async function support() {
38669
38785
  trackCommand("support", { success: true });
38670
- clack51.intro(pc55.bold("Get Help with Wraps"));
38786
+ clack52.intro(pc55.bold("Get Help with Wraps"));
38671
38787
  console.log();
38672
38788
  console.log(` ${pc55.bold("Email:")} ${pc55.cyan("hey@wraps.sh")}`);
38673
38789
  console.log(
@@ -38682,20 +38798,20 @@ async function support() {
38682
38798
  // src/commands/telemetry.ts
38683
38799
  init_esm_shims();
38684
38800
  init_client();
38685
- import * as clack52 from "@clack/prompts";
38801
+ import * as clack53 from "@clack/prompts";
38686
38802
  import pc56 from "picocolors";
38687
38803
  async function telemetryEnable() {
38688
38804
  const client = getTelemetryClient();
38689
38805
  const override = client.enable();
38690
38806
  if (override) {
38691
- clack52.log.warn(
38807
+ clack53.log.warn(
38692
38808
  "Telemetry enabled in config, but overridden by environment"
38693
38809
  );
38694
38810
  console.log(` Reason: ${pc56.yellow(override)}`);
38695
38811
  console.log(` Config: ${pc56.dim(client.getConfigPath())}`);
38696
38812
  console.log();
38697
38813
  } else {
38698
- clack52.log.success(pc56.green("Telemetry enabled"));
38814
+ clack53.log.success(pc56.green("Telemetry enabled"));
38699
38815
  console.log(` Config: ${pc56.dim(client.getConfigPath())}`);
38700
38816
  console.log(`
38701
38817
  ${pc56.dim("Thank you for helping improve Wraps!")}
@@ -38705,7 +38821,7 @@ async function telemetryEnable() {
38705
38821
  async function telemetryDisable() {
38706
38822
  const client = getTelemetryClient();
38707
38823
  client.disable();
38708
- clack52.log.success(pc56.green("Telemetry disabled"));
38824
+ clack53.log.success(pc56.green("Telemetry disabled"));
38709
38825
  console.log(` Config: ${pc56.dim(client.getConfigPath())}`);
38710
38826
  console.log(
38711
38827
  `
@@ -38715,7 +38831,7 @@ async function telemetryDisable() {
38715
38831
  }
38716
38832
  async function telemetryStatus() {
38717
38833
  const client = getTelemetryClient();
38718
- clack52.intro(pc56.bold("Telemetry Status"));
38834
+ clack53.intro(pc56.bold("Telemetry Status"));
38719
38835
  const override = client.getEnvOverride();
38720
38836
  const status2 = client.isEnabled() ? pc56.green("Enabled") : pc56.red("Disabled");
38721
38837
  console.log();
@@ -38753,7 +38869,7 @@ async function telemetryStatus() {
38753
38869
  init_esm_shims();
38754
38870
  import { existsSync as existsSync18, mkdirSync as mkdirSync2, writeFileSync } from "fs";
38755
38871
  import { join as join20 } from "path";
38756
- import * as clack53 from "@clack/prompts";
38872
+ import * as clack54 from "@clack/prompts";
38757
38873
  import pc57 from "picocolors";
38758
38874
  var EXAMPLE_CASCADE_WORKFLOW = `import {
38759
38875
  defineWorkflow,
@@ -38849,30 +38965,30 @@ export default defineConfig({
38849
38965
  });
38850
38966
  `;
38851
38967
  async function workflowInit(options = {}) {
38852
- clack53.intro(pc57.bgCyan(pc57.black(" wraps workflow init ")));
38968
+ clack54.intro(pc57.bgCyan(pc57.black(" wraps workflow init ")));
38853
38969
  const wrapsDir = join20(process.cwd(), "wraps");
38854
38970
  const workflowsDir = join20(wrapsDir, "workflows");
38855
38971
  const configPath = join20(wrapsDir, "wraps.config.ts");
38856
38972
  if (existsSync18(workflowsDir)) {
38857
- clack53.log.info(
38973
+ clack54.log.info(
38858
38974
  `Workflows directory already exists at ${pc57.cyan("wraps/workflows/")}`
38859
38975
  );
38860
38976
  const files = existsSync18(join20(workflowsDir, "cart-recovery.ts")) || existsSync18(join20(workflowsDir, "welcome-sequence.ts"));
38861
38977
  if (files && !options.yes) {
38862
- const shouldContinue = await clack53.confirm({
38978
+ const shouldContinue = await clack54.confirm({
38863
38979
  message: "Example files may already exist. Overwrite them?",
38864
38980
  initialValue: false
38865
38981
  });
38866
- if (clack53.isCancel(shouldContinue) || !shouldContinue) {
38867
- clack53.log.info("Skipping file creation.");
38982
+ if (clack54.isCancel(shouldContinue) || !shouldContinue) {
38983
+ clack54.log.info("Skipping file creation.");
38868
38984
  showNextSteps2();
38869
- clack53.outro("Done!");
38985
+ clack54.outro("Done!");
38870
38986
  return;
38871
38987
  }
38872
38988
  }
38873
38989
  }
38874
38990
  try {
38875
- const s = clack53.spinner();
38991
+ const s = clack54.spinner();
38876
38992
  s.start("Creating workflows directory...");
38877
38993
  mkdirSync2(workflowsDir, { recursive: true });
38878
38994
  s.stop("Created wraps/workflows/");
@@ -38890,26 +39006,26 @@ async function workflowInit(options = {}) {
38890
39006
  s.stop("Created 2 example workflows");
38891
39007
  if (!existsSync18(configPath)) {
38892
39008
  writeFileSync(configPath, EXAMPLE_CONFIG, "utf-8");
38893
- clack53.log.info(`Created ${pc57.cyan("wraps/wraps.config.ts")}`);
39009
+ clack54.log.info(`Created ${pc57.cyan("wraps/wraps.config.ts")}`);
38894
39010
  }
38895
- clack53.log.success(
39011
+ clack54.log.success(
38896
39012
  `${pc57.bold("Workflows scaffolded!")} Created:
38897
39013
  ${pc57.cyan("wraps/wraps.config.ts")} \u2014 Project config
38898
39014
  ${pc57.cyan("wraps/workflows/cart-recovery.ts")} \u2014 Cross-channel cascade example
38899
39015
  ${pc57.cyan("wraps/workflows/welcome-sequence.ts")} \u2014 Welcome series example`
38900
39016
  );
38901
39017
  showNextSteps2();
38902
- clack53.outro(pc57.green("Happy orchestrating!"));
39018
+ clack54.outro(pc57.green("Happy orchestrating!"));
38903
39019
  } catch (error) {
38904
- clack53.log.error(
39020
+ clack54.log.error(
38905
39021
  `Failed to scaffold workflows: ${error instanceof Error ? error.message : String(error)}`
38906
39022
  );
38907
- clack53.outro(pc57.red("Scaffolding failed."));
39023
+ clack54.outro(pc57.red("Scaffolding failed."));
38908
39024
  process.exitCode = 1;
38909
39025
  }
38910
39026
  }
38911
39027
  function showNextSteps2() {
38912
- clack53.log.info(
39028
+ clack54.log.info(
38913
39029
  `${pc57.bold("Next steps:")}
38914
39030
 
38915
39031
  1. Edit ${pc57.cyan("wraps/wraps.config.ts")} with your org slug and domain
@@ -38968,6 +39084,7 @@ var BOOLEAN_FLAGS = [
38968
39084
  "draft",
38969
39085
  "root",
38970
39086
  "cleanup",
39087
+ "reveal-secret",
38971
39088
  "help",
38972
39089
  "version"
38973
39090
  ];
@@ -39094,7 +39211,7 @@ function showVersion() {
39094
39211
  process.exit(0);
39095
39212
  }
39096
39213
  function showHelp() {
39097
- clack54.intro(pc59.bold(`WRAPS CLI v${VERSION}`));
39214
+ clack55.intro(pc59.bold(`WRAPS CLI v${VERSION}`));
39098
39215
  console.log("Deploy AWS infrastructure to your account\n");
39099
39216
  console.log("Usage: wraps [service] <command> [options]\n");
39100
39217
  console.log("Services:");
@@ -39300,7 +39417,7 @@ if (!primaryCommand) {
39300
39417
  const telemetry = getTelemetryClient();
39301
39418
  if (telemetry.shouldShowNotification()) {
39302
39419
  console.log();
39303
- clack54.log.info(pc59.bold("Anonymous Telemetry"));
39420
+ clack55.log.info(pc59.bold("Anonymous Telemetry"));
39304
39421
  console.log(
39305
39422
  ` Wraps collects ${pc59.cyan("anonymous usage data")} to improve the CLI.`
39306
39423
  );
@@ -39318,9 +39435,9 @@ if (!primaryCommand) {
39318
39435
  telemetry.markNotificationShown();
39319
39436
  }
39320
39437
  trackCommand("interactive:menu", { success: true, duration_ms: 0 });
39321
- clack54.intro(pc59.bold(`WRAPS CLI v${VERSION}`));
39438
+ clack55.intro(pc59.bold(`WRAPS CLI v${VERSION}`));
39322
39439
  console.log(" Deploy AWS infrastructure to your account.\n");
39323
- const action = await clack54.select({
39440
+ const action = await clack55.select({
39324
39441
  message: "What would you like to do?",
39325
39442
  options: [
39326
39443
  {
@@ -39370,13 +39487,13 @@ if (!primaryCommand) {
39370
39487
  }
39371
39488
  ]
39372
39489
  });
39373
- if (clack54.isCancel(action)) {
39490
+ if (clack55.isCancel(action)) {
39374
39491
  trackCommand("interactive:cancel", {
39375
39492
  success: true,
39376
39493
  duration_ms: Date.now() - startTime
39377
39494
  });
39378
39495
  await telemetry.shutdown();
39379
- clack54.cancel("Operation cancelled.");
39496
+ clack55.cancel("Operation cancelled.");
39380
39497
  process.exit(0);
39381
39498
  }
39382
39499
  trackCommand(`interactive:${action}`, {
@@ -39455,7 +39572,7 @@ async function run() {
39455
39572
  const telemetry = getTelemetryClient();
39456
39573
  if (telemetry.shouldShowNotification()) {
39457
39574
  console.log();
39458
- clack54.log.info(pc59.bold("Anonymous Telemetry"));
39575
+ clack55.log.info(pc59.bold("Anonymous Telemetry"));
39459
39576
  console.log(
39460
39577
  ` Wraps collects ${pc59.cyan("anonymous usage data")} to improve the CLI.`
39461
39578
  );
@@ -39552,7 +39669,7 @@ async function run() {
39552
39669
  break;
39553
39670
  case "verify": {
39554
39671
  if (!flags.domain) {
39555
- clack54.log.error("--domain flag is required");
39672
+ clack55.log.error("--domain flag is required");
39556
39673
  console.log(
39557
39674
  `
39558
39675
  Usage: ${pc59.cyan("wraps email verify --domain yourapp.com")}
@@ -39591,7 +39708,8 @@ Usage: ${pc59.cyan("wraps email verify --domain yourapp.com")}
39591
39708
  case "status":
39592
39709
  await inboundStatus({
39593
39710
  region: flags.region,
39594
- json: flags.json
39711
+ json: flags.json,
39712
+ revealSecret: flags.revealSecret
39595
39713
  });
39596
39714
  break;
39597
39715
  case "verify":
@@ -39625,7 +39743,7 @@ Usage: ${pc59.cyan("wraps email verify --domain yourapp.com")}
39625
39743
  });
39626
39744
  break;
39627
39745
  default:
39628
- clack54.log.error(
39746
+ clack55.log.error(
39629
39747
  `Unknown inbound command: ${inboundSubCommand || "(none)"}`
39630
39748
  );
39631
39749
  console.log(
@@ -39680,7 +39798,7 @@ Available commands: ${pc59.cyan("init")}, ${pc59.cyan("destroy")}, ${pc59.cyan("
39680
39798
  break;
39681
39799
  }
39682
39800
  default:
39683
- clack54.log.error(
39801
+ clack55.log.error(
39684
39802
  `Unknown reply command: ${replySubCommand || "(none)"}`
39685
39803
  );
39686
39804
  console.log(
@@ -39710,7 +39828,7 @@ Available commands: ${pc59.cyan("init")}, ${pc59.cyan("rotate")}, ${pc59.cyan("s
39710
39828
  break;
39711
39829
  case "verify": {
39712
39830
  if (!flags.domain) {
39713
- clack54.log.error("--domain flag is required");
39831
+ clack55.log.error("--domain flag is required");
39714
39832
  console.log(
39715
39833
  `
39716
39834
  Usage: ${pc59.cyan("wraps email domains verify --domain yourapp.com")}
@@ -39723,7 +39841,7 @@ Usage: ${pc59.cyan("wraps email domains verify --domain yourapp.com")}
39723
39841
  }
39724
39842
  case "get-dkim": {
39725
39843
  if (!flags.domain) {
39726
- clack54.log.error("--domain flag is required");
39844
+ clack55.log.error("--domain flag is required");
39727
39845
  console.log(
39728
39846
  `
39729
39847
  Usage: ${pc59.cyan("wraps email domains get-dkim --domain yourapp.com")}
@@ -39736,7 +39854,7 @@ Usage: ${pc59.cyan("wraps email domains get-dkim --domain yourapp.com")}
39736
39854
  }
39737
39855
  case "remove": {
39738
39856
  if (!flags.domain) {
39739
- clack54.log.error("--domain flag is required");
39857
+ clack55.log.error("--domain flag is required");
39740
39858
  console.log(
39741
39859
  `
39742
39860
  Usage: ${pc59.cyan("wraps email domains remove --domain yourapp.com --force")}
@@ -39751,7 +39869,7 @@ Usage: ${pc59.cyan("wraps email domains remove --domain yourapp.com --force")}
39751
39869
  break;
39752
39870
  }
39753
39871
  default:
39754
- clack54.log.error(
39872
+ clack55.log.error(
39755
39873
  `Unknown domains command: ${domainsSubCommand || "(none)"}`
39756
39874
  );
39757
39875
  console.log(
@@ -39798,7 +39916,7 @@ Available commands: ${pc59.cyan("add")}, ${pc59.cyan("list")}, ${pc59.cyan("veri
39798
39916
  });
39799
39917
  break;
39800
39918
  default:
39801
- clack54.log.error(
39919
+ clack55.log.error(
39802
39920
  `Unknown templates command: ${templatesSubCommand || "(none)"}`
39803
39921
  );
39804
39922
  console.log(
@@ -39842,7 +39960,7 @@ Available commands: ${pc59.cyan("init")}, ${pc59.cyan("push")}, ${pc59.cyan("pre
39842
39960
  });
39843
39961
  break;
39844
39962
  default:
39845
- clack54.log.error(
39963
+ clack55.log.error(
39846
39964
  `Unknown workflows command: ${workflowsSubCommand || "(none)"}`
39847
39965
  );
39848
39966
  console.log(
@@ -39872,7 +39990,7 @@ Available commands: ${pc59.cyan("init")}, ${pc59.cyan("validate")}, ${pc59.cyan(
39872
39990
  });
39873
39991
  break;
39874
39992
  default:
39875
- clack54.log.error(`Unknown email command: ${subCommand}`);
39993
+ clack55.log.error(`Unknown email command: ${subCommand}`);
39876
39994
  console.log(
39877
39995
  `
39878
39996
  Run ${pc59.cyan("wraps --help")} for available commands.
@@ -39950,7 +40068,7 @@ Run ${pc59.cyan("wraps --help")} for available commands.
39950
40068
  });
39951
40069
  break;
39952
40070
  default:
39953
- clack54.log.error(`Unknown sms command: ${subCommand}`);
40071
+ clack55.log.error(`Unknown sms command: ${subCommand}`);
39954
40072
  console.log(
39955
40073
  `
39956
40074
  Run ${pc59.cyan("wraps --help")} for available commands.
@@ -40014,7 +40132,7 @@ Run ${pc59.cyan("wraps --help")} for available commands.
40014
40132
  });
40015
40133
  break;
40016
40134
  default:
40017
- clack54.log.error(`Unknown cdn command: ${subCommand}`);
40135
+ clack55.log.error(`Unknown cdn command: ${subCommand}`);
40018
40136
  console.log(
40019
40137
  `
40020
40138
  Run ${pc59.cyan("wraps --help")} for available commands.
@@ -40039,7 +40157,7 @@ Run ${pc59.cyan("wraps --help")} for available commands.
40039
40157
  });
40040
40158
  break;
40041
40159
  default:
40042
- clack54.log.error(
40160
+ clack55.log.error(
40043
40161
  `Unknown workflow command: ${subCommand || "(none)"}`
40044
40162
  );
40045
40163
  console.log(`
@@ -40087,7 +40205,7 @@ Available commands: ${pc59.cyan("init")}
40087
40205
  });
40088
40206
  break;
40089
40207
  default:
40090
- clack54.log.error(`Unknown platform command: ${subCommand}`);
40208
+ clack55.log.error(`Unknown platform command: ${subCommand}`);
40091
40209
  console.log(
40092
40210
  `
40093
40211
  Available commands: ${pc59.cyan("connect")}, ${pc59.cyan("update-role")}
@@ -40119,7 +40237,7 @@ Available commands: ${pc59.cyan("connect")}, ${pc59.cyan("update-role")}
40119
40237
  await logout();
40120
40238
  break;
40121
40239
  default:
40122
- clack54.log.error(`Unknown auth command: ${subCommand || "(none)"}`);
40240
+ clack55.log.error(`Unknown auth command: ${subCommand || "(none)"}`);
40123
40241
  console.log(
40124
40242
  `
40125
40243
  Available commands: ${pc59.cyan("login")}, ${pc59.cyan("status")}, ${pc59.cyan("logout")}
@@ -40140,7 +40258,7 @@ Available commands: ${pc59.cyan("login")}, ${pc59.cyan("status")}, ${pc59.cyan("
40140
40258
  await doctor();
40141
40259
  break;
40142
40260
  default:
40143
- clack54.log.error(`Unknown aws command: ${subCommand}`);
40261
+ clack55.log.error(`Unknown aws command: ${subCommand}`);
40144
40262
  console.log(
40145
40263
  `
40146
40264
  Available commands: ${pc59.cyan("setup")}, ${pc59.cyan("doctor")}
@@ -40225,7 +40343,7 @@ Available commands: ${pc59.cyan("setup")}, ${pc59.cyan("doctor")}
40225
40343
  await telemetryStatus();
40226
40344
  break;
40227
40345
  default:
40228
- clack54.log.error(`Unknown telemetry command: ${subCommand}`);
40346
+ clack55.log.error(`Unknown telemetry command: ${subCommand}`);
40229
40347
  console.log(
40230
40348
  `
40231
40349
  Available commands: ${pc59.cyan("enable")}, ${pc59.cyan("disable")}, ${pc59.cyan("status")}
@@ -40252,7 +40370,7 @@ Please specify a command for ${primaryCommand} service.
40252
40370
  showHelp();
40253
40371
  break;
40254
40372
  default:
40255
- clack54.log.error(`Unknown command: ${primaryCommand}`);
40373
+ clack55.log.error(`Unknown command: ${primaryCommand}`);
40256
40374
  console.log(
40257
40375
  `
40258
40376
  Run ${pc59.cyan("wraps --help")} for available commands.