feat: upgrade to next 15

This commit is contained in:
2024-12-19 23:12:51 +01:00
parent 00ea44fc2a
commit d421278224
11 changed files with 1022 additions and 395 deletions

View File

@@ -28,10 +28,10 @@
"ioredis": "^5.4.1",
"lucia": "^3.1.1",
"lucide-react": "^0.368.0",
"next": "^14.2.3",
"next": "^15.1.2",
"next-themes": "^0.4.4",
"react": "^18",
"react-dom": "^18",
"react": "^19.0.0-rc.1",
"react-dom": "^19.0.0-rc.1",
"react-hook-form": "^7.54.1",
"sonner": "^1.4.41",
"tailwind-merge": "^2.2.2",
@@ -43,7 +43,7 @@
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "14.2.0",
"eslint-config-next": "^15.1.2",
"postcss": "^8",
"prisma": "^6.0.1",
"shadcn": "^2.1.7",

View File

@@ -9,7 +9,7 @@ export async function GET(request: Request): Promise<Response> {
const url = new URL(request.url);
const code = url.searchParams.get('code');
const state = url.searchParams.get('state');
const storedState = cookies().get('github_oauth_state')?.value ?? null;
const storedState = (await cookies()).get('github_oauth_state')?.value ?? null;
if (!code || !state || !storedState || state !== storedState) {
return new Response(null, {
status: 400,
@@ -33,7 +33,7 @@ export async function GET(request: Request): Promise<Response> {
if (existingUser) {
const session = await lucia.createSession(existingUser.id, {});
const sessionCookie = lucia.createSessionCookie(session.id);
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
return new Response(null, {
status: 302,
headers: {
@@ -54,7 +54,7 @@ export async function GET(request: Request): Promise<Response> {
const session = await lucia.createSession(userId, {});
const sessionCookie = lucia.createSessionCookie(session.id);
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
return new Response(null, {
status: 302,
headers: {

View File

@@ -6,7 +6,7 @@ export async function GET(): Promise<Response> {
const state = generateState();
const url = github.createAuthorizationURL(state, []);
cookies().set("github_oauth_state", state, {
(await cookies()).set("github_oauth_state", state, {
path: "/",
secure: process.env.NODE_ENV === "production",
httpOnly: true,

View File

@@ -11,8 +11,7 @@ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLab
import { logout } from "@/lib/auth/actions"
import { useSession } from "@/lib/providers/SessionProvider"
import Link from "next/link"
import { useState } from "react"
import { useFormState } from "react-dom"
import { useActionState } from "react"
import MobileNavbarLinks from "../MobileNavbarLinks/MobileNavbarLinks"
import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher"
@@ -35,7 +34,7 @@ function NavbarLinks() {
export default function Navbar() {
const { user } = useSession();
const [, logoutAction] = useFormState(logout, null)
const [, logoutAction] = useActionState(logout, null)
return (
<>
<nav className="flex items-center h-16 px-4 border-b gap-3 shrink-0">

View File

@@ -3,7 +3,6 @@
'use client';
import { zodResolver } from '@hookform/resolvers/zod';
import { Path, PathValue, useForm } from 'react-hook-form';
import { Button } from '@/components/ui/button';
import {
Form,
FormControl,
@@ -18,7 +17,7 @@ import { z } from 'zod';
import type { UniversalFormProps } from './types';
import { customDataSchema, projectSettingsSchema, ratelimitChangeSchema } from './zod';
import SubmitButton from '../SubmitButton/SubmitButton';
import { useFormState } from 'react-dom';
import { useActionState } from 'react';
import React from 'react';
import { toast } from 'sonner';
import { createSchema } from '@/lib/forms/zod';
@@ -39,7 +38,7 @@ export function UniversalForm<T extends z.ZodType>({
submitText = 'Submit',
submitClassname,
}: UniversalFormProps<T>) {
const [state, formAction] = useFormState(action, null);
const [state, formAction] = useActionState(action, null);
const schema = schemaDb.find((s) => s.name === schemaName)?.zod;
if (!schema) {

View File

@@ -8,6 +8,6 @@ export async function logout() {
const { session } = await validateRequest();
await lucia.invalidateSession(session!.id);
const sessionCookie = lucia.createBlankSessionCookie();
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
return redirect("/auth");
}

View File

@@ -32,7 +32,7 @@ export const lucia = new Lucia(adapter, {
},
});
export const validateRequest = cache(async () => {
const sessionId = cookies().get(lucia.sessionCookieName)?.value ?? null;
const sessionId = (await cookies()).get(lucia.sessionCookieName)?.value ?? null;
if (!sessionId)
return {
@@ -44,11 +44,11 @@ export const validateRequest = cache(async () => {
try {
if (session && session.fresh) {
const sessionCookie = lucia.createSessionCookie(session.id);
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
}
if (!session) {
const sessionCookie = lucia.createBlankSessionCookie();
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
}
} catch {
// Next.js throws error attempting to set cookies when rendering page

View File

@@ -1,11 +1,11 @@
export const bodyGen = (customData: string[]) => {
// thankfully ai came in clutch with the comma brainfuck here
const customFields = customData.map((data) => `"${data}": "${data}"`).join(',\n ');
return `{
"message": "Hello, world!",
${customData.map((data) => `"${data}": "${data}"`).join(',\n ')}
"message": "Hello, world!"${customData.length ? ',\n ' : ''}${customFields}
}`;
};
export const bodyGenNoIdent = (customData: string[]) => {
console.log(bodyGen(customData));
return JSON.stringify(JSON.parse(bodyGen(customData)));
}

View File

@@ -1,9 +1,13 @@
"use client"
'use client';
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes"
import * as React from 'react';
const NextThemesProvider = dynamic(() => import('next-themes').then((e) => e.ThemeProvider), {
ssr: false,
});
import { type ThemeProviderProps } from 'next-themes';
import dynamic from 'next/dynamic';
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}

View File

@@ -1,6 +1,10 @@
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
@@ -18,9 +22,19 @@
}
],
"paths": {
"@/*": ["./src/*"]
}
"@/*": [
"./src/*"
]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
"target": "ES2017"
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}

1337
yarn.lock

File diff suppressed because it is too large Load Diff