mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 04:12:10 +03:00
The KimiSponsorBanner (use client) version gate imported isNewer/normalizeVersion
from versionCheck.ts, whose top-level 'import { execFile } from child_process'
cannot be tree-shaken out of a client bundle — Turbopack next build failed with 33
'Module not found' errors (child_process, fs, net, dns, module). Move the pure
helpers to a dependency-free versionCompare.ts; versionCheck.ts re-exports them.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
64 lines
3.0 KiB
TypeScript
64 lines
3.0 KiB
TypeScript
// Regression guard for the base-red that broke the Turbopack `next build`:
|
|
// kimiSponsorBannerGate.ts (pulled into the "use client" KimiSponsorBanner
|
|
// bundle) imported the semver helpers from `versionCheck.ts`, whose top-level
|
|
// `import { execFile } from "child_process"` cannot be tree-shaken out of a
|
|
// client bundle → "Module not found: Can't resolve 'child_process'".
|
|
//
|
|
// The fix moved the pure helpers into `versionCompare.ts` (dependency-free) and
|
|
// pointed the client-reachable gate at it. These assertions lock that in so the
|
|
// server module can never sneak back into the client bundle via this path.
|
|
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import { fileURLToPath } from "node:url";
|
|
import { dirname, resolve } from "node:path";
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
const src = (p: string) => readFileSync(resolve(here, "../../", p), "utf8");
|
|
|
|
const COMPARE = "src/lib/system/versionCompare.ts";
|
|
const GATE = "src/app/(dashboard)/dashboard/kimiSponsorBannerGate.ts";
|
|
|
|
test("versionCompare.ts is dependency-free (no server-only imports)", () => {
|
|
// Match actual import/require statements, not the word appearing in the
|
|
// module's own docstring (which explains WHY it avoids these).
|
|
const importLines = src(COMPARE)
|
|
.split("\n")
|
|
.filter((l) => /^\s*import\b/.test(l) || /\brequire\s*\(/.test(l));
|
|
const joined = importLines.join("\n");
|
|
for (const forbidden of ["child_process", "@/lib/services/installers", "@/shared/utils/logger", '"util"']) {
|
|
assert.ok(
|
|
!joined.includes(forbidden),
|
|
`versionCompare.ts must stay client-safe — found forbidden import ${forbidden}`
|
|
);
|
|
}
|
|
// The file must in fact have no import statements at all (fully self-contained).
|
|
assert.equal(importLines.length, 0, "versionCompare.ts should have zero imports");
|
|
});
|
|
|
|
test("the client-reachable Kimi banner gate imports helpers from versionCompare, not versionCheck", () => {
|
|
const code = src(GATE);
|
|
assert.match(code, /from "@\/lib\/system\/versionCompare"/);
|
|
assert.ok(
|
|
!/from "@\/lib\/system\/versionCheck"/.test(code),
|
|
"kimiSponsorBannerGate.ts must NOT import from versionCheck (drags child_process into the client bundle)"
|
|
);
|
|
});
|
|
|
|
test("versionCompare exports working isNewer/normalizeVersion", async () => {
|
|
const m = await import("../../src/lib/system/versionCompare.ts");
|
|
assert.deepEqual(m.normalizeVersion("v3.8.60"), [3, 8, 60]);
|
|
assert.equal(m.normalizeVersion("garbage"), null);
|
|
assert.equal(m.isNewer("3.8.61", "3.8.60"), true);
|
|
assert.equal(m.isNewer("3.8.60", "3.8.60"), false);
|
|
assert.equal(m.isNewer(null, "3.8.60"), false);
|
|
});
|
|
|
|
test("versionCheck still re-exports the helpers (back-compat for server importers)", async () => {
|
|
const m = await import("../../src/lib/system/versionCheck.ts");
|
|
assert.equal(typeof m.isNewer, "function");
|
|
assert.equal(typeof m.normalizeVersion, "function");
|
|
assert.equal(m.isNewer("3.9.0", "3.8.60"), true);
|
|
});
|