postboy-tui 1.3.7 → 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 +330 -65
  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);
@@ -69342,7 +69370,7 @@ var import_react32 = __toESM(require_react(), 1);
69342
69370
  var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
69343
69371
  var ResponsePanel = import_react32.default.memo(({ response, theme }) => {
69344
69372
  const [activeTab, setActiveTab] = import_react32.useState("body");
69345
- const tabs = [{ name: "headers", label: "Headers" }, { name: "body", label: "Body" }];
69373
+ const tabs = [{ name: "body", label: "Body" }, { name: "headers", label: "Headers" }];
69346
69374
  return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
69347
69375
  flexDirection: "column",
69348
69376
  flexGrow: 1,
@@ -69843,22 +69871,236 @@ class ThemeManager {
69843
69871
  }
69844
69872
  var themeManager = new ThemeManager;
69845
69873
 
69846
- // src/ui/app/ui.tsx
69874
+ // src/ui/app/components/metricspanel.tsx
69847
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
+
70088
+ // src/ui/app/ui.tsx
70089
+ var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
69848
70090
  var SendButton = ({ onPress, loading, theme }) => {
69849
70091
  const { isFocused } = use_focus_default();
69850
70092
  use_input_default((_, key) => {
69851
70093
  if (isFocused && key.return)
69852
70094
  onPress();
69853
70095
  });
69854
- return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70096
+ return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
69855
70097
  borderStyle: "round",
69856
70098
  paddingX: 2,
69857
70099
  borderTopDimColor: true,
69858
70100
  borderColor: isFocused ? theme.accent : theme.primary,
69859
- children: loading ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Spinner, {
70101
+ children: loading ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Spinner, {
69860
70102
  theme
69861
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70103
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
69862
70104
  bold: true,
69863
70105
  color: isFocused ? theme.accent : theme.white,
69864
70106
  children: "\uD83D\uDE80 Send"
@@ -69866,12 +70108,12 @@ var SendButton = ({ onPress, loading, theme }) => {
69866
70108
  }, undefined, false, undefined, this);
69867
70109
  };
69868
70110
  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, {
70111
+ var RequestPanel = import_react34.default.memo(({ request, onMethodChange, onUrlChange, onHeadersChange, onBodyChange, onSend, loading, theme, historyUrls = [], onInputFocus }) => /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
69870
70112
  flexDirection: "column",
69871
70113
  gap: 1,
69872
70114
  flexGrow: 1,
69873
70115
  children: [
69874
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(FormField, {
70116
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(FormField, {
69875
70117
  label: "Method",
69876
70118
  value: request.method,
69877
70119
  onChange: onMethodChange,
@@ -69880,7 +70122,7 @@ var RequestPanel = import_react34.default.memo(({ request, onMethodChange, onUrl
69880
70122
  suggestions: HTTP_METHODS,
69881
70123
  onFocusChange: onInputFocus
69882
70124
  }, undefined, false, undefined, this),
69883
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(FormField, {
70125
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(FormField, {
69884
70126
  label: "URL",
69885
70127
  value: request.url,
69886
70128
  onChange: onUrlChange,
@@ -69889,7 +70131,7 @@ var RequestPanel = import_react34.default.memo(({ request, onMethodChange, onUrl
69889
70131
  suggestions: historyUrls,
69890
70132
  onFocusChange: onInputFocus
69891
70133
  }, undefined, false, undefined, this),
69892
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(KeyValueField, {
70134
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(KeyValueField, {
69893
70135
  label: "Headers",
69894
70136
  value: request.headers,
69895
70137
  onChange: onHeadersChange,
@@ -69897,7 +70139,7 @@ var RequestPanel = import_react34.default.memo(({ request, onMethodChange, onUrl
69897
70139
  theme,
69898
70140
  onFocusChange: onInputFocus
69899
70141
  }, undefined, false, undefined, this),
69900
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(KeyValueField, {
70142
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(KeyValueField, {
69901
70143
  label: "Body",
69902
70144
  value: request.body,
69903
70145
  onChange: onBodyChange,
@@ -69905,10 +70147,10 @@ var RequestPanel = import_react34.default.memo(({ request, onMethodChange, onUrl
69905
70147
  theme,
69906
70148
  onFocusChange: onInputFocus
69907
70149
  }, undefined, false, undefined, this),
69908
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70150
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
69909
70151
  marginTop: 1,
69910
70152
  justifyContent: "center",
69911
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(SendButton, {
70153
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(SendButton, {
69912
70154
  onPress: onSend,
69913
70155
  loading,
69914
70156
  theme
@@ -69922,6 +70164,7 @@ var UI = () => {
69922
70164
  const [activeTab, setActiveTab] = import_react34.useState("request");
69923
70165
  const [request, setRequest] = import_react34.useState({ method: "GET", url: "", headers: "", body: "" });
69924
70166
  const [response, setResponse] = import_react34.useState({ statustext: "", status: "", headers: "", body: "", error: "" });
70167
+ const [metrics, setMetrics] = import_react34.useState(null);
69925
70168
  const [history, setHistory] = import_react34.useState([]);
69926
70169
  const [loading, setLoading] = import_react34.useState(false);
69927
70170
  const requestRef = import_react34.useRef(request);
@@ -69965,6 +70208,7 @@ var UI = () => {
69965
70208
  const responseTime = Date.now() - startTime;
69966
70209
  await historyManager.addEntry({ ...currentRequest }, res.status, responseTime);
69967
70210
  setHistory((await historyManager.loadHistory()).entries);
70211
+ setMetrics(res.metrics);
69968
70212
  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
70213
  setActiveTab("response");
69970
70214
  } catch (error) {
@@ -70015,89 +70259,89 @@ var UI = () => {
70015
70259
  const onHeadersChange = import_react34.useCallback((headers) => setRequest((r) => ({ ...r, headers })), []);
70016
70260
  const onBodyChange = import_react34.useCallback((body) => setRequest((r) => ({ ...r, body })), []);
70017
70261
  const historyUrls = Array.from(new Set(history.map((h) => h.url))).filter(Boolean);
70018
- return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70262
+ return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70019
70263
  padding: 1,
70020
70264
  flexDirection: "column",
70021
70265
  flexGrow: 1,
70022
70266
  children: [
70023
- showThemeSelector && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70267
+ showThemeSelector && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70024
70268
  flexDirection: "row",
70025
70269
  justifyContent: "center",
70026
70270
  marginBottom: 1,
70027
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ThemeSelector, {
70271
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(ThemeSelector, {
70028
70272
  theme,
70029
70273
  onThemeChange: (themeName) => {
70030
70274
  handleThemeChange(themes[themeName]);
70031
70275
  }
70032
70276
  }, undefined, false, undefined, this)
70033
70277
  }, undefined, false, undefined, this),
70034
- showExportDialog && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70278
+ showExportDialog && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70035
70279
  flexDirection: "row",
70036
70280
  justifyContent: "center",
70037
70281
  marginBottom: 1,
70038
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ExportDialog, {
70282
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(ExportDialog, {
70039
70283
  request,
70040
70284
  onClose: () => setShowExportDialog(false),
70041
70285
  theme: theme.colors
70042
70286
  }, undefined, false, undefined, this)
70043
70287
  }, undefined, false, undefined, this),
70044
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70288
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70045
70289
  alignSelf: "center",
70046
70290
  marginBottom: 1,
70047
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70291
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70048
70292
  color: theme.colors.accent,
70049
70293
  bold: true,
70050
70294
  children: `┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓`
70051
70295
  }, undefined, false, undefined, this)
70052
70296
  }, undefined, false, undefined, this),
70053
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70297
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70054
70298
  alignSelf: "center",
70055
70299
  marginBottom: 1,
70056
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70300
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70057
70301
  color: theme.colors.primary,
70058
70302
  bold: true,
70059
70303
  children: `┃ \uD83D\uDEF0️ Welcome to PostBoy — The Modern Terminal API Client ┃`
70060
70304
  }, undefined, false, undefined, this)
70061
70305
  }, undefined, false, undefined, this),
70062
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70306
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70063
70307
  alignSelf: "center",
70064
70308
  marginBottom: 1,
70065
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70309
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70066
70310
  color: theme.colors.accent,
70067
70311
  bold: true,
70068
70312
  children: `┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛`
70069
70313
  }, undefined, false, undefined, this)
70070
70314
  }, undefined, false, undefined, this),
70071
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70315
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70072
70316
  flexGrow: 1,
70073
70317
  children: [
70074
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70318
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70075
70319
  width: "40%",
70076
70320
  borderColor: theme.colors.muted,
70077
70321
  flexDirection: "column",
70078
70322
  marginRight: 1,
70079
70323
  children: [
70080
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70324
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70081
70325
  alignSelf: "center",
70082
70326
  marginBottom: 1,
70083
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70327
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70084
70328
  color: theme.colors.accent,
70085
70329
  bold: true,
70086
70330
  children: `┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓`
70087
70331
  }, undefined, false, undefined, this)
70088
70332
  }, undefined, false, undefined, this),
70089
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70333
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70090
70334
  borderTopColor: "grey",
70091
70335
  borderColor: theme.colors.secondary,
70092
70336
  paddingX: 1,
70093
70337
  alignSelf: "center",
70094
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70338
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70095
70339
  color: theme.colors.accent,
70096
70340
  bold: true,
70097
70341
  children: "\uD83D\uDCDC History"
70098
70342
  }, undefined, false, undefined, this)
70099
70343
  }, undefined, false, undefined, this),
70100
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70344
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70101
70345
  flexDirection: "column",
70102
70346
  flexGrow: 1,
70103
70347
  borderRightColor: "grey",
@@ -70106,22 +70350,43 @@ var UI = () => {
70106
70350
  borderLeft: false,
70107
70351
  borderBottom: false,
70108
70352
  paddingY: 1,
70109
- children: history.length === 0 ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70353
+ children: history.length === 0 ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70110
70354
  padding: 1,
70111
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70355
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70112
70356
  color: theme.colors.muted,
70113
70357
  children: "No requests yet..."
70114
70358
  }, undefined, false, undefined, this)
70115
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(HistoryList, {
70359
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(HistoryList, {
70116
70360
  history,
70117
70361
  onItemClick: handleHistoryClick,
70118
70362
  theme
70119
70363
  }, undefined, false, undefined, this)
70120
70364
  }, undefined, false, undefined, this),
70121
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
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),
70386
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70122
70387
  alignSelf: "center",
70123
70388
  marginBottom: 1,
70124
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70389
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70125
70390
  color: theme.colors.accent,
70126
70391
  bold: true,
70127
70392
  children: `┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛`
@@ -70129,36 +70394,36 @@ var UI = () => {
70129
70394
  }, undefined, false, undefined, this)
70130
70395
  ]
70131
70396
  }, undefined, true, undefined, this),
70132
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70397
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70133
70398
  width: "60%",
70134
70399
  borderColor: theme.colors.muted,
70135
70400
  padding: 1,
70136
70401
  flexDirection: "column",
70137
70402
  children: [
70138
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70403
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70139
70404
  alignSelf: "center",
70140
70405
  marginBottom: 1,
70141
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70406
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70142
70407
  color: theme.colors.accent,
70143
70408
  bold: true,
70144
70409
  children: `┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓`
70145
70410
  }, undefined, false, undefined, this)
70146
70411
  }, undefined, false, undefined, this),
70147
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Tabs, {
70412
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Tabs, {
70148
70413
  tabs,
70149
70414
  activeTab,
70150
70415
  onChange: setActiveTab,
70151
70416
  theme
70152
70417
  }, undefined, false, undefined, this),
70153
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70418
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70154
70419
  marginTop: 1,
70155
70420
  flexDirection: "column",
70156
70421
  flexGrow: 1,
70157
70422
  children: [
70158
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70423
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70159
70424
  display: activeTab === "request" ? "flex" : "none",
70160
70425
  flexGrow: 1,
70161
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(RequestPanel, {
70426
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(RequestPanel, {
70162
70427
  request,
70163
70428
  onMethodChange,
70164
70429
  onUrlChange,
@@ -70171,20 +70436,20 @@ var UI = () => {
70171
70436
  onInputFocus: setInputFocused
70172
70437
  }, undefined, false, undefined, this)
70173
70438
  }, undefined, false, undefined, this),
70174
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70439
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70175
70440
  display: activeTab === "response" ? "flex" : "none",
70176
70441
  flexGrow: 1,
70177
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ResponsePanel, {
70442
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(ResponsePanel, {
70178
70443
  response,
70179
70444
  theme
70180
70445
  }, undefined, false, undefined, this)
70181
70446
  }, undefined, false, undefined, this)
70182
70447
  ]
70183
70448
  }, undefined, true, undefined, this),
70184
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
70449
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
70185
70450
  alignSelf: "center",
70186
70451
  marginBottom: 1,
70187
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
70452
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
70188
70453
  color: theme.colors.accent,
70189
70454
  bold: true,
70190
70455
  children: `┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛`
@@ -70194,7 +70459,7 @@ var UI = () => {
70194
70459
  }, undefined, true, undefined, this)
70195
70460
  ]
70196
70461
  }, undefined, true, undefined, this),
70197
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Footer, {
70462
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Footer, {
70198
70463
  theme: theme.colors
70199
70464
  }, undefined, false, undefined, this)
70200
70465
  ]
@@ -70203,14 +70468,14 @@ var UI = () => {
70203
70468
  var ui_default = UI;
70204
70469
 
70205
70470
  // src/ui/app/app.tsx
70206
- var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
70471
+ var jsx_dev_runtime14 = __toESM(require_jsx_dev_runtime(), 1);
70207
70472
  function App2() {
70208
- return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(ui_default, {}, undefined, false, undefined, this);
70473
+ return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(ui_default, {}, undefined, false, undefined, this);
70209
70474
  }
70210
70475
 
70211
70476
  // src/commands/ui.tsx
70212
70477
  var import_chalk6 = __toESM(require_source(), 1);
70213
- var jsx_dev_runtime14 = __toESM(require_jsx_dev_runtime(), 1);
70478
+ var jsx_dev_runtime15 = __toESM(require_jsx_dev_runtime(), 1);
70214
70479
  var UIWrapper = () => {
70215
70480
  const { exit } = use_app_default();
70216
70481
  use_input_default((input) => {
@@ -70218,18 +70483,18 @@ var UIWrapper = () => {
70218
70483
  exit();
70219
70484
  }
70220
70485
  });
70221
- return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
70486
+ return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
70222
70487
  flexDirection: "column",
70223
70488
  children: [
70224
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
70489
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
70225
70490
  children: import_chalk6.default.cyanBright(`PostBoy \uD83D\uDC8C`)
70226
70491
  }, undefined, false, undefined, this),
70227
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(App2, {}, undefined, false, undefined, this)
70492
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(App2, {}, undefined, false, undefined, this)
70228
70493
  ]
70229
70494
  }, undefined, true, undefined, this);
70230
70495
  };
70231
70496
  var uiCommand = () => {
70232
- render_default(/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(UIWrapper, {}, undefined, false, undefined, this));
70497
+ render_default(/* @__PURE__ */ jsx_dev_runtime15.jsxDEV(UIWrapper, {}, undefined, false, undefined, this));
70233
70498
  };
70234
70499
 
70235
70500
  // src/commands/test.ts
@@ -70398,7 +70663,7 @@ async function mockApis() {
70398
70663
 
70399
70664
  // src/index.ts
70400
70665
  var program2 = new Command;
70401
- program2.version("1.3.7").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"));
70402
70667
  program2.command("run").description("Run a test API request").action(testCommand);
70403
70668
  program2.command("mock-list").description("List the mock API servers").action(mockApis);
70404
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.7",
3
+ "version": "1.3.9",
4
4
  "main": "dist/cli.js",
5
5
  "bin": {
6
6
  "postboy-tui": "dist/cli.js"