Use American English spelling throughout

This commit is contained in:
2026-09-15 11:45:58 -07:00
parent 6ba89696ee
commit d1731efdb9
169 changed files with 786 additions and 795 deletions
+13 -13
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env node
/*
* Check a catalogue against the strings the code actually asks for.
* Check a catalog against the strings the code actually asks for.
*
* Two failures, and only one of them is visible without this.
*
@@ -8,9 +8,9 @@
* as an untranslated word on screen, which somebody will eventually notice.
*
* A *stale* key -- one whose English no longer exists, usually because it was
* mistyped when the catalogue was written -- is silent. The translation sits
* mistyped when the catalog was written -- is silent. The translation sits
* in the file looking correct, is never looked up, and the app renders English
* for ever. Nothing warns, because a catalogue is only ever read by key.
* for ever. Nothing warns, because a catalog is only ever read by key.
*/
/*
* The parser, not the compiler.
@@ -32,13 +32,13 @@ import { readFileSync, globSync } from "node:fs";
/*
* Two sets, because there are two questions and they need different nets.
*
* `wanted` is what a catalogue *owes*: the strings that actually reach t(),
* `wanted` is what a catalog *owes*: the strings that actually reach t(),
* tc() or plural(). Coverage is measured against it, so it has to stay strict
* -- widening it would count every CSS class and JMAP method name as an
* untranslated string.
*
* `seen` is every string literal in the source, and answers only "is this
* catalogue key still written down anywhere". Stale detection needs the wide
* catalog key still written down anywhere". Stale detection needs the wide
* net: a key reaches t() as a variable often enough that a strict set reports
* mostly false alarms.
*/
@@ -70,7 +70,7 @@ for (const file of globSync("web/src/**/*.{ts,tsx}").filter((f) => !f.includes("
if (ts.isJsxText(n)) { const text = n.text.trim(); if (text) seen.add(text); }
/*
* A `label:` in a constant is still a string somebody has to translate --
* it reaches t() one render later -- so it stays part of what a catalogue
* it reaches t() one render later -- so it stays part of what a catalog
* owes, and out of coverage it would flatter the number.
*/
if (ts.isPropertyAssignment(n) && n.name.getText(src) === "label" && ts.isStringLiteral(n.initializer)) wanted.add(n.initializer.text);
@@ -81,10 +81,10 @@ for (const file of globSync("web/src/**/*.{ts,tsx}").filter((f) => !f.includes("
if (ts.isCallExpression(n) && ts.isIdentifier(n.expression)) {
const fn = n.expression.text, a0 = n.arguments[0];
if ((fn === "t" || fn === "translate" || fn === "tNode") && a0 && ts.isStringLiteral(a0)) wanted.add(a0.text);
// tc(context, source) keys the catalogue on both, joined by the same
// tc(context, source) keys the catalog on both, joined by the same
// control character tc() uses. Without this the contextual entries all
// looked stale, which is the checker's own false alarm rather than a
// catalogue problem.
// catalog problem.
if (fn === "tc" && a0 && ts.isStringLiteral(a0) && n.arguments[1] && ts.isStringLiteral(n.arguments[1])) {
// Only the contextual key is required. The plain one is tc()'s
// fallback, not a second obligation -- asking for both would report
@@ -104,8 +104,8 @@ for (const file of globSync("web/src/**/*.{ts,tsx}").filter((f) => !f.includes("
}
/*
* A catalogue and a picker entry are two halves of one thing, and either half
* alone is dead weight. A catalogue with no entry in UI_LANGUAGES never
* A catalog and a picker entry are two halves of one thing, and either half
* alone is dead weight. A catalog with no entry in UI_LANGUAGES never
* reaches a reader -- it builds, it passes every test, and the language simply
* is not offered. That happened to Dutch: the entry was added by a text
* replacement anchored on a line that did not exist on that branch, so it was
@@ -113,17 +113,17 @@ for (const file of globSync("web/src/**/*.{ts,tsx}").filter((f) => !f.includes("
*/
const languagesSrc = readFileSync("web/src/lib/languages.ts", "utf8");
const registered = new Set([...languagesSrc.matchAll(/tag:\s*"([\w-]+)"/g)].map((m) => m[1]));
const catalogues = new Set(globSync("web/src/locales/*.ts").map((f) => f.split("/").pop().replace(".ts", "")));
const catalogs = new Set(globSync("web/src/locales/*.ts").map((f) => f.split("/").pop().replace(".ts", "")));
let failed = false;
for (const tag of catalogues) {
for (const tag of catalogs) {
if (!registered.has(tag)) {
failed = true;
console.log(`!! ${tag}.ts exists but is not in UI_LANGUAGES — the language is never offered\n`);
}
}
for (const tag of registered) {
if (tag !== "en" && !catalogues.has(tag)) {
if (tag !== "en" && !catalogs.has(tag)) {
failed = true;
console.log(`!! UI_LANGUAGES offers ${tag} but there is no ${tag}.ts — it would fall back to English\n`);
}