Implement zod checking on translator compiler

This commit is contained in:
Alexis Faizeau 2022-01-10 17:40:04 +01:00
parent 68dc7c2555
commit 1789f36a63
5 changed files with 48 additions and 20 deletions

View File

@ -65,7 +65,8 @@
"socket.io-client": "^2.3.0", "socket.io-client": "^2.3.0",
"standardized-audio-context": "^25.2.4", "standardized-audio-context": "^25.2.4",
"ts-proto": "^1.96.0", "ts-proto": "^1.96.0",
"uuidv4": "^6.2.10" "uuidv4": "^6.2.10",
"zod": "^3.11.6"
}, },
"scripts": { "scripts": {
"start": "run-p templater serve svelte-check-watch", "start": "run-p templater serve svelte-check-watch",

View File

@ -1,4 +1,5 @@
import fs from "fs"; import fs from "fs";
import { z } from "zod";
export type LanguageFound = { export type LanguageFound = {
id: string; id: string;
@ -7,6 +8,10 @@ export type LanguageFound = {
default: boolean; default: boolean;
}; };
type LanguageObject = {
[key: string]: string | boolean | LanguageObject;
};
const translationsBasePath = "./translations"; const translationsBasePath = "./translations";
const fallbackLanguage = process.env.FALLBACK_LANGUAGE || "en-US"; const fallbackLanguage = process.env.FALLBACK_LANGUAGE || "en-US";
@ -27,17 +32,23 @@ const getAllLanguagesByFiles = (dirPath: string, languages: Array<LanguageFound>
const rawData = fs.readFileSync(dirPath + "/" + file, "utf-8"); const rawData = fs.readFileSync(dirPath + "/" + file, "utf-8");
const languageObject = JSON.parse(rawData); const languageObject = JSON.parse(rawData);
if ( const indexLanguageObject = z.object({
"language" in languageObject && typeof languageObject.language === "string" && language: z.string(),
"country" in languageObject && typeof languageObject.country === "string" && country: z.string(),
"default" in languageObject && typeof languageObject.default === "boolean" default: z.boolean(),
) { });
try {
const indexLanguage = indexLanguageObject.parse(languageObject);
languages?.push({ languages?.push({
id: parts[1], id: parts[1],
language: languageObject.language, language: indexLanguage.language,
country: languageObject.country, country: indexLanguage.country,
default: languageObject.default default: indexLanguage.default,
}); });
} catch (e) {
console.error(e);
} }
} }
}); });
@ -45,7 +56,7 @@ const getAllLanguagesByFiles = (dirPath: string, languages: Array<LanguageFound>
return languages; return languages;
}; };
const getFallbackLanguageObject = (dirPath: string, languageObject: Object | undefined) => { const getFallbackLanguageObject = (dirPath: string, languageObject: LanguageObject | undefined) => {
const files = fs.readdirSync(dirPath); const files = fs.readdirSync(dirPath);
languageObject = languageObject || {}; languageObject = languageObject || {};
@ -59,8 +70,19 @@ const getFallbackLanguageObject = (dirPath: string, languageObject: Object | und
return; return;
} }
const rawData = fs.readFileSync(dirPath + "/" + file, "utf-8"); const data = JSON.parse(fs.readFileSync(dirPath + "/" + file, "utf-8"));
languageObject = { ...languageObject, ...JSON.parse(rawData) };
try {
const languageObjectFormat: z.ZodType<LanguageObject> = z.lazy(() => {
return z.object({}).catchall(z.union([z.string(), z.boolean(), languageObjectFormat]));
});
const languageObjectData = languageObjectFormat.parse(data);
languageObject = { ...languageObject, ...languageObjectData };
} catch (e) {
console.error(e);
}
} }
}); });

View File

@ -5,10 +5,6 @@ export type Language = {
country: string; country: string;
}; };
type LanguageObject = {
[key: string]: string | LanguageObject;
};
type TranslationParams = { type TranslationParams = {
[key: string]: string | number; [key: string]: string | number;
}; };
@ -19,7 +15,7 @@ class Translator {
country: "US", country: "US",
}; };
private readonly fallbackLanguageObject: LanguageObject = FALLBACK_LANGUAGE_OBJECT as LanguageObject; private readonly fallbackLanguageObject: LanguageObject = FALLBACK_LANGUAGE_OBJECT;
/** /**
* Current language * Current language
@ -186,10 +182,14 @@ class Translator {
*/ */
private getObjectValueByPath(key: string, object: LanguageObject): string | undefined { private getObjectValueByPath(key: string, object: LanguageObject): string | undefined {
const paths = key.split("."); const paths = key.split(".");
let currentValue: LanguageObject | string = object; let currentValue: string | boolean | LanguageObject = object;
for (const path of paths) { for (const path of paths) {
if (typeof currentValue === "string" || currentValue[path] === undefined) { if (
typeof currentValue === "string" ||
typeof currentValue === "boolean" ||
currentValue[path] === undefined
) {
return undefined; return undefined;
} }

View File

@ -1,5 +1,5 @@
type LanguageObject = { type LanguageObject = {
[key: string]: string | LanguageObject; [key: string]: string | boolean | LanguageObject;
}; };
type LanguageFound = { type LanguageFound = {

View File

@ -6553,3 +6553,8 @@ yocto-queue@^0.1.0:
version "0.1.0" version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
zod@^3.11.6:
version "3.11.6"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.11.6.tgz#e43a5e0c213ae2e02aefe7cb2b1a6fa3d7f1f483"
integrity sha512-daZ80A81I3/9lIydI44motWe6n59kRBfNzTuS2bfzVh1nAXi667TOTWWtatxyG+fwgNUiagSj/CWZwRRbevJIg==