mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 14:50:02 +00:00
fix(cli): keep font localizer process ownership explicit
This commit is contained in:
@@ -7,5 +7,6 @@ if (error) {
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
} else {
|
} else {
|
||||||
await import("../dist/fontLocalizeCli.js");
|
const { main } = await import("../dist/fontLocalizeCli.js");
|
||||||
|
process.exitCode = await main();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// fallow-ignore-file unused-file
|
||||||
import { injectDeterministicFontFaces } from "@hyperframes/producer";
|
import { injectDeterministicFontFaces } from "@hyperframes/producer";
|
||||||
import { runFontLocalize } from "./fontLocalize.js";
|
import { runFontLocalize } from "./fontLocalize.js";
|
||||||
|
|
||||||
@@ -9,7 +10,9 @@ async function readStdin(): Promise<string> {
|
|||||||
return Buffer.concat(chunks).toString("utf8");
|
return Buffer.concat(chunks).toString("utf8");
|
||||||
}
|
}
|
||||||
|
|
||||||
process.exitCode = await runFontLocalize(
|
/** Standalone-entry main; the bin wrapper owns the actual process exit code. */
|
||||||
|
export async function main(): Promise<number> {
|
||||||
|
return runFontLocalize(
|
||||||
{
|
{
|
||||||
readInput: readStdin,
|
readInput: readStdin,
|
||||||
writeOutput: (value) => process.stdout.write(value),
|
writeOutput: (value) => process.stdout.write(value),
|
||||||
@@ -21,3 +24,4 @@ process.exitCode = await runFontLocalize(
|
|||||||
allowSystemFontCapture: false,
|
allowSystemFontCapture: false,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,22 +1,28 @@
|
|||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { injectDeterministicFontFaces } from "./deterministicFonts.js";
|
import { injectDeterministicFontFaces } from "./deterministicFonts.js";
|
||||||
|
|
||||||
describe("Google Fonts text subsetting", () => {
|
async function requestedGoogleFontUrl(html: string): Promise<URL> {
|
||||||
it("sends the composition character set to the CSS API", async () => {
|
|
||||||
let requestedUrl = "";
|
let requestedUrl = "";
|
||||||
const fetchImpl = (async (input: unknown) => {
|
const fetchImpl = (async (input: unknown) => {
|
||||||
requestedUrl = String(input);
|
requestedUrl = String(input);
|
||||||
return new Response("", { status: 400 });
|
return new Response("", { status: 400 });
|
||||||
}) as unknown as typeof fetch;
|
}) as unknown as typeof fetch;
|
||||||
|
|
||||||
await injectDeterministicFontFaces(
|
await injectDeterministicFontFaces(html, {
|
||||||
|
fetchImpl,
|
||||||
|
allowSystemFontCapture: false,
|
||||||
|
});
|
||||||
|
return new URL(requestedUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Google Fonts text subsetting", () => {
|
||||||
|
it("sends the composition character set to the CSS API", async () => {
|
||||||
|
const url = await requestedGoogleFontUrl(
|
||||||
`<!doctype html><html><head><style>
|
`<!doctype html><html><head><style>
|
||||||
h1 { font-family: "Noto Performance Test", sans-serif; }
|
h1 { font-family: "Noto Performance Test", sans-serif; }
|
||||||
</style></head><body><h1>旅行ランキング</h1></body></html>`,
|
</style></head><body><h1>旅行ランキング</h1></body></html>`,
|
||||||
{ fetchImpl, allowSystemFontCapture: false },
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const url = new URL(requestedUrl);
|
|
||||||
const text = url.searchParams.get("text") ?? "";
|
const text = url.searchParams.get("text") ?? "";
|
||||||
for (const character of new Set("旅行ランキング")) {
|
for (const character of new Set("旅行ランキング")) {
|
||||||
expect(text).toContain(character);
|
expect(text).toContain(character);
|
||||||
@@ -24,48 +30,29 @@ describe("Google Fonts text subsetting", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("includes decoded HTML entities from visible composition text", async () => {
|
it("includes decoded HTML entities from visible composition text", async () => {
|
||||||
let requestedUrl = "";
|
const url = await requestedGoogleFontUrl(
|
||||||
const fetchImpl = (async (input: unknown) => {
|
|
||||||
requestedUrl = String(input);
|
|
||||||
return new Response("", { status: 400 });
|
|
||||||
}) as unknown as typeof fetch;
|
|
||||||
|
|
||||||
await injectDeterministicFontFaces(
|
|
||||||
`<!doctype html><html><head><style>
|
`<!doctype html><html><head><style>
|
||||||
h1 { font-family: "Noto Performance Test", sans-serif; }
|
h1 { font-family: "Noto Performance Test", sans-serif; }
|
||||||
</style></head><body><h1>旅行</h1></body></html>`,
|
</style></head><body><h1>旅行</h1></body></html>`,
|
||||||
{ fetchImpl, allowSystemFontCapture: false },
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(new URL(requestedUrl).searchParams.get("text")).toContain("旅行");
|
expect(url.searchParams.get("text")).toContain("旅行");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("includes case variants for transformed supplemental alias weights", async () => {
|
it("includes case variants for transformed supplemental alias weights", async () => {
|
||||||
let requestedUrl = "";
|
const url = await requestedGoogleFontUrl(
|
||||||
const fetchImpl = (async (input: unknown) => {
|
|
||||||
requestedUrl = String(input);
|
|
||||||
return new Response("", { status: 400 });
|
|
||||||
}) as unknown as typeof fetch;
|
|
||||||
|
|
||||||
await injectDeterministicFontFaces(
|
|
||||||
`<!doctype html><html><head><style>
|
`<!doctype html><html><head><style>
|
||||||
h1 { font-family: "Inter", sans-serif; font-weight: 800; text-transform: uppercase; }
|
h1 { font-family: "Inter", sans-serif; font-weight: 800; text-transform: uppercase; }
|
||||||
</style></head><body><h1>Your Kidney Transplant:<br/>What Happens Next</h1></body></html>`,
|
</style></head><body><h1>Your Kidney Transplant:<br/>What Happens Next</h1></body></html>`,
|
||||||
{ fetchImpl, allowSystemFontCapture: false },
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const text = new URL(requestedUrl).searchParams.get("text") ?? "";
|
const text = url.searchParams.get("text") ?? "";
|
||||||
for (const character of new Set("YOUR KIDNEY TRANSPLANT:WHAT HAPPENS NEXT")) {
|
for (const character of new Set("YOUR KIDNEY TRANSPLANT:WHAT HAPPENS NEXT")) {
|
||||||
expect(text).toContain(character);
|
expect(text).toContain(character);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("falls back to the full font when case closure exceeds the text URL budget", async () => {
|
it("falls back to the full font when case closure exceeds the text URL budget", async () => {
|
||||||
let requestedUrl = "";
|
|
||||||
const fetchImpl = (async (input: unknown) => {
|
|
||||||
requestedUrl = String(input);
|
|
||||||
return new Response("", { status: 400 });
|
|
||||||
}) as unknown as typeof fetch;
|
|
||||||
const caseChangingCharacters = Array.from({ length: 0x500 }, (_, index) =>
|
const caseChangingCharacters = Array.from({ length: 0x500 }, (_, index) =>
|
||||||
String.fromCodePoint(index),
|
String.fromCodePoint(index),
|
||||||
)
|
)
|
||||||
@@ -73,13 +60,12 @@ describe("Google Fonts text subsetting", () => {
|
|||||||
.slice(0, 300)
|
.slice(0, 300)
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
await injectDeterministicFontFaces(
|
const url = await requestedGoogleFontUrl(
|
||||||
`<!doctype html><html><head><style>
|
`<!doctype html><html><head><style>
|
||||||
p { font-family: "Inter", sans-serif; font-weight: 800; text-transform: uppercase; }
|
p { font-family: "Inter", sans-serif; font-weight: 800; text-transform: uppercase; }
|
||||||
</style></head><body><p>${caseChangingCharacters}</p></body></html>`,
|
</style></head><body><p>${caseChangingCharacters}</p></body></html>`,
|
||||||
{ fetchImpl, allowSystemFontCapture: false },
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(new URL(requestedUrl).searchParams.has("text")).toBe(false);
|
expect(url.searchParams.has("text")).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user