mirror of
https://github.com/dsoaress/link-free.git
synced 2026-08-16 22:46:04 +01:00
refactor: data format
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
"rules": {
|
||||
"prettier/prettier": "error",
|
||||
"simple-import-sort/imports": "error",
|
||||
"simple-import-sort/exports": "error",
|
||||
"no-unused-vars": "error"
|
||||
"simple-import-sort/exports": "error"
|
||||
}
|
||||
}
|
||||
|
||||
11
package.json
11
package.json
@@ -30,6 +30,7 @@
|
||||
"next-connect": "^0.11.0",
|
||||
"nookies": "^2.5.2",
|
||||
"polished": "^4.1.3",
|
||||
"rc-slider": "^9.7.5",
|
||||
"react": "^17.0.2",
|
||||
"react-collapsible": "^2.8.4",
|
||||
"react-color": "^2.19.3",
|
||||
@@ -44,24 +45,24 @@
|
||||
"@types/bcryptjs": "^2.4.2",
|
||||
"@types/jsonwebtoken": "^8.5.6",
|
||||
"@types/lodash": "^4.14.178",
|
||||
"@types/node": "^16.11.12",
|
||||
"@types/node": "^17.0.0",
|
||||
"@types/react": "17.0.37",
|
||||
"@types/react-color": "^3.0.6",
|
||||
"@types/styled-components": "^5.1.18",
|
||||
"babel-plugin-styled-components": "^2.0.2",
|
||||
"eslint": "8.4.1",
|
||||
"eslint": "8.5.0",
|
||||
"eslint-config-next": "12.0.7",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"eslint-plugin-prettier": "4.0.0",
|
||||
"eslint-plugin-simple-import-sort": "7.0.0",
|
||||
"husky": "7.0.4",
|
||||
"lint-staged": "12.1.2",
|
||||
"prettier": "2.5.0",
|
||||
"lint-staged": "12.1.3",
|
||||
"prettier": "2.5.1",
|
||||
"pretty-quick": "3.1.2",
|
||||
"prisma": "^3.6.0",
|
||||
"react-is": "^17.0.2",
|
||||
"ts-node": "^10.4.0",
|
||||
"typescript": "^4.5.3"
|
||||
"typescript": "^4.5.4"
|
||||
},
|
||||
"prisma": {
|
||||
"seed": "ts-node prisma/seed.ts"
|
||||
|
||||
@@ -17,13 +17,14 @@ async function main() {
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec euismod, nisl eget aliquam consectetur, nisl nunc aliquet nunc, euismod aliquam nunc nisl euismod.',
|
||||
font: '"Roboto", sans-serif',
|
||||
buttonsSchema: 'rounded',
|
||||
outline: true,
|
||||
buttonBorderRadius: '4',
|
||||
colors: {
|
||||
texts: '#000000',
|
||||
socialLinks: '#e11d48',
|
||||
buttonLinks: '#e11d48',
|
||||
background: '#f8fafc'
|
||||
texts: '#e11d48',
|
||||
icons: '#e11d48',
|
||||
background: '#f8fafc',
|
||||
buttonLabelColor: '#f8fafc',
|
||||
buttonBackgroundColor: '#e11d48',
|
||||
buttonBorderColor: '#e11d48'
|
||||
}
|
||||
},
|
||||
socialLinks: [
|
||||
|
||||
@@ -2,19 +2,19 @@ import { darken } from 'polished'
|
||||
import styled from 'styled-components'
|
||||
|
||||
type ButtonProps = {
|
||||
color?: string
|
||||
background?: string
|
||||
variant?: 'square' | 'rounded' | 'pill'
|
||||
outlined?: boolean
|
||||
labelColor?: string
|
||||
backgroundColor?: string
|
||||
borderColor?: string
|
||||
borderRadius?: string
|
||||
font?: string
|
||||
size?: 'small' | 'medium'
|
||||
}
|
||||
|
||||
export const Button = styled.button.attrs((props: ButtonProps) => ({
|
||||
color: props.color || '#f8fafc',
|
||||
background: props.background || '#e11d48',
|
||||
variant: props.variant || 'rounded',
|
||||
outlined: props.outlined || false,
|
||||
labelColor: props.labelColor || '#f8fafc',
|
||||
backgroundColor: props.backgroundColor || '#e11d48',
|
||||
borderColor: props.borderColor || '#e11d48',
|
||||
borderRadius: props.borderRadius || 8,
|
||||
font: props.font || 'inherit',
|
||||
size: props.size || 'medium'
|
||||
}))<ButtonProps>`
|
||||
@@ -24,30 +24,28 @@ export const Button = styled.button.attrs((props: ButtonProps) => ({
|
||||
width: 100%;
|
||||
padding: 0 1rem;
|
||||
font-family: ${({ font }) => font};
|
||||
color: ${({ color }) => color};
|
||||
background: ${({ background }) => background};
|
||||
color: ${({ labelColor }) => labelColor};
|
||||
background: ${({ backgroundColor }) => backgroundColor};
|
||||
border-radius: ${({ borderRadius }) => borderRadius}px;
|
||||
border-width: 2.5px;
|
||||
border-style: solid;
|
||||
border-color: ${({ borderColor }) => borderColor};
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
transition: all 0.25s ease;
|
||||
|
||||
&:hover {
|
||||
background: ${({ background }) => darken(0.1, background)};
|
||||
background: ${({ backgroundColor }) => darken(0.1, backgroundColor!)};
|
||||
border-color: ${({ borderColor }) => darken(0.1, borderColor!)};
|
||||
transform: translateY(-0.15rem);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: ${({ background }) => darken(0.2, background)};
|
||||
background: ${({ backgroundColor }) => darken(0.2, backgroundColor!)};
|
||||
border-color: ${({ borderColor }) => darken(0.2, borderColor!)};
|
||||
}
|
||||
|
||||
${({ variant }) => variant === 'square' && `border-radius: 0;`}
|
||||
|
||||
${({ variant }) => variant === 'rounded' && `border-radius: 0.5rem;`}
|
||||
|
||||
${({ variant }) => variant === 'pill' && `border-radius: 9999px;`}
|
||||
|
||||
${({ size }) =>
|
||||
size === 'small' &&
|
||||
`
|
||||
@@ -61,12 +59,4 @@ export const Button = styled.button.attrs((props: ButtonProps) => ({
|
||||
height: 3rem;
|
||||
font-size: 1rem;
|
||||
`}
|
||||
|
||||
${({ outlined, color }) =>
|
||||
outlined &&
|
||||
`
|
||||
background: transparent;
|
||||
color: ${color};
|
||||
border-color: ${color};
|
||||
`}
|
||||
`
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import { useData } from '../../../hooks/useData'
|
||||
|
||||
export function ButtonsStyleSelect() {
|
||||
const { data, setData } = useData()
|
||||
|
||||
return (
|
||||
<select
|
||||
value={data.settings.buttonsSchema}
|
||||
onChange={e =>
|
||||
setData({
|
||||
...data,
|
||||
settings: {
|
||||
...data.settings,
|
||||
buttonsSchema: e.target.value as 'square' | 'rounded' | 'pill'
|
||||
}
|
||||
})
|
||||
}
|
||||
>
|
||||
<option value="square">Square</option>
|
||||
<option value="rounded">Rounded</option>
|
||||
<option value="pill">Pill</option>
|
||||
</select>
|
||||
)
|
||||
}
|
||||
@@ -4,7 +4,13 @@ import { useData } from '../../../hooks/useData'
|
||||
import { colors } from '../../../styles/colors'
|
||||
|
||||
type ColorPickerProps = {
|
||||
prop: 'texts' | 'socialLinks' | 'background' | 'buttonLinks'
|
||||
prop:
|
||||
| 'texts'
|
||||
| 'icons'
|
||||
| 'background'
|
||||
| 'buttonLabelColor'
|
||||
| 'buttonBackgroundColor'
|
||||
| 'buttonBorderColor'
|
||||
}
|
||||
|
||||
export function ColorPicker({ prop }: ColorPickerProps) {
|
||||
|
||||
@@ -17,18 +17,26 @@ export function ColorsSettings() {
|
||||
|
||||
<div>
|
||||
<h1>Icons</h1>
|
||||
<ColorPicker prop="socialLinks" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1>Buttons</h1>
|
||||
<ColorPicker prop="buttonLinks" />
|
||||
<ColorPicker prop="icons" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1>Background</h1>
|
||||
<ColorPicker prop="background" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1>Buttons</h1>
|
||||
|
||||
<h2>Label</h2>
|
||||
<ColorPicker prop="buttonLabelColor" />
|
||||
|
||||
<h2>Background</h2>
|
||||
<ColorPicker prop="buttonBackgroundColor" />
|
||||
|
||||
<h2>Border</h2>
|
||||
<ColorPicker prop="buttonBorderColor" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,17 +1,40 @@
|
||||
import { ButtonsStyleSelect } from '../ButtonsStyleSelect'
|
||||
import 'rc-slider/assets/index.css'
|
||||
|
||||
import Slider from 'rc-slider'
|
||||
|
||||
import { useData } from '../../../hooks/useData'
|
||||
import { DescriptionInput } from '../DescriptionInput'
|
||||
import { FontsSelect } from '../FontsSelect'
|
||||
import { NameInput } from '../NameInput'
|
||||
import { OutlineCheckbox } from '../OutlineCheckbox'
|
||||
|
||||
export function DataSettings() {
|
||||
const { data, setData } = useData()
|
||||
|
||||
return (
|
||||
<div>
|
||||
<NameInput />
|
||||
<DescriptionInput />
|
||||
<FontsSelect />
|
||||
<ButtonsStyleSelect />
|
||||
<OutlineCheckbox />
|
||||
</div>
|
||||
<>
|
||||
<div>
|
||||
<NameInput />
|
||||
<DescriptionInput />
|
||||
<FontsSelect />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Slider
|
||||
value={+data.settings.buttonBorderRadius}
|
||||
min={0}
|
||||
max={40}
|
||||
step={1}
|
||||
onChange={value =>
|
||||
setData({
|
||||
...data,
|
||||
settings: {
|
||||
...data.settings,
|
||||
buttonBorderRadius: String(value)
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { useData } from '../../../hooks/useData'
|
||||
|
||||
export function OutlineCheckbox() {
|
||||
const { data, setData } = useData()
|
||||
|
||||
return (
|
||||
<input
|
||||
type="checkbox"
|
||||
defaultChecked={data.settings.outline}
|
||||
onChange={() =>
|
||||
setData({
|
||||
...data,
|
||||
settings: {
|
||||
...data.settings,
|
||||
outline: !data.settings.outline
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -44,7 +44,7 @@ export function SaveChangesAlert({
|
||||
<Wrapper>
|
||||
You have unsaved changes.
|
||||
<ButtonsGroup>
|
||||
<Button size="small" outlined onClick={() => handleCancel()}>
|
||||
<Button size="small" backgroundColor="transparent" onClick={() => handleCancel()}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button size="small" onClick={() => handleSave()}>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { isEqual } from 'lodash'
|
||||
import { useEffect, useState } from 'react'
|
||||
import Collapsible from 'react-collapsible'
|
||||
|
||||
import { useAuth } from '../../hooks/useAuth'
|
||||
import { useData } from '../../hooks/useData'
|
||||
import type { Data } from '../../types/Data'
|
||||
import { getLocalStorageData, setLocalStorageData } from '../../utils/localStorage'
|
||||
@@ -21,6 +22,8 @@ export function Dash({ initialData }: DashProps) {
|
||||
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false)
|
||||
const [activeTab, setActiveTab] = useState<'data' | 'colors'>('data')
|
||||
|
||||
const { user } = useAuth()
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoading) {
|
||||
const storageData = getLocalStorageData()
|
||||
@@ -54,6 +57,8 @@ export function Dash({ initialData }: DashProps) {
|
||||
/>
|
||||
<h1>Dash </h1>
|
||||
|
||||
<pre>{JSON.stringify(user, null, 2)}</pre>
|
||||
|
||||
{tabs.map((tab, i) => (
|
||||
<button key={i} onClick={() => setActiveTab(tab.value as 'data' | 'colors')}>
|
||||
{tab.label}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Content, Description, Name, Wrapper } from './styles'
|
||||
|
||||
export const Home = () => {
|
||||
const { data } = useData()
|
||||
const { colors, buttonsSchema, font, name, description } = data.settings
|
||||
const { colors, buttonBorderRadius, font, name, description } = data.settings
|
||||
|
||||
return (
|
||||
<Wrapper color={colors.texts} font={font}>
|
||||
@@ -15,15 +15,17 @@ export const Home = () => {
|
||||
<Name>{name}</Name>
|
||||
<SocialLinks />
|
||||
<Description>{description}</Description>
|
||||
{data.buttonLinks?.map((link, i) => (
|
||||
{data.buttonLinks?.map(link => (
|
||||
<Button
|
||||
as="a"
|
||||
key={link.id}
|
||||
href={link.href}
|
||||
labelColor={colors.buttonLabelColor}
|
||||
backgroundColor={colors.buttonBackgroundColor}
|
||||
borderColor={colors.buttonBorderColor}
|
||||
borderRadius={buttonBorderRadius}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
// key={link.id}
|
||||
key={i}
|
||||
variant={buttonsSchema}
|
||||
>
|
||||
{link.label}
|
||||
</Button>
|
||||
|
||||
@@ -8,6 +8,7 @@ type LinkProps = {
|
||||
export const Link = styled.a.attrs((props: LinkProps) => ({
|
||||
color: props.color || '#e11d48'
|
||||
}))<LinkProps>`
|
||||
color: ${({ color }) => color};
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: color 0.25s ease;
|
||||
|
||||
@@ -34,7 +34,7 @@ export function SocialLinks() {
|
||||
aria-label={label}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
color={data.settings.colors.socialLinks}
|
||||
color={data.settings.colors.icons}
|
||||
>
|
||||
<Icon size={22} />
|
||||
</Link>
|
||||
|
||||
63
src/contexts/AuthContext.tsx
Normal file
63
src/contexts/AuthContext.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import type { User } from '@prisma/client'
|
||||
import { useRouter } from 'next/router'
|
||||
import { parseCookies } from 'nookies'
|
||||
import type { ReactNode } from 'react'
|
||||
import { useEffect } from 'react'
|
||||
import { createContext, useState } from 'react'
|
||||
|
||||
import { api } from '../services/api'
|
||||
import { destroyCookies } from '../utils/destroyCookies'
|
||||
import { retrieveUser } from '../utils/retrieveUser'
|
||||
import { setCookies } from '../utils/setCookies'
|
||||
|
||||
type AuthContextType = {
|
||||
user?: Omit<User, 'password'>
|
||||
signIn: (username: string, password: string) => Promise<void>
|
||||
signOut: () => void
|
||||
}
|
||||
|
||||
type AuthProviderProps = {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export const AuthContext = createContext({} as AuthContextType)
|
||||
|
||||
export const AuthProvider = ({ children }: AuthProviderProps) => {
|
||||
const [user, setUser] = useState<Omit<User, 'password'>>()
|
||||
const { push } = useRouter()
|
||||
|
||||
useEffect(() => {
|
||||
const { accessToken } = parseCookies()
|
||||
if (accessToken) {
|
||||
retrieveUser().then(data => setUser(data))
|
||||
}
|
||||
}, [])
|
||||
|
||||
const signIn = async (username: string, password: string) => {
|
||||
try {
|
||||
const { data: signInData } = await api.post('auth', {
|
||||
username,
|
||||
password
|
||||
})
|
||||
|
||||
setCookies({
|
||||
accessToken: signInData.accessToken,
|
||||
refreshToken: signInData.refreshToken
|
||||
})
|
||||
|
||||
retrieveUser()
|
||||
.then(data => setUser(data))
|
||||
.then(() => push('/dash'))
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
const signOut = () => {
|
||||
destroyCookies()
|
||||
setUser(undefined)
|
||||
push('/')
|
||||
}
|
||||
|
||||
return <AuthContext.Provider value={{ user, signIn, signOut }}>{children}</AuthContext.Provider>
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Dispatch, ReactNode, SetStateAction } from 'react'
|
||||
import type { Dispatch, ReactNode, SetStateAction } from 'react'
|
||||
import { createContext, useState } from 'react'
|
||||
|
||||
import type { Data } from '../types/Data'
|
||||
|
||||
5
src/hooks/useAuth.ts
Normal file
5
src/hooks/useAuth.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { useContext } from 'react'
|
||||
|
||||
import { AuthContext } from '../contexts/AuthContext'
|
||||
|
||||
export const useAuth = () => useContext(AuthContext)
|
||||
@@ -1,14 +1,17 @@
|
||||
import type { AppProps } from 'next/app'
|
||||
|
||||
import { AuthProvider } from '../contexts/AuthContext'
|
||||
import { DataProvider } from '../contexts/DataContext'
|
||||
import { Layout } from '../styles/layout'
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps) {
|
||||
return (
|
||||
<DataProvider initialData={pageProps.initialData}>
|
||||
<Layout>
|
||||
<Component {...pageProps} />
|
||||
</Layout>
|
||||
<AuthProvider>
|
||||
<Layout>
|
||||
<Component {...pageProps} />
|
||||
</Layout>
|
||||
</AuthProvider>
|
||||
</DataProvider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -50,9 +50,9 @@ const handler = nc<NextApiRequest, NextApiResponse>({
|
||||
throw new ExceptionError('Credentials are invalid', 401)
|
||||
}
|
||||
|
||||
const { token, refreshToken } = await createSession(user)
|
||||
const { accessToken, refreshToken } = await createSession(user)
|
||||
|
||||
res.status(200).json({ token, refreshToken })
|
||||
res.status(200).json({ accessToken, refreshToken })
|
||||
})
|
||||
|
||||
export default handler
|
||||
|
||||
@@ -67,7 +67,7 @@ const handler = nc<NextApiRequest, NextApiResponse>({
|
||||
where: { id: refreshToken }
|
||||
})
|
||||
|
||||
res.status(200).json({ token: tokens.token, refreshToken: tokens.refreshToken })
|
||||
res.status(200).json({ accessToken: tokens.accessToken, refreshToken: tokens.refreshToken })
|
||||
})
|
||||
|
||||
export default handler
|
||||
|
||||
56
src/pages/api/users/me.ts
Normal file
56
src/pages/api/users/me.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { Prisma } from '@prisma/client'
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import nc from 'next-connect'
|
||||
|
||||
import { prisma } from '../../../services/prisma'
|
||||
import { authMiddleware } from '../../../utils/authMiddleware'
|
||||
import { ExceptionError } from '../../../utils/error'
|
||||
|
||||
interface Request extends NextApiRequest {
|
||||
userId: string
|
||||
userRole: string
|
||||
}
|
||||
|
||||
const handler = nc<Request, NextApiResponse>({
|
||||
onNoMatch: (_req, res) => {
|
||||
res.status(404).json({ error: 'Not found' })
|
||||
},
|
||||
onError: (err, _req, res) => {
|
||||
if (err instanceof ExceptionError) {
|
||||
res.status(err.status).json({
|
||||
status: err.status,
|
||||
error: err.message
|
||||
})
|
||||
} else if (err instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
res.status(400).json({
|
||||
status: 400,
|
||||
error: err.message
|
||||
})
|
||||
} else {
|
||||
res.status(500).json({
|
||||
status: 500,
|
||||
error: err.message
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
.use(authMiddleware)
|
||||
.get(async (req, res) => {
|
||||
const { userId } = req
|
||||
const response = await prisma.user.findUnique({
|
||||
where: { id: +userId },
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
role: true
|
||||
}
|
||||
})
|
||||
|
||||
if (!response) {
|
||||
throw new ExceptionError('User not found')
|
||||
}
|
||||
|
||||
res.status(200).json(response)
|
||||
})
|
||||
|
||||
export default handler
|
||||
44
src/pages/auth.tsx
Normal file
44
src/pages/auth.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import type { GetServerSideProps } from 'next'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { useAuth } from '../hooks/useAuth'
|
||||
import { fetchData } from '../services/fetchData'
|
||||
|
||||
export default function AuthPage() {
|
||||
const { signIn } = useAuth()
|
||||
const [username, setUsername] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
|
||||
return (
|
||||
<form>
|
||||
<input
|
||||
type="text"
|
||||
value={username}
|
||||
onChange={e => setUsername(e.target.value)}
|
||||
placeholder="username"
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
placeholder="password"
|
||||
/>
|
||||
<button
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
signIn(username, password)
|
||||
}}
|
||||
>
|
||||
Sign In
|
||||
</button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async () => {
|
||||
const initialData = await fetchData()
|
||||
|
||||
return {
|
||||
props: { initialData }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { GetServerSideProps } from 'next'
|
||||
import type { GetServerSideProps } from 'next'
|
||||
|
||||
import { Dash } from '../components/Dash'
|
||||
import { fetchData } from '../services/fetchData'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { GetStaticProps } from 'next'
|
||||
import type { GetStaticProps } from 'next'
|
||||
|
||||
import { Home } from '../components/Home'
|
||||
import { fetchData } from '../services/fetchData'
|
||||
|
||||
@@ -4,13 +4,14 @@ export type Data = {
|
||||
name: string
|
||||
description: string
|
||||
font: string
|
||||
buttonsSchema: 'square' | 'rounded' | 'pill'
|
||||
outline: boolean
|
||||
buttonBorderRadius: string
|
||||
colors: {
|
||||
texts: string
|
||||
socialLinks: string
|
||||
buttonLinks: string
|
||||
icons: string
|
||||
background: string
|
||||
buttonLabelColor: string
|
||||
buttonBackgroundColor: string
|
||||
buttonBorderColor: string
|
||||
}
|
||||
}
|
||||
socialLinks: {
|
||||
|
||||
@@ -23,11 +23,11 @@ export async function createSession(user: User) {
|
||||
})
|
||||
|
||||
const payload = { role: user.role, sub: user.id }
|
||||
const token = jwt.sign(payload, JWT_SECRET, {
|
||||
const accessToken = jwt.sign(payload, JWT_SECRET, {
|
||||
expiresIn: '15m'
|
||||
})
|
||||
|
||||
return { token, refreshToken: session.id }
|
||||
return { accessToken, refreshToken: session.id }
|
||||
} catch (err: any) {
|
||||
throw new ExceptionError(err)
|
||||
}
|
||||
|
||||
12
src/utils/retrieveUser.ts
Normal file
12
src/utils/retrieveUser.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { User } from '@prisma/client'
|
||||
|
||||
import { api } from '../services/api'
|
||||
|
||||
export async function retrieveUser() {
|
||||
try {
|
||||
const { data } = await api.get<Omit<User, 'password'>>('users/me')
|
||||
return data
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ type SetCookiesProps = {
|
||||
|
||||
export function setCookies({ ctx = undefined, accessToken, refreshToken }: SetCookiesProps) {
|
||||
// @ts-ignore
|
||||
api.defaults.headers['Authorization'] = `Bearer ${accessToken}`
|
||||
api.defaults.headers['authorization'] = `Bearer ${accessToken}`
|
||||
|
||||
setCookie(ctx, 'accessToken', accessToken, {
|
||||
maxAge: 60 * 60 * 24 * 30, // 30 days
|
||||
|
||||
151
yarn.lock
151
yarn.lock
@@ -122,6 +122,13 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.10.1", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0":
|
||||
version "7.16.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a"
|
||||
integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.10.2", "@babel/runtime@^7.16.3":
|
||||
version "7.16.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5"
|
||||
@@ -129,13 +136,6 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.14.0":
|
||||
version "7.16.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a"
|
||||
integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/template@^7.16.0":
|
||||
version "7.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6"
|
||||
@@ -617,11 +617,16 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c"
|
||||
integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==
|
||||
|
||||
"@types/node@*", "@types/node@^16.11.12":
|
||||
"@types/node@*":
|
||||
version "16.11.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.12.tgz#ac7fb693ac587ee182c3780c26eb65546a1a3c10"
|
||||
integrity sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==
|
||||
|
||||
"@types/node@^17.0.0":
|
||||
version "17.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.0.tgz#62797cee3b8b497f6547503b2312254d4fe3c2bb"
|
||||
integrity sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw==
|
||||
|
||||
"@types/normalize-package-data@^2.4.0":
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301"
|
||||
@@ -1256,6 +1261,11 @@ classnames@2.2.6:
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
||||
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
|
||||
|
||||
classnames@2.x, classnames@^2.2.1, classnames@^2.2.5, classnames@^2.2.6:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
|
||||
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
|
||||
|
||||
clean-stack@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
|
||||
@@ -1577,7 +1587,7 @@ debug@^3.2.7:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2:
|
||||
debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3:
|
||||
version "4.3.3"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
|
||||
integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
|
||||
@@ -1679,6 +1689,11 @@ doctrine@^3.0.0:
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
dom-align@^1.7.0:
|
||||
version "1.12.2"
|
||||
resolved "https://registry.yarnpkg.com/dom-align/-/dom-align-1.12.2.tgz#0f8164ebd0c9c21b0c790310493cd855892acd4b"
|
||||
integrity sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==
|
||||
|
||||
domain-browser@4.19.0:
|
||||
version "4.19.0"
|
||||
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.19.0.tgz#1093e17c0a17dbd521182fe90d49ac1370054af1"
|
||||
@@ -1750,7 +1765,7 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1:
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
enquirer@^2.3.5, enquirer@^2.3.6:
|
||||
enquirer@^2.3.5:
|
||||
version "2.3.6"
|
||||
resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
|
||||
integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==
|
||||
@@ -1966,10 +1981,10 @@ eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.1.0:
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz#eee4acea891814cda67a7d8812d9647dd0179af2"
|
||||
integrity sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==
|
||||
|
||||
eslint@8.4.1:
|
||||
version "8.4.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.4.1.tgz#d6531bbf3e598dffd7c0c7d35ec52a0b30fdfa2d"
|
||||
integrity sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==
|
||||
eslint@8.5.0:
|
||||
version "8.5.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.5.0.tgz#ddd2c1afd8f412036f87ae2a063d2aa296d3175f"
|
||||
integrity sha512-tVGSkgNbOfiHyVte8bCM8OmX+xG9PzVG/B4UCF60zx7j61WIVY/AqJECDgpLD4DbbESD0e174gOg3ZlrX15GDg==
|
||||
dependencies:
|
||||
"@eslint/eslintrc" "^1.0.5"
|
||||
"@humanwhocodes/config-array" "^0.9.2"
|
||||
@@ -2928,27 +2943,26 @@ lines-and-columns@^1.1.6:
|
||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
||||
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
|
||||
|
||||
lint-staged@12.1.2:
|
||||
version "12.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-12.1.2.tgz#90c571927e1371fc133e720671dd7989eab53f74"
|
||||
integrity sha512-bSMcQVqMW98HLLLR2c2tZ+vnDCnx4fd+0QJBQgN/4XkdspGRPc8DGp7UuOEBe1ApCfJ+wXXumYnJmU+wDo7j9A==
|
||||
lint-staged@12.1.3:
|
||||
version "12.1.3"
|
||||
resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-12.1.3.tgz#a16e885c0a5e77de9cf559724d29a10348670e68"
|
||||
integrity sha512-ajapdkaFxx+MVhvq6xQRg9zCnCLz49iQLJZP7+w8XaA3U4B35Z9xJJGq9vxmWo73QTvJLG+N2NxhjWiSexbAWQ==
|
||||
dependencies:
|
||||
cli-truncate "^3.1.0"
|
||||
colorette "^2.0.16"
|
||||
commander "^8.3.0"
|
||||
debug "^4.3.2"
|
||||
enquirer "^2.3.6"
|
||||
debug "^4.3.3"
|
||||
execa "^5.1.1"
|
||||
lilconfig "2.0.4"
|
||||
listr2 "^3.13.3"
|
||||
listr2 "^3.13.5"
|
||||
micromatch "^4.0.4"
|
||||
normalize-path "^3.0.0"
|
||||
object-inspect "^1.11.0"
|
||||
object-inspect "^1.11.1"
|
||||
string-argv "^0.3.1"
|
||||
supports-color "^9.0.2"
|
||||
supports-color "^9.2.1"
|
||||
yaml "^1.10.2"
|
||||
|
||||
listr2@^3.13.3:
|
||||
listr2@^3.13.5:
|
||||
version "3.13.5"
|
||||
resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.13.5.tgz#105a813f2eb2329c4aae27373a281d610ee4985f"
|
||||
integrity sha512-3n8heFQDSk+NcwBn3CgxEibZGaRzx+pC64n3YjpMD1qguV4nWus3Al+Oo3KooqFKTQEJ1v7MmnbnyyNspgx3NA==
|
||||
@@ -3421,6 +3435,11 @@ object-inspect@^1.11.0, object-inspect@^1.9.0:
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.1.tgz#d4bd7d7de54b9a75599f59a00bd698c1f1c6549b"
|
||||
integrity sha512-If7BjFlpkzzBeV1cqgT3OSWT3azyoxDGajR+iGnFBfVV2EWyDyWaZZW2ERDjUaY2QM8i5jI3Sj7mhsM4DDAqWA==
|
||||
|
||||
object-inspect@^1.11.1:
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0"
|
||||
integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
|
||||
|
||||
object-is@^1.0.1:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac"
|
||||
@@ -3724,10 +3743,10 @@ prettier-linter-helpers@^1.0.0:
|
||||
dependencies:
|
||||
fast-diff "^1.1.2"
|
||||
|
||||
prettier@2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.0.tgz#a6370e2d4594e093270419d9cc47f7670488f893"
|
||||
integrity sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg==
|
||||
prettier@2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a"
|
||||
integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==
|
||||
|
||||
pretty-quick@3.1.2:
|
||||
version "3.1.2"
|
||||
@@ -3849,6 +3868,66 @@ raw-body@2.4.1:
|
||||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
rc-align@^4.0.0:
|
||||
version "4.0.11"
|
||||
resolved "https://registry.yarnpkg.com/rc-align/-/rc-align-4.0.11.tgz#8198c62db266bc1b8ef05e56c13275bf72628a5e"
|
||||
integrity sha512-n9mQfIYQbbNTbefyQnRHZPWuTEwG1rY4a9yKlIWHSTbgwI+XUMGRYd0uJ5pE2UbrNX0WvnMBA1zJ3Lrecpra/A==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "2.x"
|
||||
dom-align "^1.7.0"
|
||||
lodash "^4.17.21"
|
||||
rc-util "^5.3.0"
|
||||
resize-observer-polyfill "^1.5.1"
|
||||
|
||||
rc-motion@^2.0.0:
|
||||
version "2.4.4"
|
||||
resolved "https://registry.yarnpkg.com/rc-motion/-/rc-motion-2.4.4.tgz#e995d5fa24fc93065c24f714857cf2677d655bb0"
|
||||
integrity sha512-ms7n1+/TZQBS0Ydd2Q5P4+wJTSOrhIrwNxLXCZpR7Fa3/oac7Yi803HDALc2hLAKaCTQtw9LmQeB58zcwOsqlQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.11.1"
|
||||
classnames "^2.2.1"
|
||||
rc-util "^5.2.1"
|
||||
|
||||
rc-slider@^9.7.5:
|
||||
version "9.7.5"
|
||||
resolved "https://registry.yarnpkg.com/rc-slider/-/rc-slider-9.7.5.tgz#193141c68e99b1dc3b746daeb6bf852946f5b7f4"
|
||||
integrity sha512-LV/MWcXFjco1epPbdw1JlLXlTgmWpB9/Y/P2yinf8Pg3wElHxA9uajN21lJiWtZjf5SCUekfSP6QMJfDo4t1hg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "^2.2.5"
|
||||
rc-tooltip "^5.0.1"
|
||||
rc-util "^5.16.1"
|
||||
shallowequal "^1.1.0"
|
||||
|
||||
rc-tooltip@^5.0.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-tooltip/-/rc-tooltip-5.1.1.tgz#94178ed162d0252bc4993b725f5dc2ac0fccf154"
|
||||
integrity sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.11.2"
|
||||
rc-trigger "^5.0.0"
|
||||
|
||||
rc-trigger@^5.0.0:
|
||||
version "5.2.10"
|
||||
resolved "https://registry.yarnpkg.com/rc-trigger/-/rc-trigger-5.2.10.tgz#8a0057a940b1b9027eaa33beec8a6ecd85cce2b1"
|
||||
integrity sha512-FkUf4H9BOFDaIwu42fvRycXMAvkttph9AlbCZXssZDVzz2L+QZ0ERvfB/4nX3ZFPh1Zd+uVGr1DEDeXxq4J1TA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.11.2"
|
||||
classnames "^2.2.6"
|
||||
rc-align "^4.0.0"
|
||||
rc-motion "^2.0.0"
|
||||
rc-util "^5.5.0"
|
||||
|
||||
rc-util@^5.16.1, rc-util@^5.2.1, rc-util@^5.3.0, rc-util@^5.5.0:
|
||||
version "5.16.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.16.1.tgz#374db7cb735512f05165ddc3d6b2c61c21b8b4e3"
|
||||
integrity sha512-kSCyytvdb3aRxQacS/71ta6c+kBWvM1v8/2h9d/HaNWauc3qB8pLnF20PJ8NajkNN8gb+rR1l0eWO+D4Pz+LLQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
react-is "^16.12.0"
|
||||
shallowequal "^1.1.0"
|
||||
|
||||
rc@^1.2.7:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
||||
@@ -3896,7 +3975,7 @@ react-is@17.0.2, react-is@^17.0.2:
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
||||
|
||||
react-is@^16.7.0, react-is@^16.8.1:
|
||||
react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
@@ -4010,6 +4089,11 @@ require-directory@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||
|
||||
resize-observer-polyfill@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
|
||||
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
|
||||
|
||||
resolve-from@5.0.0, resolve-from@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
|
||||
@@ -4550,7 +4634,7 @@ supports-color@^8.0.0:
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
supports-color@^9.0.2:
|
||||
supports-color@^9.2.1:
|
||||
version "9.2.1"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.2.1.tgz#599dc9d45acf74c6176e0d880bab1d7d718fe891"
|
||||
integrity sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ==
|
||||
@@ -4757,11 +4841,16 @@ type-fest@^0.8.1:
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||
|
||||
typescript@^4.4.3, typescript@^4.5.3:
|
||||
typescript@^4.4.3:
|
||||
version "4.5.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.3.tgz#afaa858e68c7103317d89eb90c5d8906268d353c"
|
||||
integrity sha512-eVYaEHALSt+s9LbvgEv4Ef+Tdq7hBiIZgii12xXJnukryt3pMgJf6aKhoCZ3FWQsu6sydEnkg11fYXLzhLBjeQ==
|
||||
|
||||
typescript@^4.5.4:
|
||||
version "4.5.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8"
|
||||
integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==
|
||||
|
||||
unbox-primitive@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"
|
||||
|
||||
Reference in New Issue
Block a user