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"; "use client";
import { type Message } from "@prisma/client"; import { type Message } from "ai-connector";
import { ChatMessage } from "./chat-message"; import { ChatMessage } from "./chat-message";
import { NextChatLogo } from "@/components/ui/nextchat-logo"; 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 { useRouter } from "next/navigation";
import { ChatList } from "./chat-list"; import { ChatList } from "./chat-list";
import { Prompt } from "./prompt"; import { Prompt } from "./prompt";
import { usePrompt } from "./use-prompt"; import { useChat } from "ai-connector";
export interface ChatProps { export interface ChatProps {
// create?: (input: string) => Chat | undefined; // create?: (input: string) => Chat | undefined;
messages?: Message[]; initialMessages?: Message[];
id?: string; id?: string;
} }
export function Chat({ export function Chat({
id, id,
// create, // create,
messages, initialMessages,
}: ChatProps) { }: ChatProps) {
const router = useRouter(); const router = useRouter();
const { isLoading, messageList, appendUserMessage, reloadLastMessage } = const { isLoading, messages, reload, append } = useChat({
usePrompt({ initialMessages: initialMessages as any[],
messages, id,
id, // onCreate: (id: string) => {
// onCreate: (id: string) => { // router.push(`/chat/${id}`);
// router.push(`/chat/${id}`); // },
// }, });
});
return ( return (
<main className="transition-width relative min-h-full w-full flex-1 overflow-y-auto flex flex-col"> <main className="transition-width relative min-h-full w-full flex-1 overflow-y-auto flex flex-col">
<div className="flex-1"> <div className="flex-1">
<ChatList messages={messageList} /> <ChatList messages={messages} />
</div> </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"> <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 <Prompt
onSubmit={appendUserMessage} onSubmit={(value) => {
onRefresh={messageList.length ? reloadLastMessage : undefined} append({
content: value,
role: "user",
});
}}
onRefresh={messages.length ? reload : undefined}
isLoading={isLoading} isLoading={isLoading}
/> />
</div> </div>

View file

@ -46,7 +46,7 @@ export default async function ChatPage({ params }: ChatPageProps) {
<div className="relative flex h-full w-full overflow-hidden"> <div className="relative flex h-full w-full overflow-hidden">
<Sidebar session={session} /> <Sidebar session={session} />
<div className="flex h-full min-w-0 flex-1 flex-col"> <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>
</div> </div>
); );

View file

@ -8,6 +8,7 @@ import { Plus } from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import { unstable_cache } from "next/cache"; import { unstable_cache } from "next/cache";
import { SidebarItem } from "./sidebar-item"; import { SidebarItem } from "./sidebar-item";
import { db } from "@/lib/db/schema";
export interface SidebarProps { export interface SidebarProps {
session?: Session; session?: Session;
@ -60,16 +61,7 @@ Sidebar.displayName = "Sidebar";
async function SidebarList({ session }: { session?: Session }) { async function SidebarList({ session }: { session?: Session }) {
const chats = await ( const chats = await (
await unstable_cache( await unstable_cache(
() => () => db.query.chats.findMany({}),
prisma.chat.findMany({
where: {
// This is for debugging, need to add scope to the query later
// userId: session?.user.id,
},
orderBy: {
updatedAt: "desc",
},
}),
// @ts-ignore // @ts-ignore
[session?.user?.id || ""], [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, sessions,
verificationTokens, verificationTokens,
} from "./lib/db/schema"; } from "./lib/db/schema";
import { DrizzleAdapterPg } from "./lib/db"; import { PgAdapter } from "./lib/db";
export const { export const {
handlers: { GET, POST }, handlers: { GET, POST },
auth, auth,
CSRF_experimental, CSRF_experimental,
} = NextAuth({ } = NextAuth({
adapter: DrizzleAdapterPg(db, { adapter: PgAdapter(db, {
accounts, accounts,
users, users,
sessions, 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 * ## Installation
* *
* ```bash npm2yarn2pnpm * ```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 * 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 { and, eq } from "drizzle-orm";
import { v4 as uuid } from "uuid";
import type { DbClient, Schema } from "./schema"; import type { DbClient, Schema } from "./schema";
/** /**
@ -28,7 +27,7 @@ import type { DbClient, Schema } from "./schema";
* ```js title="pages/api/auth/[...nextauth].js" * ```js title="pages/api/auth/[...nextauth].js"
* import NextAuth from "next-auth" * import NextAuth from "next-auth"
* import GoogleProvider from "next-auth/providers/google" * 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" * import { db } from "./db-schema"
* *
* export default NextAuth({ * export default NextAuth({
@ -109,7 +108,7 @@ import type { DbClient, Schema } from "./schema";
* ``` * ```
* *
**/ **/
export function DrizzleAdapterPg( export function PgAdapter(
client: DbClient, client: DbClient,
{ users, sessions, verificationTokens, accounts }: Schema { users, sessions, verificationTokens, accounts }: Schema
): Adapter { ): Adapter {
@ -117,7 +116,7 @@ export function DrizzleAdapterPg(
createUser: async (data) => { createUser: async (data) => {
return client return client
.insert(users) .insert(users)
.values({ ...data, id: uuid() }) .values({ ...data, id: crypto.randomUUID() as string })
.returning() .returning()
.then((res) => res[0]); .then((res) => res[0]);
}, },
@ -188,7 +187,7 @@ export function DrizzleAdapterPg(
// Drizzle will return `null` for fields that are not defined. // Drizzle will return `null` for fields that are not defined.
// However, the return type is expecting `undefined`. // However, the return type is expecting `undefined`.
const account: ReturnType<Adapter["linkAccount"]> = { const account = {
...updatedAccount, ...updatedAccount,
access_token: updatedAccount.access_token ?? undefined, access_token: updatedAccount.access_token ?? undefined,
token_type: updatedAccount.token_type ?? undefined, token_type: updatedAccount.token_type ?? undefined,
@ -202,20 +201,19 @@ export function DrizzleAdapterPg(
return account; return account;
}, },
getUserByAccount: async (account) => { getUserByAccount: async (account) => {
const user = const dbAccount = await client
(await client .select()
.select() .from(accounts)
.from(users) .where(
.innerJoin( and(
accounts, eq(accounts.providerAccountId, account.providerAccountId),
and( eq(accounts.provider, account.provider)
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) => { deleteSession: async (sessionToken) => {
await client 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"); ALTER TABLE "accounts" ADD CONSTRAINT "accounts_provider_providerAccountId" PRIMARY KEY("provider","providerAccountId");
CREATE TABLE IF NOT EXISTS "sessions" ( CREATE TABLE IF NOT EXISTS "sessions" (
"sessionToken" text PRIMARY KEY NOT NULL,
"userId" text 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" ( CREATE TABLE IF NOT EXISTS "users" (
"id" text PRIMARY KEY NOT NULL, "id" text PRIMARY KEY NOT NULL,
"name" text, "name" text,
"email" text NOT NULL, "email" text NOT NULL,
"emailVerified" timestamp, "emailVerified" integer,
"image" text "image" text
); );
CREATE TABLE IF NOT EXISTS "verificationToken" ( CREATE TABLE IF NOT EXISTS "verificationToken" (
"identifier" text NOT NULL, "identifier" text NOT NULL,
"token" text NOT NULL, "token" text NOT NULL,
"expires" timestamp NOT NULL "expires" integer NOT NULL
); );
--> statement-breakpoint --> statement-breakpoint
ALTER TABLE "verificationToken" ADD CONSTRAINT "verificationToken_identifier_token" PRIMARY KEY("identifier","token"); 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", "version": "5",
"dialect": "pg", "dialect": "pg",
"id": "ea430ef9-8e30-4cb6-9985-d03f43656cf8", "id": "c6cb6121-2dc1-49be-8bd9-62f1c0c55939",
"prevId": "00000000-0000-0000-0000-000000000000", "prevId": "00000000-0000-0000-0000-000000000000",
"tables": { "tables": {
"accounts": { "accounts": {
@ -105,21 +105,21 @@
"name": "sessions", "name": "sessions",
"schema": "", "schema": "",
"columns": { "columns": {
"sessionToken": {
"name": "sessionToken",
"type": "text",
"primaryKey": true,
"notNull": true
},
"userId": { "userId": {
"name": "userId", "name": "userId",
"type": "text", "type": "text",
"primaryKey": false, "primaryKey": false,
"notNull": true "notNull": true
}, },
"sessionToken": {
"name": "sessionToken",
"type": "text",
"primaryKey": true,
"notNull": true
},
"expires": { "expires": {
"name": "expires", "name": "expires",
"type": "timestamp", "type": "integer",
"primaryKey": false, "primaryKey": false,
"notNull": true "notNull": true
} }
@ -166,7 +166,7 @@
}, },
"emailVerified": { "emailVerified": {
"name": "emailVerified", "name": "emailVerified",
"type": "timestamp", "type": "integer",
"primaryKey": false, "primaryKey": false,
"notNull": false "notNull": false
}, },
@ -199,7 +199,7 @@
}, },
"expires": { "expires": {
"name": "expires", "name": "expires",
"type": "timestamp", "type": "integer",
"primaryKey": false, "primaryKey": false,
"notNull": true "notNull": true
} }

View file

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

View file

@ -5,15 +5,15 @@
{ {
"idx": 0, "idx": 0,
"version": "5", "version": "5",
"when": 1684771069602, "when": 1685716228240,
"tag": "0000_flawless_moondragon", "tag": "0000_clammy_freak",
"breakpoints": false "breakpoints": false
}, },
{ {
"idx": 1, "idx": 1,
"version": "5", "version": "5",
"when": 1684771628481, "when": 1685716937211,
"tag": "0001_colorful_spectrum", "tag": "0001_petite_sue_storm",
"breakpoints": false "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 { 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( // const connection = createPool({ connectionString: process.env.POSTGRES_URL });
"users",
{ export const users = pgTable("users", {
id: text("id").notNull().primaryKey(), id: text("id").notNull().primaryKey(),
name: text("name"), name: text("name"),
email: text("email").notNull(), email: text("email").notNull(),
emailVerified: timestamp("emailVerified", { mode: "date" }), emailVerified: integer("emailVerified"),
image: text("image"), image: text("image"),
}, });
(user) => ({
emailKey: uniqueIndex("User_email_key").on(user.email), export const usersRelations = relations(users, ({ many }) => ({
}) chats: many(chats),
); accounts: many(accounts),
}));
export const accounts = pgTable( export const accounts = pgTable(
"accounts", "accounts",
@ -41,313 +36,63 @@ export const accounts = pgTable(
id_token: text("id_token"), id_token: text("id_token"),
session_state: text("session_state"), session_state: text("session_state"),
}, },
(table) => { (account) => ({
return { _: primaryKey(account.provider, account.providerAccountId),
providerProviderAccountIdKey: uniqueIndex( })
"Account_provider_providerAccountId_key"
).on(table.provider, table.providerAccountId),
};
}
); );
export const sessions = pgTable( export const sessions = pgTable("sessions", {
"sessions", userId: text("userId")
{ .notNull()
sessionToken: text("sessionToken").notNull().primaryKey(), .references(() => users.id, { onDelete: "cascade" }),
userId: text("userId") sessionToken: text("sessionToken").notNull().primaryKey(),
.notNull() expires: integer("expires").notNull(),
.references(() => users.id, { onDelete: "cascade" }), });
expires: timestamp("expires", { mode: "date" }).notNull(),
},
(table) => {
return {
sessionTokenKey: uniqueIndex("Session_sessionToken_key").on(
table.sessionToken
),
};
}
);
export const verificationTokens = pgTable( export const verificationTokens = pgTable(
"verificationToken", "verificationToken",
{ {
identifier: text("identifier").notNull(), identifier: text("identifier").notNull(),
token: text("token").notNull(), token: text("token").notNull(),
expires: timestamp("expires", { mode: "date" }).notNull(), expires: integer("expires").notNull(),
}, },
(table) => ({ (vt) => ({
identifierTokenKey: uniqueIndex( _: primaryKey(vt.identifier, vt.token),
"VerificationToken_identifier_token_key"
).on(table.identifier, table.token),
tokenKey: uniqueIndex("VerificationToken_token_key").on(table.token),
}) })
); );
// Connect to Vercel Postgres
export const db = drizzle(sql);
export type DbClient = typeof db;
export type Schema = { export type Schema = {
users: typeof users; users: typeof users;
accounts: typeof accounts; accounts: typeof accounts;
sessions: typeof sessions; sessions: typeof sessions;
verificationTokens: typeof verificationTokens; 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( export const chatsRelations = relations(chats, ({ one }) => ({
// "users", user: one(users, {
// { fields: [chats.userId],
// id: uuid("id") references: [users.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 verificationTokens = pgTable( export const db = drizzle(sql, {
// "verification_tokens", schema: {
// { users,
// identifier: text("identifier").notNull(), accounts,
// token: text("token").notNull(), sessions,
// expires: timestamp("expires", { precision: 3 }).notNull(), verificationTokens,
// }, chats,
// (table) => { chatsRelations,
// return { usersRelations,
// identifierTokenKey: uniqueIndex( },
// "VerificationToken_identifier_token_key" });
// ).on(table.identifier, table.token),
// tokenKey: uniqueIndex("VerificationToken_token_key").on(table.token),
// };
// }
// );
// export const sessions = pgTable( export type DbClient = typeof db;
// "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;
// },
// };
// }

View file

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