diff --git a/.gitignore b/.gitignore index 25f53c7..0c70dec 100644 --- a/.gitignore +++ b/.gitignore @@ -44,4 +44,6 @@ next-env.d.ts public/robots.txt public/sitemap-0.xml -public/sitemap.xml \ No newline at end of file +public/sitemap.xml +# Sentry Config File +.env.sentry-build-plugin diff --git a/app/apis/[providerSlug]/[serviceSlug]/page.tsx b/app/apis/[providerSlug]/[serviceSlug]/page.tsx index 071d613..a85b337 100644 --- a/app/apis/[providerSlug]/[serviceSlug]/page.tsx +++ b/app/apis/[providerSlug]/[serviceSlug]/page.tsx @@ -9,12 +9,7 @@ import { Badge } from "@/components/ui/badge"; import JsonTreeContainer, { JsonTree } from "@/components/JsonTree"; import ApiButtons from "@/components/ApiButtons"; import VisitCounter from "@/components/VisitCounter"; - -interface ApiVersion { - version: string; - swaggerUrl: string; - swaggerYamlUrl: string; -} +import type { ApiVersion } from "@/types/api"; function stripMarkdown(markdown: string): string { return markdown @@ -37,85 +32,95 @@ export function getData( ? `${providerSlug}:${serviceSlug}` : providerSlug; + if (apiList[targetKey]) { + return processApiData(targetKey, apiList[targetKey]); + } + for (const key in apiList) { - if (apiList.hasOwnProperty(key) && key === targetKey) { - try { - const api = apiList[key]; - const versions = api.versions || {}; - const preferred = api.preferred || Object.keys(versions)[0] || ""; - const preferredVersion = versions[preferred] || {}; - const info = preferredVersion.info || {}; - const externalDocs = preferredVersion.externalDocs || {}; - const contact = info.contact || {}; - - const logo = { - url: info["x-logo"]?.url || "/assets/images/no-logo.svg", - backgroundColor: info["x-logo"]?.backgroundColor || null, - }; - - const externalUrl = - externalDocs.url || - contact.url || - (key.indexOf(".local") < 0 ? `https://${key.split(":")[0]}` : ""); - - let origUrl = ""; - if ( - info["x-origin"] && - Array.isArray(info["x-origin"]) && - info["x-origin"].length > 0 - ) { - origUrl = - info["x-origin"][0]?.url || preferredVersion.swaggerUrl || ""; - } else { - origUrl = preferredVersion.swaggerUrl || ""; - } - - const categories = info["x-apisguru-categories"] || []; - const tags = info["x-tags"] || []; - - const versionsArray = Object.entries(versions).map( - ([version, details]: [string, any]) => ({ - version, - swaggerUrl: details?.swaggerUrl || "", - swaggerYamlUrl: details?.swaggerYamlUrl || "", - }) - ); - - const description = info.description || "No description available"; - const cardDescription = marked(description); - const cardDescriptionPlain = stripMarkdown(description); - - return { - name: key, - preferred: api.preferred || "", - info, - api: { - swaggerUrl: preferredVersion.swaggerUrl || "", - swaggerYamlUrl: preferredVersion.swaggerYamlUrl || "", - }, - logo, - externalUrl, - origUrl, - versions: versionsArray, - cardDescription, - cardDescriptionPlain, - categories, - tags, - integrations: api.integrations || [], - updated: preferredVersion.updated || "", // Include the updated field - }; - } catch (error) { - console.error(`Error processing API ${key}:`, error); - return null; - } + if ( + apiList.hasOwnProperty(key) && + key.toLowerCase() === targetKey.toLowerCase() + ) { + return processApiData(key, apiList[key]); } } + console.warn( `No API found for provider: ${providerSlug}, service: ${serviceSlug}` ); return null; } +function processApiData(key: string, api: any) { + try { + const versions = api.versions || {}; + const preferred = api.preferred || Object.keys(versions)[0] || ""; + const preferredVersion = versions[preferred] || {}; + const info = preferredVersion.info || {}; + const externalDocs = preferredVersion.externalDocs || {}; + const contact = info.contact || {}; + + const logo = { + url: info["x-logo"]?.url || "/assets/images/no-logo.svg", + backgroundColor: info["x-logo"]?.backgroundColor || null, + }; + + const externalUrl = + externalDocs.url || + contact.url || + (key.indexOf(".local") < 0 ? `https://${key.split(":")[0]}` : ""); + + let origUrl = ""; + if ( + info["x-origin"] && + Array.isArray(info["x-origin"]) && + info["x-origin"].length > 0 + ) { + origUrl = info["x-origin"][0]?.url || preferredVersion.swaggerUrl || ""; + } else { + origUrl = preferredVersion.swaggerUrl || ""; + } + + const categories = info["x-apisguru-categories"] || []; + const tags = info["x-tags"] || []; + + const versionsArray = Object.entries(versions).map( + ([version, details]: [string, any]) => ({ + version, + swaggerUrl: details?.swaggerUrl || "", + swaggerYamlUrl: details?.swaggerYamlUrl || "", + }) + ); + + const description = info.description || "No description available"; + const cardDescription = marked(description); + const cardDescriptionPlain = stripMarkdown(description); + + return { + name: key, + preferred: api.preferred || "", + info, + api: { + swaggerUrl: preferredVersion.swaggerUrl || "", + swaggerYamlUrl: preferredVersion.swaggerYamlUrl || "", + }, + logo, + externalUrl, + origUrl, + versions: versionsArray, + cardDescription, + cardDescriptionPlain, + categories, + tags, + integrations: api.integrations || [], + updated: preferredVersion.updated || "", + }; + } catch (error) { + console.error(`Error processing API ${key}:`, error); + return null; + } +} + export async function generateStaticParams() { const apiList = list as Record; const params: { providerSlug: string; serviceSlug: string }[] = []; @@ -213,10 +218,7 @@ export default async function ApiPage({ return (
- +
diff --git a/app/global-error.tsx b/app/global-error.tsx new file mode 100644 index 0000000..9388e06 --- /dev/null +++ b/app/global-error.tsx @@ -0,0 +1,27 @@ +"use client"; + +import * as Sentry from "@sentry/nextjs"; +import NextError from "next/error"; +import { useEffect } from "react"; + +export default function GlobalError({ + error, +}: { + error: Error & { digest?: string }; +}) { + useEffect(() => { + Sentry.captureException(error); + }, [error]); + + return ( + + + {/* `NextError` is the default Next.js error page component. Its type + definition requires a `statusCode` prop. However, since the App Router + does not expose status codes for errors, we simply pass 0 to render a + generic error message. */} + + + + ); +} diff --git a/app/layout.tsx b/app/layout.tsx index 70ce2e8..958f5d9 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -68,19 +68,6 @@ export default function RootLayout({