@wraps.dev/cli 2.22.0 → 2.22.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.
Binary file
package/dist/cli.js CHANGED
@@ -24129,6 +24129,11 @@ function truncate(str, len) {
24129
24129
  if (!str) return pc30.dim("\u2014");
24130
24130
  return str.length > len ? `${str.slice(0, len - 1)}\u2026` : str;
24131
24131
  }
24132
+ var ANSI_PATTERN = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
24133
+ function padVisible(str, len) {
24134
+ const visibleLength = str.replace(ANSI_PATTERN, "").length;
24135
+ return visibleLength >= len ? str : str + " ".repeat(len - visibleLength);
24136
+ }
24132
24137
  async function emailLogsList(options) {
24133
24138
  const token = await resolveTokenAsync({ token: options.token });
24134
24139
  if (!token) {
@@ -24177,9 +24182,9 @@ async function emailLogsList(options) {
24177
24182
  const header = pc30.bold("Time".padEnd(COL.time)) + " " + pc30.bold("Status".padEnd(COL.status)) + " " + pc30.bold("To".padEnd(COL.to)) + " " + pc30.bold("Subject".padEnd(COL.subject)) + " " + pc30.bold("Message ID");
24178
24183
  const rows = data.logs.map((log59) => {
24179
24184
  const time = relativeTime(log59.createdAt).padEnd(COL.time);
24180
- const status2 = colorStatus(log59.status.padEnd(COL.status));
24181
- const to = truncate(log59.recipient, COL.to).padEnd(COL.to);
24182
- const subject = truncate(log59.subject, COL.subject).padEnd(COL.subject);
24185
+ const status2 = padVisible(colorStatus(log59.status), COL.status);
24186
+ const to = padVisible(truncate(log59.recipient, COL.to), COL.to);
24187
+ const subject = padVisible(truncate(log59.subject, COL.subject), COL.subject);
24183
24188
  const msgId = truncate(log59.messageId, COL.msgId);
24184
24189
  return `${time} ${status2} ${to} ${subject} ${msgId}`;
24185
24190
  });
@@ -32055,6 +32060,44 @@ import { confirm as confirm19, intro as intro36, isCancel as isCancel27, log as
32055
32060
  import * as pulumi24 from "@pulumi/pulumi";
32056
32061
  import pc44 from "picocolors";
32057
32062
  init_events();
32063
+
32064
+ // src/utils/selfhost/api-url.ts
32065
+ init_esm_shims();
32066
+ init_metadata();
32067
+ var SELFHOST_API_FUNCTION_NAME = "wraps-selfhost-api";
32068
+ async function resolveSelfhostApiUrl(region) {
32069
+ try {
32070
+ const { LambdaClient: LambdaClient3, GetFunctionUrlConfigCommand } = await import("@aws-sdk/client-lambda");
32071
+ const lambda5 = new LambdaClient3({ region });
32072
+ const result = await lambda5.send(
32073
+ new GetFunctionUrlConfigCommand({
32074
+ FunctionName: SELFHOST_API_FUNCTION_NAME
32075
+ })
32076
+ );
32077
+ return result.FunctionUrl ?? null;
32078
+ } catch {
32079
+ return null;
32080
+ }
32081
+ }
32082
+ async function reconcileSelfhostApiUrl(metadata, region) {
32083
+ const selfhost = metadata.services.selfhost;
32084
+ if (!selfhost) {
32085
+ return null;
32086
+ }
32087
+ if (selfhost.apiUrl) {
32088
+ return selfhost.apiUrl;
32089
+ }
32090
+ const recovered = await resolveSelfhostApiUrl(region);
32091
+ if (!recovered) {
32092
+ return null;
32093
+ }
32094
+ selfhost.apiUrl = recovered;
32095
+ metadata.timestamp = (/* @__PURE__ */ new Date()).toISOString();
32096
+ await saveConnectionMetadata(metadata);
32097
+ return recovered;
32098
+ }
32099
+
32100
+ // src/commands/platform/connect.ts
32058
32101
  init_aws();
32059
32102
  init_config();
32060
32103
  init_errors();
@@ -32447,8 +32490,7 @@ async function resolveOrganization() {
32447
32490
  return orgs.find((o) => o.id === selected) || null;
32448
32491
  }
32449
32492
  async function registerConnection(params) {
32450
- const baseURL = getApiBaseUrl();
32451
- const response = await fetch(`${baseURL}/v1/connections`, {
32493
+ const response = await fetch(`${params.baseURL}/v1/connections`, {
32452
32494
  method: "POST",
32453
32495
  headers: {
32454
32496
  "Content-Type": "application/json",
@@ -32472,8 +32514,13 @@ async function registerConnection(params) {
32472
32514
  }
32473
32515
  async function authenticatedConnect(token, options) {
32474
32516
  const startTime = Date.now();
32517
+ const selfhosted = options.selfhosted === true;
32475
32518
  if (!isJsonMode()) {
32476
- intro36(pc44.bold("Connect to Wraps Platform"));
32519
+ intro36(
32520
+ pc44.bold(
32521
+ selfhosted ? "Connect to Self-Hosted Wraps" : "Connect to Wraps Platform"
32522
+ )
32523
+ );
32477
32524
  }
32478
32525
  const progress = new DeploymentProgress();
32479
32526
  try {
@@ -32481,12 +32528,30 @@ async function authenticatedConnect(token, options) {
32481
32528
  options,
32482
32529
  progress
32483
32530
  );
32531
+ const selfhostService = metadata.services.selfhost;
32532
+ if (selfhosted && selfhostService) {
32533
+ await reconcileSelfhostApiUrl(metadata, region);
32534
+ }
32535
+ if (selfhosted && !selfhostService?.apiUrl) {
32536
+ progress.stop();
32537
+ log38.error(
32538
+ `No reachable self-hosted deployment found for account ${pc44.cyan(identity.accountId)} in region ${pc44.cyan(region)}`
32539
+ );
32540
+ console.log(
32541
+ `
32542
+ Run ${pc44.cyan("wraps selfhost deploy")} to finish deploying the self-hosted control plane first.
32543
+ `
32544
+ );
32545
+ process.exit(1);
32546
+ }
32547
+ const apiBaseUrl = selfhosted && selfhostService ? selfhostService.apiUrl : getApiBaseUrl();
32548
+ const dashboardUrl = selfhosted && selfhostService ? selfhostService.config.appUrl : getAppBaseUrl();
32484
32549
  const hasEmail = !!metadata.services.email?.config;
32485
32550
  const org = await resolveOrganization();
32486
32551
  if (!org) {
32487
32552
  progress.stop();
32488
32553
  log38.error(
32489
- "No organizations found. Sign in at https://app.wraps.dev to create one."
32554
+ `No organizations found. Sign in at ${dashboardUrl} to create one.`
32490
32555
  );
32491
32556
  process.exit(1);
32492
32557
  }
@@ -32499,7 +32564,7 @@ async function authenticatedConnect(token, options) {
32499
32564
  if (!isJsonMode()) {
32500
32565
  progress.stop();
32501
32566
  log38.warn(
32502
- "Event tracking must be enabled to connect to the Wraps Platform."
32567
+ selfhosted ? "Event tracking must be enabled to connect to your self-hosted instance." : "Event tracking must be enabled to connect to the Wraps Platform."
32503
32568
  );
32504
32569
  }
32505
32570
  const enableTracking = options.yes || await confirm19({
@@ -32537,8 +32602,9 @@ async function authenticatedConnect(token, options) {
32537
32602
  features.sms = metadata.services.sms.config;
32538
32603
  }
32539
32604
  const result = await progress.execute(
32540
- "Registering connection with Wraps Platform",
32605
+ selfhosted ? "Registering connection with your self-hosted instance" : "Registering connection with Wraps Platform",
32541
32606
  async () => registerConnection({
32607
+ baseURL: apiBaseUrl,
32542
32608
  token,
32543
32609
  orgId: org.id,
32544
32610
  accountId: identity.accountId,
@@ -32595,17 +32661,22 @@ You can try the manual flow: ${pc44.cyan("wraps auth logout")} then ${pc44.cyan(
32595
32661
  region,
32596
32662
  organizationId: org.id,
32597
32663
  connectionId: result.connectionId,
32598
- webhookConnected: true
32664
+ webhookConnected: true,
32665
+ selfhosted
32599
32666
  });
32600
32667
  } else {
32601
- outro24(pc44.green("Platform connection complete!"));
32668
+ outro24(
32669
+ pc44.green(
32670
+ selfhosted ? "Self-hosted connection complete!" : "Platform connection complete!"
32671
+ )
32672
+ );
32602
32673
  console.log();
32603
32674
  console.log(
32604
32675
  pc44.dim(
32605
32676
  "Events from your AWS infrastructure will stream to the dashboard."
32606
32677
  )
32607
32678
  );
32608
- console.log(` Dashboard: ${pc44.cyan("https://app.wraps.dev")}`);
32679
+ console.log(` Dashboard: ${pc44.cyan(dashboardUrl)}`);
32609
32680
  console.log();
32610
32681
  }
32611
32682
  const duration = Date.now() - startTime;
@@ -32635,6 +32706,22 @@ async function connect3(options) {
32635
32706
  await authenticatedConnect(token, options);
32636
32707
  return;
32637
32708
  }
32709
+ if (options.selfhosted) {
32710
+ if (isJsonMode()) {
32711
+ jsonError("platform.connect", {
32712
+ code: "NOT_AUTHENTICATED",
32713
+ message: "Not signed in to the self-hosted instance.",
32714
+ suggestion: "Run `wraps selfhost login` first."
32715
+ });
32716
+ } else {
32717
+ intro36(pc44.bold("Connect to Self-Hosted Wraps"));
32718
+ log38.error("You need to sign in to your self-hosted instance first.");
32719
+ console.log(`
32720
+ Run ${pc44.cyan("wraps selfhost login")} first.
32721
+ `);
32722
+ }
32723
+ process.exit(1);
32724
+ }
32638
32725
  const startTime = Date.now();
32639
32726
  intro36(pc44.bold("Connect to Wraps Platform"));
32640
32727
  const progress = new DeploymentProgress();
@@ -33913,12 +34000,13 @@ async function selfhostDeploy(options) {
33913
34000
  timestamp: deployedAt,
33914
34001
  services: {}
33915
34002
  };
34003
+ const priorApiUrl = savedMetadata.services.selfhost?.apiUrl ?? "";
33916
34004
  savedMetadata.services.selfhost = {
33917
34005
  deployedAt,
33918
34006
  pulumiStackName: stackName,
33919
34007
  config: selfhostConfig,
33920
- apiUrl: ""
33921
- // Updated with real URL after Pulumi succeeds
34008
+ apiUrl: priorApiUrl
34009
+ // Refreshed from Pulumi outputs after deploy succeeds
33922
34010
  };
33923
34011
  savedMetadata.timestamp = deployedAt;
33924
34012
  await saveConnectionMetadata(savedMetadata);
@@ -34084,12 +34172,12 @@ async function selfhostDeploy(options) {
34084
34172
  // src/commands/selfhost/env.ts
34085
34173
  init_esm_shims();
34086
34174
  init_events();
34175
+ import * as clack45 from "@clack/prompts";
34176
+ import pc48 from "picocolors";
34087
34177
  init_aws();
34088
34178
  init_json_output();
34089
34179
  init_metadata();
34090
34180
  init_region_resolver();
34091
- import * as clack45 from "@clack/prompts";
34092
- import pc48 from "picocolors";
34093
34181
  async function selfhostEnv(options) {
34094
34182
  const startTime = Date.now();
34095
34183
  if (!isJsonMode()) {
@@ -34113,7 +34201,8 @@ Run ${pc48.cyan("wraps selfhost deploy")} to deploy the self-hosted control plan
34113
34201
  process.exit(1);
34114
34202
  return;
34115
34203
  }
34116
- const { config: config2, apiUrl } = metadata.services.selfhost;
34204
+ const { config: config2 } = metadata.services.selfhost;
34205
+ const apiUrl = await reconcileSelfhostApiUrl(metadata, region);
34117
34206
  if (!apiUrl) {
34118
34207
  clack45.log.error(
34119
34208
  "Self-hosted deployment is incomplete \u2014 API URL is not available yet."
@@ -34338,13 +34427,13 @@ Run ${pc49.cyan("wraps selfhost deploy")} to deploy the self-hosted control plan
34338
34427
  // src/commands/selfhost/status.ts
34339
34428
  init_esm_shims();
34340
34429
  init_events();
34430
+ import * as clack47 from "@clack/prompts";
34431
+ import pc50 from "picocolors";
34341
34432
  init_aws();
34342
34433
  init_json_output();
34343
34434
  init_metadata();
34344
34435
  init_output();
34345
34436
  init_region_resolver();
34346
- import * as clack47 from "@clack/prompts";
34347
- import pc50 from "picocolors";
34348
34437
  function displaySelfhostStatus(options) {
34349
34438
  const lines = [];
34350
34439
  lines.push(pc50.bold(pc50.green("Self-Hosted Control Plane Active")));
@@ -34392,9 +34481,10 @@ Run ${pc50.cyan("wraps selfhost deploy")} to deploy the self-hosted control plan
34392
34481
  progress.stop();
34393
34482
  const selfhostService = metadata.services.selfhost;
34394
34483
  const config2 = selfhostService.config;
34484
+ const apiUrl = await reconcileSelfhostApiUrl(metadata, region) ?? selfhostService.apiUrl;
34395
34485
  const statusData = {
34396
34486
  region,
34397
- apiUrl: selfhostService.apiUrl,
34487
+ apiUrl,
34398
34488
  deployedAt: selfhostService.deployedAt,
34399
34489
  neonProjectId: config2.neonProjectId,
34400
34490
  appUrl: config2.appUrl,
@@ -43175,7 +43265,8 @@ Run ${pc67.cyan("wraps --help")} for available commands.
43175
43265
  region: flags.region,
43176
43266
  force: flags.force,
43177
43267
  yes: flags.yes,
43178
- json: flags.json
43268
+ json: flags.json,
43269
+ selfhosted: true
43179
43270
  });
43180
43271
  break;
43181
43272
  default: