import http from 'node:http' const port = Number(process.env.MOCK_CORE_PORT || 18080) const token = process.env.MOCK_ACCESS_TOKEN || 'MOCK-ACCESS' const refresh = process.env.MOCK_REFRESH_TOKEN || 'MOCK-REFRESH' const users = new Map([ ['admin@example.com', { id: 1, role: 'admin', email: 'admin@example.com', username: 'admin' }], ['user@example.com', { id: 2, role: 'user', email: 'user@example.com', username: 'user' }] ]) function json(res, status, body) { res.writeHead(status, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' }) res.end(JSON.stringify(body)) } async function body(req) { const chunks = [] for await (const chunk of req) chunks.push(chunk) return chunks.length ? JSON.parse(Buffer.concat(chunks).toString('utf8')) : {} } function authorized(req) { return req.headers.authorization === `Bearer ${token}` || req.headers.authorization === `Bearer NEW-MOCK-ACCESS` } function subscriptions(page = 1, pageSize = 50) { const all = Array.from({ length: 57 }, (_, index) => ({ id: index + 1, user_id: 1, plan_id: 10 + (index % 2), plan_name: index % 2 ? '专业版' : '基础版', status: 'active', starts_at: '2026-08-01T00:00:00Z', expires_at: '2026-09-01T00:00:00Z', cycle_usage_usd: index / 100, cycle_quota_usd: 100, user: { id: 1, username: 'admin', email: 'admin@example.com', balance: 123.45 } })) const start = (page - 1) * pageSize return { items: all.slice(start, start + pageSize), total: all.length, page, page_size: pageSize, pages: Math.ceil(all.length / pageSize) } } const server = http.createServer(async (req, res) => { const url = new URL(req.url, `http://${req.headers.host}`) const path = url.pathname if (req.method === 'POST' && path === '/api/v1/auth/login') { const input = await body(req) const user = users.get(input.email) if (!user || input.password !== 'password') return json(res, 401, { code: 401, message: 'invalid credentials' }) return json(res, 200, { code: 0, message: 'success', data: { access_token: token, refresh_token: refresh, user } }) } if (req.method === 'POST' && path === '/api/v1/auth/refresh') { const input = await body(req) if (input.refresh_token !== refresh && input.refresh_token !== 'NEW-MOCK-REFRESH') return json(res, 401, { code: 401, message: 'expired' }) return json(res, 200, { code: 0, message: 'success', data: { access_token: 'NEW-MOCK-ACCESS', refresh_token: 'NEW-MOCK-REFRESH' } }) } if (req.method === 'POST' && path === '/api/v1/auth/logout') return json(res, 200, { code: 0, message: 'success', data: {} }) if (req.method === 'GET' && path === '/api/v1/settings/public') return json(res, 200, { code: 0, message: 'success', data: { turnstile_enabled: false, geetest_captcha_enabled: false, tencent_captcha_enabled: false, aliyun_captcha_enabled: false } }) if (!authorized(req)) return json(res, 401, { code: 401, message: 'unauthorized' }) if (req.method === 'GET' && path === '/api/v1/auth/me') return json(res, 200, { code: 0, message: 'success', data: users.get('admin@example.com') }) if (req.method === 'GET' && path === '/api/v1/admin/payment/plans') { return json(res, 200, { code: 0, message: 'success', data: [{ id: 10, name: '基础版', price: 9.9, currency: 'USD', validity_days: 30, validity_unit: 'day', for_sale: true, included_groups: [] }, { id: 11, name: '专业版', price: 19.9, currency: 'USD', validity_days: 30, validity_unit: 'day', for_sale: true, included_groups: [] }] }) } if (req.method === 'GET' && path === '/api/v1/admin/subscriptions') { const page = Number(url.searchParams.get('page') || 1) const pageSize = Number(url.searchParams.get('page_size') || 50) return json(res, 200, { code: 0, message: 'success', data: subscriptions(page, pageSize) }) } const subscriptionMatch = path.match(/^\/api\/v1\/admin\/subscriptions\/(\d+)$/) if (req.method === 'GET' && subscriptionMatch) return json(res, 200, { code: 0, message: 'success', data: subscriptions(1, 1).items[0] }) const userSubscriptionsMatch = path.match(/^\/api\/v1\/admin\/users\/(\d+)\/subscriptions$/) if (req.method === 'GET' && userSubscriptionsMatch) return json(res, 200, { code: 0, message: 'success', data: subscriptions(1, 2).items }) const userMatch = path.match(/^\/api\/v1\/admin\/users\/(\d+)$/) if (req.method === 'GET' && userMatch) return json(res, 200, { code: 0, message: 'success', data: { id: Number(userMatch[1]), username: 'admin', email: 'admin@example.com', balance: 123.45, frozen_balance: 0 } }) return json(res, 404, { code: 404, message: 'not found' }) }) server.listen(port, '127.0.0.1', () => { process.stdout.write(`mock core listening on 127.0.0.1:${port}\n`) })