UNPKG

bigblocks

Version:

Complete Bitcoin UI component library - authentication, social, wallet, market, inscriptions, and blockchain interactions for React

185 lines (184 loc) 6.73 kB
// BigBlocks Next.js Adapter // Wraps the framework-agnostic core with Next.js specific functionality // Works without Next.js installed (graceful fallbacks) import { createBigBlocksAuth, } from "../bigblocks-core.js"; // Mock NextResponse class for when Next.js isn't available class MockNextResponse { body; init; constructor(body, init) { this.body = body; this.init = init; } static next() { return new globalThis.Response("", { status: 200 }); } static json(data, init) { return new globalThis.Response(JSON.stringify(data), { ...init, headers: { "Content-Type": "application/json", ...init?.headers, }, }); } } // Safe dynamic import helper that evades bundler analysis async function tryImportNext() { try { // Construct the import path to avoid bundler static analysis const nextModule = "next"; const serverPath = "server"; const importPath = `${nextModule}/${serverPath}`; // @ts-ignore - Next.js is an optional peer dependency const importFn = new Function("path", "return import(path)"); return await importFn(importPath); } catch { return { NextResponse: MockNextResponse }; } } /** * Creates BigBlocks auth handlers for Next.js * Works with both Pages Router (/pages/api) and App Router (/app/api) */ export function createNextJSBigBlocks(options = {}) { const core = createBigBlocksAuth(options); // App Router handler (app/api/auth/[...bigblocks]/route.ts) const handler = async (request) => { try { // Convert NextRequest to standard Request if needed let webRequest; if ("nextUrl" in request) { // NextRequest webRequest = new globalThis.Request(request.url, { method: request.method, headers: request.headers, body: request.body, }); } else { // Already a standard Request webRequest = request; } const response = await core.handler(webRequest); // Try to use NextResponse if available, fallback to Response try { const { NextResponse } = await tryImportNext(); return new NextResponse(response.body, { status: response.status, statusText: response.statusText, headers: response.headers, }); } catch { // Fallback to standard Response return response; } } catch (error) { console.error("BigBlocks Next.js handler error:", error); return new globalThis.Response(JSON.stringify({ error: "Internal server error" }), { status: 500, headers: { "Content-Type": "application/json" }, }); } }; // Pages Router handlers (/pages/api/auth/[...bigblocks].ts) const pageHandler = async (req, res) => { try { // Convert Next.js req/res to standard Request const protocol = req.headers["x-forwarded-proto"] || "http"; const host = req.headers.host || "localhost"; const url = new URL(req.url || "/", `${protocol}://${host}`); const body = req.method !== "GET" && req.method !== "HEAD" ? JSON.stringify(req.body) : null; const webRequest = new globalThis.Request(url.toString(), { method: req.method, headers: req.headers, body, }); const response = await core.handler(webRequest); const responseBody = await response.text(); // Set response res.status(response.status); // Copy headers response.headers.forEach((value, key) => { res.setHeader(key, value); }); res.send(responseBody); } catch (error) { console.error("BigBlocks Pages API error:", error); res.status(500).json({ error: "Internal server error" }); } }; // Middleware helper for authentication const middleware = async (request) => { try { const session = await core.api.getSession(request.headers); if (!session) { return new globalThis.Response(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "Content-Type": "application/json" }, }); } // Try to use NextResponse if available try { const { NextResponse } = await tryImportNext(); const response = NextResponse.next(); response.headers.set("x-user-id", session.user.id); response.headers.set("x-user-address", session.user.address); return response; } catch { // Fallback to standard Response const response = new globalThis.Response("", { status: 200 }); response.headers.set("x-user-id", session.user.id); response.headers.set("x-user-address", session.user.address); return response; } } catch (error) { console.error("BigBlocks middleware error:", error); return new globalThis.Response(JSON.stringify({ error: "Internal server error" }), { status: 500, headers: { "Content-Type": "application/json" }, }); } }; return { // App Router (recommended) GET: handler, POST: handler, PUT: handler, DELETE: handler, // Pages Router (legacy) handler: pageHandler, // Middleware middleware, // Direct API access api: core.api, // Config options: core.options, }; } // Convenience exports for different Next.js patterns export const createAppRouterHandlers = (options) => { const handlers = createNextJSBigBlocks(options); return { GET: handlers.GET, POST: handlers.POST, PUT: handlers.PUT, DELETE: handlers.DELETE, }; }; export const createPagesAPIHandler = (options) => { const { handler } = createNextJSBigBlocks(options); return handler; }; export const createNextMiddleware = (options) => { const { middleware } = createNextJSBigBlocks(options); return middleware; };