@koda-sl/baker-cli 0.150.0-dev.a970fa118 → 0.150.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/{chunk-JBDSJZBZ.js → chunk-OO5BDH3J.js} +4 -4
- package/dist/chunk-OO5BDH3J.js.map +1 -0
- package/dist/cli.js +67 -48
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-JBDSJZBZ.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
toModelSafeImage,
|
|
37
37
|
ulid,
|
|
38
38
|
validateCanvasDeep
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-OO5BDH3J.js";
|
|
40
40
|
import {
|
|
41
41
|
csvOrJson,
|
|
42
42
|
daysAgoIso,
|
|
@@ -15369,11 +15369,46 @@ function resolveFetchWeights(flag, declared) {
|
|
|
15369
15369
|
return declared?.length ? declared : [400];
|
|
15370
15370
|
}
|
|
15371
15371
|
function googleFontCssUrl(family, weights) {
|
|
15372
|
-
const name = family.trim().
|
|
15372
|
+
const name = family.trim().split(/\s+/).map(encodeURIComponent).join("+");
|
|
15373
15373
|
const axis = [...new Set(weights)].sort((a, b) => a - b).join(";");
|
|
15374
15374
|
const spec = axis ? `${name}:wght@${axis}` : name;
|
|
15375
15375
|
return `${GOOGLE_CSS2}?family=${spec}&display=swap`;
|
|
15376
15376
|
}
|
|
15377
|
+
var STANDARD_WEIGHTS = [100, 200, 300, 400, 500, 600, 700, 800, 900];
|
|
15378
|
+
async function probeServedWeights(family, fetchCss) {
|
|
15379
|
+
const probes = await Promise.all(
|
|
15380
|
+
STANDARD_WEIGHTS.map(async (weight) => await fetchCss(googleFontCssUrl(family, [weight])) ? weight : null)
|
|
15381
|
+
);
|
|
15382
|
+
return probes.filter((w) => w !== null);
|
|
15383
|
+
}
|
|
15384
|
+
async function checkFontRequests(requests, fetchCss) {
|
|
15385
|
+
const results = [];
|
|
15386
|
+
for (const request of requests) {
|
|
15387
|
+
const css = await fetchCss(googleFontCssUrl(request.family, request.weights));
|
|
15388
|
+
if (css === null) {
|
|
15389
|
+
const served2 = await probeServedWeights(request.family, fetchCss);
|
|
15390
|
+
results.push({
|
|
15391
|
+
family: request.family,
|
|
15392
|
+
requested: request.weights,
|
|
15393
|
+
served: served2,
|
|
15394
|
+
missing: request.weights.filter((w) => !served2.includes(w)),
|
|
15395
|
+
subsets: [],
|
|
15396
|
+
cause: served2.length === 0 ? "unknown-family" : "unavailable-weight"
|
|
15397
|
+
});
|
|
15398
|
+
continue;
|
|
15399
|
+
}
|
|
15400
|
+
const faces = parseGoogleFontFaces(css);
|
|
15401
|
+
const served = [...new Set(faces.map((f) => f.weight))].sort((a, b) => a - b);
|
|
15402
|
+
results.push({
|
|
15403
|
+
family: request.family,
|
|
15404
|
+
requested: request.weights,
|
|
15405
|
+
served,
|
|
15406
|
+
missing: request.weights.filter((w) => !served.includes(w)),
|
|
15407
|
+
subsets: [...new Set(faces.map((f) => f.subset))]
|
|
15408
|
+
});
|
|
15409
|
+
}
|
|
15410
|
+
return results;
|
|
15411
|
+
}
|
|
15377
15412
|
|
|
15378
15413
|
// src/commands/brand/fonts.ts
|
|
15379
15414
|
var GLOBAL_CSS = path.join("src", "styles", "global.css");
|
|
@@ -15406,19 +15441,19 @@ function fail(code, message, fix) {
|
|
|
15406
15441
|
writeJson({ ok: false, error: { code, message, ...fix ? { fix } : {} } });
|
|
15407
15442
|
process.exit(2);
|
|
15408
15443
|
}
|
|
15444
|
+
var REQUEST_TIMEOUT_MS = 15e3;
|
|
15409
15445
|
async function fetchGoogleCss(url) {
|
|
15410
15446
|
try {
|
|
15411
|
-
const res = await fetch(url, {
|
|
15447
|
+
const res = await fetch(url, {
|
|
15448
|
+
headers: { "User-Agent": BROWSER_UA },
|
|
15449
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
15450
|
+
});
|
|
15412
15451
|
if (!res.ok) return null;
|
|
15413
15452
|
return await res.text();
|
|
15414
15453
|
} catch {
|
|
15415
15454
|
return null;
|
|
15416
15455
|
}
|
|
15417
15456
|
}
|
|
15418
|
-
async function diagnoseUnserved(family) {
|
|
15419
|
-
const bare = await fetchGoogleCss(googleFontCssUrl(family, []));
|
|
15420
|
-
return bare === null ? "unknown-family" : "unavailable-weight";
|
|
15421
|
-
}
|
|
15422
15457
|
async function readGlobalCss() {
|
|
15423
15458
|
try {
|
|
15424
15459
|
return await readFile(path.resolve(process.cwd(), GLOBAL_CSS), "utf8");
|
|
@@ -15444,41 +15479,20 @@ var fontsCheckCommand = defineCommand85({
|
|
|
15444
15479
|
});
|
|
15445
15480
|
return;
|
|
15446
15481
|
}
|
|
15447
|
-
const families =
|
|
15448
|
-
const
|
|
15449
|
-
|
|
15450
|
-
const
|
|
15451
|
-
|
|
15452
|
-
|
|
15453
|
-
|
|
15454
|
-
|
|
15455
|
-
|
|
15456
|
-
|
|
15457
|
-
|
|
15458
|
-
|
|
15459
|
-
|
|
15460
|
-
|
|
15461
|
-
missing: request.weights,
|
|
15462
|
-
cause
|
|
15463
|
-
});
|
|
15464
|
-
continue;
|
|
15465
|
-
}
|
|
15466
|
-
const faces = parseGoogleFontFaces(served);
|
|
15467
|
-
const servedWeights = [...new Set(faces.map((f) => f.weight))].sort((a, b) => a - b);
|
|
15468
|
-
const missing = request.weights.filter((w) => !servedWeights.includes(w));
|
|
15469
|
-
if (missing.length > 0) unavailable.push(`${request.family} ${missing.join("/")}`);
|
|
15470
|
-
families.push({
|
|
15471
|
-
family: request.family,
|
|
15472
|
-
requested: request.weights,
|
|
15473
|
-
served: servedWeights,
|
|
15474
|
-
missing,
|
|
15475
|
-
subsets: [...new Set(faces.map((f) => f.subset))]
|
|
15476
|
-
});
|
|
15477
|
-
}
|
|
15478
|
-
if (unavailable.length > 0) {
|
|
15479
|
-
fail("FONT_NOT_SERVED", `Google Fonts does not serve: ${unavailable.join("; ")}`, {
|
|
15480
|
-
action: `Correct the family name or weight in ${GLOBAL_CSS} and src/brand/BRAND.md, or run \`baker brand fonts fetch\` for a weight that does exist.`,
|
|
15481
|
-
explanation: "A requested weight Google does not serve is silently synthesized by the browser, so the page looks subtly wrong with nothing failing."
|
|
15482
|
+
const families = await checkFontRequests(requests, fetchGoogleCss);
|
|
15483
|
+
const broken = families.filter((f) => f.missing.length > 0);
|
|
15484
|
+
if (broken.length > 0) {
|
|
15485
|
+
const summary = broken.map(
|
|
15486
|
+
(f) => f.cause === "unknown-family" ? `${f.family} (no such family on Google Fonts \u2014 check the exact spelling)` : `${f.family} ${f.missing.join("/")} (served: ${f.served.join("/") || "none"})`
|
|
15487
|
+
).join("; ");
|
|
15488
|
+
fail("FONT_NOT_SERVED", `Google Fonts does not serve: ${summary}`, {
|
|
15489
|
+
action: `Correct the family name or weight in ${GLOBAL_CSS} and src/brand/BRAND.md, picking from the \`served\` weights below.`,
|
|
15490
|
+
explanation: "A requested weight Google does not serve is silently synthesized by the browser, so the page looks subtly wrong with nothing failing.",
|
|
15491
|
+
// The per-family breakdown is the point of the command, so it ships on
|
|
15492
|
+
// the failure path too — otherwise the only remedy is re-running the
|
|
15493
|
+
// command that just failed. Healthy families are included so a
|
|
15494
|
+
// multi-family brand shows what NOT to touch.
|
|
15495
|
+
families
|
|
15482
15496
|
});
|
|
15483
15497
|
}
|
|
15484
15498
|
writeJson({
|
|
@@ -15515,16 +15529,18 @@ var fontsFetchCommand = defineCommand85({
|
|
|
15515
15529
|
);
|
|
15516
15530
|
const servedCss = await fetchGoogleCss(googleFontCssUrl(family, weights));
|
|
15517
15531
|
if (servedCss === null) {
|
|
15518
|
-
const
|
|
15532
|
+
const [diagnosis] = await checkFontRequests([{ family, weights }], fetchGoogleCss);
|
|
15533
|
+
const served = diagnosis?.served ?? [];
|
|
15519
15534
|
fail(
|
|
15520
15535
|
"FONT_NOT_SERVED",
|
|
15521
|
-
|
|
15522
|
-
|
|
15536
|
+
served.length === 0 ? `Google Fonts has no family called "${family}".` : `"${family}" exists on Google Fonts but not at weight ${weights.join("/")}.`,
|
|
15537
|
+
served.length === 0 ? {
|
|
15523
15538
|
action: "Check the exact family name at fonts.google.com, then retry.",
|
|
15524
15539
|
explanation: "Family names are case- and space-sensitive in the Google Fonts API."
|
|
15525
15540
|
} : {
|
|
15526
|
-
action: `
|
|
15527
|
-
explanation: "Google rejects the whole request when one requested weight does not exist."
|
|
15541
|
+
action: `Retry with --weights set to one of these: ${served.join(",")}.`,
|
|
15542
|
+
explanation: "Google rejects the whole request when one requested weight does not exist.",
|
|
15543
|
+
served
|
|
15528
15544
|
}
|
|
15529
15545
|
);
|
|
15530
15546
|
}
|
|
@@ -15539,7 +15555,10 @@ var fontsFetchCommand = defineCommand85({
|
|
|
15539
15555
|
await mkdir(fontsDir, { recursive: true });
|
|
15540
15556
|
const downloaded = [];
|
|
15541
15557
|
for (const face of faces) {
|
|
15542
|
-
const res = await fetch(face.url, {
|
|
15558
|
+
const res = await fetch(face.url, {
|
|
15559
|
+
headers: { "User-Agent": BROWSER_UA },
|
|
15560
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
15561
|
+
});
|
|
15543
15562
|
if (!res.ok) continue;
|
|
15544
15563
|
await writeFile(path.join(fontsDir, fontFileName(face)), Buffer.from(await res.arrayBuffer()));
|
|
15545
15564
|
downloaded.push(face);
|