mirror of
https://github.com/logto-io/logto.git
synced 2025-03-31 22:51:25 -05:00
refactor: replace LanguageKey
with LanguageTag
(#2080)
This commit is contained in:
parent
8417fc851a
commit
691bdb3ac9
15 changed files with 67 additions and 58 deletions
|
@ -1,10 +1,10 @@
|
|||
import type { LanguageKey } from '@logto/core-kit';
|
||||
import { LanguageTag } from '@logto/language-kit';
|
||||
import resources from '@logto/phrases';
|
||||
import i18next from 'i18next';
|
||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
|
||||
const initI18n = async (language?: LanguageKey) =>
|
||||
const initI18n = async (language?: LanguageTag) =>
|
||||
i18next
|
||||
.use(initReactI18next)
|
||||
.use(LanguageDetector)
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
// https://react.i18next.com/latest/typescript#create-a-declaration-file
|
||||
|
||||
import { Translation, Errors } from '@logto/phrases';
|
||||
import { LocalPhrase } from '@logto/phrases';
|
||||
|
||||
declare module 'react-i18next' {
|
||||
interface CustomTypeOptions {
|
||||
allowObjectInHTMLChildren: true;
|
||||
resources: {
|
||||
translation: Translation;
|
||||
errors: Errors;
|
||||
};
|
||||
resources: LocalPhrase;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { getDefaultLanguage } from '@logto/core-kit';
|
||||
import { languageOptions } from '@logto/phrases';
|
||||
import {
|
||||
builtInLanguageOptions as consoleBuiltInLanguageOptions,
|
||||
getDefaultLanguageTag,
|
||||
} from '@logto/phrases';
|
||||
import { AppearanceMode } from '@logto/schemas';
|
||||
import classNames from 'classnames';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
|
@ -25,7 +27,7 @@ const Settings = () => {
|
|||
i18n: { language },
|
||||
} = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
|
||||
const defaultLanguage = getDefaultLanguage(language);
|
||||
const defaultLanguage = getDefaultLanguageTag(language);
|
||||
|
||||
const { data, error, update, isLoading, isLoaded } = useUserPreferences();
|
||||
const {
|
||||
|
@ -63,7 +65,7 @@ const Settings = () => {
|
|||
render={({ field: { value, onChange } }) => (
|
||||
<Select
|
||||
value={value ?? defaultLanguage}
|
||||
options={languageOptions}
|
||||
options={consoleBuiltInLanguageOptions}
|
||||
onChange={onChange}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -17,10 +17,11 @@
|
|||
"stylelint": "stylelint \"src/**/*.scss\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@logto/core-kit": "^1.0.0-beta.13",
|
||||
"@logto/language-kit": "1.0.0-beta.16",
|
||||
"@logto/phrases": "^1.0.0-beta.9",
|
||||
"@logto/react": "1.0.0-beta.8",
|
||||
"@logto/schemas": "^1.0.0-beta.9",
|
||||
"@logto/core-kit": "^1.0.0-beta.13",
|
||||
"@parcel/core": "2.7.0",
|
||||
"@parcel/transformer-sass": "2.7.0",
|
||||
"@silverhand/eslint-config": "1.0.0",
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import type { LanguageKey } from '@logto/core-kit';
|
||||
import type { LanguageTag } from '@logto/language-kit';
|
||||
import resources from '@logto/phrases';
|
||||
import i18next from 'i18next';
|
||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
|
||||
const initI18n = async (language?: LanguageKey) =>
|
||||
const initI18n = async (language?: LanguageTag) =>
|
||||
i18next
|
||||
.use(initReactI18next)
|
||||
.use(LanguageDetector)
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
// https://react.i18next.com/latest/typescript#create-a-declaration-file
|
||||
|
||||
import { Translation, Errors } from '@logto/phrases';
|
||||
import { LocalPhrase } from '@logto/phrases';
|
||||
// eslint-disable-next-line unused-imports/no-unused-imports
|
||||
import { CustomTypeOptions } from 'react-i18next';
|
||||
|
||||
declare module 'react-i18next' {
|
||||
interface CustomTypeOptions {
|
||||
allowObjectInHTMLChildren: true;
|
||||
resources: {
|
||||
translation: Translation;
|
||||
errors: Errors;
|
||||
};
|
||||
resources: LocalPhrase;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,9 +29,10 @@
|
|||
"url": "https://github.com/logto-io/logto/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"@logto/core-kit": "^1.0.0-beta.13",
|
||||
"@logto/core-kit": "1.0.0-beta.16",
|
||||
"@logto/language-kit": "1.0.0-beta.15",
|
||||
"@silverhand/essentials": "^1.2.1"
|
||||
"@silverhand/essentials": "^1.2.1",
|
||||
"zod": "^3.18.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@silverhand/eslint-config": "1.0.0",
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import { fallback } from '@logto/core-kit';
|
||||
import { languages, LanguageTag } from '@logto/language-kit';
|
||||
import { NormalizeKeyPaths } from '@silverhand/essentials';
|
||||
import { z } from 'zod';
|
||||
|
||||
import en from './locales/en';
|
||||
import fr from './locales/fr';
|
||||
|
@ -6,16 +9,37 @@ import koKR from './locales/ko-kr';
|
|||
import ptPT from './locales/pt-pt';
|
||||
import trTR from './locales/tr-tr';
|
||||
import zhCN from './locales/zh-cn';
|
||||
import { Resource } from './types';
|
||||
import { LocalPhrase } from './types';
|
||||
|
||||
export type { LocalPhrase } from './types';
|
||||
|
||||
export type I18nKey = NormalizeKeyPaths<typeof en.translation>;
|
||||
|
||||
export const builtInLanguages = ['en', 'fr', 'pt-PT', 'zh-CN', 'ko-KR', 'tr-TR'] as const;
|
||||
|
||||
export const builtInLanguageOptions = builtInLanguages.map((languageTag) => ({
|
||||
value: languageTag,
|
||||
title: languages[languageTag],
|
||||
}));
|
||||
|
||||
export const builtInLanguageTagGuard = z.enum(builtInLanguages);
|
||||
|
||||
export type BuiltInLanguageTag = z.infer<typeof builtInLanguageTagGuard>;
|
||||
|
||||
export { languageOptions } from './types';
|
||||
export type Translation = typeof en.translation;
|
||||
export type Errors = typeof en.errors;
|
||||
export type LogtoErrorCode = NormalizeKeyPaths<Errors>;
|
||||
export type LogtoErrorI18nKey = `errors:${LogtoErrorCode}`;
|
||||
export type I18nKey = NormalizeKeyPaths<Translation>;
|
||||
|
||||
export type AdminConsoleKey = NormalizeKeyPaths<typeof en.translation.admin_console>;
|
||||
|
||||
export const getDefaultLanguageTag = (languages: string): LanguageTag =>
|
||||
builtInLanguageTagGuard.or(fallback<LanguageTag>('en')).parse(languages);
|
||||
|
||||
export const isBuiltInLanguageTag = (language: string): language is BuiltInLanguageTag =>
|
||||
builtInLanguageTagGuard.safeParse(language).success;
|
||||
|
||||
export type Resource = Record<BuiltInLanguageTag, LocalPhrase>;
|
||||
|
||||
const resource: Resource = {
|
||||
en,
|
||||
fr,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import en from '../en';
|
||||
import { LocalPhrase } from '../../types';
|
||||
import errors from './errors';
|
||||
import translation from './translation';
|
||||
|
||||
const fr: typeof en = Object.freeze({
|
||||
const fr: LocalPhrase = Object.freeze({
|
||||
translation,
|
||||
errors,
|
||||
});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import en from '../en';
|
||||
import { LocalPhrase } from '../../types';
|
||||
import errors from './errors';
|
||||
import translation from './translation';
|
||||
|
||||
const koKR: typeof en = Object.freeze({
|
||||
const koKR: LocalPhrase = Object.freeze({
|
||||
translation,
|
||||
errors,
|
||||
});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import en from '../en';
|
||||
import { LocalPhrase } from '../../types';
|
||||
import errors from './errors';
|
||||
import translation from './translation';
|
||||
|
||||
const ptPT: typeof en = Object.freeze({
|
||||
const ptPT: LocalPhrase = Object.freeze({
|
||||
translation,
|
||||
errors,
|
||||
});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import en from '../en';
|
||||
import { LocalPhrase } from '../../types';
|
||||
import errors from './errors';
|
||||
import translation from './translation';
|
||||
|
||||
const trTR: typeof en = Object.freeze({
|
||||
const trTR: LocalPhrase = Object.freeze({
|
||||
translation,
|
||||
errors,
|
||||
});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import en from '../en';
|
||||
import { LocalPhrase } from '../../types';
|
||||
import errors from './errors';
|
||||
import translation from './translation';
|
||||
|
||||
const zhCN: typeof en = Object.freeze({
|
||||
const zhCN: LocalPhrase = Object.freeze({
|
||||
translation,
|
||||
errors,
|
||||
});
|
||||
|
|
|
@ -1,21 +1,3 @@
|
|||
import { LanguageKey, languageKeyGuard } from '@logto/core-kit';
|
||||
import en from './locales/en';
|
||||
|
||||
/* Copied from i18next/index.d.ts */
|
||||
export type Resource = Record<LanguageKey, ResourceLanguage>;
|
||||
|
||||
export type ResourceLanguage = Record<string, ResourceKey>;
|
||||
|
||||
export type ResourceKey = string | Record<string, unknown>;
|
||||
|
||||
const languageCodeAndDisplayNameMappings: Record<LanguageKey, string> = {
|
||||
en: 'English',
|
||||
fr: 'Français',
|
||||
'pt-PT': 'Português',
|
||||
'zh-CN': '简体中文',
|
||||
'tr-TR': 'Türkçe',
|
||||
'ko-KR': '한국어',
|
||||
};
|
||||
|
||||
export const languageOptions: Array<{ value: LanguageKey; title: string }> = Object.entries(
|
||||
languageCodeAndDisplayNameMappings
|
||||
).map(([key, value]) => ({ value: languageKeyGuard.parse(key), title: value }));
|
||||
export type LocalPhrase = typeof en;
|
||||
|
|
11
pnpm-lock.yaml
generated
11
pnpm-lock.yaml
generated
|
@ -318,6 +318,7 @@ importers:
|
|||
packages/demo-app:
|
||||
specifiers:
|
||||
'@logto/core-kit': ^1.0.0-beta.13
|
||||
'@logto/language-kit': 1.0.0-beta.16
|
||||
'@logto/phrases': ^1.0.0-beta.9
|
||||
'@logto/react': 1.0.0-beta.8
|
||||
'@logto/schemas': ^1.0.0-beta.9
|
||||
|
@ -344,6 +345,7 @@ importers:
|
|||
typescript: ^4.7.4
|
||||
devDependencies:
|
||||
'@logto/core-kit': 1.0.0-beta.13
|
||||
'@logto/language-kit': 1.0.0-beta.16
|
||||
'@logto/phrases': link:../phrases
|
||||
'@logto/react': 1.0.0-beta.8_react@18.2.0
|
||||
'@logto/schemas': link:../schemas
|
||||
|
@ -423,7 +425,7 @@ importers:
|
|||
|
||||
packages/phrases:
|
||||
specifiers:
|
||||
'@logto/core-kit': ^1.0.0-beta.13
|
||||
'@logto/core-kit': 1.0.0-beta.16
|
||||
'@logto/language-kit': 1.0.0-beta.15
|
||||
'@silverhand/eslint-config': 1.0.0
|
||||
'@silverhand/essentials': ^1.2.1
|
||||
|
@ -432,10 +434,12 @@ importers:
|
|||
lint-staged: ^13.0.0
|
||||
prettier: ^2.7.1
|
||||
typescript: ^4.7.4
|
||||
zod: ^3.18.0
|
||||
dependencies:
|
||||
'@logto/core-kit': 1.0.0-beta.13
|
||||
'@logto/core-kit': 1.0.0-beta.16
|
||||
'@logto/language-kit': 1.0.0-beta.15
|
||||
'@silverhand/essentials': 1.2.1
|
||||
zod: 3.18.0
|
||||
devDependencies:
|
||||
'@silverhand/eslint-config': 1.0.0_swk2g7ygmfleszo5c33j4vooni
|
||||
'@silverhand/ts-config': 1.0.0_typescript@4.7.4
|
||||
|
@ -2465,7 +2469,7 @@ packages:
|
|||
dependencies:
|
||||
'@logto/language-kit': 1.0.0-beta.16
|
||||
color: 4.2.3
|
||||
nanoid: 3.1.30
|
||||
nanoid: 3.3.4
|
||||
zod: 3.18.0
|
||||
|
||||
/@logto/js/1.0.0-beta.8:
|
||||
|
@ -11288,6 +11292,7 @@ packages:
|
|||
resolution: {integrity: sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==}
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/nanoid/3.3.1:
|
||||
resolution: {integrity: sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==}
|
||||
|
|
Loading…
Add table
Reference in a new issue