feat(providers): custom icon URL for compatible provider nodes (#5815)

Integrated into release/v3.8.44 — custom icon URL for compatible provider nodes (DB migration 113 + nodes.ts + Zod schema + API routes + catalog + ProviderIcon UI). Re-cut onto the release tip (branch was fossilized ~13 real files); reconciled icon_url into the release's evolved nodes.ts/routes via 3-way. Validated: 14 backend + 5 frontend(vitest) + 24 page-utils tests green, typecheck:core 0, provider-consistency OK, file-size/env-doc-sync pass. UNSTABLE red is the inherited environmental setup-claude base-red.
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-02 22:08:44 -03:00
committed by GitHub
parent 0965c54245
commit a49d34bf49
17 changed files with 611 additions and 26 deletions

View File

@@ -56,7 +56,8 @@ export async function PUT(request: Request, { params }: { params: Promise<{ id:
if (isValidationFailure(validation)) {
return NextResponse.json({ error: validation.error }, { status: 400 });
}
const { name, prefix, apiType, baseUrl, chatPath, modelsPath, customHeaders } = validation.data;
const { name, prefix, apiType, baseUrl, chatPath, modelsPath, customHeaders, iconUrl } =
validation.data;
const node: any = await getProviderNodeById(id);
if (!node) {
@@ -93,6 +94,9 @@ export async function PUT(request: Request, { params }: { params: Promise<{ id:
baseUrl: sanitizedBaseUrl,
chatPath: chatPath || null,
modelsPath: isClaudeCodeCompatibleProvider(id) ? null : modelsPath || null,
// #2166: explicit null (not omission) so an empty submission clears a
// previously stored custom icon.
iconUrl: iconUrl?.trim() || null,
customHeaders: customHeaders || null,
};

View File

@@ -79,6 +79,7 @@ export async function POST(request) {
chatPath,
modelsPath,
customHeaders,
iconUrl,
} = validation.data;
// Determine type
@@ -98,6 +99,7 @@ export async function POST(request) {
name: name.trim(),
chatPath: chatPath || null,
modelsPath: modelsPath || null,
iconUrl: iconUrl?.trim() || null,
customHeaders: customHeaders || null,
});
return NextResponse.json({ node }, { status: 201 });
@@ -127,6 +129,7 @@ export async function POST(request) {
name: name.trim(),
chatPath: chatPath || null,
modelsPath: compatMode === "cc" ? null : modelsPath || null,
iconUrl: iconUrl?.trim() || null,
customHeaders: customHeaders || null,
});
return NextResponse.json({ node }, { status: 201 });