From 0641151ca115f31d0ebb1d4c17eb48958927b996 Mon Sep 17 00:00:00 2001 From: garronej Date: Sun, 31 Jul 2022 20:00:57 +0200 Subject: [PATCH] Fix specialization of i18n using global --- src/lib/i18n/createI18nApi.tsx | 16 ++++++++-------- src/lib/i18n/index.ts | 3 +++ src/lib/useFormValidationSlice.tsx | 11 +++-------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/lib/i18n/createI18nApi.tsx b/src/lib/i18n/createI18nApi.tsx index ea5130f9..8988b530 100644 --- a/src/lib/i18n/createI18nApi.tsx +++ b/src/lib/i18n/createI18nApi.tsx @@ -9,9 +9,7 @@ import type { KcContextBase } from "../getKcContext/KcContextBase"; const fallbackLanguageTag = "en"; -export type BaseMessageKey = keyof typeof baseMessages | keyof typeof keycloakifyExtraMessages[typeof fallbackLanguageTag]; - -type I18n = { +export type I18n = { msgStr: (key: MessageKey, ...args: (string | undefined)[]) => string; msg: (key: MessageKey, ...args: (string | undefined)[]) => JSX.Element; /** advancedMsg("${access-denied}") === advancedMsg("access-denied") === msg("access-denied") */ @@ -24,7 +22,7 @@ type I18n = { labelBySupportedLanguageTag: Record; }; -type KcContextLike = { +export type KcContextLike = { locale?: { currentLanguageTag: string; supported: { languageTag: string; url: string; label: string }[]; @@ -39,12 +37,14 @@ export type I18nProviderProps = { kcContext: KcContextLike; }; +const allExtraMessages: { [languageTag: string]: { [key: string]: string } } = {}; + export function createI18nApi(params: { extraMessages: { [languageTag: string]: { [key in ExtraMessageKey]: string } }; }) { - const { extraMessages } = params ?? {}; + Object.assign(allExtraMessages, params.extraMessages); - type MessageKey = ExtraMessageKey | BaseMessageKey; + type MessageKey = ExtraMessageKey | keyof typeof baseMessages | keyof typeof keycloakifyExtraMessages[typeof fallbackLanguageTag]; const context = createContext | undefined>(undefined); @@ -81,12 +81,12 @@ export function createI18nApi(params: { "fallbackMessages": { ...fallbackMessages, ...(keycloakifyExtraMessages[fallbackLanguageTag] ?? {}), - ...(extraMessages?.[fallbackLanguageTag] ?? {}), + ...(allExtraMessages[fallbackLanguageTag] ?? {}), } as any, "messages": { ...messages, ...((keycloakifyExtraMessages as any)[currentLanguageTag] ?? {}), - ...(extraMessages?.[currentLanguageTag] ?? {}), + ...(allExtraMessages[currentLanguageTag] ?? {}), } as any, }), currentLanguageTag, diff --git a/src/lib/i18n/index.ts b/src/lib/i18n/index.ts index 88a3caaa..3d609c04 100644 --- a/src/lib/i18n/index.ts +++ b/src/lib/i18n/index.ts @@ -1,5 +1,8 @@ import { createI18nApi } from "./createI18nApi"; +import type { I18n } from "./createI18nApi"; export const { I18nProvider, useI18n } = createI18nApi({ "extraMessages": {}, }); + +export type MessageKey = ReturnType extends I18n ? U : never; diff --git a/src/lib/useFormValidationSlice.tsx b/src/lib/useFormValidationSlice.tsx index 13c81c6a..f4a7bf8c 100644 --- a/src/lib/useFormValidationSlice.tsx +++ b/src/lib/useFormValidationSlice.tsx @@ -2,19 +2,18 @@ import "./tools/Array.prototype.every"; import React, { useMemo, useReducer, Fragment } from "react"; import type { KcContextBase, Validators, Attribute } from "./getKcContext/KcContextBase"; import { useI18n } from "./i18n"; -import type { KcLanguageTag } from "./i18n"; +import type { MessageKey } from "./i18n"; import { useConstCallback } from "powerhooks/useConstCallback"; import { id } from "tsafe/id"; -import type { MessageKey } from "./i18n"; import { emailRegexp } from "./tools/emailRegExp"; +/** Expect to be used in a component wrapped within a */ export function useGetErrors(params: { kcContext: { messagesPerField: Pick; profile: { attributes: { name: string; value?: string; validators: Validators }[]; }; - locale?: { currentLanguageTag: KcLanguageTag }; }; }) { const { kcContext } = params; @@ -24,7 +23,7 @@ export function useGetErrors(params: { profile: { attributes }, } = kcContext; - const { msg, msgStr, advancedMsg, advancedMsgStr } = getMsg(kcContext); + const { msg, msgStr, advancedMsg, advancedMsgStr } = useI18n(); const getErrors = useConstCallback((params: { name: string; fieldValueByAttributeName: Record }) => { const { name, fieldValueByAttributeName } = params; @@ -313,9 +312,6 @@ export function useFormValidationSlice(params: { }; passwordRequired: boolean; realm: { registrationEmailAsUsername: boolean }; - locale?: { - currentLanguageTag: KcLanguageTag; - }; }; /** NOTE: Try to avoid passing a new ref every render for better performances. */ passwordValidators?: Validators; @@ -385,7 +381,6 @@ export function useFormValidationSlice(params: { "profile": { "attributes": attributesWithPassword, }, - "locale": kcContext.locale, }, });