@wraps.dev/cli 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1348,9 +1348,12 @@ var init_route53 = __esm({
1348
1348
 
1349
1349
  // src/cli.ts
1350
1350
  init_esm_shims();
1351
- import * as clack12 from "@clack/prompts";
1351
+ import { readFileSync } from "fs";
1352
+ import { dirname as dirname2, join as join4 } from "path";
1353
+ import { fileURLToPath as fileURLToPath4 } from "url";
1354
+ import * as clack13 from "@clack/prompts";
1352
1355
  import args from "args";
1353
- import pc12 from "picocolors";
1356
+ import pc13 from "picocolors";
1354
1357
 
1355
1358
  // src/commands/connect.ts
1356
1359
  init_esm_shims();
@@ -4369,17 +4372,14 @@ Run ${pc9.cyan("wraps init")} to deploy infrastructure.
4369
4372
  });
4370
4373
  }
4371
4374
 
4372
- // src/commands/upgrade.ts
4375
+ // src/commands/update.ts
4373
4376
  init_esm_shims();
4374
4377
  import * as clack10 from "@clack/prompts";
4375
4378
  import * as pulumi11 from "@pulumi/pulumi";
4376
4379
  import pc10 from "picocolors";
4377
4380
  init_aws();
4378
- init_costs();
4379
- init_presets();
4380
- init_prompts();
4381
- async function upgrade(options) {
4382
- clack10.intro(pc10.bold("Wraps Upgrade - Enhance Your Email Infrastructure"));
4381
+ async function update(options) {
4382
+ clack10.intro(pc10.bold("Wraps Update - Apply CLI Updates to Infrastructure"));
4383
4383
  const progress = new DeploymentProgress();
4384
4384
  const wasAutoInstalled = await progress.execute(
4385
4385
  "Checking Pulumi CLI installation",
@@ -4423,33 +4423,224 @@ ${pc10.bold("Current Configuration:")}
4423
4423
  }
4424
4424
  if (config.tracking?.enabled) {
4425
4425
  console.log(` ${pc10.green("\u2713")} Open & Click Tracking`);
4426
+ }
4427
+ if (config.suppressionList?.enabled) {
4428
+ console.log(` ${pc10.green("\u2713")} Bounce/Complaint Suppression`);
4429
+ }
4430
+ if (config.eventTracking?.enabled) {
4431
+ console.log(` ${pc10.green("\u2713")} Event Tracking (EventBridge)`);
4432
+ }
4433
+ if (config.dedicatedIp) {
4434
+ console.log(` ${pc10.green("\u2713")} Dedicated IP Address`);
4435
+ }
4436
+ console.log("");
4437
+ console.log(`${pc10.bold("What will be updated:")}
4438
+ `);
4439
+ console.log(
4440
+ ` ${pc10.cyan("\u2022")} Lambda function code (if event tracking enabled)`
4441
+ );
4442
+ console.log(
4443
+ ` ${pc10.cyan("\u2022")} EventBridge rules (if event tracking enabled)`
4444
+ );
4445
+ console.log(` ${pc10.cyan("\u2022")} IAM policies (security improvements)`);
4446
+ console.log(` ${pc10.cyan("\u2022")} SES configuration set (feature updates)`);
4447
+ console.log("");
4448
+ progress.info(
4449
+ "Your current configuration will be preserved - no features will be added or removed"
4450
+ );
4451
+ console.log("");
4452
+ if (!options.yes) {
4453
+ const confirmed = await clack10.confirm({
4454
+ message: "Proceed with update?",
4455
+ initialValue: true
4456
+ });
4457
+ if (clack10.isCancel(confirmed) || !confirmed) {
4458
+ clack10.cancel("Update cancelled.");
4459
+ process.exit(0);
4460
+ }
4461
+ }
4462
+ let vercelConfig;
4463
+ if (metadata.provider === "vercel" && metadata.vercel) {
4464
+ vercelConfig = metadata.vercel;
4465
+ }
4466
+ const stackConfig = {
4467
+ provider: metadata.provider,
4468
+ region,
4469
+ vercel: vercelConfig,
4470
+ emailConfig: config
4471
+ };
4472
+ let outputs;
4473
+ try {
4474
+ outputs = await progress.execute(
4475
+ "Updating Wraps infrastructure (this may take 2-3 minutes)",
4476
+ async () => {
4477
+ await ensurePulumiWorkDir();
4478
+ const stack = await pulumi11.automation.LocalWorkspace.createOrSelectStack(
4479
+ {
4480
+ stackName: metadata.pulumiStackName || `wraps-${identity.accountId}-${region}`,
4481
+ projectName: "wraps-email",
4482
+ program: async () => {
4483
+ const result = await deployEmailStack(stackConfig);
4484
+ return {
4485
+ roleArn: result.roleArn,
4486
+ configSetName: result.configSetName,
4487
+ tableName: result.tableName,
4488
+ region: result.region,
4489
+ lambdaFunctions: result.lambdaFunctions,
4490
+ domain: result.domain,
4491
+ dkimTokens: result.dkimTokens,
4492
+ customTrackingDomain: result.customTrackingDomain
4493
+ };
4494
+ }
4495
+ },
4496
+ {
4497
+ workDir: getPulumiWorkDir(),
4498
+ envVars: {
4499
+ PULUMI_CONFIG_PASSPHRASE: ""
4500
+ },
4501
+ secretsProvider: "passphrase"
4502
+ }
4503
+ );
4504
+ await stack.workspace.selectStack(
4505
+ metadata.pulumiStackName || `wraps-${identity.accountId}-${region}`
4506
+ );
4507
+ await stack.setConfig("aws:region", { value: region });
4508
+ const upResult = await stack.up({ onOutput: () => {
4509
+ } });
4510
+ const pulumiOutputs = upResult.outputs;
4511
+ return {
4512
+ roleArn: pulumiOutputs.roleArn?.value,
4513
+ configSetName: pulumiOutputs.configSetName?.value,
4514
+ tableName: pulumiOutputs.tableName?.value,
4515
+ region: pulumiOutputs.region?.value,
4516
+ lambdaFunctions: pulumiOutputs.lambdaFunctions?.value,
4517
+ domain: pulumiOutputs.domain?.value,
4518
+ dkimTokens: pulumiOutputs.dkimTokens?.value,
4519
+ customTrackingDomain: pulumiOutputs.customTrackingDomain?.value
4520
+ };
4521
+ }
4522
+ );
4523
+ } catch (error) {
4524
+ clack10.log.error("Infrastructure update failed");
4525
+ if (error.message?.includes("stack is currently locked")) {
4526
+ clack10.log.warn("\nThe Pulumi stack is locked from a previous run.");
4527
+ clack10.log.info("To fix this, run:");
4528
+ clack10.log.info(` ${pc10.cyan("rm -rf ~/.wraps/pulumi/.pulumi/locks")}`);
4529
+ clack10.log.info("\nThen try running wraps update again.");
4530
+ }
4531
+ throw new Error(`Pulumi update failed: ${error.message}`);
4532
+ }
4533
+ metadata.timestamp = (/* @__PURE__ */ new Date()).toISOString();
4534
+ await saveConnectionMetadata(metadata);
4535
+ progress.info("Connection metadata updated");
4536
+ displaySuccess({
4537
+ roleArn: outputs.roleArn,
4538
+ configSetName: outputs.configSetName,
4539
+ region: outputs.region,
4540
+ tableName: outputs.tableName,
4541
+ customTrackingDomain: outputs.customTrackingDomain
4542
+ });
4543
+ console.log(`
4544
+ ${pc10.green("\u2713")} ${pc10.bold("Update complete!")}
4545
+ `);
4546
+ console.log(
4547
+ "Infrastructure has been updated with the latest CLI improvements.\n"
4548
+ );
4549
+ console.log(`${pc10.bold("Next steps:")}
4550
+ `);
4551
+ console.log(
4552
+ ` ${pc10.cyan("1.")} No code changes needed - your existing SDK integration continues to work`
4553
+ );
4554
+ console.log(
4555
+ ` ${pc10.cyan("2.")} Check ${pc10.cyan("wraps status")} to verify all resources are healthy`
4556
+ );
4557
+ console.log(
4558
+ ` ${pc10.cyan("3.")} View analytics at ${pc10.cyan("wraps console")}
4559
+ `
4560
+ );
4561
+ }
4562
+
4563
+ // src/commands/upgrade.ts
4564
+ init_esm_shims();
4565
+ import * as clack11 from "@clack/prompts";
4566
+ import * as pulumi12 from "@pulumi/pulumi";
4567
+ import pc11 from "picocolors";
4568
+ init_aws();
4569
+ init_costs();
4570
+ init_presets();
4571
+ init_prompts();
4572
+ async function upgrade(options) {
4573
+ clack11.intro(pc11.bold("Wraps Upgrade - Enhance Your Email Infrastructure"));
4574
+ const progress = new DeploymentProgress();
4575
+ const wasAutoInstalled = await progress.execute(
4576
+ "Checking Pulumi CLI installation",
4577
+ async () => await ensurePulumiInstalled()
4578
+ );
4579
+ if (wasAutoInstalled) {
4580
+ progress.info("Pulumi CLI was automatically installed");
4581
+ }
4582
+ const identity = await progress.execute(
4583
+ "Validating AWS credentials",
4584
+ async () => validateAWSCredentials()
4585
+ );
4586
+ progress.info(`Connected to AWS account: ${pc11.cyan(identity.accountId)}`);
4587
+ let region = options.region;
4588
+ if (!region) {
4589
+ const defaultRegion = await getAWSRegion();
4590
+ region = defaultRegion;
4591
+ }
4592
+ const metadata = await loadConnectionMetadata(identity.accountId, region);
4593
+ if (!metadata) {
4594
+ clack11.log.error(
4595
+ `No Wraps connection found for account ${pc11.cyan(identity.accountId)} in region ${pc11.cyan(region)}`
4596
+ );
4597
+ clack11.log.info(
4598
+ `Use ${pc11.cyan("wraps init")} to create new infrastructure or ${pc11.cyan("wraps connect")} to connect existing.`
4599
+ );
4600
+ process.exit(1);
4601
+ }
4602
+ progress.info(`Found existing connection created: ${metadata.timestamp}`);
4603
+ console.log(`
4604
+ ${pc11.bold("Current Configuration:")}
4605
+ `);
4606
+ if (metadata.preset) {
4607
+ console.log(` Preset: ${pc11.cyan(metadata.preset)}`);
4608
+ } else {
4609
+ console.log(` Preset: ${pc11.cyan("custom")}`);
4610
+ }
4611
+ const config = metadata.emailConfig;
4612
+ if (config.domain) {
4613
+ console.log(` Sending Domain: ${pc11.cyan(config.domain)}`);
4614
+ }
4615
+ if (config.tracking?.enabled) {
4616
+ console.log(` ${pc11.green("\u2713")} Open & Click Tracking`);
4426
4617
  if (config.tracking.customRedirectDomain) {
4427
4618
  console.log(
4428
- ` ${pc10.dim("\u2514\u2500")} Custom domain: ${pc10.cyan(config.tracking.customRedirectDomain)}`
4619
+ ` ${pc11.dim("\u2514\u2500")} Custom domain: ${pc11.cyan(config.tracking.customRedirectDomain)}`
4429
4620
  );
4430
4621
  }
4431
4622
  }
4432
4623
  if (config.suppressionList?.enabled) {
4433
- console.log(` ${pc10.green("\u2713")} Bounce/Complaint Suppression`);
4624
+ console.log(` ${pc11.green("\u2713")} Bounce/Complaint Suppression`);
4434
4625
  }
4435
4626
  if (config.eventTracking?.enabled) {
4436
- console.log(` ${pc10.green("\u2713")} Event Tracking (EventBridge)`);
4627
+ console.log(` ${pc11.green("\u2713")} Event Tracking (EventBridge)`);
4437
4628
  if (config.eventTracking.dynamoDBHistory) {
4438
4629
  console.log(
4439
- ` ${pc10.dim("\u2514\u2500")} Email History: ${pc10.cyan(config.eventTracking.archiveRetention || "90days")}`
4630
+ ` ${pc11.dim("\u2514\u2500")} Email History: ${pc11.cyan(config.eventTracking.archiveRetention || "90days")}`
4440
4631
  );
4441
4632
  }
4442
4633
  }
4443
4634
  if (config.dedicatedIp) {
4444
- console.log(` ${pc10.green("\u2713")} Dedicated IP Address`);
4635
+ console.log(` ${pc11.green("\u2713")} Dedicated IP Address`);
4445
4636
  }
4446
4637
  const currentCostData = calculateCosts(config, 5e4);
4447
4638
  console.log(
4448
4639
  `
4449
- Estimated Cost: ${pc10.cyan(`~${formatCost(currentCostData.total.monthly)}/mo`)}`
4640
+ Estimated Cost: ${pc11.cyan(`~${formatCost(currentCostData.total.monthly)}/mo`)}`
4450
4641
  );
4451
4642
  console.log("");
4452
- const upgradeAction = await clack10.select({
4643
+ const upgradeAction = await clack11.select({
4453
4644
  message: "What would you like to do?",
4454
4645
  options: [
4455
4646
  {
@@ -4484,8 +4675,8 @@ ${pc10.bold("Current Configuration:")}
4484
4675
  }
4485
4676
  ]
4486
4677
  });
4487
- if (clack10.isCancel(upgradeAction)) {
4488
- clack10.cancel("Upgrade cancelled.");
4678
+ if (clack11.isCancel(upgradeAction)) {
4679
+ clack11.cancel("Upgrade cancelled.");
4489
4680
  process.exit(0);
4490
4681
  }
4491
4682
  let updatedConfig = { ...config };
@@ -4503,15 +4694,15 @@ ${pc10.bold("Current Configuration:")}
4503
4694
  disabled: currentPresetIdx >= 0 && idx <= currentPresetIdx ? "Current or lower tier" : void 0
4504
4695
  })).filter((p) => !p.disabled);
4505
4696
  if (availablePresets.length === 0) {
4506
- clack10.log.warn("Already on highest preset (Enterprise)");
4697
+ clack11.log.warn("Already on highest preset (Enterprise)");
4507
4698
  process.exit(0);
4508
4699
  }
4509
- const selectedPreset = await clack10.select({
4700
+ const selectedPreset = await clack11.select({
4510
4701
  message: "Select new preset:",
4511
4702
  options: availablePresets
4512
4703
  });
4513
- if (clack10.isCancel(selectedPreset)) {
4514
- clack10.cancel("Upgrade cancelled.");
4704
+ if (clack11.isCancel(selectedPreset)) {
4705
+ clack11.cancel("Upgrade cancelled.");
4515
4706
  process.exit(0);
4516
4707
  }
4517
4708
  const presetConfig = getPreset(selectedPreset);
@@ -4525,11 +4716,11 @@ ${pc10.bold("Current Configuration:")}
4525
4716
  }
4526
4717
  case "tracking-domain": {
4527
4718
  if (!config.domain) {
4528
- clack10.log.error(
4719
+ clack11.log.error(
4529
4720
  "No sending domain configured. You must configure a sending domain before adding a custom tracking domain."
4530
4721
  );
4531
- clack10.log.info(
4532
- `Use ${pc10.cyan("wraps init")} to set up a sending domain first.`
4722
+ clack11.log.info(
4723
+ `Use ${pc11.cyan("wraps init")} to set up a sending domain first.`
4533
4724
  );
4534
4725
  process.exit(1);
4535
4726
  }
@@ -4540,21 +4731,21 @@ ${pc10.bold("Current Configuration:")}
4540
4731
  );
4541
4732
  const sendingDomain = domains.find((d) => d.domain === config.domain);
4542
4733
  if (!sendingDomain?.verified) {
4543
- clack10.log.error(
4544
- `Sending domain ${pc10.cyan(config.domain)} is not verified.`
4734
+ clack11.log.error(
4735
+ `Sending domain ${pc11.cyan(config.domain)} is not verified.`
4545
4736
  );
4546
- clack10.log.info(
4737
+ clack11.log.info(
4547
4738
  "You must verify your sending domain before adding a custom tracking domain."
4548
4739
  );
4549
- clack10.log.info(
4550
- `Use ${pc10.cyan("wraps verify")} to check DNS records and complete verification.`
4740
+ clack11.log.info(
4741
+ `Use ${pc11.cyan("wraps verify")} to check DNS records and complete verification.`
4551
4742
  );
4552
4743
  process.exit(1);
4553
4744
  }
4554
4745
  progress.info(
4555
- `Sending domain ${pc10.cyan(config.domain)} is verified ${pc10.green("\u2713")}`
4746
+ `Sending domain ${pc11.cyan(config.domain)} is verified ${pc11.green("\u2713")}`
4556
4747
  );
4557
- const trackingDomain = await clack10.text({
4748
+ const trackingDomain = await clack11.text({
4558
4749
  message: "Custom tracking redirect domain:",
4559
4750
  placeholder: "track.yourdomain.com",
4560
4751
  initialValue: config.tracking?.customRedirectDomain || "",
@@ -4564,8 +4755,8 @@ ${pc10.bold("Current Configuration:")}
4564
4755
  }
4565
4756
  }
4566
4757
  });
4567
- if (clack10.isCancel(trackingDomain)) {
4568
- clack10.cancel("Upgrade cancelled.");
4758
+ if (clack11.isCancel(trackingDomain)) {
4759
+ clack11.cancel("Upgrade cancelled.");
4569
4760
  process.exit(0);
4570
4761
  }
4571
4762
  updatedConfig = {
@@ -4580,7 +4771,7 @@ ${pc10.bold("Current Configuration:")}
4580
4771
  break;
4581
4772
  }
4582
4773
  case "retention": {
4583
- const retention = await clack10.select({
4774
+ const retention = await clack11.select({
4584
4775
  message: "Email history retention period:",
4585
4776
  options: [
4586
4777
  { value: "7days", label: "7 days", hint: "Minimal storage cost" },
@@ -4599,8 +4790,8 @@ ${pc10.bold("Current Configuration:")}
4599
4790
  ],
4600
4791
  initialValue: config.eventTracking?.archiveRetention || "90days"
4601
4792
  });
4602
- if (clack10.isCancel(retention)) {
4603
- clack10.cancel("Upgrade cancelled.");
4793
+ if (clack11.isCancel(retention)) {
4794
+ clack11.cancel("Upgrade cancelled.");
4604
4795
  process.exit(0);
4605
4796
  }
4606
4797
  updatedConfig = {
@@ -4616,7 +4807,7 @@ ${pc10.bold("Current Configuration:")}
4616
4807
  break;
4617
4808
  }
4618
4809
  case "events": {
4619
- const selectedEvents = await clack10.multiselect({
4810
+ const selectedEvents = await clack11.multiselect({
4620
4811
  message: "Select SES event types to track:",
4621
4812
  options: [
4622
4813
  { value: "SEND", label: "Send", hint: "Email sent to SES" },
@@ -4660,8 +4851,8 @@ ${pc10.bold("Current Configuration:")}
4660
4851
  ],
4661
4852
  required: true
4662
4853
  });
4663
- if (clack10.isCancel(selectedEvents)) {
4664
- clack10.cancel("Upgrade cancelled.");
4854
+ if (clack11.isCancel(selectedEvents)) {
4855
+ clack11.cancel("Upgrade cancelled.");
4665
4856
  process.exit(0);
4666
4857
  }
4667
4858
  updatedConfig = {
@@ -4676,16 +4867,16 @@ ${pc10.bold("Current Configuration:")}
4676
4867
  break;
4677
4868
  }
4678
4869
  case "dedicated-ip": {
4679
- const confirmed = await clack10.confirm({
4870
+ const confirmed = await clack11.confirm({
4680
4871
  message: "Enable dedicated IP? (Requires 100k+ emails/day, adds ~$50-100/mo)",
4681
4872
  initialValue: false
4682
4873
  });
4683
- if (clack10.isCancel(confirmed)) {
4684
- clack10.cancel("Upgrade cancelled.");
4874
+ if (clack11.isCancel(confirmed)) {
4875
+ clack11.cancel("Upgrade cancelled.");
4685
4876
  process.exit(0);
4686
4877
  }
4687
4878
  if (!confirmed) {
4688
- clack10.log.info("Dedicated IP not enabled.");
4879
+ clack11.log.info("Dedicated IP not enabled.");
4689
4880
  process.exit(0);
4690
4881
  }
4691
4882
  updatedConfig = {
@@ -4709,28 +4900,28 @@ ${pc10.bold("Current Configuration:")}
4709
4900
  const newCostData = calculateCosts(updatedConfig, 5e4);
4710
4901
  const costDiff = newCostData.total.monthly - currentCostData.total.monthly;
4711
4902
  console.log(`
4712
- ${pc10.bold("Cost Impact:")}`);
4903
+ ${pc11.bold("Cost Impact:")}`);
4713
4904
  console.log(
4714
- ` Current: ${pc10.cyan(`${formatCost(currentCostData.total.monthly)}/mo`)}`
4905
+ ` Current: ${pc11.cyan(`${formatCost(currentCostData.total.monthly)}/mo`)}`
4715
4906
  );
4716
4907
  console.log(
4717
- ` New: ${pc10.cyan(`${formatCost(newCostData.total.monthly)}/mo`)}`
4908
+ ` New: ${pc11.cyan(`${formatCost(newCostData.total.monthly)}/mo`)}`
4718
4909
  );
4719
4910
  if (costDiff > 0) {
4720
- console.log(` Change: ${pc10.yellow(`+${formatCost(costDiff)}/mo`)}`);
4911
+ console.log(` Change: ${pc11.yellow(`+${formatCost(costDiff)}/mo`)}`);
4721
4912
  } else if (costDiff < 0) {
4722
4913
  console.log(
4723
- ` Change: ${pc10.green(`${formatCost(Math.abs(costDiff))}/mo`)}`
4914
+ ` Change: ${pc11.green(`${formatCost(Math.abs(costDiff))}/mo`)}`
4724
4915
  );
4725
4916
  }
4726
4917
  console.log("");
4727
4918
  if (!options.yes) {
4728
- const confirmed = await clack10.confirm({
4919
+ const confirmed = await clack11.confirm({
4729
4920
  message: "Proceed with upgrade?",
4730
4921
  initialValue: true
4731
4922
  });
4732
- if (clack10.isCancel(confirmed) || !confirmed) {
4733
- clack10.cancel("Upgrade cancelled.");
4923
+ if (clack11.isCancel(confirmed) || !confirmed) {
4924
+ clack11.cancel("Upgrade cancelled.");
4734
4925
  process.exit(0);
4735
4926
  }
4736
4927
  }
@@ -4752,7 +4943,7 @@ ${pc10.bold("Cost Impact:")}`);
4752
4943
  "Updating Wraps infrastructure (this may take 2-3 minutes)",
4753
4944
  async () => {
4754
4945
  await ensurePulumiWorkDir();
4755
- const stack = await pulumi11.automation.LocalWorkspace.createOrSelectStack(
4946
+ const stack = await pulumi12.automation.LocalWorkspace.createOrSelectStack(
4756
4947
  {
4757
4948
  stackName: metadata.pulumiStackName || `wraps-${identity.accountId}-${region}`,
4758
4949
  projectName: "wraps-email",
@@ -4798,12 +4989,12 @@ ${pc10.bold("Cost Impact:")}`);
4798
4989
  }
4799
4990
  );
4800
4991
  } catch (error) {
4801
- clack10.log.error("Infrastructure upgrade failed");
4992
+ clack11.log.error("Infrastructure upgrade failed");
4802
4993
  if (error.message?.includes("stack is currently locked")) {
4803
- clack10.log.warn("\nThe Pulumi stack is locked from a previous run.");
4804
- clack10.log.info("To fix this, run:");
4805
- clack10.log.info(` ${pc10.cyan("rm -rf ~/.wraps/pulumi/.pulumi/locks")}`);
4806
- clack10.log.info("\nThen try running wraps upgrade again.");
4994
+ clack11.log.warn("\nThe Pulumi stack is locked from a previous run.");
4995
+ clack11.log.info("To fix this, run:");
4996
+ clack11.log.info(` ${pc11.cyan("rm -rf ~/.wraps/pulumi/.pulumi/locks")}`);
4997
+ clack11.log.info("\nThen try running wraps upgrade again.");
4807
4998
  }
4808
4999
  throw new Error(`Pulumi upgrade failed: ${error.message}`);
4809
5000
  }
@@ -4828,16 +5019,16 @@ ${pc10.bold("Cost Impact:")}`);
4828
5019
  customTrackingDomain: outputs.customTrackingDomain
4829
5020
  });
4830
5021
  console.log(`
4831
- ${pc10.green("\u2713")} ${pc10.bold("Upgrade complete!")}
5022
+ ${pc11.green("\u2713")} ${pc11.bold("Upgrade complete!")}
4832
5023
  `);
4833
5024
  if (upgradeAction === "preset" && newPreset) {
4834
5025
  console.log(
4835
- `Upgraded to ${pc10.cyan(newPreset)} preset (${pc10.green(formatCost(newCostData.total.monthly) + "/mo")})
5026
+ `Upgraded to ${pc11.cyan(newPreset)} preset (${pc11.green(formatCost(newCostData.total.monthly) + "/mo")})
4836
5027
  `
4837
5028
  );
4838
5029
  } else {
4839
5030
  console.log(
4840
- `Updated configuration (${pc10.green(formatCost(newCostData.total.monthly) + "/mo")})
5031
+ `Updated configuration (${pc11.green(formatCost(newCostData.total.monthly) + "/mo")})
4841
5032
  `
4842
5033
  );
4843
5034
  }
@@ -4848,10 +5039,10 @@ init_esm_shims();
4848
5039
  init_aws();
4849
5040
  import { Resolver } from "dns/promises";
4850
5041
  import { GetEmailIdentityCommand as GetEmailIdentityCommand3, SESv2Client as SESv2Client3 } from "@aws-sdk/client-sesv2";
4851
- import * as clack11 from "@clack/prompts";
4852
- import pc11 from "picocolors";
5042
+ import * as clack12 from "@clack/prompts";
5043
+ import pc12 from "picocolors";
4853
5044
  async function verify(options) {
4854
- clack11.intro(pc11.bold(`Verifying ${options.domain}`));
5045
+ clack12.intro(pc12.bold(`Verifying ${options.domain}`));
4855
5046
  const progress = new DeploymentProgress();
4856
5047
  const region = await getAWSRegion();
4857
5048
  const sesClient = new SESv2Client3({ region });
@@ -4870,10 +5061,10 @@ async function verify(options) {
4870
5061
  dkimTokens = identity.DkimAttributes?.Tokens || [];
4871
5062
  } catch (_error) {
4872
5063
  progress.stop();
4873
- clack11.log.error(`Domain ${options.domain} not found in SES`);
5064
+ clack12.log.error(`Domain ${options.domain} not found in SES`);
4874
5065
  console.log(
4875
5066
  `
4876
- Run ${pc11.cyan(`wraps init --domain ${options.domain}`)} to add this domain.
5067
+ Run ${pc12.cyan(`wraps init --domain ${options.domain}`)} to add this domain.
4877
5068
  `
4878
5069
  );
4879
5070
  process.exit(1);
@@ -4936,11 +5127,11 @@ Run ${pc11.cyan(`wraps init --domain ${options.domain}`)} to add this domain.
4936
5127
  progress.stop();
4937
5128
  const verificationStatus = identity.VerifiedForSendingStatus ? "verified" : "pending";
4938
5129
  const dkimStatus = identity.DkimAttributes?.Status || "PENDING";
4939
- clack11.note(
5130
+ clack12.note(
4940
5131
  [
4941
- `${pc11.bold("Domain:")} ${options.domain}`,
4942
- `${pc11.bold("Verification Status:")} ${verificationStatus === "verified" ? pc11.green("\u2713 Verified") : pc11.yellow("\u23F1 Pending")}`,
4943
- `${pc11.bold("DKIM Status:")} ${dkimStatus === "SUCCESS" ? pc11.green("\u2713 Success") : pc11.yellow(`\u23F1 ${dkimStatus}`)}`
5132
+ `${pc12.bold("Domain:")} ${options.domain}`,
5133
+ `${pc12.bold("Verification Status:")} ${verificationStatus === "verified" ? pc12.green("\u2713 Verified") : pc12.yellow("\u23F1 Pending")}`,
5134
+ `${pc12.bold("DKIM Status:")} ${dkimStatus === "SUCCESS" ? pc12.green("\u2713 Success") : pc12.yellow(`\u23F1 ${dkimStatus}`)}`
4944
5135
  ].join("\n"),
4945
5136
  "SES Status"
4946
5137
  );
@@ -4949,38 +5140,38 @@ Run ${pc11.cyan(`wraps init --domain ${options.domain}`)} to add this domain.
4949
5140
  let statusColor;
4950
5141
  if (record.status === "verified") {
4951
5142
  statusIcon = "\u2713";
4952
- statusColor = pc11.green;
5143
+ statusColor = pc12.green;
4953
5144
  } else if (record.status === "incorrect") {
4954
5145
  statusIcon = "\u2717";
4955
- statusColor = pc11.red;
5146
+ statusColor = pc12.red;
4956
5147
  } else {
4957
5148
  statusIcon = "\u2717";
4958
- statusColor = pc11.red;
5149
+ statusColor = pc12.red;
4959
5150
  }
4960
5151
  const recordInfo = record.records ? ` \u2192 ${record.records.join(", ")}` : "";
4961
5152
  return ` ${statusColor(statusIcon)} ${record.name} (${record.type}) ${statusColor(
4962
5153
  record.status
4963
5154
  )}${recordInfo}`;
4964
5155
  });
4965
- clack11.note(dnsLines.join("\n"), "DNS Records");
5156
+ clack12.note(dnsLines.join("\n"), "DNS Records");
4966
5157
  const allVerified = dnsResults.every((r) => r.status === "verified");
4967
5158
  const someIncorrect = dnsResults.some((r) => r.status === "incorrect");
4968
5159
  if (verificationStatus === "verified" && allVerified) {
4969
- clack11.outro(
4970
- pc11.green("\u2713 Domain is fully verified and ready to send emails!")
5160
+ clack12.outro(
5161
+ pc12.green("\u2713 Domain is fully verified and ready to send emails!")
4971
5162
  );
4972
5163
  } else if (someIncorrect) {
4973
- clack11.outro(
4974
- pc11.red("\u2717 Some DNS records are incorrect. Please update them.")
5164
+ clack12.outro(
5165
+ pc12.red("\u2717 Some DNS records are incorrect. Please update them.")
4975
5166
  );
4976
5167
  console.log(
4977
5168
  `
4978
- Run ${pc11.cyan("wraps status")} to see the correct DNS records.
5169
+ Run ${pc12.cyan("wraps status")} to see the correct DNS records.
4979
5170
  `
4980
5171
  );
4981
5172
  } else {
4982
- clack11.outro(
4983
- pc11.yellow("\u23F1 Waiting for DNS propagation and SES verification")
5173
+ clack12.outro(
5174
+ pc12.yellow("\u23F1 Waiting for DNS propagation and SES verification")
4984
5175
  );
4985
5176
  console.log("\nDNS records can take up to 48 hours to propagate.");
4986
5177
  console.log(
@@ -5015,44 +5206,61 @@ function printCompletionScript() {
5015
5206
 
5016
5207
  // src/cli.ts
5017
5208
  init_errors();
5209
+ var __filename2 = fileURLToPath4(import.meta.url);
5210
+ var __dirname3 = dirname2(__filename2);
5211
+ var packageJson = JSON.parse(
5212
+ readFileSync(join4(__dirname3, "../package.json"), "utf-8")
5213
+ );
5214
+ var VERSION = packageJson.version;
5018
5215
  setupTabCompletion();
5216
+ function showVersion() {
5217
+ console.log(`wraps v${VERSION}`);
5218
+ process.exit(0);
5219
+ }
5019
5220
  function showHelp() {
5020
- clack12.intro(pc12.bold("WRAPS CLI"));
5221
+ clack13.intro(pc13.bold(`WRAPS CLI v${VERSION}`));
5021
5222
  console.log("Deploy email infrastructure to your AWS account\n");
5022
5223
  console.log("Usage: wraps <command> [options]\n");
5023
5224
  console.log("Commands:");
5024
- console.log(` ${pc12.cyan("init")} Deploy new email infrastructure`);
5225
+ console.log(` ${pc13.cyan("init")} Deploy new email infrastructure`);
5226
+ console.log(
5227
+ ` ${pc13.cyan("connect")} Connect to existing AWS SES infrastructure`
5228
+ );
5025
5229
  console.log(
5026
- ` ${pc12.cyan("connect")} Connect to existing AWS SES infrastructure`
5230
+ ` ${pc13.cyan("console")} Start local web dashboard for monitoring`
5027
5231
  );
5028
5232
  console.log(
5029
- ` ${pc12.cyan("console")} Start local web dashboard for monitoring`
5233
+ ` ${pc13.cyan("update")} Update infrastructure with latest CLI changes`
5030
5234
  );
5031
5235
  console.log(
5032
- ` ${pc12.cyan("upgrade")} Add features to existing connection`
5236
+ ` ${pc13.cyan("upgrade")} Add features to existing connection`
5033
5237
  );
5034
- console.log(` ${pc12.cyan("status")} Show current infrastructure status`);
5238
+ console.log(` ${pc13.cyan("status")} Show current infrastructure status`);
5035
5239
  console.log(
5036
- ` ${pc12.cyan("verify")} Verify domain DNS records and SES status`
5240
+ ` ${pc13.cyan("verify")} Verify domain DNS records and SES status`
5037
5241
  );
5038
- console.log(` ${pc12.cyan("restore")} Restore original AWS configuration`);
5039
- console.log(` ${pc12.cyan("destroy")} Remove all deployed infrastructure`);
5040
- console.log(` ${pc12.cyan("completion")} Generate shell completion script
5242
+ console.log(` ${pc13.cyan("restore")} Restore original AWS configuration`);
5243
+ console.log(` ${pc13.cyan("destroy")} Remove all deployed infrastructure`);
5244
+ console.log(` ${pc13.cyan("completion")} Generate shell completion script
5041
5245
  `);
5042
5246
  console.log("Options:");
5043
5247
  console.log(
5044
- ` ${pc12.dim("--provider")} Hosting provider (vercel, aws, railway, other)`
5248
+ ` ${pc13.dim("--provider")} Hosting provider (vercel, aws, railway, other)`
5045
5249
  );
5046
- console.log(` ${pc12.dim("--region")} AWS region`);
5047
- console.log(` ${pc12.dim("--domain")} Domain to verify`);
5048
- console.log(` ${pc12.dim("--account")} AWS account ID or alias
5250
+ console.log(` ${pc13.dim("--region")} AWS region`);
5251
+ console.log(` ${pc13.dim("--domain")} Domain to verify`);
5252
+ console.log(` ${pc13.dim("--account")} AWS account ID or alias`);
5253
+ console.log(` ${pc13.dim("--version, -v")} Show version number
5049
5254
  `);
5050
5255
  console.log(
5051
- `Run ${pc12.cyan("wraps <command> --help")} for more information on a command.
5256
+ `Run ${pc13.cyan("wraps <command> --help")} for more information on a command.
5052
5257
  `
5053
5258
  );
5054
5259
  process.exit(0);
5055
5260
  }
5261
+ if (process.argv.includes("--version") || process.argv.includes("-v")) {
5262
+ showVersion();
5263
+ }
5056
5264
  if (process.argv.includes("--help") || process.argv.includes("-h")) {
5057
5265
  showHelp();
5058
5266
  }
@@ -5122,10 +5330,10 @@ async function run() {
5122
5330
  break;
5123
5331
  case "verify":
5124
5332
  if (!flags.domain) {
5125
- clack12.log.error("--domain flag is required");
5333
+ clack13.log.error("--domain flag is required");
5126
5334
  console.log(
5127
5335
  `
5128
- Usage: ${pc12.cyan("wraps verify --domain yourapp.com")}
5336
+ Usage: ${pc13.cyan("wraps verify --domain yourapp.com")}
5129
5337
  `
5130
5338
  );
5131
5339
  process.exit(1);
@@ -5147,6 +5355,12 @@ Usage: ${pc12.cyan("wraps verify --domain yourapp.com")}
5147
5355
  noOpen: flags.noOpen
5148
5356
  });
5149
5357
  break;
5358
+ case "update":
5359
+ await update({
5360
+ region: flags.region,
5361
+ yes: flags.yes
5362
+ });
5363
+ break;
5150
5364
  case "upgrade":
5151
5365
  await upgrade({
5152
5366
  region: flags.region,
@@ -5168,10 +5382,10 @@ Usage: ${pc12.cyan("wraps verify --domain yourapp.com")}
5168
5382
  printCompletionScript();
5169
5383
  break;
5170
5384
  default:
5171
- clack12.log.error(`Unknown command: ${command}`);
5385
+ clack13.log.error(`Unknown command: ${command}`);
5172
5386
  console.log(
5173
5387
  `
5174
- Run ${pc12.cyan("wraps --help")} for available commands.
5388
+ Run ${pc13.cyan("wraps --help")} for available commands.
5175
5389
  `
5176
5390
  );
5177
5391
  process.exit(1);