mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-19 13:33:35 +08:00
refactor: update provider API — presets endpoint, simplified activate, official route
This commit is contained in:
parent
747b45b14f
commit
e584df1d28
@ -1,30 +1,29 @@
|
||||
/**
|
||||
* Providers REST API
|
||||
*
|
||||
* GET /api/providers — 列出所有 provider
|
||||
* GET /api/providers/:id — 获取单个 provider
|
||||
* POST /api/providers — 添加 provider
|
||||
* PUT /api/providers/:id — 更新 provider
|
||||
* DELETE /api/providers/:id — 删除 provider
|
||||
* POST /api/providers/:id/activate — 激活 provider
|
||||
* POST /api/providers/:id/test — 测试已保存 provider
|
||||
* POST /api/providers/test — 测试未保存的配置
|
||||
* GET /api/providers — list all saved providers + activeId
|
||||
* GET /api/providers/presets — list available presets
|
||||
* POST /api/providers — add a provider
|
||||
* PUT /api/providers/:id — update a provider
|
||||
* DELETE /api/providers/:id — delete a provider
|
||||
* POST /api/providers/:id/activate — activate a saved provider
|
||||
* POST /api/providers/official — activate official (clear env)
|
||||
* POST /api/providers/:id/test — test a saved provider
|
||||
* POST /api/providers/test — test unsaved config
|
||||
*/
|
||||
|
||||
import { z } from 'zod'
|
||||
import { ProviderService } from '../services/providerService.js'
|
||||
import { PROVIDER_PRESETS } from '../config/providerPresets.js'
|
||||
import {
|
||||
CreateProviderSchema,
|
||||
UpdateProviderSchema,
|
||||
TestProviderSchema,
|
||||
ActivateProviderSchema,
|
||||
} from '../types/provider.js'
|
||||
import { ApiError, errorResponse } from '../middleware/errorHandler.js'
|
||||
|
||||
const providerService = new ProviderService()
|
||||
|
||||
// ─── Sanitization ─────────────────────────────────────────────────────────────
|
||||
|
||||
function maskApiKey(key: string): string {
|
||||
if (key.length <= 8) return '****'
|
||||
return key.slice(0, 4) + '****' + key.slice(-4)
|
||||
@ -37,27 +36,36 @@ function sanitizeProvider(provider: Record<string, unknown>): Record<string, unk
|
||||
return provider
|
||||
}
|
||||
|
||||
// ─── Router ───────────────────────────────────────────────────────────────────
|
||||
|
||||
export async function handleProvidersApi(
|
||||
req: Request,
|
||||
url: URL,
|
||||
_url: URL,
|
||||
segments: string[],
|
||||
): Promise<Response> {
|
||||
try {
|
||||
const id = segments[2] // provider ID or 'test'
|
||||
const action = segments[3] // 'activate' | 'test' | undefined
|
||||
const id = segments[2]
|
||||
const action = segments[3]
|
||||
|
||||
// ── POST /api/providers/test (test unsaved configuration) ──────────
|
||||
// POST /api/providers/test
|
||||
if (id === 'test' && req.method === 'POST') {
|
||||
return await handleTestUnsaved(req)
|
||||
}
|
||||
|
||||
// ── /api/providers (no ID) ────────────────────────────────────────
|
||||
// GET /api/providers/presets
|
||||
if (id === 'presets' && req.method === 'GET') {
|
||||
return Response.json({ presets: PROVIDER_PRESETS })
|
||||
}
|
||||
|
||||
// POST /api/providers/official
|
||||
if (id === 'official' && req.method === 'POST') {
|
||||
await providerService.activateOfficial()
|
||||
return Response.json({ ok: true })
|
||||
}
|
||||
|
||||
// /api/providers (no ID)
|
||||
if (!id) {
|
||||
if (req.method === 'GET') {
|
||||
const providers = await providerService.listProviders()
|
||||
return Response.json({ providers: providers.map(sanitizeProvider) })
|
||||
const { providers, activeId } = await providerService.listProviders()
|
||||
return Response.json({ providers: providers.map(sanitizeProvider), activeId })
|
||||
}
|
||||
if (req.method === 'POST') {
|
||||
return await handleCreate(req)
|
||||
@ -65,20 +73,21 @@ export async function handleProvidersApi(
|
||||
throw methodNotAllowed(req.method)
|
||||
}
|
||||
|
||||
// ── /api/providers/:id/activate ───────────────────────────────────
|
||||
// /api/providers/:id/activate
|
||||
if (action === 'activate') {
|
||||
if (req.method !== 'POST') throw methodNotAllowed(req.method)
|
||||
return await handleActivate(req, id)
|
||||
await providerService.activateProvider(id)
|
||||
return Response.json({ ok: true })
|
||||
}
|
||||
|
||||
// ── /api/providers/:id/test ───────────────────────────────────────
|
||||
// /api/providers/:id/test
|
||||
if (action === 'test') {
|
||||
if (req.method !== 'POST') throw methodNotAllowed(req.method)
|
||||
const result = await providerService.testProvider(id)
|
||||
return Response.json({ result })
|
||||
}
|
||||
|
||||
// ── /api/providers/:id (no action) ────────────────────────────────
|
||||
// /api/providers/:id
|
||||
if (req.method === 'GET') {
|
||||
const provider = await providerService.getProvider(id)
|
||||
return Response.json({ provider: sanitizeProvider(provider) })
|
||||
@ -97,8 +106,6 @@ export async function handleProvidersApi(
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Handlers ─────────────────────────────────────────────────────────────────
|
||||
|
||||
async function handleCreate(req: Request): Promise<Response> {
|
||||
const body = await parseJsonBody(req)
|
||||
try {
|
||||
@ -106,9 +113,7 @@ async function handleCreate(req: Request): Promise<Response> {
|
||||
const provider = await providerService.addProvider(input)
|
||||
return Response.json({ provider }, { status: 201 })
|
||||
} catch (err) {
|
||||
if (err instanceof z.ZodError) {
|
||||
throw ApiError.badRequest(err.issues.map((i) => i.message).join('; '))
|
||||
}
|
||||
if (err instanceof z.ZodError) throw ApiError.badRequest(err.issues.map((i) => i.message).join('; '))
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -120,23 +125,7 @@ async function handleUpdate(req: Request, id: string): Promise<Response> {
|
||||
const provider = await providerService.updateProvider(id, input)
|
||||
return Response.json({ provider })
|
||||
} catch (err) {
|
||||
if (err instanceof z.ZodError) {
|
||||
throw ApiError.badRequest(err.issues.map((i) => i.message).join('; '))
|
||||
}
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
async function handleActivate(req: Request, id: string): Promise<Response> {
|
||||
const body = await parseJsonBody(req)
|
||||
try {
|
||||
const input = ActivateProviderSchema.parse(body)
|
||||
await providerService.activateProvider(id, input.modelId)
|
||||
return Response.json({ ok: true })
|
||||
} catch (err) {
|
||||
if (err instanceof z.ZodError) {
|
||||
throw ApiError.badRequest(err.issues.map((i) => i.message).join('; '))
|
||||
}
|
||||
if (err instanceof z.ZodError) throw ApiError.badRequest(err.issues.map((i) => i.message).join('; '))
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@ -148,15 +137,11 @@ async function handleTestUnsaved(req: Request): Promise<Response> {
|
||||
const result = await providerService.testProviderConfig(input)
|
||||
return Response.json({ result })
|
||||
} catch (err) {
|
||||
if (err instanceof z.ZodError) {
|
||||
throw ApiError.badRequest(err.issues.map((i) => i.message).join('; '))
|
||||
}
|
||||
if (err instanceof z.ZodError) throw ApiError.badRequest(err.issues.map((i) => i.message).join('; '))
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
||||
|
||||
async function parseJsonBody(req: Request): Promise<Record<string, unknown>> {
|
||||
try {
|
||||
return (await req.json()) as Record<string, unknown>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user