import { api, type CodexAccount } from './api'; interface UsageWindow { used_percent?: unknown; usedPercent?: unknown; reset_at?: unknown; resetAt?: unknown; reset_after_seconds?: unknown; resetAfterSeconds?: unknown; } interface RateLimit { primary_window?: UsageWindow | null; primaryWindow?: UsageWindow | null; secondary_window?: UsageWindow | null; secondaryWindow?: UsageWindow | null; } function normalizeAuthIndex(value: unknown): string | null { if (typeof value === 'number' && Number.isFinite(value)) return value.toString(); if (typeof value === 'string') return value.trim() || null; return null; } function normalizeNumberValue(value: unknown): number | null { if (typeof value === 'number' && Number.isFinite(value)) return value; if (typeof value === 'string' && value.trim()) { const parsed = Number(value.trim()); return Number.isFinite(parsed) ? parsed : null; } return null; } function parseCodexUsagePayload(payload: unknown): Record | null { if (typeof payload === 'string' && payload.trim()) { try { return JSON.parse(payload) as Record; } catch { return null; } } return payload !== null && typeof payload === 'object' ? (payload as Record) : null; } export interface CodexQuota { planType: string | null; windows: Array<{ id: string; label: string; remaining: number | null; resetAt: number | null }>; } function resetAt(window: UsageWindow): number | null { const absolute = normalizeNumberValue(window.reset_at ?? window.resetAt); if (absolute !== null) return absolute < 1e12 ? absolute * 1000 : absolute; const offset = normalizeNumberValue(window.reset_after_seconds ?? window.resetAfterSeconds); return offset === null ? null : Date.now() + offset * 1000; } function addRateLimit( result: CodexQuota['windows'], limit: RateLimit | null | undefined, prefix: string, labels: [string, string], ) { const windows = [limit?.primary_window ?? limit?.primaryWindow, limit?.secondary_window ?? limit?.secondaryWindow]; windows.forEach((window, index) => { if (!window) return; const used = normalizeNumberValue(window.used_percent ?? window.usedPercent); result.push({ id: `${prefix}-${index}`, label: labels[index], remaining: used === null ? null : Math.max(0, Math.min(100, 100 - used)), resetAt: resetAt(window), }); }); } export async function fetchCodexQuota( account: CodexAccount, managementKey: string, ): Promise { const authIndex = normalizeAuthIndex(account.auth_index ?? account.authIndex); if (!authIndex) throw new Error('This account has no auth index, so quota cannot be queried.'); const response = await api.getCodexQuota(authIndex, managementKey); const statusCode = Number(response.status_code || 0); if (statusCode < 200 || statusCode >= 300) { throw new Error(`Quota request failed with HTTP ${statusCode || 'unknown'}`); } const payload = parseCodexUsagePayload(response.body); if (!payload) throw new Error('The quota response was empty or invalid.'); const source = payload; const windows: CodexQuota['windows'] = []; addRateLimit( windows, (source.rate_limit ?? source.rateLimit) as RateLimit | undefined, 'codex', ['5-hour limit', 'Weekly limit'], ); addRateLimit( windows, (source.code_review_rate_limit ?? source.codeReviewRateLimit) as RateLimit | undefined, 'review', ['Code review 5-hour limit', 'Code review weekly limit'], ); return { planType: typeof source.plan_type === 'string' ? source.plan_type : typeof source.planType === 'string' ? source.planType : typeof account.plan_type === 'string' ? account.plan_type : typeof account.planType === 'string' ? account.planType : null, windows, }; }