diff --git a/packages/console/package.json b/packages/console/package.json index 1b816c659..b3948b6c7 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -18,7 +18,8 @@ }, "devDependencies": { "@fontsource/roboto-mono": "^4.5.7", - "@logto/core-kit": "^1.0.0-beta.13", + "@logto/core-kit": "1.0.0-beta.16", + "@logto/language-kit": "1.0.0-beta.16", "@logto/phrases": "^1.0.0-beta.9", "@logto/phrases-ui": "^1.0.0-beta.9", "@logto/react": "1.0.0-beta.8", diff --git a/packages/console/src/pages/SignInExperience/components/LanguagesForm.tsx b/packages/console/src/pages/SignInExperience/components/LanguagesForm.tsx index ae0475b12..7ed8ff7a9 100644 --- a/packages/console/src/pages/SignInExperience/components/LanguagesForm.tsx +++ b/packages/console/src/pages/SignInExperience/components/LanguagesForm.tsx @@ -1,4 +1,4 @@ -import { languageOptions } from '@logto/phrases-ui'; +import { builtInLanguageOptions } from '@logto/phrases-ui'; import classNames from 'classnames'; import { useState } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; @@ -47,7 +47,7 @@ const LanguagesForm = ({ isManageLanguageVisible = false }: Props) => { name="languageInfo.fallbackLanguage" control={control} render={({ field: { value, onChange } }) => ( - )} />
diff --git a/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageEditor.tsx b/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageEditor.tsx index 0fb511f5e..223819068 100644 --- a/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageEditor.tsx +++ b/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageEditor.tsx @@ -1,5 +1,6 @@ -import type { LanguageKey } from '@logto/core-kit'; -import resource, { languageCodeAndDisplayNameMappings } from '@logto/phrases-ui'; +import { languages, LanguageTag } from '@logto/language-kit'; +import resource, { isBuiltInLanguageTag } from '@logto/phrases-ui'; +import en from '@logto/phrases-ui/lib/locales/en'; import { Translation } from '@logto/schemas'; import cleanDeep from 'clean-deep'; import { useEffect, useMemo } from 'react'; @@ -18,25 +19,26 @@ import * as style from './LanguageEditor.module.scss'; import { CustomPhraseResponse } from './types'; type LanguageEditorProps = { - selectedLanguageKey: LanguageKey; + selectedLanguageTag: LanguageTag; onFormStateChange: (isDirty: boolean) => void; }; const emptyUiTranslation = createEmptyUiTranslation(); -const LanguageEditor = ({ selectedLanguageKey, onFormStateChange }: LanguageEditorProps) => { +const LanguageEditor = ({ selectedLanguageTag, onFormStateChange }: LanguageEditorProps) => { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); - const isBuiltInLanguage = Object.keys(resource).includes(selectedLanguageKey); + const isBuiltIn = isBuiltInLanguageTag(selectedLanguageTag); + const translationEntries = useMemo( - () => Object.entries(resource[selectedLanguageKey].translation), - [selectedLanguageKey] + () => Object.entries((isBuiltIn ? resource[selectedLanguageTag] : en).translation), + [isBuiltIn, selectedLanguageTag] ); const api = useApi(); const { data: customPhrase, mutate } = useSWR( - `/api/custom-phrases/${selectedLanguageKey}`, + `/api/custom-phrases/${selectedLanguageTag}`, { shouldRetryOnError: (error: unknown) => { if (error instanceof RequestError) { @@ -62,7 +64,7 @@ const LanguageEditor = ({ selectedLanguageKey, onFormStateChange }: LanguageEdit const onSubmit = handleSubmit(async (formData: Translation) => { const updatedCustomPhrase = await api - .put(`/api/custom-phrases/${selectedLanguageKey}`, { + .put(`/api/custom-phrases/${selectedLanguageTag}`, { json: { ...cleanDeep(formData), }, @@ -80,9 +82,9 @@ const LanguageEditor = ({ selectedLanguageKey, onFormStateChange }: LanguageEdit return (
- {languageCodeAndDisplayNameMappings[selectedLanguageKey]} - {selectedLanguageKey} - {isBuiltInLanguage && ( + {languages[selectedLanguageTag]} + {selectedLanguageTag} + {isBuiltIn && ( {t('sign_in_exp.others.manage_language.logto_provided')} diff --git a/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageItem.module.scss b/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageItem.module.scss index 94fafa6e0..a61b54822 100644 --- a/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageItem.module.scss +++ b/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageItem.module.scss @@ -11,7 +11,7 @@ color: var(--color-text); } - .languageKey { + .languageTag { font: var(--font-label-large); color: var(--color-caption); } @@ -24,7 +24,7 @@ background-color: var(--color-focused-variant); .languageName, - .languageKey { + .languageTag { color: var(--color-text-link); } } diff --git a/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageItem.tsx b/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageItem.tsx index 0a306dbc2..11cbdef4a 100644 --- a/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageItem.tsx +++ b/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageItem.tsx @@ -1,20 +1,19 @@ -import { LanguageKey } from '@logto/core-kit'; -import { languageCodeAndDisplayNameMappings } from '@logto/phrases-ui'; +import { languages, LanguageTag } from '@logto/language-kit'; import classNames from 'classnames'; import * as style from './LanguageItem.module.scss'; type Props = { - languageKey: LanguageKey; + languageTag: LanguageTag; isSelected: boolean; onClick: () => void; }; -const LanguageItem = ({ languageKey, isSelected, onClick }: Props) => { +const LanguageItem = ({ languageTag, isSelected, onClick }: Props) => { return (
-
{languageCodeAndDisplayNameMappings[languageKey]}
-
{languageKey}
+
{languages[languageTag]}
+
{languageTag}
); }; diff --git a/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageNav.tsx b/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageNav.tsx index 9d246d091..0f8232048 100644 --- a/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageNav.tsx +++ b/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/LanguageNav.tsx @@ -1,4 +1,4 @@ -import { LanguageKey } from '@logto/core-kit'; +import { LanguageTag } from '@logto/language-kit'; import Button from '@/components/Button'; import Plus from '@/icons/Plus'; @@ -7,12 +7,12 @@ import LanguageItem from './LanguageItem'; import * as style from './LanguageNav.module.scss'; type Props = { - languageKeys: LanguageKey[]; - selectedLanguage: LanguageKey; - onSelect: (languageKey: LanguageKey) => void; + languageTags: LanguageTag[]; + selectedLanguageTag: LanguageTag; + onSelect: (languageTag: LanguageTag) => void; }; -const LanguageNav = ({ languageKeys, selectedLanguage, onSelect }: Props) => { +const LanguageNav = ({ languageTags, selectedLanguageTag, onSelect }: Props) => { // TODO: LOG-4146 Add Custom Language return (
@@ -24,13 +24,13 @@ const LanguageNav = ({ languageKeys, selectedLanguage, onSelect }: Props) => { size="medium" />
- {languageKeys.map((key) => ( + {languageTags.map((languageTag) => ( { - onSelect(key); + onSelect(languageTag); }} /> ))} diff --git a/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/index.tsx b/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/index.tsx index d24576117..3d1781d71 100644 --- a/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/index.tsx +++ b/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/index.tsx @@ -1,5 +1,5 @@ -import { getDefaultLanguage, LanguageKey } from '@logto/core-kit'; -import { languageOptions as uiLanguageOptions } from '@logto/phrases-ui'; +import { LanguageTag } from '@logto/language-kit'; +import { builtInLanguages as builtInUiLanguages } from '@logto/phrases-ui'; import { useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import Modal from 'react-modal'; @@ -26,31 +26,33 @@ const ManageLanguageModal = ({ isOpen, onClose }: ManageLanguageModalProps) => { '/api/custom-phrases' ); - const allLanguageKeys = useMemo(() => { - const uiBuiltInLanguageKeys = uiLanguageOptions.map((option) => option.value); - const customUiLanguageKeys = customPhraseResponses?.map(({ languageKey }) => languageKey); + const allLanguageTags = useMemo( + () => + [ + ...new Set([ + ...builtInUiLanguages, + ...(customPhraseResponses?.map(({ languageKey }) => languageKey) ?? []), + ]), + ] + .slice() + .sort(), + [customPhraseResponses] + ); - const allKeys = customUiLanguageKeys?.length - ? [...new Set([...uiBuiltInLanguageKeys, ...customUiLanguageKeys])] - : uiBuiltInLanguageKeys; + const defaultLanguageTag = allLanguageTags[0] ?? 'en'; - return allKeys.slice().sort(); - }, [customPhraseResponses]); - - const defaultLanguageKey = getDefaultLanguage(allLanguageKeys[0] ?? ''); - - const [selectedLanguageKey, setSelectedLanguageKey] = useState(defaultLanguageKey); + const [selectedLanguageTag, setSelectedLanguageTag] = useState(defaultLanguageTag); const [isLanguageEditorDirty, setIsLanguageEditorDirty] = useState(false); const [isUnsavedAlertOpen, setIsUnsavedAlertOpen] = useState(false); - const [preselectedLanguageKey, setPreselectedLanguageKey] = useState(); + const [preselectedLanguageTag, setPreselectedLanguageTag] = useState(); useEffect(() => { if (!isOpen) { - setSelectedLanguageKey(defaultLanguageKey); + setSelectedLanguageTag(defaultLanguageTag); } - }, [allLanguageKeys, setSelectedLanguageKey, isOpen, defaultLanguageKey]); + }, [allLanguageTags, setSelectedLanguageTag, isOpen, defaultLanguageTag]); return ( @@ -60,7 +62,7 @@ const ManageLanguageModal = ({ isOpen, onClose }: ManageLanguageModalProps) => { size="xlarge" onClose={() => { if (isLanguageEditorDirty) { - setPreselectedLanguageKey(undefined); + setPreselectedLanguageTag(undefined); setIsUnsavedAlertOpen(true); return; @@ -70,20 +72,20 @@ const ManageLanguageModal = ({ isOpen, onClose }: ManageLanguageModalProps) => { >
{ + languageTags={allLanguageTags} + selectedLanguageTag={selectedLanguageTag} + onSelect={(languageTag) => { if (isLanguageEditorDirty) { - setPreselectedLanguageKey(languageKey); + setPreselectedLanguageTag(languageTag); setIsUnsavedAlertOpen(true); return; } - setSelectedLanguageKey(languageKey); + setSelectedLanguageTag(languageTag); }} />
@@ -97,9 +99,9 @@ const ManageLanguageModal = ({ isOpen, onClose }: ManageLanguageModalProps) => { onConfirm={() => { setIsUnsavedAlertOpen(false); - if (preselectedLanguageKey) { - setSelectedLanguageKey(preselectedLanguageKey); - setPreselectedLanguageKey(undefined); + if (preselectedLanguageTag) { + setSelectedLanguageTag(preselectedLanguageTag); + setPreselectedLanguageTag(undefined); return; } diff --git a/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/types.ts b/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/types.ts index 3b9549af8..164e76f73 100644 --- a/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/types.ts +++ b/packages/console/src/pages/SignInExperience/components/ManageLanguageModal/types.ts @@ -1,7 +1,7 @@ -import type { LanguageKey } from '@logto/core-kit'; +import type { LanguageTag } from '@logto/language-kit'; import type { Translation } from '@logto/schemas'; export type CustomPhraseResponse = { - languageKey: LanguageKey; + languageKey: LanguageTag; translation: Translation; }; diff --git a/packages/console/src/pages/SignInExperience/components/Preview.tsx b/packages/console/src/pages/SignInExperience/components/Preview.tsx index b221a4433..5fd1995bd 100644 --- a/packages/console/src/pages/SignInExperience/components/Preview.tsx +++ b/packages/console/src/pages/SignInExperience/components/Preview.tsx @@ -1,5 +1,5 @@ -import type { LanguageKey } from '@logto/core-kit'; -import { languageOptions } from '@logto/phrases-ui'; +import { LanguageTag } from '@logto/language-kit'; +import { builtInLanguageOptions } from '@logto/phrases-ui'; import { AppearanceMode, ConnectorResponse, @@ -28,7 +28,7 @@ type Props = { const Preview = ({ signInExperience, className }: Props) => { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); - const [language, setLanguage] = useState('en'); + const [language, setLanguage] = useState('en'); const [mode, setMode] = useState(AppearanceMode.LightMode); const [platform, setPlatform] = useState<'desktopWeb' | 'mobile' | 'mobileWeb'>('desktopWeb'); const { data: allConnectors } = useSWR('/api/connectors'); @@ -57,12 +57,12 @@ const Preview = ({ signInExperience, className }: Props) => { const availableLanguageOptions = useMemo(() => { if (signInExperience && !signInExperience.languageInfo.autoDetect) { - return languageOptions.filter( + return builtInLanguageOptions.filter( ({ value }) => value === signInExperience.languageInfo.fallbackLanguage ); } - return languageOptions; + return builtInLanguageOptions; }, [signInExperience]); useEffect(() => { diff --git a/packages/core/package.json b/packages/core/package.json index e65c200cc..b08fcc7fb 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -23,7 +23,8 @@ }, "dependencies": { "@logto/connector-kit": "^1.0.0-beta.13", - "@logto/core-kit": "^1.0.0-beta.13", + "@logto/core-kit": "1.0.0-beta.16", + "@logto/language-kit": "1.0.0-beta.16", "@logto/phrases": "^1.0.0-beta.9", "@logto/phrases-ui": "^1.0.0-beta.9", "@logto/schemas": "^1.0.0-beta.9", diff --git a/packages/core/src/lib/phrase.ts b/packages/core/src/lib/phrase.ts index 701596a89..2b98dce66 100644 --- a/packages/core/src/lib/phrase.ts +++ b/packages/core/src/lib/phrase.ts @@ -1,16 +1,12 @@ -import { LanguageKey } from '@logto/core-kit'; -import resource, { LocalePhrase } from '@logto/phrases-ui'; +import resource, { isBuiltInLanguageTag, LocalePhrase } from '@logto/phrases-ui'; import { CustomPhrase } from '@logto/schemas'; import cleanDeep from 'clean-deep'; import deepmerge from 'deepmerge'; import { findCustomPhraseByLanguageKey } from '@/queries/custom-phrase'; -export const isBuiltInLanguage = (key: string): key is LanguageKey => - Object.keys(resource).includes(key); - export const getPhrase = async (supportedLanguage: string, customLanguages: string[]) => { - if (!isBuiltInLanguage(supportedLanguage)) { + if (!isBuiltInLanguageTag(supportedLanguage)) { return deepmerge( resource.en, cleanDeep(await findCustomPhraseByLanguageKey(supportedLanguage)) diff --git a/packages/core/src/routes/phrase.ts b/packages/core/src/routes/phrase.ts index f5958809e..c6ca70fa6 100644 --- a/packages/core/src/routes/phrase.ts +++ b/packages/core/src/routes/phrase.ts @@ -1,8 +1,9 @@ +import { isBuiltInLanguageTag } from '@logto/phrases-ui'; import { adminConsoleApplicationId, adminConsoleSignInExperience } from '@logto/schemas/lib/seeds'; import { Provider } from 'oidc-provider'; import detectLanguage from '@/i18n/detect-language'; -import { isBuiltInLanguage, getPhrase } from '@/lib/phrase'; +import { getPhrase } from '@/lib/phrase'; import { findAllCustomLanguageKeys } from '@/queries/custom-phrase'; import { findDefaultSignInExperience } from '@/queries/sign-in-experience'; @@ -32,8 +33,9 @@ export default function phraseRoutes(router: T, provi const acceptableLanguages = [...detectedLanguages, fallbackLanguage]; const customLanguages = await findAllCustomLanguageKeys(); const language = - acceptableLanguages.find((key) => isBuiltInLanguage(key) || customLanguages.includes(key)) ?? - 'en'; + acceptableLanguages.find( + (key) => isBuiltInLanguageTag(key) || customLanguages.includes(key) + ) ?? 'en'; ctx.set('Content-Language', language); ctx.body = await getPhrase(language, customLanguages); diff --git a/packages/phrases-ui/package.json b/packages/phrases-ui/package.json index 1aec57084..fb7685173 100644 --- a/packages/phrases-ui/package.json +++ b/packages/phrases-ui/package.json @@ -29,8 +29,10 @@ "url": "https://github.com/logto-io/logto/issues" }, "dependencies": { - "@logto/core-kit": "^1.0.0-beta.13", - "@silverhand/essentials": "^1.2.1" + "@logto/core-kit": "1.0.0-beta.16", + "@logto/language-kit": "1.0.0-beta.16", + "@silverhand/essentials": "^1.2.1", + "zod": "^3.18.0" }, "devDependencies": { "@silverhand/eslint-config": "1.0.0", diff --git a/packages/phrases-ui/src/index.ts b/packages/phrases-ui/src/index.ts index 7d7d438ab..eea0892af 100644 --- a/packages/phrases-ui/src/index.ts +++ b/packages/phrases-ui/src/index.ts @@ -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,14 +9,25 @@ 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'; - -export { languageCodeAndDisplayNameMappings, languageOptions } from './types'; +import { LocalePhrase } from './types'; export type { LocalePhrase } from './types'; export type I18nKey = NormalizeKeyPaths; +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; + +export type Resource = Record; + const resource: Resource = { en, fr, @@ -23,4 +37,10 @@ const resource: Resource = { 'tr-TR': trTR, }; +export const getDefaultLanguageTag = (language: string): LanguageTag => + builtInLanguageTagGuard.or(fallback('en')).parse(language); + +export const isBuiltInLanguageTag = (language: string): language is BuiltInLanguageTag => + builtInLanguageTagGuard.safeParse(language).success; + export default resource; diff --git a/packages/phrases-ui/src/types.ts b/packages/phrases-ui/src/types.ts index 209c33698..6c5768035 100644 --- a/packages/phrases-ui/src/types.ts +++ b/packages/phrases-ui/src/types.ts @@ -1,19 +1,3 @@ -import { LanguageKey, languageKeyGuard } from '@logto/core-kit'; - import en from './locales/en'; export type LocalePhrase = typeof en; -export type Resource = Record; - -export const languageCodeAndDisplayNameMappings: Record = { - en: 'English', - fr: 'Français', - 'pt-PT': 'Português', - 'zh-CN': '简体中文', - 'tr-TR': 'Türkçe', - 'ko-KR': '한국어', -}; - -export const languageOptions = Object.entries(languageCodeAndDisplayNameMappings).map( - ([key, value]) => ({ value: languageKeyGuard.parse(key), title: value }) -); diff --git a/packages/phrases/package.json b/packages/phrases/package.json index 326561656..3c6daf68b 100644 --- a/packages/phrases/package.json +++ b/packages/phrases/package.json @@ -30,6 +30,7 @@ }, "dependencies": { "@logto/core-kit": "^1.0.0-beta.13", + "@logto/language-kit": "1.0.0-beta.15", "@silverhand/essentials": "^1.2.1" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11b60cb5c..0818dc9c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,7 +21,8 @@ importers: packages/console: specifiers: '@fontsource/roboto-mono': ^4.5.7 - '@logto/core-kit': ^1.0.0-beta.13 + '@logto/core-kit': 1.0.0-beta.16 + '@logto/language-kit': 1.0.0-beta.16 '@logto/phrases': ^1.0.0-beta.9 '@logto/phrases-ui': ^1.0.0-beta.9 '@logto/react': 1.0.0-beta.8 @@ -86,7 +87,8 @@ importers: zod: ^3.18.0 devDependencies: '@fontsource/roboto-mono': 4.5.7 - '@logto/core-kit': 1.0.0-beta.13 + '@logto/core-kit': 1.0.0-beta.16 + '@logto/language-kit': 1.0.0-beta.16 '@logto/phrases': link:../phrases '@logto/phrases-ui': link:../phrases-ui '@logto/react': 1.0.0-beta.8_react@18.2.0 @@ -153,7 +155,8 @@ importers: packages/core: specifiers: '@logto/connector-kit': ^1.0.0-beta.13 - '@logto/core-kit': ^1.0.0-beta.13 + '@logto/core-kit': 1.0.0-beta.16 + '@logto/language-kit': 1.0.0-beta.16 '@logto/phrases': ^1.0.0-beta.9 '@logto/phrases-ui': ^1.0.0-beta.9 '@logto/schemas': ^1.0.0-beta.9 @@ -231,7 +234,8 @@ importers: zod: ^3.18.0 dependencies: '@logto/connector-kit': 1.0.0-beta.13 - '@logto/core-kit': 1.0.0-beta.13 + '@logto/core-kit': 1.0.0-beta.16 + '@logto/language-kit': 1.0.0-beta.16 '@logto/phrases': link:../phrases '@logto/phrases-ui': link:../phrases-ui '@logto/schemas': link:../schemas @@ -418,6 +422,7 @@ importers: packages/phrases: specifiers: '@logto/core-kit': ^1.0.0-beta.13 + '@logto/language-kit': 1.0.0-beta.15 '@silverhand/eslint-config': 1.0.0 '@silverhand/essentials': ^1.2.1 '@silverhand/ts-config': 1.0.0 @@ -427,6 +432,7 @@ importers: typescript: ^4.7.4 dependencies: '@logto/core-kit': 1.0.0-beta.13 + '@logto/language-kit': 1.0.0-beta.15 '@silverhand/essentials': 1.2.1 devDependencies: '@silverhand/eslint-config': 1.0.0_swk2g7ygmfleszo5c33j4vooni @@ -438,7 +444,8 @@ importers: packages/phrases-ui: specifiers: - '@logto/core-kit': ^1.0.0-beta.13 + '@logto/core-kit': 1.0.0-beta.16 + '@logto/language-kit': 1.0.0-beta.16 '@silverhand/eslint-config': 1.0.0 '@silverhand/essentials': ^1.2.1 '@silverhand/ts-config': 1.0.0 @@ -446,9 +453,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.16 '@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 @@ -2423,7 +2433,7 @@ packages: resolution: {integrity: sha512-bUgAaba1RkYIjHMPrcefLTJAf0d1uVhr864Gh/4JO7/du3xmbFbAWzDyfOhwzt1YZoG4NaMmjVXicfSh/zF/YQ==} engines: {node: ^16.0.0} dependencies: - '@logto/core-kit': 1.0.0-beta.13 + '@logto/core-kit': 1.0.0-beta.16 '@silverhand/essentials': 1.2.1 zod: 3.18.0 dev: false @@ -2445,6 +2455,15 @@ packages: zod: 3.18.0 dev: true + /@logto/core-kit/1.0.0-beta.16: + resolution: {integrity: sha512-6f03W+FczXOusWPB9PiMz8mIMIaylYEyPSmICmN8YmIUJgD7jN1tHRJSZjnuo/8h2L6szm/8oNGqcxgIpBjeWg==} + engines: {node: ^16.0.0} + dependencies: + '@logto/language-kit': 1.0.0-beta.16 + color: 4.2.3 + nanoid: 3.1.30 + zod: 3.18.0 + /@logto/js/1.0.0-beta.8: resolution: {integrity: sha512-Xo63sYZHnoFV+UTCtxRvGk+RuC3yJ3aDEpVDqShSZyfqY0xwGU5naIWHQXOd4koqkAQtp613AdL0qsEshrSl7Q==} dependencies: @@ -2455,6 +2474,19 @@ packages: lodash.get: 4.4.2 dev: true + /@logto/language-kit/1.0.0-beta.15: + resolution: {integrity: sha512-gRwE1E1+pItO/LsczC+hj02/wcIVjPJFB4qFBz580gTaa3rhWVYoZZ0DIGqZMQ0fMZ9Qwq7ncG47lS06gKBPmA==} + engines: {node: ^16.0.0} + dependencies: + zod: 3.18.0 + dev: false + + /@logto/language-kit/1.0.0-beta.16: + resolution: {integrity: sha512-1F7o6DlBrmK9QgZNOzf5RmWjN+36Pak2qfiu7NbMRRAlmNLmADqA0Is6v+cfRb6PMCPmRgbn9Iad5Q7NZctDVg==} + engines: {node: ^16.0.0} + dependencies: + zod: 3.18.0 + /@logto/node/1.0.0-beta.8: resolution: {integrity: sha512-IsQeFGhycUyX1R3/DiODK/nL2tsZaoeITKgqeJP68jiJnO51wPT9ewlFnJ656l/4bCA791oH71WTeeSvKJ8L2w==} dependencies: @@ -3846,7 +3878,7 @@ packages: '@jest/types': 28.1.3 deepmerge: 4.2.2 identity-obj-proxy: 3.0.0 - jest: 28.1.3_k5ytkvaprncdyzidqqws5bqksq + jest: 28.1.3_@types+node@16.11.12 jest-matcher-specific-error: 1.0.0 jest-transform-stub: 2.0.0 ts-jest: 28.0.7_lhw3xkmzugq5tscs3x2ndm4sby @@ -5923,8 +5955,8 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - is-text-path: 1.0.1 JSONStream: 1.3.5 + is-text-path: 1.0.1 lodash: 4.17.21 meow: 8.1.2 split2: 3.2.2 @@ -11252,7 +11284,6 @@ 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==} @@ -11715,7 +11746,7 @@ packages: quick-lru: 5.1.1 raw-body: 2.4.3 optionalDependencies: - paseto3: /paseto/3.1.0 + paseto3: /paseto/3.1.1 transitivePeerDependencies: - supports-color dev: false @@ -12125,8 +12156,8 @@ packages: engines: {node: ^12.19.0 || >=14.15.0} dev: false - /paseto/3.1.0: - resolution: {integrity: sha512-oVSKoCH89M0WU3I+13NoCP9wGRel0BlQumwxsDZPk1yJtqS76PWKRM7vM9D4bz4PcScT0aIiAipC7lW6hSgkBQ==} + /paseto/3.1.1: + resolution: {integrity: sha512-pZmPoGPsR9dBdaKhyKeRLNdvdDbpFA/1Ku/3LuQaY/ssPE4fzSRuNz2+qoSRaIB/mDcbWyzZKjV8ook6AzlsSg==} engines: {node: '>=16.0.0'} requiresBuild: true dev: false @@ -14824,7 +14855,7 @@ packages: '@jest/types': 28.1.3 bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 28.1.3_k5ytkvaprncdyzidqqws5bqksq + jest: 28.1.3_@types+node@16.11.12 jest-util: 28.1.3 json5: 2.2.1 lodash.memoize: 4.1.2