import { gql, GraphQLClient } from "graphql-request"; import type { PageData } from "@/types/page"; import { getBaseUrl } from "./gr-client"; // import * as Sentry from "@sentry/nextjs"; const PageQuery = gql/* GraphQL */ ` query PageQuery($slug: String!) { pageBySlug(slug: $slug) { id title description } } `; const BlockQuery = gql/* GraphQL */ ` query BlockQuery($pageId: String!) { pageBlocks(pageId: $pageId) { __typename ... on TextBlockType { id markdown } ... on ChartBlockType { id title series { x y } } ... on SettingsBlockType { id category editable } ... on HeroBlockType { id title subtitle backgroundImage ctaText ctaLink } } } `; export async function fetchPage(slug: string, jwt?: string): Promise { // return Sentry.startSpan( // { // op: "http.client", // name: `GraphQL fetchPage: ${slug}`, // }, // async (span) => { // span.setAttribute("page.slug", slug); // span.setAttribute("auth.hasJwt", !!jwt); const client = new GraphQLClient(getBaseUrl()); if (jwt) { client.setHeader('Authorization', `Bearer ${jwt}`); } try { // 获取页面基本信息 const pageResponse: any = await client.request(PageQuery, { slug }); // const pageResponse: any = await Sentry.startSpan( // { // op: "http.client", // name: "GraphQL PageQuery", // }, // () => client.request(PageQuery, { slug }) // ); if (!pageResponse?.pageBySlug) { throw new Error('Page not found'); } // 获取页面块数据 const blocksResponse: any = await client.request(BlockQuery, { pageId: pageResponse.pageBySlug.id }); // const blocksResponse: any = await Sentry.startSpan( // { // op: "http.client", // name: "GraphQL BlockQuery", // }, // () => client.request(BlockQuery, { // pageId: pageResponse.pageBySlug.id // }) // ); if (!blocksResponse?.pageBlocks) { throw new Error('Failed to fetch page blocks'); } // span.setAttribute("page.blocksCount", blocksResponse.pageBlocks.length); // 合并数据 return { ...pageResponse.pageBySlug, blocks: blocksResponse.pageBlocks, }; } catch (error) { // Sentry.captureException(error, { // tags: { operation: 'fetchPage' }, // extra: { slug, hasJwt: !!jwt } // }); console.error('Failed to fetch page:', error); return null; } // } // ); } export async function getSiteConfigs() { // return Sentry.startSpan( // { // op: "http.client", // name: "Fetch Site Configs", // }, // async (span) => { try { const baseUrl = process.env.NEXTAUTH_URL || 'http://localhost:3000'; // span.setAttribute("api.baseUrl", baseUrl); const siteConfigs = await fetch(`${baseUrl}/api/site`, { headers: { 'Content-Type': 'application/json', }, // Add timeout to prevent hanging during build signal: AbortSignal.timeout(5000) }); // span.setAttribute("http.status_code", siteConfigs.status); if (!siteConfigs.ok) { const error = new Error(`Failed to fetch site configs: ${siteConfigs.status} ${siteConfigs.statusText}`); // Sentry.captureException(error, { // tags: { operation: 'getSiteConfigs' }, // extra: { status: siteConfigs.status, statusText: siteConfigs.statusText } // }); console.warn(`Failed to fetch site configs: ${siteConfigs.status} ${siteConfigs.statusText}`); return getDefaultSiteConfigs(); } const data = await siteConfigs.json(); // span.setAttribute("configs.count", data.length); return data; } catch (error) { // Sentry.captureException(error, { // tags: { operation: 'getSiteConfigs' } // }); console.warn('Failed to fetch site configs, using defaults:', error); return getDefaultSiteConfigs(); } // } // ); } function getDefaultSiteConfigs() { return [ { key: 'site.name', value: 'MosaicMap' }, { key: 'site.description', value: 'Interactive map visualization with custom WebGL timeline' } ]; }