Enable to add label to extra message not in the default set
This commit is contained in:
@ -13,6 +13,7 @@ import { downloadKeycloakDefaultTheme } from "./shared/downloadKeycloakDefaultTh
|
|||||||
import { getThisCodebaseRootDirPath } from "../src/bin/tools/getThisCodebaseRootDirPath";
|
import { getThisCodebaseRootDirPath } from "../src/bin/tools/getThisCodebaseRootDirPath";
|
||||||
import { deepAssign } from "../src/tools/deepAssign";
|
import { deepAssign } from "../src/tools/deepAssign";
|
||||||
import { THEME_TYPES } from "../src/bin/shared/constants";
|
import { THEME_TYPES } from "../src/bin/shared/constants";
|
||||||
|
import { transformCodebase } from "../src/bin/tools/transformCodebase";
|
||||||
const propertiesParser: any = require("properties-parser");
|
const propertiesParser: any = require("properties-parser");
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
|
@ -3,6 +3,8 @@ import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "keycloakify/bin/shared/constants
|
|||||||
import { id } from "tsafe/id";
|
import { id } from "tsafe/id";
|
||||||
import type { KcContext } from "./KcContext";
|
import type { KcContext } from "./KcContext";
|
||||||
import { BASE_URL } from "keycloakify/lib/BASE_URL";
|
import { BASE_URL } from "keycloakify/lib/BASE_URL";
|
||||||
|
import { assert, type Equals } from "tsafe/assert";
|
||||||
|
import type { LanguageTag } from "keycloakify/account/i18n/messages_defaultSet/types";
|
||||||
|
|
||||||
const resourcesPath = `${BASE_URL}${WELL_KNOWN_DIRECTORY_BASE_NAME.DOT_KEYCLOAKIFY}/account`;
|
const resourcesPath = `${BASE_URL}${WELL_KNOWN_DIRECTORY_BASE_NAME.DOT_KEYCLOAKIFY}/account`;
|
||||||
|
|
||||||
@ -38,35 +40,53 @@ export const kcContextCommonMock: KcContext.Common = {
|
|||||||
exists: () => false
|
exists: () => false
|
||||||
},
|
},
|
||||||
locale: {
|
locale: {
|
||||||
supported: [
|
supported: (
|
||||||
/* spell-checker: disable */
|
[
|
||||||
["de", "Deutsch"],
|
/* spell-checker: disable */
|
||||||
["no", "Norsk"],
|
["de", "Deutsch"],
|
||||||
["ru", "Русский"],
|
["no", "Norsk"],
|
||||||
["sv", "Svenska"],
|
["ru", "Русский"],
|
||||||
["pt-BR", "Português (Brasil)"],
|
["sv", "Svenska"],
|
||||||
["lt", "Lietuvių"],
|
["pt-BR", "Português (Brasil)"],
|
||||||
["en", "English"],
|
["lt", "Lietuvių"],
|
||||||
["it", "Italiano"],
|
["en", "English"],
|
||||||
["fr", "Français"],
|
["it", "Italiano"],
|
||||||
["zh-CN", "中文简体"],
|
["fr", "Français"],
|
||||||
["es", "Español"],
|
["zh-CN", "中文简体"],
|
||||||
["cs", "Čeština"],
|
["es", "Español"],
|
||||||
["ja", "日本語"],
|
["cs", "Čeština"],
|
||||||
["sk", "Slovenčina"],
|
["ja", "日本語"],
|
||||||
["pl", "Polski"],
|
["sk", "Slovenčina"],
|
||||||
["ca", "Català"],
|
["pl", "Polski"],
|
||||||
["nl", "Nederlands"],
|
["ca", "Català"],
|
||||||
["tr", "Türkçe"]
|
["nl", "Nederlands"],
|
||||||
/* spell-checker: enable */
|
["tr", "Türkçe"],
|
||||||
].map(
|
["ar", "العربية"],
|
||||||
([languageTag, label]) =>
|
["da", "Dansk"],
|
||||||
({
|
["fi", "Suomi"],
|
||||||
languageTag,
|
["hu", "Magyar"],
|
||||||
label,
|
["lv", "Latviešu"]
|
||||||
url: "https://gist.github.com/garronej/52baaca1bb925f2296ab32741e062b8e"
|
/* spell-checker: enable */
|
||||||
}) as const
|
] as const
|
||||||
),
|
).map(([languageTag, label]) => {
|
||||||
|
{
|
||||||
|
type Got = typeof languageTag;
|
||||||
|
type Expected = LanguageTag;
|
||||||
|
|
||||||
|
type Missing = Exclude<Expected, Got>;
|
||||||
|
type Unexpected = Exclude<Got, Expected>;
|
||||||
|
|
||||||
|
assert<Equals<Missing, never>>;
|
||||||
|
assert<Equals<Unexpected, never>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
languageTag,
|
||||||
|
label,
|
||||||
|
url: "https://gist.github.com/garronej/52baaca1bb925f2296ab32741e062b8e"
|
||||||
|
} as const;
|
||||||
|
}),
|
||||||
|
|
||||||
currentLanguageTag: "en"
|
currentLanguageTag: "en"
|
||||||
},
|
},
|
||||||
features: {
|
features: {
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
import { id } from "tsafe/id";
|
import { id } from "tsafe/id";
|
||||||
import { assert, type Equals } from "tsafe/assert";
|
import { assert, type Equals } from "tsafe/assert";
|
||||||
import { BASE_URL } from "keycloakify/lib/BASE_URL";
|
import { BASE_URL } from "keycloakify/lib/BASE_URL";
|
||||||
|
import type { LanguageTag } from "keycloakify/login/i18n/messages_defaultSet/types";
|
||||||
|
|
||||||
const attributesByName = Object.fromEntries(
|
const attributesByName = Object.fromEntries(
|
||||||
id<Attribute[]>([
|
id<Attribute[]>([
|
||||||
@ -116,35 +117,59 @@ export const kcContextCommonMock: KcContext.Common = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
locale: {
|
locale: {
|
||||||
supported: [
|
supported: (
|
||||||
/* spell-checker: disable */
|
[
|
||||||
["de", "Deutsch"],
|
/* spell-checker: disable */
|
||||||
["no", "Norsk"],
|
["de", "Deutsch"],
|
||||||
["ru", "Русский"],
|
["no", "Norsk"],
|
||||||
["sv", "Svenska"],
|
["ru", "Русский"],
|
||||||
["pt-BR", "Português (Brasil)"],
|
["sv", "Svenska"],
|
||||||
["lt", "Lietuvių"],
|
["pt-BR", "Português (Brasil)"],
|
||||||
["en", "English"],
|
["lt", "Lietuvių"],
|
||||||
["it", "Italiano"],
|
["en", "English"],
|
||||||
["fr", "Français"],
|
["it", "Italiano"],
|
||||||
["zh-CN", "中文简体"],
|
["fr", "Français"],
|
||||||
["es", "Español"],
|
["zh-CN", "中文简体"],
|
||||||
["cs", "Čeština"],
|
["es", "Español"],
|
||||||
["ja", "日本語"],
|
["cs", "Čeština"],
|
||||||
["sk", "Slovenčina"],
|
["ja", "日本語"],
|
||||||
["pl", "Polski"],
|
["sk", "Slovenčina"],
|
||||||
["ca", "Català"],
|
["pl", "Polski"],
|
||||||
["nl", "Nederlands"],
|
["ca", "Català"],
|
||||||
["tr", "Türkçe"]
|
["nl", "Nederlands"],
|
||||||
/* spell-checker: enable */
|
["tr", "Türkçe"],
|
||||||
].map(
|
["ar", "العربية"],
|
||||||
([languageTag, label]) =>
|
["da", "Dansk"],
|
||||||
({
|
["el", "Ελληνικά"],
|
||||||
languageTag,
|
["fa", "فارسی"],
|
||||||
label,
|
["fi", "Suomi"],
|
||||||
url: "https://gist.github.com/garronej/52baaca1bb925f2296ab32741e062b8e"
|
["hu", "Magyar"],
|
||||||
}) as const
|
["ka", "ქართული"],
|
||||||
),
|
["lv", "Latviešu"],
|
||||||
|
["pt", "Português"],
|
||||||
|
["th", "ไทย"],
|
||||||
|
["uk", "Українська"],
|
||||||
|
["zh-TW", "中文繁體"]
|
||||||
|
/* spell-checker: enable */
|
||||||
|
] as const
|
||||||
|
).map(([languageTag, label]) => {
|
||||||
|
{
|
||||||
|
type Got = typeof languageTag;
|
||||||
|
type Expected = LanguageTag;
|
||||||
|
|
||||||
|
type Missing = Exclude<Expected, Got>;
|
||||||
|
type Unexpected = Exclude<Got, Expected>;
|
||||||
|
|
||||||
|
assert<Equals<Missing, never>>;
|
||||||
|
assert<Equals<Unexpected, never>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
languageTag,
|
||||||
|
label,
|
||||||
|
url: "https://gist.github.com/garronej/52baaca1bb925f2296ab32741e062b8e"
|
||||||
|
} as const;
|
||||||
|
}),
|
||||||
|
|
||||||
currentLanguageTag: "en"
|
currentLanguageTag: "en"
|
||||||
},
|
},
|
||||||
|
@ -43,7 +43,10 @@ export function createGetI18n<
|
|||||||
LanguageTag_notInDefaultSet extends string = never
|
LanguageTag_notInDefaultSet extends string = never
|
||||||
>(params: {
|
>(params: {
|
||||||
extraLanguageTranslations: {
|
extraLanguageTranslations: {
|
||||||
[languageTag in LanguageTag_notInDefaultSet]: () => Promise<{ default: Record<MessageKey_defaultSet, string> }>;
|
[languageTag in LanguageTag_notInDefaultSet]: {
|
||||||
|
label: string;
|
||||||
|
getMessages: () => Promise<{ default: Record<MessageKey_defaultSet, string> }>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
messagesByLanguageTag_themeDefined: Partial<{
|
messagesByLanguageTag_themeDefined: Partial<{
|
||||||
[languageTag in LanguageTag_defaultSet | LanguageTag_notInDefaultSet]: {
|
[languageTag in LanguageTag_defaultSet | LanguageTag_notInDefaultSet]: {
|
||||||
@ -100,7 +103,44 @@ export function createGetI18n<
|
|||||||
|
|
||||||
return targetSupportedLocale.url;
|
return targetSupportedLocale.url;
|
||||||
},
|
},
|
||||||
labelBySupportedLanguageTag: Object.fromEntries((kcContext.locale?.supported ?? []).map(({ languageTag, label }) => [languageTag, label]))
|
labelBySupportedLanguageTag: (() => {
|
||||||
|
const labelBySupportedLanguageTag = Object.fromEntries(
|
||||||
|
(kcContext.locale?.supported ?? []).map(({ languageTag, label }) => [languageTag, label])
|
||||||
|
);
|
||||||
|
|
||||||
|
// NOTE: For IE11
|
||||||
|
if (typeof Proxy === undefined) {
|
||||||
|
return labelBySupportedLanguageTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: This is for convenience in Storybook
|
||||||
|
return new Proxy<Record<string, string>>(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
get: function (...args) {
|
||||||
|
const [, languageTag] = args;
|
||||||
|
|
||||||
|
if (typeof languageTag !== "string") {
|
||||||
|
return window.Reflect.get(...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
let label = labelBySupportedLanguageTag[languageTag];
|
||||||
|
|
||||||
|
if (label === undefined) {
|
||||||
|
assert(is<Exclude<LanguageTag, LanguageTag_defaultSet>>(languageTag));
|
||||||
|
|
||||||
|
const entry = extraLanguageTranslations[languageTag];
|
||||||
|
|
||||||
|
assert(entry !== undefined);
|
||||||
|
|
||||||
|
label = entry.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})()
|
||||||
};
|
};
|
||||||
|
|
||||||
const { createI18nTranslationFunctions } = createI18nTranslationFunctionsFactory<MessageKey_themeDefined>({
|
const { createI18nTranslationFunctions } = createI18nTranslationFunctionsFactory<MessageKey_themeDefined>({
|
||||||
@ -147,12 +187,14 @@ export function createGetI18n<
|
|||||||
if (isEmpty) {
|
if (isEmpty) {
|
||||||
assert(is<Exclude<LanguageTag, LanguageTag_defaultSet>>(currentLanguageTag));
|
assert(is<Exclude<LanguageTag, LanguageTag_defaultSet>>(currentLanguageTag));
|
||||||
|
|
||||||
const asyncFunction = extraLanguageTranslations[currentLanguageTag];
|
const entry = extraLanguageTranslations[currentLanguageTag];
|
||||||
|
|
||||||
assert(asyncFunction !== undefined);
|
assert(entry !== undefined);
|
||||||
|
|
||||||
return asyncFunction().then(({ default: messages }) => messages);
|
return entry.getMessages().then(({ default: messages }) => messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return fromDefaultSet;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
const i18n_currentLanguage: I18n = {
|
const i18n_currentLanguage: I18n = {
|
||||||
|
@ -23,9 +23,12 @@ export type I18nInitializer<
|
|||||||
withExtraLanguages: <
|
withExtraLanguages: <
|
||||||
LanguageTag_notInDefaultSet extends string
|
LanguageTag_notInDefaultSet extends string
|
||||||
>(extraLanguageTranslations: {
|
>(extraLanguageTranslations: {
|
||||||
[LanguageTag in LanguageTag_notInDefaultSet]: () => Promise<{
|
[LanguageTag in LanguageTag_notInDefaultSet]: {
|
||||||
default: Record<MessageKey_defaultSet, string>;
|
label: string;
|
||||||
}>;
|
getMessages: () => Promise<{
|
||||||
|
default: Record<MessageKey_defaultSet, string>;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
}) => I18nInitializer<
|
}) => I18nInitializer<
|
||||||
ThemeName,
|
ThemeName,
|
||||||
MessageKey_themeDefined,
|
MessageKey_themeDefined,
|
||||||
@ -61,9 +64,12 @@ function createI18nInitializer<
|
|||||||
LanguageTag_notInDefaultSet extends string = never
|
LanguageTag_notInDefaultSet extends string = never
|
||||||
>(params: {
|
>(params: {
|
||||||
extraLanguageTranslations: {
|
extraLanguageTranslations: {
|
||||||
[LanguageTag in LanguageTag_notInDefaultSet]: () => Promise<{
|
[LanguageTag in LanguageTag_notInDefaultSet]: {
|
||||||
default: Record<MessageKey_defaultSet, string>;
|
label: string;
|
||||||
}>;
|
getMessages: () => Promise<{
|
||||||
|
default: Record<MessageKey_defaultSet, string>;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
messagesByLanguageTag_themeDefined: Partial<{
|
messagesByLanguageTag_themeDefined: Partial<{
|
||||||
[LanguageTag in LanguageTag_defaultSet | LanguageTag_notInDefaultSet]: Record<
|
[LanguageTag in LanguageTag_defaultSet | LanguageTag_notInDefaultSet]: Record<
|
||||||
|
@ -23,9 +23,12 @@ export type I18nInitializer<
|
|||||||
withExtraLanguages: <
|
withExtraLanguages: <
|
||||||
LanguageTag_notInDefaultSet extends string
|
LanguageTag_notInDefaultSet extends string
|
||||||
>(extraLanguageTranslations: {
|
>(extraLanguageTranslations: {
|
||||||
[LanguageTag in LanguageTag_notInDefaultSet]: () => Promise<{
|
[LanguageTag in LanguageTag_notInDefaultSet]: {
|
||||||
default: Record<MessageKey_defaultSet, string>;
|
label: string;
|
||||||
}>;
|
getMessages: () => Promise<{
|
||||||
|
default: Record<MessageKey_defaultSet, string>;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
}) => I18nInitializer<
|
}) => I18nInitializer<
|
||||||
ThemeName,
|
ThemeName,
|
||||||
MessageKey_themeDefined,
|
MessageKey_themeDefined,
|
||||||
@ -61,9 +64,12 @@ function createI18nInitializer<
|
|||||||
LanguageTag_notInDefaultSet extends string = never
|
LanguageTag_notInDefaultSet extends string = never
|
||||||
>(params: {
|
>(params: {
|
||||||
extraLanguageTranslations: {
|
extraLanguageTranslations: {
|
||||||
[LanguageTag in LanguageTag_notInDefaultSet]: () => Promise<{
|
[LanguageTag in LanguageTag_notInDefaultSet]: {
|
||||||
default: Record<MessageKey_defaultSet, string>;
|
label: string;
|
||||||
}>;
|
getMessages: () => Promise<{
|
||||||
|
default: Record<MessageKey_defaultSet, string>;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
messagesByLanguageTag_themeDefined: Partial<{
|
messagesByLanguageTag_themeDefined: Partial<{
|
||||||
[LanguageTag in LanguageTag_defaultSet | LanguageTag_notInDefaultSet]: Record<
|
[LanguageTag in LanguageTag_defaultSet | LanguageTag_notInDefaultSet]: Record<
|
||||||
|
@ -18,7 +18,10 @@ export function createUseI18n<
|
|||||||
LanguageTag_notInDefaultSet extends string = never
|
LanguageTag_notInDefaultSet extends string = never
|
||||||
>(params: {
|
>(params: {
|
||||||
extraLanguageTranslations: {
|
extraLanguageTranslations: {
|
||||||
[languageTag in LanguageTag_notInDefaultSet]: () => Promise<{ default: Record<MessageKey_defaultSet, string> }>;
|
[languageTag in LanguageTag_notInDefaultSet]: {
|
||||||
|
label: string;
|
||||||
|
getMessages: () => Promise<{ default: Record<MessageKey_defaultSet, string> }>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
messagesByLanguageTag_themeDefined: Partial<{
|
messagesByLanguageTag_themeDefined: Partial<{
|
||||||
[languageTag in LanguageTag_defaultSet | LanguageTag_notInDefaultSet]: {
|
[languageTag in LanguageTag_defaultSet | LanguageTag_notInDefaultSet]: {
|
||||||
|
Reference in New Issue
Block a user