Gardening (#540)

This commit is contained in:
Jared Palmer 2024-11-15 11:12:05 -05:00 committed by GitHub
commit f23c73f6a5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
65 changed files with 457 additions and 325 deletions

View file

@ -6,29 +6,10 @@
"prettier",
"plugin:tailwindcss/recommended"
],
"plugins": ["import", "tailwindcss"],
"plugins": ["tailwindcss"],
"rules": {
"tailwindcss/no-custom-classname": "off",
"tailwindcss/classnames-order": "off",
"import/order": [
"error",
{
"groups": [
"builtin",
"external",
"internal",
["parent", "sibling"],
"index",
"object",
"type"
],
"newlines-between": "always",
"alphabetize": {
"order": "asc",
"caseInsensitive": true
}
}
]
"tailwindcss/classnames-order": "off"
},
"settings": {
"import/resolver": {

View file

@ -2,7 +2,7 @@
import { z } from 'zod';
import { createUser, getUser } from '@/db/queries';
import { createUser, getUser } from '@/lib/db/queries';
import { signIn } from './auth';
@ -61,7 +61,7 @@ export const register = async (
password: formData.get('password'),
});
let [user] = await getUser(validatedData.email);
const [user] = await getUser(validatedData.email);
if (user) {
return { status: 'user_exists' } as RegisterActionState;

View file

@ -1,4 +1,4 @@
import { NextAuthConfig } from 'next-auth';
import type { NextAuthConfig } from 'next-auth';
export const authConfig = {
pages: {
@ -11,10 +11,10 @@ export const authConfig = {
],
callbacks: {
authorized({ auth, request: { nextUrl } }) {
let isLoggedIn = !!auth?.user;
let isOnChat = nextUrl.pathname.startsWith('/');
let isOnRegister = nextUrl.pathname.startsWith('/register');
let isOnLogin = nextUrl.pathname.startsWith('/login');
const isLoggedIn = !!auth?.user;
const isOnChat = nextUrl.pathname.startsWith('/');
const isOnRegister = nextUrl.pathname.startsWith('/register');
const isOnLogin = nextUrl.pathname.startsWith('/login');
if (isLoggedIn && (isOnLogin || isOnRegister)) {
return Response.redirect(new URL('/', nextUrl as unknown as URL));

View file

@ -2,7 +2,7 @@ import { compare } from 'bcrypt-ts';
import NextAuth, { User, Session } from 'next-auth';
import Credentials from 'next-auth/providers/credentials';
import { getUser } from '@/db/queries';
import { getUser } from '@/lib/db/queries';
import { authConfig } from './auth.config';

View file

@ -5,8 +5,8 @@ import { useRouter } from 'next/navigation';
import { useActionState, useEffect, useState } from 'react';
import { toast } from 'sonner';
import { AuthForm } from '@/components/custom/auth-form';
import { SubmitButton } from '@/components/custom/submit-button';
import { AuthForm } from '@/components/auth-form';
import { SubmitButton } from '@/components/submit-button';
import { login, LoginActionState } from '../actions';

View file

@ -5,10 +5,10 @@ import { useRouter } from 'next/navigation';
import { useActionState, useEffect, useState } from 'react';
import { toast } from 'sonner';
import { AuthForm } from '@/components/custom/auth-form';
import { SubmitButton } from '@/components/custom/submit-button';
import { AuthForm } from '@/components/auth-form';
import { SubmitButton } from '@/components/submit-button';
import { register, RegisterActionState } from '../actions';
import { register, type RegisterActionState } from '../actions';
export default function Page() {
const router = useRouter();

View file

@ -16,7 +16,7 @@ export async function generateTitleFromUserMessage({
message: CoreUserMessage;
}) {
const { text: title } = await generateText({
model: customModel('gpt-3.5-turbo'),
model: customModel('gpt-4o-mini'),
system: `\n
- you will generate a short title based on the first message a user begins a conversation with
- ensure it is not more than 80 characters long

View file

@ -19,8 +19,8 @@ import {
saveDocument,
saveMessages,
saveSuggestions,
} from '@/db/queries';
import { Suggestion } from '@/db/schema';
} from '@/lib/db/queries';
import { Suggestion } from '@/lib/db/schema';
import {
generateUUID,
getMostRecentUserMessage,

View file

@ -3,7 +3,7 @@ import {
deleteDocumentsByIdAfterTimestamp,
getDocumentsById,
saveDocument,
} from '@/db/queries';
} from '@/lib/db/queries';
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);

View file

@ -1,5 +1,5 @@
import { auth } from '@/app/(auth)/auth';
import { getChatsByUserId } from '@/db/queries';
import { getChatsByUserId } from '@/lib/db/queries';
export async function GET() {
const session = await auth();

View file

@ -1,5 +1,5 @@
import { auth } from '@/app/(auth)/auth';
import { getSuggestionsByDocumentId } from '@/db/queries';
import { getSuggestionsByDocumentId } from '@/lib/db/queries';
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);

View file

@ -1,5 +1,5 @@
import { auth } from '@/app/(auth)/auth';
import { getVotesByChatId, voteMessage } from '@/db/queries';
import { getVotesByChatId, voteMessage } from '@/lib/db/queries';
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);

View file

@ -4,8 +4,8 @@ import { notFound } from 'next/navigation';
import { DEFAULT_MODEL_NAME, models } from '@/ai/models';
import { auth } from '@/app/(auth)/auth';
import { Chat as PreviewChat } from '@/components/custom/chat';
import { getChatById, getMessagesByChatId } from '@/db/queries';
import { Chat as PreviewChat } from '@/components/chat';
import { getChatById, getMessagesByChatId } from '@/lib/db/queries';
import { convertToUIMessages } from '@/lib/utils';
export default async function Page(props: { params: Promise<any> }) {

View file

@ -1,6 +1,6 @@
import { cookies } from 'next/headers';
import { AppSidebar } from '@/components/custom/app-sidebar';
import { AppSidebar } from '@/components/app-sidebar';
import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar';
import { auth } from '../(auth)/auth';

View file

@ -1,7 +1,7 @@
import { cookies } from 'next/headers';
import { DEFAULT_MODEL_NAME, models } from '@/ai/models';
import { Chat } from '@/components/custom/chat';
import { Chat } from '@/components/chat';
import { generateUUID } from '@/lib/utils';
export default async function Page() {

View file

@ -104,17 +104,17 @@
}
@font-face {
font-family: 'geist';
font-family: "geist";
font-style: normal;
font-weight: 100 900;
src: url(/fonts/geist.woff2) format('woff2');
src: url(/fonts/geist.woff2) format("woff2");
}
@font-face {
font-family: 'geist-mono';
font-family: "geist-mono";
font-style: normal;
font-weight: 100 900;
src: url(/fonts/geist-mono.woff2) format('woff2');
src: url(/fonts/geist-mono.woff2) format("woff2");
}
}
@ -123,7 +123,7 @@
pointer-events: none !important;
}
*[class^='text-'] {
*[class^="text-"] {
color: transparent;
@apply rounded-md bg-foreground/20 select-none animate-pulse;
}

View file

@ -1,7 +1,7 @@
import { Metadata } from 'next';
import { Toaster } from 'sonner';
import { ThemeProvider } from '@/components/custom/theme-provider';
import { ThemeProvider } from '@/components/theme-provider';
import './globals.css';

58
biome.json Normal file
View file

@ -0,0 +1,58 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"vcs": { "enabled": false, "clientKind": "git", "useIgnoreFile": true },
"files": {
"ignoreUnknown": false,
"ignore": [
"**/pnpm-lock.yaml",
"lib/db/migrations",
"lib/editor/react-renderer.tsx",
"node_modules",
".next",
"public",
".vercel"
]
},
"formatter": {
"enabled": true,
"useEditorconfig": true,
"formatWithErrors": false,
"indentStyle": "space",
"indentWidth": 2,
"lineEnding": "lf",
"lineWidth": 80,
"attributePosition": "auto",
"bracketSpacing": true,
"ignore": ["**/pnpm-lock.yaml", "lib/db/drizzle"]
},
"organizeImports": { "enabled": true },
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"a11y": {
"noSvgWithoutTitle": "off",
"useKeyWithClickEvents": "off"
},
"style": {
"noNonNullAssertion": "off"
},
"correctness": {
"useExhaustiveDependencies": "off"
}
}
},
"javascript": {
"formatter": {
"jsxQuoteStyle": "double",
"quoteProperties": "asNeeded",
"trailingCommas": "es5",
"semicolons": "always",
"arrowParentheses": "always",
"bracketSameLine": false,
"quoteStyle": "single",
"attributePosition": "auto",
"bracketSpacing": true
}
}
}

View file

@ -4,9 +4,9 @@ import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { type User } from 'next-auth';
import { PlusIcon } from '@/components/custom/icons';
import { SidebarHistory } from '@/components/custom/sidebar-history';
import { SidebarUserNav } from '@/components/custom/sidebar-user-nav';
import { PlusIcon } from '@/components/icons';
import { SidebarHistory } from '@/components/sidebar-history';
import { SidebarUserNav } from '@/components/sidebar-user-nav';
import { Button } from '@/components/ui/button';
import {
Sidebar,

View file

@ -1,7 +1,7 @@
import Form from 'next/form';
import { Input } from '../ui/input';
import { Label } from '../ui/label';
import { Input } from './ui/input';
import { Label } from './ui/label';
export function AuthForm({
action,

View file

@ -17,7 +17,7 @@ import {
useWindowSize,
} from 'usehooks-ts';
import { Document, Suggestion, Vote } from '@/db/schema';
import { Document, Suggestion, Vote } from '@/lib/db/schema';
import { fetcher } from '@/lib/utils';
import { DiffView } from './diffview';
@ -27,10 +27,10 @@ import { CopyIcon, CrossIcon, DeltaIcon, RedoIcon, UndoIcon } from './icons';
import { PreviewMessage } from './message';
import { MultimodalInput } from './multimodal-input';
import { Toolbar } from './toolbar';
import { Button } from './ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip';
import { useScrollToBottom } from './use-scroll-to-bottom';
import { VersionFooter } from './version-footer';
import { Button } from '../ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';
export interface UIBlock {
title: string;
documentId: string;

View file

@ -4,13 +4,13 @@ import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useWindowSize } from 'usehooks-ts';
import { ModelSelector } from '@/components/custom/model-selector';
import { SidebarToggle } from '@/components/custom/sidebar-toggle';
import { ModelSelector } from '@/components/model-selector';
import { SidebarToggle } from '@/components/sidebar-toggle';
import { Button } from '@/components/ui/button';
import { BetterTooltip } from '@/components/ui/tooltip';
import { PlusIcon, VercelIcon } from './icons';
import { useSidebar } from '../ui/sidebar';
import { useSidebar } from './ui/sidebar';
export function ChatHeader({ selectedModelId }: { selectedModelId: string }) {
const router = useRouter();

View file

@ -7,10 +7,10 @@ import { useState } from 'react';
import useSWR, { useSWRConfig } from 'swr';
import { useWindowSize } from 'usehooks-ts';
import { ChatHeader } from '@/components/custom/chat-header';
import { PreviewMessage, ThinkingMessage } from '@/components/custom/message';
import { useScrollToBottom } from '@/components/custom/use-scroll-to-bottom';
import { Vote } from '@/db/schema';
import { ChatHeader } from '@/components/chat-header';
import { PreviewMessage, ThinkingMessage } from '@/components/message';
import { useScrollToBottom } from '@/components/use-scroll-to-bottom';
import { Vote } from '@/lib/db/schema';
import { fetcher } from '@/lib/utils';
import { Block, UIBlock } from './block';

View file

@ -6,7 +6,7 @@ import { EditorState } from 'prosemirror-state';
import { EditorView } from 'prosemirror-view';
import React, { memo, useEffect, useRef } from 'react';
import { Suggestion } from '@/db/schema';
import { Suggestion } from '@/lib/db/schema';
import {
documentSchema,
handleTransaction,

View file

@ -3,17 +3,17 @@ import { toast } from 'sonner';
import { useSWRConfig } from 'swr';
import { useCopyToClipboard } from 'usehooks-ts';
import { Vote } from '@/db/schema';
import { Vote } from '@/lib/db/schema';
import { getMessageIdFromAnnotations } from '@/lib/utils';
import { CopyIcon, ThumbDownIcon, ThumbUpIcon } from './icons';
import { Button } from '../ui/button';
import { Button } from './ui/button';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '../ui/tooltip';
} from './ui/tooltip';
export function MessageActions({
chatId,

View file

@ -5,7 +5,7 @@ import cx from 'classnames';
import { motion } from 'framer-motion';
import { Dispatch, SetStateAction } from 'react';
import { Vote } from '@/db/schema';
import { Vote } from '@/lib/db/schema';
import { UIBlock } from './block';
import { DocumentToolCall, DocumentToolResult } from './document';

View file

@ -19,8 +19,8 @@ import { sanitizeUIMessages } from '@/lib/utils';
import { ArrowUpIcon, PaperclipIcon, StopIcon } from './icons';
import { PreviewAttachment } from './preview-attachment';
import { Button } from '../ui/button';
import { Textarea } from '../ui/textarea';
import { Button } from './ui/button';
import { Textarea } from './ui/textarea';
const suggestedActions = [
{

View file

@ -8,7 +8,7 @@ import { useEffect, useState } from 'react';
import { toast } from 'sonner';
import useSWR from 'swr';
import { MoreHorizontalIcon, TrashIcon } from '@/components/custom/icons';
import { MoreHorizontalIcon, TrashIcon } from '@/components/icons';
import {
AlertDialog,
AlertDialogAction,
@ -34,7 +34,7 @@ import {
SidebarMenuItem,
useSidebar,
} from '@/components/ui/sidebar';
import { Chat } from '@/db/schema';
import { Chat } from '@/lib/db/schema';
import { fetcher } from '@/lib/utils';
type GroupedChats = {

View file

@ -5,7 +5,7 @@ import { BetterTooltip } from '@/components/ui/tooltip';
import { cn } from '@/lib/utils';
import { SidebarLeftIcon } from './icons';
import { Button } from '../ui/button';
import { Button } from './ui/button';
export function SidebarToggle({
className,

View file

@ -2,9 +2,9 @@
import { useFormStatus } from 'react-dom';
import { LoaderIcon } from '@/components/custom/icons';
import { LoaderIcon } from '@/components/icons';
import { Button } from '../ui/button';
import { Button } from './ui/button';
export function SubmitButton({
children,

View file

@ -7,7 +7,7 @@ import { useWindowSize } from 'usehooks-ts';
import { UISuggestion } from '@/lib/editor/suggestions';
import { CrossIcon, MessageIcon } from './icons';
import { Button } from '../ui/button';
import { Button } from './ui/button';
export const Suggestion = ({
suggestion,

View file

@ -26,7 +26,7 @@ import {
StopIcon,
SummarizeIcon,
} from './icons';
import { Button } from '../ui/button';
import { Button } from './ui/button';
type ToolProps = {
type: 'final-polish' | 'request-suggestions' | 'adjust-reading-level';

View file

@ -2,7 +2,7 @@ import { JSONValue } from 'ai';
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
import { useSWRConfig } from 'swr';
import { Suggestion } from '@/db/schema';
import { Suggestion } from '@/lib/db/schema';
import { UIBlock } from './block';

View file

@ -6,12 +6,12 @@ import { useState } from 'react';
import { useSWRConfig } from 'swr';
import { useWindowSize } from 'usehooks-ts';
import { Document } from '@/db/schema';
import { Document } from '@/lib/db/schema';
import { getDocumentTimestampByIndex } from '@/lib/utils';
import { UIBlock } from './block';
import { LoaderIcon } from './icons';
import { Button } from '../ui/button';
import { Button } from './ui/button';
interface VersionFooterProps {
block: UIBlock;

View file

@ -6,8 +6,8 @@ config({
});
export default defineConfig({
schema: './db/schema.ts',
out: './lib/drizzle',
schema: './lib/db/schema.ts',
out: './lib/db/migrations',
dialect: 'postgresql',
dbCredentials: {
url: process.env.POSTGRES_URL!,

View file

@ -5,7 +5,7 @@ import { DOMParser, Node } from 'prosemirror-model';
import { Decoration, DecorationSet, EditorView } from 'prosemirror-view';
import { renderToString } from 'react-dom/server';
import { Markdown } from '@/components/custom/markdown';
import { Markdown } from '@/components/markdown';
import { documentSchema } from './config';
import { createSuggestionWidget, UISuggestion } from './suggestions';

View file

@ -3,8 +3,8 @@ import { PluginKey, Plugin } from 'prosemirror-state';
import { Decoration, DecorationSet, EditorView } from 'prosemirror-view';
import { createRoot } from 'react-dom/client';
import { Suggestion as PreviewSuggestion } from '@/components/custom/suggestion';
import { Suggestion } from '@/db/schema';
import { Suggestion as PreviewSuggestion } from '@/components/suggestion';
import { Suggestion } from '@/lib/db/schema';
export interface UISuggestion extends Suggestion {
selectionStart: number;

View file

@ -8,7 +8,7 @@ import {
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
import { Message as DBMessage, Document } from '@/db/schema';
import { Message as DBMessage, Document } from '@/lib/db/schema';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));

View file

@ -4,10 +4,14 @@
"private": true,
"scripts": {
"dev": "next dev --turbo",
"build": "tsx db/migrate && next build",
"build": "next build",
"start": "next start",
"lint": "next lint",
"format": "prettier --write ."
"lint:fix": "next lint --fix",
"format": "biome format --write",
"db:generate": "drizzle-kit generate",
"db:migrate": "npx tsx lib/db/migrate.ts",
"db:studio": "drizzle-kit studio"
},
"dependencies": {
"@ai-sdk/openai": "1.0.0-canary.3",
@ -62,9 +66,10 @@
"zod": "^3.23.8"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@tailwindcss/typography": "^0.5.15",
"@types/d3-scale": "^4.0.8",
"@types/node": "^20",
"@types/node": "^22.8.6",
"@types/pdf-parse": "^1.1.4",
"@types/react": "^18",
"@types/react-dom": "^18",
@ -73,10 +78,8 @@
"eslint-config-next": "14.2.5",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.3",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-tailwindcss": "^3.17.5",
"postcss": "^8",
"prettier": "^3.3.3",
"tailwindcss": "^3.4.1",
"tsx": "^4.19.1",
"typescript": "^5"

543
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,9 +0,0 @@
/** @type {import('prettier').Config} */
module.exports = {
endOfLine: 'lf',
semi: true,
useTabs: false,
singleQuote: true,
tabWidth: 2,
trailingComma: 'es5',
};