import "server-only"; import { getAiProvidersByType } from "@/lib/db/queries"; import type { TripoProviderConfig } from "./types"; const DEFAULT_TRIPO_BASE_URL = "https://api.tripo3d.ai/v2/openapi"; let tripoProviderCursor = 0; function sanitizeTripoApiKey(value: string): string { return String(value || "") .replace(/[\u2028\u2029]/g, "") .replace(/[\u0000-\u001F\u007F]/g, "") .replace(/\s+/g, "") .trim(); } function sanitizeTripoBaseUrl(value: string): string { return String(value || "") .replace(/[\u2028\u2029]/g, "") .replace(/[\u0000-\u001F\u007F]/g, "") .trim(); } export async function getTripoProviderConfigs(): Promise { const providers = await getAiProvidersByType({ type: "tripo-3d", enabledOnly: true, }); const normalizedProviders = providers .map((provider): TripoProviderConfig | null => { const providerApiKey = sanitizeTripoApiKey(String(provider.apiKey || "")); if (!providerApiKey) return null; return { apiKey: providerApiKey, baseUrl: sanitizeTripoBaseUrl(String(provider.baseUrl || "")) || DEFAULT_TRIPO_BASE_URL, providerId: provider.id, providerName: provider.name, }; }) .filter((item): item is TripoProviderConfig => Boolean(item)); if (normalizedProviders.length > 0) { return normalizedProviders; } const envApiKey = sanitizeTripoApiKey(String(process.env.TRIPO_API_KEY || "")); if (!envApiKey) { return []; } return [ { apiKey: envApiKey, baseUrl: sanitizeTripoBaseUrl(String(process.env.TRIPO_BASE_URL || "")) || DEFAULT_TRIPO_BASE_URL, providerName: "TRIPO_API_KEY", }, ]; } export async function getTripoProviderConfig( preferredProviderId?: string | null, ): Promise { const providers = await getTripoProviderConfigs(); const normalizedPreferredProviderId = String(preferredProviderId || "").trim(); if (normalizedPreferredProviderId) { const matchedProvider = providers.find( (provider) => provider.providerId === normalizedPreferredProviderId, ); if (matchedProvider) return matchedProvider; } const tripoProvider = providers.length > 0 ? providers[tripoProviderCursor % providers.length] : null; if (providers.length > 0) { tripoProviderCursor = (tripoProviderCursor + 1) % providers.length; } if (tripoProvider) return tripoProvider; throw new Error("未配置 Tripo3D API,请在系统设置-本地AI新增 Tripo3D 提供商"); }