mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-12 02:02:13 +03:00
Release v3.8.41 — 52 commits since v3.8.40 (19 CHANGELOG bullets, 11 contributors). All gating CI green: Unit×8, Coverage×8, Vitest, Package Artifact, Quality Ratchet, CodeQL, Lint, Docs Sync (Strict), Node 24/26 compat, E2E×9, Integration, Electron smoke. Advisory checks overridden (main unprotected): PR Test Policy = test-masking heuristic on the cumulative 52-commit assert delta (legitimate dead-code-sweep removals + consolidations, reviewed per-PR); SonarCloud/SonarQube = new-code maintainability/coverage quality gate (CodeQL/Semgrep/Security/npm-audit/Dependabot all clean — not a security finding).
242 lines
6.5 KiB
TypeScript
242 lines
6.5 KiB
TypeScript
import {
|
|
APIKEY_PROVIDERS,
|
|
AUDIO_ONLY_PROVIDERS,
|
|
CLOUD_AGENT_PROVIDERS,
|
|
LOCAL_PROVIDERS,
|
|
NOAUTH_PROVIDERS,
|
|
OAUTH_PROVIDERS,
|
|
SEARCH_PROVIDERS,
|
|
UPSTREAM_PROXY_PROVIDERS,
|
|
WEB_COOKIE_PROVIDERS,
|
|
isClaudeCodeCompatibleProvider,
|
|
supportsApiKeyOnFreeProvider,
|
|
type RiskNoticeVariant,
|
|
} from "@/shared/constants/providers";
|
|
|
|
export type ProviderDisplayAuthType = "oauth" | "apikey" | "compatible" | "no-auth";
|
|
export type ProviderToggleAuthType = "oauth" | "free" | "apikey" | "no-auth";
|
|
export type StaticProviderCatalogCategory =
|
|
| "no-auth"
|
|
| "oauth"
|
|
| "web-cookie"
|
|
| "local"
|
|
| "search"
|
|
| "audio"
|
|
| "upstream-proxy"
|
|
| "apikey"
|
|
| "cloud-agent";
|
|
|
|
export interface ProviderCatalogMetadata {
|
|
id: string;
|
|
name: string;
|
|
color: string;
|
|
alias?: string;
|
|
icon?: string;
|
|
textIcon?: string;
|
|
website?: string;
|
|
authHint?: string;
|
|
apiHint?: string;
|
|
passthroughModels?: boolean;
|
|
subscriptionRisk?: boolean;
|
|
riskNoticeVariant?: RiskNoticeVariant;
|
|
apiType?: string;
|
|
baseUrl?: string;
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
type ProviderRecord = Record<string, ProviderCatalogMetadata>;
|
|
|
|
export interface StaticProviderCatalogGroup {
|
|
category: StaticProviderCatalogCategory;
|
|
providers: ProviderRecord;
|
|
displayAuthType: Exclude<ProviderDisplayAuthType, "compatible">;
|
|
toggleAuthType: ProviderToggleAuthType;
|
|
}
|
|
|
|
export interface CompatibleProviderNodeLike {
|
|
id: string;
|
|
name?: string | null;
|
|
type?: string | null;
|
|
apiType?: string | null;
|
|
baseUrl?: string | null;
|
|
}
|
|
|
|
export interface CompatibleProviderLabels {
|
|
ccCompatibleName: string;
|
|
anthropicCompatibleName: string;
|
|
openAiCompatibleName: string;
|
|
}
|
|
|
|
export interface ResolvedStaticProviderCatalogEntry extends ProviderCatalogMetadata {
|
|
category: StaticProviderCatalogCategory;
|
|
displayAuthType: Exclude<ProviderDisplayAuthType, "compatible">;
|
|
toggleAuthType: ProviderToggleAuthType;
|
|
isCompatible: false;
|
|
}
|
|
|
|
export interface ResolvedCompatibleProviderCatalogEntry extends ProviderCatalogMetadata {
|
|
category: "compatible";
|
|
displayAuthType: "compatible";
|
|
toggleAuthType: "apikey";
|
|
isCompatible: true;
|
|
type?: string | null;
|
|
}
|
|
|
|
export type ResolvedProviderCatalogEntry =
|
|
| ResolvedStaticProviderCatalogEntry
|
|
| ResolvedCompatibleProviderCatalogEntry;
|
|
|
|
export const STATIC_PROVIDER_CATALOG_GROUPS: Record<
|
|
StaticProviderCatalogCategory,
|
|
StaticProviderCatalogGroup
|
|
> = {
|
|
"no-auth": {
|
|
category: "no-auth",
|
|
providers: NOAUTH_PROVIDERS as ProviderRecord,
|
|
displayAuthType: "no-auth",
|
|
toggleAuthType: "no-auth",
|
|
},
|
|
oauth: {
|
|
category: "oauth",
|
|
providers: OAUTH_PROVIDERS as ProviderRecord,
|
|
displayAuthType: "oauth",
|
|
toggleAuthType: "oauth",
|
|
},
|
|
"web-cookie": {
|
|
category: "web-cookie",
|
|
providers: WEB_COOKIE_PROVIDERS as ProviderRecord,
|
|
displayAuthType: "apikey",
|
|
toggleAuthType: "apikey",
|
|
},
|
|
local: {
|
|
category: "local",
|
|
providers: LOCAL_PROVIDERS as ProviderRecord,
|
|
displayAuthType: "apikey",
|
|
toggleAuthType: "apikey",
|
|
},
|
|
search: {
|
|
category: "search",
|
|
providers: SEARCH_PROVIDERS as ProviderRecord,
|
|
displayAuthType: "apikey",
|
|
toggleAuthType: "apikey",
|
|
},
|
|
audio: {
|
|
category: "audio",
|
|
providers: AUDIO_ONLY_PROVIDERS as ProviderRecord,
|
|
displayAuthType: "apikey",
|
|
toggleAuthType: "apikey",
|
|
},
|
|
"upstream-proxy": {
|
|
category: "upstream-proxy",
|
|
providers: UPSTREAM_PROXY_PROVIDERS as ProviderRecord,
|
|
displayAuthType: "apikey",
|
|
toggleAuthType: "apikey",
|
|
},
|
|
apikey: {
|
|
category: "apikey",
|
|
providers: APIKEY_PROVIDERS as ProviderRecord,
|
|
displayAuthType: "apikey",
|
|
toggleAuthType: "apikey",
|
|
},
|
|
"cloud-agent": {
|
|
category: "cloud-agent",
|
|
providers: CLOUD_AGENT_PROVIDERS as ProviderRecord,
|
|
displayAuthType: "apikey",
|
|
toggleAuthType: "apikey",
|
|
},
|
|
};
|
|
|
|
export const STATIC_PROVIDER_CATALOG_RESOLUTION_ORDER: StaticProviderCatalogCategory[] = [
|
|
"no-auth",
|
|
"oauth",
|
|
"web-cookie",
|
|
"local",
|
|
"search",
|
|
"audio",
|
|
"upstream-proxy",
|
|
"cloud-agent",
|
|
"apikey",
|
|
];
|
|
|
|
const MANAGED_PROVIDER_CONNECTION_CATEGORIES = new Set<StaticProviderCatalogCategory>([
|
|
"apikey",
|
|
"web-cookie",
|
|
"local",
|
|
"search",
|
|
"audio",
|
|
"cloud-agent",
|
|
]);
|
|
|
|
export function getStaticProviderCatalogGroup(
|
|
category: StaticProviderCatalogCategory
|
|
): StaticProviderCatalogGroup {
|
|
return STATIC_PROVIDER_CATALOG_GROUPS[category];
|
|
}
|
|
|
|
export function resolveStaticProviderCatalogEntry(
|
|
providerId: string
|
|
): ResolvedStaticProviderCatalogEntry | null {
|
|
for (const category of STATIC_PROVIDER_CATALOG_RESOLUTION_ORDER) {
|
|
const group = STATIC_PROVIDER_CATALOG_GROUPS[category];
|
|
const provider = group.providers[providerId];
|
|
if (!provider) continue;
|
|
return {
|
|
...provider,
|
|
category,
|
|
displayAuthType: group.displayAuthType,
|
|
toggleAuthType: group.toggleAuthType,
|
|
isCompatible: false,
|
|
};
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function isManagedProviderConnectionId(providerId: string): boolean {
|
|
if (supportsApiKeyOnFreeProvider(providerId)) return true;
|
|
|
|
const entry = resolveStaticProviderCatalogEntry(providerId);
|
|
return !!(entry && MANAGED_PROVIDER_CONNECTION_CATEGORIES.has(entry.category));
|
|
}
|
|
|
|
export function resolveCompatibleProviderCatalogEntry(
|
|
providerNode: CompatibleProviderNodeLike,
|
|
labels: CompatibleProviderLabels
|
|
): ResolvedCompatibleProviderCatalogEntry {
|
|
const isCcCompatible = isClaudeCodeCompatibleProvider(providerNode.id);
|
|
const isAnthropicCompatible = providerNode.type === "anthropic-compatible" && !isCcCompatible;
|
|
|
|
return {
|
|
id: providerNode.id,
|
|
name:
|
|
providerNode.name ||
|
|
(isCcCompatible
|
|
? labels.ccCompatibleName
|
|
: isAnthropicCompatible
|
|
? labels.anthropicCompatibleName
|
|
: labels.openAiCompatibleName),
|
|
color: isCcCompatible ? "#B45309" : isAnthropicCompatible ? "#D97757" : "#10A37F",
|
|
textIcon: isCcCompatible ? "CC" : isAnthropicCompatible ? "AC" : "OC",
|
|
apiType: providerNode.apiType || undefined,
|
|
baseUrl: providerNode.baseUrl || undefined,
|
|
type: providerNode.type,
|
|
category: "compatible",
|
|
displayAuthType: "compatible",
|
|
toggleAuthType: "apikey",
|
|
isCompatible: true,
|
|
};
|
|
}
|
|
|
|
export function resolveProviderCatalogEntry(
|
|
providerId: string,
|
|
options?: {
|
|
providerNode?: CompatibleProviderNodeLike | null;
|
|
compatibleLabels?: CompatibleProviderLabels | null;
|
|
}
|
|
): ResolvedProviderCatalogEntry | null {
|
|
if (options?.providerNode && options.compatibleLabels) {
|
|
return resolveCompatibleProviderCatalogEntry(options.providerNode, options.compatibleLabels);
|
|
}
|
|
|
|
return resolveStaticProviderCatalogEntry(providerId);
|
|
}
|