mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 15:00:43 +00:00
be177f445a
**Add approved & assigned issue number here:** N/A — maintainer change, groundwork for #4231. ## Description: One-time recursive key sort of `resources/lang/en.json` (`jq -S` + prettier), with a test (`tests/EnJsonSorted.test.ts`) that enforces the invariant from now on. Why: sorted keys make the file deterministic, give translation PRs stable insertion points instead of everyone appending at section ends, and let the map-generator (#4231) rewrite the en.json map section with a plain JSON unmarshal/marshal round-trip — Go's `encoding/json` sorts object keys on marshal, so under this invariant a full-file rewrite is a no-op for everything it doesn't change. Crowdin matches translation entries by key path, not file position, so existing translations are unaffected. Only en.json is touched and checked; other language files remain Crowdin-managed (they may get reordered by Crowdin's next export, which is cosmetic). The diff is 100% line moves — no key or value changes (JSON-equal before and after). ## Please complete the following: - [x] I have added screenshots for all UI updates (no UI changes) - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory ## Please put your Discord username so you can be contacted if a bug or regression is found: evanpelle 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
41 lines
1.5 KiB
TypeScript
41 lines
1.5 KiB
TypeScript
import fs from "fs";
|
|
import path from "path";
|
|
|
|
const EN_JSON = path.join(__dirname, "..", "resources", "lang", "en.json");
|
|
|
|
/** Collect every object whose keys are out of order, as dotted paths. */
|
|
function findUnsortedObjects(value: unknown, objectPath: string): string[] {
|
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
return [];
|
|
}
|
|
const errors: string[] = [];
|
|
const keys = Object.keys(value);
|
|
for (let i = 1; i < keys.length; i++) {
|
|
if (keys[i - 1] > keys[i]) {
|
|
errors.push(
|
|
`${objectPath}: "${keys[i]}" should come before "${keys[i - 1]}"`,
|
|
);
|
|
}
|
|
}
|
|
for (const [key, child] of Object.entries(value)) {
|
|
errors.push(...findUnsortedObjects(child, `${objectPath}.${key}`));
|
|
}
|
|
return errors;
|
|
}
|
|
|
|
// en.json keys are kept alphabetically sorted at every level. This keeps the
|
|
// file deterministic, gives translation PRs stable insertion points, and lets
|
|
// the map-generator rewrite it with a plain JSON round-trip (Go's
|
|
// encoding/json sorts object keys on marshal).
|
|
// Other language files are managed by Crowdin and are not checked.
|
|
test("en.json keys are alphabetically sorted at every level", () => {
|
|
const content = JSON.parse(fs.readFileSync(EN_JSON, "utf8"));
|
|
const errors = findUnsortedObjects(content, "en.json");
|
|
if (errors.length > 0) {
|
|
throw new Error(
|
|
"en.json keys are out of order (sort with `jq -S . resources/lang/en.json` + prettier):\n" +
|
|
errors.join("\n"),
|
|
);
|
|
}
|
|
});
|