feat(codex): add credits balance to quota query

- Parse Codex usage credits balance and unlimited status
- Display credits in quota cards and auth file panels
- Add i18n labels and related tests
This commit is contained in:
lzt404 committed 2026-10-05 00:45:17 +08:00
1 parent a79140b8d2
commit 2b81856521
8 files changed
+54 -3

No files matched your search

+2 -1
View File
@@ -5,6 +5,7 @@ import { consumeCodexResetCredit, loadQuota } from '../src/services/quotaService
const success = (body: unknown) => ({ status_code: 200, body });
const codexUsage = {
rate_limit: { primary_window: { used_percent: 25, limit_window_seconds: 18000 } },
credits: { balance: 12.5, unlimited: false },
rate_limit_reset_credits: { available_count: 2, applicable_available_count: 0 },
};
const codexFile = { name: 'codex-test.json', provider: 'codex', auth_index: 1 };
@@ -39,7 +40,7 @@ describe('quota API compatibility', () => {
...codexFile,
metadata: { id_token: { chatgpt_account_id: 'account-test', plan_type: 'pro', chatgpt_subscription_active_until: '2030-01-01T00:00:00Z' } },
});
expect(result).toMatchObject({ status: 'success', plan: 'pro', resetCredits: 2, resetCreditsApplicable: 0, resetCreditsError: 'credits forbidden' });
expect(result).toMatchObject({ status: 'success', plan: 'pro', creditBalance: '12.5', creditsUnlimited: false, resetCredits: 2, resetCreditsApplicable: 0, resetCreditsError: 'credits forbidden' });
expect(result.subscriptionActiveUntil).toBe('2030-01-01T00:00:00Z');
expect(calls).toHaveLength(2);
for (const call of calls) {
+15
View File
@@ -1,10 +1,25 @@
import { describe, expect, it } from 'bun:test';
import {
codexAccountCreditsFor,
codexResetCreditDetailsFor,
codexResetCreditsFor,
quotaRowsFor,
} from '../src/services/quotaService';
describe('Codex account credits', () => {
it('reads a numeric balance and unlimited flag from usage payloads', () => {
expect(codexAccountCreditsFor({ credits: { balance: 12.5, unlimited: false } }))
.toEqual({ balance: '12.5', unlimited: false });
expect(codexAccountCreditsFor({ credits: { unlimited: true } }))
.toEqual({ unlimited: true });
});
it('ignores malformed balances', () => {
expect(codexAccountCreditsFor({ credits: { balance: 'N/A', unlimited: false } }))
.toEqual({ unlimited: false });
});
});
describe('quotaRowsFor', () => {
it('把 Codex 的已用百分比转换为剩余额度', () => {
const rows = quotaRowsFor('codex', {