mirror of
https://github.com/logto-io/logto.git
synced 2025-03-24 22:41:28 -05:00
✨ Add register moweb page
This commit is contained in:
parent
2756bd4b83
commit
95c3b1e824
16 changed files with 349 additions and 43 deletions
|
@ -8,6 +8,9 @@ const translation = {
|
|||
},
|
||||
register: {
|
||||
create_account: 'Create an Account',
|
||||
title: 'Sign Up',
|
||||
loading: 'Signing Up...',
|
||||
have_account: 'Already have an account?'
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ const translation = {
|
|||
},
|
||||
register: {
|
||||
create_account: '新用户注册',
|
||||
title: '注册',
|
||||
loading: '注册中...',
|
||||
have_account: '已经有账户?'
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
"@logto/eslint-config-react": "^0.1.0-rc.14",
|
||||
"@logto/ts-config": "^0.1.0-rc.14",
|
||||
"@logto/ts-config-react": "^0.1.0-rc.14",
|
||||
"@testing-library/react": "^12.0.0",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="<%= process.env.PUBLIC_PATH %>favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no user-scalable=0" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<%= htmlWebpackPlugin.tags.headTags %>
|
||||
<!--
|
||||
|
|
|
@ -4,15 +4,17 @@ import AppContent from './components/AppContent';
|
|||
import initI18n from './init/i18n';
|
||||
import Consent from './pages/Consent';
|
||||
import SignIn from './pages/SignIn';
|
||||
import Register from './pages/Register';
|
||||
import './scss/normalized.scss';
|
||||
|
||||
initI18n();
|
||||
|
||||
const App = () => (
|
||||
<AppContent theme="dark">
|
||||
<AppContent theme="light">
|
||||
<Switch>
|
||||
<Route exact path="/sign-in" component={SignIn} />
|
||||
<Route exact path="/sign-in/consent" component={Consent} />
|
||||
<Route exact path="/Register" component={Register} />
|
||||
</Switch>
|
||||
</AppContent>
|
||||
);
|
||||
|
|
15
packages/ui/src/apis/register.ts
Normal file
15
packages/ui/src/apis/register.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import ky from 'ky';
|
||||
|
||||
export const register = async (username: string, password: string) => {
|
||||
type Response = {
|
||||
redirectTo: string;
|
||||
};
|
||||
return ky
|
||||
.post('/api/register', {
|
||||
json: {
|
||||
username,
|
||||
password,
|
||||
},
|
||||
})
|
||||
.json<Response>();
|
||||
};
|
|
@ -13,13 +13,14 @@
|
|||
box-shadow: var(--shadow-button);
|
||||
transition: var(--transition-default-control);
|
||||
cursor: pointer;
|
||||
-webkit-appearance: none;
|
||||
|
||||
&:disabled {
|
||||
background: var(--color-button-background-disabled);
|
||||
color: var(--color-button-text-disabled);
|
||||
}
|
||||
|
||||
&:not(:disabled):hover {
|
||||
background: var(--color-button-background-hover);
|
||||
}
|
||||
// &:not(:disabled):hover {
|
||||
// background: var(--color-button-background-hover);
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||
import styles from './index.module.scss';
|
||||
|
||||
export type Props = {
|
||||
name: string;
|
||||
autoComplete?: AutoCompleteType;
|
||||
isDisabled?: boolean;
|
||||
className?: string;
|
||||
|
@ -13,6 +14,7 @@ export type Props = {
|
|||
};
|
||||
|
||||
const Input = ({
|
||||
name,
|
||||
autoComplete,
|
||||
isDisabled,
|
||||
className,
|
||||
|
@ -23,6 +25,7 @@ const Input = ({
|
|||
}: Props) => {
|
||||
return (
|
||||
<input
|
||||
name={name}
|
||||
disabled={isDisabled}
|
||||
className={classNames(styles.input, className)}
|
||||
placeholder={placeholder}
|
||||
|
|
57
packages/ui/src/pages/Register/index.module.scss
Normal file
57
packages/ui/src/pages/Register/index.module.scss
Normal file
|
@ -0,0 +1,57 @@
|
|||
@use '/src/scss/underscore' as _;
|
||||
|
||||
|
||||
@mixin flex-colomn {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
position: relative;
|
||||
padding: _.unit(8);
|
||||
height: 100%;
|
||||
@include flex-colomn;
|
||||
}
|
||||
|
||||
.form {
|
||||
width: 100%;
|
||||
@include flex-colomn;
|
||||
|
||||
> * {
|
||||
margin-bottom: _.unit(1.5);
|
||||
}
|
||||
|
||||
.title {
|
||||
font: var(--font-heading-1);
|
||||
color: var(--color-heading);
|
||||
margin-bottom: _.unit(9);
|
||||
}
|
||||
|
||||
.box {
|
||||
margin-bottom: _.unit(-6);
|
||||
}
|
||||
|
||||
.box,
|
||||
> input:not([type='button']) {
|
||||
margin-top: _.unit(3);
|
||||
width: 100%;
|
||||
max-width: 320px;
|
||||
}
|
||||
|
||||
> input[type='button'] {
|
||||
margin-top: _.unit(12);
|
||||
}
|
||||
|
||||
.haveAccount {
|
||||
position: absolute;
|
||||
bottom: _.unit(10);
|
||||
}
|
||||
|
||||
.prefix {
|
||||
font: var(--font-body-bold);
|
||||
color: var(--color-placeholder);
|
||||
margin-right: _.unit(0.5);
|
||||
}
|
||||
}
|
70
packages/ui/src/pages/Register/index.tsx
Normal file
70
packages/ui/src/pages/Register/index.tsx
Normal file
|
@ -0,0 +1,70 @@
|
|||
import React, { FC, FormEventHandler, useState, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { register } from '@/apis/register';
|
||||
import Button from '@/components/Button';
|
||||
import Input from '@/components/Input';
|
||||
import MessageBox from '@/components/MessageBox';
|
||||
import TextLink from '@/components/TextLink';
|
||||
|
||||
import styles from './index.module.scss';
|
||||
|
||||
export type PageState = 'idle' | 'loading' | 'error';
|
||||
|
||||
const App: FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [pageState, setPageState] = useState<PageState>('idle');
|
||||
const isLoading = pageState === 'loading';
|
||||
|
||||
const signUp: FormEventHandler = useCallback(async (event) => {
|
||||
event.preventDefault();
|
||||
setPageState('loading');
|
||||
try {
|
||||
window.location.href = (await register(username, password)).redirectTo;
|
||||
} catch {
|
||||
// TODO: Show specific error after merge into monorepo
|
||||
setPageState('error');
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={classNames(styles.wrapper)}>
|
||||
<form className={classNames(styles.form)}>
|
||||
<div className={styles.title}>{t('register.create_account')}</div>
|
||||
<Input
|
||||
name="username"
|
||||
isDisabled={isLoading}
|
||||
placeholder={t('sign_in.username')}
|
||||
value={username}
|
||||
onChange={setUsername} // TODO: account validation
|
||||
/>
|
||||
<Input
|
||||
name="password"
|
||||
isDisabled={isLoading}
|
||||
placeholder={t('sign_in.password')}
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={setPassword} // TODO: password validation
|
||||
/>
|
||||
{pageState === 'error' && (
|
||||
<MessageBox className={styles.box}>{t('sign_in.error')}</MessageBox>
|
||||
)}
|
||||
<Button
|
||||
isDisabled={isLoading}
|
||||
value={isLoading ? t('register.loading') : t('register.title')}
|
||||
onClick={signUp}
|
||||
/>
|
||||
|
||||
<div className={styles.haveAccount}>
|
||||
<span className={styles.prefix}>{t('register.have_account')}</span>
|
||||
<TextLink href="/sign-in">{t('sign_in.title')}</TextLink>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
|
@ -1,13 +1,27 @@
|
|||
@use '/src/scss/underscore' as _;
|
||||
|
||||
.wrapper {
|
||||
position: relative;
|
||||
padding: _.unit(8);
|
||||
|
||||
@mixin flex-colomn {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
position: relative;
|
||||
padding: _.unit(8);
|
||||
height: 100%;
|
||||
@include flex-colomn;
|
||||
}
|
||||
|
||||
.form {
|
||||
width: 100%;
|
||||
@include flex-colomn;
|
||||
|
||||
> * {
|
||||
margin-bottom: _.unit(1.5);
|
||||
}
|
||||
|
||||
.title {
|
||||
font: var(--font-heading-1);
|
||||
|
|
|
@ -1,22 +1,26 @@
|
|||
import React, { FC, FormEventHandler, useState, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { signInBasic } from '@/apis/sign-in';
|
||||
import Button from '@/components/Button';
|
||||
import Input from '@/components/Input';
|
||||
import MessageBox from '@/components/MessageBox';
|
||||
import TextLink from '@/components/TextLink';
|
||||
import React, { FormEventHandler, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import styles from './index.module.scss';
|
||||
|
||||
export type PageState = 'idle' | 'loading' | 'error';
|
||||
|
||||
const Home = () => {
|
||||
const Home: FC = () => {
|
||||
// TODO: Consider creading cross page data modal
|
||||
const { t } = useTranslation();
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [pageState, setPageState] = useState<PageState>('idle');
|
||||
const isLoading = pageState === 'loading';
|
||||
|
||||
const signIn: FormEventHandler = async (event) => {
|
||||
const signIn: FormEventHandler = useCallback(async (event) => {
|
||||
event.preventDefault();
|
||||
setPageState('loading');
|
||||
try {
|
||||
|
@ -25,38 +29,42 @@ const Home = () => {
|
|||
// TODO: Show specific error after merge into monorepo
|
||||
setPageState('error');
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<form className={styles.wrapper}>
|
||||
<div className={styles.title}>Sign in to Logto</div>
|
||||
<Input
|
||||
autoComplete="username"
|
||||
isDisabled={isLoading}
|
||||
placeholder={t('sign_in.password')}
|
||||
value={username}
|
||||
onChange={setUsername}
|
||||
/>
|
||||
<Input
|
||||
autoComplete="current-password"
|
||||
isDisabled={isLoading}
|
||||
placeholder={t('sign_in.password')}
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={setPassword}
|
||||
/>
|
||||
{pageState === 'error' && (
|
||||
<MessageBox className={styles.box}>{t('sign_in.error')}</MessageBox>
|
||||
)}
|
||||
<Button
|
||||
isDisabled={isLoading}
|
||||
value={isLoading ? t('sign_in.loading') : t('sign_in.title')}
|
||||
onClick={signIn}
|
||||
/>
|
||||
<TextLink className={styles.createAccount} href="/register">
|
||||
{t('register.create_account')}
|
||||
</TextLink>
|
||||
</form>
|
||||
<div className={classNames(styles.wrapper)}>
|
||||
<form className={classNames(styles.form)}>
|
||||
<div className={styles.title}>Sign in to Logto</div>
|
||||
<Input
|
||||
name="username"
|
||||
autoComplete="username"
|
||||
isDisabled={isLoading}
|
||||
placeholder={t('sign_in.username')}
|
||||
value={username}
|
||||
onChange={setUsername}
|
||||
/>
|
||||
<Input
|
||||
name="password"
|
||||
autoComplete="current-password"
|
||||
isDisabled={isLoading}
|
||||
placeholder={t('sign_in.password')}
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={setPassword}
|
||||
/>
|
||||
{pageState === 'error' && (
|
||||
<MessageBox className={styles.box}>{t('sign_in.error')}</MessageBox>
|
||||
)}
|
||||
<Button
|
||||
isDisabled={isLoading}
|
||||
value={isLoading ? t('sign_in.loading') : t('sign_in.title')}
|
||||
onClick={signIn}
|
||||
/>
|
||||
<TextLink className={styles.createAccount} href="/register">
|
||||
{t('register.create_account')}
|
||||
</TextLink>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import App from './App';
|
||||
import App from '../App';
|
||||
|
||||
jest.mock('ky', () => ({}));
|
||||
|
22
packages/ui/src/test/pages/Register.test.tsx
Normal file
22
packages/ui/src/test/pages/Register.test.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
import React from 'react';
|
||||
import { render, fireEvent, waitFor } from '@testing-library/react';
|
||||
import App from '@/pages/Register';
|
||||
import { register } from '@/apis/register';
|
||||
|
||||
jest.mock('@/apis/register', () => ({ register: jest.fn(async () => Promise.resolve()) }));
|
||||
|
||||
describe('<App />', () => {
|
||||
test('renders without exploding', async () => {
|
||||
const { queryByText, getByText } = render(<App />);
|
||||
expect(queryByText('register.create_account')).not.toBeNull();
|
||||
expect(queryByText('register.have_account')).not.toBeNull();
|
||||
|
||||
const submit = getByText('register.title');
|
||||
fireEvent.click(submit);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(register).toBeCalled();
|
||||
expect(queryByText('register.loading')).not.toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
21
packages/ui/src/test/pages/SignIn.test.tsx
Normal file
21
packages/ui/src/test/pages/SignIn.test.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
import React from 'react';
|
||||
import { render, fireEvent, waitFor } from '@testing-library/react';
|
||||
import App from '@/pages/SignIn';
|
||||
import { signInBasic } from '@/apis/sign-in';
|
||||
|
||||
jest.mock('@/apis/sign-in', () => ({ signInBasic: jest.fn(async () => Promise.resolve()) }));
|
||||
|
||||
describe('<App />', () => {
|
||||
test('renders without exploding', async () => {
|
||||
const { queryByText, getByText } = render(<App />);
|
||||
expect(queryByText('Sign in to Logto')).not.toBeNull();
|
||||
|
||||
const submit = getByText('sign_in.title');
|
||||
fireEvent.click(submit);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(signInBasic).toBeCalled();
|
||||
expect(queryByText('sign_in.loading')).not.toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
86
pnpm-lock.yaml
generated
86
pnpm-lock.yaml
generated
|
@ -163,6 +163,7 @@ importers:
|
|||
'@logto/phrases': ^0.1.0
|
||||
'@logto/ts-config': ^0.1.0-rc.14
|
||||
'@logto/ts-config-react': ^0.1.0-rc.14
|
||||
'@testing-library/react': ^12.0.0
|
||||
'@types/jest': ^26.0.24
|
||||
'@types/react': ^17.0.14
|
||||
'@types/react-dom': ^17.0.9
|
||||
|
@ -210,6 +211,7 @@ importers:
|
|||
'@logto/eslint-config-react': 0.1.0-rc.14_0b4fa7c4abbcdb6140ac6718cc7d2571
|
||||
'@logto/ts-config': 0.1.0-rc.14_f847e35c67ce67b1737c27c823675243
|
||||
'@logto/ts-config-react': 0.1.0-rc.14_885243f2ccfa42cc3bca8b90895b55f6
|
||||
'@testing-library/react': 12.0.0_react-dom@17.0.2+react@17.0.2
|
||||
'@types/jest': 26.0.24
|
||||
'@types/react': 17.0.15
|
||||
'@types/react-dom': 17.0.9
|
||||
|
@ -1462,6 +1464,14 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@babel/runtime-corejs3/7.14.9:
|
||||
resolution: {integrity: sha512-64RiH2ON4/y8qYtoa8rUiyam/tUVyGqRyNYhe+vCRGmjnV4bUlZvY+mwd0RrmLoCpJpdq3RsrNqKb7SJdw/4kw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
core-js-pure: 3.16.0
|
||||
regenerator-runtime: 0.13.9
|
||||
dev: true
|
||||
|
||||
/@babel/runtime/7.14.8:
|
||||
resolution: {integrity: sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
@ -2935,6 +2945,33 @@ packages:
|
|||
defer-to-connect: 2.0.1
|
||||
dev: false
|
||||
|
||||
/@testing-library/dom/8.1.0:
|
||||
resolution: {integrity: sha512-kmW9alndr19qd6DABzQ978zKQ+J65gU2Rzkl8hriIetPnwpesRaK4//jEQyYh8fEALmGhomD/LBQqt+o+DL95Q==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.14.5
|
||||
'@babel/runtime': 7.14.8
|
||||
'@types/aria-query': 4.2.2
|
||||
aria-query: 4.2.2
|
||||
chalk: 4.1.2
|
||||
dom-accessibility-api: 0.5.6
|
||||
lz-string: 1.4.4
|
||||
pretty-format: 27.0.6
|
||||
dev: true
|
||||
|
||||
/@testing-library/react/12.0.0_react-dom@17.0.2+react@17.0.2:
|
||||
resolution: {integrity: sha512-sh3jhFgEshFyJ/0IxGltRhwZv2kFKfJ3fN1vTZ6hhMXzz9ZbbcTgmDYM4e+zJv+oiVKKEWZPyqPAh4MQBI65gA==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
react-dom: '*'
|
||||
dependencies:
|
||||
'@babel/runtime': 7.14.8
|
||||
'@testing-library/dom': 8.1.0
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
dev: true
|
||||
|
||||
/@tootallnate/once/1.1.2:
|
||||
resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==}
|
||||
engines: {node: '>= 6'}
|
||||
|
@ -2962,6 +2999,10 @@ packages:
|
|||
'@types/node': 16.4.6
|
||||
dev: true
|
||||
|
||||
/@types/aria-query/4.2.2:
|
||||
resolution: {integrity: sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==}
|
||||
dev: true
|
||||
|
||||
/@types/babel__core/7.1.15:
|
||||
resolution: {integrity: sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==}
|
||||
dependencies:
|
||||
|
@ -3800,6 +3841,11 @@ packages:
|
|||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
|
||||
/ansi-styles/5.2.0:
|
||||
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/any-promise/1.3.0:
|
||||
resolution: {integrity: sha1-q8av7tzqUugJzcA3au0845Y10X8=}
|
||||
dev: false
|
||||
|
@ -3844,6 +3890,14 @@ packages:
|
|||
sprintf-js: 1.0.3
|
||||
dev: true
|
||||
|
||||
/aria-query/4.2.2:
|
||||
resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==}
|
||||
engines: {node: '>=6.0'}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.14.8
|
||||
'@babel/runtime-corejs3': 7.14.9
|
||||
dev: true
|
||||
|
||||
/arity-n/1.0.4:
|
||||
resolution: {integrity: sha1-2edrEXM+CFacCEeuezmyhgswt0U=}
|
||||
dev: true
|
||||
|
@ -4754,6 +4808,14 @@ packages:
|
|||
supports-color: 7.2.0
|
||||
dev: true
|
||||
|
||||
/chalk/4.1.2:
|
||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
supports-color: 7.2.0
|
||||
dev: true
|
||||
|
||||
/char-regex/1.0.2:
|
||||
resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -5354,6 +5416,11 @@ packages:
|
|||
semver: 7.0.0
|
||||
dev: true
|
||||
|
||||
/core-js-pure/3.16.0:
|
||||
resolution: {integrity: sha512-wzlhZNepF/QA9yvx3ePDgNGudU5KDB8lu/TRPKelYA/QtSnkS/cLl2W+TIdEX1FAFcBr0YpY7tPDlcmXJ7AyiQ==}
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
|
||||
/core-js/3.15.2:
|
||||
resolution: {integrity: sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==}
|
||||
requiresBuild: true
|
||||
|
@ -6017,6 +6084,10 @@ packages:
|
|||
esutils: 2.0.3
|
||||
dev: true
|
||||
|
||||
/dom-accessibility-api/0.5.6:
|
||||
resolution: {integrity: sha512-DplGLZd8L1lN64jlT27N9TVSESFR5STaEJvX+thCby7fuCHonfPpAlodYc3vuUYbDuDec5w8AMP7oCM5TWFsqw==}
|
||||
dev: true
|
||||
|
||||
/dom-converter/0.2.0:
|
||||
resolution: {integrity: sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==}
|
||||
dependencies:
|
||||
|
@ -9917,6 +9988,11 @@ packages:
|
|||
yallist: 4.0.0
|
||||
dev: true
|
||||
|
||||
/lz-string/1.4.4:
|
||||
resolution: {integrity: sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/make-dir/2.1.0:
|
||||
resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -12219,6 +12295,16 @@ packages:
|
|||
react-is: 17.0.2
|
||||
dev: true
|
||||
|
||||
/pretty-format/27.0.6:
|
||||
resolution: {integrity: sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==}
|
||||
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
||||
dependencies:
|
||||
'@jest/types': 27.0.6
|
||||
ansi-regex: 5.0.0
|
||||
ansi-styles: 5.2.0
|
||||
react-is: 17.0.2
|
||||
dev: true
|
||||
|
||||
/pretty-ms/6.0.1:
|
||||
resolution: {integrity: sha512-ke4njoVmlotekHlHyCZ3wI/c5AMT8peuHs8rKJqekj/oR5G8lND2dVpicFlUz5cbZgE290vvkMuDwfj/OcW1kw==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
Loading…
Add table
Reference in a new issue