postboy-tui 1.3.7 → 1.3.8

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 +366 -113
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -67630,6 +67630,14 @@ function sendRequest({ method, url, headers = {}, body }) {
67630
67630
  return new Promise((resolve, reject) => {
67631
67631
  const urlObj = new URL2(url);
67632
67632
  const isHttps = urlObj.protocol === "https:";
67633
+ const timings = {
67634
+ start: performance.now(),
67635
+ dnsLookup: 0,
67636
+ tcpConnection: 0,
67637
+ tlsHandshake: 0,
67638
+ ttfb: 0,
67639
+ end: 0
67640
+ };
67633
67641
  const options = {
67634
67642
  method,
67635
67643
  hostname: urlObj.hostname,
@@ -67639,21 +67647,41 @@ function sendRequest({ method, url, headers = {}, body }) {
67639
67647
  };
67640
67648
  const reqModule = isHttps ? https : http;
67641
67649
  const req = reqModule.request(options, (res) => {
67650
+ timings.ttfb = performance.now();
67642
67651
  let data = "";
67643
67652
  res.on("data", (chunk) => {
67644
67653
  data += chunk;
67645
67654
  });
67646
67655
  res.on("end", () => {
67647
- try {
67648
- resolve({
67649
- status: res.statusCode || 0,
67650
- statusText: res.statusMessage || "",
67651
- headers: Object.fromEntries(Object.entries(res.headers).map(([k, v]) => [k, Array.isArray(v) ? v.join(", ") : v || ""])),
67652
- body: data
67653
- });
67654
- } catch (err) {
67655
- reject(err);
67656
- }
67656
+ timings.end = performance.now();
67657
+ const contentLength = parseInt(res.headers["content-length"] || "0", 10) || Buffer.byteLength(data, "utf8");
67658
+ const metrics = {
67659
+ dnsLookup: timings.dnsLookup - timings.start,
67660
+ tcpConnection: timings.tcpConnection - timings.dnsLookup,
67661
+ tlsHandshake: isHttps ? timings.tlsHandshake - timings.tcpConnection : 0,
67662
+ ttfb: timings.ttfb - timings.start,
67663
+ contentDownload: timings.end - timings.ttfb,
67664
+ total: timings.end - timings.start,
67665
+ contentLength
67666
+ };
67667
+ resolve({
67668
+ status: res.statusCode || 0,
67669
+ statusText: res.statusMessage || "",
67670
+ headers: Object.fromEntries(Object.entries(res.headers).map(([k, v]) => [k, Array.isArray(v) ? v.join(", ") : v || ""])),
67671
+ body: data,
67672
+ metrics
67673
+ });
67674
+ });
67675
+ });
67676
+ req.on("socket", (socket) => {
67677
+ socket.on("lookup", () => {
67678
+ timings.dnsLookup = performance.now();
67679
+ });
67680
+ socket.on("connect", () => {
67681
+ timings.tcpConnection = performance.now();
67682
+ });
67683
+ socket.on("secureConnect", () => {
67684
+ timings.tlsHandshake = performance.now();
67657
67685
  });
67658
67686
  });
67659
67687
  req.on("error", reject);
@@ -69339,25 +69367,241 @@ var JsonSyntaxHighlight = import_react31.default.memo(({ jsonString, theme }) =>
69339
69367
 
69340
69368
  // src/ui/app/components/responsepanel.tsx
69341
69369
  var import_react32 = __toESM(require_react(), 1);
69370
+
69371
+ // src/ui/app/components/metricspanel.tsx
69342
69372
  var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
69343
- var ResponsePanel = import_react32.default.memo(({ response, theme }) => {
69344
- const [activeTab, setActiveTab] = import_react32.useState("body");
69345
- const tabs = [{ name: "headers", label: "Headers" }, { name: "body", label: "Body" }];
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);
69346
69431
  return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69347
69432
  flexDirection: "column",
69348
- flexGrow: 1,
69433
+ paddingX: 1,
69349
69434
  children: [
69350
69435
  /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69351
69436
  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,
69352
69503
  children: [
69353
69504
  /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69354
- width: 8,
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
+ children: [
69567
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69568
+ color: theme.colors.muted,
69569
+ children: "────────────────────────────────────────────────────────────"
69570
+ }, undefined, false, undefined, this),
69571
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69572
+ marginTop: 1,
69355
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
+ width: 8,
69599
+ children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69356
69600
  color: theme.colors.primary,
69357
69601
  children: "STATUS:"
69358
69602
  }, undefined, false, undefined, this)
69359
69603
  }, undefined, false, undefined, this),
69360
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69604
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69361
69605
  color: getStatusColor(response.status, theme),
69362
69606
  bold: true,
69363
69607
  children: [
@@ -69368,30 +69612,30 @@ var ResponsePanel = import_react32.default.memo(({ response, theme }) => {
69368
69612
  }, undefined, true, undefined, this)
69369
69613
  ]
69370
69614
  }, undefined, true, undefined, this),
69371
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Tabs, {
69615
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Tabs, {
69372
69616
  tabs,
69373
69617
  activeTab,
69374
69618
  onChange: setActiveTab,
69375
69619
  theme
69376
69620
  }, undefined, false, undefined, this),
69377
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69621
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69378
69622
  marginTop: 1,
69379
69623
  flexGrow: 1,
69380
69624
  children: [
69381
- activeTab === "headers" && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(ScrollableBox, {
69382
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69625
+ activeTab === "headers" && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(ScrollableBox, {
69626
+ children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69383
69627
  flexDirection: "column",
69384
- children: Object.entries(JSON.parse(response.headers || "{}")).map(([key, value]) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69628
+ children: Object.entries(JSON.parse(response.headers || "{}")).map(([key, value]) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69385
69629
  children: [
69386
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69630
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69387
69631
  color: theme.colors.accent,
69388
69632
  children: key
69389
69633
  }, undefined, false, undefined, this),
69390
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69634
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69391
69635
  color: theme.colors.muted,
69392
69636
  children: ": "
69393
69637
  }, undefined, false, undefined, this),
69394
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
69638
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69395
69639
  color: theme.colors.success,
69396
69640
  children: String(value)
69397
69641
  }, undefined, false, undefined, this)
@@ -69399,15 +69643,21 @@ var ResponsePanel = import_react32.default.memo(({ response, theme }) => {
69399
69643
  }, key, true, undefined, this))
69400
69644
  }, undefined, false, undefined, this)
69401
69645
  }, undefined, false, undefined, this),
69402
- activeTab === "body" && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(ScrollableBox, {
69403
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69646
+ activeTab === "body" && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(ScrollableBox, {
69647
+ children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69404
69648
  flexDirection: "column",
69405
69649
  flexGrow: 1,
69406
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(JsonSyntaxHighlight, {
69650
+ children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(JsonSyntaxHighlight, {
69407
69651
  jsonString: response.body,
69408
69652
  theme
69409
69653
  }, undefined, false, undefined, this)
69410
69654
  }, 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)
69411
69661
  }, undefined, false, undefined, this)
69412
69662
  ]
69413
69663
  }, undefined, true, undefined, this)
@@ -69504,7 +69754,7 @@ var saveToFile = async (content, filePath) => {
69504
69754
  };
69505
69755
 
69506
69756
  // src/ui/app/components/exportdialog.tsx
69507
- var jsx_dev_runtime11 = __toESM(require_jsx_dev_runtime(), 1);
69757
+ var jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
69508
69758
  var EXPORT_DIR = `${process.env.HOME}/.postboy/exports`;
69509
69759
  var ExportDialog = ({ request, onClose, theme }) => {
69510
69760
  const [format, setFormat] = import_react33.useState("curl");
@@ -69584,58 +69834,58 @@ ${finalPath}` : "Failed to save file");
69584
69834
  }
69585
69835
  });
69586
69836
  const preview = getExportContent();
69587
- return /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69837
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69588
69838
  flexDirection: "column",
69589
69839
  borderStyle: "double",
69590
69840
  borderColor: theme.accent,
69591
69841
  padding: 1,
69592
69842
  children: [
69593
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69843
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69594
69844
  marginBottom: 1,
69595
69845
  children: [
69596
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69846
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69597
69847
  color: theme.accent,
69598
69848
  bold: true,
69599
69849
  children: "Export Request"
69600
69850
  }, undefined, false, undefined, this),
69601
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69851
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69602
69852
  color: theme.muted,
69603
69853
  children: " (Tab: switch, ←→: select, Enter: confirm, Esc: cancel)"
69604
69854
  }, undefined, false, undefined, this)
69605
69855
  ]
69606
69856
  }, undefined, true, undefined, this),
69607
- message ? /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69857
+ message ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69608
69858
  padding: 1,
69609
69859
  flexDirection: "column",
69610
69860
  borderStyle: "round",
69611
69861
  borderColor: theme.success,
69612
69862
  children: message.split(`
69613
- `).map((line, i) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69863
+ `).map((line, i) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69614
69864
  color: theme.success,
69615
69865
  bold: true,
69616
69866
  children: line
69617
69867
  }, i, false, undefined, this))
69618
- }, undefined, false, undefined, this) : showSavePrompt ? /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69868
+ }, undefined, false, undefined, this) : showSavePrompt ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69619
69869
  flexDirection: "column",
69620
69870
  gap: 1,
69621
69871
  children: [
69622
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69872
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69623
69873
  children: [
69624
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69874
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69625
69875
  color: theme.primary,
69626
69876
  children: "File path: "
69627
69877
  }, undefined, false, undefined, this),
69628
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69878
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69629
69879
  borderStyle: "round",
69630
69880
  borderColor: theme.accent,
69631
69881
  paddingX: 1,
69632
69882
  flexGrow: 1,
69633
69883
  children: [
69634
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69884
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69635
69885
  color: theme.white,
69636
69886
  children: filePath
69637
69887
  }, undefined, false, undefined, this),
69638
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69888
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69639
69889
  color: theme.accent,
69640
69890
  children: "▌"
69641
69891
  }, undefined, false, undefined, this)
@@ -69643,7 +69893,7 @@ ${finalPath}` : "Failed to save file");
69643
69893
  }, undefined, true, undefined, this)
69644
69894
  ]
69645
69895
  }, undefined, true, undefined, this),
69646
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69896
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69647
69897
  color: theme.muted,
69648
69898
  children: [
69649
69899
  "Extension .",
@@ -69652,32 +69902,32 @@ ${finalPath}` : "Failed to save file");
69652
69902
  ]
69653
69903
  }, undefined, true, undefined, this)
69654
69904
  ]
69655
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69905
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69656
69906
  flexDirection: "column",
69657
69907
  gap: 1,
69658
69908
  children: [
69659
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69909
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69660
69910
  gap: 2,
69661
69911
  children: [
69662
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69912
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69663
69913
  color: theme.primary,
69664
69914
  children: "Format: "
69665
69915
  }, undefined, false, undefined, this),
69666
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69916
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69667
69917
  borderStyle: "round",
69668
69918
  borderColor: activeField === "format" && format === "curl" ? theme.accent : theme.muted,
69669
69919
  paddingX: 1,
69670
- children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69920
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69671
69921
  color: format === "curl" ? theme.accent : theme.muted,
69672
69922
  bold: format === "curl",
69673
69923
  children: "cURL"
69674
69924
  }, undefined, false, undefined, this)
69675
69925
  }, undefined, false, undefined, this),
69676
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69926
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69677
69927
  borderStyle: "round",
69678
69928
  borderColor: activeField === "format" && format === "fetch" ? theme.accent : theme.muted,
69679
69929
  paddingX: 1,
69680
- children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69930
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69681
69931
  color: format === "fetch" ? theme.accent : theme.muted,
69682
69932
  bold: format === "fetch",
69683
69933
  children: "Fetch"
@@ -69685,28 +69935,28 @@ ${finalPath}` : "Failed to save file");
69685
69935
  }, undefined, false, undefined, this)
69686
69936
  ]
69687
69937
  }, undefined, true, undefined, this),
69688
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69938
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69689
69939
  gap: 2,
69690
69940
  children: [
69691
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69941
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69692
69942
  color: theme.primary,
69693
69943
  children: "Action: "
69694
69944
  }, undefined, false, undefined, this),
69695
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69945
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69696
69946
  borderStyle: "round",
69697
69947
  borderColor: activeField === "action" && action === "copy" ? theme.accent : theme.muted,
69698
69948
  paddingX: 1,
69699
- children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69949
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69700
69950
  color: action === "copy" ? theme.accent : theme.muted,
69701
69951
  bold: action === "copy",
69702
69952
  children: "Copy to Clipboard"
69703
69953
  }, undefined, false, undefined, this)
69704
69954
  }, undefined, false, undefined, this),
69705
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69955
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69706
69956
  borderStyle: "round",
69707
69957
  borderColor: activeField === "action" && action === "save" ? theme.accent : theme.muted,
69708
69958
  paddingX: 1,
69709
- children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69959
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69710
69960
  color: action === "save" ? theme.accent : theme.muted,
69711
69961
  bold: action === "save",
69712
69962
  children: "Save to File"
@@ -69714,21 +69964,21 @@ ${finalPath}` : "Failed to save file");
69714
69964
  }, undefined, false, undefined, this)
69715
69965
  ]
69716
69966
  }, undefined, true, undefined, this),
69717
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69967
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69718
69968
  flexDirection: "column",
69719
69969
  marginTop: 1,
69720
69970
  children: [
69721
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69971
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69722
69972
  color: theme.primary,
69723
69973
  children: "Preview:"
69724
69974
  }, undefined, false, undefined, this),
69725
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
69975
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
69726
69976
  borderStyle: "round",
69727
69977
  borderColor: theme.muted,
69728
69978
  padding: 1,
69729
69979
  flexDirection: "column",
69730
69980
  children: preview.split(`
69731
- `).map((line, i) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
69981
+ `).map((line, i) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
69732
69982
  color: theme.white,
69733
69983
  children: line
69734
69984
  }, i, false, undefined, this))
@@ -69844,21 +70094,21 @@ class ThemeManager {
69844
70094
  var themeManager = new ThemeManager;
69845
70095
 
69846
70096
  // src/ui/app/ui.tsx
69847
- var jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
70097
+ var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
69848
70098
  var SendButton = ({ onPress, loading, theme }) => {
69849
70099
  const { isFocused } = use_focus_default();
69850
70100
  use_input_default((_, key) => {
69851
70101
  if (isFocused && key.return)
69852
70102
  onPress();
69853
70103
  });
69854
- return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70104
+ return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
69855
70105
  borderStyle: "round",
69856
70106
  paddingX: 2,
69857
70107
  borderTopDimColor: true,
69858
70108
  borderColor: isFocused ? theme.accent : theme.primary,
69859
- children: loading ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Spinner, {
70109
+ children: loading ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Spinner, {
69860
70110
  theme
69861
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70111
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
69862
70112
  bold: true,
69863
70113
  color: isFocused ? theme.accent : theme.white,
69864
70114
  children: "\uD83D\uDE80 Send"
@@ -69866,12 +70116,12 @@ var SendButton = ({ onPress, loading, theme }) => {
69866
70116
  }, undefined, false, undefined, this);
69867
70117
  };
69868
70118
  var HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"];
69869
- var RequestPanel = import_react34.default.memo(({ request, onMethodChange, onUrlChange, onHeadersChange, onBodyChange, onSend, loading, theme, historyUrls = [], onInputFocus }) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70119
+ var RequestPanel = import_react34.default.memo(({ request, onMethodChange, onUrlChange, onHeadersChange, onBodyChange, onSend, loading, theme, historyUrls = [], onInputFocus }) => /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
69870
70120
  flexDirection: "column",
69871
70121
  gap: 1,
69872
70122
  flexGrow: 1,
69873
70123
  children: [
69874
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(FormField, {
70124
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(FormField, {
69875
70125
  label: "Method",
69876
70126
  value: request.method,
69877
70127
  onChange: onMethodChange,
@@ -69880,7 +70130,7 @@ var RequestPanel = import_react34.default.memo(({ request, onMethodChange, onUrl
69880
70130
  suggestions: HTTP_METHODS,
69881
70131
  onFocusChange: onInputFocus
69882
70132
  }, undefined, false, undefined, this),
69883
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(FormField, {
70133
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(FormField, {
69884
70134
  label: "URL",
69885
70135
  value: request.url,
69886
70136
  onChange: onUrlChange,
@@ -69889,7 +70139,7 @@ var RequestPanel = import_react34.default.memo(({ request, onMethodChange, onUrl
69889
70139
  suggestions: historyUrls,
69890
70140
  onFocusChange: onInputFocus
69891
70141
  }, undefined, false, undefined, this),
69892
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(KeyValueField, {
70142
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(KeyValueField, {
69893
70143
  label: "Headers",
69894
70144
  value: request.headers,
69895
70145
  onChange: onHeadersChange,
@@ -69897,7 +70147,7 @@ var RequestPanel = import_react34.default.memo(({ request, onMethodChange, onUrl
69897
70147
  theme,
69898
70148
  onFocusChange: onInputFocus
69899
70149
  }, undefined, false, undefined, this),
69900
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(KeyValueField, {
70150
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(KeyValueField, {
69901
70151
  label: "Body",
69902
70152
  value: request.body,
69903
70153
  onChange: onBodyChange,
@@ -69905,10 +70155,10 @@ var RequestPanel = import_react34.default.memo(({ request, onMethodChange, onUrl
69905
70155
  theme,
69906
70156
  onFocusChange: onInputFocus
69907
70157
  }, undefined, false, undefined, this),
69908
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70158
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
69909
70159
  marginTop: 1,
69910
70160
  justifyContent: "center",
69911
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(SendButton, {
70161
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(SendButton, {
69912
70162
  onPress: onSend,
69913
70163
  loading,
69914
70164
  theme
@@ -69922,6 +70172,7 @@ var UI = () => {
69922
70172
  const [activeTab, setActiveTab] = import_react34.useState("request");
69923
70173
  const [request, setRequest] = import_react34.useState({ method: "GET", url: "", headers: "", body: "" });
69924
70174
  const [response, setResponse] = import_react34.useState({ statustext: "", status: "", headers: "", body: "", error: "" });
70175
+ const [metrics, setMetrics] = import_react34.useState(null);
69925
70176
  const [history, setHistory] = import_react34.useState([]);
69926
70177
  const [loading, setLoading] = import_react34.useState(false);
69927
70178
  const requestRef = import_react34.useRef(request);
@@ -69965,6 +70216,7 @@ var UI = () => {
69965
70216
  const responseTime = Date.now() - startTime;
69966
70217
  await historyManager.addEntry({ ...currentRequest }, res.status, responseTime);
69967
70218
  setHistory((await historyManager.loadHistory()).entries);
70219
+ setMetrics(res.metrics);
69968
70220
  setResponse({ statustext: res.statusText, status: res.status.toString(), headers: JSON.stringify(res.headers), body: res.body, error: res.status >= 200 && res.status < 400 ? "" : `Error: ${res.statusText}` });
69969
70221
  setActiveTab("response");
69970
70222
  } catch (error) {
@@ -70015,89 +70267,89 @@ var UI = () => {
70015
70267
  const onHeadersChange = import_react34.useCallback((headers) => setRequest((r) => ({ ...r, headers })), []);
70016
70268
  const onBodyChange = import_react34.useCallback((body) => setRequest((r) => ({ ...r, body })), []);
70017
70269
  const historyUrls = Array.from(new Set(history.map((h) => h.url))).filter(Boolean);
70018
- return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70270
+ return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70019
70271
  padding: 1,
70020
70272
  flexDirection: "column",
70021
70273
  flexGrow: 1,
70022
70274
  children: [
70023
- showThemeSelector && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70275
+ showThemeSelector && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70024
70276
  flexDirection: "row",
70025
70277
  justifyContent: "center",
70026
70278
  marginBottom: 1,
70027
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ThemeSelector, {
70279
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(ThemeSelector, {
70028
70280
  theme,
70029
70281
  onThemeChange: (themeName) => {
70030
70282
  handleThemeChange(themes[themeName]);
70031
70283
  }
70032
70284
  }, undefined, false, undefined, this)
70033
70285
  }, undefined, false, undefined, this),
70034
- showExportDialog && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70286
+ showExportDialog && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70035
70287
  flexDirection: "row",
70036
70288
  justifyContent: "center",
70037
70289
  marginBottom: 1,
70038
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ExportDialog, {
70290
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(ExportDialog, {
70039
70291
  request,
70040
70292
  onClose: () => setShowExportDialog(false),
70041
70293
  theme: theme.colors
70042
70294
  }, undefined, false, undefined, this)
70043
70295
  }, undefined, false, undefined, this),
70044
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70296
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70045
70297
  alignSelf: "center",
70046
70298
  marginBottom: 1,
70047
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70299
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70048
70300
  color: theme.colors.accent,
70049
70301
  bold: true,
70050
70302
  children: `┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓`
70051
70303
  }, undefined, false, undefined, this)
70052
70304
  }, undefined, false, undefined, this),
70053
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70305
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70054
70306
  alignSelf: "center",
70055
70307
  marginBottom: 1,
70056
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70308
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70057
70309
  color: theme.colors.primary,
70058
70310
  bold: true,
70059
70311
  children: `┃ \uD83D\uDEF0️ Welcome to PostBoy — The Modern Terminal API Client ┃`
70060
70312
  }, undefined, false, undefined, this)
70061
70313
  }, undefined, false, undefined, this),
70062
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70314
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70063
70315
  alignSelf: "center",
70064
70316
  marginBottom: 1,
70065
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70317
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70066
70318
  color: theme.colors.accent,
70067
70319
  bold: true,
70068
70320
  children: `┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛`
70069
70321
  }, undefined, false, undefined, this)
70070
70322
  }, undefined, false, undefined, this),
70071
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70323
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70072
70324
  flexGrow: 1,
70073
70325
  children: [
70074
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70326
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70075
70327
  width: "40%",
70076
70328
  borderColor: theme.colors.muted,
70077
70329
  flexDirection: "column",
70078
70330
  marginRight: 1,
70079
70331
  children: [
70080
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70332
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70081
70333
  alignSelf: "center",
70082
70334
  marginBottom: 1,
70083
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70335
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70084
70336
  color: theme.colors.accent,
70085
70337
  bold: true,
70086
70338
  children: `┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓`
70087
70339
  }, undefined, false, undefined, this)
70088
70340
  }, undefined, false, undefined, this),
70089
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70341
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70090
70342
  borderTopColor: "grey",
70091
70343
  borderColor: theme.colors.secondary,
70092
70344
  paddingX: 1,
70093
70345
  alignSelf: "center",
70094
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70346
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70095
70347
  color: theme.colors.accent,
70096
70348
  bold: true,
70097
70349
  children: "\uD83D\uDCDC History"
70098
70350
  }, undefined, false, undefined, this)
70099
70351
  }, undefined, false, undefined, this),
70100
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70352
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70101
70353
  flexDirection: "column",
70102
70354
  flexGrow: 1,
70103
70355
  borderRightColor: "grey",
@@ -70106,22 +70358,22 @@ var UI = () => {
70106
70358
  borderLeft: false,
70107
70359
  borderBottom: false,
70108
70360
  paddingY: 1,
70109
- children: history.length === 0 ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70361
+ children: history.length === 0 ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70110
70362
  padding: 1,
70111
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70363
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70112
70364
  color: theme.colors.muted,
70113
70365
  children: "No requests yet..."
70114
70366
  }, undefined, false, undefined, this)
70115
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(HistoryList, {
70367
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(HistoryList, {
70116
70368
  history,
70117
70369
  onItemClick: handleHistoryClick,
70118
70370
  theme
70119
70371
  }, undefined, false, undefined, this)
70120
70372
  }, undefined, false, undefined, this),
70121
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70373
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70122
70374
  alignSelf: "center",
70123
70375
  marginBottom: 1,
70124
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70376
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70125
70377
  color: theme.colors.accent,
70126
70378
  bold: true,
70127
70379
  children: `┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛`
@@ -70129,36 +70381,36 @@ var UI = () => {
70129
70381
  }, undefined, false, undefined, this)
70130
70382
  ]
70131
70383
  }, undefined, true, undefined, this),
70132
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70384
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70133
70385
  width: "60%",
70134
70386
  borderColor: theme.colors.muted,
70135
70387
  padding: 1,
70136
70388
  flexDirection: "column",
70137
70389
  children: [
70138
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70390
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70139
70391
  alignSelf: "center",
70140
70392
  marginBottom: 1,
70141
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70393
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70142
70394
  color: theme.colors.accent,
70143
70395
  bold: true,
70144
70396
  children: `┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓`
70145
70397
  }, undefined, false, undefined, this)
70146
70398
  }, undefined, false, undefined, this),
70147
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Tabs, {
70399
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Tabs, {
70148
70400
  tabs,
70149
70401
  activeTab,
70150
70402
  onChange: setActiveTab,
70151
70403
  theme
70152
70404
  }, undefined, false, undefined, this),
70153
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70405
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70154
70406
  marginTop: 1,
70155
70407
  flexDirection: "column",
70156
70408
  flexGrow: 1,
70157
70409
  children: [
70158
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70410
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70159
70411
  display: activeTab === "request" ? "flex" : "none",
70160
70412
  flexGrow: 1,
70161
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(RequestPanel, {
70413
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(RequestPanel, {
70162
70414
  request,
70163
70415
  onMethodChange,
70164
70416
  onUrlChange,
@@ -70171,20 +70423,21 @@ var UI = () => {
70171
70423
  onInputFocus: setInputFocused
70172
70424
  }, undefined, false, undefined, this)
70173
70425
  }, undefined, false, undefined, this),
70174
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70426
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70175
70427
  display: activeTab === "response" ? "flex" : "none",
70176
70428
  flexGrow: 1,
70177
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ResponsePanel, {
70429
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(ResponsePanel, {
70178
70430
  response,
70179
- theme
70431
+ theme,
70432
+ metrics
70180
70433
  }, undefined, false, undefined, this)
70181
70434
  }, undefined, false, undefined, this)
70182
70435
  ]
70183
70436
  }, undefined, true, undefined, this),
70184
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70437
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70185
70438
  alignSelf: "center",
70186
70439
  marginBottom: 1,
70187
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70440
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70188
70441
  color: theme.colors.accent,
70189
70442
  bold: true,
70190
70443
  children: `┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛`
@@ -70194,7 +70447,7 @@ var UI = () => {
70194
70447
  }, undefined, true, undefined, this)
70195
70448
  ]
70196
70449
  }, undefined, true, undefined, this),
70197
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Footer, {
70450
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Footer, {
70198
70451
  theme: theme.colors
70199
70452
  }, undefined, false, undefined, this)
70200
70453
  ]
@@ -70203,14 +70456,14 @@ var UI = () => {
70203
70456
  var ui_default = UI;
70204
70457
 
70205
70458
  // src/ui/app/app.tsx
70206
- var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
70459
+ var jsx_dev_runtime14 = __toESM(require_jsx_dev_runtime(), 1);
70207
70460
  function App2() {
70208
- return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(ui_default, {}, undefined, false, undefined, this);
70461
+ return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(ui_default, {}, undefined, false, undefined, this);
70209
70462
  }
70210
70463
 
70211
70464
  // src/commands/ui.tsx
70212
70465
  var import_chalk6 = __toESM(require_source(), 1);
70213
- var jsx_dev_runtime14 = __toESM(require_jsx_dev_runtime(), 1);
70466
+ var jsx_dev_runtime15 = __toESM(require_jsx_dev_runtime(), 1);
70214
70467
  var UIWrapper = () => {
70215
70468
  const { exit } = use_app_default();
70216
70469
  use_input_default((input) => {
@@ -70218,18 +70471,18 @@ var UIWrapper = () => {
70218
70471
  exit();
70219
70472
  }
70220
70473
  });
70221
- return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
70474
+ return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
70222
70475
  flexDirection: "column",
70223
70476
  children: [
70224
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
70477
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
70225
70478
  children: import_chalk6.default.cyanBright(`PostBoy \uD83D\uDC8C`)
70226
70479
  }, undefined, false, undefined, this),
70227
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(App2, {}, undefined, false, undefined, this)
70480
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(App2, {}, undefined, false, undefined, this)
70228
70481
  ]
70229
70482
  }, undefined, true, undefined, this);
70230
70483
  };
70231
70484
  var uiCommand = () => {
70232
- render_default(/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(UIWrapper, {}, undefined, false, undefined, this));
70485
+ render_default(/* @__PURE__ */ jsx_dev_runtime15.jsxDEV(UIWrapper, {}, undefined, false, undefined, this));
70233
70486
  };
70234
70487
 
70235
70488
  // src/commands/test.ts
@@ -70398,7 +70651,7 @@ async function mockApis() {
70398
70651
 
70399
70652
  // src/index.ts
70400
70653
  var program2 = new Command;
70401
- program2.version("1.3.7").description(import_chalk9.default.yellow("PostBoy CLI - Test your APIs with ease"));
70654
+ program2.version("1.3.8").description(import_chalk9.default.yellow("PostBoy CLI - Test your APIs with ease"));
70402
70655
  program2.command("run").description("Run a test API request").action(testCommand);
70403
70656
  program2.command("mock-list").description("List the mock API servers").action(mockApis);
70404
70657
  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.7",
3
+ "version": "1.3.8",
4
4
  "main": "dist/cli.js",
5
5
  "bin": {
6
6
  "postboy-tui": "dist/cli.js"