Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: upgrade t3 stack since 07-20-2024 #5

Merged
merged 1 commit into from
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
# If you are cloning this repo, create a copy of this file named `.env` and populate it with your secrets.

# The database URL is used to connect to your Supabase database.
POSTGRES_URL="postgres://postgres.[USERNAME]:[PASSWORD]@aws-0-eu-central-1.pooler.supabase.com:6543/postgres?workaround=supabase-pooler.vercel"

DATABASE_URL='mongodb+srv://<username>:<password>@<cluster>/<database>?retryWrites=true&w=majority'

# You can generate the secret via 'openssl rand -base64 32' on Unix
# @see https://next-auth.js.org/configuration/options#secret
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@

## Installation

There are two ways of initializing an app using the `create-t3-turbo` starter. You can either use this repository as a template:
There are two ways of initializing an app using the `create-t3-turbo-with-prisma` starter. You can either use this repository as a template:

![use-as-template](https://github.com/t3-oss/create-t3-turbo/assets/51714798/bb6c2e5d-d8b6-416e-aeb3-b3e50e2ca994)

or use Turbo's CLI to init your project (use PNPM as package manager):

```bash
npx create-turbo@latest -e https://github.com/t3-oss/create-t3-turbo
npx create-turbo@latest -e https://github.com/Security2431/create-t3-turbo-with-prisma
```

## About
Expand Down Expand Up @@ -57,7 +57,7 @@ packages
├─ auth
| └─ Authentication using next-auth.
├─ db
| └─ Typesafe db calls using Drizzle & Supabase
| └─ Typesafe db calls using Prisma & MongoDB
└─ ui
└─ Start of a UI package for the webapp using shadcn-ui
tooling
Expand All @@ -76,7 +76,7 @@ tooling
## Quick Start

> **Note**
> The [db](./packages/db) package is preconfigured to use Supabase and is **edge-bound** with the [Vercel Postgres](https://github.com/vercel/storage/tree/main/packages/postgres) driver. If you're using something else, make the necessary modifications to the [schema](./packages/db/src/schema) as well as the [client](./packages/db/src/index.ts) and the [drizzle config](./packages/db/drizzle.config.ts). If you want to switch to non-edge database driver, remove `export const runtime = "edge";` [from all pages and api routes](https://github.com/t3-oss/create-t3-turbo/issues/634#issuecomment-1730240214).
> The [db](./packages/db) package is preconfigured to use [MongoDB](https://www.mongodb.com/) database. If you're using something else, update the schema.prisma provider in [prisma](./packages/db/prisma).

To get it running, follow the steps below:

Expand All @@ -90,7 +90,7 @@ pnpm i
# There is an `.env.example` in the root directory you can use for reference
cp .env.example .env

# Push the Drizzle schema to the database
# Push the Prisma schema to the database
pnpm db:push
```

Expand Down Expand Up @@ -200,7 +200,7 @@ Deploying your Expo application works slightly differently compared to Next.js o

1. Make sure to modify the `getBaseUrl` function to point to your backend's production URL:

<https://github.com/t3-oss/create-t3-turbo/blob/656965aff7db271e5e080242c4a3ce4dad5d25f8/apps/expo/src/utils/api.tsx#L20-L37>
<https://github.com/Security2431/create-t3-turbo-with-prisma/blob/main/apps/expo/src/utils/api.tsx#L20-L40>

2. Let's start by setting up [EAS Build](https://docs.expo.dev/build/introduction), which is short for Expo Application Services. The build service helps you create builds of your app, without requiring a full native development setup. The commands below are a summary of [Creating your first build](https://docs.expo.dev/build/setup).

Expand Down
2 changes: 1 addition & 1 deletion apps/nextjs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ If you are not familiar with the different technologies used in this project, pl

- [Next.js](https://nextjs.org)
- [NextAuth.js](https://next-auth.js.org)
- [Drizzle](https://orm.drizzle.team)
- [Prisma](https://prisma.io)
- [Tailwind CSS](https://tailwindcss.com)
- [tRPC](https://trpc.io)

Expand Down
2 changes: 1 addition & 1 deletion apps/nextjs/src/app/_components/posts.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use client";

import type { RouterOutputs } from "@acme/api";
import { CreatePostSchema } from "@acme/db/schema";
import { cn } from "@acme/ui";
import { Button } from "@acme/ui/button";
import {
Expand All @@ -14,6 +13,7 @@ import {
} from "@acme/ui/form";
import { Input } from "@acme/ui/input";
import { toast } from "@acme/ui/toast";
import { CreatePostSchema } from "@acme/validators";

import { api } from "~/trpc/react";

Expand Down
2 changes: 1 addition & 1 deletion apps/nextjs/src/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { NextRequest, NextResponse } from "next/server";

import { handlers, isSecureContext } from "@acme/auth";

export const runtime = "edge";
// export const runtime = "edge";

const EXPO_COOKIE_NAME = "__acme-expo-redirect-state";
const AUTH_COOKIE_PATTERN = /authjs\.session-token=([^;]+)/;
Expand Down
2 changes: 1 addition & 1 deletion apps/nextjs/src/app/api/trpc/[trpc]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { appRouter, createTRPCContext } from "@acme/api";
import { auth } from "@acme/auth";

export const runtime = "edge";
// export const runtime = "edge";

/**
* Configure basic CORS headers
Expand Down
2 changes: 1 addition & 1 deletion apps/nextjs/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
PostList,
} from "./_components/posts";

export const runtime = "edge";
// export const runtime = "edge";

export default function HomePage() {
// You can await this here if you don't want to show Suspense fallback below
Expand Down
2 changes: 1 addition & 1 deletion apps/nextjs/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const env = createEnv({
* This way you can ensure the app isn't built with invalid env vars.
*/
server: {
POSTGRES_URL: z.string().url(),
DATABASE_URL: z.string().url(),
},

/**
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"build": "turbo run build",
"clean": "git clean -xdf node_modules",
"clean:workspaces": "turbo run clean",
"db:generate": "pnpm -F @acme/db generate",
"db:push": "turbo -F @acme/db push",
"db:studio": "turbo -F @acme/db studio",
"dev": "turbo watch dev",
Expand Down
25 changes: 5 additions & 20 deletions packages/api/src/router/post.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,25 @@
import type { TRPCRouterRecord } from "@trpc/server";
import { z } from "zod";

import { desc, eq } from "@acme/db";
import { CreatePostSchema, Post } from "@acme/db/schema";
import { CreatePostSchema } from "@acme/validators";

import { protectedProcedure, publicProcedure } from "../trpc";

export const postRouter = {
all: publicProcedure.query(({ ctx }) => {
// return ctx.db.select().from(schema.post).orderBy(desc(schema.post.id));
return ctx.db.query.Post.findMany({
orderBy: desc(Post.id),
limit: 10,
});
return ctx.db.post.findMany({ orderBy: { id: "desc" } });
}),

byId: publicProcedure
.input(z.object({ id: z.string() }))
.query(({ ctx, input }) => {
// return ctx.db
// .select()
// .from(schema.post)
// .where(eq(schema.post.id, input.id));

return ctx.db.query.Post.findFirst({
where: eq(Post.id, input.id),
});
return ctx.db.post.findFirst({ where: { id: input.id } });
}),

create: protectedProcedure
.input(CreatePostSchema)
.mutation(({ ctx, input }) => {
return ctx.db.insert(Post).values(input);
return ctx.db.post.create({ data: input });
}),

delete: protectedProcedure.input(z.string()).mutation(({ ctx, input }) => {
return ctx.db.delete(Post).where(eq(Post.id, input));
return ctx.db.post.delete({ where: { id: input } });
}),
} satisfies TRPCRouterRecord;
2 changes: 1 addition & 1 deletion packages/api/src/trpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ZodError } from "zod";

import type { Session } from "@acme/auth";
import { auth, validateToken } from "@acme/auth";
import { db } from "@acme/db/client";
import { db } from "@acme/db";

/**
* Isomorphic Session getter for API requests
Expand Down
2 changes: 1 addition & 1 deletion packages/auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"dependencies": {
"@acme/db": "workspace:*",
"@auth/core": "0.32.0",
"@auth/drizzle-adapter": "^1.4.1",
"@auth/prisma-adapter": "^2.4.1",
"@t3-oss/env-nextjs": "^0.10.1",
"next": "^14.2.4",
"next-auth": "5.0.0-beta.19",
Expand Down
11 changes: 3 additions & 8 deletions packages/auth/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import type {
Session as NextAuthSession,
} from "next-auth";
import { skipCSRFCheck } from "@auth/core";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import { PrismaAdapter } from "@auth/prisma-adapter";
import Discord from "next-auth/providers/discord";

import { db } from "@acme/db/client";
import { Account, Session, User } from "@acme/db/schema";
import { db } from "@acme/db";

import { env } from "../env";

Expand All @@ -20,11 +19,7 @@ declare module "next-auth" {
}
}

const adapter = DrizzleAdapter(db, {
usersTable: User,
accountsTable: Account,
sessionsTable: Session,
});
const adapter = PrismaAdapter(db);

export const isSecureContext = env.NODE_ENV !== "development";

Expand Down
13 changes: 0 additions & 13 deletions packages/db/drizzle.config.ts

This file was deleted.

26 changes: 11 additions & 15 deletions packages/db/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,39 @@
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./client": {
"types": "./dist/client.d.ts",
"default": "./dist/client.js"
},
"./schema": {
"types": "./dist/schema.d.ts",
"default": "./dist/schema.js"
}
},
"license": "MIT",
"prisma": {
"schema": "./src/schema.prisma"
},
"scripts": {
"build": "tsc",
"dev": "tsc",
"clean": "rm -rf .turbo dist node_modules",
"format": "prettier --check . --ignore-path ../../.gitignore",
"lint": "eslint",
"push": "pnpm with-env drizzle-kit push",
"studio": "pnpm with-env drizzle-kit studio",
"generate": "pnpm with-env prisma generate",
"push": "pnpm with-env prisma db push --skip-generate",
"studio": "pnpm with-env prisma studio --port 5556",
"typecheck": "tsc --noEmit --emitDeclarationOnly false",
"with-env": "dotenv -e ../../.env --"
"with-env": "dotenv -e ../../.env --",
"postinstall": "pnpm generate"
},
"dependencies": {
"@prisma/client": "^5.15.1",
"@prisma/extension-accelerate": "^1.1.0",
"@t3-oss/env-core": "^0.10.1",
"@vercel/postgres": "^0.9.0",
"drizzle-orm": "^0.31.2",
"drizzle-zod": "^0.5.1",
"zod": "catalog:"
},
"devDependencies": {
"@acme/eslint-config": "workspace:*",
"@acme/prettier-config": "workspace:*",
"@acme/tsconfig": "workspace:*",
"dotenv-cli": "^7.4.2",
"drizzle-kit": "^0.22.8",
"eslint": "catalog:",
"prettier": "catalog:",
"prisma": "^5.15.1",
"typescript": "catalog:"
},
"prettier": "@acme/prettier-config"
Expand Down
6 changes: 0 additions & 6 deletions packages/db/src/client.ts

This file was deleted.

31 changes: 29 additions & 2 deletions packages/db/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,29 @@
export * from "drizzle-orm/sql";
export { alias } from "drizzle-orm/pg-core";
/* eslint-disable no-restricted-properties */

// Solution for prisma edge: @link https://github.com/prisma/prisma/issues/22050#issuecomment-1821208388
// import { PrismaClient } from "@prisma/client/edge";
// import { withAccelerate } from "@prisma/extension-accelerate";

import { PrismaClient } from "@prisma/client";

export * from "@prisma/client";

// Learn more about instantiating PrismaClient in Next.js here: https://www.prisma.io/docs/data-platform/accelerate/getting-started
const prismaClientSingleton = () => {
return new PrismaClient({
log:
process.env.NODE_ENV === "development"
? ["query", "error", "warn"]
: ["error"],
});
};

type PrismaClientSingleton = ReturnType<typeof prismaClientSingleton>;

const globalForPrisma = globalThis as unknown as {
prisma: PrismaClientSingleton | undefined;
};

export const db = globalForPrisma.prisma ?? prismaClientSingleton();

if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db;
68 changes: 68 additions & 0 deletions packages/db/src/schema.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}

model Post {
id String @id @default(auto()) @map("_id") @db.ObjectId
title String
content String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}

// NextAuth.js Models
// NOTE: When using postgresql, mysql or sqlserver,
// uncomment the @db.Text annotations below
// @see https://next-auth.js.org/schemas/models
model Account {
id String @id @default(auto()) @map("_id") @db.ObjectId
userId String @db.ObjectId
type String
provider String
providerAccountId String
refresh_token String?
access_token String?
expires_at Int?
token_type String?
scope String?
id_token String?
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)

@@unique([provider, providerAccountId])
}

model Session {
id String @id @default(auto()) @map("_id") @db.ObjectId
sessionToken String @unique
userId String @db.ObjectId
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}

model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String?
email String? @unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
}

model VerificationToken {
id String @id @default(auto()) @map("_id") @db.ObjectId
identifier String
token String @unique
expires DateTime

@@unique([identifier, token])
}
Loading