import { json, type LoaderFunction, type LoaderFunctionArgs } from '@remix-run/cloudflare'; /** * Diagnostic API for troubleshooting connection issues */ interface AppContext { env?: { GITHUB_ACCESS_TOKEN?: string; NETLIFY_TOKEN?: string; }; } export const loader: LoaderFunction = async ({ request, context }: LoaderFunctionArgs & { context: AppContext }) => { // Get environment variables const envVars = { hasGithubToken: Boolean(process.env.GITHUB_ACCESS_TOKEN || context.env?.GITHUB_ACCESS_TOKEN), hasNetlifyToken: Boolean(process.env.NETLIFY_TOKEN || context.env?.NETLIFY_TOKEN), nodeEnv: process.env.NODE_ENV, }; // Check cookies const cookieHeader = request.headers.get('Cookie') || ''; const cookies = cookieHeader.split(';').reduce( (acc, cookie) => { const [key, value] = cookie.trim().split('='); if (key) { acc[key] = value; } return acc; }, {} as Record, ); const hasGithubTokenCookie = Boolean(cookies.githubToken); const hasGithubUsernameCookie = Boolean(cookies.githubUsername); const hasNetlifyCookie = Boolean(cookies.netlifyToken); // Get local storage status (this can only be checked client-side) const localStorageStatus = { explanation: 'Local storage can only be checked on the client side. Use browser devtools to check.', githubKeysToCheck: ['github_connection'], netlifyKeysToCheck: ['netlify_connection'], }; // Check if CORS might be an issue const corsStatus = { headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, }; // Check if API endpoints are reachable const apiEndpoints = { githubUser: '/api/system/git-info?action=getUser', githubRepos: '/api/system/git-info?action=getRepos', githubOrgs: '/api/system/git-info?action=getOrgs', githubActivity: '/api/system/git-info?action=getActivity', gitInfo: '/api/system/git-info', }; // Test GitHub API connectivity let githubApiStatus; try { const githubResponse = await fetch('https://api.github.com/zen', { method: 'GET', headers: { Accept: 'application/vnd.github.v3+json', }, }); githubApiStatus = { isReachable: githubResponse.ok, status: githubResponse.status, statusText: githubResponse.statusText, }; } catch (error) { githubApiStatus = { isReachable: false, error: error instanceof Error ? error.message : String(error), }; } // Test Netlify API connectivity let netlifyApiStatus; try { const netlifyResponse = await fetch('https://api.netlify.com/api/v1/', { method: 'GET', }); netlifyApiStatus = { isReachable: netlifyResponse.ok, status: netlifyResponse.status, statusText: netlifyResponse.statusText, }; } catch (error) { netlifyApiStatus = { isReachable: false, error: error instanceof Error ? error.message : String(error), }; } // Provide technical details about the environment const technicalDetails = { serverTimestamp: new Date().toISOString(), userAgent: request.headers.get('User-Agent'), referrer: request.headers.get('Referer'), host: request.headers.get('Host'), method: request.method, url: request.url, }; // Return diagnostics return json( { status: 'success', environment: envVars, cookies: { hasGithubTokenCookie, hasGithubUsernameCookie, hasNetlifyCookie, }, localStorage: localStorageStatus, apiEndpoints, externalApis: { github: githubApiStatus, netlify: netlifyApiStatus, }, corsStatus, technicalDetails, }, { headers: corsStatus.headers, }, ); };