| 257 | * @returns Content from the URL or null on error |
| 258 | */ |
| 259 | export async function fetchUrlContent<T extends keyof FormatOptions>({ |
| 260 | url, |
| 261 | format, |
| 262 | }: { |
| 263 | url: string; |
| 264 | format: T; |
| 265 | }): Promise<FormatOptions[T] | null> { |
| 266 | try { |
| 267 | console.log(`Fetching ${url} with Cloudflare tiered cache`); |
| 268 | |
| 269 | const cfCacheOptions = { |
| 270 | cacheEverything: true, |
| 271 | cacheTtlByStatus: { |
| 272 | "200-299": 3600, // Cache successful responses for 1 hour |
| 273 | "404": 60, // Cache "Not Found" responses for 60 seconds |
| 274 | "500-599": 0, // Do not cache server error responses |
| 275 | }, |
| 276 | }; |
| 277 | |
| 278 | // Use Cloudflare's tiered cache for content requests |
| 279 | const response = await fetch(url, { |
| 280 | cf: cfCacheOptions, |
| 281 | }); |
| 282 | |
| 283 | // Don't proceed with unsuccessful responses |
| 284 | if (!response.ok) { |
| 285 | console.log( |
| 286 | `Error fetching ${url}: ${response.status} ${response.statusText}`, |
| 287 | ); |
| 288 | return null; |
| 289 | } |
| 290 | |
| 291 | // Process the response based on requested format |
| 292 | const result = |
| 293 | format === "json" ? await response.json() : await response.text(); |
| 294 | return result as FormatOptions[T]; |
| 295 | } catch (error) { |
| 296 | console.warn(`Failed to fetch URL content (${url}):`, error); |
| 297 | return null; |
| 298 | } |
| 299 | } |
| 300 | |
| 301 | /** |
| 302 | * Get cached fetchDocumentation result |