Try to hack auth

This commit is contained in:
Jared Palmer 2023-06-02 11:15:04 -04:00
parent d88eae7230
commit 030b23985d
19 changed files with 330 additions and 673 deletions

43
app/api/chat/route.ts Normal file
View file

@ -0,0 +1,43 @@
import { auth } from "@/auth";
import { chats, db } from "@/lib/db/schema";
import { openai } from "@/lib/openai";
import { OpenAIStream, StreamingTextResponse } from "ai-connector";
export const runtime = "edge";
export const POST = auth(async function POST(req: Request) {
const json = await req.json();
// @ts-ignore
console.log(req.auth); // todo fix types
const res = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: json.messages.map((m: any) => ({
content: m.content,
role: m.role,
})),
temperature: 0.7,
top_p: 1,
frequency_penalty: 1,
max_tokens: 500,
n: 1,
stream: true,
});
const stream = await OpenAIStream(res, {
async onCompletion(completion) {
// @ts-ignore
if (req.auth?.user?.email == null) {
return;
}
const title = json.messages[0].content.substring(0, 20);
await db.insert(chats).values({
id: crypto.randomUUID(),
title,
userId: (req as any).auth?.user?.email,
});
},
});
return new StreamingTextResponse(stream);
});

View file

@ -1,45 +0,0 @@
import { auth } from "@/auth";
import { OpenAIStream, openai } from "@/lib/openai";
import { prisma } from "@/lib/prisma";
export const POST = auth(async function POST(req: Request) {
const json = await req.json();
// @ts-ignore
console.log(req.auth); // todo fix types
const res = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: json.messages,
temperature: 0.7,
top_p: 1,
frequency_penalty: 1,
max_tokens: 500,
n: 1,
stream: true,
});
const stream = await OpenAIStream(res);
let fullResponse = "";
const decoder = new TextDecoder();
const saveToPrisma = new TransformStream({
transform: async (chunk, controller) => {
controller.enqueue(chunk);
fullResponse += decoder.decode(chunk);
},
flush: async () => {
await prisma.chat.upsert({
where: {
id: json.id,
},
create: json,
update: json,
});
},
});
return new Response(stream.pipeThrough(saveToPrisma), {
status: 200,
headers: { "Content-Type": "text/event-stream" },
});
});

View file

@ -1,6 +1,6 @@
"use client";
import { type Message } from "@prisma/client";
import { type Message } from "ai-connector";
import { ChatMessage } from "./chat-message";
import { NextChatLogo } from "@/components/ui/nextchat-logo";

View file

@ -4,39 +4,43 @@ import { type Message } from "@prisma/client";
import { useRouter } from "next/navigation";
import { ChatList } from "./chat-list";
import { Prompt } from "./prompt";
import { usePrompt } from "./use-prompt";
import { useChat } from "ai-connector";
export interface ChatProps {
// create?: (input: string) => Chat | undefined;
messages?: Message[];
initialMessages?: Message[];
id?: string;
}
export function Chat({
id,
// create,
messages,
initialMessages,
}: ChatProps) {
const router = useRouter();
const { isLoading, messageList, appendUserMessage, reloadLastMessage } =
usePrompt({
messages,
id,
// onCreate: (id: string) => {
// router.push(`/chat/${id}`);
// },
});
const { isLoading, messages, reload, append } = useChat({
initialMessages: initialMessages as any[],
id,
// onCreate: (id: string) => {
// router.push(`/chat/${id}`);
// },
});
return (
<main className="transition-width relative min-h-full w-full flex-1 overflow-y-auto flex flex-col">
<div className="flex-1">
<ChatList messages={messageList} />
<ChatList messages={messages} />
</div>
<div className="sticky light-gradient dark:bg-gradient-to-b dark:from-zinc-900 dark:to-zinc-950 bottom-0 left-0 w-full border-t bg-white dark:bg-black md:border-t-0 py-4 md:border-transparent md:!bg-transparent md:dark:border-transparent pr-0 lg:pr-[260px] flex dark:border-transparent items-center justify-center">
<Prompt
onSubmit={appendUserMessage}
onRefresh={messageList.length ? reloadLastMessage : undefined}
onSubmit={(value) => {
append({
content: value,
role: "user",
});
}}
onRefresh={messages.length ? reload : undefined}
isLoading={isLoading}
/>
</div>

View file

@ -46,7 +46,7 @@ export default async function ChatPage({ params }: ChatPageProps) {
<div className="relative flex h-full w-full overflow-hidden">
<Sidebar session={session} />
<div className="flex h-full min-w-0 flex-1 flex-col">
<Chat id={chat.id} messages={chat.messages} />
<Chat id={chat.id} initialMessages={chat.messages} />
</div>
</div>
);

View file

@ -8,6 +8,7 @@ import { Plus } from "lucide-react";
import Link from "next/link";
import { unstable_cache } from "next/cache";
import { SidebarItem } from "./sidebar-item";
import { db } from "@/lib/db/schema";
export interface SidebarProps {
session?: Session;
@ -60,16 +61,7 @@ Sidebar.displayName = "Sidebar";
async function SidebarList({ session }: { session?: Session }) {
const chats = await (
await unstable_cache(
() =>
prisma.chat.findMany({
where: {
// This is for debugging, need to add scope to the query later
// userId: session?.user.id,
},
orderBy: {
updatedAt: "desc",
},
}),
() => db.query.chats.findMany({}),
// @ts-ignore
[session?.user?.id || ""],
{

View file

@ -1,130 +0,0 @@
import { useState, useCallback, useRef, useEffect } from "react";
import { type Message } from "@prisma/client";
import { nanoid } from "@/lib/utils";
export function usePrompt({
messages = [],
id,
}: {
messages?: Message[];
id: string | undefined;
}) {
const [isLoading, setIsLoading] = useState(false);
const [messageList, setMessageList] = useState(messages);
const isLoadingRef = useRef(isLoading);
const messageListRef = useRef(messageList);
useEffect(() => {
isLoadingRef.current = isLoading;
}, [isLoading]);
useEffect(() => {
messageListRef.current = messageList;
}, [messageList]);
const appendUserMessage = useCallback(
async (content: string | Message) => {
// Prevent multiple requests at once
if (isLoadingRef.current) return;
const userMsg =
typeof content === "string"
? ({ id: nanoid(10), role: "user", content } as Message)
: content;
const assMsg = {
id: nanoid(10),
role: "assistant",
content: "",
} as Message;
const messageListSnapshot = messageListRef.current;
// Reset output
setIsLoading(true);
try {
// Set user input immediately
setMessageList([...messageListSnapshot, userMsg]);
// If streaming, we need to use fetchEventSource directly
const response = await fetch(`/api/generate`, {
method: "POST",
body: JSON.stringify({
id: id || nanoid(10),
messages: [...messageListSnapshot, userMsg].map((m) => ({
role: m.role,
content: m.content,
})),
}),
headers: { "Content-Type": "application/json" },
});
// This data is a ReadableStream
const data = response.body;
if (!data) {
return;
}
const reader = data.getReader();
const decoder = new TextDecoder();
let done = false;
let accumulatedValue = ""; // Variable to accumulate chunks
while (!done) {
const { value, done: doneReading } = await reader.read();
done = doneReading;
const chunkValue = decoder.decode(value);
accumulatedValue += chunkValue; // Accumulate the chunk value
// Check if the accumulated value contains the delimiter
const delimiter = "\n";
const chunks = accumulatedValue.split(delimiter);
// Process all chunks except the last one (which may be incomplete)
while (chunks.length > 1) {
const chunkToDispatch = chunks.shift(); // Get the first chunk
if (chunkToDispatch && chunkToDispatch.length > 0) {
const chunk = JSON.parse(chunkToDispatch);
assMsg.content += chunk;
setMessageList([...messageListSnapshot, userMsg, assMsg]);
}
}
// The last chunk may be incomplete, so keep it in the accumulated value
accumulatedValue = chunks[0];
}
// Process any remaining accumulated value after the loop is done
if (accumulatedValue.length > 0) {
assMsg.content += accumulatedValue;
setMessageList([...messageListSnapshot, userMsg, assMsg]);
}
} finally {
setIsLoading(false);
}
},
[id]
);
const reloadLastMessage = useCallback(async () => {
// Prevent multiple requests at once
if (isLoadingRef.current) return;
const userMsg = messageListRef.current.at(-2);
const assMsg = messageListRef.current.at(-1);
// Both should exist.
if (!userMsg || !assMsg) return;
messageListRef.current = messageListRef.current.slice(0, -2);
setMessageList(messageListRef.current);
await appendUserMessage(userMsg);
}, [appendUserMessage]);
return {
messageList,
appendUserMessage,
reloadLastMessage,
isLoading,
};
}

View file

@ -9,14 +9,14 @@ import {
sessions,
verificationTokens,
} from "./lib/db/schema";
import { DrizzleAdapterPg } from "./lib/db";
import { PgAdapter } from "./lib/db";
export const {
handlers: { GET, POST },
auth,
CSRF_experimental,
} = NextAuth({
adapter: DrizzleAdapterPg(db, {
adapter: PgAdapter(db, {
accounts,
users,
sessions,

View file

@ -1,4 +0,0 @@
import { drizzle } from "drizzle-orm/vercel-postgres";
import { sql } from "@vercel/postgres";
export const db = drizzle(sql);

View file

@ -9,15 +9,14 @@
* ## Installation
*
* ```bash npm2yarn2pnpm
* npm install next-auth drizzle-orm @next-auth/drizzle-adapter
* npm install next-auth drizzle-orm @auth/drizzle-adapter
* npm install drizzle-kit --save-dev
* ```
*
* @module @next-auth/drizzle-adapter
* @module @auth/drizzle-adapter
*/
import type { Adapter } from "@auth/nextjs/adapters";
import type { Adapter } from "@auth/core/adapters";
import { and, eq } from "drizzle-orm";
import { v4 as uuid } from "uuid";
import type { DbClient, Schema } from "./schema";
/**
@ -28,7 +27,7 @@ import type { DbClient, Schema } from "./schema";
* ```js title="pages/api/auth/[...nextauth].js"
* import NextAuth from "next-auth"
* import GoogleProvider from "next-auth/providers/google"
* import { DrizzleAdapter } from "@next-auth/drizzle-adapter"
* import { DrizzleAdapter } from "@auth/drizzle-adapter"
* import { db } from "./db-schema"
*
* export default NextAuth({
@ -109,7 +108,7 @@ import type { DbClient, Schema } from "./schema";
* ```
*
**/
export function DrizzleAdapterPg(
export function PgAdapter(
client: DbClient,
{ users, sessions, verificationTokens, accounts }: Schema
): Adapter {
@ -117,7 +116,7 @@ export function DrizzleAdapterPg(
createUser: async (data) => {
return client
.insert(users)
.values({ ...data, id: uuid() })
.values({ ...data, id: crypto.randomUUID() as string })
.returning()
.then((res) => res[0]);
},
@ -188,7 +187,7 @@ export function DrizzleAdapterPg(
// Drizzle will return `null` for fields that are not defined.
// However, the return type is expecting `undefined`.
const account: ReturnType<Adapter["linkAccount"]> = {
const account = {
...updatedAccount,
access_token: updatedAccount.access_token ?? undefined,
token_type: updatedAccount.token_type ?? undefined,
@ -202,20 +201,19 @@ export function DrizzleAdapterPg(
return account;
},
getUserByAccount: async (account) => {
const user =
(await client
.select()
.from(users)
.innerJoin(
accounts,
and(
eq(accounts.providerAccountId, account.providerAccountId),
eq(accounts.provider, account.provider)
)
const dbAccount = await client
.select()
.from(accounts)
.where(
and(
eq(accounts.providerAccountId, account.providerAccountId),
eq(accounts.provider, account.provider)
)
.then((res) => res[0])) ?? null;
)
.leftJoin(users, eq(accounts.userId, users.id))
.then((res) => res[0]);
return user.users;
return dbAccount.users;
},
deleteSession: async (sessionToken) => {
await client

View file

@ -15,23 +15,23 @@ CREATE TABLE IF NOT EXISTS "accounts" (
ALTER TABLE "accounts" ADD CONSTRAINT "accounts_provider_providerAccountId" PRIMARY KEY("provider","providerAccountId");
CREATE TABLE IF NOT EXISTS "sessions" (
"sessionToken" text PRIMARY KEY NOT NULL,
"userId" text NOT NULL,
"expires" timestamp NOT NULL
"sessionToken" text PRIMARY KEY NOT NULL,
"expires" integer NOT NULL
);
CREATE TABLE IF NOT EXISTS "users" (
"id" text PRIMARY KEY NOT NULL,
"name" text,
"email" text NOT NULL,
"emailVerified" timestamp,
"emailVerified" integer,
"image" text
);
CREATE TABLE IF NOT EXISTS "verificationToken" (
"identifier" text NOT NULL,
"token" text NOT NULL,
"expires" timestamp NOT NULL
"expires" integer NOT NULL
);
--> statement-breakpoint
ALTER TABLE "verificationToken" ADD CONSTRAINT "verificationToken_identifier_token" PRIMARY KEY("identifier","token");

View file

@ -1,7 +0,0 @@
ALTER TABLE "accounts" DROP CONSTRAINT "accounts_provider_providerAccountId";
ALTER TABLE "verificationToken" DROP CONSTRAINT "verificationToken_identifier_token";
CREATE UNIQUE INDEX IF NOT EXISTS "Account_provider_providerAccountId_key" ON "accounts" ("provider","providerAccountId");
CREATE UNIQUE INDEX IF NOT EXISTS "Session_sessionToken_key" ON "sessions" ("sessionToken");
CREATE UNIQUE INDEX IF NOT EXISTS "User_email_key" ON "users" ("email");
CREATE UNIQUE INDEX IF NOT EXISTS "VerificationToken_identifier_token_key" ON "verificationToken" ("identifier","token");
CREATE UNIQUE INDEX IF NOT EXISTS "VerificationToken_token_key" ON "verificationToken" ("token");

View file

@ -0,0 +1,11 @@
CREATE TABLE IF NOT EXISTS "chats" (
"id" text PRIMARY KEY NOT NULL,
"role" text NOT NULL,
"userId" text NOT NULL
);
DO $$ BEGIN
ALTER TABLE "chats" ADD CONSTRAINT "chats_userId_users_id_fk" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

View file

@ -1,7 +1,7 @@
{
"version": "5",
"dialect": "pg",
"id": "ea430ef9-8e30-4cb6-9985-d03f43656cf8",
"id": "c6cb6121-2dc1-49be-8bd9-62f1c0c55939",
"prevId": "00000000-0000-0000-0000-000000000000",
"tables": {
"accounts": {
@ -105,21 +105,21 @@
"name": "sessions",
"schema": "",
"columns": {
"sessionToken": {
"name": "sessionToken",
"type": "text",
"primaryKey": true,
"notNull": true
},
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
"notNull": true
},
"sessionToken": {
"name": "sessionToken",
"type": "text",
"primaryKey": true,
"notNull": true
},
"expires": {
"name": "expires",
"type": "timestamp",
"type": "integer",
"primaryKey": false,
"notNull": true
}
@ -166,7 +166,7 @@
},
"emailVerified": {
"name": "emailVerified",
"type": "timestamp",
"type": "integer",
"primaryKey": false,
"notNull": false
},
@ -199,7 +199,7 @@
},
"expires": {
"name": "expires",
"type": "timestamp",
"type": "integer",
"primaryKey": false,
"notNull": true
}

View file

@ -1,8 +1,8 @@
{
"version": "5",
"dialect": "pg",
"id": "34122d24-88e0-430e-862c-2168b0f866cb",
"prevId": "ea430ef9-8e30-4cb6-9985-d03f43656cf8",
"id": "ad52915b-d697-4935-9373-97dca163dd91",
"prevId": "c6cb6121-2dc1-49be-8bd9-62f1c0c55939",
"tables": {
"accounts": {
"name": "accounts",
@ -75,16 +75,7 @@
"notNull": false
}
},
"indexes": {
"Account_provider_providerAccountId_key": {
"name": "Account_provider_providerAccountId_key",
"columns": [
"provider",
"providerAccountId"
],
"isUnique": true
}
},
"indexes": {},
"foreignKeys": {
"accounts_userId_users_id_fk": {
"name": "accounts_userId_users_id_fk",
@ -100,40 +91,81 @@
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {}
"compositePrimaryKeys": {
"accounts_provider_providerAccountId": {
"name": "accounts_provider_providerAccountId",
"columns": [
"provider",
"providerAccountId"
]
}
}
},
"sessions": {
"name": "sessions",
"chats": {
"name": "chats",
"schema": "",
"columns": {
"sessionToken": {
"name": "sessionToken",
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"role": {
"name": "role",
"type": "text",
"primaryKey": false,
"notNull": true
},
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"chats_userId_users_id_fk": {
"name": "chats_userId_users_id_fk",
"tableFrom": "chats",
"tableTo": "users",
"columnsFrom": [
"userId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {}
},
"sessions": {
"name": "sessions",
"schema": "",
"columns": {
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
"notNull": true
},
"sessionToken": {
"name": "sessionToken",
"type": "text",
"primaryKey": true,
"notNull": true
},
"expires": {
"name": "expires",
"type": "timestamp",
"type": "integer",
"primaryKey": false,
"notNull": true
}
},
"indexes": {
"Session_sessionToken_key": {
"name": "Session_sessionToken_key",
"columns": [
"sessionToken"
],
"isUnique": true
}
},
"indexes": {},
"foreignKeys": {
"sessions_userId_users_id_fk": {
"name": "sessions_userId_users_id_fk",
@ -175,7 +207,7 @@
},
"emailVerified": {
"name": "emailVerified",
"type": "timestamp",
"type": "integer",
"primaryKey": false,
"notNull": false
},
@ -186,15 +218,7 @@
"notNull": false
}
},
"indexes": {
"User_email_key": {
"name": "User_email_key",
"columns": [
"email"
],
"isUnique": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {}
},
@ -216,30 +240,22 @@
},
"expires": {
"name": "expires",
"type": "timestamp",
"type": "integer",
"primaryKey": false,
"notNull": true
}
},
"indexes": {
"VerificationToken_identifier_token_key": {
"name": "VerificationToken_identifier_token_key",
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"verificationToken_identifier_token": {
"name": "verificationToken_identifier_token",
"columns": [
"identifier",
"token"
],
"isUnique": true
},
"VerificationToken_token_key": {
"name": "VerificationToken_token_key",
"columns": [
"token"
],
"isUnique": true
]
}
},
"foreignKeys": {},
"compositePrimaryKeys": {}
}
}
},
"enums": {},

View file

@ -5,15 +5,15 @@
{
"idx": 0,
"version": "5",
"when": 1684771069602,
"tag": "0000_flawless_moondragon",
"when": 1685716228240,
"tag": "0000_clammy_freak",
"breakpoints": false
},
{
"idx": 1,
"version": "5",
"when": 1684771628481,
"tag": "0001_colorful_spectrum",
"when": 1685716937211,
"tag": "0001_petite_sue_storm",
"breakpoints": false
}
]

View file

@ -1,28 +1,23 @@
import {
integer,
timestamp,
pgTable,
text,
primaryKey,
uniqueIndex,
} from "drizzle-orm/pg-core";
import { drizzle } from "drizzle-orm/vercel-postgres";
import { sql } from "@vercel/postgres";
import { ProviderType } from "@auth/nextjs/providers";
import { sql } from "@vercel/postgres";
import { relations } from "drizzle-orm";
import { integer, pgTable, primaryKey, text } from "drizzle-orm/pg-core";
import { drizzle } from "drizzle-orm/vercel-postgres";
export const users = pgTable(
"users",
{
id: text("id").notNull().primaryKey(),
name: text("name"),
email: text("email").notNull(),
emailVerified: timestamp("emailVerified", { mode: "date" }),
image: text("image"),
},
(user) => ({
emailKey: uniqueIndex("User_email_key").on(user.email),
})
);
// const connection = createPool({ connectionString: process.env.POSTGRES_URL });
export const users = pgTable("users", {
id: text("id").notNull().primaryKey(),
name: text("name"),
email: text("email").notNull(),
emailVerified: integer("emailVerified"),
image: text("image"),
});
export const usersRelations = relations(users, ({ many }) => ({
chats: many(chats),
accounts: many(accounts),
}));
export const accounts = pgTable(
"accounts",
@ -41,313 +36,63 @@ export const accounts = pgTable(
id_token: text("id_token"),
session_state: text("session_state"),
},
(table) => {
return {
providerProviderAccountIdKey: uniqueIndex(
"Account_provider_providerAccountId_key"
).on(table.provider, table.providerAccountId),
};
}
(account) => ({
_: primaryKey(account.provider, account.providerAccountId),
})
);
export const sessions = pgTable(
"sessions",
{
sessionToken: text("sessionToken").notNull().primaryKey(),
userId: text("userId")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
expires: timestamp("expires", { mode: "date" }).notNull(),
},
(table) => {
return {
sessionTokenKey: uniqueIndex("Session_sessionToken_key").on(
table.sessionToken
),
};
}
);
export const sessions = pgTable("sessions", {
userId: text("userId")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
sessionToken: text("sessionToken").notNull().primaryKey(),
expires: integer("expires").notNull(),
});
export const verificationTokens = pgTable(
"verificationToken",
{
identifier: text("identifier").notNull(),
token: text("token").notNull(),
expires: timestamp("expires", { mode: "date" }).notNull(),
expires: integer("expires").notNull(),
},
(table) => ({
identifierTokenKey: uniqueIndex(
"VerificationToken_identifier_token_key"
).on(table.identifier, table.token),
tokenKey: uniqueIndex("VerificationToken_token_key").on(table.token),
(vt) => ({
_: primaryKey(vt.identifier, vt.token),
})
);
// Connect to Vercel Postgres
export const db = drizzle(sql);
export type DbClient = typeof db;
export type Schema = {
users: typeof users;
accounts: typeof accounts;
sessions: typeof sessions;
verificationTokens: typeof verificationTokens;
};
// import { sql, eq, and } from "drizzle-orm";
// import {
// PgDatabase,
// QueryResultHKT,
// integer,
// pgTable,
// text,
// timestamp,
// uniqueIndex,
// uuid,
// } from "drizzle-orm/pg-core";
// import { drizzle } from "drizzle-orm/vercel-postgres";
// import { sql as c } from "@vercel/postgres";
// import { Adapter, AdapterUser } from "@auth/nextjs/adapters";
// export const db = drizzle(c);
export const chats = pgTable("chats", {
id: text("id").notNull().primaryKey(),
title: text("role").notNull(),
userId: text("userId")
.notNull()
.references(() => users.id),
});
// export const users = pgTable(
// "users",
// {
// id: uuid("id")
// .notNull()
// .primaryKey()
// .default(sql`gen_random_uuid()`),
// name: text("name"),
// email: text("email"),
// emailVerified: timestamp("emailVerified", { precision: 3 }),
// image: text("image"),
// },
// (table) => {
// return {
// emailKey: uniqueIndex("User_email_key").on(table.email),
// };
// }
// );
export const chatsRelations = relations(chats, ({ one }) => ({
user: one(users, {
fields: [chats.userId],
references: [users.id],
}),
}));
// export const verificationTokens = pgTable(
// "verification_tokens",
// {
// identifier: text("identifier").notNull(),
// token: text("token").notNull(),
// expires: timestamp("expires", { precision: 3 }).notNull(),
// },
// (table) => {
// return {
// identifierTokenKey: uniqueIndex(
// "VerificationToken_identifier_token_key"
// ).on(table.identifier, table.token),
// tokenKey: uniqueIndex("VerificationToken_token_key").on(table.token),
// };
// }
// );
export const db = drizzle(sql, {
schema: {
users,
accounts,
sessions,
verificationTokens,
chats,
chatsRelations,
usersRelations,
},
});
// export const sessions = pgTable(
// "sessions",
// {
// id: uuid("id")
// .notNull()
// .primaryKey()
// .default(sql`gen_random_uuid()`),
// sessionToken: text("sessionToken").notNull(),
// userId: uuid("userId")
// .notNull()
// .references(() => users.id, { onDelete: "cascade", onUpdate: "cascade" }),
// expires: timestamp("expires", { precision: 3 }).notNull(),
// },
// (table) => {
// return {
// sessionTokenKey: uniqueIndex("Session_sessionToken_key").on(
// table.sessionToken
// ),
// };
// }
// );
// export const accounts = pgTable(
// "accounts",
// {
// id: uuid("id")
// .notNull()
// .primaryKey()
// .default(sql`gen_random_uuid()`),
// userId: uuid("userId")
// .notNull()
// .references(() => users.id, { onDelete: "cascade", onUpdate: "cascade" }),
// type: text("type").notNull(),
// provider: text("provider").notNull(),
// providerAccountId: text("providerAccountId").notNull(),
// refresh_token: text("refresh_token"),
// access_token: text("access_token"),
// expires_at: integer("expires_at"),
// token_type: text("token_type"),
// scope: text("scope"),
// id_token: text("id_token"),
// session_state: text("session_state"),
// },
// (table) => {
// return {
// providerProviderAccountIdKey: uniqueIndex(
// "Account_provider_providerAccountId_key"
// ).on(table.provider, table.providerAccountId),
// };
// }
// );
// type Users = typeof users;
// type Sessions = typeof sessions;
// type Accounts = typeof accounts;
// type VerificationTokens = typeof verificationTokens;
// export function DrizzleAdapter<
// T extends PgDatabase<U>,
// U extends QueryResultHKT
// >({
// db,
// schema,
// }: {
// db: T;
// schema: {
// users: Users;
// sessions: Sessions;
// accounts: Accounts;
// verificationTokens: VerificationTokens;
// };
// }): Adapter {
// return {
// async createUser(user) {
// const [newUser] = await db.insert(schema.users).values(user).returning();
// return newUser as AdapterUser;
// },
// async getUser(id) {
// const [user] = await db
// .select()
// .from(schema.users)
// .where(eq(schema.users.id, id));
// return (user as AdapterUser) || null;
// },
// async getUserByEmail(email) {
// const [user] = await db
// .select()
// .from(schema.users)
// .where(eq(schema.users.email, email));
// return (user as AdapterUser) || null;
// },
// async getUserByAccount({ providerAccountId, provider }) {
// const results = await db
// .select()
// .from(schema.users)
// .leftJoin(schema.accounts, eq(schema.accounts.userId, schema.users.id))
// .where(
// and(
// eq(schema.accounts.provider, provider),
// eq(schema.accounts.providerAccountId, providerAccountId)
// )
// );
// if (results.length) {
// return results[0].users as AdapterUser;
// }
// return null;
// },
// async updateUser(user) {
// const userId = user.id;
// if (!userId) {
// throw new Error("Cannot update user without id");
// }
// const [updatedUser] = await db
// .update(schema.users)
// .set(user)
// .where(eq(schema.users.id, userId))
// .returning();
// return updatedUser as AdapterUser;
// },
// async deleteUser(userId) {
// await db.delete(schema.users).where(eq(schema.users.id, userId));
// },
// async linkAccount(account) {
// await db.insert(schema.accounts).values(account);
// },
// async unlinkAccount({ providerAccountId, provider }) {
// await db
// .delete(schema.accounts)
// .where(
// and(
// eq(schema.accounts.provider, provider),
// eq(schema.accounts.providerAccountId, providerAccountId)
// )
// );
// },
// async createSession(session) {
// const [newSession] = await db
// .insert(schema.sessions)
// .values(session)
// .returning();
// return newSession;
// },
// async getSessionAndUser(sessionToken) {
// const results = await db
// .select()
// .from(schema.sessions)
// .leftJoin(schema.users, eq(schema.users.id, schema.sessions.userId))
// .where(eq(schema.sessions.sessionToken, sessionToken));
// if (results.length) {
// return {
// user: results[0].users! as AdapterUser,
// session: results[0].sessions,
// };
// }
// return null;
// },
// async updateSession(session) {
// const [updatedSession] = await db
// .update(schema.sessions)
// .set(session)
// .where(eq(schema.sessions.sessionToken, session.sessionToken))
// .returning();
// return updatedSession;
// },
// async deleteSession(sessionToken) {
// await db
// .delete(schema.sessions)
// .where(eq(schema.sessions.sessionToken, sessionToken));
// },
// async createVerificationToken(token) {
// const [newVerificationToken] = await db
// .insert(schema.verificationTokens)
// .values(token)
// .returning();
// return newVerificationToken;
// },
// async useVerificationToken({ identifier, token }) {
// const [deletedVerificationToken] = await db
// .delete(schema.verificationTokens)
// .where(
// and(
// eq(schema.verificationTokens.identifier, identifier),
// eq(schema.verificationTokens.token, token)
// )
// )
// .returning();
// return deletedVerificationToken || null;
// },
// };
// }
export type DbClient = typeof db;

View file

@ -3,8 +3,8 @@
"version": "0.0.2",
"private": true,
"scripts": {
"dev": "prisma generate && next dev",
"build": "prisma generate && next build",
"dev": "next dev",
"build": "next build",
"db:mg:create": "drizzle-kit generate:pg --config=drizzle.config.ts",
"db:mg:apply": "ts-node --project tsconfig.migration.json ./lib/db/migrate --config=drizzle.config.ts",
"db:check": "drizzle-kit check:pg --config=drizzle.config.ts",
@ -18,6 +18,7 @@
"format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache"
},
"dependencies": {
"@auth/core": "0.0.0-manual.527fff6c",
"@auth/nextjs": "0.0.0-manual.030e8328",
"@next-auth/prisma-adapter": "1.0.6",
"@prisma/client": "^4.14.0",
@ -25,6 +26,7 @@
"@vercel/analytics": "^1.0.0",
"@vercel/kv": "^0.2.1",
"@vercel/postgres": "^0.3.0",
"ai-connector": "^0.0.5",
"body-scroll-lock": "4.0.0-beta.0",
"class-variance-authority": "^0.4.0",
"clsx": "^1.2.1",
@ -38,7 +40,7 @@
"jsonwebtoken": "^9.0.0",
"lucide-react": "0.216.0",
"nanoid": "^4.0.2",
"next": "13.4.3-canary.3",
"next": "13.4.5-canary.3",
"next-themes": "^0.2.1",
"openai-edge": "^0.5.1",
"react": "^18.2.0",
@ -69,7 +71,7 @@
"dotenv": "^16.0.3",
"drizzle-kit": "^0.18.0",
"eslint": "^8.31.0",
"eslint-config-next": "13.4.3-canary.3",
"eslint-config-next": "13.4.5-canary.3",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-react": "^7.31.11",
"eslint-plugin-tailwindcss": "^3.8.0",

138
pnpm-lock.yaml generated
View file

@ -4,9 +4,12 @@ overrides:
'@auth/core': 0.0.0-manual.527fff6c
dependencies:
'@auth/core':
specifier: 0.0.0-manual.527fff6c
version: 0.0.0-manual.527fff6c
'@auth/nextjs':
specifier: 0.0.0-manual.030e8328
version: 0.0.0-manual.030e8328(next@13.4.3-canary.3)(react@18.2.0)
version: 0.0.0-manual.030e8328(next@13.4.5-canary.3)(react@18.2.0)
'@next-auth/prisma-adapter':
specifier: 1.0.6
version: 1.0.6(@prisma/client@4.14.0)(next-auth@4.22.1)
@ -25,6 +28,9 @@ dependencies:
'@vercel/postgres':
specifier: ^0.3.0
version: 0.3.0
ai-connector:
specifier: ^0.0.5
version: 0.0.5(react@18.2.0)
body-scroll-lock:
specifier: 4.0.0-beta.0
version: 4.0.0-beta.0
@ -65,11 +71,11 @@ dependencies:
specifier: ^4.0.2
version: 4.0.2
next:
specifier: 13.4.3-canary.3
version: 13.4.3-canary.3(@babel/core@7.21.8)(react-dom@18.2.0)(react@18.2.0)
specifier: 13.4.5-canary.3
version: 13.4.5-canary.3(@babel/core@7.21.8)(react-dom@18.2.0)(react@18.2.0)
next-themes:
specifier: ^0.2.1
version: 0.2.1(next@13.4.3-canary.3)(react-dom@18.2.0)(react@18.2.0)
version: 0.2.1(next@13.4.5-canary.3)(react-dom@18.2.0)(react@18.2.0)
openai-edge:
specifier: ^0.5.1
version: 0.5.1
@ -154,8 +160,8 @@ devDependencies:
specifier: ^8.31.0
version: 8.40.0
eslint-config-next:
specifier: 13.4.3-canary.3
version: 13.4.3-canary.3(eslint@8.40.0)(typescript@4.9.5)
specifier: 13.4.5-canary.3
version: 13.4.5-canary.3(eslint@8.40.0)(typescript@4.9.5)
eslint-config-prettier:
specifier: ^8.3.0
version: 8.8.0(eslint@8.40.0)
@ -213,14 +219,14 @@ packages:
preact-render-to-string: 5.2.3(preact@10.11.3)
dev: false
/@auth/nextjs@0.0.0-manual.030e8328(next@13.4.3-canary.3)(react@18.2.0):
/@auth/nextjs@0.0.0-manual.030e8328(next@13.4.5-canary.3)(react@18.2.0):
resolution: {integrity: sha512-AAtUl9EVCKqLRneDAq6KfUprWmsBRzsBoQ+8ytz/Nfgs8Uax5CWvCJs2CsnYNk04bXSB4L7eyMJmc1zTzZKaHg==}
peerDependencies:
next: ^13.4.2
react: ^18.2.0
dependencies:
'@auth/core': 0.0.0-manual.527fff6c
next: 13.4.3-canary.3(@babel/core@7.21.8)(react-dom@18.2.0)(react@18.2.0)
next: 13.4.5-canary.3(@babel/core@7.21.8)(react-dom@18.2.0)(react@18.2.0)
react: 18.2.0
transitivePeerDependencies:
- nodemailer
@ -593,21 +599,21 @@ packages:
next-auth: ^4
dependencies:
'@prisma/client': 4.14.0(prisma@4.14.0)
next-auth: 4.22.1(next@13.4.3-canary.3)(react-dom@18.2.0)(react@18.2.0)
next-auth: 4.22.1(next@13.4.5-canary.3)(react-dom@18.2.0)(react@18.2.0)
dev: false
/@next/env@13.4.3-canary.3:
resolution: {integrity: sha512-AlAPQdQ2qf3RJsaaKMXo22l9MLUeqIiDJSJ1LcM9uWiOMIAgsLlQCxcoGcm7rQP9CSw4VPPFSpCR0tvCKmxVwQ==}
/@next/env@13.4.5-canary.3:
resolution: {integrity: sha512-2TrPvCIs8R9DpFpEDmGUOpWkVqbpb4+sGQMcZVP4zDYYg893p0nAbNbBxL996oBl+/vLTzcLIDceP5peHsGPzg==}
dev: false
/@next/eslint-plugin-next@13.4.3-canary.3:
resolution: {integrity: sha512-ggD4Z0psyVcLcr0QlGXu+zEdbiYZra8r9LZgL1XuTAtTl4H1h3QgpNB6ENVqJCQibH8h0bBktOrRpHiLwbyRQw==}
/@next/eslint-plugin-next@13.4.5-canary.3:
resolution: {integrity: sha512-hsFfLSo8snWDLBwDT7+i4gEWZjsEzNHlZLT0ox8ftcZo3XBz8FrX11h9yGacageRbiiTotl/5U31Dxrt7MVoBA==}
dependencies:
glob: 7.1.7
dev: true
/@next/swc-darwin-arm64@13.4.3-canary.3:
resolution: {integrity: sha512-MVmNJTKe50Qm5a6Khju3MpYiTie9ByJVT67rvYxCfZkd48p59PWoosu9tvCtlVuxb5jZxzOAZ/vzDciTs7Vgcw==}
/@next/swc-darwin-arm64@13.4.5-canary.3:
resolution: {integrity: sha512-mUlpzua0RDPLNfNeqi0DzWNCqVzMphNh42BS8PojVO3NPC55+RX9tllQngz+qFAOcLL7g4LgoeE9VWgh31s/WQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
@ -615,8 +621,8 @@ packages:
dev: false
optional: true
/@next/swc-darwin-x64@13.4.3-canary.3:
resolution: {integrity: sha512-NLrVHpJNqrKF93gZEQSoEq1WAVy0JYq8fry7CvSj2cCjgQxna06LPfkX9R3Iu3eRJJD/idCxbedXjg52oma/sg==}
/@next/swc-darwin-x64@13.4.5-canary.3:
resolution: {integrity: sha512-0bkYuSFh1/0ZedCVsSMtHiSxdfQxF0BO/v5VwRdOLtOZE8WrQdoXsWiVsiFBOTutiZDhats9exFOFgmymoSqSA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
@ -624,8 +630,8 @@ packages:
dev: false
optional: true
/@next/swc-linux-arm64-gnu@13.4.3-canary.3:
resolution: {integrity: sha512-CfrQFtHsbSeN43o/OSMCSUmA610u3gteKhq1SGzzq7TVaT4OnqoHEHfROEmgrpAkIMq65yIlHJM/Aq3/EBkFaw==}
/@next/swc-linux-arm64-gnu@13.4.5-canary.3:
resolution: {integrity: sha512-+PxhM2E98APKNEl1FCwhqU9ttGRoWsZcPPU20qcKFrJ/fKbfaWDnhzlSiZPmmERISZrmd54Uy3maNq9ys+bz6g==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
@ -633,8 +639,8 @@ packages:
dev: false
optional: true
/@next/swc-linux-arm64-musl@13.4.3-canary.3:
resolution: {integrity: sha512-rRAilp0kqBAWJJuOfaK+GFclricB/lqFspFhk7U6tkYDHyXDZ/MrjTlfOraOJtqBTFtLM1zuzLvPhcK22DzJhA==}
/@next/swc-linux-arm64-musl@13.4.5-canary.3:
resolution: {integrity: sha512-KMRWPxeoZ41146NHpMAGMtD/RkQt/0QOlL13pREnNjeTzQI6P20X+ra5tHkCQoFB/8xseN9RXnuLMyYG3mYoGw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
@ -642,8 +648,8 @@ packages:
dev: false
optional: true
/@next/swc-linux-x64-gnu@13.4.3-canary.3:
resolution: {integrity: sha512-9weSKDC6eJcDOhKURj/oKa7f9Z9fEZKjnYQBJDX/ojy1LThei/drRNXYrXTY1iay7tcbRhEBvtCiYaEPjvLBUA==}
/@next/swc-linux-x64-gnu@13.4.5-canary.3:
resolution: {integrity: sha512-dwSxDddWMaTAmSPxSWWrwaHHPqLlnNJoc22dTfyQX9Hwecq+Sq2RGSkGicga3z6Z7rX3Nm4MbNduM2GWXwcvgg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
@ -651,8 +657,8 @@ packages:
dev: false
optional: true
/@next/swc-linux-x64-musl@13.4.3-canary.3:
resolution: {integrity: sha512-yODhVd1qvxFhUja4WrSJhZhyiLD85O5855FxCVxky85qb2+aTjWMYv5DM7sl1fzCag7EwtcI4+HJb4rkBMifRQ==}
/@next/swc-linux-x64-musl@13.4.5-canary.3:
resolution: {integrity: sha512-R2SqJsC6QPNxO3t/U2fMouzLfUNLHP8PfZH/XTIwQ12dxZCwUwBg/cNX5ocBtoci3lCYNcOLNjSuc3z9b/yIeQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
@ -660,8 +666,8 @@ packages:
dev: false
optional: true
/@next/swc-win32-arm64-msvc@13.4.3-canary.3:
resolution: {integrity: sha512-2SY5f5tndZtObiqS2Uioyou18Ef+fG5yzCj4EAvk1FhuQBoprLaVDyP3wehJACg9U5kYocvLA18wKIt8byhG2g==}
/@next/swc-win32-arm64-msvc@13.4.5-canary.3:
resolution: {integrity: sha512-/spv7kDp2xKUJzdvGFU2gf/N1lXtm/E2p/Fx/XreUyajiaT0f57d2mHfDabW5saq3KL3wPlWZ5zW7iDh2Awm+Q==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
@ -669,8 +675,8 @@ packages:
dev: false
optional: true
/@next/swc-win32-ia32-msvc@13.4.3-canary.3:
resolution: {integrity: sha512-eCEPIrSkpIG+k4h9d8h56lVhqpPjjFm/C/P3Vq1AGDSPh9DQ+xfWTleWBeVskKO4RZf1R4aCHLVw12rkQcLw8g==}
/@next/swc-win32-ia32-msvc@13.4.5-canary.3:
resolution: {integrity: sha512-VIlQ+emO306CYbIyEKu8RTAzmMw/z+akEhu2urZPKjj+UMKCLfq1w4u3GJfURfdRiJ5ws7fLXDHVAjon4G+Ygg==}
engines: {node: '>= 10'}
cpu: [ia32]
os: [win32]
@ -678,8 +684,8 @@ packages:
dev: false
optional: true
/@next/swc-win32-x64-msvc@13.4.3-canary.3:
resolution: {integrity: sha512-n8vAEOOiFgbXleiPTAQjiEgMFCLQaTqPl23fmzf/yKx2RjmWxYM19vn7SoaV20sVPK36KMAorxxYB7H/ny9hKw==}
/@next/swc-win32-x64-msvc@13.4.5-canary.3:
resolution: {integrity: sha512-JSb5haHmRxn2Jysrsw3UJ/mgNu0TD+JJdHyGkdQeGIM4V1Q1G/KgQNCTovWfimd8e1JUoZqSV4aX+y7zEDVkEg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@ -1284,6 +1290,18 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
/ai-connector@0.0.5(react@18.2.0):
resolution: {integrity: sha512-byHDAVQt3zlQ61uEBDKlOlY3uX2O+ahNVV1bnnHhnv4fNIlu+NWefxlRUqAxVM80tlCrS/+aXA8AlpkIZsa1tg==}
engines: {node: '>=14.6'}
peerDependencies:
react: ^18.0.0
dependencies:
eventsource-parser: 1.0.0
nanoid: 3.3.6
react: 18.2.0
swr: 2.1.5(react@18.2.0)
dev: false
/ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
dependencies:
@ -2313,8 +2331,8 @@ packages:
engines: {node: '>=12'}
dev: false
/eslint-config-next@13.4.3-canary.3(eslint@8.40.0)(typescript@4.9.5):
resolution: {integrity: sha512-vKWwNIUvCRRZLHejVAu/eodOMRmTVYHsTnzFIAQeD7PEIbyJl8fTntPyoE3rPgChWamRYAWR9isyZER4ToUc7Q==}
/eslint-config-next@13.4.5-canary.3(eslint@8.40.0)(typescript@4.9.5):
resolution: {integrity: sha512-F1W76ozmRCPk8sxPXO4tSy3pstBerEfiZ1Aiagr+d2a+l/Mx5CgHWf75CwsQfpiC6BbAee8RrdIjb8kvGlPeww==}
peerDependencies:
eslint: ^7.23.0 || ^8.0.0
typescript: '>=3.3.1'
@ -2322,7 +2340,7 @@ packages:
typescript:
optional: true
dependencies:
'@next/eslint-plugin-next': 13.4.3-canary.3
'@next/eslint-plugin-next': 13.4.5-canary.3
'@rushstack/eslint-patch': 1.2.0
'@typescript-eslint/parser': 5.59.5(eslint@8.40.0)(typescript@4.9.5)
eslint: 8.40.0
@ -4031,7 +4049,7 @@ packages:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: true
/next-auth@4.22.1(next@13.4.3-canary.3)(react-dom@18.2.0)(react@18.2.0):
/next-auth@4.22.1(next@13.4.5-canary.3)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-NTR3f6W7/AWXKw8GSsgSyQcDW6jkslZLH8AiZa5PQ09w1kR8uHtR9rez/E9gAq/o17+p0JYHE8QjF3RoniiObA==}
peerDependencies:
next: ^12.2.5 || ^13
@ -4046,7 +4064,7 @@ packages:
'@panva/hkdf': 1.1.1
cookie: 0.5.0
jose: 4.14.4
next: 13.4.3-canary.3(@babel/core@7.21.8)(react-dom@18.2.0)(react@18.2.0)
next: 13.4.5-canary.3(@babel/core@7.21.8)(react-dom@18.2.0)(react@18.2.0)
oauth: 0.9.15
openid-client: 5.4.2
preact: 10.14.1
@ -4056,14 +4074,14 @@ packages:
uuid: 8.3.2
dev: false
/next-themes@0.2.1(next@13.4.3-canary.3)(react-dom@18.2.0)(react@18.2.0):
/next-themes@0.2.1(next@13.4.5-canary.3)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==}
peerDependencies:
next: '*'
react: '*'
react-dom: '*'
dependencies:
next: 13.4.3-canary.3(@babel/core@7.21.8)(react-dom@18.2.0)(react@18.2.0)
next: 13.4.5-canary.3(@babel/core@7.21.8)(react-dom@18.2.0)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false
@ -4072,14 +4090,13 @@ packages:
resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==}
dev: true
/next@13.4.3-canary.3(@babel/core@7.21.8)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-Fix/RAVHJHUpJZsvftaC5Pm8qGP7/NIitOBsKPozSPKIekCUWwKiaoLPY140taMgl9R+oW1nXKwYhAdjM8gSMg==}
/next@13.4.5-canary.3(@babel/core@7.21.8)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-5YLpHWSLjjInYlqxtkZZr7cwYp62wXEm7ik6Wu+4JqWQdbwD/pemuXwErxRIt65ruDQwe9RvE/dzMOuQuNDE+A==}
engines: {node: '>=16.8.0'}
hasBin: true
peerDependencies:
'@opentelemetry/api': ^1.1.0
fibers: '>= 3.1.0'
node-sass: ^6.0.0 || ^7.0.0
react: ^18.2.0
react-dom: ^18.2.0
sass: ^1.3.0
@ -4088,12 +4105,10 @@ packages:
optional: true
fibers:
optional: true
node-sass:
optional: true
sass:
optional: true
dependencies:
'@next/env': 13.4.3-canary.3
'@next/env': 13.4.5-canary.3
'@swc/helpers': 0.5.1
busboy: 1.6.0
caniuse-lite: 1.0.30001486
@ -4103,15 +4118,15 @@ packages:
styled-jsx: 5.1.1(@babel/core@7.21.8)(react@18.2.0)
zod: 3.21.4
optionalDependencies:
'@next/swc-darwin-arm64': 13.4.3-canary.3
'@next/swc-darwin-x64': 13.4.3-canary.3
'@next/swc-linux-arm64-gnu': 13.4.3-canary.3
'@next/swc-linux-arm64-musl': 13.4.3-canary.3
'@next/swc-linux-x64-gnu': 13.4.3-canary.3
'@next/swc-linux-x64-musl': 13.4.3-canary.3
'@next/swc-win32-arm64-msvc': 13.4.3-canary.3
'@next/swc-win32-ia32-msvc': 13.4.3-canary.3
'@next/swc-win32-x64-msvc': 13.4.3-canary.3
'@next/swc-darwin-arm64': 13.4.5-canary.3
'@next/swc-darwin-x64': 13.4.5-canary.3
'@next/swc-linux-arm64-gnu': 13.4.5-canary.3
'@next/swc-linux-arm64-musl': 13.4.5-canary.3
'@next/swc-linux-x64-gnu': 13.4.5-canary.3
'@next/swc-linux-x64-musl': 13.4.5-canary.3
'@next/swc-win32-arm64-msvc': 13.4.5-canary.3
'@next/swc-win32-ia32-msvc': 13.4.5-canary.3
'@next/swc-win32-x64-msvc': 13.4.5-canary.3
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
@ -5059,6 +5074,15 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
/swr@2.1.5(react@18.2.0):
resolution: {integrity: sha512-/OhfZMcEpuz77KavXST5q6XE9nrOBOVcBLWjMT+oAE/kQHyE3PASrevXCtQDZ8aamntOfFkbVJp7Il9tNBQWrw==}
peerDependencies:
react: ^16.11.0 || ^17.0.0 || ^18.0.0
dependencies:
react: 18.2.0
use-sync-external-store: 1.2.0(react@18.2.0)
dev: false
/synckit@0.8.5:
resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==}
engines: {node: ^14.18.0 || >=16.0.0}
@ -5405,6 +5429,14 @@ packages:
tslib: 2.5.0
dev: false
/use-sync-external-store@1.2.0(react@18.2.0):
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
react: 18.2.0
dev: false
/utf-8-validate@6.0.3:
resolution: {integrity: sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==}
engines: {node: '>=6.14.2'}