mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-17 20:32:25 +03:00
`APIKEY_PROVIDERS merges the 6 family files into 240 entries` fails on the
release tip, taking a unit-test shard red on every open PR.
Agnes AI China (#13399, cdcde97c7) added one `apikey/regional` entry, so the
real count is 241 — confirmed at runtime: `Object.keys(APIKEY_PROVIDERS).length`
is 241 and includes `agnes-cn`.
The hardcoded number is deliberate, not an oversight: the test is a tripwire for
silent loss or duplication across the six family files, and each bump is
documented in the header with the provider and the PR that caused it. Kept that
convention rather than deriving the count at runtime, which would make the test
assert nothing.
127 lines
6.7 KiB
TypeScript
127 lines
6.7 KiB
TypeScript
// Characterization of the providers.ts catalog split (god-file decomposition): the host became a
|
|
// barrel that re-exports 10 data catalogs now living under constants/providers/*, and APIKEY is
|
|
// merged from 6 semantic family files (apikey/<family>.ts). Locks: the public surface (every catalog
|
|
// + helpers still exported), the spread-merge integrity (198 APIKEY entries, no loss/dup), and that
|
|
// load-time Zod validation still runs. Pure-data move → behavior must be identical.
|
|
// Count was 171 before obsolete provider removals (PR #6675: glhf/kluster/cablyai/inclusionai etc.,
|
|
// 171->167) plus #6126 (ClinePass dual-auth): the API-key-only APIKEY_PROVIDERS_GATEWAYS entry was
|
|
// removed as a duplicate now that clinepass is OAuth-primary (OAUTH_PROVIDERS.clinepass) with its
|
|
// BYOK path admitted through the DUAL_AUTH_APIKEY_PROVIDER_IDS gate instead (167->166), then the
|
|
// OpenVecta inference-gateway addition brought it back to 167, then #7246 (Chenzk API gateway)
|
|
// brought it to 168, then more additions brought it to 172, then #6650 (g4f.space no-key gateway:
|
|
// 5 new sub-path entries — g4f-groq/g4f-gemini/g4f-pollinations/g4f-ollama/g4f-nvidia) brought it
|
|
// to 177, then 2 more provider additions in the v3.8.49 cycle brought it to 179, the free-catalog
|
|
// expansion (#7840, navy) to 180, the Alibaba/Qwen Cloud regional additions (#7882) to 182, and
|
|
// #7887 (5 free-tier providers: ainative/aion/sealion/routeway/nara) to 187, then #8077 (clova-studio/
|
|
// internlm/ant-ling, all regional) to 190, then #8161 (sarvam/writer/plamo — writer in frontier-labs,
|
|
// sarvam+plamo in regional) to 193, then #8170 (inception/typhoon — inception in frontier-labs,
|
|
// typhoon in regional) to 195, then Firecrawl dual search+fetch under SEARCH_PROVIDERS.firecrawl
|
|
// (removed specialty-media duplicate) to 194, #8861 (Xiaomi MiMo Token Plan, regional) to 195, and
|
|
// the Cheaper Inference gateway (OSS-sponsor reseller, gateways family) to 198 (UnoRouter #9009),
|
|
// then later additions to 199; retiring GitHub Models brings it to 198.
|
|
// The v3.8.50 free-tier gateway waves (#9631 registry cycle, waves 2-5, #9210 phase 3) grew the
|
|
// gateways family to 228 measured on the tip; Puter retired (#10210) and chatanywhere restored
|
|
// (base-reds round 3, #9985) are both included in that measurement; Cursor API (specialty-media,
|
|
// #10729) brings it to 229; Token Kiosk (gateways, #10722) — merged in the same
|
|
// merge-train batch — independently bumped the gateways family too, landing at 231; Freebuff
|
|
// (gateways, #10531) brings it to 232. #8864 moves uncloseai (gateways family) into
|
|
// NOAUTH_PROVIDERS, dropping the APIKEY_PROVIDERS count to 231. Logfare (gateways, #10987) brings it back to 232.
|
|
// #11176 removes hackclub (gateways family), landing at 231.
|
|
// The v3.8.50 back-merge (f95b03d) adds Synthetic (specialty-media) and
|
|
// Kilo Gateway (gateways); #11434 adds volcengine-agent-plan and
|
|
// volcengine-coding-plan (regional family) — both land at 233.
|
|
// release/v3.8.51 adds Opper (gateways, #11629) and 1min.ai (gateways, #11631) — lands at 235;
|
|
// Perplexity Agent API (#12103) makes it 236;
|
|
// UC Direct (#11513, uncensored.com metered Developer API) adds one frontier-labs entry — 237;
|
|
// SeekAi (#11786, QuantumNous New-API gateway) adds one gateways entry — 238.
|
|
// GreenPT (#13024, 2b9e7fb3e) and EURouter (#13025, 22473dee5) each add one gateways entry — 240.
|
|
// Agnes AI China (#13399, cdcde97c7) adds one apikey/regional entry — 241.
|
|
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
const P = await import("../../src/shared/constants/providers.ts");
|
|
|
|
const APIKEY_PROVIDER_COUNT = 241;
|
|
|
|
test("barrel still exports every catalog + key helpers", () => {
|
|
for (const name of [
|
|
"NOAUTH_PROVIDERS",
|
|
"OAUTH_PROVIDERS",
|
|
"WEB_COOKIE_PROVIDERS",
|
|
"APIKEY_PROVIDERS",
|
|
"LOCAL_PROVIDERS",
|
|
"SEARCH_PROVIDERS",
|
|
"AUDIO_ONLY_PROVIDERS",
|
|
"UPSTREAM_PROXY_PROVIDERS",
|
|
"CLOUD_AGENT_PROVIDERS",
|
|
"SYSTEM_PROVIDERS",
|
|
"AI_PROVIDERS",
|
|
"ALIAS_TO_ID",
|
|
"ID_TO_ALIAS",
|
|
"getProviderById",
|
|
"getProviderByAlias",
|
|
"resolveProviderId",
|
|
]) {
|
|
assert.ok(name in P, `missing export: ${name}`);
|
|
}
|
|
});
|
|
|
|
test(`APIKEY_PROVIDERS merges the 6 family files into ${APIKEY_PROVIDER_COUNT} entries (no loss / no dup)`, async () => {
|
|
const keys = Object.keys((P as Record<string, object>).APIKEY_PROVIDERS);
|
|
assert.equal(keys.length, APIKEY_PROVIDER_COUNT);
|
|
assert.equal(new Set(keys).size, APIKEY_PROVIDER_COUNT, "duplicate keys after spread-merge");
|
|
// the merged object's entry-count equals the sum of the 6 semantic family files; families are a
|
|
// strict partition (every provider in exactly one), so the sum must be exactly APIKEY_PROVIDER_COUNT.
|
|
const families: [string, string][] = [
|
|
["gateways", "APIKEY_PROVIDERS_GATEWAYS"],
|
|
["frontier-labs", "APIKEY_PROVIDERS_FRONTIER"],
|
|
["inference-hosts", "APIKEY_PROVIDERS_INFERENCE"],
|
|
["enterprise-cloud", "APIKEY_PROVIDERS_ENTERPRISE"],
|
|
["regional", "APIKEY_PROVIDERS_REGIONAL"],
|
|
["specialty-media", "APIKEY_PROVIDERS_SPECIALTY"],
|
|
];
|
|
let famTotal = 0;
|
|
const seen = new Set<string>();
|
|
for (const [file, exportName] of families) {
|
|
const mod = await import(`../../src/shared/constants/providers/apikey/${file}.ts`);
|
|
const famKeys = Object.keys(mod[exportName]);
|
|
famTotal += famKeys.length;
|
|
for (const k of famKeys) {
|
|
assert.ok(!seen.has(k), `provider ${k} appears in more than one family`);
|
|
seen.add(k);
|
|
}
|
|
}
|
|
assert.equal(
|
|
famTotal,
|
|
APIKEY_PROVIDER_COUNT,
|
|
`families must partition all ${APIKEY_PROVIDER_COUNT} providers`
|
|
);
|
|
});
|
|
|
|
test("AI_PROVIDERS Proxy aggregates all sections; lookups resolve", () => {
|
|
const ai = (P as Record<string, Record<string, unknown>>).AI_PROVIDERS;
|
|
assert.ok(Object.keys(ai).length > 200);
|
|
assert.ok((P as Record<string, (id: string) => unknown>).getProviderById("openai"));
|
|
assert.ok((P as Record<string, (id: string) => unknown>).getProviderById("claude"));
|
|
// a moved catalog is reachable through the barrel re-export
|
|
assert.ok((P as Record<string, Record<string, unknown>>).APIKEY_PROVIDERS["openai"]);
|
|
});
|
|
|
|
test("each extracted data module is importable on its own", async () => {
|
|
const mods = [
|
|
["noauth", "NOAUTH_PROVIDERS"],
|
|
["oauth", "OAUTH_PROVIDERS"],
|
|
["web-cookie", "WEB_COOKIE_PROVIDERS"],
|
|
["local", "LOCAL_PROVIDERS"],
|
|
["search", "SEARCH_PROVIDERS"],
|
|
["audio", "AUDIO_ONLY_PROVIDERS"],
|
|
["upstream-proxy", "UPSTREAM_PROXY_PROVIDERS"],
|
|
["cloud-agent", "CLOUD_AGENT_PROVIDERS"],
|
|
["system", "SYSTEM_PROVIDERS"],
|
|
];
|
|
for (const [file, name] of mods) {
|
|
const m = await import(`../../src/shared/constants/providers/${file}.ts`);
|
|
assert.ok(m[name] && typeof m[name] === "object", `${file}.ts must export ${name}`);
|
|
}
|
|
});
|