import { formatSize } from "@yaakapp-internal/lib/formatSize";
import type { Flow } from "@yaakapp-internal/proxy-lib";
import {
DetailsBanner,
formatMillis,
HeadersTable,
KeyValueRow,
KeyValueRows,
} from "@yaakapp-internal/ui";
import { useMemo } from "react";
import { EmptyState } from "./FlowBodyViewer";
const startedFormat = new Intl.DateTimeFormat("en-US", {
month: "short",
day: "numeric",
year: "numeric",
hour: "numeric",
minute: "2-digit",
second: "2-digit",
fractionalSecondDigits: 3,
timeZoneName: "short",
});
const bytesFormat = new Intl.NumberFormat("en-US");
export function FlowHeaders({ flow }: { flow: Flow }) {
const versions =
flow.upstreamHttpVersion == null
? `${flow.clientHttpVersion} from the app`
: `${flow.clientHttpVersion} from the app, ${flow.upstreamHttpVersion} to the server`;
return (
Info}>
{startedFormat.format(new Date(`${flow.startedAt}Z`))}
{flow.url}
{flow.remoteAddr ?? }
{versions}
{flow.elapsedMs == null ? (
) : flow.elapsedHeadersMs == null ? (
`${formatMillis(flow.elapsedMs)} in all`
) : (
`${formatMillis(flow.elapsedMs)} in all, headers after ${formatMillis(flow.elapsedHeadersMs)}`
)}
{formatSize(flow.requestSize)} sent, {formatSize(flow.responseSize)} received{" "}
({bytesFormat.format(flow.responseSize)} B)
);
}
export function FlowQuery({ flow }: { flow: Flow }) {
const params = useMemo(() => queryParams(flow.url), [flow.url]);
if (params.length === 0) {
return No query parameters;
}
return (
{params.map(([name, value], i) => (
// oxlint-disable-next-line react/no-array-index-key -- a name can repeat
{value}
))}
);
}
export function queryParams(url: string): [string, string][] {
try {
return [...new URL(url).searchParams.entries()];
} catch {
return [];
}
}
function Missing() {
return --;
}