Refactor of the i18n download mechanism
This commit is contained in:
parent
aaac1f54e8
commit
a3fd376b24
2
.gitignore
vendored
2
.gitignore
vendored
@ -50,3 +50,5 @@ jspm_packages
|
||||
|
||||
/keycloak_email
|
||||
/build_keycloak
|
||||
/src/login/i18n/baseMessages/
|
||||
/src/account/i18n/baseMessages/
|
@ -7,5 +7,6 @@ node_modules/
|
||||
/src/tools/types/
|
||||
/sample_react_project
|
||||
/build_keycloak/
|
||||
/src/i18n/generated_messages/
|
||||
/.vscode/
|
||||
/src/login/i18n/baseMessages/
|
||||
/src/account/i18n/baseMessages/
|
||||
|
@ -9,6 +9,7 @@
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"postinstall": "yarn generate-i18n-messages",
|
||||
"build": "rimraf dist/ && tsc -p src/bin && tsc -p src/tsconfig.json && tsc-alias -p src/tsconfig.json && yarn grant-exec-perms && yarn copy-files dist/",
|
||||
"build:watch": "tsc -p src/tsconfig.json && (concurrently \"tsc -p src/tsconfig.json -w\" \"tsc-alias -p src/tsconfig.json\")",
|
||||
"build:test": "rimraf dist_test/ && tsc -p test/tsconfig.json && tsc-alias -p test/tsconfig.json && yarn copy-files dist_test/src",
|
||||
|
@ -17,76 +17,101 @@ const { isSilent } = getCliOptions(process.argv.slice(2));
|
||||
const logger = getLogger({ isSilent });
|
||||
|
||||
(async () => {
|
||||
for (const keycloakVersion of ["11.0.3", "15.0.2", "18.0.1", "21.0.1"]) {
|
||||
logger.log(JSON.stringify({ keycloakVersion }));
|
||||
const keycloakVersion = "21.0.1";
|
||||
|
||||
const tmpDirPath = pathJoin(getProjectRoot(), "tmp_xImOef9dOd44");
|
||||
const tmpDirPath = pathJoin(getProjectRoot(), "tmp_xImOef9dOd44");
|
||||
|
||||
fs.rmSync(tmpDirPath, { "recursive": true, "force": true });
|
||||
fs.rmSync(tmpDirPath, { "recursive": true, "force": true });
|
||||
|
||||
await downloadBuiltinKeycloakTheme({
|
||||
keycloakVersion,
|
||||
"destDirPath": tmpDirPath,
|
||||
isSilent
|
||||
});
|
||||
await downloadBuiltinKeycloakTheme({
|
||||
keycloakVersion,
|
||||
"destDirPath": tmpDirPath,
|
||||
isSilent
|
||||
});
|
||||
|
||||
type Dictionary = { [idiomId: string]: string };
|
||||
type Dictionary = { [idiomId: string]: string };
|
||||
|
||||
const record: { [typeOfPage: string]: { [language: string]: Dictionary } } = {};
|
||||
const record: { [typeOfPage: string]: { [language: string]: Dictionary } } = {};
|
||||
|
||||
{
|
||||
const baseThemeDirPath = pathJoin(tmpDirPath, "base");
|
||||
{
|
||||
const baseThemeDirPath = pathJoin(tmpDirPath, "base");
|
||||
|
||||
crawl(baseThemeDirPath).forEach(filePath => {
|
||||
const match = filePath.match(/^([^/]+)\/messages\/messages_([^.]+)\.properties$/);
|
||||
crawl(baseThemeDirPath).forEach(filePath => {
|
||||
const match = filePath.match(/^([^/]+)\/messages\/messages_([^.]+)\.properties$/);
|
||||
|
||||
if (match === null) {
|
||||
return;
|
||||
}
|
||||
if (match === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [, typeOfPage, language] = match;
|
||||
const [, typeOfPage, language] = match;
|
||||
|
||||
(record[typeOfPage] ??= {})[language.replace(/_/g, "-")] = Object.fromEntries(
|
||||
Object.entries(propertiesParser.parse(fs.readFileSync(pathJoin(baseThemeDirPath, filePath)).toString("utf8"))).map(
|
||||
([key, value]: any) => [key, value.replace(/''/g, "'")]
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fs.rmSync(tmpDirPath, { recursive: true, force: true });
|
||||
|
||||
Object.keys(record).forEach(themeType => {
|
||||
const recordForPageType = record[themeType];
|
||||
|
||||
Object.keys(recordForPageType).forEach(language => {
|
||||
if (themeType !== "login") {
|
||||
return;
|
||||
}
|
||||
|
||||
const filePath = pathJoin(getProjectRoot(), "src", themeType, "i18n", "generated_messages", keycloakVersion, `${language}.ts`);
|
||||
|
||||
fs.mkdirSync(pathDirname(filePath), { "recursive": true });
|
||||
|
||||
fs.writeFileSync(
|
||||
filePath,
|
||||
Buffer.from(
|
||||
[
|
||||
`//This code was automatically generated by running ${pathRelative(getProjectRoot(), __filename)}`,
|
||||
"//PLEASE DO NOT EDIT MANUALLY",
|
||||
"",
|
||||
"/* spell-checker: disable */",
|
||||
`const messages= ${JSON.stringify(recordForPageType[language], null, 2)};`,
|
||||
"",
|
||||
"export default messages;",
|
||||
"/* spell-checker: enable */"
|
||||
].join("\n"),
|
||||
"utf8"
|
||||
)
|
||||
);
|
||||
|
||||
logger.log(`${filePath} wrote`);
|
||||
});
|
||||
(record[typeOfPage] ??= {})[language.replace(/_/g, "-")] = Object.fromEntries(
|
||||
Object.entries(propertiesParser.parse(fs.readFileSync(pathJoin(baseThemeDirPath, filePath)).toString("utf8"))).map(
|
||||
([key, value]: any) => [key, value.replace(/''/g, "'")]
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fs.rmSync(tmpDirPath, { recursive: true, force: true });
|
||||
|
||||
Object.keys(record).forEach(themeType => {
|
||||
const recordForPageType = record[themeType];
|
||||
|
||||
if (themeType !== "login") {
|
||||
return;
|
||||
}
|
||||
|
||||
const baseMessagesDirPath = pathJoin(getProjectRoot(), "src", themeType, "i18n", "baseMessages");
|
||||
|
||||
const languages = Object.keys(recordForPageType);
|
||||
|
||||
const generatedFileHeader = [
|
||||
`//This code was automatically generated by running ${pathRelative(getProjectRoot(), __filename)}`,
|
||||
"//PLEASE DO NOT EDIT MANUALLY",
|
||||
""
|
||||
].join("\n");
|
||||
|
||||
languages.forEach(language => {
|
||||
const filePath = pathJoin(baseMessagesDirPath, `${language}.ts`);
|
||||
|
||||
fs.mkdirSync(pathDirname(filePath), { "recursive": true });
|
||||
|
||||
fs.writeFileSync(
|
||||
filePath,
|
||||
Buffer.from(
|
||||
[
|
||||
generatedFileHeader,
|
||||
"/* spell-checker: disable */",
|
||||
`const messages= ${JSON.stringify(recordForPageType[language], null, 2)};`,
|
||||
"",
|
||||
"export default messages;",
|
||||
"/* spell-checker: enable */"
|
||||
].join("\n"),
|
||||
"utf8"
|
||||
)
|
||||
);
|
||||
|
||||
logger.log(`${filePath} wrote`);
|
||||
});
|
||||
|
||||
fs.writeFileSync(
|
||||
pathJoin(baseMessagesDirPath, "index.ts"),
|
||||
Buffer.from(
|
||||
[
|
||||
generatedFileHeader,
|
||||
"export async function getMessages(currentLanguageTag: string) {",
|
||||
" const { default: messages } = await (() => {",
|
||||
" switch (currentLanguageTag) {",
|
||||
...languages.map(language => ` case "${language}": return import("./${language}");`),
|
||||
' default: return { "default": {} };',
|
||||
" }",
|
||||
" })();",
|
||||
" return messages;",
|
||||
"}"
|
||||
].join("\n"),
|
||||
"utf8"
|
||||
)
|
||||
);
|
||||
});
|
||||
})();
|
||||
|
@ -1,7 +1,8 @@
|
||||
import "minimal-polyfills/Object.fromEntries";
|
||||
//NOTE for later: https://github.com/remarkjs/react-markdown/blob/236182ecf30bd89c1e5a7652acaf8d0bf81e6170/src/renderers.js#L7-L35
|
||||
import { useEffect, useState, useRef } from "react";
|
||||
import type baseMessages from "./generated_messages/18.0.1/login/en";
|
||||
import fallbackMessages from "./baseMessages/en";
|
||||
import { getMessages } from "./baseMessages";
|
||||
import { assert } from "tsafe/assert";
|
||||
import type { KcContext } from "../kcContext/KcContext";
|
||||
import { Markdown } from "keycloakify/tools/Markdown";
|
||||
@ -17,7 +18,7 @@ export type KcContextLike = {
|
||||
|
||||
assert<KcContext extends KcContextLike ? true : false>();
|
||||
|
||||
export type MessageKey = keyof typeof baseMessages | keyof (typeof keycloakifyExtraMessages)[typeof fallbackLanguageTag];
|
||||
export type MessageKey = keyof typeof fallbackMessages | keyof (typeof keycloakifyExtraMessages)[typeof fallbackLanguageTag];
|
||||
|
||||
export type GenericI18n<MessageKey extends string> = {
|
||||
/**
|
||||
@ -89,60 +90,6 @@ export function createUseI18n<ExtraMessageKey extends string = never>(extraMessa
|
||||
(async () => {
|
||||
const { currentLanguageTag = fallbackLanguageTag } = kcContext.locale ?? {};
|
||||
|
||||
const [fallbackMessages, messages] = await Promise.all([
|
||||
import("./generated_messages/18.0.1/login/en"),
|
||||
(() => {
|
||||
switch (currentLanguageTag) {
|
||||
case "ca":
|
||||
return import("./generated_messages/18.0.1/login/ca");
|
||||
case "cs":
|
||||
return import("./generated_messages/18.0.1/login/cs");
|
||||
case "da":
|
||||
return import("./generated_messages/18.0.1/login/da");
|
||||
case "de":
|
||||
return import("./generated_messages/18.0.1/login/de");
|
||||
case "en":
|
||||
return import("./generated_messages/18.0.1/login/en");
|
||||
case "es":
|
||||
return import("./generated_messages/18.0.1/login/es");
|
||||
case "fi":
|
||||
return import("./generated_messages/18.0.1/login/fi");
|
||||
case "fr":
|
||||
return import("./generated_messages/18.0.1/login/fr");
|
||||
case "hu":
|
||||
return import("./generated_messages/18.0.1/login/hu");
|
||||
case "it":
|
||||
return import("./generated_messages/18.0.1/login/it");
|
||||
case "ja":
|
||||
return import("./generated_messages/18.0.1/login/ja");
|
||||
case "lt":
|
||||
return import("./generated_messages/18.0.1/login/lt");
|
||||
case "lv":
|
||||
return import("./generated_messages/18.0.1/login/lv");
|
||||
case "nl":
|
||||
return import("./generated_messages/18.0.1/login/nl");
|
||||
case "no":
|
||||
return import("./generated_messages/18.0.1/login/no");
|
||||
case "pl":
|
||||
return import("./generated_messages/18.0.1/login/pl");
|
||||
case "pt-BR":
|
||||
return import("./generated_messages/18.0.1/login/pt-BR");
|
||||
case "ru":
|
||||
return import("./generated_messages/18.0.1/login/ru");
|
||||
case "sk":
|
||||
return import("./generated_messages/18.0.1/login/sk");
|
||||
case "sv":
|
||||
return import("./generated_messages/18.0.1/login/sv");
|
||||
case "tr":
|
||||
return import("./generated_messages/18.0.1/login/tr");
|
||||
case "zh-CN":
|
||||
return import("./generated_messages/18.0.1/login/zh-CN");
|
||||
default:
|
||||
return { "default": {} };
|
||||
}
|
||||
})()
|
||||
]).then(modules => modules.map(module => module.default));
|
||||
|
||||
setI18n({
|
||||
...createI18nTranslationFunctions({
|
||||
"fallbackMessages": {
|
||||
@ -151,7 +98,7 @@ export function createUseI18n<ExtraMessageKey extends string = never>(extraMessa
|
||||
...(extraMessages[fallbackLanguageTag] ?? {})
|
||||
} as any,
|
||||
"messages": {
|
||||
...messages,
|
||||
...(await getMessages(currentLanguageTag)),
|
||||
...((keycloakifyExtraMessages as any)[currentLanguageTag] ?? {}),
|
||||
...(extraMessages[currentLanguageTag] ?? {})
|
||||
} as any
|
||||
|
Loading…
x
Reference in New Issue
Block a user