mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-05 06:42:12 +03:00
db/proxies.ts was a 1059-line god-file. Extract the two acyclic, DB-free
slices into sibling leaf modules under src/lib/db/proxies/, leaving the
tightly-coupled CRUD + assignment + resolution core in the host:
- proxies/types.ts (65) 10 proxy type/interface declarations
- proxies/mappers.ts (180) pure row mappers / scope normalizers / payload
coercers (toRecord, mapProxyRow, mapAssignmentRow,
isRelayProxyType, extractRelayAuth,
toRegistryProxyResolution, normalizeScope,
normalizeAssignmentScopeId, toLegacyProxyLevel,
coerceProxyPayload, redactProxySecrets)
Host proxies.ts: 1059 -> 847 lines. The resolution functions call
createProxy/assignProxyToScope, so the CRUD+resolution core CANNOT be
extracted without an import cycle and stays in the host. The host re-exports
the 2 moved public functions (extractRelayAuth, redactProxySecrets) via
`export { ... } from './proxies/mappers'` — the public API stays IDENTICAL
(20 functions; no types were ever publicly exported). Bodies moved verbatim;
the only host edits are the new leaf imports, the re-export, dropping the now
unused `import { decrypt }`, and two prettier line-wrap reflows of retained
ternary/union lines (token-identical).
Behavior-preserving: 69 existing proxy/registry/relay/family consumer tests
stay green; new tests/unit/db-proxies-split.test.ts guards the re-export
barrel + characterizes the pure mappers (35 assertions).
Refs #3501.
154 lines
5.8 KiB
TypeScript
154 lines
5.8 KiB
TypeScript
/**
|
|
* Characterization + API-surface test: proxies.ts god-file decomposition.
|
|
*
|
|
* The host src/lib/db/proxies.ts was split into two sibling leaf modules under
|
|
* src/lib/db/proxies/:
|
|
* - types.ts — the 10 proxy type/interface declarations
|
|
* - mappers.ts — the pure row mappers / scope normalizers / payload coercers
|
|
* (toRecord, mapProxyRow, isRelayProxyType, extractRelayAuth,
|
|
* normalizeScope, toLegacyProxyLevel, coerceProxyPayload,
|
|
* redactProxySecrets, …)
|
|
*
|
|
* The tightly-coupled CRUD + assignment + resolution core stays in the host
|
|
* (resolution calls createProxy/assignProxyToScope, so extracting it would
|
|
* create an import cycle).
|
|
*
|
|
* Verifies that:
|
|
* 1. The pure mappers behave correctly (DB-free).
|
|
* 2. The host proxies.ts still re-exports the FULL public API (20 functions).
|
|
* 3. The mappers leaf exports its pieces directly.
|
|
*
|
|
* Pure typeof/behaviour checks only — no DB handle is opened.
|
|
*/
|
|
|
|
import { describe, it } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
// ── 1. mappers.ts — pure helper behaviour ────────────────────────────────────
|
|
|
|
import {
|
|
isRelayProxyType,
|
|
extractRelayAuth,
|
|
normalizeScope,
|
|
normalizeAssignmentScopeId,
|
|
toLegacyProxyLevel,
|
|
} from "../../src/lib/db/proxies/mappers.ts";
|
|
|
|
describe("proxies/mappers — isRelayProxyType", () => {
|
|
it("is true only for relay proxy types", () => {
|
|
for (const t of ["vercel", "deno", "cloudflare"]) {
|
|
assert.equal(isRelayProxyType(t), true, t);
|
|
}
|
|
});
|
|
it("is false for non-relay or non-string input", () => {
|
|
assert.equal(isRelayProxyType("http"), false);
|
|
assert.equal(isRelayProxyType("socks5"), false);
|
|
assert.equal(isRelayProxyType(123), false);
|
|
assert.equal(isRelayProxyType(null), false);
|
|
});
|
|
});
|
|
|
|
describe("proxies/mappers — normalizeScope", () => {
|
|
it("maps the legacy 'key' alias to 'account'", () => {
|
|
assert.equal(normalizeScope("key"), "account");
|
|
});
|
|
it("passes through known scopes (case-insensitive)", () => {
|
|
assert.equal(normalizeScope("Provider"), "provider");
|
|
assert.equal(normalizeScope("ACCOUNT"), "account");
|
|
assert.equal(normalizeScope("combo"), "combo");
|
|
});
|
|
it("defaults to 'global' for unknown / empty", () => {
|
|
assert.equal(normalizeScope("bogus"), "global");
|
|
assert.equal(normalizeScope(""), "global");
|
|
});
|
|
});
|
|
|
|
describe("proxies/mappers — normalizeAssignmentScopeId", () => {
|
|
it("returns the sentinel for the global scope", () => {
|
|
assert.equal(normalizeAssignmentScopeId("global", "ignored"), "__global__");
|
|
});
|
|
it("returns the scopeId (or null) for other scopes", () => {
|
|
assert.equal(normalizeAssignmentScopeId("provider", "openai"), "openai");
|
|
assert.equal(normalizeAssignmentScopeId("account", null), null);
|
|
assert.equal(normalizeAssignmentScopeId("account", undefined), null);
|
|
});
|
|
});
|
|
|
|
describe("proxies/mappers — toLegacyProxyLevel", () => {
|
|
it("maps 'account' back to the legacy 'key' level", () => {
|
|
assert.equal(toLegacyProxyLevel("account"), "key");
|
|
});
|
|
it("passes through the other scopes unchanged", () => {
|
|
assert.equal(toLegacyProxyLevel("global"), "global");
|
|
assert.equal(toLegacyProxyLevel("provider"), "provider");
|
|
assert.equal(toLegacyProxyLevel("combo"), "combo");
|
|
});
|
|
});
|
|
|
|
describe("proxies/mappers — extractRelayAuth", () => {
|
|
it("returns undefined for non-string input", () => {
|
|
assert.equal(extractRelayAuth(null), undefined);
|
|
assert.equal(extractRelayAuth(42), undefined);
|
|
});
|
|
it("returns undefined for invalid JSON (try/catch)", () => {
|
|
assert.equal(extractRelayAuth("not json"), undefined);
|
|
});
|
|
it("returns the plaintext relayAuth field when present", () => {
|
|
assert.equal(extractRelayAuth(JSON.stringify({ relayAuth: "tok-123" })), "tok-123");
|
|
});
|
|
it("returns undefined when no relay auth is stored", () => {
|
|
assert.equal(extractRelayAuth(JSON.stringify({ other: "x" })), undefined);
|
|
});
|
|
});
|
|
|
|
// ── 2. proxies.ts — full public API surface preserved ────────────────────────
|
|
|
|
const host = await import("../../src/lib/db/proxies.ts");
|
|
|
|
describe("proxies.ts public API surface (20 symbols)", () => {
|
|
const expected = [
|
|
"assignProxyToScope",
|
|
"bulkAssignProxyToScope",
|
|
"createProxy",
|
|
"createProxyAndAssign",
|
|
"deleteProxyById",
|
|
"extractRelayAuth", // re-export from mappers
|
|
"getProxyAssignments",
|
|
"getProxyById",
|
|
"getProxyHealthStats",
|
|
"getProxyRegistryGeneration",
|
|
"getProxyWhereUsed",
|
|
"listProxies",
|
|
"migrateLegacyProxyConfigToRegistry",
|
|
"redactProxySecrets", // re-export from mappers
|
|
"resolveProxyForConnectionFromRegistry",
|
|
"resolveProxyForProvider",
|
|
"resolveProxyForScopeFromRegistry",
|
|
"updateProxy",
|
|
"updateProxyAndAssign",
|
|
"upsertProxy",
|
|
];
|
|
|
|
for (const name of expected) {
|
|
it(`re-exports ${name} as a function`, () => {
|
|
assert.equal(typeof host[name], "function", `${name} must be a function on the host module`);
|
|
});
|
|
}
|
|
|
|
it("exposes exactly the 20 expected callables (no public symbol lost)", () => {
|
|
const missing = expected.filter((n) => typeof host[n] !== "function");
|
|
assert.deepEqual(missing, [], `missing public exports: ${missing.join(", ")}`);
|
|
});
|
|
});
|
|
|
|
// ── 3. mappers leaf exports its slice directly ───────────────────────────────
|
|
|
|
describe("mappers.ts exports its public helpers directly", () => {
|
|
it("re-exported public mappers are functions on the leaf", async () => {
|
|
const mappers = await import("../../src/lib/db/proxies/mappers.ts");
|
|
assert.equal(typeof mappers.extractRelayAuth, "function");
|
|
assert.equal(typeof mappers.redactProxySecrets, "function");
|
|
assert.equal(typeof mappers.coerceProxyPayload, "function");
|
|
});
|
|
});
|