Merge branch 'main' into fix/next-auth-protocol-detection
This commit is contained in:
commit
8a5b2fdf84
20 changed files with 255 additions and 82 deletions
|
|
@ -1,4 +1,5 @@
|
|||
## Get your OpenAI API Key
|
||||
## You must first activate a Billing Account here: https://platform.openai.com/account/billing/overview
|
||||
## Then get your OpenAI API Key here: https://platform.openai.com/account/api-keys
|
||||
OPENAI_API_KEY=XXXXXXXX
|
||||
|
||||
## Generate a random secret: https://generate-secret.vercel.app/32
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
- [Next.js](https://nextjs.org) App Router
|
||||
- React Server Components (RSCs), Suspense, and Server Actions
|
||||
- [Vercel AI SDK](https://sdk.vercel.ai/docs) for streaming chat UI
|
||||
- Support for OpenAI (default), Anthropic, HuggingFace, or custom AI chat models and/or LangChain
|
||||
- Support for OpenAI (default), Anthropic, Hugging Face, or custom AI chat models and/or LangChain
|
||||
- Edge runtime-ready
|
||||
- [shadcn/ui](https://ui.shadcn.com)
|
||||
- Styling with [Tailwind CSS](https://tailwindcss.com)
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
## Model Providers
|
||||
|
||||
This template ships with OpenAI `gpt-3.5-turbo` as the default. However, thanks to the [Vercel AI SDK](https://sdk.vercel.ai/docs), you can switch LLM providers to [Anthropic](https://anthropic.com), [HuggingFace](https://huggingface.co), or using [LangChain](https://js.langchain.com) with just a few lines of code.
|
||||
This template ships with OpenAI `gpt-3.5-turbo` as the default. However, thanks to the [Vercel AI SDK](https://sdk.vercel.ai/docs), you can switch LLM providers to [Anthropic](https://anthropic.com), [Hugging Face](https://huggingface.co), or using [LangChain](https://js.langchain.com) with just a few lines of code.
|
||||
|
||||
## Deploy Your Own
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,9 @@ export async function clearChats() {
|
|||
}
|
||||
|
||||
const chats: string[] = await kv.zrange(`user:chat:${session.user.id}`, 0, -1)
|
||||
|
||||
if (!chats.length) {
|
||||
return redirect('/')
|
||||
}
|
||||
const pipeline = kv.pipeline()
|
||||
|
||||
for (const chat of chats) {
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
export { GET, POST } from '@/auth'
|
||||
export const runtime = 'edge'
|
||||
|
|
|
|||
|
|
@ -7,22 +7,26 @@ import { nanoid } from '@/lib/utils'
|
|||
|
||||
export const runtime = 'edge'
|
||||
|
||||
const configuration = new Configuration({
|
||||
apiKey: process.env.OPENAI_API_KEY
|
||||
})
|
||||
|
||||
const openai = new OpenAIApi(configuration)
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const json = await req.json()
|
||||
const { messages, previewToken } = json
|
||||
const session = await auth()
|
||||
|
||||
if (process.env.VERCEL_ENV !== 'preview') {
|
||||
if (process.env.VERCEL_ENV === 'preview') {
|
||||
if (session == null) {
|
||||
return new Response('Unauthorized', { status: 401 })
|
||||
}
|
||||
}
|
||||
|
||||
const configuration = new Configuration({
|
||||
apiKey: previewToken || process.env.OPENAI_API_KEY
|
||||
})
|
||||
|
||||
const openai = new OpenAIApi(configuration)
|
||||
if (previewToken) {
|
||||
configuration.apiKey = previewToken
|
||||
}
|
||||
|
||||
const res = await openai.createChatCompletion({
|
||||
model: 'gpt-3.5-turbo',
|
||||
|
|
@ -34,7 +38,7 @@ export async function POST(req: Request) {
|
|||
const stream = OpenAIStream(res, {
|
||||
async onCompletion(completion) {
|
||||
const title = json.messages[0].content.substring(0, 100)
|
||||
const userId = session?.user.id
|
||||
const userId = session?.user?.id
|
||||
if (userId) {
|
||||
const id = json.id ?? nanoid()
|
||||
const createdAt = Date.now()
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export async function generateMetadata({
|
|||
|
||||
const chat = await getChat(params.id, session.user.id)
|
||||
return {
|
||||
title: chat?.title.slice(0, 50) ?? 'Chat'
|
||||
title: chat?.title.toString().slice(0, 50) ?? 'Chat'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ export default async function SharePage({ params }: SharePageProps) {
|
|||
return (
|
||||
<>
|
||||
<div className="flex-1 space-y-6">
|
||||
<div className="border-b bg-background px-4 py-6 md:px-6 md:py-8">
|
||||
<div className="mx-auto max-w-2xl md:px-6">
|
||||
<div className="space-y-1">
|
||||
<div className="px-4 py-6 border-b bg-background md:px-6 md:py-8">
|
||||
<div className="max-w-2xl mx-auto md:px-6">
|
||||
<div className="space-y-1 md:-mx-8">
|
||||
<h1 className="text-2xl font-bold">{chat.title}</h1>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{formatDate(chat.createdAt)} · {chat.messages.length} messages
|
||||
|
|
|
|||
15
auth.ts
15
auth.ts
|
|
@ -1,25 +1,18 @@
|
|||
import NextAuth from 'next-auth'
|
||||
import GitHub from 'next-auth/providers/github'
|
||||
|
||||
declare module 'next-auth' {
|
||||
interface Session {
|
||||
user: {
|
||||
/** The user's id. */
|
||||
id: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const {
|
||||
handlers: { GET, POST },
|
||||
auth,
|
||||
CSRF_experimental
|
||||
// @ts-ignore
|
||||
} = NextAuth({
|
||||
// @ts-expect-error
|
||||
// @ts-ignore
|
||||
providers: [GitHub],
|
||||
callbacks: {
|
||||
// @ts-ignore
|
||||
jwt: async ({ token, profile }) => {
|
||||
if (profile) {
|
||||
if (profile?.id) {
|
||||
token.id = profile.id
|
||||
token.image = profile.picture
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ export function ChatMessageActions({
|
|||
}: ChatMessageActionsProps) {
|
||||
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2000 })
|
||||
|
||||
const onCopy = () => {
|
||||
if (isCopied) return
|
||||
copyToClipboard(message.content)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
|
|
@ -26,11 +31,7 @@ export function ChatMessageActions({
|
|||
)}
|
||||
{...props}
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => copyToClipboard(message.content)}
|
||||
>
|
||||
<Button variant="ghost" size="icon" onClick={onCopy}>
|
||||
{isCopied ? <IconCheck /> : <IconCopy />}
|
||||
<span className="sr-only">Copy message</span>
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import Link from 'next/link'
|
|||
import { cn } from '@/lib/utils'
|
||||
import { auth } from '@/auth'
|
||||
import { clearChats } from '@/app/actions'
|
||||
import { buttonVariants } from '@/components/ui/button'
|
||||
import { Button, buttonVariants } from '@/components/ui/button'
|
||||
import { Sidebar } from '@/components/sidebar'
|
||||
import { SidebarList } from '@/components/sidebar-list'
|
||||
import {
|
||||
|
|
@ -22,7 +22,7 @@ import { LoginButton } from '@/components/login-button'
|
|||
export async function Header() {
|
||||
const session = await auth()
|
||||
return (
|
||||
<header className="sticky top-0 z-50 flex h-16 w-full shrink-0 items-center justify-between border-b bg-gradient-to-b from-background/10 via-background/50 to-background/80 px-4 backdrop-blur-xl">
|
||||
<header className="sticky top-0 z-50 flex items-center justify-between w-full h-16 px-4 border-b shrink-0 bg-gradient-to-b from-background/10 via-background/50 to-background/80 backdrop-blur-xl">
|
||||
<div className="flex items-center">
|
||||
{session?.user ? (
|
||||
<Sidebar>
|
||||
|
|
@ -37,21 +37,18 @@ export async function Header() {
|
|||
</Sidebar>
|
||||
) : (
|
||||
<Link href="/" target="_blank" rel="nofollow">
|
||||
<IconNextChat className="mr-2 h-6 w-6 dark:hidden" inverted />
|
||||
<IconNextChat className="mr-2 hidden h-6 w-6 dark:block" />
|
||||
<IconNextChat className="w-6 h-6 mr-2 dark:hidden" inverted />
|
||||
<IconNextChat className="hidden w-6 h-6 mr-2 dark:block" />
|
||||
</Link>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
<IconSeparator className="h-6 w-6 text-muted-foreground/50" />
|
||||
<IconSeparator className="w-6 h-6 text-muted-foreground/50" />
|
||||
{session?.user ? (
|
||||
<UserMenu user={session.user} />
|
||||
) : (
|
||||
<LoginButton
|
||||
variant="link"
|
||||
showGithubIcon={false}
|
||||
text="Login"
|
||||
className="-ml-2"
|
||||
/>
|
||||
<Button variant="link" asChild className="-ml-2">
|
||||
<Link href="/sign-in?callbackUrl=/">Login</Link>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -63,7 +60,7 @@ export async function Header() {
|
|||
className={cn(buttonVariants({ variant: 'outline' }))}
|
||||
>
|
||||
<IconGitHub />
|
||||
<span className="ml-2 hidden md:flex">GitHub</span>
|
||||
<span className="hidden ml-2 md:flex">GitHub</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/vercel/nextjs-ai-chatbot/"
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ export function LoginButton({
|
|||
variant="outline"
|
||||
onClick={() => {
|
||||
setIsLoading(true)
|
||||
// next-auth signIn() function doesn't work yet at Edge Runtime due to usage of BroadcastChannel
|
||||
signIn('github', { callbackUrl: `/` })
|
||||
}}
|
||||
disabled={isLoading}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { IconArrowElbow, IconPlus } from '@/components/ui/icons'
|
|||
|
||||
export interface PromptProps
|
||||
extends Pick<UseChatHelpers, 'input' | 'setInput'> {
|
||||
onSubmit: (value: string) => void
|
||||
onSubmit: (value: string) => Promise<void>
|
||||
isLoading: boolean
|
||||
}
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ export function PromptForm({
|
|||
<form
|
||||
onSubmit={async e => {
|
||||
e.preventDefault()
|
||||
if (input === '') {
|
||||
if (!input?.trim()) {
|
||||
return
|
||||
}
|
||||
setInput('')
|
||||
|
|
@ -46,7 +46,7 @@ export function PromptForm({
|
|||
}}
|
||||
ref={formRef}
|
||||
>
|
||||
<div className="relative flex w-full grow flex-col overflow-hidden bg-background px-8 sm:rounded-md sm:border sm:px-12">
|
||||
<div className="relative flex max-h-60 w-full grow flex-col overflow-hidden bg-background px-8 sm:rounded-md sm:border sm:px-12">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Link
|
||||
|
|
|
|||
|
|
@ -84,6 +84,11 @@ const CodeBlock: FC<Props> = memo(({ language, value }) => {
|
|||
URL.revokeObjectURL(url)
|
||||
}
|
||||
|
||||
const onCopy = () => {
|
||||
if (isCopied) return
|
||||
copyToClipboard(value)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="codeblock relative w-full bg-zinc-950 font-sans">
|
||||
<div className="flex w-full items-center justify-between bg-zinc-800 px-6 py-2 pr-4 text-zinc-100">
|
||||
|
|
@ -102,7 +107,7 @@ const CodeBlock: FC<Props> = memo(({ language, value }) => {
|
|||
variant="ghost"
|
||||
size="icon"
|
||||
className="text-xs hover:bg-zinc-800 focus-visible:ring-1 focus-visible:ring-slate-700 focus-visible:ring-offset-0"
|
||||
onClick={() => copyToClipboard(value)}
|
||||
onClick={onCopy}
|
||||
>
|
||||
{isCopied ? <IconCheck /> : <IconCopy />}
|
||||
<span className="sr-only">Copy code</span>
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ export function useCopyToClipboard({
|
|||
const [isCopied, setIsCopied] = React.useState<Boolean>(false)
|
||||
|
||||
const copyToClipboard = (value: string) => {
|
||||
if (
|
||||
typeof window === 'undefined' ||
|
||||
!navigator.clipboard ||
|
||||
!navigator.clipboard.writeText
|
||||
) {
|
||||
if (typeof window === 'undefined' || !navigator.clipboard?.writeText) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,11 @@ export function useEnterSubmit(): {
|
|||
const handleKeyDown = (
|
||||
event: React.KeyboardEvent<HTMLTextAreaElement>
|
||||
): void => {
|
||||
if (event.key === 'Enter' && !event.shiftKey) {
|
||||
if (
|
||||
event.key === 'Enter' &&
|
||||
!event.shiftKey &&
|
||||
!event.nativeEvent.isComposing
|
||||
) {
|
||||
formRef.current?.requestSubmit()
|
||||
event.preventDefault()
|
||||
}
|
||||
|
|
|
|||
13
next-auth.d.ts
vendored
Normal file
13
next-auth.d.ts
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import NextAuth, { DefaultSession } from 'next-auth'
|
||||
|
||||
declare module 'next-auth' {
|
||||
/**
|
||||
* Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
|
||||
*/
|
||||
interface Session {
|
||||
user: {
|
||||
/** The user's postal address. */
|
||||
id: string
|
||||
} & DefaultSession['user']
|
||||
}
|
||||
}
|
||||
|
|
@ -26,14 +26,14 @@
|
|||
"@vercel/analytics": "^1.0.0",
|
||||
"@vercel/kv": "^0.2.1",
|
||||
"@vercel/og": "^0.5.7",
|
||||
"ai": "^2.1.2",
|
||||
"ai": "^2.1.6",
|
||||
"body-scroll-lock": "4.0.0-beta.0",
|
||||
"class-variance-authority": "^0.4.0",
|
||||
"clsx": "^1.2.1",
|
||||
"focus-trap-react": "^10.1.1",
|
||||
"nanoid": "^4.0.2",
|
||||
"next": "13.4.7-canary.1",
|
||||
"next-auth": "0.0.0-manual.f414f2f5",
|
||||
"next-auth": "0.0.0-manual.4cd21ea5",
|
||||
"next-themes": "^0.2.1",
|
||||
"openai-edge": "^0.5.1",
|
||||
"react": "^18.2.0",
|
||||
|
|
@ -67,5 +67,10 @@
|
|||
"tailwindcss-animate": "^1.0.5",
|
||||
"typescript": "^5.1.3"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"@auth/nextjs": "0.0.0-manual.223c6467"
|
||||
}
|
||||
},
|
||||
"packageManager": "pnpm@8.6.1"
|
||||
}
|
||||
|
|
|
|||
196
pnpm-lock.yaml
generated
196
pnpm-lock.yaml
generated
|
|
@ -1,9 +1,12 @@
|
|||
lockfileVersion: '6.1'
|
||||
lockfileVersion: '6.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: false
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
overrides:
|
||||
'@auth/nextjs': 0.0.0-manual.223c6467
|
||||
|
||||
dependencies:
|
||||
'@radix-ui/react-alert-dialog':
|
||||
specifier: ^1.0.4
|
||||
|
|
@ -42,8 +45,8 @@ dependencies:
|
|||
specifier: ^0.5.7
|
||||
version: 0.5.7
|
||||
ai:
|
||||
specifier: ^2.1.2
|
||||
version: 2.1.2(react@18.2.0)
|
||||
specifier: ^2.1.6
|
||||
version: 2.1.6(react@18.2.0)(svelte@3.59.2)(vue@3.3.4)
|
||||
body-scroll-lock:
|
||||
specifier: 4.0.0-beta.0
|
||||
version: 4.0.0-beta.0
|
||||
|
|
@ -55,7 +58,7 @@ dependencies:
|
|||
version: 1.2.1
|
||||
focus-trap-react:
|
||||
specifier: ^10.1.1
|
||||
version: 10.1.1(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 10.1.1(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
nanoid:
|
||||
specifier: ^4.0.2
|
||||
version: 4.0.2
|
||||
|
|
@ -63,8 +66,8 @@ dependencies:
|
|||
specifier: 13.4.7-canary.1
|
||||
version: 13.4.7-canary.1(react-dom@18.2.0)(react@18.2.0)
|
||||
next-auth:
|
||||
specifier: 0.0.0-manual.f414f2f5
|
||||
version: 0.0.0-manual.f414f2f5(next@13.4.7-canary.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
specifier: 0.0.0-manual.4cd21ea5
|
||||
version: 0.0.0-manual.4cd21ea5(next@13.4.7-canary.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
next-themes:
|
||||
specifier: ^0.2.1
|
||||
version: 0.2.1(next@13.4.7-canary.1)(react-dom@18.2.0)(react@18.2.0)
|
||||
|
|
@ -79,7 +82,7 @@ dependencies:
|
|||
version: 18.2.0(react@18.2.0)
|
||||
react-hot-toast:
|
||||
specifier: ^2.4.1
|
||||
version: 2.4.1(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 2.4.1(csstype@3.1.2)(react-dom@18.2.0)(react@18.2.0)
|
||||
react-intersection-observer:
|
||||
specifier: ^9.4.4
|
||||
version: 9.4.4(react@18.2.0)
|
||||
|
|
@ -184,7 +187,7 @@ packages:
|
|||
/@auth/nextjs@0.0.0-manual.179c08d4(next@13.4.7-canary.1)(react@18.2.0):
|
||||
resolution: {integrity: sha512-HVuDgb6xlYLV5mHTGc0Pycg8BlwtcvjvS+54QXEbOBpA5tulzKxAH8QlCoKj5R9XHW9hP9DiCnvXyVV9x2N+jA==}
|
||||
peerDependencies:
|
||||
next: ^13.4.6
|
||||
next: ^13.4.2
|
||||
react: ^18.2.0
|
||||
dependencies:
|
||||
'@auth/core': 0.0.0-manual.8fcd46b0
|
||||
|
|
@ -194,12 +197,39 @@ packages:
|
|||
- nodemailer
|
||||
dev: false
|
||||
|
||||
/@babel/helper-string-parser@7.22.5:
|
||||
resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: false
|
||||
|
||||
/@babel/helper-validator-identifier@7.22.5:
|
||||
resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: false
|
||||
|
||||
/@babel/parser@7.22.5:
|
||||
resolution: {integrity: sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@babel/types': 7.22.5
|
||||
dev: false
|
||||
|
||||
/@babel/runtime@7.21.5:
|
||||
resolution: {integrity: sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
regenerator-runtime: 0.13.11
|
||||
|
||||
/@babel/types@7.22.5:
|
||||
resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/helper-string-parser': 7.22.5
|
||||
'@babel/helper-validator-identifier': 7.22.5
|
||||
to-fast-properties: 2.0.0
|
||||
dev: false
|
||||
|
||||
/@esbuild/android-arm@0.15.18:
|
||||
resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==}
|
||||
engines: {node: '>=12'}
|
||||
|
|
@ -321,7 +351,6 @@ packages:
|
|||
|
||||
/@jridgewell/sourcemap-codec@1.4.15:
|
||||
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
|
||||
dev: true
|
||||
|
||||
/@jridgewell/trace-mapping@0.3.18:
|
||||
resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==}
|
||||
|
|
@ -1358,6 +1387,89 @@ packages:
|
|||
yoga-wasm-web: 0.3.3
|
||||
dev: false
|
||||
|
||||
/@vue/compiler-core@3.3.4:
|
||||
resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==}
|
||||
dependencies:
|
||||
'@babel/parser': 7.22.5
|
||||
'@vue/shared': 3.3.4
|
||||
estree-walker: 2.0.2
|
||||
source-map-js: 1.0.2
|
||||
dev: false
|
||||
|
||||
/@vue/compiler-dom@3.3.4:
|
||||
resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==}
|
||||
dependencies:
|
||||
'@vue/compiler-core': 3.3.4
|
||||
'@vue/shared': 3.3.4
|
||||
dev: false
|
||||
|
||||
/@vue/compiler-sfc@3.3.4:
|
||||
resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==}
|
||||
dependencies:
|
||||
'@babel/parser': 7.22.5
|
||||
'@vue/compiler-core': 3.3.4
|
||||
'@vue/compiler-dom': 3.3.4
|
||||
'@vue/compiler-ssr': 3.3.4
|
||||
'@vue/reactivity-transform': 3.3.4
|
||||
'@vue/shared': 3.3.4
|
||||
estree-walker: 2.0.2
|
||||
magic-string: 0.30.0
|
||||
postcss: 8.4.23
|
||||
source-map-js: 1.0.2
|
||||
dev: false
|
||||
|
||||
/@vue/compiler-ssr@3.3.4:
|
||||
resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==}
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.3.4
|
||||
'@vue/shared': 3.3.4
|
||||
dev: false
|
||||
|
||||
/@vue/reactivity-transform@3.3.4:
|
||||
resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==}
|
||||
dependencies:
|
||||
'@babel/parser': 7.22.5
|
||||
'@vue/compiler-core': 3.3.4
|
||||
'@vue/shared': 3.3.4
|
||||
estree-walker: 2.0.2
|
||||
magic-string: 0.30.0
|
||||
dev: false
|
||||
|
||||
/@vue/reactivity@3.3.4:
|
||||
resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==}
|
||||
dependencies:
|
||||
'@vue/shared': 3.3.4
|
||||
dev: false
|
||||
|
||||
/@vue/runtime-core@3.3.4:
|
||||
resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==}
|
||||
dependencies:
|
||||
'@vue/reactivity': 3.3.4
|
||||
'@vue/shared': 3.3.4
|
||||
dev: false
|
||||
|
||||
/@vue/runtime-dom@3.3.4:
|
||||
resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==}
|
||||
dependencies:
|
||||
'@vue/runtime-core': 3.3.4
|
||||
'@vue/shared': 3.3.4
|
||||
csstype: 3.1.2
|
||||
dev: false
|
||||
|
||||
/@vue/server-renderer@3.3.4(vue@3.3.4):
|
||||
resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==}
|
||||
peerDependencies:
|
||||
vue: 3.3.4
|
||||
dependencies:
|
||||
'@vue/compiler-ssr': 3.3.4
|
||||
'@vue/shared': 3.3.4
|
||||
vue: 3.3.4
|
||||
dev: false
|
||||
|
||||
/@vue/shared@3.3.4:
|
||||
resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==}
|
||||
dev: false
|
||||
|
||||
/acorn-jsx@5.3.2(acorn@8.8.2):
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
|
|
@ -1372,8 +1484,8 @@ packages:
|
|||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/ai@2.1.2(react@18.2.0):
|
||||
resolution: {integrity: sha512-WhyGH95Pv/gpgVMQT5eCyKXJh7irozr+bmpJ94somfRYBcAN2U270ii/OOHzGLrPM3liTbBilGQL2Ds7/5sz9Q==}
|
||||
/ai@2.1.6(react@18.2.0)(svelte@3.59.2)(vue@3.3.4):
|
||||
resolution: {integrity: sha512-YFCy7KEUDvuNGNuD8Bz7BynXB/eW2jJRAxAIM8Hb5/gpppZJs6/nTSdpocROxoGESJchtkFgYdygieG/wciEEQ==}
|
||||
engines: {node: '>=14.6'}
|
||||
peerDependencies:
|
||||
react: ^18.0.0
|
||||
|
|
@ -1390,9 +1502,11 @@ packages:
|
|||
eventsource-parser: 1.0.0
|
||||
nanoid: 3.3.6
|
||||
react: 18.2.0
|
||||
sswr: 1.10.0
|
||||
sswr: 1.10.0(svelte@3.59.2)
|
||||
svelte: 3.59.2
|
||||
swr: 2.1.5(react@18.2.0)
|
||||
swrv: 1.0.3
|
||||
swrv: 1.0.3(vue@3.3.4)
|
||||
vue: 3.3.4
|
||||
dev: false
|
||||
|
||||
/ajv@6.12.6:
|
||||
|
|
@ -2644,6 +2758,10 @@ packages:
|
|||
engines: {node: '>=4.0'}
|
||||
dev: true
|
||||
|
||||
/estree-walker@2.0.2:
|
||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||
dev: false
|
||||
|
||||
/esutils@2.0.3:
|
||||
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
@ -2774,7 +2892,7 @@ packages:
|
|||
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
|
||||
dev: true
|
||||
|
||||
/focus-trap-react@10.1.1(react-dom@18.2.0)(react@18.2.0):
|
||||
/focus-trap-react@10.1.1(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-OtLeSIQPKFzMzbLHkGtfZYwGLMhTRHd3CDhfyd0DDx8tvXzlgpseClDiuiKoiIHZtdjsbXTfTmUuuLKaxrwSyQ==}
|
||||
peerDependencies:
|
||||
prop-types: ^15.8.1
|
||||
|
|
@ -2782,6 +2900,7 @@ packages:
|
|||
react-dom: '>=16.3.0'
|
||||
dependencies:
|
||||
focus-trap: 7.4.0
|
||||
prop-types: 15.8.1
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
tabbable: 6.1.2
|
||||
|
|
@ -2967,10 +3086,12 @@ packages:
|
|||
slash: 4.0.0
|
||||
dev: true
|
||||
|
||||
/goober@2.1.13:
|
||||
/goober@2.1.13(csstype@3.1.2):
|
||||
resolution: {integrity: sha512-jFj3BQeleOoy7t93E9rZ2de+ScC4lQICLwiAQmKMg9F6roKGaLSHoCDYKkWlSafg138jejvq/mTdvmnwDQgqoQ==}
|
||||
peerDependencies:
|
||||
csstype: ^3.0.10
|
||||
dependencies:
|
||||
csstype: 3.1.2
|
||||
dev: false
|
||||
|
||||
/gopd@1.0.1:
|
||||
|
|
@ -3515,6 +3636,13 @@ packages:
|
|||
es5-ext: 0.10.62
|
||||
dev: true
|
||||
|
||||
/magic-string@0.30.0:
|
||||
resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
dev: false
|
||||
|
||||
/markdown-table@3.0.3:
|
||||
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
|
||||
dev: false
|
||||
|
|
@ -4017,8 +4145,8 @@ packages:
|
|||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||
dev: true
|
||||
|
||||
/next-auth@0.0.0-manual.f414f2f5(next@13.4.7-canary.1)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-qJmSX4QUV8V2JOQavl0fQyJymt0fte7eDQsMGTpx8ZRU2Qvx8uh+xrvXlHt3dXf603OB3QkWaj77ipIEt62Hfg==}
|
||||
/next-auth@0.0.0-manual.4cd21ea5(next@13.4.7-canary.1)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-qzsrs2xeopmIYUz1C+FbudBIoNI7xSTd1xWeECr/Qa4NFzbCt8Dr9tb2Yocpa5jnRpk0xN96HwsJqimOYVjtRg==}
|
||||
peerDependencies:
|
||||
next: ^13.4.5
|
||||
nodemailer: ^6.6.5
|
||||
|
|
@ -4429,7 +4557,6 @@ packages:
|
|||
nanoid: 3.3.6
|
||||
picocolors: 1.0.0
|
||||
source-map-js: 1.0.2
|
||||
dev: true
|
||||
|
||||
/preact-render-to-string@5.2.3(preact@10.11.3):
|
||||
resolution: {integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==}
|
||||
|
|
@ -4505,14 +4632,14 @@ packages:
|
|||
scheduler: 0.23.0
|
||||
dev: false
|
||||
|
||||
/react-hot-toast@2.4.1(react-dom@18.2.0)(react@18.2.0):
|
||||
/react-hot-toast@2.4.1(csstype@3.1.2)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
react: '>=16'
|
||||
react-dom: '>=16'
|
||||
dependencies:
|
||||
goober: 2.1.13
|
||||
goober: 2.1.13(csstype@3.1.2)
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
|
|
@ -4867,11 +4994,12 @@ packages:
|
|||
resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
|
||||
dev: false
|
||||
|
||||
/sswr@1.10.0:
|
||||
/sswr@1.10.0(svelte@3.59.2):
|
||||
resolution: {integrity: sha512-nLWAJSQy3h8t7rrbTXanRyVHuQPj4PwKIVGe4IMlxJFdhyaxnN/JGACnvQKGDeWiTGYIZIx/jRuUsPEF0867Pg==}
|
||||
peerDependencies:
|
||||
svelte: ^3.29.0
|
||||
dependencies:
|
||||
svelte: 3.59.2
|
||||
swrev: 3.0.0
|
||||
dev: false
|
||||
|
||||
|
|
@ -5005,6 +5133,11 @@ packages:
|
|||
engines: {node: '>= 0.4'}
|
||||
dev: true
|
||||
|
||||
/svelte@3.59.2:
|
||||
resolution: {integrity: sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==}
|
||||
engines: {node: '>= 8'}
|
||||
dev: false
|
||||
|
||||
/swr@2.1.5(react@18.2.0):
|
||||
resolution: {integrity: sha512-/OhfZMcEpuz77KavXST5q6XE9nrOBOVcBLWjMT+oAE/kQHyE3PASrevXCtQDZ8aamntOfFkbVJp7Il9tNBQWrw==}
|
||||
peerDependencies:
|
||||
|
|
@ -5018,10 +5151,12 @@ packages:
|
|||
resolution: {integrity: sha512-QJuZiptdOmbDY45pECBRVEgnoBlOKjeT2MWVz04wKHpWX15hM3P7EjcIbHDg5yLoPCMQ7to3349MEE+l9QF5HA==}
|
||||
dev: false
|
||||
|
||||
/swrv@1.0.3:
|
||||
/swrv@1.0.3(vue@3.3.4):
|
||||
resolution: {integrity: sha512-sl+eLEE+aPPjhP1E8gQ75q3RPRyw5Gd/kROnrTFo3+LkCeLskv7F+uAl5W97wgJkzitobL6FLsRPVm0DgIgN8A==}
|
||||
peerDependencies:
|
||||
vue: '>=3.2.26 < 4'
|
||||
dependencies:
|
||||
vue: 3.3.4
|
||||
dev: false
|
||||
|
||||
/synckit@0.8.5:
|
||||
|
|
@ -5118,6 +5253,11 @@ packages:
|
|||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/to-fast-properties@2.0.0:
|
||||
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
/to-regex-range@5.0.1:
|
||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||
engines: {node: '>=8.0'}
|
||||
|
|
@ -5392,6 +5532,16 @@ packages:
|
|||
vfile-message: 3.1.4
|
||||
dev: false
|
||||
|
||||
/vue@3.3.4:
|
||||
resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==}
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.3.4
|
||||
'@vue/compiler-sfc': 3.3.4
|
||||
'@vue/runtime-dom': 3.3.4
|
||||
'@vue/server-renderer': 3.3.4(vue@3.3.4)
|
||||
'@vue/shared': 3.3.4
|
||||
dev: false
|
||||
|
||||
/watchpack@2.4.0:
|
||||
resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
|
|
|||
|
|
@ -56,9 +56,6 @@ module.exports = {
|
|||
md: `calc(var(--radius) - 2px)`,
|
||||
sm: 'calc(var(--radius) - 4px)'
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['var(--font-sans)', ...fontFamily.sans]
|
||||
},
|
||||
keyframes: {
|
||||
'accordion-down': {
|
||||
from: { height: 0 },
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"next-auth.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue