🦴 Add viewer backbone
This commit is contained in:
@ -14,7 +14,7 @@ import { useEditor } from 'contexts/EditorContext'
|
||||
import { useGraph } from 'contexts/GraphContext'
|
||||
import { useTypebot } from 'contexts/TypebotContext'
|
||||
import React, { useMemo, useState } from 'react'
|
||||
import { parseTypebotToPublicTypebot } from 'services/typebots'
|
||||
import { parseTypebotToPublicTypebot } from 'services/publicTypebot'
|
||||
|
||||
export const PreviewDrawer = () => {
|
||||
const { typebot } = useTypebot()
|
||||
|
@ -1,9 +1,18 @@
|
||||
import { Button } from '@chakra-ui/react'
|
||||
import { useTypebot } from 'contexts/TypebotContext'
|
||||
|
||||
export const PublishButton = () => {
|
||||
const { isPublishing, isPublished, publishTypebot } = useTypebot()
|
||||
|
||||
return (
|
||||
<Button ml={2} colorScheme={'blue'}>
|
||||
Publish
|
||||
<Button
|
||||
ml={2}
|
||||
colorScheme="blue"
|
||||
isLoading={isPublishing}
|
||||
isDisabled={isPublished}
|
||||
onClick={publishTypebot}
|
||||
>
|
||||
{isPublished ? 'Published' : 'Publish'}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { Flex } from '@chakra-ui/react'
|
||||
import { TypebotViewer } from 'bot-engine'
|
||||
import { useTypebot } from 'contexts/TypebotContext'
|
||||
import React, { useMemo } from 'react'
|
||||
import { parseTypebotToPublicTypebot } from 'services/typebots'
|
||||
import { parseTypebotToPublicTypebot } from 'services/publicTypebot'
|
||||
import { SideMenu } from './SideMenu'
|
||||
|
||||
export const ThemeContent = () => {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useToast } from '@chakra-ui/react'
|
||||
import {
|
||||
Block,
|
||||
PublicTypebot,
|
||||
Settings,
|
||||
Step,
|
||||
StepType,
|
||||
@ -8,16 +9,25 @@ import {
|
||||
Theme,
|
||||
Typebot,
|
||||
} from 'bot-engine'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { useRouter } from 'next/router'
|
||||
import {
|
||||
createContext,
|
||||
ReactNode,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react'
|
||||
import {
|
||||
createPublishedTypebot,
|
||||
parseTypebotToPublicTypebot,
|
||||
updatePublishedTypebot,
|
||||
} from 'services/publicTypebot'
|
||||
import {
|
||||
checkIfPublished,
|
||||
checkIfTypebotsAreEqual,
|
||||
parseDefaultPublicId,
|
||||
parseNewBlock,
|
||||
parseNewStep,
|
||||
updateTypebot,
|
||||
@ -25,6 +35,8 @@ import {
|
||||
import {
|
||||
fetcher,
|
||||
insertItemInList,
|
||||
isDefined,
|
||||
omit,
|
||||
preventUserFromRefreshing,
|
||||
} from 'services/utils'
|
||||
import useSWR from 'swr'
|
||||
@ -32,6 +44,9 @@ import { NewBlockPayload, Coordinates } from './GraphContext'
|
||||
|
||||
const typebotContext = createContext<{
|
||||
typebot?: Typebot
|
||||
publishedTypebot?: PublicTypebot
|
||||
isPublished: boolean
|
||||
isPublishing: boolean
|
||||
hasUnsavedChanges: boolean
|
||||
isSavingLoading: boolean
|
||||
save: () => void
|
||||
@ -57,6 +72,7 @@ const typebotContext = createContext<{
|
||||
updateTheme: (theme: Theme) => void
|
||||
updateSettings: (settings: Settings) => void
|
||||
updatePublicId: (publicId: string) => void
|
||||
publishTypebot: () => void
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
//@ts-ignore
|
||||
}>({})
|
||||
@ -74,7 +90,7 @@ export const TypebotContext = ({
|
||||
status: 'error',
|
||||
})
|
||||
const [undoStack, setUndoStack] = useState<Typebot[]>([])
|
||||
const { typebot, isLoading, mutate } = useFetchedTypebot({
|
||||
const { typebot, publishedTypebot, isLoading, mutate } = useFetchedTypebot({
|
||||
typebotId,
|
||||
onError: (error) =>
|
||||
toast({
|
||||
@ -83,18 +99,33 @@ export const TypebotContext = ({
|
||||
}),
|
||||
})
|
||||
const [localTypebot, setLocalTypebot] = useState<Typebot>()
|
||||
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false)
|
||||
const [localPublishedTypebot, setLocalPublishedTypebot] =
|
||||
useState<PublicTypebot>()
|
||||
const [isSavingLoading, setIsSavingLoading] = useState(false)
|
||||
const [isPublishing, setIsPublishing] = useState(false)
|
||||
|
||||
const hasUnsavedChanges = useMemo(
|
||||
() =>
|
||||
isDefined(typebot) &&
|
||||
isDefined(localTypebot) &&
|
||||
!deepEqual(localTypebot, typebot),
|
||||
[typebot, localTypebot]
|
||||
)
|
||||
const isPublished = useMemo(
|
||||
() =>
|
||||
isDefined(typebot) &&
|
||||
isDefined(publishedTypebot) &&
|
||||
checkIfPublished(typebot, publishedTypebot),
|
||||
[typebot, publishedTypebot]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (!localTypebot || !typebot) return
|
||||
if (!checkIfTypebotsAreEqual(localTypebot, typebot)) {
|
||||
setHasUnsavedChanges(true)
|
||||
pushNewTypebotInUndoStack(localTypebot)
|
||||
window.removeEventListener('beforeunload', preventUserFromRefreshing)
|
||||
window.addEventListener('beforeunload', preventUserFromRefreshing)
|
||||
} else {
|
||||
setHasUnsavedChanges(false)
|
||||
window.removeEventListener('beforeunload', preventUserFromRefreshing)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@ -108,6 +139,7 @@ export const TypebotContext = ({
|
||||
return
|
||||
}
|
||||
setLocalTypebot({ ...typebot })
|
||||
if (publishedTypebot) setLocalPublishedTypebot({ ...publishedTypebot })
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isLoading])
|
||||
|
||||
@ -128,7 +160,6 @@ export const TypebotContext = ({
|
||||
setIsSavingLoading(false)
|
||||
if (error) return toast({ title: error.name, description: error.message })
|
||||
mutate({ typebot: localTypebot })
|
||||
setHasUnsavedChanges(false)
|
||||
window.removeEventListener('beforeunload', preventUserFromRefreshing)
|
||||
}
|
||||
|
||||
@ -290,10 +321,34 @@ export const TypebotContext = ({
|
||||
setLocalTypebot({ ...localTypebot, publicId })
|
||||
}
|
||||
|
||||
const publishTypebot = async () => {
|
||||
if (!localTypebot) return
|
||||
if (!localPublishedTypebot)
|
||||
updatePublicId(parseDefaultPublicId(localTypebot.name, localTypebot.id))
|
||||
if (hasUnsavedChanges) await saveTypebot()
|
||||
setIsPublishing(true)
|
||||
if (localPublishedTypebot) {
|
||||
const { error } = await updatePublishedTypebot(
|
||||
localPublishedTypebot.id,
|
||||
omit(parseTypebotToPublicTypebot(localTypebot), 'id')
|
||||
)
|
||||
setIsPublishing(false)
|
||||
if (error) return toast({ title: error.name, description: error.message })
|
||||
} else {
|
||||
const { error } = await createPublishedTypebot(
|
||||
omit(parseTypebotToPublicTypebot(localTypebot), 'id')
|
||||
)
|
||||
setIsPublishing(false)
|
||||
if (error) return toast({ title: error.name, description: error.message })
|
||||
}
|
||||
mutate({ typebot: localTypebot })
|
||||
}
|
||||
|
||||
return (
|
||||
<typebotContext.Provider
|
||||
value={{
|
||||
typebot: localTypebot,
|
||||
publishedTypebot: localPublishedTypebot,
|
||||
updateStep,
|
||||
addNewBlock,
|
||||
addStepToBlock,
|
||||
@ -308,6 +363,9 @@ export const TypebotContext = ({
|
||||
updateTheme,
|
||||
updateSettings,
|
||||
updatePublicId,
|
||||
publishTypebot,
|
||||
isPublishing,
|
||||
isPublished,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
@ -324,13 +382,14 @@ export const useFetchedTypebot = ({
|
||||
typebotId?: string
|
||||
onError: (error: Error) => void
|
||||
}) => {
|
||||
const { data, error, mutate } = useSWR<{ typebot: Typebot }, Error>(
|
||||
typebotId ? `/api/typebots/${typebotId}` : null,
|
||||
fetcher
|
||||
)
|
||||
const { data, error, mutate } = useSWR<
|
||||
{ typebot: Typebot; publishedTypebot?: PublicTypebot },
|
||||
Error
|
||||
>(typebotId ? `/api/typebots/${typebotId}` : null, fetcher)
|
||||
if (error) onError(error)
|
||||
return {
|
||||
typebot: data?.typebot,
|
||||
publishedTypebot: data?.publishedTypebot,
|
||||
isLoading: !error && !data,
|
||||
mutate,
|
||||
}
|
||||
|
30
apps/builder/pages/api/publicTypebots.ts
Normal file
30
apps/builder/pages/api/publicTypebots.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import prisma from 'libs/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { getSession } from 'next-auth/react'
|
||||
import { methodNotAllowed } from 'services/api/utils'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const session = await getSession({ req })
|
||||
|
||||
if (!session?.user)
|
||||
return res.status(401).json({ message: 'Not authenticated' })
|
||||
|
||||
try {
|
||||
if (req.method === 'POST') {
|
||||
const data = JSON.parse(req.body)
|
||||
const typebot = await prisma.publicTypebot.create({
|
||||
data: { ...data },
|
||||
})
|
||||
return res.send(typebot)
|
||||
}
|
||||
return methodNotAllowed(res)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
if (err instanceof Error) {
|
||||
return res.status(500).send({ title: err.name, message: err.message })
|
||||
}
|
||||
return res.status(500).send({ message: 'An error occured', error: err })
|
||||
}
|
||||
}
|
||||
|
||||
export default handler
|
24
apps/builder/pages/api/publicTypebots/[id].ts
Normal file
24
apps/builder/pages/api/publicTypebots/[id].ts
Normal file
@ -0,0 +1,24 @@
|
||||
import prisma from 'libs/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { getSession } from 'next-auth/react'
|
||||
import { methodNotAllowed } from 'services/api/utils'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const session = await getSession({ req })
|
||||
|
||||
if (!session?.user)
|
||||
return res.status(401).json({ message: 'Not authenticated' })
|
||||
|
||||
const id = req.query.id.toString()
|
||||
if (req.method === 'PUT') {
|
||||
const data = JSON.parse(req.body)
|
||||
const typebots = await prisma.publicTypebot.update({
|
||||
where: { id },
|
||||
data,
|
||||
})
|
||||
return res.send({ typebots })
|
||||
}
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
@ -13,8 +13,13 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
if (req.method === 'GET') {
|
||||
const typebot = await prisma.typebot.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
publishedTypebot: true,
|
||||
},
|
||||
})
|
||||
return res.send({ typebot })
|
||||
if (!typebot) return res.send({ typebot: null })
|
||||
const { publishedTypebot, ...restOfTypebot } = typebot
|
||||
return res.send({ typebot: restOfTypebot, publishedTypebot })
|
||||
}
|
||||
if (req.method === 'DELETE') {
|
||||
const typebots = await prisma.typebot.delete({
|
||||
|
35
apps/builder/services/publicTypebot.ts
Normal file
35
apps/builder/services/publicTypebot.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { PublicTypebot, Typebot } from 'bot-engine'
|
||||
import { sendRequest } from './utils'
|
||||
import shortId from 'short-uuid'
|
||||
|
||||
export const parseTypebotToPublicTypebot = (
|
||||
typebot: Typebot
|
||||
): PublicTypebot => ({
|
||||
id: shortId.generate(),
|
||||
blocks: typebot.blocks,
|
||||
name: typebot.name,
|
||||
startBlock: typebot.startBlock,
|
||||
typebotId: typebot.id,
|
||||
theme: typebot.theme,
|
||||
settings: typebot.settings,
|
||||
publicId: typebot.publicId,
|
||||
})
|
||||
|
||||
export const createPublishedTypebot = async (
|
||||
typebot: Omit<PublicTypebot, 'id'>
|
||||
) =>
|
||||
sendRequest({
|
||||
url: `/api/publicTypebots`,
|
||||
method: 'POST',
|
||||
body: typebot,
|
||||
})
|
||||
|
||||
export const updatePublishedTypebot = async (
|
||||
id: string,
|
||||
typebot: Omit<PublicTypebot, 'id'>
|
||||
) =>
|
||||
sendRequest({
|
||||
url: `/api/publicTypebots/${id}`,
|
||||
method: 'PUT',
|
||||
body: typebot,
|
||||
})
|
@ -3,8 +3,8 @@ import {
|
||||
StepType,
|
||||
Block,
|
||||
TextStep,
|
||||
PublicTypebot,
|
||||
TextInputStep,
|
||||
PublicTypebot,
|
||||
} from 'bot-engine'
|
||||
import shortId from 'short-uuid'
|
||||
import { Typebot } from 'bot-engine'
|
||||
@ -154,18 +154,16 @@ export const checkIfTypebotsAreEqual = (
|
||||
}
|
||||
)
|
||||
|
||||
export const parseTypebotToPublicTypebot = (
|
||||
typebot: Typebot
|
||||
): PublicTypebot => ({
|
||||
id: shortId.generate(),
|
||||
blocks: typebot.blocks,
|
||||
name: typebot.name,
|
||||
startBlock: typebot.startBlock,
|
||||
typebotId: typebot.id,
|
||||
theme: typebot.theme,
|
||||
settings: typebot.settings,
|
||||
publicId: typebot.publicId,
|
||||
})
|
||||
export const checkIfPublished = (
|
||||
typebot: Typebot,
|
||||
publicTypebot: PublicTypebot
|
||||
) =>
|
||||
deepEqual(typebot.blocks, publicTypebot.blocks) &&
|
||||
deepEqual(typebot.startBlock, publicTypebot.startBlock) &&
|
||||
typebot.name === publicTypebot.name &&
|
||||
typebot.publicId === publicTypebot.publicId &&
|
||||
deepEqual(typebot.settings, publicTypebot.settings) &&
|
||||
deepEqual(typebot.theme, publicTypebot.theme)
|
||||
|
||||
export const parseDefaultPublicId = (name: string, id: string) =>
|
||||
toKebabCase(`${name}-${id?.slice(0, 5)}`)
|
||||
|
@ -71,3 +71,23 @@ export const toKebabCase = (value: string) => {
|
||||
if (!matched) return ''
|
||||
return matched.map((x) => x.toLowerCase()).join('-')
|
||||
}
|
||||
|
||||
interface Omit {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
<T extends object, K extends [...(keyof T)[]]>(obj: T, ...keys: K): {
|
||||
[K2 in Exclude<keyof T, K[number]>]: T[K2]
|
||||
}
|
||||
}
|
||||
|
||||
export const omit: Omit = (obj, ...keys) => {
|
||||
const ret = {} as {
|
||||
[K in keyof typeof obj]: typeof obj[K]
|
||||
}
|
||||
let key: keyof typeof obj
|
||||
for (key in obj) {
|
||||
if (!keys.includes(key)) {
|
||||
ret[key] = obj[key]
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
3
apps/viewer/assets/styles.css
Normal file
3
apps/viewer/assets/styles.css
Normal file
@ -0,0 +1,3 @@
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
62
apps/viewer/components/Seo.tsx
Normal file
62
apps/viewer/components/Seo.tsx
Normal file
@ -0,0 +1,62 @@
|
||||
import Head from 'next/head'
|
||||
import React from 'react'
|
||||
|
||||
type SEOProps = any
|
||||
|
||||
export const SEO = ({
|
||||
iconUrl,
|
||||
thumbnailUrl,
|
||||
title,
|
||||
description,
|
||||
url,
|
||||
chatbotName,
|
||||
}: SEOProps) => (
|
||||
<Head>
|
||||
<title>{title ?? chatbotName}</title>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
href={iconUrl ?? 'https://bot.typebot.io/favicon.png'}
|
||||
/>
|
||||
<meta name="title" content={title ?? chatbotName} />
|
||||
<meta
|
||||
name="description"
|
||||
content={
|
||||
description ??
|
||||
'Build beautiful conversational forms and embed them directly in your applications without a line of code. Triple your response rate and collect answers that has more value compared to a traditional form.'
|
||||
}
|
||||
/>
|
||||
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={url ?? 'https://bot.typebot.io'} />
|
||||
<meta property="og:title" content={title ?? chatbotName} />
|
||||
<meta property="og:site_name" content={title ?? chatbotName} />
|
||||
<meta
|
||||
property="og:description"
|
||||
content={
|
||||
description ??
|
||||
'Build beautiful conversational forms and embed them directly in your applications without a line of code. Triple your response rate and collect answers that has more value compared to a traditional form.'
|
||||
}
|
||||
/>
|
||||
<meta
|
||||
property="og:image"
|
||||
itemProp="image"
|
||||
content={thumbnailUrl ?? 'https://bot.typebot.io/site-preview.png'}
|
||||
/>
|
||||
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:url" content={url ?? 'https://bot.typebot.io'} />
|
||||
<meta property="twitter:title" content={title ?? chatbotName} />
|
||||
<meta
|
||||
property="twitter:description"
|
||||
content={
|
||||
description ??
|
||||
'Build beautiful conversational forms and embed them directly in your applications without a line of code. Triple your response rate and collect answers that has more value compared to a traditional form.'
|
||||
}
|
||||
/>
|
||||
<meta
|
||||
property="twitter:image"
|
||||
content={thumbnailUrl ?? 'https://bot.typebot.io/site-preview.png'}
|
||||
/>
|
||||
</Head>
|
||||
)
|
29
apps/viewer/layouts/ErrorPage.tsx
Normal file
29
apps/viewer/layouts/ErrorPage.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import React from 'react'
|
||||
|
||||
export const ErrorPage = ({ error }: { error: 'offline' | '500' | 'IE' }) => {
|
||||
let errorLabel =
|
||||
'An error occured. Please try to refresh or contact the owner of this bot.'
|
||||
if (error === 'offline') {
|
||||
errorLabel =
|
||||
'Looks like your device is offline. Please, try to refresh the page.'
|
||||
}
|
||||
if (error === 'IE') {
|
||||
errorLabel = "This bot isn't compatible with Internet Explorer."
|
||||
}
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
height: '100vh',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
{error === '500' && (
|
||||
<h1 style={{ fontWeight: 'bold', fontSize: '30px' }}>500</h1>
|
||||
)}
|
||||
<h2>{errorLabel}</h2>
|
||||
</div>
|
||||
)
|
||||
}
|
16
apps/viewer/layouts/NotFoundPage.tsx
Normal file
16
apps/viewer/layouts/NotFoundPage.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import React from 'react'
|
||||
|
||||
export const NotFoundPage = () => (
|
||||
<div
|
||||
style={{
|
||||
height: '100vh',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<h1 style={{ fontWeight: 'bold', fontSize: '30px' }}>404</h1>
|
||||
<h2>The bot you're looking for doesn't exist</h2>
|
||||
</div>
|
||||
)
|
26
apps/viewer/layouts/TypebotPage.tsx
Normal file
26
apps/viewer/layouts/TypebotPage.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import { PublicTypebot, TypebotViewer } from 'bot-engine'
|
||||
import React from 'react'
|
||||
import { SEO } from '../components/Seo'
|
||||
import { ErrorPage } from './ErrorPage'
|
||||
import { NotFoundPage } from './NotFoundPage'
|
||||
|
||||
export type TypebotPageProps = {
|
||||
typebot?: PublicTypebot
|
||||
url: string
|
||||
isIE: boolean
|
||||
}
|
||||
|
||||
export const TypebotPage = ({ typebot, isIE, url }: TypebotPageProps) => {
|
||||
if (!typebot) {
|
||||
return <NotFoundPage />
|
||||
}
|
||||
if (isIE) {
|
||||
return <ErrorPage error={'IE'} />
|
||||
}
|
||||
return (
|
||||
<div style={{ height: '100vh' }}>
|
||||
<SEO url={url} chatbotName={typebot.name} />
|
||||
<TypebotViewer typebot={typebot} />
|
||||
</div>
|
||||
)
|
||||
}
|
15
apps/viewer/libs/prisma.ts
Normal file
15
apps/viewer/libs/prisma.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { PrismaClient } from 'db'
|
||||
|
||||
declare const global: { prisma: PrismaClient }
|
||||
let prisma: PrismaClient
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
prisma = new PrismaClient()
|
||||
} else {
|
||||
if (!global.prisma) {
|
||||
global.prisma = new PrismaClient()
|
||||
}
|
||||
prisma = global.prisma
|
||||
}
|
||||
|
||||
export default prisma
|
@ -11,20 +11,20 @@
|
||||
"dependencies": {
|
||||
"bot-engine": "*",
|
||||
"db": "*",
|
||||
"next": "^12.0.4",
|
||||
"next": "^12.0.7",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.9",
|
||||
"@types/react": "^17.0.35",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"@types/node": "^17.0.4",
|
||||
"@types/react": "^17.0.38",
|
||||
"@typescript-eslint/eslint-plugin": "^5.8.0",
|
||||
"eslint": "<8.0.0",
|
||||
"eslint-config-next": "12.0.4",
|
||||
"eslint-config-next": "12.0.7",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"prettier": "^2.4.1",
|
||||
"prettier": "^2.5.1",
|
||||
"typescript": "^4.5.4"
|
||||
}
|
||||
}
|
||||
|
5
apps/viewer/pages/404.tsx
Normal file
5
apps/viewer/pages/404.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import React from 'react'
|
||||
import { NotFoundPage } from '../layouts/NotFoundPage'
|
||||
|
||||
const NotFoundErrorPage = () => <NotFoundPage />
|
||||
export default NotFoundErrorPage
|
44
apps/viewer/pages/[publicId].tsx
Normal file
44
apps/viewer/pages/[publicId].tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import { PublicTypebot } from 'bot-engine'
|
||||
import { GetServerSideProps, GetServerSidePropsContext } from 'next'
|
||||
import { TypebotPage, TypebotPageProps } from '../layouts/TypebotPage'
|
||||
import prisma from '../libs/prisma'
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async (
|
||||
context: GetServerSidePropsContext
|
||||
) => {
|
||||
let typebot: PublicTypebot | undefined
|
||||
const isIE = /MSIE|Trident/.test(context.req.headers['user-agent'] ?? '')
|
||||
const pathname = context.resolvedUrl.split('?')[0]
|
||||
try {
|
||||
if (!context.req.headers.host) return { props: {} }
|
||||
typebot = await getTypebotFromPublicId(context.query.publicId.toString())
|
||||
if (!typebot) return { props: {} }
|
||||
return {
|
||||
props: {
|
||||
typebot,
|
||||
isIE,
|
||||
url: `https://${context.req.headers.host}${pathname}`,
|
||||
},
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
return {
|
||||
props: {
|
||||
isIE,
|
||||
url: `https://${context.req.headers.host}${pathname}`,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const getTypebotFromPublicId = async (
|
||||
publicId: string
|
||||
): Promise<PublicTypebot | undefined> => {
|
||||
const typebot = await prisma.publicTypebot.findUnique({
|
||||
where: { publicId },
|
||||
})
|
||||
return (typebot as unknown as PublicTypebot | undefined) ?? undefined
|
||||
}
|
||||
|
||||
const App = (props: TypebotPageProps) => <TypebotPage {...props} />
|
||||
export default App
|
15
apps/viewer/pages/_app.tsx
Normal file
15
apps/viewer/pages/_app.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import React from 'react'
|
||||
import '../assets/styles.css'
|
||||
|
||||
type Props = {
|
||||
Component: React.ComponentType
|
||||
pageProps: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
export default function MyApp({ Component, pageProps }: Props): JSX.Element {
|
||||
const { ...componentProps } = pageProps
|
||||
|
||||
return <Component {...componentProps} />
|
||||
}
|
@ -1,7 +1,46 @@
|
||||
import React from 'react'
|
||||
import { PublicTypebot } from 'bot-engine'
|
||||
import { GetServerSideProps, GetServerSidePropsContext } from 'next'
|
||||
import { TypebotPage, TypebotPageProps } from '../layouts/TypebotPage'
|
||||
import prisma from '../libs/prisma'
|
||||
|
||||
const HomePage = () => {
|
||||
return <div>Welcome to "Viewer"!</div>
|
||||
export const getServerSideProps: GetServerSideProps = async (
|
||||
context: GetServerSidePropsContext
|
||||
) => {
|
||||
let typebot: PublicTypebot | undefined
|
||||
const isIE = /MSIE|Trident/.test(context.req.headers['user-agent'] ?? '')
|
||||
const pathname = context.resolvedUrl.split('?')[0]
|
||||
try {
|
||||
if (!context.req.headers.host) return { props: {} }
|
||||
typebot = await getTypebotFromUrl(context.req.headers.host)
|
||||
if (!typebot) return { props: {} }
|
||||
return {
|
||||
props: {
|
||||
typebot,
|
||||
isIE,
|
||||
url: `https://${context.req.headers.host}${pathname}`,
|
||||
},
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
return {
|
||||
props: {
|
||||
isIE,
|
||||
url: `https://${context.req.headers.host}${pathname}`,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default HomePage
|
||||
const getTypebotFromUrl = async (
|
||||
hostname: string
|
||||
): Promise<PublicTypebot | undefined> => {
|
||||
const publicId = hostname.split('.').shift()
|
||||
if (!publicId) return
|
||||
const typebot = await prisma.publicTypebot.findUnique({
|
||||
where: { publicId },
|
||||
})
|
||||
return (typebot as unknown as PublicTypebot | undefined) ?? undefined
|
||||
}
|
||||
|
||||
const App = (props: TypebotPageProps) => <TypebotPage {...props} />
|
||||
export default App
|
||||
|
@ -11,13 +11,12 @@
|
||||
"db:nuke": "docker-compose down --volumes --remove-orphans",
|
||||
"dev": "dotenv -e .env yarn docker:up && dotenv -e .env turbo run dev --parallel",
|
||||
"build": "dotenv -e .env turbo run build",
|
||||
"build:builder": "yarn build --scope=builder --includeDependencies",
|
||||
"test": "dotenv -e .env turbo run dev test",
|
||||
"lint": "turbo run lint"
|
||||
},
|
||||
"devDependencies": {
|
||||
"dotenv-cli": "^4.1.0",
|
||||
"turbo": "^1.0.19"
|
||||
"dotenv-cli": "^4.1.1",
|
||||
"turbo": "^1.0.23"
|
||||
},
|
||||
"turbo": {
|
||||
"baseBranch": "origin/main",
|
||||
|
@ -30,7 +30,7 @@ export const TypebotViewer = ({
|
||||
<Frame
|
||||
id="typebot-iframe"
|
||||
head={<style>{style}</style>}
|
||||
style={{ width: '100%' }}
|
||||
style={{ width: '100%', height: '100%', border: 'none' }}
|
||||
>
|
||||
<style
|
||||
dangerouslySetInnerHTML={{
|
||||
@ -42,7 +42,7 @@ export const TypebotViewer = ({
|
||||
<div
|
||||
className="flex text-base overflow-hidden bg-cover h-screen w-screen flex-col items-center typebot-container"
|
||||
style={{
|
||||
// We set this as inline style to avoid color flashing (due to SSR)
|
||||
// We set this as inline style to avoid color for SSR
|
||||
backgroundColor: containerBgColor,
|
||||
}}
|
||||
>
|
||||
|
241
yarn.lock
241
yarn.lock
@ -1010,13 +1010,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-12.0.7.tgz#316f7bd1b6b69f554d2676cfc91a16bc7e32ee79"
|
||||
integrity sha512-TNDqBV37wd95SiNdZsSUq8gnnrTwr+aN9wqy4Zxrxw4bC/jCHNsbK94DxjkG99VL30VCRXXDBTA1/Wa2jIpF9Q==
|
||||
|
||||
"@next/eslint-plugin-next@12.0.4":
|
||||
version "12.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-12.0.4.tgz#f1751715634e200a868aa3fa42b4c3391254de81"
|
||||
integrity sha512-3N+LG+wQQB0JLfMj4YKkefWnjcsFVBmixRWdzbVBnt/cxbVZ0izf+BR1MzvrPX1oaP0OrYk8X/9Mn9Yftuajvg==
|
||||
dependencies:
|
||||
glob "7.1.7"
|
||||
|
||||
"@next/eslint-plugin-next@12.0.7":
|
||||
version "12.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-12.0.7.tgz#2c71bb66b8f8ff1080086342113406aa3156976f"
|
||||
@ -1288,7 +1281,7 @@
|
||||
estree-walker "^1.0.1"
|
||||
picomatch "^2.2.2"
|
||||
|
||||
"@rushstack/eslint-patch@^1.0.6", "@rushstack/eslint-patch@^1.0.8":
|
||||
"@rushstack/eslint-patch@^1.0.8":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz#7f698254aadf921e48dda8c0a6b304026b8a9323"
|
||||
integrity sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==
|
||||
@ -1447,6 +1440,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.14.tgz#4939fb42e5b0ffb3ea7e193c28244fe7414977a6"
|
||||
integrity sha512-mK6BKLpL0bG6v2CxHbm0ed6RcZrAtTHBTd/ZpnlVPVa3HkumsqLE4BC4u6TQ8D7pnrRbOU0am6epuALs+Ncnzw==
|
||||
|
||||
"@types/node@^17.0.4":
|
||||
version "17.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.4.tgz#fec0ce0526abb6062fd206d72a642811b887a111"
|
||||
integrity sha512-6xwbrW4JJiJLgF+zNypN5wr2ykM9/jHcL7rQ8fZe2vuftggjzZeRSM4OwRc6Xk8qWjwJ99qVHo/JgOGmomWRog==
|
||||
|
||||
"@types/nprogress@^0.2.0":
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/nprogress/-/nprogress-0.2.0.tgz#86c593682d4199212a0509cc3c4d562bbbd6e45f"
|
||||
@ -1476,7 +1474,7 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^17.0.35", "@types/react@^17.0.37":
|
||||
"@types/react@*", "@types/react@^17.0.37":
|
||||
version "17.0.37"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.37.tgz#6884d0aa402605935c397ae689deed115caad959"
|
||||
integrity sha512-2FS1oTqBGcH/s0E+CjrCCR9+JMpsu9b69RTFO+40ua43ZqP5MmQ4iUde/dMjWR909KxZwmOQIFq6AV6NjEG5xg==
|
||||
@ -1485,6 +1483,15 @@
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/react@^17.0.38":
|
||||
version "17.0.38"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.38.tgz#f24249fefd89357d5fa71f739a686b8d7c7202bd"
|
||||
integrity sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/resolve@1.17.1":
|
||||
version "1.17.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6"
|
||||
@ -1546,20 +1553,6 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^5.4.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.7.0.tgz#12d54709f8ea1da99a01d8a992cd0474ad0f0aa9"
|
||||
integrity sha512-8RTGBpNn5a9M628wBPrCbJ+v3YTEOE2qeZb7TDkGKTDXSj36KGRg92SpFFaR/0S3rSXQxM0Og/kV9EyadsYSBg==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "5.7.0"
|
||||
"@typescript-eslint/scope-manager" "5.7.0"
|
||||
debug "^4.3.2"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
ignore "^5.1.8"
|
||||
regexpp "^3.2.0"
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^5.8.0":
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.8.0.tgz#52cd9305ceef98a5333f9492d519e6c6c7fe7d43"
|
||||
@ -1574,18 +1567,6 @@
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/experimental-utils@5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.7.0.tgz#2b1633e6613c3238036156f70c32634843ad034f"
|
||||
integrity sha512-u57eZ5FbEpzN5kSjmVrSesovWslH2ZyNPnaXQMXWgH57d5+EVHEt76W75vVuI9qKZ5BMDKNfRN+pxcPEjQjb2A==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.9"
|
||||
"@typescript-eslint/scope-manager" "5.7.0"
|
||||
"@typescript-eslint/types" "5.7.0"
|
||||
"@typescript-eslint/typescript-estree" "5.7.0"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
"@typescript-eslint/experimental-utils@5.8.0":
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.8.0.tgz#0916ffe98d34b3c95e3652efa0cace61a7b25728"
|
||||
@ -1598,16 +1579,6 @@
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
"@typescript-eslint/parser@^4.20.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899"
|
||||
integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "4.33.0"
|
||||
"@typescript-eslint/types" "4.33.0"
|
||||
"@typescript-eslint/typescript-estree" "4.33.0"
|
||||
debug "^4.3.1"
|
||||
|
||||
"@typescript-eslint/parser@^5.0.0":
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.8.0.tgz#b39970b21c1d7bc4a6018507fb29b380328d2587"
|
||||
@ -1618,22 +1589,6 @@
|
||||
"@typescript-eslint/typescript-estree" "5.8.0"
|
||||
debug "^4.3.2"
|
||||
|
||||
"@typescript-eslint/scope-manager@4.33.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3"
|
||||
integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.33.0"
|
||||
"@typescript-eslint/visitor-keys" "4.33.0"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.7.0.tgz#70adf960e5a58994ad50438ba60d98ecadd79452"
|
||||
integrity sha512-7mxR520DGq5F7sSSgM0HSSMJ+TFUymOeFRMfUfGFAVBv8BR+Jv1vHgAouYUvWRZeszVBJlLcc9fDdktxb5kmxA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.7.0"
|
||||
"@typescript-eslint/visitor-keys" "5.7.0"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.8.0":
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.8.0.tgz#2371095b4fa4c7be6a80b380f4e1b49c715e16f4"
|
||||
@ -1642,47 +1597,11 @@
|
||||
"@typescript-eslint/types" "5.8.0"
|
||||
"@typescript-eslint/visitor-keys" "5.8.0"
|
||||
|
||||
"@typescript-eslint/types@4.33.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72"
|
||||
integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==
|
||||
|
||||
"@typescript-eslint/types@5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.7.0.tgz#2d4cae0105ba7d08bffa69698197a762483ebcbe"
|
||||
integrity sha512-5AeYIF5p2kAneIpnLFve8g50VyAjq7udM7ApZZ9JYjdPjkz0LvODfuSHIDUVnIuUoxafoWzpFyU7Sqbxgi79mA==
|
||||
|
||||
"@typescript-eslint/types@5.8.0":
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.8.0.tgz#e7fa74ec35d9dbe3560d039d3d8734986c3971e0"
|
||||
integrity sha512-LdCYOqeqZWqCMOmwFnum6YfW9F3nKuxJiR84CdIRN5nfHJ7gyvGpXWqL/AaW0k3Po0+wm93ARAsOdzlZDPCcXg==
|
||||
|
||||
"@typescript-eslint/typescript-estree@4.33.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609"
|
||||
integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.33.0"
|
||||
"@typescript-eslint/visitor-keys" "4.33.0"
|
||||
debug "^4.3.1"
|
||||
globby "^11.0.3"
|
||||
is-glob "^4.0.1"
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.7.0.tgz#968fad899050ccce4f08a40cd5fabc0798525006"
|
||||
integrity sha512-aO1Ql+izMrTnPj5aFFlEJkpD4jRqC4Gwhygu2oHK2wfVQpmOPbyDSveJ+r/NQo+PWV43M6uEAeLVbTi09dFLhg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.7.0"
|
||||
"@typescript-eslint/visitor-keys" "5.7.0"
|
||||
debug "^4.3.2"
|
||||
globby "^11.0.4"
|
||||
is-glob "^4.0.3"
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.8.0":
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.8.0.tgz#900469ba9d5a37f4482b014ecce4a5dbb86cb4dd"
|
||||
@ -1696,22 +1615,6 @@
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@4.33.0":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd"
|
||||
integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.33.0"
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.7.0.tgz#e05164239eb7cb8aa9fa06c516ede480ce260178"
|
||||
integrity sha512-hdohahZ4lTFcglZSJ3DGdzxQHBSxsLVqHzkiOmKi7xVAWC4y2c1bIMKmPJSrA4aOEoRUPOKQ87Y/taC7yVHpFg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.7.0"
|
||||
eslint-visitor-keys "^3.0.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.8.0":
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.8.0.tgz#22d4ed96fe2451135299239feedb9fe1dcec780c"
|
||||
@ -3213,7 +3116,7 @@ domutils@^2.8.0:
|
||||
domelementtype "^2.2.0"
|
||||
domhandler "^4.2.0"
|
||||
|
||||
dotenv-cli@^4.1.0:
|
||||
dotenv-cli@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/dotenv-cli/-/dotenv-cli-4.1.1.tgz#26a59fbb25876008985a15fa366b416607e8372c"
|
||||
integrity sha512-XvKv1pa+UBrsr3CtLGBsR6NdsoS7znqaHUf4Knj0eZO+gOI/hjj9KgWDP+KjpfEbj6wAba1UpbhaP9VezNkWhg==
|
||||
@ -3384,21 +3287,6 @@ escape-string-regexp@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
eslint-config-next@12.0.4:
|
||||
version "12.0.4"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-12.0.4.tgz#22f0305770f0d11bfa034df0efea7cf9cdb37d58"
|
||||
integrity sha512-uBOHBjYaRF0MaS5feB7lFOncHhSrtFxZy/oud6pEW/wn/JUQtZWeH/J4JyODBfX+G7h9mttgHLZNmUjNJis6Kw==
|
||||
dependencies:
|
||||
"@next/eslint-plugin-next" "12.0.4"
|
||||
"@rushstack/eslint-patch" "^1.0.6"
|
||||
"@typescript-eslint/parser" "^4.20.0"
|
||||
eslint-import-resolver-node "^0.3.4"
|
||||
eslint-import-resolver-typescript "^2.4.0"
|
||||
eslint-plugin-import "^2.22.1"
|
||||
eslint-plugin-jsx-a11y "^6.4.1"
|
||||
eslint-plugin-react "^7.23.1"
|
||||
eslint-plugin-react-hooks "^4.2.0"
|
||||
|
||||
eslint-config-next@12.0.7:
|
||||
version "12.0.7"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-12.0.7.tgz#985f06c3d749673f6b4b214db6b9321da1bf0b5f"
|
||||
@ -3454,7 +3342,7 @@ eslint-plugin-cypress@^2.12.1:
|
||||
dependencies:
|
||||
globals "^11.12.0"
|
||||
|
||||
eslint-plugin-import@^2.22.1, eslint-plugin-import@^2.25.2:
|
||||
eslint-plugin-import@^2.25.2:
|
||||
version "2.25.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz#a554b5f66e08fb4f6dc99221866e57cfff824766"
|
||||
integrity sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==
|
||||
@ -3473,7 +3361,7 @@ eslint-plugin-import@^2.22.1, eslint-plugin-import@^2.25.2:
|
||||
resolve "^1.20.0"
|
||||
tsconfig-paths "^3.11.0"
|
||||
|
||||
eslint-plugin-jsx-a11y@^6.4.1, eslint-plugin-jsx-a11y@^6.5.1:
|
||||
eslint-plugin-jsx-a11y@^6.5.1:
|
||||
version "6.5.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz#cdbf2df901040ca140b6ec14715c988889c2a6d8"
|
||||
integrity sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g==
|
||||
@ -3498,12 +3386,12 @@ eslint-plugin-prettier@^4.0.0:
|
||||
dependencies:
|
||||
prettier-linter-helpers "^1.0.0"
|
||||
|
||||
eslint-plugin-react-hooks@^4.2.0, eslint-plugin-react-hooks@^4.3.0:
|
||||
eslint-plugin-react-hooks@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172"
|
||||
integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==
|
||||
|
||||
eslint-plugin-react@^7.23.1, eslint-plugin-react@^7.27.0:
|
||||
eslint-plugin-react@^7.27.0:
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.27.1.tgz#469202442506616f77a854d91babaae1ec174b45"
|
||||
integrity sha512-meyunDjMMYeWr/4EBLTV1op3iSG3mjT/pz5gti38UzfM4OPpNc2m0t2xvKCOMU5D6FSdd34BIMFOvQbW+i8GAA==
|
||||
@ -4078,7 +3966,7 @@ globals@^13.6.0, globals@^13.9.0:
|
||||
dependencies:
|
||||
type-fest "^0.20.2"
|
||||
|
||||
globby@^11.0.3, globby@^11.0.4:
|
||||
globby@^11.0.4:
|
||||
version "11.0.4"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5"
|
||||
integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==
|
||||
@ -5076,7 +4964,7 @@ next-auth@beta:
|
||||
preact-render-to-string "^5.1.19"
|
||||
uuid "^8.3.2"
|
||||
|
||||
next@^12.0.4, next@^12.0.7:
|
||||
next@^12.0.7:
|
||||
version "12.0.7"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-12.0.7.tgz#33ebf229b81b06e583ab5ae7613cffe1ca2103fc"
|
||||
integrity sha512-sKO8GJJYfuk9c+q+zHSNumvff+wP7ufmOlwT6BuzwiYfFJ61VTTkfTcDLSJ+95ErQJiC54uS4Yg5JEE8H6jXRA==
|
||||
@ -5936,7 +5824,7 @@ prettier-linter-helpers@^1.0.0:
|
||||
dependencies:
|
||||
fast-diff "^1.1.2"
|
||||
|
||||
prettier@^2.4.1, prettier@^2.5.1:
|
||||
prettier@^2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a"
|
||||
integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==
|
||||
@ -7289,10 +7177,83 @@ tunnel-agent@^0.6.0:
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
turbo@^1.0.19:
|
||||
version "1.0.19"
|
||||
resolved "https://registry.yarnpkg.com/turbo/-/turbo-1.0.19.tgz#5c666b7b497e443269da2c553d00fe23dbcc6914"
|
||||
integrity sha512-/gdEdpdludyHX+344JQ84bglK33dI4IWTtGkBkfJnSQW+lC3/JFAu9jy+4zNK2gdzxjwcB2/qQK+Pv53SZd1Kw==
|
||||
turbo-darwin-64@1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo-darwin-64/-/turbo-darwin-64-1.0.23.tgz#0164b1a2ee6782bf2233bb1887b01ac78486378e"
|
||||
integrity sha512-z6ArzNKpQIw/YhFf20lUGl5VaGTZ94MSppXuuYkCyxMQwK3qye3r2ENQbUKkxfv16fAmfr7z1bJt6YwfOjwPiw==
|
||||
|
||||
turbo-darwin-arm64@1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo-darwin-arm64/-/turbo-darwin-arm64-1.0.23.tgz#7d6de986595d6ded9d853744c26780b50c7b196c"
|
||||
integrity sha512-U02Ip7kO7eDN3WRliIrPtqYFqcpsvpNsE5fX1T0uFjXfSJruiDBrrNpGmZEh8hatS5wQyG7VaxW+izJqd7TCsw==
|
||||
|
||||
turbo-freebsd-64@1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo-freebsd-64/-/turbo-freebsd-64-1.0.23.tgz#f78d2056414496334cb8c6bc28ac7f3d5d0ab30c"
|
||||
integrity sha512-5XT8pp0uJ1vRqNJydacn6ouY4COUeufOdLuiPOWAOsvMW5FOJNAOdAJ7lISBBqhCpYF8CEZ9kCAI2f9nOzzY0Q==
|
||||
|
||||
turbo-freebsd-arm64@1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo-freebsd-arm64/-/turbo-freebsd-arm64-1.0.23.tgz#d7d4eca48a21da17403c804e5bd52a3daffbdc1c"
|
||||
integrity sha512-70BGJTVX3jYvzDISp8dWM/rwiK4CDlNVQJnnlUMKrueFtpgHZhsRKjIeNgIKxVSTyp4xT0Vl4xhc9zFhMT17aw==
|
||||
|
||||
turbo-linux-32@1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-32/-/turbo-linux-32-1.0.23.tgz#c11de3c98944d43b9e25582c03ddd8f38d6cd85c"
|
||||
integrity sha512-ee3N8f7h1qg5noKII5Tq2gyG6PVFl/apllX0TPbZiUab6553QPfVt+tB+5W6BZmKGUdHHCvW42xuig0krrrRGw==
|
||||
|
||||
turbo-linux-64@1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-64/-/turbo-linux-64-1.0.23.tgz#7700a5e5ad96e741405957e7cd33a7422c49bfbd"
|
||||
integrity sha512-j2+1P2+rdOXb/yzz78SCmxXLdFSSlCzZS0Psg1vetYozuoT0k+xu7gr6iqEHdBWw39jNFuT72hVqrNZ4TClHcA==
|
||||
|
||||
turbo-linux-arm64@1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-arm64/-/turbo-linux-arm64-1.0.23.tgz#79b49e14ef3038f99036134abcf53c17645b5eb9"
|
||||
integrity sha512-VNW8yyBG63MGUzZ/Y2DS883P8rzz/hQuiCklw2lTBQ4O9dp2FxYrAVnmCxbnsIDZG/wEupdvaHVgqH7j2DJgwg==
|
||||
|
||||
turbo-linux-arm@1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-arm/-/turbo-linux-arm-1.0.23.tgz#7140b73572948a0285395feb3abe8a9067f74d68"
|
||||
integrity sha512-+aD+v03bpkmuXEfk14w2fLH5cAyfyGlAs5gBwQmwyF3XllJ40OL/cw9xDnBREpZsnm9o1GTQpr0wmepjw9d4iQ==
|
||||
|
||||
turbo-linux-mips64le@1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-mips64le/-/turbo-linux-mips64le-1.0.23.tgz#fa4e989a8e149e3684f4732ed1b2a386fc829c8a"
|
||||
integrity sha512-CJNd7F9z8EhqcdJnd1rSiU/+hSNG3E+fudQ5pr55y0nhSShFMMdZxdLvL5zzhWpBl1g8YldphjPqNLChgGatKw==
|
||||
|
||||
turbo-linux-ppc64le@1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-ppc64le/-/turbo-linux-ppc64le-1.0.23.tgz#3c1e0f5a79b8c34d790c7828ec443ed73ed95706"
|
||||
integrity sha512-RjzDqXQl+nqV+2A6MRk1sALBQtpCB/h8qDWhJIL/VUgToTMdllAThiYI+lALLmGWBumXs4XDbk+83FGJlJ1bDg==
|
||||
|
||||
turbo-windows-32@1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo-windows-32/-/turbo-windows-32-1.0.23.tgz#17d58f43406cd68062131924f94c2df8ca159f9e"
|
||||
integrity sha512-qTfldTd5OO/s8unGFnITe4IX8ua2SNj/VVQbvVcObDJK6xrfBY4tDS78rIo9//xTSRyK+28AoPxRZsVqqF2hlA==
|
||||
|
||||
turbo-windows-64@1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo-windows-64/-/turbo-windows-64-1.0.23.tgz#0e53fde0395fa88006be7fcd36c1853995cfa319"
|
||||
integrity sha512-yzhF6GEYiyrXoO/l9T6amB16OITsFXdeMTc0Vf2BZFOG1fn9Muc4CxQ+CcdsLlai+TqQTKlpEf0+l83vI+R2Jw==
|
||||
|
||||
turbo@^1.0.23:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/turbo/-/turbo-1.0.23.tgz#9a8f54f116daee67e0c131c4c936f075d32281a2"
|
||||
integrity sha512-/VHsARQyl8wsfCJtuJicjYq7Do/P5yjJde3bjG9TAZHj/PzA9LuRU7WOEPfUrT+felOQ3vwUMZtC8xrYFmndLA==
|
||||
optionalDependencies:
|
||||
turbo-darwin-64 "1.0.23"
|
||||
turbo-darwin-arm64 "1.0.23"
|
||||
turbo-freebsd-64 "1.0.23"
|
||||
turbo-freebsd-arm64 "1.0.23"
|
||||
turbo-linux-32 "1.0.23"
|
||||
turbo-linux-64 "1.0.23"
|
||||
turbo-linux-arm "1.0.23"
|
||||
turbo-linux-arm64 "1.0.23"
|
||||
turbo-linux-mips64le "1.0.23"
|
||||
turbo-linux-ppc64le "1.0.23"
|
||||
turbo-windows-32 "1.0.23"
|
||||
turbo-windows-64 "1.0.23"
|
||||
|
||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||
version "0.14.5"
|
||||
|
Reference in New Issue
Block a user