@dutodev/cli 1.3.0 → 1.4.0

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.
@@ -76,6 +76,17 @@ function Detail({ record }) {
76
76
  record.replayOf
77
77
  ] }),
78
78
  record.error && /* @__PURE__ */ jsx(Text, { color: C.err, children: record.error }),
79
+ record.redirect && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
80
+ /* @__PURE__ */ jsx(Text, { color: C.signal, children: "\u21AA Location rewritten" }),
81
+ /* @__PURE__ */ jsxs(Text, { color: C.muted, children: [
82
+ " ",
83
+ record.redirect.from
84
+ ] }),
85
+ /* @__PURE__ */ jsxs(Text, { children: [
86
+ " \u2192 ",
87
+ record.redirect.to
88
+ ] })
89
+ ] }),
79
90
  /* @__PURE__ */ jsx(Section, { title: "Request", headers: record.reqHeaders, body: record.reqBody, truncated: record.reqTruncated, note: bodyNote(record, "req") }),
80
91
  /* @__PURE__ */ jsx(Section, { title: "Response", headers: record.resHeaders, body: record.resBody, truncated: record.resTruncated, note: bodyNote(record, "res") }),
81
92
  /* @__PURE__ */ jsxs(Text, { color: C.muted, children: [
@@ -169,6 +180,7 @@ function QrView({ tunnel, link, now }) {
169
180
  // src/ui/RequestList.tsx
170
181
  import { Box as Box3, Text as Text4 } from "ink";
171
182
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
183
+ var REWRITTEN = " \u21AA rewritten";
172
184
  function accessLabel(a) {
173
185
  if (!a) return null;
174
186
  if (a.kind === "user") return { text: a.user, color: C.muted };
@@ -180,7 +192,8 @@ function RequestList(props) {
180
192
  const start = Math.max(0, Math.min(selected - Math.floor(height / 2), records.length - height));
181
193
  const visible = records.slice(start, start + height);
182
194
  const accessW = Math.max(0, ...visible.map((r) => (accessLabel(r.access)?.text.length ?? -1) + 1));
183
- const pathW = Math.max(10, width - 54 - accessW);
195
+ const redirectW = visible.some((r) => r.redirect) ? REWRITTEN.length : 0;
196
+ const pathW = Math.max(10, width - 54 - accessW - redirectW);
184
197
  const title = props.filter ? `REQUESTS \xB7 filter: ${props.filter} ` : "REQUESTS ";
185
198
  return /* @__PURE__ */ jsxs4(Box3, { flexDirection: "column", children: [
186
199
  /* @__PURE__ */ jsx4(Text4, { color: C.muted, children: title + "\u2500".repeat(Math.max(0, width - title.length)) }),
@@ -204,7 +217,8 @@ function RequestList(props) {
204
217
  /* @__PURE__ */ jsx4(Text4, { color: C.muted, children: tail.padStart(7) }),
205
218
  " ",
206
219
  /* @__PURE__ */ jsx4(Text4, { color: C.muted, children: r.websocket ? "" : formatBytes(r.bytes).padStart(8) }),
207
- acc ? /* @__PURE__ */ jsx4(Text4, { color: acc.color, children: ` ${acc.text}` }) : null
220
+ acc ? /* @__PURE__ */ jsx4(Text4, { color: acc.color, children: ` ${acc.text}` }) : null,
221
+ r.redirect ? /* @__PURE__ */ jsx4(Text4, { color: C.signal, children: REWRITTEN }) : null
208
222
  ] }, r.id);
209
223
  })
210
224
  ] });
package/dist/index.js CHANGED
@@ -50,7 +50,7 @@ import { join as join5, relative } from "path";
50
50
  import cac from "cac";
51
51
 
52
52
  // src/version.ts
53
- var CLI_VERSION = "1.3.0";
53
+ var CLI_VERSION = "1.4.0";
54
54
 
55
55
  // src/api.ts
56
56
  var DutoApiError = class extends Error {
@@ -523,7 +523,7 @@ async function browserLogin(o) {
523
523
  const start = await api.startLogin({
524
524
  deviceId: o.deviceId,
525
525
  deviceName: hostname(),
526
- cliVersion: "1.3.0",
526
+ cliVersion: "1.4.0",
527
527
  nodeVersion: process.version,
528
528
  os: process.platform,
529
529
  arch: process.arch
@@ -755,6 +755,8 @@ button { font: inherit; color: inherit; background: none; border: 0; padding: 0;
755
755
  .row .dur { text-align: right; }
756
756
  .m { font-weight: 700; }
757
757
  .mut { color: ${C.muted}; }
758
+ .sig { color: ${C.signal}; }
759
+ .redirect { margin-top: 6px; display: grid; gap: 2px; }
758
760
  .empty { padding: 12px; color: ${C.muted}; }
759
761
  .detail { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
760
762
  .pane { flex: 1; }
@@ -891,7 +893,12 @@ function renderList() {
891
893
  row.setAttribute("role", "option");
892
894
  row.setAttribute("aria-selected", it.id === state.selected ? "true" : "false");
893
895
  row.dataset.id = String(it.id);
894
- row.appendChild(el("span", "mut", it.replayOf !== undefined ? "↻" : ""));
896
+ if (it.replayOf !== undefined) row.appendChild(el("span", "mut", "↻"));
897
+ else if (it.rewritten) {
898
+ var mark = el("span", "sig", "↪");
899
+ mark.title = "Location rewritten";
900
+ row.appendChild(mark);
901
+ } else row.appendChild(el("span", "mut", ""));
895
902
  if (multi) row.appendChild(el("span", "mut", it.tunnel));
896
903
  row.appendChild(el("span", "m", methodOf(it)));
897
904
  var p = el("span", "", it.path);
@@ -973,6 +980,13 @@ function renderDetail() {
973
980
  if (d.replayOf !== undefined) parts.push("↻ replay of #" + d.replayOf);
974
981
  head.appendChild(el("span", "mut", " · " + parts.join(" · ")));
975
982
  if (d.error) head.appendChild(el("div", "msg err", d.error));
983
+ if (d.redirect) {
984
+ var moved = el("div", "redirect");
985
+ moved.appendChild(el("div", "sig", "↪ Location rewritten"));
986
+ moved.appendChild(el("div", "mut", d.redirect.from));
987
+ moved.appendChild(el("div", "", "→ " + d.redirect.to));
988
+ head.appendChild(moved);
989
+ }
976
990
 
977
991
  var tabs = document.querySelectorAll(".tab");
978
992
  for (var i = 0; i < tabs.length; i++) {
@@ -1348,7 +1362,8 @@ function listItem(r) {
1348
1362
  startedAt: r.startedAt,
1349
1363
  websocket: r.websocket,
1350
1364
  ...r.replayOf !== void 0 && { replayOf: r.replayOf },
1351
- ...r.error !== void 0 && { error: r.error }
1365
+ ...r.error !== void 0 && { error: r.error },
1366
+ ...r.redirect !== void 0 && { rewritten: true }
1352
1367
  };
1353
1368
  }
1354
1369
  function detail(r, session) {
@@ -1364,6 +1379,7 @@ function detail(r, session) {
1364
1379
  return {
1365
1380
  ...listItem(r),
1366
1381
  edge: edgeOf(r.reqHeaders),
1382
+ redirect: r.redirect ?? null,
1367
1383
  reqHeaders: r.reqHeaders,
1368
1384
  resHeaders: r.resHeaders,
1369
1385
  reqBody: r.reqBody,
@@ -2138,7 +2154,12 @@ async function startProxy(o) {
2138
2154
  return;
2139
2155
  }
2140
2156
  if (route.host && route.rewriteRedirects !== false && typeof up.headers.location === "string") {
2141
- up.headers.location = rewriteLocation(up.headers.location, route.host, hostOf(req));
2157
+ const from = up.headers.location;
2158
+ const to = rewriteLocation(from, route.host, hostOf(req));
2159
+ if (to !== from) {
2160
+ up.headers.location = to;
2161
+ o.store.update(id, { redirect: { from, to } });
2162
+ }
2142
2163
  }
2143
2164
  res.writeHead(up.statusCode ?? 502, up.statusMessage, up.headers);
2144
2165
  trackResponse(id, started, up, reqCap);
@@ -2601,7 +2622,7 @@ function runPlain(session, out) {
2601
2622
  printed.add(r.id);
2602
2623
  const method = r.websocket ? "WS" : r.method;
2603
2624
  out(
2604
- `${formatTime(r.startedAt)} ${r.tunnel.padEnd(8)} ${method} ${r.path} ${paint(statusColor(r.status), String(r.status))} ${formatDuration(r.durationMs)} ${formatBytes(r.bytes)}`
2625
+ `${formatTime(r.startedAt)} ${r.tunnel.padEnd(8)} ${method} ${r.path} ${paint(statusColor(r.status), String(r.status))} ${formatDuration(r.durationMs)} ${formatBytes(r.bytes)}${r.redirect ? ` ${paint("signal", `\u21AA Location rewritten to ${r.redirect.to}`)}` : ""}`
2605
2626
  );
2606
2627
  }
2607
2628
  };
@@ -2682,7 +2703,7 @@ async function runSession(specs, source, flags) {
2682
2703
  }
2683
2704
  }
2684
2705
  if (wantsUi(flags)) {
2685
- const { runFullscreen } = await import("./fullscreen-AI6PC7RL.js");
2706
+ const { runFullscreen } = await import("./fullscreen-MZMQ6ADN.js");
2686
2707
  const code = await runFullscreen(session, specs, CLI_VERSION, inspector, inspectorError, update);
2687
2708
  await inspector?.close().catch(() => void 0);
2688
2709
  process.exit(code);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dutodev/cli",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Expose a local port at https://<name>-<user>.duto.dev with one command.",
5
5
  "license": "MIT",
6
6
  "type": "module",