export declare const rateLimitTemplate = "const rateLimitMap = new Map();\n\nconst WINDOW_MS = 60_000; // 1 minute\nconst MAX_REQUESTS = 10;\nconst MAX_TRACKED_CLIENTS = 10_000;\n\n// Clean up stale entries periodically\nconst CLEANUP_INTERVAL_MS = 5 * 60_000;\nlet lastCleanup = Date.now();\n\nfunction cleanup() {\n const now = Date.now();\n if (now - lastCleanup < CLEANUP_INTERVAL_MS) return;\n lastCleanup = now;\n rateLimitMap.forEach((entry, key) => {\n if (now > entry.resetTime) {\n rateLimitMap.delete(key);\n }\n });\n}\n\nfunction validClientAddress(value: string | null): string | null {\n const candidate = value?.split(\",\")[0]?.trim();\n return candidate && /^[0-9a-f:.]{3,64}$/i.test(candidate) ? candidate : null;\n}\n\n/**\n * Web Request does not expose the peer address. Trust an IP header only when\n * the runtime identifies a platform that overwrites that specific header.\n * Self-hosted deployments fall back to one shared bucket and should enforce a\n * stronger distributed rate limit at their trusted reverse proxy.\n */\nfunction clientIdentity(request: Request): string {\n let platform = \"\";\n let address: string | null = null;\n\n if (process.env.VERCEL === \"1\") {\n platform = \"vercel\";\n address = validClientAddress(request.headers.get(\"x-vercel-forwarded-for\"));\n } else if (process.env.CF_PAGES === \"1\") {\n platform = \"cloudflare\";\n address = validClientAddress(request.headers.get(\"cf-connecting-ip\"));\n } else if (process.env.FLY_APP_NAME) {\n platform = \"fly\";\n address = validClientAddress(request.headers.get(\"fly-client-ip\"));\n }\n\n return address ? `${platform}:${address}` : \"shared:untrusted-proxy\";\n}\n\nexport function rateLimit(request: Request): {\n allowed: boolean;\n retryAfter: number;\n} {\n cleanup();\n\n const now = Date.now();\n const identity = clientIdentity(request);\n const entry = rateLimitMap.get(identity);\n\n if (!entry || now > entry.resetTime) {\n // Bound memory even when an attacker rotates spoofed forwarding headers.\n // Map iteration is insertion ordered, so remove the oldest tracked client.\n if (rateLimitMap.size >= MAX_TRACKED_CLIENTS) {\n const oldestKey = rateLimitMap.keys().next().value;\n if (oldestKey !== undefined) rateLimitMap.delete(oldestKey);\n }\n rateLimitMap.set(identity, { count: 1, resetTime: now + WINDOW_MS });\n return { allowed: true, retryAfter: 0 };\n }\n\n entry.count++;\n\n if (entry.count > MAX_REQUESTS) {\n const retryAfter = Math.ceil((entry.resetTime - now) / 1000);\n return { allowed: false, retryAfter };\n }\n\n return { allowed: true, retryAfter: 0 };\n}\n";