Skip to content

Commit 0f94f6f

Browse files
committed
refactor(scan): remove legacy discovery preview
1 parent e70ea31 commit 0f94f6f

17 files changed

Lines changed: 746 additions & 2722 deletions

File tree

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
"use client";
2+
3+
import { useMemo, useState } from "react";
4+
5+
import { Loader2 } from "lucide-react";
6+
import z from "zod";
7+
8+
import { Card, CardContent } from "@/components/ui/card";
9+
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field";
10+
import {
11+
InputGroup,
12+
InputGroupAddon,
13+
InputGroupInput,
14+
} from "@/components/ui/input-group";
15+
import { useDebounce } from "@/hooks/use-debounce";
16+
import { api } from "@/trpc/client";
17+
18+
function normalizeInput(value: string): string {
19+
const trimmed = value.trim();
20+
if (!trimmed || trimmed.includes("://")) return trimmed;
21+
return `https://${trimmed}`;
22+
}
23+
24+
function getPath(resourceUrl: string): string {
25+
try {
26+
const url = new URL(resourceUrl);
27+
return decodeURIComponent(`${url.pathname}${url.search}`);
28+
} catch {
29+
return resourceUrl;
30+
}
31+
}
32+
33+
export function TryDiscovery() {
34+
const [url, setUrl] = useState("");
35+
const debouncedUrl = useDebounce(url, 500);
36+
const normalizedUrl = useMemo(
37+
() => normalizeInput(debouncedUrl),
38+
[debouncedUrl]
39+
);
40+
const isValidUrl = z.url().safeParse(normalizedUrl).success;
41+
const origin = isValidUrl ? new URL(normalizedUrl).origin : null;
42+
43+
const discovery = api.public.resources.checkDiscovery.useQuery(
44+
{ origin: origin!, bustCache: false },
45+
{
46+
enabled: origin !== null && debouncedUrl === url,
47+
retry: false,
48+
staleTime: 30_000,
49+
}
50+
);
51+
52+
const resources = discovery.data?.found ? discovery.data.resources : [];
53+
const isLoading =
54+
isValidUrl && debouncedUrl === url && discovery.isPending && url.length > 0;
55+
56+
return (
57+
<div className="flex flex-col gap-4" data-not-typeset>
58+
<Card>
59+
<CardContent>
60+
<Field>
61+
<FieldLabel htmlFor="discovery-url">
62+
Origin or endpoint URL
63+
</FieldLabel>
64+
<InputGroup>
65+
<InputGroupInput
66+
id="discovery-url"
67+
type="text"
68+
placeholder="https://yourdomain.com"
69+
value={url}
70+
onChange={(event) => {
71+
setUrl(event.target.value);
72+
}}
73+
/>
74+
{isLoading ? (
75+
<InputGroupAddon align="inline-end">
76+
<Loader2 className="size-4 animate-spin text-muted-foreground" />
77+
</InputGroupAddon>
78+
) : null}
79+
</InputGroup>
80+
<FieldDescription>
81+
Runs discovery against the origin and lists the routes x402scan
82+
resolves. Nothing is registered.
83+
</FieldDescription>
84+
</Field>
85+
</CardContent>
86+
</Card>
87+
88+
{isValidUrl && discovery.isSuccess && resources.length > 0 ? (
89+
<Card>
90+
<CardContent>
91+
<p className="mb-2 type-label">
92+
Found {resources.length} endpoint
93+
{resources.length === 1 ? "" : "s"}
94+
</p>
95+
<ul className="space-y-1 text-muted-foreground">
96+
{resources.slice(0, 10).map((resource) => (
97+
<li key={`${resource.method ?? "GET"}-${resource.url}`}>
98+
<code className="type-compact-code">
99+
<strong className="text-foreground">
100+
{resource.method ?? "GET"}
101+
</strong>{" "}
102+
{getPath(resource.url)}
103+
</code>
104+
</li>
105+
))}
106+
{resources.length > 10 ? (
107+
<li className="text-muted-foreground/60">
108+
...and {resources.length - 10} more
109+
</li>
110+
) : null}
111+
</ul>
112+
</CardContent>
113+
</Card>
114+
) : null}
115+
116+
{isValidUrl &&
117+
discovery.isSuccess &&
118+
(!discovery.data?.found || resources.length === 0) ? (
119+
<p className="type-supporting-body text-muted-foreground">
120+
{discovery.data?.found
121+
? "No discoverable endpoints found at this origin."
122+
: (discovery.data?.error ??
123+
"No discoverable endpoints found at this origin.")}
124+
</p>
125+
) : null}
126+
127+
{isValidUrl && discovery.isError ? (
128+
<p className="type-supporting-body text-destructive">
129+
Discovery failed. Check the URL and try again.
130+
</p>
131+
) : null}
132+
</div>
133+
);
134+
}

apps/scan/src/app/(app)/(home)/discovery/quickstart/page.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import Link from "next/link";
22
import { ArrowRight, Plus } from "lucide-react";
33

4+
import { TryDiscovery } from "@/app/(app)/(home)/_components/try-discovery";
45
import { DiscoveryPageHeader } from "@/app/(app)/(home)/discovery/_components/page-header";
56
import { QuickstartPromptCard } from "@/app/(app)/(home)/discovery/quickstart/_components/prompt-card";
6-
import { TryDiscovery } from "@/app/(app)/(home)/integration-spec/try-discovery";
77
import { buttonVariants } from "@/components/ui/button";
88

99
export const metadata = {

apps/scan/src/app/(app)/(home)/integration-spec/page.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import Link from "next/link";
22
import { Plus } from "lucide-react";
33

4+
import { TryDiscovery } from "@/app/(app)/(home)/_components/try-discovery";
45
import { CopyPageDropdown } from "@/app/(app)/(home)/discovery/_components/copy-page-dropdown";
56
import { DiscoveryDocActions } from "@/app/(app)/(home)/discovery/_components/doc-actions";
67
import { DiscoveryPageHeader } from "@/app/(app)/(home)/discovery/_components/page-header";
78
import { AgentPromptPreview } from "@/app/(app)/(home)/integration-spec/agent-prompt-preview";
89
import { CopyForAgentsButton } from "@/app/(app)/(home)/integration-spec/copy-for-agents-button";
910
import { PAGE_MARKDOWN } from "@/app/(app)/(home)/integration-spec/_content/markdown";
1011
import { SPEC_PROMPT } from "@/app/(app)/(home)/integration-spec/_content/prompt";
11-
import { TryDiscovery } from "@/app/(app)/(home)/integration-spec/try-discovery";
1212
import { buttonVariants } from "@/components/ui/button";
1313
import { env } from "@/env";
1414

apps/scan/src/app/(app)/(home)/integration-spec/try-discovery.tsx

Lines changed: 0 additions & 126 deletions
This file was deleted.

0 commit comments

Comments
 (0)