value !== null
-}
-
export const preventUserFromRefreshing = (e: BeforeUnloadEvent) => {
e.preventDefault()
e.returnValue = ''
diff --git a/apps/viewer/layouts/ErrorPage.tsx b/apps/viewer/layouts/ErrorPage.tsx
index f86270b7a..d734f4af4 100644
--- a/apps/viewer/layouts/ErrorPage.tsx
+++ b/apps/viewer/layouts/ErrorPage.tsx
@@ -1,15 +1,6 @@
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."
- }
+export const ErrorPage = ({ error }: { error: Error }) => {
return (
{
flexDirection: 'column',
}}
>
- {error === '500' && (
-
500
- )}
- {errorLabel}
+ {error.name}
+ {error.message}
)
}
diff --git a/apps/viewer/layouts/TypebotPage.tsx b/apps/viewer/layouts/TypebotPage.tsx
index c66c431ee..aaa0430e0 100644
--- a/apps/viewer/layouts/TypebotPage.tsx
+++ b/apps/viewer/layouts/TypebotPage.tsx
@@ -1,6 +1,7 @@
-import { PublicTypebot, TypebotViewer } from 'bot-engine'
-import React from 'react'
+import { Answer, PublicTypebot, TypebotViewer } from 'bot-engine'
+import React, { useEffect, useState } from 'react'
import { SEO } from '../components/Seo'
+import { createResult, updateResult } from '../services/result'
import { ErrorPage } from './ErrorPage'
import { NotFoundPage } from './NotFoundPage'
@@ -10,17 +11,61 @@ export type TypebotPageProps = {
isIE: boolean
}
+const sessionStorageKey = 'resultId'
+
export const TypebotPage = ({ typebot, isIE, url }: TypebotPageProps) => {
+ const [error, setError] = useState(
+ isIE ? new Error('Internet explorer is not supported') : undefined
+ )
+ const [resultId, setResultId] = useState()
+
+ useEffect(() => {
+ initializeResult()
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [])
+
+ const initializeResult = async () => {
+ if (!typebot) return
+ const resultIdFromSession = sessionStorage.getItem(sessionStorageKey)
+ if (resultIdFromSession) setResultId(resultIdFromSession)
+ else {
+ const { error, data: result } = await createResult(typebot.typebotId)
+ if (error) setError(error)
+ if (result) {
+ setResultId(result.id)
+ sessionStorage.setItem(sessionStorageKey, result.id)
+ }
+ }
+ }
+
+ const handleAnswersUpdate = async (answers: Answer[]) => {
+ if (!resultId) return setError(new Error('Result was not created'))
+ const { error } = await updateResult(resultId, { answers })
+ if (error) setError(error)
+ }
+
+ const handleCompleted = async () => {
+ if (!resultId) return setError(new Error('Result was not created'))
+ const { error } = await updateResult(resultId, { isCompleted: true })
+ if (error) setError(error)
+ }
+
if (!typebot) {
return
}
- if (isIE) {
- return
+ if (error) {
+ return
}
return (
-
+ {resultId && (
+
+ )}
)
}
diff --git a/apps/viewer/next.config.js b/apps/viewer/next.config.js
new file mode 100644
index 000000000..f4620f088
--- /dev/null
+++ b/apps/viewer/next.config.js
@@ -0,0 +1,6 @@
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+const withTM = require('next-transpile-modules')(['utils'])
+
+module.exports = withTM({
+ reactStrictMode: true,
+})
diff --git a/apps/viewer/package.json b/apps/viewer/package.json
index 8ca8320ec..1a6de1fe5 100644
--- a/apps/viewer/package.json
+++ b/apps/viewer/package.json
@@ -13,7 +13,8 @@
"db": "*",
"next": "^12.0.7",
"react": "^17.0.2",
- "react-dom": "^17.0.2"
+ "react-dom": "^17.0.2",
+ "utils": "*"
},
"devDependencies": {
"@types/node": "^17.0.4",
@@ -24,6 +25,7 @@
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-prettier": "^4.0.0",
+ "next-transpile-modules": "^9.0.0",
"prettier": "^2.5.1",
"typescript": "^4.5.4"
}
diff --git a/apps/viewer/pages/[publicId].tsx b/apps/viewer/pages/[publicId].tsx
index 3d4f943e0..f8ddfc994 100644
--- a/apps/viewer/pages/[publicId].tsx
+++ b/apps/viewer/pages/[publicId].tsx
@@ -11,7 +11,7 @@ export const getServerSideProps: GetServerSideProps = async (
const pathname = context.resolvedUrl.split('?')[0]
try {
if (!context.req.headers.host) return { props: {} }
- typebot = await getTypebotFromPublicId(context.query.publicId.toString())
+ typebot = await getTypebotFromPublicId(context.query.publicId?.toString())
if (!typebot) return { props: {} }
return {
props: {
@@ -32,8 +32,9 @@ export const getServerSideProps: GetServerSideProps = async (
}
const getTypebotFromPublicId = async (
- publicId: string
+ publicId?: string
): Promise => {
+ if (!publicId) return
const typebot = await prisma.publicTypebot.findUnique({
where: { publicId },
})
diff --git a/apps/viewer/pages/api/results.ts b/apps/viewer/pages/api/results.ts
new file mode 100644
index 000000000..80192340a
--- /dev/null
+++ b/apps/viewer/pages/api/results.ts
@@ -0,0 +1,16 @@
+import prisma from 'libs/prisma'
+import { NextApiRequest, NextApiResponse } from 'next'
+import { methodNotAllowed } from 'utils'
+
+const handler = async (req: NextApiRequest, res: NextApiResponse) => {
+ if (req.method === 'POST') {
+ const { typebotId } = JSON.parse(req.body)
+ const result = await prisma.result.create({
+ data: { typebotId },
+ })
+ return res.send(result)
+ }
+ return methodNotAllowed(res)
+}
+
+export default handler
diff --git a/apps/viewer/pages/api/results/[id].ts b/apps/viewer/pages/api/results/[id].ts
new file mode 100644
index 000000000..0c8664e5e
--- /dev/null
+++ b/apps/viewer/pages/api/results/[id].ts
@@ -0,0 +1,18 @@
+import prisma from 'libs/prisma'
+import { NextApiRequest, NextApiResponse } from 'next'
+import { methodNotAllowed } from 'utils'
+
+const handler = async (req: NextApiRequest, res: NextApiResponse) => {
+ if (req.method === 'PATCH') {
+ const data = JSON.parse(req.body)
+ const id = req.query.id.toString()
+ const result = await prisma.result.update({
+ where: { id },
+ data: { ...data, updatedAt: new Date() },
+ })
+ return res.send(result)
+ }
+ return methodNotAllowed(res)
+}
+
+export default handler
diff --git a/apps/viewer/services/result.ts b/apps/viewer/services/result.ts
new file mode 100644
index 000000000..864a47959
--- /dev/null
+++ b/apps/viewer/services/result.ts
@@ -0,0 +1,21 @@
+import { Result } from 'db'
+import { sendRequest } from 'utils'
+
+export const createResult = async (typebotId: string) => {
+ return sendRequest({
+ url: `/api/results`,
+ method: 'POST',
+ body: { typebotId },
+ })
+}
+
+export const updateResult = async (
+ resultId: string,
+ result: Partial
+) => {
+ return sendRequest({
+ url: `/api/results/${resultId}`,
+ method: 'PATCH',
+ body: result,
+ })
+}
diff --git a/apps/viewer/tsconfig.json b/apps/viewer/tsconfig.json
index b29b6b742..53c073685 100644
--- a/apps/viewer/tsconfig.json
+++ b/apps/viewer/tsconfig.json
@@ -4,7 +4,7 @@
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
- "strict": false,
+ "strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
@@ -14,8 +14,9 @@
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
+ "baseUrl": ".",
"composite": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
- "exclude": ["node_modules"]
+ "exclude": ["node_modules", "cypress"]
}
diff --git a/packages/bot-engine/package.json b/packages/bot-engine/package.json
index cf39d48e5..cb6ecc68c 100644
--- a/packages/bot-engine/package.json
+++ b/packages/bot-engine/package.json
@@ -7,6 +7,7 @@
"types": "dist/index.d.ts",
"dependencies": {
"db": "*",
+ "fast-equals": "^2.0.4",
"react-frame-component": "^5.2.1",
"react-scroll": "^1.8.4",
"react-transition-group": "^4.4.2"
@@ -15,18 +16,18 @@
"@rollup/plugin-commonjs": "^21.0.1",
"@rollup/plugin-node-resolve": "^13.1.1",
"@rollup/plugin-typescript": "^8.3.0",
- "@types/react": "^17.0.37",
+ "@types/react": "^17.0.38",
"@types/react-scroll": "^1.8.3",
"@types/react-transition-group": "^4.4.4",
"autoprefixer": "^10.4.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.5",
- "rollup": "^2.61.1",
- "rollup-plugin-dts": "^4.0.1",
+ "rollup": "^2.62.0",
+ "rollup-plugin-dts": "^4.1.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-terser": "^7.0.2",
- "tailwindcss": "^3.0.7",
+ "tailwindcss": "^3.0.8",
"typescript": "^4.5.4"
},
"peerDependencies": {
diff --git a/packages/bot-engine/src/components/ChatBlock/ChatBlock.tsx b/packages/bot-engine/src/components/ChatBlock/ChatBlock.tsx
index 9e78fe642..87a64b62f 100644
--- a/packages/bot-engine/src/components/ChatBlock/ChatBlock.tsx
+++ b/packages/bot-engine/src/components/ChatBlock/ChatBlock.tsx
@@ -8,7 +8,7 @@ import { HostAvatarsContext } from '../../contexts/HostAvatarsContext'
type ChatBlockProps = {
block: Block
- onBlockEnd: (nextBlockId: string) => void
+ onBlockEnd: (nextBlockId?: string) => void
}
export const ChatBlock = ({ block, onBlockEnd }: ChatBlockProps) => {
@@ -31,7 +31,10 @@ export const ChatBlock = ({ block, onBlockEnd }: ChatBlockProps) => {
const displayNextStep = () => {
const currentStep = [...displayedSteps].pop()
- if (currentStep?.target?.blockId)
+ if (
+ currentStep?.target?.blockId ||
+ displayedSteps.length === block.steps.length
+ )
return onBlockEnd(currentStep?.target?.blockId)
const nextStep = block.steps[displayedSteps.length]
if (nextStep) setDisplayedSteps([...displayedSteps, nextStep])
diff --git a/packages/bot-engine/src/components/ChatBlock/ChatStep/ChatStep.tsx b/packages/bot-engine/src/components/ChatBlock/ChatStep/ChatStep.tsx
index 4b00022ff..5623bbfa3 100644
--- a/packages/bot-engine/src/components/ChatBlock/ChatStep/ChatStep.tsx
+++ b/packages/bot-engine/src/components/ChatBlock/ChatStep/ChatStep.tsx
@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react'
+import { useAnswers } from '../../../contexts/AnswersContext'
import { useHostAvatars } from '../../../contexts/HostAvatarsContext'
import { Step } from '../../../models'
import { isTextInputStep, isTextStep } from '../../../services/utils'
@@ -13,13 +14,21 @@ export const ChatStep = ({
step: Step
onTransitionEnd: () => void
}) => {
+ const { addAnswer } = useAnswers()
+
+ const handleInputSubmit = (content: string) => {
+ addAnswer({ stepId: step.id, blockId: step.blockId, content })
+ onTransitionEnd()
+ }
+
if (isTextStep(step))
return
- if (isTextInputStep(step)) return
+ if (isTextInputStep(step))
+ return
return No step
}
-const InputChatStep = ({ onSubmit }: { onSubmit: () => void }) => {
+const InputChatStep = ({ onSubmit }: { onSubmit: (value: string) => void }) => {
const { addNewAvatarOffset } = useHostAvatars()
const [answer, setAnswer] = useState()
@@ -29,7 +38,7 @@ const InputChatStep = ({ onSubmit }: { onSubmit: () => void }) => {
const handleSubmit = (value: string) => {
setAnswer(value)
- onSubmit()
+ onSubmit(value)
}
if (answer) {
diff --git a/packages/bot-engine/src/components/ConversationContainer.tsx b/packages/bot-engine/src/components/ConversationContainer.tsx
index 0a8620eca..ee2ebeddd 100644
--- a/packages/bot-engine/src/components/ConversationContainer.tsx
+++ b/packages/bot-engine/src/components/ConversationContainer.tsx
@@ -1,28 +1,36 @@
import React, { useEffect, useRef, useState } from 'react'
-import { PublicTypebot } from '..'
+import { Answer, PublicTypebot } from '..'
import { Block } from '..'
import { ChatBlock } from './ChatBlock/ChatBlock'
import { useFrame } from 'react-frame-component'
import { setCssVariablesValue } from '../services/theme'
+import { useAnswers } from '../contexts/AnswersContext'
+import { deepEqual } from 'fast-equals'
+type Props = {
+ typebot: PublicTypebot
+ onNewBlockVisible: (blockId: string) => void
+ onAnswersUpdate: (answers: Answer[]) => void
+ onCompleted: () => void
+}
export const ConversationContainer = ({
typebot,
- onNewBlockVisisble,
-}: {
- typebot: PublicTypebot
- onNewBlockVisisble: (blockId: string) => void
-}) => {
+ onNewBlockVisible,
+ onAnswersUpdate,
+ onCompleted,
+}: Props) => {
const { document: frameDocument } = useFrame()
const [displayedBlocks, setDisplayedBlocks] = useState([])
-
- const [isConversationEnded, setIsConversationEnded] = useState(false)
+ const [localAnswers, setLocalAnswers] = useState([])
+ const { answers } = useAnswers()
const bottomAnchor = useRef(null)
- const displayNextBlock = (blockId: string) => {
+ const displayNextBlock = (blockId?: string) => {
+ if (!blockId) return onCompleted()
const nextBlock = typebot.blocks.find((b) => b.id === blockId)
- if (!nextBlock) return
- onNewBlockVisisble(blockId)
+ if (!nextBlock) return onCompleted()
+ onNewBlockVisible(blockId)
setDisplayedBlocks([...displayedBlocks, nextBlock])
}
@@ -35,6 +43,12 @@ export const ConversationContainer = ({
setCssVariablesValue(typebot.theme, frameDocument.body.style)
}, [typebot.theme, frameDocument])
+ useEffect(() => {
+ if (deepEqual(localAnswers, answers)) return
+ setLocalAnswers(answers)
+ onAnswersUpdate(answers)
+ }, [answers])
+
return (
))}
{/* We use a block to simulate padding because it makes iOS scroll flicker */}
-
+
)
}
diff --git a/packages/bot-engine/src/components/TypebotViewer.tsx b/packages/bot-engine/src/components/TypebotViewer.tsx
index dabc067b9..7da9b0c9d 100644
--- a/packages/bot-engine/src/components/TypebotViewer.tsx
+++ b/packages/bot-engine/src/components/TypebotViewer.tsx
@@ -1,19 +1,23 @@
import React, { useMemo } from 'react'
-import { BackgroundType, PublicTypebot } from '../models'
+import { Answer, BackgroundType, PublicTypebot } from '../models'
import { TypebotContext } from '../contexts/TypebotContext'
import Frame from 'react-frame-component'
//@ts-ignore
import style from '../assets/style.css'
import { ConversationContainer } from './ConversationContainer'
-import { ResultContext } from '../contexts/ResultsContext'
+import { AnswersContext } from '../contexts/AnswersContext'
export type TypebotViewerProps = {
typebot: PublicTypebot
- onNewBlockVisisble?: (blockId: string) => void
+ onNewBlockVisible?: (blockId: string) => void
+ onAnswersUpdate?: (answers: Answer[]) => void
+ onCompleted?: () => void
}
export const TypebotViewer = ({
typebot,
- onNewBlockVisisble,
+ onNewBlockVisible,
+ onAnswersUpdate,
+ onCompleted,
}: TypebotViewerProps) => {
const containerBgColor = useMemo(
() =>
@@ -23,7 +27,13 @@ export const TypebotViewer = ({
[typebot.theme.general.background]
)
const handleNewBlockVisible = (blockId: string) => {
- if (onNewBlockVisisble) onNewBlockVisisble(blockId)
+ if (onNewBlockVisible) onNewBlockVisible(blockId)
+ }
+ const handleAnswersUpdate = (answers: Answer[]) => {
+ if (onAnswersUpdate) onAnswersUpdate(answers)
+ }
+ const handleCompleted = () => {
+ if (onCompleted) onCompleted()
}
return (
@@ -38,22 +48,24 @@ export const TypebotViewer = ({
}}
/>
-
+
-
+
)
diff --git a/packages/bot-engine/src/contexts/AnswersContext.tsx b/packages/bot-engine/src/contexts/AnswersContext.tsx
new file mode 100644
index 000000000..90d3fc646
--- /dev/null
+++ b/packages/bot-engine/src/contexts/AnswersContext.tsx
@@ -0,0 +1,34 @@
+import { Answer } from '../models'
+import React, { createContext, ReactNode, useContext, useState } from 'react'
+
+const answersContext = createContext<{
+ answers: Answer[]
+ addAnswer: (answer: Answer) => void
+ //@ts-ignore
+}>({})
+
+export const AnswersContext = ({
+ children,
+ typebotId,
+}: {
+ children: ReactNode
+ typebotId: string
+}) => {
+ const [answers, setAnswers] = useState([])
+
+ const addAnswer = (answer: Answer) =>
+ setAnswers((answers) => [...answers, answer])
+
+ return (
+
+ {children}
+
+ )
+}
+
+export const useAnswers = () => useContext(answersContext)
diff --git a/packages/bot-engine/src/contexts/ResultsContext.tsx b/packages/bot-engine/src/contexts/ResultsContext.tsx
deleted file mode 100644
index 3a3f6c663..000000000
--- a/packages/bot-engine/src/contexts/ResultsContext.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import { Answer, Result } from '../models'
-import React, {
- createContext,
- Dispatch,
- ReactNode,
- SetStateAction,
- useContext,
- useState,
-} from 'react'
-
-const resultContext = createContext<{
- result: Result
- setResult: Dispatch>
- addAnswer: (answer: Answer) => void
- //@ts-ignore
-}>({})
-
-export const ResultContext = ({
- children,
- typebotId,
-}: {
- children: ReactNode
- typebotId: string
-}) => {
- const [result, setResult] = useState({
- id: 'tmp',
- createdAt: new Date(),
- updatedAt: new Date(),
- answers: [],
- typebotId,
- isCompleted: false,
- })
-
- const addAnswer = (answer: Answer) =>
- setResult({ ...result, answers: [...result.answers, answer] })
-
- return (
-
- {children}
-
- )
-}
-
-export const useResult = () => useContext(resultContext)
diff --git a/apps/builder/services/api/utils.ts b/packages/utils/apiUtils.ts
similarity index 100%
rename from apps/builder/services/api/utils.ts
rename to packages/utils/apiUtils.ts
diff --git a/packages/utils/index.ts b/packages/utils/index.ts
new file mode 100644
index 000000000..e5c865a06
--- /dev/null
+++ b/packages/utils/index.ts
@@ -0,0 +1,2 @@
+export * from './utils'
+export * from './apiUtils'
diff --git a/packages/utils/package.json b/packages/utils/package.json
new file mode 100644
index 000000000..c5f40cc33
--- /dev/null
+++ b/packages/utils/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "utils",
+ "version": "1.0.0",
+ "main": "index.ts",
+ "license": "AGPL-3.0-or-later",
+ "private": true,
+ "devDependencies": {
+ "typescript": "^4.5.4"
+ },
+ "dependencies": {
+ "next": "^12.0.7"
+ }
+}
diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json
new file mode 100644
index 000000000..3ffa57bad
--- /dev/null
+++ b/packages/utils/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "target": "es2016",
+ "module": "commonjs",
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "skipLibCheck": true
+ }
+}
diff --git a/packages/utils/utils.ts b/packages/utils/utils.ts
new file mode 100644
index 000000000..91565d808
--- /dev/null
+++ b/packages/utils/utils.ts
@@ -0,0 +1,27 @@
+export const sendRequest = async ({
+ url,
+ method,
+ body,
+}: {
+ url: string
+ method: string
+ body?: Record
+}): Promise<{ data?: ResponseData; error?: Error }> => {
+ try {
+ const response = await fetch(url, {
+ method,
+ mode: 'cors',
+ body: body ? JSON.stringify(body) : undefined,
+ })
+ if (!response.ok) throw new Error(response.statusText)
+ const data = await response.json()
+ return { data }
+ } catch (e) {
+ console.error(e)
+ return { error: e as Error }
+ }
+}
+
+export const isDefined = (value: T | undefined | null): value is T => {
+ return value !== undefined && value !== null
+}
diff --git a/yarn.lock b/yarn.lock
index 8af517cd9..bb8b046d0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1903,6 +1903,11 @@ arch@^2.2.0:
resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11"
integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==
+arg@4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.0.tgz#583c518199419e0037abb74062c37f8519e575f0"
+ integrity sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==
+
arg@^4.1.0:
version "4.1.3"
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
@@ -2309,6 +2314,11 @@ builtin-status-codes@^3.0.0:
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
+bytes@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
+ integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
+
bytes@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
@@ -2588,6 +2598,11 @@ constants-browserify@1.0.0:
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
+content-type@1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
+ integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
+
convert-source-map@1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
@@ -2999,6 +3014,11 @@ delayed-stream@~1.0.0:
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
+depd@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"
+ integrity sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=
+
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@@ -3204,6 +3224,14 @@ end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"
+enhanced-resolve@^5.7.0:
+ version "5.8.3"
+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0"
+ integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==
+ dependencies:
+ graceful-fs "^4.2.4"
+ tapable "^2.2.0"
+
enquirer@^2.3.5, enquirer@^2.3.6:
version "2.3.6"
resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
@@ -3986,7 +4014,7 @@ globby@^11.0.4:
merge2 "^1.3.0"
slash "^3.0.0"
-graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0:
+graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4:
version "4.2.8"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
@@ -4083,6 +4111,16 @@ htmlparser2@^7.2.0:
domutils "^2.8.0"
entities "^3.0.1"
+http-errors@1.6.2:
+ version "1.6.2"
+ resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736"
+ integrity sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=
+ dependencies:
+ depd "1.1.1"
+ inherits "2.0.3"
+ setprototypeof "1.0.3"
+ statuses ">= 1.3.1 < 2"
+
http-errors@1.7.3:
version "1.7.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
@@ -4126,6 +4164,11 @@ hyphenate-style-name@^1.0.2:
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
+iconv-lite@0.4.19:
+ version "0.4.19"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
+ integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==
+
iconv-lite@0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@@ -4232,6 +4275,11 @@ inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, i
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+inherits@2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+ integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
+
ini@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5"
@@ -4418,6 +4466,11 @@ is-shared-array-buffer@^1.0.1:
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6"
integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==
+is-stream@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+ integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
+
is-stream@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
@@ -4862,6 +4915,16 @@ micro-cors@^0.1.1:
resolved "https://registry.yarnpkg.com/micro-cors/-/micro-cors-0.1.1.tgz#af7a480182c114ffd1ada84ad9dffc52bb4f4054"
integrity sha512-6WqIahA5sbQR1Gjexp1VuWGFDKbZZleJb/gy1khNGk18a6iN1FdTcr3Q8twaxkV5H94RjxIBjirYbWCehpMBFw==
+micro@^9.3.4:
+ version "9.3.4"
+ resolved "https://registry.yarnpkg.com/micro/-/micro-9.3.4.tgz#745a494e53c8916f64fb6a729f8cbf2a506b35ad"
+ integrity sha512-smz9naZwTG7qaFnEZ2vn248YZq9XR+XoOH3auieZbkhDL4xLOxiE+KqG8qqnBeKfXA9c1uEFGCxPN1D+nT6N7w==
+ dependencies:
+ arg "4.1.0"
+ content-type "1.0.4"
+ is-stream "1.1.0"
+ raw-body "2.3.2"
+
micromatch@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
@@ -4983,6 +5046,14 @@ next-auth@beta:
preact-render-to-string "^5.1.19"
uuid "^8.3.2"
+next-transpile-modules@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/next-transpile-modules/-/next-transpile-modules-9.0.0.tgz#133b1742af082e61cc76b02a0f12ffd40ce2bf90"
+ integrity sha512-VCNFOazIAnXn1hvgYYSTYMnoWgKgwlYh4lm1pKbSfiB3kj5ZYLcKVhfh3jkPOg1cnd9DP+pte9yCUocdPEUBTQ==
+ dependencies:
+ enhanced-resolve "^5.7.0"
+ escalade "^3.1.1"
+
next@^12.0.7:
version "12.0.7"
resolved "https://registry.yarnpkg.com/next/-/next-12.0.7.tgz#33ebf229b81b06e583ab5ae7613cffe1ca2103fc"
@@ -6029,6 +6100,16 @@ randomfill@^1.0.3:
randombytes "^2.0.5"
safe-buffer "^5.1.0"
+raw-body@2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"
+ integrity sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=
+ dependencies:
+ bytes "3.0.0"
+ http-errors "1.6.2"
+ iconv-lite "0.4.19"
+ unpipe "1.0.0"
+
raw-body@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c"
@@ -6347,7 +6428,7 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
hash-base "^3.0.0"
inherits "^2.0.1"
-rollup-plugin-dts@^4.0.1:
+rollup-plugin-dts@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/rollup-plugin-dts/-/rollup-plugin-dts-4.1.0.tgz#63b1e7de3970bb6d50877e60df2150a3892bc49c"
integrity sha512-rriXIm3jdUiYeiAAd1Fv+x2AxK6Kq6IybB2Z/IdoAW95fb4uRUurYsEYKa8L1seedezDeJhy8cfo8FEL9aZzqg==
@@ -6397,7 +6478,7 @@ rollup-pluginutils@^2.8.2:
dependencies:
estree-walker "^0.6.1"
-rollup@^2.61.1:
+rollup@^2.62.0:
version "2.62.0"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.62.0.tgz#9e640b419fc5b9e0241844f6d55258bd79986ecc"
integrity sha512-cJEQq2gwB0GWMD3rYImefQTSjrPYaC6s4J9pYqnstVLJ1CHa/aZNVkD4Epuvg4iLeMA4KRiq7UM7awKK6j7jcw==
@@ -6509,6 +6590,11 @@ setimmediate@^1.0.4:
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
+setprototypeof@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04"
+ integrity sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=
+
setprototypeof@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
@@ -6778,7 +6864,7 @@ stacktrace-parser@0.1.10:
dependencies:
type-fest "^0.7.1"
-"statuses@>= 1.5.0 < 2":
+"statuses@>= 1.3.1 < 2", "statuses@>= 1.5.0 < 2":
version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
@@ -7028,10 +7114,10 @@ table@^6.0.9:
string-width "^4.2.3"
strip-ansi "^6.0.1"
-tailwindcss@^3.0.7:
- version "3.0.7"
- resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.0.7.tgz#15936881f042a7eb8d6f2b6a454bac9f51181bbd"
- integrity sha512-rZdKNHtC64jcQncLoWOuCzj4lQDTAgLtgK3WmQS88tTdpHh9OwLqULTQxI3tw9AMJsqSpCKlmcjW/8CSnni6zQ==
+tailwindcss@^3.0.8:
+ version "3.0.8"
+ resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.0.8.tgz#6c751c3d2ee8e1fa18b108303b73f44a5e868992"
+ integrity sha512-Yww1eRYO1AxITJmW/KduZPxNvYdHuedeKwPju9Oakp7MdiixRi5xkpLhirsc81QCxHL0eoce6qKmxXwYGt4Cjw==
dependencies:
arg "^5.0.1"
chalk "^4.1.2"
@@ -7055,6 +7141,11 @@ tailwindcss@^3.0.7:
resolve "^1.20.0"
tmp "^0.2.1"
+tapable@^2.2.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
+ integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
+
terser@^5.0.0:
version "5.10.0"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc"