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

feat: add drizzle #1461

Merged
merged 81 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
711f3b7
feat: add drizzle
juliusmarminge Jun 4, 2023
365f711
log next steps
juliusmarminge Jun 4, 2023
54898e1
Create fast-teachers-explain.md
juliusmarminge Jun 4, 2023
21a7062
add config file for push
juliusmarminge Jun 4, 2023
9eb1af1
Update cli/template/extras/config/drizzle.config.ts
juliusmarminge Jun 4, 2023
eb6040c
?
juliusmarminge Jun 4, 2023
52fd092
fix log
juliusmarminge Jun 4, 2023
8b3c334
what's wrong pretier
juliusmarminge Jun 4, 2023
3fb205e
rename number to name because its a varchar field
c-ehrlich Jun 27, 2023
1dd1db8
add next step
c-ehrlich Jun 27, 2023
d684c7e
fix schemas
juliusmarminge Jul 2, 2023
f37b9de
changed varchar to text on drizzle nextauth to prevent auth errors (#…
not-ani Jul 30, 2023
6352f52
Merge branch 'next' into drizzle
juliusmarminge Aug 10, 2023
c5cf536
Merge branch 'next' into drizzle
juliusmarminge Aug 10, 2023
c256269
format
juliusmarminge Aug 10, 2023
076bf36
lint
juliusmarminge Aug 10, 2023
af5257f
fix
juliusmarminge Aug 10, 2023
0fe5664
fix more
juliusmarminge Aug 10, 2023
7fabeea
fixx
juliusmarminge Aug 10, 2023
d7afbfa
fix
juliusmarminge Aug 10, 2023
74cdef3
fix and move
juliusmarminge Aug 10, 2023
d47195e
bumps
juliusmarminge Aug 10, 2023
b805566
fixxx
juliusmarminge Aug 10, 2023
1ed4302
fixxxx
juliusmarminge Aug 10, 2023
62b7292
add cast
juliusmarminge Aug 10, 2023
2489792
fixxx
juliusmarminge Aug 10, 2023
9738590
fixxx
juliusmarminge Aug 10, 2023
d0c06f6
lint fix
juliusmarminge Aug 10, 2023
c62f5f2
nuke inquirer completely
juliusmarminge Aug 10, 2023
be42a79
changeset
juliusmarminge Aug 10, 2023
5b4d054
fixx
juliusmarminge Aug 10, 2023
3f78700
use env
juliusmarminge Aug 10, 2023
815b027
fixy
juliusmarminge Aug 12, 2023
7383336
replace project1 with projectname
juliusmarminge Aug 12, 2023
740a905
mk dir first
juliusmarminge Aug 12, 2023
cc23103
Merge branch 'next' into drizzle
juliusmarminge Aug 12, 2023
8c6aa8c
rev
juliusmarminge Aug 12, 2023
c16e108
fix undefined
juliusmarminge Aug 12, 2023
2e818cd
fix prefix name
juliusmarminge Aug 12, 2023
604ac41
fix lint
juliusmarminge Aug 12, 2023
ce5f31b
use `CURRENT_TIMESTAMP`
juliusmarminge Aug 13, 2023
66e7107
Merge branch 'next' into drizzle
juliusmarminge Aug 13, 2023
07ab600
use `text`
juliusmarminge Aug 13, 2023
fc03108
added drizzle.config.ts to polish and english folder-structure (#1506)
wiktrek Aug 13, 2023
a885d95
placeholder docs
juliusmarminge Aug 13, 2023
bf91d2d
Merge branch 'next' into drizzle
juliusmarminge Aug 13, 2023
f6b65d1
prettier
c-ehrlich Aug 20, 2023
78c6c88
Merge branch 'next' into drizzle
juliusmarminge Aug 27, 2023
c2a50ba
bump
juliusmarminge Aug 27, 2023
532d070
bump
juliusmarminge Aug 27, 2023
532bda3
fix
juliusmarminge Aug 27, 2023
a9be92c
fix manypkg
juliusmarminge Aug 27, 2023
b9664a7
Merge branch 'next' into drizzle
juliusmarminge Aug 27, 2023
2e953da
fix next-step log
juliusmarminge Aug 27, 2023
8d38d48
Merge branch 'next' into drizzle
juliusmarminge Aug 27, 2023
6cebea7
Merge branch 'next' into drizzle
juliusmarminge Aug 27, 2023
429a77a
exit gracefully if prisma and drizzle are selected
c-ehrlich Aug 28, 2023
7193a1f
test if
juliusmarminge Sep 1, 2023
14f81cc
Merge branch 'next' into drizzle
juliusmarminge Sep 1, 2023
1d30d53
?
juliusmarminge Sep 1, 2023
503fcab
Update e2e.yml
juliusmarminge Sep 1, 2023
d55ead4
syntax
juliusmarminge Sep 1, 2023
ac8ee80
??
juliusmarminge Sep 1, 2023
83dce06
bruh??
juliusmarminge Sep 1, 2023
80714f2
yaml is fucked
juliusmarminge Sep 1, 2023
4723e20
Update e2e.yml
juliusmarminge Sep 1, 2023
f22f59c
this kinda suck
juliusmarminge Sep 1, 2023
29502d8
fix expr
juliusmarminge Sep 1, 2023
fd4ed67
Update e2e.yml
juliusmarminge Sep 1, 2023
23f1774
format
juliusmarminge Sep 1, 2023
93a1d2a
fix schema location in drizzle config
c-ehrlich Sep 2, 2023
d260df8
fix session relation
juliusmarminge Sep 5, 2023
6e8dd51
fix env for drizzle-kit
juliusmarminge Sep 5, 2023
46d1077
table filter for drizzle-kit
juliusmarminge Sep 5, 2023
3b365f1
format
juliusmarminge Sep 5, 2023
74af6b3
Merge branch 'next' into drizzle
juliusmarminge Sep 6, 2023
a2eecac
add dotenv-cli so db:push works w/o global dotenv
c-ehrlich Sep 6, 2023
3fe2b41
rm other dotenv dep and install the cli one
juliusmarminge Sep 7, 2023
22250c1
add note about drizzle to first steps docs
c-ehrlich Sep 7, 2023
260f2a5
update links
juliusmarminge Sep 11, 2023
4e8fe9f
use bigint over serial
juliusmarminge Sep 11, 2023
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
22 changes: 22 additions & 0 deletions .changeset/fast-teachers-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
"create-t3-app": patch
---

feat: add drizzle

This release adds a new option to use [`drizzle-orm`](https://orm.drizzle.team/) as an alternative to Prisma.

To make the different ORM options as similar as possible, some minor changes has also been made to the Prisma installer:

- a new script `db:push` has been added and is included in both ORM options.
- the prisma client has been renamed to `db` in the trpc context - you now access your database client like
```ts
examples: publicProcedure.query((opts) => {
// prisma
opts.ctx.db.example.findMany()
// drizzle
opts.ctx.cb.query.example.findMany()
juliusmarminge marked this conversation as resolved.
Show resolved Hide resolved
}),
```

You cannot choose the two options in the same app.
7 changes: 4 additions & 3 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ jobs:
tailwind: ["true", "false"]
nextAuth: ["true", "false"]
prisma: ["true", "false"]
drizzle: ["true", "false"]

name: "Build and Start T3 App ${{ matrix.trpc }}-${{ matrix.tailwind }}-${{ matrix.nextAuth }}-${{ matrix.prisma }}"
name: "Build and Start T3 App ${{ matrix.trpc }}-${{ matrix.tailwind }}-${{ matrix.nextAuth }}-${{ matrix.prisma }}-${{ matrix.drizzle}}"
steps:
- uses: actions/checkout@v3
with:
Expand Down Expand Up @@ -65,7 +66,7 @@ jobs:
# has to be scaffolded outside the CLI project so that no lint/tsconfig are leaking
# through. this way it ensures that it is the app's configs that are being used
# FIXME: this is a bit hacky, would rather have --packages=trpc,tailwind,... but not sure how to setup the matrix for that
- run: cd cli && pnpm start ../../ci-${{ matrix.trpc }}-${{ matrix.tailwind }}-${{ matrix.nextAuth }}-${{ matrix.prisma }} --noGit --CI --trpc=${{ matrix.trpc }} --tailwind=${{ matrix.tailwind }} --nextAuth=${{ matrix.nextAuth }} --prisma=${{ matrix.prisma }}
- run: cd ../ci-${{ matrix.trpc }}-${{ matrix.tailwind }}-${{ matrix.nextAuth }}-${{ matrix.prisma }} && pnpm build
- run: cd cli && pnpm start ../../ci-${{ matrix.trpc }}-${{ matrix.tailwind }}-${{ matrix.nextAuth }}-${{ matrix.prisma }}-${{ matrix.drizzle}} --noGit --CI --trpc=${{ matrix.trpc }} --tailwind=${{ matrix.tailwind }} --nextAuth=${{ matrix.nextAuth }} --prisma=${{ matrix.prisma }} --drizzle=${{ matrix.drizzle }}
- run: cd ../ci-${{ matrix.trpc }}-${{ matrix.tailwind }}-${{ matrix.nextAuth }}-${{ matrix.prisma }}-${{ matrix.drizzle}} && pnpm build
env:
NEXTAUTH_SECRET: foo
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,8 @@
"mdx.experimentalLanguageServer": true,
"[astro]": {
"editor.defaultFormatter": "astro-build.astro-vscode"
},
"[prisma]": {
"editor.defaultFormatter": "Prisma.prisma"
}
}
2 changes: 2 additions & 0 deletions cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"sort-package-json": "^2.4.1"
},
"devDependencies": {
"@planetscale/database": "^1.7.0",
"@prisma/client": "^4.14.0",
"@t3-oss/env-nextjs": "^0.3.1",
"@tanstack/react-query": "^4.29.7",
Expand All @@ -63,6 +64,7 @@
"@types/gradient-string": "^1.1.2",
"@types/inquirer": "^9.0.3",
"@types/node": "^18.16.0",
"drizzle-orm": "^0.26.5",
"next": "^13.4.1",
"next-auth": "^4.22.1",
"prettier": "^2.8.8",
Expand Down
24 changes: 24 additions & 0 deletions cli/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ interface CliFlags {
/** @internal Used in CI. */
prisma: boolean;
/** @internal Used in CI. */
drizzle: boolean;
/** @internal Used in CI. */
nextAuth: boolean;
}

Expand All @@ -45,6 +47,7 @@ const defaultOptions: CliResults = {
tailwind: false,
trpc: false,
prisma: false,
drizzle: false,
nextAuth: false,
importAlias: "~/",
},
Expand Down Expand Up @@ -103,6 +106,12 @@ export const runCli = async () => {
(value) => !!value && value !== "false",
)
/** @experimental - Used for CI E2E tests. Used in conjunction with `--CI` to skip prompting. */
.option(
"--drizzle [boolean]",
"Experimental: Boolean value if we should install Drizzle. Must be used in conjunction with `--CI`.",
(value) => !!value && value !== "false",
)
/** @experimental - Used for CI E2E tests. Used in conjunction with `--CI` to skip prompting. */
.option(
"--trpc [boolean]",
"Experimental: Boolean value if we should install tRPC. Must be used in conjunction with `--CI`.",
Expand Down Expand Up @@ -152,7 +161,16 @@ export const runCli = async () => {
if (cliResults.flags.trpc) cliResults.packages.push("trpc");
if (cliResults.flags.tailwind) cliResults.packages.push("tailwind");
if (cliResults.flags.prisma) cliResults.packages.push("prisma");
if (cliResults.flags.drizzle) cliResults.packages.push("drizzle");
if (cliResults.flags.nextAuth) cliResults.packages.push("nextAuth");

if (cliResults.flags.prisma && cliResults.flags.drizzle) {
console.warn(
"Incompatible combination Prisma + Drizzle. Falling back to Prisma only.",
c-ehrlich marked this conversation as resolved.
Show resolved Hide resolved
);
cliResults.flags.drizzle = false;
cliResults.packages.splice(cliResults.packages.indexOf("drizzle"), 1);
}
}

// Explained below why this is in a try/catch block
Expand Down Expand Up @@ -264,6 +282,12 @@ const promptPackages = async (): Promise<AvailablePackages[]> => {
name: pkgName,
checked: false,
})),
validate: (input: string[]) => {
if (input.includes("prisma") && input.includes("drizzle")) {
return "You cannot select both Prisma and Drizzle in the same app.";
}
return true;
},
});

return packages;
Expand Down
11 changes: 8 additions & 3 deletions cli/src/helpers/logNextSteps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,15 @@ export const logNextSteps = ({
}

if (packages?.prisma.inUse) {
logger.info(
` ${pkgManager === "npm" ? "npx" : pkgManager} prisma db push`,
);
logger.info(` ${pkgManager === "npm" ? "npm run" : pkgManager} db:push`);
}

logger.info(` ${pkgManager === "npm" ? "npm run" : pkgManager} dev`);

if (packages?.drizzle.inUse) {
logger.warn(
`\nThank you for trying out the new Drizzle option. If you encounter any issues, please open an issue!`,
`\nNote: We use the PlanetScale driver so that you can query your data in edge runtimes. If you want to use a different driver, you'll need to change it yourself.`,
);
}
};
7 changes: 7 additions & 0 deletions cli/src/installers/dependencyVersionMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ export const dependencyVersionMap = {
prisma: "^4.14.0",
"@prisma/client": "^4.14.0",

// Drizzle
"drizzle-orm": "^0.26.3",
"drizzle-kit": "^0.18.1",
dotenv: "^16.1.4",
// REVIEW: Is it fine including pscale by default?
c-ehrlich marked this conversation as resolved.
Show resolved Hide resolved
"@planetscale/database": "^1.7.0",

// TailwindCSS
tailwindcss: "^3.3.0",
autoprefixer: "^10.4.14",
Expand Down
52 changes: 52 additions & 0 deletions cli/src/installers/drizzle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import fs from "fs-extra";
import path from "path";
import { type PackageJson } from "type-fest";
import { PKG_ROOT } from "~/consts.js";
import { type Installer } from "~/installers/index.js";
import { addPackageDependency } from "~/utils/addPackageDependency.js";

export const drizzleInstaller: Installer = ({ projectDir, packages }) => {
addPackageDependency({
projectDir,
dependencies: ["drizzle-kit", "dotenv"],
devMode: true,
});
addPackageDependency({
projectDir,
dependencies: ["drizzle-orm", "@planetscale/database"],
devMode: false,
});

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

const configFile = path.join(extrasDir, "config/drizzle.config.ts");
const configDest = path.join(projectDir, "drizzle.config.ts");

const schemaSrc = path.join(
extrasDir,
"src/server/db",
packages?.nextAuth.inUse
? "drizzle-schema-auth.ts"
juliusmarminge marked this conversation as resolved.
Show resolved Hide resolved
: "drizzle-schema-base.ts",
);
const schemaDest = path.join(projectDir, "src/server/db/schema.ts");

const clientSrc = path.join(extrasDir, "src/server/db/index-drizzle.ts");
const clientDest = path.join(projectDir, "src/server/db/index.ts");

// add db:push script to package.json
const packageJsonPath = path.join(projectDir, "package.json");

const packageJsonContent = fs.readJSONSync(packageJsonPath) as PackageJson;
packageJsonContent.scripts = {
...packageJsonContent.scripts,
"db:push": "drizzle-kit push:mysql",
};

fs.copySync(configFile, configDest);
fs.copySync(schemaSrc, schemaDest);
fs.copySync(clientSrc, clientDest);
fs.writeJSONSync(packageJsonPath, packageJsonContent, {
spaces: 2,
});
};
22 changes: 18 additions & 4 deletions cli/src/installers/envVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ import { type Installer } from "~/installers/index.js";
export const envVariablesInstaller: Installer = ({ projectDir, packages }) => {
const usingAuth = packages?.nextAuth.inUse;
const usingPrisma = packages?.prisma.inUse;
const usingDrizzle = packages?.drizzle.inUse;

const envContent = getEnvContent(!!usingAuth, !!usingPrisma);
const envContent = getEnvContent(!!usingAuth, !!usingPrisma, !!usingDrizzle);

const envFile =
usingAuth && usingPrisma
? "with-auth-prisma.mjs"
: usingAuth
? "with-auth.mjs"
: usingPrisma
? "with-prisma.mjs"
: usingPrisma || usingDrizzle
? "with-db.mjs"
: "";

if (envFile !== "") {
Expand All @@ -35,7 +36,11 @@ export const envVariablesInstaller: Installer = ({ projectDir, packages }) => {
fs.writeFileSync(envExampleDest, exampleEnvContent + envContent, "utf-8");
};

const getEnvContent = (usingAuth: boolean, usingPrisma: boolean) => {
const getEnvContent = (
usingAuth: boolean,
usingPrisma: boolean,
usingDrizzle: boolean,
) => {
let content = `
# When adding additional environment variables, the schema in "/src/env.mjs"
# should be updated accordingly.
Expand All @@ -50,6 +55,15 @@ const getEnvContent = (usingAuth: boolean, usingPrisma: boolean) => {
DATABASE_URL="file:./db.sqlite"
`;

if (usingDrizzle) {
content += `
# Drizzle
# Get the Database URL from the "prisma" dropdown selector in PlanetScale.
# Change the query params at the end of the URL to "?ssl={"rejectUnauthorized":true}"
DATABASE_URL='mysql://YOUR_MYSQL_URL_HERE?ssl={"rejectUnauthorized":true}'
`;
}

if (usingAuth)
content += `
# Next Auth
Expand Down
6 changes: 6 additions & 0 deletions cli/src/installers/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { drizzleInstaller } from "./drizzle.js";
import { envVariablesInstaller } from "~/installers/envVars.js";
import { nextAuthInstaller } from "~/installers/nextAuth.js";
import { prismaInstaller } from "~/installers/prisma.js";
Expand All @@ -10,6 +11,7 @@ import { type PackageManager } from "~/utils/getUserPkgManager.js";
export const availablePackages = [
"nextAuth",
"prisma",
"drizzle",
"tailwind",
"trpc",
"envVariables",
Expand Down Expand Up @@ -44,6 +46,10 @@ export const buildPkgInstallerMap = (
inUse: packages.includes("prisma"),
installer: prismaInstaller,
},
drizzle: {
inUse: packages.includes("drizzle"),
installer: drizzleInstaller,
},
tailwind: {
inUse: packages.includes("tailwind"),
installer: tailwindInstaller,
Expand Down
10 changes: 9 additions & 1 deletion cli/src/installers/nextAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ import { addPackageDependency } from "~/utils/addPackageDependency.js";

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

const deps: AvailableDependencies[] = ["next-auth"];
if (usingPrisma) deps.push("@next-auth/prisma-adapter");
// This adapter is not yet available on npm so we have our own inhoused
juliusmarminge marked this conversation as resolved.
Show resolved Hide resolved
// if (usingDrizzle) deps.push("@next-auth/drizzle-adapter");

addPackageDependency({
projectDir,
Expand All @@ -25,7 +29,11 @@ export const nextAuthInstaller: Installer = ({ projectDir, packages }) => {
const authConfigSrc = path.join(
extrasDir,
"src/server/auth",
usingPrisma ? "with-prisma.ts" : "base.ts",
usingPrisma
? "with-prisma.ts"
: usingDrizzle
? "with-drizzle.ts"
: "base.ts",
);
const authConfigDest = path.join(projectDir, "src/server/auth.ts");

Expand Down
5 changes: 3 additions & 2 deletions cli/src/installers/prisma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,17 @@ export const prismaInstaller: Installer = ({ projectDir, packages }) => {
);
const schemaDest = path.join(projectDir, "prisma/schema.prisma");

const clientSrc = path.join(extrasDir, "src/server/db.ts");
const clientSrc = path.join(extrasDir, "src/server/db/db-prisma.ts");
const clientDest = path.join(projectDir, "src/server/db.ts");

// add postinstall script to package.json
// add postinstall and push script to package.json
const packageJsonPath = path.join(projectDir, "package.json");

const packageJsonContent = fs.readJSONSync(packageJsonPath) as PackageJson;
packageJsonContent.scripts = {
...packageJsonContent.scripts,
postinstall: "prisma generate",
"db:push": "prisma db push",
};

fs.copySync(schemaSrc, schemaDest);
Expand Down
14 changes: 10 additions & 4 deletions cli/src/installers/trpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export const trpcInstaller: Installer = ({ projectDir, packages }) => {

const usingAuth = packages?.nextAuth.inUse;
const usingPrisma = packages?.prisma.inUse;
const usingDrizzle = packages?.drizzle.inUse;
const usingDb = usingPrisma || usingDrizzle;

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

Expand All @@ -30,12 +32,12 @@ export const trpcInstaller: Installer = ({ projectDir, packages }) => {
const utilsDest = path.join(projectDir, "src/utils/api.ts");

const trpcFile =
usingAuth && usingPrisma
? "with-auth-prisma.ts"
usingAuth && usingDb
? "with-auth-db.ts"
: usingAuth
? "with-auth.ts"
: usingPrisma
? "with-prisma.ts"
: usingDb
? "with-db.ts"
: "base.ts";
const trpcSrc = path.join(extrasDir, "src/server/api/trpc", trpcFile);
const trpcDest = path.join(projectDir, "src/server/api/trpc.ts");
Expand All @@ -46,10 +48,14 @@ export const trpcInstaller: Installer = ({ projectDir, packages }) => {
const exampleRouterFile =
usingAuth && usingPrisma
? "with-auth-prisma.ts"
: usingAuth && usingDrizzle
? "with-auth-drizzle.ts"
: usingAuth
? "with-auth.ts"
: usingPrisma
? "with-prisma.ts"
: usingDrizzle
? "with-drizzle.ts"
: "base.ts";

const exampleRouterSrc = path.join(
Expand Down
9 changes: 9 additions & 0 deletions cli/template/extras/config/drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as dotenv from "dotenv";
import { type Config } from "drizzle-kit";

dotenv.config();

export default {
schema: "./src/server/db/schema.ts",
connectionString: process.env.DATABASE_URL,
juliusmarminge marked this conversation as resolved.
Show resolved Hide resolved
} satisfies Config;
Loading