postboy-tui 1.3.8 → 1.3.9

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.
Files changed (2) hide show
  1. package/dist/cli.js +285 -273
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -69367,241 +69367,25 @@ var JsonSyntaxHighlight = import_react31.default.memo(({ jsonString, theme }) =>
69367
69367
 
69368
69368
  // src/ui/app/components/responsepanel.tsx
69369
69369
  var import_react32 = __toESM(require_react(), 1);
69370
-
69371
- // src/ui/app/components/metricspanel.tsx
69372
69370
  var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
69373
- var MetricBar = ({ label, value, maxValue, color, theme }) => {
69374
- const barWidth = 40;
69375
- const safeValue = Math.max(0, value);
69376
- const filledWidth = Math.max(0, Math.min(barWidth, maxValue > 0 ? Math.round(safeValue / maxValue * barWidth) : 0));
69377
- const emptyWidth = barWidth - filledWidth;
69378
- const bar = "█".repeat(filledWidth) + "░".repeat(emptyWidth);
69379
- return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69380
- marginY: 0,
69381
- children: [
69382
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69383
- width: 18,
69384
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69385
- color: theme.colors.muted,
69386
- children: label
69387
- }, undefined, false, undefined, this)
69388
- }, undefined, false, undefined, this),
69389
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69390
- width: barWidth + 2,
69391
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69392
- color,
69393
- children: bar
69394
- }, undefined, false, undefined, this)
69395
- }, undefined, false, undefined, this),
69396
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69397
- width: 12,
69398
- justifyContent: "flex-end",
69399
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69400
- color: theme.colors.white,
69401
- bold: true,
69402
- children: [
69403
- safeValue.toFixed(1),
69404
- "ms"
69405
- ]
69406
- }, undefined, true, undefined, this)
69407
- }, undefined, false, undefined, this)
69408
- ]
69409
- }, undefined, true, undefined, this);
69410
- };
69411
- var formatBytes = (bytes) => {
69412
- if (bytes === 0)
69413
- return "0 B";
69414
- const k = 1024;
69415
- const sizes = ["B", "KB", "MB", "GB"];
69416
- const i = Math.floor(Math.log(bytes) / Math.log(k));
69417
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
69418
- };
69419
- var MetricsPanel = ({ metrics, theme }) => {
69420
- if (!metrics) {
69421
- return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69422
- flexDirection: "column",
69423
- padding: 1,
69424
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69425
- color: theme.colors.muted,
69426
- children: "No metrics available. Send a request first."
69427
- }, undefined, false, undefined, this)
69428
- }, undefined, false, undefined, this);
69429
- }
69430
- const maxTime = Math.max(Math.max(0, metrics.dnsLookup), Math.max(0, metrics.tcpConnection), Math.max(0, metrics.tlsHandshake), Math.max(0, metrics.ttfb), Math.max(0, metrics.contentDownload), 1);
69371
+ var ResponsePanel = import_react32.default.memo(({ response, theme }) => {
69372
+ const [activeTab, setActiveTab] = import_react32.useState("body");
69373
+ const tabs = [{ name: "body", label: "Body" }, { name: "headers", label: "Headers" }];
69431
69374
  return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69432
69375
  flexDirection: "column",
69433
- paddingX: 1,
69376
+ flexGrow: 1,
69434
69377
  children: [
69435
69378
  /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69436
69379
  marginBottom: 1,
69437
- flexDirection: "column",
69438
- children: [
69439
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69440
- color: theme.colors.accent,
69441
- bold: true,
69442
- children: "⚡ Performance Breakdown"
69443
- }, undefined, false, undefined, this),
69444
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69445
- color: theme.colors.muted,
69446
- children: "────────────────────────────────────────────────────────────"
69447
- }, undefined, false, undefined, this)
69448
- ]
69449
- }, undefined, true, undefined, this),
69450
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69451
- flexDirection: "column",
69452
- gap: 0,
69453
- children: [
69454
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(MetricBar, {
69455
- label: "\uD83D\uDD0D DNS Lookup",
69456
- value: metrics.dnsLookup,
69457
- maxValue: maxTime,
69458
- color: theme.colors.cool,
69459
- theme
69460
- }, undefined, false, undefined, this),
69461
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(MetricBar, {
69462
- label: "\uD83D\uDD0C TCP Connect",
69463
- value: metrics.tcpConnection,
69464
- maxValue: maxTime,
69465
- color: theme.colors.success,
69466
- theme
69467
- }, undefined, false, undefined, this),
69468
- metrics.tlsHandshake > 0 && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(MetricBar, {
69469
- label: "\uD83D\uDD10 TLS Handshake",
69470
- value: metrics.tlsHandshake,
69471
- maxValue: maxTime,
69472
- color: theme.colors.secondary,
69473
- theme
69474
- }, undefined, false, undefined, this),
69475
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(MetricBar, {
69476
- label: "⏱️ TTFB",
69477
- value: metrics.ttfb,
69478
- maxValue: maxTime,
69479
- color: theme.colors.accent,
69480
- theme
69481
- }, undefined, false, undefined, this),
69482
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(MetricBar, {
69483
- label: "\uD83D\uDCE5 Download",
69484
- value: metrics.contentDownload,
69485
- maxValue: maxTime,
69486
- color: theme.colors.primary,
69487
- theme
69488
- }, undefined, false, undefined, this)
69489
- ]
69490
- }, undefined, true, undefined, this),
69491
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69492
- marginTop: 1,
69493
- flexDirection: "column",
69494
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69495
- color: theme.colors.muted,
69496
- children: "────────────────────────────────────────────────────────────"
69497
- }, undefined, false, undefined, this)
69498
- }, undefined, false, undefined, this),
69499
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69500
- marginTop: 1,
69501
- flexDirection: "column",
69502
- gap: 0,
69503
- children: [
69504
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69505
- children: [
69506
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69507
- width: 18,
69508
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69509
- color: theme.colors.accent,
69510
- bold: true,
69511
- children: "\uD83D\uDCCA Total Time"
69512
- }, undefined, false, undefined, this)
69513
- }, undefined, false, undefined, this),
69514
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69515
- color: theme.colors.white,
69516
- bold: true,
69517
- children: [
69518
- metrics.total.toFixed(2),
69519
- " ms"
69520
- ]
69521
- }, undefined, true, undefined, this)
69522
- ]
69523
- }, undefined, true, undefined, this),
69524
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69525
- children: [
69526
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69527
- width: 18,
69528
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69529
- color: theme.colors.accent,
69530
- bold: true,
69531
- children: "\uD83D\uDCE6 Size"
69532
- }, undefined, false, undefined, this)
69533
- }, undefined, false, undefined, this),
69534
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69535
- color: theme.colors.white,
69536
- bold: true,
69537
- children: formatBytes(metrics.contentLength)
69538
- }, undefined, false, undefined, this)
69539
- ]
69540
- }, undefined, true, undefined, this),
69541
- metrics.contentLength > 0 && metrics.contentDownload > 0 && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69542
- children: [
69543
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69544
- width: 18,
69545
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69546
- color: theme.colors.accent,
69547
- bold: true,
69548
- children: "\uD83D\uDE80 Speed"
69549
- }, undefined, false, undefined, this)
69550
- }, undefined, false, undefined, this),
69551
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69552
- color: theme.colors.success,
69553
- bold: true,
69554
- children: [
69555
- formatBytes(metrics.contentLength / (metrics.contentDownload / 1000)),
69556
- "/s"
69557
- ]
69558
- }, undefined, true, undefined, this)
69559
- ]
69560
- }, undefined, true, undefined, this)
69561
- ]
69562
- }, undefined, true, undefined, this),
69563
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69564
- marginTop: 1,
69565
- flexDirection: "column",
69566
69380
  children: [
69567
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69568
- color: theme.colors.muted,
69569
- children: "────────────────────────────────────────────────────────────"
69570
- }, undefined, false, undefined, this),
69571
69381
  /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69572
- marginTop: 1,
69573
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69574
- color: theme.colors.muted,
69575
- dimColor: true,
69576
- children: "TTFB = Time To First Byte (DNS + TCP + TLS + Server Processing)"
69577
- }, undefined, false, undefined, this)
69578
- }, undefined, false, undefined, this)
69579
- ]
69580
- }, undefined, true, undefined, this)
69581
- ]
69582
- }, undefined, true, undefined, this);
69583
- };
69584
-
69585
- // src/ui/app/components/responsepanel.tsx
69586
- var jsx_dev_runtime11 = __toESM(require_jsx_dev_runtime(), 1);
69587
- var ResponsePanel = import_react32.default.memo(({ response, theme, metrics = null }) => {
69588
- const [activeTab, setActiveTab] = import_react32.useState("body");
69589
- const tabs = [{ name: "body", label: "Body" }, { name: "headers", label: "Headers" }, { name: "metrics", label: "⚡ Metrics" }];
69590
- return /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69591
- flexDirection: "column",
69592
- flexGrow: 1,
69593
- children: [
69594
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69595
- marginBottom: 1,
69596
- children: [
69597
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69598
69382
  width: 8,
69599
- children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69383
+ children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69600
69384
  color: theme.colors.primary,
69601
69385
  children: "STATUS:"
69602
69386
  }, undefined, false, undefined, this)
69603
69387
  }, undefined, false, undefined, this),
69604
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69388
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69605
69389
  color: getStatusColor(response.status, theme),
69606
69390
  bold: true,
69607
69391
  children: [
@@ -69612,30 +69396,30 @@ var ResponsePanel = import_react32.default.memo(({ response, theme, metrics = nu
69612
69396
  }, undefined, true, undefined, this)
69613
69397
  ]
69614
69398
  }, undefined, true, undefined, this),
69615
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Tabs, {
69399
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Tabs, {
69616
69400
  tabs,
69617
69401
  activeTab,
69618
69402
  onChange: setActiveTab,
69619
69403
  theme
69620
69404
  }, undefined, false, undefined, this),
69621
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69405
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69622
69406
  marginTop: 1,
69623
69407
  flexGrow: 1,
69624
69408
  children: [
69625
- activeTab === "headers" && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(ScrollableBox, {
69626
- children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69409
+ activeTab === "headers" && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(ScrollableBox, {
69410
+ children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69627
69411
  flexDirection: "column",
69628
- children: Object.entries(JSON.parse(response.headers || "{}")).map(([key, value]) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69412
+ children: Object.entries(JSON.parse(response.headers || "{}")).map(([key, value]) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69629
69413
  children: [
69630
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69414
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69631
69415
  color: theme.colors.accent,
69632
69416
  children: key
69633
69417
  }, undefined, false, undefined, this),
69634
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69418
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69635
69419
  color: theme.colors.muted,
69636
69420
  children: ": "
69637
69421
  }, undefined, false, undefined, this),
69638
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69422
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69639
69423
  color: theme.colors.success,
69640
69424
  children: String(value)
69641
69425
  }, undefined, false, undefined, this)
@@ -69643,21 +69427,15 @@ var ResponsePanel = import_react32.default.memo(({ response, theme, metrics = nu
69643
69427
  }, key, true, undefined, this))
69644
69428
  }, undefined, false, undefined, this)
69645
69429
  }, undefined, false, undefined, this),
69646
- activeTab === "body" && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(ScrollableBox, {
69647
- children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69430
+ activeTab === "body" && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(ScrollableBox, {
69431
+ children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69648
69432
  flexDirection: "column",
69649
69433
  flexGrow: 1,
69650
- children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(JsonSyntaxHighlight, {
69434
+ children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(JsonSyntaxHighlight, {
69651
69435
  jsonString: response.body,
69652
69436
  theme
69653
69437
  }, undefined, false, undefined, this)
69654
69438
  }, undefined, false, undefined, this)
69655
- }, undefined, false, undefined, this),
69656
- activeTab === "metrics" && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(ScrollableBox, {
69657
- children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(MetricsPanel, {
69658
- metrics,
69659
- theme
69660
- }, undefined, false, undefined, this)
69661
69439
  }, undefined, false, undefined, this)
69662
69440
  ]
69663
69441
  }, undefined, true, undefined, this)
@@ -69754,7 +69532,7 @@ var saveToFile = async (content, filePath) => {
69754
69532
  };
69755
69533
 
69756
69534
  // src/ui/app/components/exportdialog.tsx
69757
- var jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
69535
+ var jsx_dev_runtime11 = __toESM(require_jsx_dev_runtime(), 1);
69758
69536
  var EXPORT_DIR = `${process.env.HOME}/.postboy/exports`;
69759
69537
  var ExportDialog = ({ request, onClose, theme }) => {
69760
69538
  const [format, setFormat] = import_react33.useState("curl");
@@ -69834,58 +69612,58 @@ ${finalPath}` : "Failed to save file");
69834
69612
  }
69835
69613
  });
69836
69614
  const preview = getExportContent();
69837
- return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69615
+ return /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69838
69616
  flexDirection: "column",
69839
69617
  borderStyle: "double",
69840
69618
  borderColor: theme.accent,
69841
69619
  padding: 1,
69842
69620
  children: [
69843
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69621
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69844
69622
  marginBottom: 1,
69845
69623
  children: [
69846
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69624
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69847
69625
  color: theme.accent,
69848
69626
  bold: true,
69849
69627
  children: "Export Request"
69850
69628
  }, undefined, false, undefined, this),
69851
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69629
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69852
69630
  color: theme.muted,
69853
69631
  children: " (Tab: switch, ←→: select, Enter: confirm, Esc: cancel)"
69854
69632
  }, undefined, false, undefined, this)
69855
69633
  ]
69856
69634
  }, undefined, true, undefined, this),
69857
- message ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69635
+ message ? /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69858
69636
  padding: 1,
69859
69637
  flexDirection: "column",
69860
69638
  borderStyle: "round",
69861
69639
  borderColor: theme.success,
69862
69640
  children: message.split(`
69863
- `).map((line, i) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69641
+ `).map((line, i) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69864
69642
  color: theme.success,
69865
69643
  bold: true,
69866
69644
  children: line
69867
69645
  }, i, false, undefined, this))
69868
- }, undefined, false, undefined, this) : showSavePrompt ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69646
+ }, undefined, false, undefined, this) : showSavePrompt ? /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69869
69647
  flexDirection: "column",
69870
69648
  gap: 1,
69871
69649
  children: [
69872
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69650
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69873
69651
  children: [
69874
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69652
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69875
69653
  color: theme.primary,
69876
69654
  children: "File path: "
69877
69655
  }, undefined, false, undefined, this),
69878
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69656
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69879
69657
  borderStyle: "round",
69880
69658
  borderColor: theme.accent,
69881
69659
  paddingX: 1,
69882
69660
  flexGrow: 1,
69883
69661
  children: [
69884
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69662
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69885
69663
  color: theme.white,
69886
69664
  children: filePath
69887
69665
  }, undefined, false, undefined, this),
69888
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69666
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69889
69667
  color: theme.accent,
69890
69668
  children: "▌"
69891
69669
  }, undefined, false, undefined, this)
@@ -69893,7 +69671,7 @@ ${finalPath}` : "Failed to save file");
69893
69671
  }, undefined, true, undefined, this)
69894
69672
  ]
69895
69673
  }, undefined, true, undefined, this),
69896
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69674
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69897
69675
  color: theme.muted,
69898
69676
  children: [
69899
69677
  "Extension .",
@@ -69902,32 +69680,32 @@ ${finalPath}` : "Failed to save file");
69902
69680
  ]
69903
69681
  }, undefined, true, undefined, this)
69904
69682
  ]
69905
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69683
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69906
69684
  flexDirection: "column",
69907
69685
  gap: 1,
69908
69686
  children: [
69909
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69687
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69910
69688
  gap: 2,
69911
69689
  children: [
69912
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69690
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69913
69691
  color: theme.primary,
69914
69692
  children: "Format: "
69915
69693
  }, undefined, false, undefined, this),
69916
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69694
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69917
69695
  borderStyle: "round",
69918
69696
  borderColor: activeField === "format" && format === "curl" ? theme.accent : theme.muted,
69919
69697
  paddingX: 1,
69920
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69698
+ children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69921
69699
  color: format === "curl" ? theme.accent : theme.muted,
69922
69700
  bold: format === "curl",
69923
69701
  children: "cURL"
69924
69702
  }, undefined, false, undefined, this)
69925
69703
  }, undefined, false, undefined, this),
69926
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69704
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69927
69705
  borderStyle: "round",
69928
69706
  borderColor: activeField === "format" && format === "fetch" ? theme.accent : theme.muted,
69929
69707
  paddingX: 1,
69930
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69708
+ children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69931
69709
  color: format === "fetch" ? theme.accent : theme.muted,
69932
69710
  bold: format === "fetch",
69933
69711
  children: "Fetch"
@@ -69935,28 +69713,28 @@ ${finalPath}` : "Failed to save file");
69935
69713
  }, undefined, false, undefined, this)
69936
69714
  ]
69937
69715
  }, undefined, true, undefined, this),
69938
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69716
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69939
69717
  gap: 2,
69940
69718
  children: [
69941
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69719
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69942
69720
  color: theme.primary,
69943
69721
  children: "Action: "
69944
69722
  }, undefined, false, undefined, this),
69945
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69723
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69946
69724
  borderStyle: "round",
69947
69725
  borderColor: activeField === "action" && action === "copy" ? theme.accent : theme.muted,
69948
69726
  paddingX: 1,
69949
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69727
+ children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69950
69728
  color: action === "copy" ? theme.accent : theme.muted,
69951
69729
  bold: action === "copy",
69952
69730
  children: "Copy to Clipboard"
69953
69731
  }, undefined, false, undefined, this)
69954
69732
  }, undefined, false, undefined, this),
69955
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69733
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69956
69734
  borderStyle: "round",
69957
69735
  borderColor: activeField === "action" && action === "save" ? theme.accent : theme.muted,
69958
69736
  paddingX: 1,
69959
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69737
+ children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69960
69738
  color: action === "save" ? theme.accent : theme.muted,
69961
69739
  bold: action === "save",
69962
69740
  children: "Save to File"
@@ -69964,21 +69742,21 @@ ${finalPath}` : "Failed to save file");
69964
69742
  }, undefined, false, undefined, this)
69965
69743
  ]
69966
69744
  }, undefined, true, undefined, this),
69967
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69745
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69968
69746
  flexDirection: "column",
69969
69747
  marginTop: 1,
69970
69748
  children: [
69971
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69749
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69972
69750
  color: theme.primary,
69973
69751
  children: "Preview:"
69974
69752
  }, undefined, false, undefined, this),
69975
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69753
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69976
69754
  borderStyle: "round",
69977
69755
  borderColor: theme.muted,
69978
69756
  padding: 1,
69979
69757
  flexDirection: "column",
69980
69758
  children: preview.split(`
69981
- `).map((line, i) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69759
+ `).map((line, i) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69982
69760
  color: theme.white,
69983
69761
  children: line
69984
69762
  }, i, false, undefined, this))
@@ -70093,6 +69871,220 @@ class ThemeManager {
70093
69871
  }
70094
69872
  var themeManager = new ThemeManager;
70095
69873
 
69874
+ // src/ui/app/components/metricspanel.tsx
69875
+ var jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
69876
+ var MetricBar = ({ label, value, maxValue, color, theme }) => {
69877
+ const barWidth = 40;
69878
+ const safeValue = Math.max(0, value);
69879
+ const filledWidth = Math.max(0, Math.min(barWidth, maxValue > 0 ? Math.round(safeValue / maxValue * barWidth) : 0));
69880
+ const emptyWidth = barWidth - filledWidth;
69881
+ const bar = "█".repeat(filledWidth) + "░".repeat(emptyWidth);
69882
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69883
+ marginY: 0,
69884
+ children: [
69885
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69886
+ width: 18,
69887
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69888
+ color: theme.colors.muted,
69889
+ children: label
69890
+ }, undefined, false, undefined, this)
69891
+ }, undefined, false, undefined, this),
69892
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69893
+ width: barWidth + 2,
69894
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69895
+ color,
69896
+ children: bar
69897
+ }, undefined, false, undefined, this)
69898
+ }, undefined, false, undefined, this),
69899
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69900
+ width: 12,
69901
+ justifyContent: "flex-end",
69902
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69903
+ color: theme.colors.white,
69904
+ bold: true,
69905
+ children: [
69906
+ safeValue.toFixed(1),
69907
+ "ms"
69908
+ ]
69909
+ }, undefined, true, undefined, this)
69910
+ }, undefined, false, undefined, this)
69911
+ ]
69912
+ }, undefined, true, undefined, this);
69913
+ };
69914
+ var formatBytes = (bytes) => {
69915
+ if (bytes === 0)
69916
+ return "0 B";
69917
+ const k = 1024;
69918
+ const sizes = ["B", "KB", "MB", "GB"];
69919
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
69920
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
69921
+ };
69922
+ var MetricsPanel = ({ metrics, theme }) => {
69923
+ if (!metrics) {
69924
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69925
+ flexDirection: "column",
69926
+ padding: 1,
69927
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69928
+ color: theme.colors.muted,
69929
+ children: "No metrics available. Send a request first."
69930
+ }, undefined, false, undefined, this)
69931
+ }, undefined, false, undefined, this);
69932
+ }
69933
+ const maxTime = Math.max(Math.max(0, metrics.dnsLookup), Math.max(0, metrics.tcpConnection), Math.max(0, metrics.tlsHandshake), Math.max(0, metrics.ttfb), Math.max(0, metrics.contentDownload), 1);
69934
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69935
+ flexDirection: "column",
69936
+ paddingX: 1,
69937
+ children: [
69938
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69939
+ marginBottom: 1,
69940
+ flexDirection: "column",
69941
+ children: [
69942
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69943
+ color: theme.colors.accent,
69944
+ bold: true,
69945
+ children: "⚡ Performance Breakdown"
69946
+ }, undefined, false, undefined, this),
69947
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69948
+ color: theme.colors.muted,
69949
+ children: "────────────────────────────────────────────────────────────"
69950
+ }, undefined, false, undefined, this)
69951
+ ]
69952
+ }, undefined, true, undefined, this),
69953
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69954
+ flexDirection: "column",
69955
+ gap: 0,
69956
+ children: [
69957
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(MetricBar, {
69958
+ label: "\uD83D\uDD0D DNS Lookup",
69959
+ value: metrics.dnsLookup,
69960
+ maxValue: maxTime,
69961
+ color: theme.colors.cool,
69962
+ theme
69963
+ }, undefined, false, undefined, this),
69964
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(MetricBar, {
69965
+ label: "\uD83D\uDD0C TCP Connect",
69966
+ value: metrics.tcpConnection,
69967
+ maxValue: maxTime,
69968
+ color: theme.colors.success,
69969
+ theme
69970
+ }, undefined, false, undefined, this),
69971
+ metrics.tlsHandshake > 0 && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(MetricBar, {
69972
+ label: "\uD83D\uDD10 TLS Handshake",
69973
+ value: metrics.tlsHandshake,
69974
+ maxValue: maxTime,
69975
+ color: theme.colors.secondary,
69976
+ theme
69977
+ }, undefined, false, undefined, this),
69978
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(MetricBar, {
69979
+ label: "⏱️ TTFB",
69980
+ value: metrics.ttfb,
69981
+ maxValue: maxTime,
69982
+ color: theme.colors.accent,
69983
+ theme
69984
+ }, undefined, false, undefined, this),
69985
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(MetricBar, {
69986
+ label: "\uD83D\uDCE5 Download",
69987
+ value: metrics.contentDownload,
69988
+ maxValue: maxTime,
69989
+ color: theme.colors.primary,
69990
+ theme
69991
+ }, undefined, false, undefined, this)
69992
+ ]
69993
+ }, undefined, true, undefined, this),
69994
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69995
+ marginTop: 1,
69996
+ flexDirection: "column",
69997
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69998
+ color: theme.colors.muted,
69999
+ children: "────────────────────────────────────────────────────────────"
70000
+ }, undefined, false, undefined, this)
70001
+ }, undefined, false, undefined, this),
70002
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70003
+ marginTop: 1,
70004
+ flexDirection: "column",
70005
+ gap: 0,
70006
+ children: [
70007
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70008
+ children: [
70009
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70010
+ width: 18,
70011
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70012
+ color: theme.colors.accent,
70013
+ bold: true,
70014
+ children: "\uD83D\uDCCA Total Time"
70015
+ }, undefined, false, undefined, this)
70016
+ }, undefined, false, undefined, this),
70017
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70018
+ color: theme.colors.white,
70019
+ bold: true,
70020
+ children: [
70021
+ metrics.total.toFixed(2),
70022
+ " ms"
70023
+ ]
70024
+ }, undefined, true, undefined, this)
70025
+ ]
70026
+ }, undefined, true, undefined, this),
70027
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70028
+ children: [
70029
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70030
+ width: 18,
70031
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70032
+ color: theme.colors.accent,
70033
+ bold: true,
70034
+ children: "\uD83D\uDCE6 Size"
70035
+ }, undefined, false, undefined, this)
70036
+ }, undefined, false, undefined, this),
70037
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70038
+ color: theme.colors.white,
70039
+ bold: true,
70040
+ children: formatBytes(metrics.contentLength)
70041
+ }, undefined, false, undefined, this)
70042
+ ]
70043
+ }, undefined, true, undefined, this),
70044
+ metrics.contentLength > 0 && metrics.contentDownload > 0 && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70045
+ children: [
70046
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70047
+ width: 18,
70048
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70049
+ color: theme.colors.accent,
70050
+ bold: true,
70051
+ children: "\uD83D\uDE80 Speed"
70052
+ }, undefined, false, undefined, this)
70053
+ }, undefined, false, undefined, this),
70054
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70055
+ color: theme.colors.success,
70056
+ bold: true,
70057
+ children: [
70058
+ formatBytes(metrics.contentLength / (metrics.contentDownload / 1000)),
70059
+ "/s"
70060
+ ]
70061
+ }, undefined, true, undefined, this)
70062
+ ]
70063
+ }, undefined, true, undefined, this)
70064
+ ]
70065
+ }, undefined, true, undefined, this),
70066
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70067
+ marginTop: 1,
70068
+ flexDirection: "column",
70069
+ children: [
70070
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70071
+ color: theme.colors.muted,
70072
+ children: "────────────────────────────────────────────────────────────"
70073
+ }, undefined, false, undefined, this),
70074
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70075
+ marginTop: 1,
70076
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70077
+ color: theme.colors.muted,
70078
+ dimColor: true,
70079
+ children: "TTFB = Time To First Byte (DNS + TCP + TLS + Server Processing)"
70080
+ }, undefined, false, undefined, this)
70081
+ }, undefined, false, undefined, this)
70082
+ ]
70083
+ }, undefined, true, undefined, this)
70084
+ ]
70085
+ }, undefined, true, undefined, this);
70086
+ };
70087
+
70096
70088
  // src/ui/app/ui.tsx
70097
70089
  var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
70098
70090
  var SendButton = ({ onPress, loading, theme }) => {
@@ -70370,6 +70362,27 @@ var UI = () => {
70370
70362
  theme
70371
70363
  }, undefined, false, undefined, this)
70372
70364
  }, undefined, false, undefined, this),
70365
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70366
+ flexDirection: "column",
70367
+ borderStyle: "round",
70368
+ borderColor: theme.colors.muted,
70369
+ marginX: 1,
70370
+ children: [
70371
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70372
+ alignSelf: "center",
70373
+ paddingX: 1,
70374
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70375
+ color: theme.colors.accent,
70376
+ bold: true,
70377
+ children: "⚡ Metrics"
70378
+ }, undefined, false, undefined, this)
70379
+ }, undefined, false, undefined, this),
70380
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(MetricsPanel, {
70381
+ metrics,
70382
+ theme
70383
+ }, undefined, false, undefined, this)
70384
+ ]
70385
+ }, undefined, true, undefined, this),
70373
70386
  /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70374
70387
  alignSelf: "center",
70375
70388
  marginBottom: 1,
@@ -70428,8 +70441,7 @@ var UI = () => {
70428
70441
  flexGrow: 1,
70429
70442
  children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(ResponsePanel, {
70430
70443
  response,
70431
- theme,
70432
- metrics
70444
+ theme
70433
70445
  }, undefined, false, undefined, this)
70434
70446
  }, undefined, false, undefined, this)
70435
70447
  ]
@@ -70651,7 +70663,7 @@ async function mockApis() {
70651
70663
 
70652
70664
  // src/index.ts
70653
70665
  var program2 = new Command;
70654
- program2.version("1.3.8").description(import_chalk9.default.yellow("PostBoy CLI - Test your APIs with ease"));
70666
+ program2.version("1.3.9").description(import_chalk9.default.yellow("PostBoy CLI - Test your APIs with ease"));
70655
70667
  program2.command("run").description("Run a test API request").action(testCommand);
70656
70668
  program2.command("mock-list").description("List the mock API servers").action(mockApis);
70657
70669
  program2.command("ui").description("UI for PostBoy").action(uiCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postboy-tui",
3
- "version": "1.3.8",
3
+ "version": "1.3.9",
4
4
  "main": "dist/cli.js",
5
5
  "bin": {
6
6
  "postboy-tui": "dist/cli.js"