0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor(console,core,phrases): replace LanguageKey with LangaugeTag in phrase-ui related code (#2024)

This commit is contained in:
Xiao Yijun 2022-09-28 18:16:23 +08:00 committed by GitHub
parent 7ce55a8458
commit 2c1610d665
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 153 additions and 112 deletions

View file

@ -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",

View file

@ -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 } }) => (
<Select value={value} options={languageOptions} onChange={onChange} />
<Select value={value} options={builtInLanguageOptions} onChange={onChange} />
)}
/>
<div className={styles.defaultLanguageDescription}>

View file

@ -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<CustomPhraseResponse, RequestError>(
`/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 (
<div className={style.languageEditor}>
<div className={style.title}>
{languageCodeAndDisplayNameMappings[selectedLanguageKey]}
<span>{selectedLanguageKey}</span>
{isBuiltInLanguage && (
{languages[selectedLanguageTag]}
<span>{selectedLanguageTag}</span>
{isBuiltIn && (
<span className={style.builtInFlag}>
{t('sign_in_exp.others.manage_language.logto_provided')}
</span>

View file

@ -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);
}
}

View file

@ -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 (
<div className={classNames(style.languageItem, isSelected && style.selected)} onClick={onClick}>
<div className={style.languageName}>{languageCodeAndDisplayNameMappings[languageKey]}</div>
<div className={style.languageKey}>{languageKey}</div>
<div className={style.languageName}>{languages[languageTag]}</div>
<div className={style.languageTag}>{languageTag}</div>
</div>
);
};

View file

@ -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 (
<div className={style.languageNav}>
@ -24,13 +24,13 @@ const LanguageNav = ({ languageKeys, selectedLanguage, onSelect }: Props) => {
size="medium"
/>
<div>
{languageKeys.map((key) => (
{languageTags.map((languageTag) => (
<LanguageItem
key={key}
languageKey={key}
isSelected={selectedLanguage === key}
key={languageTag}
languageTag={languageTag}
isSelected={selectedLanguageTag === languageTag}
onClick={() => {
onSelect(key);
onSelect(languageTag);
}}
/>
))}

View file

@ -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<LanguageKey>(defaultLanguageKey);
const [selectedLanguageTag, setSelectedLanguageTag] = useState<LanguageTag>(defaultLanguageTag);
const [isLanguageEditorDirty, setIsLanguageEditorDirty] = useState(false);
const [isUnsavedAlertOpen, setIsUnsavedAlertOpen] = useState(false);
const [preselectedLanguageKey, setPreselectedLanguageKey] = useState<LanguageKey>();
const [preselectedLanguageTag, setPreselectedLanguageTag] = useState<LanguageTag>();
useEffect(() => {
if (!isOpen) {
setSelectedLanguageKey(defaultLanguageKey);
setSelectedLanguageTag(defaultLanguageTag);
}
}, [allLanguageKeys, setSelectedLanguageKey, isOpen, defaultLanguageKey]);
}, [allLanguageTags, setSelectedLanguageTag, isOpen, defaultLanguageTag]);
return (
<Modal isOpen={isOpen} className={modalStyles.content} overlayClassName={modalStyles.overlay}>
@ -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) => {
>
<div className={style.container}>
<LanguageNav
languageKeys={allLanguageKeys}
selectedLanguage={selectedLanguageKey}
onSelect={(languageKey) => {
languageTags={allLanguageTags}
selectedLanguageTag={selectedLanguageTag}
onSelect={(languageTag) => {
if (isLanguageEditorDirty) {
setPreselectedLanguageKey(languageKey);
setPreselectedLanguageTag(languageTag);
setIsUnsavedAlertOpen(true);
return;
}
setSelectedLanguageKey(languageKey);
setSelectedLanguageTag(languageTag);
}}
/>
<LanguageEditor
selectedLanguageKey={selectedLanguageKey}
selectedLanguageTag={selectedLanguageTag}
onFormStateChange={setIsLanguageEditorDirty}
/>
</div>
@ -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;
}

View file

@ -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;
};

View file

@ -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<LanguageKey>('en');
const [language, setLanguage] = useState<LanguageTag>('en');
const [mode, setMode] = useState<AppearanceMode>(AppearanceMode.LightMode);
const [platform, setPlatform] = useState<'desktopWeb' | 'mobile' | 'mobileWeb'>('desktopWeb');
const { data: allConnectors } = useSWR<ConnectorResponse[], RequestError>('/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(() => {

View file

@ -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",

View file

@ -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<LocalePhrase, CustomPhrase>(
resource.en,
cleanDeep(await findCustomPhraseByLanguageKey(supportedLanguage))

View file

@ -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<T extends AnonymousRouter>(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);

View file

@ -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",

View file

@ -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<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 type Resource = Record<BuiltInLanguageTag, LocalePhrase>;
const resource: Resource = {
en,
fr,
@ -23,4 +37,10 @@ const resource: Resource = {
'tr-TR': trTR,
};
export const getDefaultLanguageTag = (language: string): LanguageTag =>
builtInLanguageTagGuard.or(fallback<LanguageTag>('en')).parse(language);
export const isBuiltInLanguageTag = (language: string): language is BuiltInLanguageTag =>
builtInLanguageTagGuard.safeParse(language).success;
export default resource;

View file

@ -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<LanguageKey, LocalePhrase>;
export 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 = Object.entries(languageCodeAndDisplayNameMappings).map(
([key, value]) => ({ value: languageKeyGuard.parse(key), title: value })
);

View file

@ -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": {

View file

@ -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