Skip to content

Commit

Permalink
fix: properly handle redirects (#423)
Browse files Browse the repository at this point in the history
* fix(debugger): show examples only if they are available

* feat(debugger): show response headers

* fix: properly handle redirects

* feat: show previous frame when redirected
  • Loading branch information
michalkvasnicak authored Jun 11, 2024
1 parent ce837a1 commit b06b5b3
Show file tree
Hide file tree
Showing 16 changed files with 367 additions and 150 deletions.
5 changes: 5 additions & 0 deletions .changeset/cold-bulldogs-scream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@frames.js/debugger": patch
---

feat(debugger): show response headers
5 changes: 5 additions & 0 deletions .changeset/fast-shirts-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@frames.js/render": patch
---

fix(@frames.js/render): properly handle redirects
5 changes: 5 additions & 0 deletions .changeset/nasty-paws-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@frames.js/debugger": patch
---

fix(debugger): show examples links only if examples are available
5 changes: 5 additions & 0 deletions .changeset/rare-olives-stare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@frames.js/debugger": patch
---

fix(debugger): properly handle redirects
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ export type ExampleItem = {
};

type FrameDebuggerExamplesSectionProps = {
examples: ExampleItem[] | null;
examples: ExampleItem[];
};

export function FrameDebuggerExamplesSection({
examples,
}: FrameDebuggerExamplesSectionProps) {
if (!examples || examples.length === 0) {
if (examples.length === 0) {
return null;
}

Expand Down
135 changes: 135 additions & 0 deletions packages/debugger/app/components/frame-debugger-request-details.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import type { FramesStackItem } from "@frames.js/render";
import { JSONTree } from "react-json-tree";
import {
Table,
TableBody,
TableCell,
TableHead,
TableRow,
} from "@/components/table";
import { urlSearchParamsToObject } from "../utils/url-search-params-to-object";

type FrameDebuggerRequestDetailsProps = {
frameStackItem: FramesStackItem;
};

export function FrameDebuggerRequestDetails({
frameStackItem,
}: FrameDebuggerRequestDetailsProps) {
return (
<>
<h2 className="my-4 text-muted-foreground font-semibold text-sm">
Request
</h2>
<Table>
<TableBody>
<TableRow>
<TableHead>URL</TableHead>
<TableCell className="w-full">{frameStackItem.url}</TableCell>
</TableRow>
<TableRow>
<TableHead>Method</TableHead>
<TableCell>{frameStackItem.request.method}</TableCell>
</TableRow>
<TableRow>
<TableHead>Query Params</TableHead>
<TableCell>
<JSONTree
data={urlSearchParamsToObject(
new URL(frameStackItem.url).searchParams
)}
invertTheme
theme="default"
></JSONTree>
</TableCell>
</TableRow>
{frameStackItem.request.method === "POST" ? (
<TableRow>
<TableHead>Payload</TableHead>
<TableCell>
<JSONTree
data={frameStackItem.requestDetails.body}
invertTheme
theme="default"
></JSONTree>
</TableCell>
</TableRow>
) : null}
</TableBody>
</Table>
{frameStackItem.status !== "pending" ? (
<>
<h2 className="my-4 text-muted-foreground font-semibold text-sm">
Response
</h2>
<Table>
<TableBody>
<TableRow>
<TableHead>Response status</TableHead>
<TableCell className="w-full">
{frameStackItem.responseStatus}
</TableCell>
</TableRow>
{frameStackItem.response && (
<TableRow>
<TableHead>Response headers</TableHead>
<TableCell className="w-full">
<JSONTree
data={Object.fromEntries(
frameStackItem.response.headers.entries()
)}
theme="default"
invertTheme
></JSONTree>
</TableCell>
</TableRow>
)}
{"frame" in frameStackItem ? (
<TableRow>
<TableHead>Frame Response</TableHead>
<TableCell>
<JSONTree
data={frameStackItem.frame}
invertTheme
theme="default"
></JSONTree>
</TableCell>
</TableRow>
) : (
<TableRow>
<TableHead>Response</TableHead>
<TableCell>
<JSONTree
data={
frameStackItem.status === "message"
? {
message: frameStackItem.message,
}
: frameStackItem.responseBody
}
theme="default"
invertTheme
></JSONTree>
</TableCell>
</TableRow>
)}
{frameStackItem.status === "requestError" &&
!!frameStackItem.requestError && (
<TableRow>
<TableHead>Error</TableHead>
<TableCell>
<JSONTree
data={frameStackItem.requestError}
theme="default"
invertTheme
></JSONTree>
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</>
) : null}
</>
);
}
147 changes: 17 additions & 130 deletions packages/debugger/app/components/frame-debugger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,7 @@ import {
defaultTheme,
} from "@frames.js/render";
import { FrameImageNext } from "@frames.js/render/next";
import { JSONTree } from "react-json-tree";
import {
Table,
TableBody,
TableCell,
TableHead,
TableRow,
} from "@/components/table";
import { Table, TableBody, TableCell, TableRow } from "@/components/table";
import {
AlertTriangle,
BanIcon,
Expand All @@ -40,6 +33,7 @@ import {
LoaderIcon,
RefreshCwIcon,
XCircle,
ExternalLinkIcon,
} from "lucide-react";
import { Card, CardContent } from "@/components/ui/card";
import { MockHubConfig } from "./mock-hub-config";
Expand All @@ -58,26 +52,13 @@ import { useRouter } from "next/navigation";
import { WithTooltip } from "./with-tooltip";
import { DebuggerConsole } from "./debugger-console";
import { FrameDebuggerLinksSidebarSection } from "./frame-debugger-links-sidebar-section";
import { FrameDebuggerRequestDetails } from "./frame-debugger-request-details";
import { urlSearchParamsToObject } from "../utils/url-search-params-to-object";

type FrameDiagnosticsProps = {
stackItem: FramesStackItem;
};

function paramsToObject(entries: IterableIterator<[string, string]>): object {
const result: Record<string, any> = {};
for (const [key, value] of entries) {
// each 'entry' is a [key, value] tupple
if (value.startsWith("{")) {
try {
result[key] = JSON.parse(value);
continue;
} catch (err) {}
}
result[key] = value;
}
return result;
}

function isPropertyExperimental([key, value]: [string, string]) {
// tx is experimental
return false;
Expand All @@ -103,6 +84,10 @@ function FrameDiagnostics({ stackItem }: FrameDiagnosticsProps) {
return { validProperties, invalidProperties, isValid: true };
}

if (stackItem.status === "doneRedirect") {
return { validProperties, invalidProperties, isValid: true };
}

const result = stackItem.frameResult;

// we need to check validation errors first because getFrame incorrectly return a value for a key even if it's invalid
Expand Down Expand Up @@ -271,6 +256,10 @@ const FramesRequestCardContentIcon: React.FC<{
}
}

if (stackItem.status === "doneRedirect") {
return <ExternalLinkIcon size={20} color="green" />;
}

if (stackItem.frameResult?.status === "failure") {
return <XCircle size={20} color="red" />;
}
Expand Down Expand Up @@ -342,8 +331,8 @@ const FramesRequestCardContent: React.FC<{
}}
>
{JSON.stringify(
paramsToObject(
new URL(frameStackItem.url).searchParams.entries()
urlSearchParamsToObject(
new URL(frameStackItem.url).searchParams
),
null,
2
Expand Down Expand Up @@ -626,111 +615,9 @@ export const FrameDebugger = React.forwardRef<
></DebuggerConsole>
</TabsContent>
<TabsContent className="overflow-y-auto" value="request">
<h2 className="my-4 text-muted-foreground font-semibold text-sm">
Request
</h2>
<Table>
<TableBody>
<TableRow>
<TableHead>URL</TableHead>
<TableCell className="w-full">
{currentFrameStackItem.url}
</TableCell>
</TableRow>
<TableRow>
<TableHead>Method</TableHead>
<TableCell>
{currentFrameStackItem.request.method}
</TableCell>
</TableRow>
<TableRow>
<TableHead>Query Params</TableHead>
<TableCell>
<JSONTree
data={paramsToObject(
new URL(
currentFrameStackItem.url
).searchParams.entries()
)}
invertTheme
theme="default"
></JSONTree>
</TableCell>
</TableRow>
{currentFrameStackItem.request.method === "POST" ? (
<TableRow>
<TableHead>Payload</TableHead>
<TableCell>
<JSONTree
data={currentFrameStackItem.requestDetails.body}
invertTheme
theme="default"
></JSONTree>
</TableCell>
</TableRow>
) : null}
</TableBody>
</Table>
{currentFrameStackItem.status !== "pending" ? (
<>
<h2 className="my-4 text-muted-foreground font-semibold text-sm">
Response
</h2>
<Table>
<TableBody>
<TableRow>
<TableHead>Response status</TableHead>
<TableCell className="w-full">
{currentFrameStackItem.responseStatus}
</TableCell>
</TableRow>
{"frame" in currentFrameStackItem ? (
<TableRow>
<TableHead>Frame Response</TableHead>
<TableCell>
<JSONTree
data={currentFrameStackItem.frame}
invertTheme
theme="default"
></JSONTree>
</TableCell>
</TableRow>
) : (
<TableRow>
<TableHead>Response</TableHead>
<TableCell>
<JSONTree
data={
currentFrameStackItem.status === "message"
? {
message:
currentFrameStackItem.message,
}
: currentFrameStackItem.responseBody
}
theme="default"
invertTheme
></JSONTree>
</TableCell>
</TableRow>
)}
{currentFrameStackItem.status === "requestError" &&
!!currentFrameStackItem.requestError && (
<TableRow>
<TableHead>Error</TableHead>
<TableCell>
<JSONTree
data={currentFrameStackItem.requestError}
theme="default"
invertTheme
></JSONTree>
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</>
) : null}
<FrameDebuggerRequestDetails
frameStackItem={currentFrameStackItem}
></FrameDebuggerRequestDetails>
</TabsContent>
<TabsContent className="overflow-y-auto" value="meta">
{currentFrameStackItem.status === "done" ? (
Expand Down
1 change: 0 additions & 1 deletion packages/debugger/app/debugger-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import {
import { useLensIdentity } from "./hooks/use-lens-identity";
import { useLensFrameContext } from "./hooks/use-lens-context";
import { ProfileSelectorModal } from "./components/lens-profile-select";
import { FrameDebuggerExamplesSection } from "./components/frame-debugger-examples-section";

const FALLBACK_URL =
process.env.NEXT_PUBLIC_DEBUGGER_DEFAULT_URL || "http://localhost:3000";
Expand Down
Loading

0 comments on commit b06b5b3

Please sign in to comment.