mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 08:20:50 +00:00
Sort en.json keys alphabetically at every level (#4232)
**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>
This commit is contained in:
+1354
-1354
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
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"),
|
||||
);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user