Skip to content

Commit

Permalink
feat: next 15 (#2000)
Browse files Browse the repository at this point in the history
Co-authored-by: Julius Marminge <[email protected]>
  • Loading branch information
ronanru and juliusmarminge authored Oct 26, 2024
1 parent 42d468e commit 41de302
Show file tree
Hide file tree
Showing 69 changed files with 239 additions and 546 deletions.
5 changes: 5 additions & 0 deletions .changeset/grumpy-otters-kneel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"create-t3-app": minor
---

update to next.js 15 and next-auth v5
12 changes: 6 additions & 6 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ jobs:
- run: cd ../ci-${{ matrix.trpc }}-${{ matrix.tailwind }}-${{ matrix.nextAuth }}-${{ matrix.prisma }}-${{ matrix.drizzle}}-${{ matrix.appRouter }}-${{ matrix.dbType }} && pnpm build
if: ${{ steps.matrix-valid.outputs.continue == 'true' }}
env:
NEXTAUTH_SECRET: foo
DISCORD_CLIENT_ID: bar
DISCORD_CLIENT_SECRET: baz
AUTH_SECRET: foo
AUTH_DISCORD_ID: bar
AUTH_DISCORD_SECRET: baz
SKIP_ENV_VALIDATION: true

build-t3-app-with-bun:
Expand Down Expand Up @@ -101,7 +101,7 @@ jobs:
- run: cd ../ci-bun && bun run build
# - run: cd ../ci-bun && bun --bun run build
env:
NEXTAUTH_SECRET: foo
AUTH_SECRET: foo
AUTH_DISCORD_ID: bar
AUTH_DISCORD_SECRET: baz
DATABASE_URL: mysql://root:root@localhost:3306/test # can't use url from example env cause we block that in t3-env
DISCORD_CLIENT_ID: bar
DISCORD_CLIENT_SECRET: baz
6 changes: 6 additions & 0 deletions cli/src/helpers/logNextSteps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ export const logNextSteps = async ({
}
}

if (packages?.nextAuth.inUse) {
logger.info(
` Fill in your .env with necessary values. See https://create.t3.gg/en/usage/first-steps for more info.`
);
}

if (["npm", "bun"].includes(pkgManager)) {
logger.info(` ${pkgManager} run dev`);
} else {
Expand Down
6 changes: 3 additions & 3 deletions cli/src/installers/dependencyVersionMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
*/
export const dependencyVersionMap = {
// NextAuth.js
"next-auth": "^4.24.7",
"@auth/prisma-adapter": "^1.6.0",
"@auth/drizzle-adapter": "^1.1.0",
"next-auth": "5.0.0-beta.25",
"@auth/prisma-adapter": "^2.7.2",
"@auth/drizzle-adapter": "^1.7.2",

// Prisma
prisma: "^5.14.0",
Expand Down
42 changes: 26 additions & 16 deletions cli/src/installers/envVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,19 @@ export const envVariablesInstaller: Installer = ({
const envDest = path.join(projectDir, ".env");
const envExampleDest = path.join(projectDir, ".env.example");

fs.writeFileSync(envDest, envContent, "utf-8");
fs.writeFileSync(envExampleDest, exampleEnvContent + envContent, "utf-8");
const _exampleEnvContent = exampleEnvContent + envContent;

// Generate an auth secret and put in .env, not .env.example
const secret = Buffer.from(
crypto.getRandomValues(new Uint8Array(32))
).toString("base64");
const _envContent = envContent.replace(
'AUTH_SECRET=""',
`AUTH_SECRET="${secret}" # Generated by create-t3-app.`
);

fs.writeFileSync(envDest, _envContent, "utf-8");
fs.writeFileSync(envExampleDest, _exampleEnvContent, "utf-8");
};

const getEnvContent = (
Expand All @@ -69,6 +80,19 @@ const getEnvContent = (
.trim()
.concat("\n");

if (usingAuth)
content += `
# Next Auth
# You can generate a new secret on the command line with:
# npx auth secret
# https://next-auth.js.org/configuration/options#secret
AUTH_SECRET=""
# Next Auth Discord Provider
AUTH_DISCORD_ID=""
AUTH_DISCORD_SECRET=""
`;

if (usingPrisma)
content += `
# Prisma
Expand Down Expand Up @@ -97,20 +121,6 @@ DATABASE_URL='mysql://YOUR_MYSQL_URL_HERE?sslaccept=strict'`;
content += "\n";
}

if (usingAuth)
content += `
# Next Auth
# You can generate a new secret on the command line with:
# openssl rand -base64 32
# https://next-auth.js.org/configuration/options#secret
# NEXTAUTH_SECRET=""
NEXTAUTH_URL="http://localhost:3000"
# Next Auth Discord Provider
DISCORD_CLIENT_ID=""
DISCORD_CLIENT_SECRET=""
`;

if (!usingAuth && !usingPrisma)
content += `
# Example:
Expand Down
23 changes: 10 additions & 13 deletions cli/src/installers/nextAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ import { type AvailableDependencies } from "~/installers/dependencyVersionMap.js
import { type Installer } from "~/installers/index.js";
import { addPackageDependency } from "~/utils/addPackageDependency.js";

export const nextAuthInstaller: Installer = ({
projectDir,
packages,
appRouter,
}) => {
export const nextAuthInstaller: Installer = ({ projectDir, packages }) => {
const usingPrisma = packages?.prisma.inUse;
const usingDrizzle = packages?.drizzle.inUse;

Expand All @@ -26,25 +22,26 @@ export const nextAuthInstaller: Installer = ({

const extrasDir = path.join(PKG_ROOT, "template/extras");

const apiHandlerFile = "src/pages/api/auth/[...nextauth].ts";
const routeHandlerFile = "src/app/api/auth/[...nextauth]/route.ts";
const srcToUse = appRouter ? routeHandlerFile : apiHandlerFile;
const apiHandlerFile = "src/app/api/auth/[...nextauth]/route.ts";

const apiHandlerSrc = path.join(extrasDir, srcToUse);
const apiHandlerDest = path.join(projectDir, srcToUse);
const apiHandlerSrc = path.join(extrasDir, apiHandlerFile);
const apiHandlerDest = path.join(projectDir, apiHandlerFile);

const authConfigSrc = path.join(
extrasDir,
"src/server",
appRouter ? "auth-app" : "auth-pages",
"src/server/auth/config",
usingPrisma
? "with-prisma.ts"
: usingDrizzle
? "with-drizzle.ts"
: "base.ts"
);
const authConfigDest = path.join(projectDir, "src/server/auth.ts");
const authConfigDest = path.join(projectDir, "src/server/auth/config.ts");

const authIndexSrc = path.join(extrasDir, "src/server/auth/index.ts");
const authIndexDest = path.join(projectDir, "src/server/auth/index.ts");

fs.copySync(apiHandlerSrc, apiHandlerDest);
fs.copySync(authConfigSrc, authConfigDest);
fs.copySync(authIndexSrc, authIndexDest);
};
4 changes: 2 additions & 2 deletions cli/src/installers/tailwind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export const tailwindInstaller: Installer = ({ projectDir }) => {
const twCfgSrc = path.join(extrasDir, "config/tailwind.config.ts");
const twCfgDest = path.join(projectDir, "tailwind.config.ts");

const postcssCfgSrc = path.join(extrasDir, "config/postcss.config.cjs");
const postcssCfgDest = path.join(projectDir, "postcss.config.cjs");
const postcssCfgSrc = path.join(extrasDir, "config/postcss.config.js");
const postcssCfgDest = path.join(projectDir, "postcss.config.js");

const prettierSrc = path.join(extrasDir, "config/_prettier.config.js");
const prettierDest = path.join(projectDir, "prettier.config.js");
Expand Down
2 changes: 1 addition & 1 deletion cli/template/base/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
* for Docker builds.
*/
await import("./src/env.js");
import "./src/env.js";

/** @type {import("next").NextConfig} */
const config = {
Expand Down
6 changes: 3 additions & 3 deletions cli/template/base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "module",
"private": true,
"scripts": {
"dev": "next dev",
"dev": "next dev --turbo",
"build": "next build",
"start": "next start",
"lint": "next lint",
Expand All @@ -16,7 +16,7 @@
"dependencies": {
"@t3-oss/env-nextjs": "^0.10.1",
"geist": "^1.3.0",
"next": "^14.2.4",
"next": "^15.0.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"zod": "^3.23.3"
Expand All @@ -29,7 +29,7 @@
"@typescript-eslint/eslint-plugin": "^8.1.0",
"@typescript-eslint/parser": "^8.1.0",
"eslint": "^8.57.0",
"eslint-config-next": "^14.2.4",
"eslint-config-next": "^15.0.1",
"typescript": "^5.5.3"
}
}
4 changes: 1 addition & 3 deletions cli/template/extras/config/_prettier.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */
const config = {
export default {
plugins: ["prettier-plugin-tailwindcss"],
};

export default config;
2 changes: 1 addition & 1 deletion cli/template/extras/config/next-config-appdir.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
* for Docker builds.
*/
await import("./src/env.js");
import "./src/env.js";

/** @type {import("next").NextConfig} */
const config = {};
Expand Down
7 changes: 0 additions & 7 deletions cli/template/extras/config/postcss.config.cjs

This file was deleted.

5 changes: 5 additions & 0 deletions cli/template/extras/config/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default {
plugins: {
tailwindcss: {},
},
};
8 changes: 2 additions & 6 deletions cli/template/extras/src/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import NextAuth from "next-auth";
import { handlers } from "~/server/auth";

import { authOptions } from "~/server/auth";

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
export const { GET, POST } = handlers;
4 changes: 2 additions & 2 deletions cli/template/extras/src/app/page/with-auth-trpc-tw.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import Link from "next/link";

import { LatestPost } from "~/app/_components/post";
import { getServerAuthSession } from "~/server/auth";
import { auth } from "~/server/auth";
import { api, HydrateClient } from "~/trpc/server";

export default async function Home() {
const hello = await api.post.hello({ text: "from tRPC" });
const session = await getServerAuthSession();
const session = await auth();

if (session?.user) {
void api.post.getLatest.prefetch();
Expand Down
4 changes: 2 additions & 2 deletions cli/template/extras/src/app/page/with-auth-trpc.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import Link from "next/link";

import { LatestPost } from "~/app/_components/post";
import { getServerAuthSession } from "~/server/auth";
import { auth } from "~/server/auth";
import { api, HydrateClient } from "~/trpc/server";
import styles from "./index.module.css";

export default async function Home() {
const hello = await api.post.hello({ text: "from tRPC" });
const session = await getServerAuthSession();
const session = await auth();

if (session?.user) {
void api.post.getLatest.prefetch();
Expand Down
26 changes: 9 additions & 17 deletions cli/template/extras/src/env/with-auth-db-planetscale.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ export const env = createEnv({
* isn't built with invalid env vars.
*/
server: {
AUTH_SECRET:
process.env.NODE_ENV === "production"
? z.string()
: z.string().optional(),
AUTH_DISCORD_ID: z.string(),
AUTH_DISCORD_SECRET: z.string(),
DATABASE_URL: z
.string()
.url()
Expand All @@ -17,19 +23,6 @@ export const env = createEnv({
NODE_ENV: z
.enum(["development", "test", "production"])
.default("development"),
NEXTAUTH_SECRET:
process.env.NODE_ENV === "production"
? z.string()
: z.string().optional(),
NEXTAUTH_URL: z.preprocess(
// This makes Vercel deployments not fail if you don't set NEXTAUTH_URL
// Since NextAuth.js automatically uses the VERCEL_URL if present.
(str) => process.env.VERCEL_URL ?? str,
// VERCEL_URL doesn't include `https` so it cant be validated as a URL
process.env.VERCEL ? z.string() : z.string().url()
),
DISCORD_CLIENT_ID: z.string(),
DISCORD_CLIENT_SECRET: z.string(),
},

/**
Expand All @@ -46,12 +39,11 @@ export const env = createEnv({
* middlewares) or client-side so we need to destruct manually.
*/
runtimeEnv: {
AUTH_SECRET: process.env.AUTH_SECRET,
AUTH_DISCORD_ID: process.env.AUTH_DISCORD_ID,
AUTH_DISCORD_SECRET: process.env.AUTH_DISCORD_SECRET,
DATABASE_URL: process.env.DATABASE_URL,
NODE_ENV: process.env.NODE_ENV,
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
DISCORD_CLIENT_ID: process.env.DISCORD_CLIENT_ID,
DISCORD_CLIENT_SECRET: process.env.DISCORD_CLIENT_SECRET,
},
/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially
Expand Down
26 changes: 9 additions & 17 deletions cli/template/extras/src/env/with-auth-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,16 @@ export const env = createEnv({
* isn't built with invalid env vars.
*/
server: {
AUTH_SECRET:
process.env.NODE_ENV === "production"
? z.string()
: z.string().optional(),
AUTH_DISCORD_ID: z.string(),
AUTH_DISCORD_SECRET: z.string(),
DATABASE_URL: z.string().url(),
NODE_ENV: z
.enum(["development", "test", "production"])
.default("development"),
NEXTAUTH_SECRET:
process.env.NODE_ENV === "production"
? z.string()
: z.string().optional(),
NEXTAUTH_URL: z.preprocess(
// This makes Vercel deployments not fail if you don't set NEXTAUTH_URL
// Since NextAuth.js automatically uses the VERCEL_URL if present.
(str) => process.env.VERCEL_URL ?? str,
// VERCEL_URL doesn't include `https` so it cant be validated as a URL
process.env.VERCEL ? z.string() : z.string().url()
),
DISCORD_CLIENT_ID: z.string(),
DISCORD_CLIENT_SECRET: z.string(),
},

/**
Expand All @@ -40,12 +33,11 @@ export const env = createEnv({
* middlewares) or client-side so we need to destruct manually.
*/
runtimeEnv: {
AUTH_SECRET: process.env.AUTH_SECRET,
AUTH_DISCORD_ID: process.env.AUTH_DISCORD_ID,
AUTH_DISCORD_SECRET: process.env.AUTH_DISCORD_SECRET,
DATABASE_URL: process.env.DATABASE_URL,
NODE_ENV: process.env.NODE_ENV,
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
DISCORD_CLIENT_ID: process.env.DISCORD_CLIENT_ID,
DISCORD_CLIENT_SECRET: process.env.DISCORD_CLIENT_SECRET,
},
/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially
Expand Down
Loading

0 comments on commit 41de302

Please sign in to comment.