@21st-sdk/nextjs 0.0.8

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.
package/src/server.ts ADDED
@@ -0,0 +1,62 @@
1
+ export interface TokenHandlerOptions {
2
+ /** Your an_sk_ API key — keep in process.env, never expose to client */
3
+ apiKey: string
4
+ /** Relay URL. Default: "https://relay.an.dev" */
5
+ relayUrl?: string
6
+ /** Token expiry. Default: "1h" */
7
+ expiresIn?: string
8
+ }
9
+
10
+ export interface ExchangeTokenOptions extends TokenHandlerOptions {
11
+ /** Agent slug to scope the token to */
12
+ agent?: string
13
+ /** User identifier for the token */
14
+ userId?: string
15
+ }
16
+
17
+ /** Exchange an an_sk_ API key for a short-lived JWT via the relay */
18
+ export async function exchangeToken(options: ExchangeTokenOptions) {
19
+ const {
20
+ apiKey,
21
+ relayUrl = "https://relay.an.dev",
22
+ expiresIn = "1h",
23
+ agent,
24
+ userId,
25
+ } = options
26
+
27
+ const res = await fetch(`${relayUrl}/v1/tokens`, {
28
+ method: "POST",
29
+ headers: {
30
+ "Content-Type": "application/json",
31
+ Authorization: `Bearer ${apiKey}`,
32
+ },
33
+ body: JSON.stringify({
34
+ userId,
35
+ agents: agent ? [agent] : undefined,
36
+ expiresIn,
37
+ }),
38
+ })
39
+
40
+ if (!res.ok) {
41
+ const err = await res.json().catch(() => ({ error: "Failed to exchange token" }))
42
+ throw new Error(err.error || `Token exchange failed: ${res.status}`)
43
+ }
44
+
45
+ return res.json() as Promise<{ token: string; expiresAt: string }>
46
+ }
47
+
48
+ /** Create a Next.js API route handler that exchanges an_sk_ keys for JWTs */
49
+ export function createAnTokenHandler(options: TokenHandlerOptions) {
50
+ return async function POST(req: Request) {
51
+ try {
52
+ const body = await req.json().catch(() => ({}))
53
+ const { agent, userId } = body as { agent?: string; userId?: string }
54
+
55
+ const data = await exchangeToken({ ...options, agent, userId })
56
+ return Response.json(data)
57
+ } catch (err) {
58
+ const message = err instanceof Error ? err.message : "Internal error"
59
+ return Response.json({ error: message }, { status: 500 })
60
+ }
61
+ }
62
+ }