Fix translations

This commit is contained in:
Kalle
2026-08-26 18:28:54 +03:00
parent e1eef816b5
commit a42fc86a0f
11 changed files with 72 additions and 16 deletions

View File

@@ -0,0 +1,56 @@
import fs from "node:fs";
import path from "node:path";
import { describe, expect, test } from "vitest";
import { DEFAULT_LANGUAGE, languages } from "./config";
const LOCALES_DIR = path.join(process.cwd(), "locales");
const namespaceFiles = fs
.readdirSync(path.join(LOCALES_DIR, DEFAULT_LANGUAGE))
.filter((file) => file.endsWith(".json"));
const readNamespace = (language: string, file: string) => {
const filePath = path.join(LOCALES_DIR, language, file);
if (!fs.existsSync(filePath)) return null;
return JSON.parse(fs.readFileSync(filePath, "utf8")) as Record<
string,
string
>;
};
const interpolatedVariables = (value: string) =>
Array.from(value.matchAll(/\{\{\s*([a-zA-Z0-9_.]+)\s*(?:,[^}]*)?\}\}/g))
.map((match) => match[1])
.sort();
describe("translations", () => {
test.each(languages.filter(({ code }) => code !== DEFAULT_LANGUAGE))(
"$code interpolates the same variables as English",
({ code }) => {
const mismatches: string[] = [];
for (const file of namespaceFiles) {
const english = readNamespace(DEFAULT_LANGUAGE, file)!;
const translated = readNamespace(code, file);
if (!translated) continue;
for (const [key, englishValue] of Object.entries(english)) {
const translatedValue = translated[key];
if (!translatedValue) continue;
const expected = interpolatedVariables(englishValue).join(",");
const actual = interpolatedVariables(translatedValue).join(",");
if (expected !== actual) {
mismatches.push(
`${file} ${key}: English has [${expected}], ${code} has [${actual}]`,
);
}
}
}
expect(mismatches).toEqual([]);
},
);
});

View File

@@ -264,11 +264,11 @@
"labels.profileCommissionText": "info om bestilling",
"labels.profileNewProfileEnabled": "",
"bottomTexts.profileCustomAvatar": "",
"bottomTexts.profileCustomName": "Hvis feltet ikke udfyldes bruges dit discordbrugernavn: \"{{discordName}}\"",
"bottomTexts.profileCustomName": "Hvis feltet ikke udfyldes bruges dit discordbrugernavn",
"bottomTexts.profileCustomUrl": "",
"bottomTexts.profileInGameName": "",
"bottomTexts.profileBattlefy": "Battlefy-brugernavn bruges til seeding og bekræftelse i nogle turneringer",
"bottomTexts.profileShowDiscordUniqueName": "Vil du gøre dit unikke Discord-brugernavn ({{discordUniqueName}}) synligt for offentligheden?",
"bottomTexts.profileShowDiscordUniqueName": "Vil du gøre dit unikke Discord-brugernavn synligt for offentligheden?",
"bottomTexts.profileCommissionsOpen": "",
"bottomTexts.profileCommissionText": "Pris, åbne pladser eller andre relevante informationer der er relateret til at afgive en bestilling til dig.",
"bottomTexts.profileNewProfileEnabled": "",

View File

@@ -268,7 +268,7 @@
"bottomTexts.profileCustomUrl": "Para los mecenas (Supporter y superior) hay un enlace corto disponible. Ej. en lugar de sendou.ink/u/sendou, se puede usar snd.ink/sendou.",
"bottomTexts.profileInGameName": "Formato: Nombre#disc (ej. Jugador#1234)",
"bottomTexts.profileBattlefy": "Se usa para el seed y la verificación en algunos torneos",
"bottomTexts.profileShowDiscordUniqueName": "¿Mostrar tu nombre de Discord ({{discordUniqueName}}) públicamente?",
"bottomTexts.profileShowDiscordUniqueName": "¿Mostrar tu nombre de Discord públicamente?",
"bottomTexts.profileCommissionsOpen": "Las comisiones se cierran automáticamente después de un mes",
"bottomTexts.profileCommissionText": "Precio, espacios abiertos, o cualquier otra información sobre tus comisiones.",
"bottomTexts.profileNewProfileEnabled": "Habilitar la nueva página de perfil basada en widgets (solo para supporter)",

View File

@@ -264,11 +264,11 @@
"labels.profileCommissionText": "Info de comisiones",
"labels.profileNewProfileEnabled": "Nueva página de perfil",
"bottomTexts.profileCustomAvatar": "Los mecenas (Supporter y superior) pueden subir una imagen para usarla en lugar del avatar de Discord",
"bottomTexts.profileCustomName": "Si vacío, se mostrará tu nombre de Discord: \"{{discordName}}\"",
"bottomTexts.profileCustomName": "Si vacío, se mostrará tu nombre de Discord",
"bottomTexts.profileCustomUrl": "Para los mecenas (Supporter y superior) hay un enlace corto disponible. Ej. en lugar de sendou.ink/u/sendou, se puede usar snd.ink/sendou.",
"bottomTexts.profileInGameName": "Formato: Nombre#disc (ej. Jugador#1234)",
"bottomTexts.profileBattlefy": "El nombre de tu cuenta de Battlefy se utiliza para la clasificación y verificación en algunos torneos.",
"bottomTexts.profileShowDiscordUniqueName": "¿Mostrar tu nombre de Discord ({{discordUniqueName}}) públicamente?",
"bottomTexts.profileShowDiscordUniqueName": "¿Mostrar tu nombre de Discord públicamente?",
"bottomTexts.profileCommissionsOpen": "Las comisiones se cierran automáticamente después de un mes",
"bottomTexts.profileCommissionText": "Precio, espacios abiertos, o cualquier otra información sobre tus comisiones.",
"bottomTexts.profileNewProfileEnabled": "Habilitar la nueva página de perfil basada en widgets (solo para supporter)",

View File

@@ -268,7 +268,7 @@
"bottomTexts.profileCustomUrl": "",
"bottomTexts.profileInGameName": "",
"bottomTexts.profileBattlefy": "",
"bottomTexts.profileShowDiscordUniqueName": "Show your unique Discord name ({{discordUniqueName}}) publicly?",
"bottomTexts.profileShowDiscordUniqueName": "",
"bottomTexts.profileCommissionsOpen": "",
"bottomTexts.profileCommissionText": "Prix, disponibilités et tout autres info nécéssaires",
"bottomTexts.profileNewProfileEnabled": "",

View File

@@ -264,11 +264,11 @@
"labels.profileCommissionText": "Info pour les commissions",
"labels.profileNewProfileEnabled": "",
"bottomTexts.profileCustomAvatar": "",
"bottomTexts.profileCustomName": "Si il n'est pas présent, votre pseudo discord est utilisé: \"{{discordName}}\"",
"bottomTexts.profileCustomName": "Si il n'est pas présent, votre pseudo discord est utilisé",
"bottomTexts.profileCustomUrl": "Pour les Supporter patrons (& plus), les liens courts sont disponibles. Exemple: Au mieux de sendou.ink/u/sendou, snd.ink/sendou peut être utilisé.",
"bottomTexts.profileInGameName": "",
"bottomTexts.profileBattlefy": "Votre nom Battlefy est utiliser pour le seeding et la verification de certains tournois",
"bottomTexts.profileShowDiscordUniqueName": "Show your unique Discord name ({{discordUniqueName}}) publicly?",
"bottomTexts.profileShowDiscordUniqueName": "",
"bottomTexts.profileCommissionsOpen": "",
"bottomTexts.profileCommissionText": "Prix, disponibilités et tout autres info nécéssaires",
"bottomTexts.profileNewProfileEnabled": "",

View File

@@ -268,7 +268,7 @@
"bottomTexts.profileCustomUrl": "",
"bottomTexts.profileInGameName": "",
"bottomTexts.profileBattlefy": "",
"bottomTexts.profileShowDiscordUniqueName": "להראות את שם ה-Discord היחודי שלכם ({{discordUniqueName}}) בפומבי?",
"bottomTexts.profileShowDiscordUniqueName": "להראות את שם ה-Discord היחודי שלכם בפומבי?",
"bottomTexts.profileCommissionsOpen": "",
"bottomTexts.profileCommissionText": "מחיר, כמות בקשות או מידע אחר שקשור לבקשות אלכם",
"bottomTexts.profileNewProfileEnabled": "",

View File

@@ -264,11 +264,11 @@
"labels.profileCommissionText": "Info sulle commissioni",
"labels.profileNewProfileEnabled": "",
"bottomTexts.profileCustomAvatar": "",
"bottomTexts.profileCustomName": "Se mancante, viene usato il tuo nome visualizzato Discord: \"{{discordName}}\"",
"bottomTexts.profileCustomName": "Se mancante, viene usato il tuo nome visualizzato Discord",
"bottomTexts.profileCustomUrl": "Per gli iscritti al Patreon (Supporter compreso in su) è disponibile il link corto. Es. invece di sendou.ink/u/sendou, può essere usato snd.ink/sendou.",
"bottomTexts.profileInGameName": "",
"bottomTexts.profileBattlefy": "Il nome dell'account Battlefy è usato per il seeding e verifica in alcuni tornei",
"bottomTexts.profileShowDiscordUniqueName": "Mostrare il proprio nome unico Discord ({{discordUniqueName}}) pubblicamente?",
"bottomTexts.profileShowDiscordUniqueName": "Mostrare il proprio nome unico Discord pubblicamente?",
"bottomTexts.profileCommissionsOpen": "",
"bottomTexts.profileCommissionText": "Prezzo, posti liberi o altre info relative al commissionarti",
"bottomTexts.profileNewProfileEnabled": "",

View File

@@ -264,11 +264,11 @@
"labels.profileCommissionText": "依頼に関する情報",
"labels.profileNewProfileEnabled": "",
"bottomTexts.profileCustomAvatar": "",
"bottomTexts.profileCustomName": "記入されてない場合ディスコードの表示名 \"{{discordName}}\"を使います",
"bottomTexts.profileCustomName": "記入されてない場合ディスコードの表示名を使います",
"bottomTexts.profileCustomUrl": "",
"bottomTexts.profileInGameName": "",
"bottomTexts.profileBattlefy": "Battlefyのアカウント名は特定のトーナメンでシーディング及びにプレイヤー情報の確認に使用されます。",
"bottomTexts.profileShowDiscordUniqueName": "Discord のユニーク名 ({{discordUniqueName}}) 公表しますか?",
"bottomTexts.profileShowDiscordUniqueName": "Discord のユニーク名公表しますか?",
"bottomTexts.profileCommissionsOpen": "",
"bottomTexts.profileCommissionText": "価格、受付数、その他依頼に関する情報",
"bottomTexts.profileNewProfileEnabled": "",

View File

@@ -268,7 +268,7 @@
"bottomTexts.profileCustomUrl": "",
"bottomTexts.profileInGameName": "",
"bottomTexts.profileBattlefy": "",
"bottomTexts.profileShowDiscordUniqueName": "Deixe ativado para mostrar seu nome de usuário único do Discord ({{discordUniqueName}}) publicamente.",
"bottomTexts.profileShowDiscordUniqueName": "Deixe ativado para mostrar seu nome de usuário único do Discord publicamente.",
"bottomTexts.profileCommissionsOpen": "",
"bottomTexts.profileCommissionText": "Preço, vagas abertas ou qualquer outra informação relacionada ao processo de fazer um pedido para você.",
"bottomTexts.profileNewProfileEnabled": "",

View File

@@ -264,11 +264,11 @@
"labels.profileCommissionText": "Информация о коммишенах",
"labels.profileNewProfileEnabled": "",
"bottomTexts.profileCustomAvatar": "",
"bottomTexts.profileCustomName": "Если пользовательское имя отсутствует, то будет использовано ваше имя в Discord: \"{{discordName}}\"",
"bottomTexts.profileCustomName": "Если пользовательское имя отсутствует, то будет использовано ваше имя в Discord",
"bottomTexts.profileCustomUrl": "Для меценатов (Supporter и выше) доступна короткая ссылка. Например, вместо sendou.ink/u/sendou может быть использована сссылка snd.ink/sendou.",
"bottomTexts.profileInGameName": "",
"bottomTexts.profileBattlefy": "Имя на Battlefy может быть использовано для посева и верификации в некоторых турнирах",
"bottomTexts.profileShowDiscordUniqueName": "Показывать ваше уникальное Discord имя ({{discordUniqueName}})?",
"bottomTexts.profileShowDiscordUniqueName": "Показывать ваше уникальное Discord имя?",
"bottomTexts.profileCommissionsOpen": "",
"bottomTexts.profileCommissionText": "Цена, слоты и другая информация о ваших коммишенах",
"bottomTexts.profileNewProfileEnabled": "",