[READ-ONLY] Mirror of https://github.com/mrgnw/ananas. learn multiple languages at once ananas.xcc.es
0

Configure Feed

Select the types of activity you want to include in your feed.

debug all headers

+69 -171
+31 -143
src/lib/components/DebugButton.svelte
··· 9 9 title?: string; 10 10 }>(); 11 11 12 - const title = $derived(props.title ?? 'Debug Information'); 12 + const title = $derived(props.title ?? 'Raw Headers'); 13 13 const data = $derived(props.data ?? {}); 14 14 15 - // Log received data on mount 15 + // Enable this for additional debugging 16 16 onMount(() => { 17 - console.log('[DEBUG BUTTON] Received data keys:', Object.keys(data)); 18 - if (data.headers) { 19 - console.log('[DEBUG BUTTON] Headers available:', Object.keys(data.headers).length); 20 - } else { 21 - console.log('[DEBUG BUTTON] No headers object found in data'); 22 - } 23 - }); 24 - 25 - // Determine which headers object to use (supporting both data.headers and data.allHeaders) 26 - const headers = $derived(() => { 27 - if (data.headers) return data.headers; 28 - if (data.allHeaders) return data.allHeaders; 29 - return null; 17 + console.log('[DEBUG BUTTON] Received data:', data); 18 + console.log('[DEBUG BUTTON] Data keys:', Object.keys(data)); 19 + console.log('[DEBUG BUTTON] Has allHeaders?', !!data.allHeaders); 30 20 }); 31 21 32 - // Add fallback debugging info if headers are missing 33 - const debugInfo = $derived(() => { 34 - return { 35 - dataAvailable: Object.keys(data).length > 0, 36 - headersAvailable: headers ? Object.keys(headers).length : 0, 37 - timestamp: new Date().toISOString() 38 - }; 39 - }); 22 + // Get headers from top-level allHeaders property 23 + const allHeaders = $derived(data.allHeaders || {}); 40 24 41 - // Check if we have Cloudflare-specific headers 42 - const hasCfHeaders = $derived(() => { 43 - if (!headers) return false; 44 - return Object.keys(headers).some(key => key.startsWith('cf-')); 45 - }); 25 + // Count headers for display 26 + const headerCount = $derived(Object.keys(allHeaders).length); 46 27 47 - function formatValue(value) { 48 - if (value === null) return 'null'; 49 - if (value === undefined) return 'undefined'; 50 - if (typeof value === 'object') { 51 - return JSON.stringify(value, null, 2); 52 - } 53 - return String(value); 54 - } 28 + // Check for Cloudflare headers 29 + const hasCfHeaders = $derived(Object.keys(allHeaders).some(key => key.startsWith('cf-'))); 55 30 </script> 56 31 57 32 <DropdownMenu.Root> ··· 59 34 <Button 60 35 variant="outline" 61 36 size="icon" 62 - class="rounded-full shadow-lg hover:shadow-xl transition-all duration-200 bg-blue-100 hover:bg-blue-200 dark:bg-blue-900 dark:hover:bg-blue-800" 37 + class="rounded-full bg-blue-100 hover:bg-blue-200" 63 38 builders={[builder]} 64 39 > 65 40 <Bug class="h-5 w-5" /> 66 41 </Button> 67 42 </DropdownMenu.Trigger> 68 - <DropdownMenu.Content class="w-80 max-h-[80vh] overflow-y-auto"> 43 + <DropdownMenu.Content class="w-[90vw] max-w-[800px] max-h-[80vh] overflow-y-auto"> 69 44 <DropdownMenu.Label>{title}</DropdownMenu.Label> 70 45 71 46 <div class="p-2 font-mono text-xs"> 72 - <!-- Diagnostic Information --> 73 - <div class="mb-3 bg-yellow-50 p-2 rounded border"> 74 - <div class="font-semibold text-sm text-yellow-700">Diagnostic Info</div> 75 - <div class="mt-1"> 76 - <div>Data keys: {Object.keys(data).join(', ') || 'none'}</div> 77 - <div>Headers: {headers ? Object.keys(headers).length : 'Not available'}</div> 78 - <div>CF detected: {hasCfHeaders ? 'Yes' : 'No'}</div> 79 - <div>Timestamp: {debugInfo.timestamp}</div> 80 - </div> 47 + <!-- Show debugging info --> 48 + <div class="bg-yellow-50 p-2 rounded border mb-2"> 49 + <div>Data keys received: {Object.keys(data).join(', ')}</div> 50 + <div>allHeaders present: {data.allHeaders ? 'Yes' : 'No'}</div> 81 51 </div> 82 - 83 - {#if data && Object.keys(data).length > 0} 84 - {#if data.ip_country} 85 - <div class="mb-3 bg-blue-50 p-2 rounded border"> 86 - <div class="font-semibold text-sm text-blue-700">Cloudflare Country</div> 87 - <div class="mt-1"> 88 - <div class="text-lg font-bold">{data.ip_country || 'Not available'}</div> 89 - {#if data.country_phone} 90 - <div class="text-sm">Phone Code: {data.country_phone}</div> 91 - {/if} 92 - </div> 93 - </div> 94 - {/if} 95 - 96 - {#if headers} 97 - <div class="mb-3"> 98 - <div class="font-semibold text-sm text-green-700">HTTP Headers {hasCfHeaders ? '✓ Cloudflare Detected' : ''}</div> 99 - <div class="bg-gray-50 p-2 rounded border mt-1 max-h-80 overflow-y-auto"> 100 - <input 101 - type="text" 102 - placeholder="Filter headers..." 103 - class="w-full p-1 mb-2 border rounded text-xs" 104 - on:input={(e) => { 105 - const value = e.target.value.toLowerCase(); 106 - const rows = document.querySelectorAll('tr.header-row'); 107 - rows.forEach(row => { 108 - const text = row.textContent.toLowerCase(); 109 - row.style.display = text.includes(value) ? '' : 'none'; 110 - }); 111 - }} 112 - /> 113 - <table class="w-full text-left"> 114 - <thead> 115 - <tr> 116 - <th class="pb-1 border-b">Header</th> 117 - <th class="pb-1 border-b">Value</th> 118 - </tr> 119 - </thead> 120 - <tbody> 121 - {#each Object.entries(headers) as [key, value]} 122 - <tr class="border-b border-gray-100 header-row {key.startsWith('cf-') ? 'bg-blue-50' : ''}"> 123 - <td class="pr-2 py-1 font-medium">{key}</td> 124 - <td class="py-1 break-all">{value}</td> 125 - </tr> 126 - {/each} 127 - </tbody> 128 - </table> 129 - </div> 130 - </div> 52 + 53 + <!-- Show raw headers data --> 54 + <div class="bg-gray-50 p-2 rounded border mt-1 overflow-auto"> 55 + <pre class="whitespace-pre-wrap break-all">{JSON.stringify(allHeaders, null, 2)}</pre> 56 + </div> 57 + 58 + <!-- Basic stats about the data --> 59 + <div class="mt-2 text-xs text-gray-500"> 60 + Headers count: {headerCount} 61 + {#if hasCfHeaders} 62 + <span class="ml-2 text-green-600 font-bold">✓ Cloudflare headers present</span> 131 63 {/if} 132 - 133 - {#each Object.entries(data) as [key, value]} 134 - {#if key !== 'headers' && key !== 'allHeaders' && key !== 'ip_country' && key !== 'country_phone'} 135 - <div class="mb-3"> 136 - <div class="font-semibold text-sm">{key}</div> 137 - <div class="bg-gray-50 p-2 rounded border mt-1"> 138 - {#if typeof value === 'object' && value !== null} 139 - {#each Object.entries(value) as [subKey, subValue]} 140 - <div class="mb-1"> 141 - <span class="font-medium">{subKey}:</span> 142 - {#if typeof subValue === 'object' && subValue !== null && Array.isArray(subValue)} 143 - <div class="ml-2"> 144 - {#if subValue.length > 0} 145 - <ul class="list-disc ml-4 mt-1"> 146 - {#each subValue as item} 147 - <li class="mb-1"> 148 - {#if typeof item === 'object' && item !== null} 149 - <pre class="whitespace-pre-wrap break-all text-xs">{formatValue(item)}</pre> 150 - {:else} 151 - {item} 152 - {/if} 153 - </li> 154 - {/each} 155 - </ul> 156 - {:else} 157 - <span class="text-gray-500">Empty array</span> 158 - {/if} 159 - </div> 160 - {:else if typeof subValue === 'object' && subValue !== null} 161 - <pre class="ml-2 whitespace-pre-wrap break-all text-xs">{formatValue(subValue)}</pre> 162 - {:else} 163 - <span class="ml-2">{formatValue(subValue)}</span> 164 - {/if} 165 - </div> 166 - {/each} 167 - {:else} 168 - {formatValue(value)} 169 - {/if} 170 - </div> 171 - </div> 172 - {/if} 173 - {/each} 174 - {:else} 175 - <div class="text-gray-400">No debug data available</div> 176 - {/if} 64 + </div> 177 65 </div> 178 66 179 67 <DropdownMenu.Separator /> 180 - <DropdownMenu.Item on:click={() => console.log('Debug data:', data)}> 181 - Log to Console 68 + <DropdownMenu.Item on:click={() => console.log('Raw Headers:', allHeaders)}> 69 + Log Headers to Console 182 70 </DropdownMenu.Item> 183 71 </DropdownMenu.Content> 184 72 </DropdownMenu.Root>
+4 -3
src/lib/utils/cloudflare.js
··· 8 8 export function getCloudflareData(request) { 9 9 const { headers } = request; 10 10 11 - // Capture all headers as an object for debugging 11 + // Capture all headers as a plain object for debugging 12 + // Using a plain object ensures it can be properly serialized 12 13 const allHeaders = {}; 13 14 headers.forEach((value, key) => { 14 15 allHeaders[key] = value; ··· 24 25 const countryInfo = getCountryInfo(ip_country); 25 26 const country_phone = countryInfo ? countryInfo.phone : null; 26 27 28 + // Make sure we return a serializable plain object with all data 27 29 return { 28 30 ip_country, 29 31 country_phone, 30 32 accept_language, 31 33 countryInfo, 32 - // Include all headers for client-side debugging 33 - headers: allHeaders 34 + allHeaders // Renamed from headers to allHeaders for clarity 34 35 }; 35 36 }
+17 -14
src/routes/+layout.server.ts
··· 1 1 import { getCloudflareData } from '$lib/utils/cloudflare.js'; 2 - import { Database } from 'bun:sqlite'; 3 2 import type { LayoutServerLoad } from './$types'; 4 3 5 4 export const load: LayoutServerLoad = async ({ request, params = {} }) => { 6 5 // Get Cloudflare data 7 6 const cloudflareData = getCloudflareData(request); 8 7 9 - console.log('[LAYOUT SERVER] Headers received:', cloudflareData.headers); 10 - console.log('[LAYOUT SERVER] Cloudflare country:', cloudflareData.ip_country); 11 - 12 - // Test the database connection and log the result 13 - const db = new Database(process.env.DATABASE_URL || ':memory:'); 14 - const testQuery = db.query("SELECT 'banana' AS fruit"); 15 - const result = testQuery.get(); 8 + // Log what we're passing to the client 9 + console.log('[LAYOUT SERVER] Headers being passed to client:', 10 + Object.keys(cloudflareData.allHeaders).length, 'headers'); 16 11 12 + // Simple test data instead of SQLite database 13 + const testQueryResult = { fruit: 'banana' }; 14 + 15 + // In SvelteKit, returned objects are serialized with devalue 16 + // Make sure we return allHeaders directly at the top level for accessibility 17 17 return { 18 - ...cloudflareData, 19 - testQueryResult: result, 20 - // Include the slug like textme does (if available) 21 - slug: params.slug, 22 - // Keep the headers for debugging 23 - headers: cloudflareData.headers 18 + ip_country: cloudflareData.ip_country, 19 + country_phone: cloudflareData.country_phone, 20 + accept_language: cloudflareData.accept_language, 21 + countryInfo: cloudflareData.countryInfo, 22 + allHeaders: cloudflareData.allHeaders, 23 + testQueryResult, 24 + // Don't nest under cloudflareData as it makes access more complex 25 + slug: params.slug 26 + 24 27 }; 25 28 };
+17 -11
src/routes/+layout.svelte
··· 10 10 /** @type {{children?: import('svelte').Snippet}} */ 11 11 let { children } = $props(); 12 12 13 - // Add derived data for debugging using Svelte 5 runes 14 - const pageData = $derived(page.data || {}); 13 + // Create debug data object with direct access to the headers 15 14 const debugData = $derived({ 16 - ...page.data, 17 - // Fallback structure if headers are missing 15 + // Direct access to headers from the data object 16 + allHeaders: $page.data.allHeaders, 17 + // Include other data for reference 18 + ip_country: $page.data.ip_country, 18 19 clientInfo: { 19 20 browser: browser ? 'True' : 'False', 20 21 timestamp: new Date().toISOString(), ··· 22 23 } 23 24 }); 24 25 25 - // Log Cloudflare data to console on client 26 + // Log Cloudflare data to console on client for debugging 26 27 onMount(() => { 27 - if (browser && page && page.data) { 28 - console.log('[CLIENT] Page data available:', Object.keys(page.data)); 29 - console.log('[CLIENT] Headers available:', page.data.headers ? 'Yes' : 'No'); 28 + if (browser) { 29 + console.log('[CLIENT] Full page data structure:', $page.data); 30 30 31 - // Log entire page data for debugging 32 - console.log('[CLIENT] Full page data:', page.data); 31 + // Specifically check for allHeaders 32 + if ($page.data.allHeaders) { 33 + console.log('[CLIENT] Headers found! Count:', Object.keys($page.data.allHeaders).length); 34 + console.log('[CLIENT] Some headers:', Object.keys($page.data.allHeaders).slice(0, 3)); 35 + } else { 36 + console.log('[CLIENT] No headers found in page data'); 37 + console.log('[CLIENT] Available keys:', Object.keys($page.data)); 38 + } 33 39 } 34 40 }); 35 41 ··· 48 54 {#if browser} 49 55 <div class="fixed bottom-4 right-4 flex gap-2 z-50 bg-white/50 p-2 rounded-lg"> 50 56 <DebugButton 51 - title="Cloudflare Data" 57 + title="Cloudflare Headers ({debugData.allHeaders ? Object.keys(debugData.allHeaders).length : 0})" 52 58 data={debugData} 53 59 /> 54 60 <SettingsButton />