import { existsSync } from "node:fs"; import path from "node:path"; import type { Metadata } from "next"; import { redirect } from "next/navigation"; import { auth } from "@/app/(auth)/auth"; import { PascalEditorFrame } from "@/components/pascal-editor/pascal-editor-frame"; import { getSiteSettings } from "@/lib/db/queries"; const LOCAL_PASCAL_EDITOR_SRC = "/vendor/pascal-editor/index.html"; const DEV_SELF_HOSTED_PASCAL_EDITOR_SRC = "http://localhost:3002"; export const dynamic = "force-dynamic"; export const metadata: Metadata = { title: "建筑编辑", }; export const runtime = "nodejs"; export default async function PascalEditorPage() { const [session, siteSettings] = await Promise.all([auth(), getSiteSettings()]); if (!session?.user?.id) { redirect("/login?callbackUrl=%2Fpascal-editor"); } const configuredSrc = normalizePascalEditorUrl( process.env.NEXT_PUBLIC_PASCAL_EDITOR_URL || process.env.PASCAL_EDITOR_URL || "" ); const hasLocalEditor = existsSync( path.join(process.cwd(), "public/vendor/pascal-editor/index.html") ); const shouldUseDevSelfHosted = process.env.NODE_ENV === "development" && !configuredSrc && !hasLocalEditor; const hasDevSelfHostedEditor = shouldUseDevSelfHosted && (await isHttpUrlReachable(DEV_SELF_HOSTED_PASCAL_EDITOR_SRC)); const src = configuredSrc || (hasLocalEditor ? LOCAL_PASCAL_EDITOR_SRC : "") || (hasDevSelfHostedEditor ? DEV_SELF_HOSTED_PASCAL_EDITOR_SRC : "") || LOCAL_PASCAL_EDITOR_SRC; const isReady = Boolean(configuredSrc || hasLocalEditor || hasDevSelfHostedEditor); return ( ); } function normalizePascalEditorUrl(value: string) { const trimmed = value.trim(); if (!trimmed) { return ""; } if (trimmed.startsWith("/")) { return trimmed; } try { const url = new URL(trimmed); return url.protocol === "http:" || url.protocol === "https:" ? url.toString() : ""; } catch { return ""; } } async function isHttpUrlReachable(value: string) { try { const response = await fetch(value, { cache: "no-store", signal: AbortSignal.timeout(3000), }); return response.ok; } catch { return false; } }