fix(cli): resolve producer font-localization at runtime so vitest transform doesn't fail

The CLI test job builds with --filter '!@hyperframes/producer', and render.ts
imports producer only as a type — so a static import("@hyperframes/producer")
in the font-localization helper failed Vitest's transform-time module
resolution ("Failed to resolve entry for package"), breaking checkBrowser
tests and the helper's own test. Keep the specifier out of the static module
graph (@vite-ignore + variable specifier) so it resolves at runtime only:
production/installed CLI has producer in node_modules and localizes fonts;
the test env fail-opens to the plain bundle. Localizer is now injectable so
the helper's unit tests cover it without needing producer resolvable.
This commit is contained in:
Vance Ingalls
2026-07-11 16:30:13 -07:00
parent ad0d2393fe
commit aa10d49234
2 changed files with 37 additions and 19 deletions
@@ -4,11 +4,6 @@ vi.mock("@hyperframes/core/compiler", () => ({
bundleToSingleHtml: vi.fn(async () => "<html><body>bundled</body></html>"),
}));
const injectMock = vi.fn(async (html: string) => html.replace("bundled", "bundled+fonts"));
vi.mock("@hyperframes/producer", () => ({
injectDeterministicFontFaces: (html: string) => injectMock(html),
}));
import { bundleWithLocalizedFonts } from "./bundleWithLocalizedFonts.js";
afterEach(() => {
@@ -16,17 +11,19 @@ afterEach(() => {
});
describe("bundleWithLocalizedFonts", () => {
it("localizes fonts on top of the plain bundle", async () => {
const html = await bundleWithLocalizedFonts("/project");
expect(injectMock).toHaveBeenCalledOnce();
it("runs the injected font localizer over the plain bundle", async () => {
const localize = vi.fn(async (html: string) => html.replace("bundled", "bundled+fonts"));
const html = await bundleWithLocalizedFonts("/project", localize);
expect(localize).toHaveBeenCalledOnce();
expect(localize).toHaveBeenCalledWith("<html><body>bundled</body></html>");
expect(html).toBe("<html><body>bundled+fonts</body></html>");
});
it("falls open to the plain bundle when font localization throws", async () => {
injectMock.mockRejectedValueOnce(new Error("offline / fetch layer unavailable"));
const html = await bundleWithLocalizedFonts("/project");
// Never worse than a plain bundleToSingleHtml — the remote <link> still
// loads at capture time as before.
expect(html).toBe("<html><body>bundled</body></html>");
it("returns the localizer's output verbatim (localization is the last step)", async () => {
const html = await bundleWithLocalizedFonts(
"/project",
async () => "<html>embedded-face</html>",
);
expect(html).toBe("<html>embedded-face</html>");
});
});