better-ts-stack 0.1.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +12 -6
  2. package/dist/builder/configGenerator.d.ts.map +1 -1
  3. package/dist/builder/configGenerator.js +30 -24
  4. package/dist/builder/configGenerator.js.map +1 -1
  5. package/dist/builder/dependencyInstaller.d.ts.map +1 -1
  6. package/dist/builder/dependencyInstaller.js +1 -10
  7. package/dist/builder/dependencyInstaller.js.map +1 -1
  8. package/dist/builder/index.d.ts.map +1 -1
  9. package/dist/builder/index.js +3 -7
  10. package/dist/builder/index.js.map +1 -1
  11. package/dist/builder/moduleSelector.d.ts.map +1 -1
  12. package/dist/builder/moduleSelector.js +1 -1
  13. package/dist/builder/moduleSelector.js.map +1 -1
  14. package/dist/builder/templateContext.d.ts +2 -2
  15. package/dist/builder/templateContext.d.ts.map +1 -1
  16. package/dist/builder/templateContext.js +1 -3
  17. package/dist/builder/templateContext.js.map +1 -1
  18. package/dist/modules/registry.d.ts.map +1 -1
  19. package/dist/modules/registry.js +2 -5
  20. package/dist/modules/registry.js.map +1 -1
  21. package/dist/output/nextSteps.d.ts.map +1 -1
  22. package/dist/output/nextSteps.js +7 -34
  23. package/dist/output/nextSteps.js.map +1 -1
  24. package/dist/prompts/index.d.ts.map +1 -1
  25. package/dist/prompts/index.js +3 -14
  26. package/dist/prompts/index.js.map +1 -1
  27. package/dist/prompts/stack.d.ts +3 -0
  28. package/dist/prompts/stack.d.ts.map +1 -0
  29. package/dist/prompts/stack.js +77 -0
  30. package/dist/prompts/stack.js.map +1 -0
  31. package/dist/types/index.d.ts +12 -10
  32. package/dist/types/index.d.ts.map +1 -1
  33. package/dist/types/index.js +6 -10
  34. package/dist/types/index.js.map +1 -1
  35. package/dist/validators/index.d.ts +1 -1
  36. package/dist/validators/index.d.ts.map +1 -1
  37. package/dist/validators/index.js +1 -1
  38. package/package.json +12 -12
  39. package/templates/backend/express/config.json +44 -42
  40. package/templates/backend/express/eslint.config.mjs +40 -31
  41. package/templates/backend/express/src/index.ts +61 -46
  42. package/templates/backend/express/src/routes/health.ts +12 -12
  43. package/templates/backend/express/tsconfig.json +25 -23
  44. package/templates/frontend/nextjs/config.json +33 -27
  45. package/templates/frontend/nextjs/eslint.config.mjs +11 -11
  46. package/templates/frontend/nextjs/proxy.ts.hbs +9 -8
  47. package/templates/frontend/nextjs/tsconfig.json +34 -21
  48. package/templates/frontend/tanstack/components.json +18 -0
  49. package/templates/frontend/tanstack/config.json +49 -0
  50. package/templates/frontend/tanstack/eslint.config.mjs +23 -0
  51. package/templates/frontend/tanstack/gitignore +38 -0
  52. package/templates/frontend/tanstack/public/favicon.svg +7 -0
  53. package/templates/frontend/tanstack/src/components/ui/button.tsx +51 -0
  54. package/templates/frontend/tanstack/src/components/ui/card.tsx +60 -0
  55. package/templates/frontend/tanstack/src/components/ui/field.tsx +67 -0
  56. package/templates/frontend/tanstack/src/components/ui/input.tsx +18 -0
  57. package/templates/frontend/tanstack/src/lib/utils.ts +6 -0
  58. package/templates/frontend/tanstack/src/routeTree.gen.ts +68 -0
  59. package/templates/frontend/tanstack/src/router.tsx +32 -0
  60. package/templates/frontend/tanstack/src/routes/__root.tsx +70 -0
  61. package/templates/frontend/tanstack/src/routes/index.tsx.hbs +102 -0
  62. package/templates/frontend/tanstack/src/styles/app.css +85 -0
  63. package/templates/frontend/tanstack/tsconfig.json +22 -0
  64. package/templates/frontend/tanstack/vite.config.ts +14 -0
  65. package/templates/modules/auth/express/config.json +26 -1
  66. package/templates/modules/auth/express/src/routes/auth.ts.hbs +1 -1
  67. package/templates/modules/auth/express/src/services/userStore.ts.hbs +95 -107
  68. package/templates/modules/auth/nextjs/config.json +6 -6
  69. package/templates/modules/auth/nextjs/lib/auth.ts.hbs +34 -32
  70. package/templates/modules/auth/tanstack/config.json +33 -0
  71. package/templates/modules/auth/tanstack/src/components/auth/sign-in-form.tsx +135 -0
  72. package/templates/modules/auth/tanstack/src/components/auth/sign-out-button.tsx +49 -0
  73. package/templates/modules/auth/tanstack/src/components/auth/sign-up-form.tsx +153 -0
  74. package/templates/modules/auth/tanstack/src/lib/auth-client.ts +3 -0
  75. package/templates/modules/auth/tanstack/src/lib/auth-functions.ts +12 -0
  76. package/templates/modules/auth/tanstack/src/lib/auth-schema.ts +39 -0
  77. package/templates/modules/auth/tanstack/src/lib/auth.ts.hbs +38 -0
  78. package/templates/modules/auth/tanstack/src/routeTree.gen.ts +140 -0
  79. package/templates/modules/auth/tanstack/src/routes/api/auth/$.ts +16 -0
  80. package/templates/modules/auth/tanstack/src/routes/dashboard.tsx +111 -0
  81. package/templates/modules/auth/tanstack/src/routes/sign-in.tsx +37 -0
  82. package/templates/modules/auth/tanstack/src/routes/sign-up.tsx +37 -0
  83. package/templates/modules/docker/.dockerignore +14 -13
  84. package/templates/modules/docker/Dockerfile.hbs +64 -9
  85. package/templates/modules/docker/config.json +19 -16
  86. package/templates/modules/docker/docker-compose.yml.hbs +9 -9
  87. package/templates/modules/drizzle/express/config.json +27 -0
  88. package/templates/modules/drizzle/express/drizzle.config.ts +13 -0
  89. package/templates/modules/drizzle/express/src/lib/db.ts +13 -0
  90. package/templates/modules/drizzle/express/src/lib/schema.ts +10 -0
  91. package/templates/modules/drizzle/nextjs/config.json +27 -19
  92. package/templates/modules/drizzle/nextjs/lib/db.ts +3 -1
  93. package/templates/modules/drizzle/nextjs/lib/schema.ts.hbs +84 -84
  94. package/templates/modules/drizzle/tanstack/config.json +26 -0
  95. package/templates/modules/drizzle/tanstack/drizzle.config.ts +13 -0
  96. package/templates/modules/drizzle/tanstack/src/lib/db.ts +13 -0
  97. package/templates/modules/drizzle/tanstack/src/lib/schema.ts.hbs +84 -0
  98. package/templates/modules/mongoose/config.json +16 -16
  99. package/templates/modules/mongoose/src/lib/db.ts.hbs +0 -13
  100. package/templates/modules/mongoose/src/models/User.ts +48 -47
  101. package/templates/modules/prisma/express/config.json +27 -21
  102. package/templates/modules/prisma/express/prisma/schema.prisma +3 -2
  103. package/templates/modules/prisma/express/prisma.config.ts +12 -13
  104. package/templates/modules/prisma/express/src/lib/prisma.ts +24 -37
  105. package/templates/modules/prisma/nextjs/config.json +28 -23
  106. package/templates/modules/prisma/nextjs/prisma/schema.prisma.hbs +91 -90
  107. package/templates/modules/prisma/tanstack/config.json +28 -0
  108. package/templates/modules/prisma/tanstack/prisma/schema.prisma.hbs +91 -0
  109. package/templates/modules/prisma/tanstack/prisma.config.ts +12 -0
  110. package/templates/modules/prisma/tanstack/src/lib/prisma.ts +18 -0
  111. package/dist/prompts/backend/index.d.ts +0 -3
  112. package/dist/prompts/backend/index.d.ts.map +0 -1
  113. package/dist/prompts/backend/index.js +0 -128
  114. package/dist/prompts/backend/index.js.map +0 -1
  115. package/dist/prompts/frontend/index.d.ts +0 -3
  116. package/dist/prompts/frontend/index.d.ts.map +0 -1
  117. package/dist/prompts/frontend/index.js +0 -111
  118. package/dist/prompts/frontend/index.js.map +0 -1
@@ -0,0 +1,111 @@
1
+ import { createFileRoute, redirect } from "@tanstack/react-router";
2
+ import { Link } from "@tanstack/react-router";
3
+ import { ArrowRight, ShieldCheck } from "lucide-react";
4
+
5
+ import { SignOutButton } from "~/components/auth/sign-out-button";
6
+ import { buttonVariants } from "~/components/ui/button";
7
+ import {
8
+ Card,
9
+ CardContent,
10
+ CardDescription,
11
+ CardHeader,
12
+ CardTitle,
13
+ } from "~/components/ui/card";
14
+ import { getSession } from "~/lib/auth-functions";
15
+ import { cn } from "~/lib/utils";
16
+
17
+ export const Route = createFileRoute("/dashboard")({
18
+ beforeLoad: async () => {
19
+ const session = await getSession();
20
+
21
+ if (!session) {
22
+ throw redirect({ to: "/sign-in" });
23
+ }
24
+
25
+ return { user: session.user };
26
+ },
27
+ component: Dashboard,
28
+ });
29
+
30
+ function Dashboard() {
31
+ const user = Route.useRouteContext({ select: (ctx) => ctx.user });
32
+
33
+ return (
34
+ <main className="min-h-screen bg-[linear-gradient(180deg,_#f8fafc_0%,_#eef2ff_100%)] px-6 py-16 sm:px-10">
35
+ <div className="mx-auto max-w-5xl space-y-8">
36
+ <header className="flex flex-col gap-6 rounded-[2rem] border border-white/70 bg-white/85 p-8 shadow-xl shadow-slate-200/60 backdrop-blur md:flex-row md:items-end md:justify-between">
37
+ <div className="space-y-3">
38
+ <span className="inline-flex items-center gap-2 rounded-full bg-emerald-50 px-3 py-1 text-xs font-medium uppercase tracking-[0.24em] text-emerald-700">
39
+ <ShieldCheck className="size-4" />
40
+ Authenticated session
41
+ </span>
42
+ <div className="space-y-1">
43
+ <h1 className="text-3xl font-semibold tracking-tight text-slate-950">
44
+ Welcome {user.name}
45
+ </h1>
46
+ <p className="text-sm text-slate-600">{user.email}</p>
47
+ </div>
48
+ </div>
49
+ <SignOutButton />
50
+ </header>
51
+
52
+ <section className="grid gap-5 md:grid-cols-2">
53
+ <Card>
54
+ <CardHeader>
55
+ <CardTitle>Protected route example</CardTitle>
56
+ <CardDescription>
57
+ This page verifies the session on the server before rendering any
58
+ content.
59
+ </CardDescription>
60
+ </CardHeader>
61
+ <CardContent className="space-y-4 text-sm text-slate-600">
62
+ <p>
63
+ The route guard calls{" "}
64
+ <code className="font-mono text-slate-900">getSession()</code> in
65
+ <code className="font-mono text-slate-900"> beforeLoad</code>,
66
+ which reads the cookie headers server-side via{" "}
67
+ <code className="font-mono text-slate-900">
68
+ auth.api.getSession
69
+ </code>{" "}
70
+ on every render and navigation.
71
+ </p>
72
+ <p>
73
+ That keeps route protection aligned with Better Auth&apos;s
74
+ TanStack Start guidance while staying easy to extend.
75
+ </p>
76
+ </CardContent>
77
+ </Card>
78
+
79
+ <Card>
80
+ <CardHeader>
81
+ <CardTitle>Suggested next steps</CardTitle>
82
+ <CardDescription>
83
+ Keep the generated auth flow, then customize the app around your
84
+ product.
85
+ </CardDescription>
86
+ </CardHeader>
87
+ <CardContent className="space-y-3 text-sm text-slate-600">
88
+ <p>
89
+ Replace the demo dashboard with your first authenticated page.
90
+ </p>
91
+ <p>Extend the schema with profile or onboarding fields.</p>
92
+ <p>
93
+ Add provider-based auth or email verification later if needed.
94
+ </p>
95
+ <Link
96
+ to="/"
97
+ className={cn(
98
+ buttonVariants({ variant: "outline" }),
99
+ "w-fit gap-2"
100
+ )}
101
+ >
102
+ Back to home
103
+ <ArrowRight className="size-4" />
104
+ </Link>
105
+ </CardContent>
106
+ </Card>
107
+ </section>
108
+ </div>
109
+ </main>
110
+ );
111
+ }
@@ -0,0 +1,37 @@
1
+ import { createFileRoute, redirect } from "@tanstack/react-router";
2
+
3
+ import { SignInForm } from "~/components/auth/sign-in-form";
4
+ import { getSession } from "~/lib/auth-functions";
5
+
6
+ export const Route = createFileRoute("/sign-in")({
7
+ beforeLoad: async () => {
8
+ const session = await getSession();
9
+
10
+ if (session) {
11
+ throw redirect({ to: "/dashboard" });
12
+ }
13
+ },
14
+ component: SignInPage,
15
+ });
16
+
17
+ function SignInPage() {
18
+ return (
19
+ <main className="min-h-screen bg-[radial-gradient(circle_at_top,_rgba(14,165,233,0.16),_transparent_30%),linear-gradient(180deg,_#f8fafc_0%,_#eef2ff_100%)] px-6 py-16 sm:px-10">
20
+ <div className="mx-auto flex min-h-[calc(100vh-8rem)] max-w-5xl items-center gap-12 lg:grid lg:grid-cols-[0.9fr_1.1fr]">
21
+ <section className="hidden space-y-5 lg:block">
22
+ <span className="inline-flex rounded-full border border-sky-200 bg-white/80 px-3 py-1 text-xs font-medium uppercase tracking-[0.24em] text-sky-700">
23
+ Better Auth
24
+ </span>
25
+ <h1 className="text-4xl font-semibold tracking-tight text-slate-950">
26
+ Welcome back.
27
+ </h1>
28
+ <p className="max-w-md text-base leading-7 text-slate-600">
29
+ This generated starter includes protected routes, session-aware page
30
+ guards, and reusable auth form primitives you can extend from here.
31
+ </p>
32
+ </section>
33
+ <SignInForm />
34
+ </div>
35
+ </main>
36
+ );
37
+ }
@@ -0,0 +1,37 @@
1
+ import { createFileRoute, redirect } from "@tanstack/react-router";
2
+
3
+ import { SignUpForm } from "~/components/auth/sign-up-form";
4
+ import { getSession } from "~/lib/auth-functions";
5
+
6
+ export const Route = createFileRoute("/sign-up")({
7
+ beforeLoad: async () => {
8
+ const session = await getSession();
9
+
10
+ if (session) {
11
+ throw redirect({ to: "/dashboard" });
12
+ }
13
+ },
14
+ component: SignUpPage,
15
+ });
16
+
17
+ function SignUpPage() {
18
+ return (
19
+ <main className="min-h-screen bg-[radial-gradient(circle_at_top,_rgba(56,189,248,0.18),_transparent_28%),linear-gradient(180deg,_#f8fafc_0%,_#ecfeff_100%)] px-6 py-16 sm:px-10">
20
+ <div className="mx-auto flex min-h-[calc(100vh-8rem)] max-w-5xl items-center gap-12 lg:grid lg:grid-cols-[0.9fr_1.1fr]">
21
+ <section className="hidden space-y-5 lg:block">
22
+ <span className="inline-flex rounded-full border border-sky-200 bg-white/80 px-3 py-1 text-xs font-medium uppercase tracking-[0.24em] text-sky-700">
23
+ Better Auth
24
+ </span>
25
+ <h1 className="text-4xl font-semibold tracking-tight text-slate-950">
26
+ Create your account.
27
+ </h1>
28
+ <p className="max-w-md text-base leading-7 text-slate-600">
29
+ Start with email and password today, then layer in profile data,
30
+ onboarding, and provider-based auth when your product needs it.
31
+ </p>
32
+ </section>
33
+ <SignUpForm />
34
+ </div>
35
+ </main>
36
+ );
37
+ }
@@ -1,13 +1,14 @@
1
- node_modules
2
- npm-debug.log
3
- .env
4
- .env.local
5
- .git
6
- .gitignore
7
- README.md
8
- .vscode
9
- .idea
10
- dist
11
- coverage
12
- .DS_Store
13
- *.log
1
+ node_modules
2
+ npm-debug.log
3
+ .env*
4
+ .git
5
+ .gitignore
6
+ README.md
7
+ .vscode
8
+ .idea
9
+ dist
10
+ coverage
11
+ .DS_Store
12
+ *.log
13
+
14
+ .next
@@ -1,6 +1,6 @@
1
1
  {{#if (eq framework 'nextjs')}}
2
2
  # Base stage
3
- FROM node:20-alpine AS base
3
+ FROM node:24-alpine AS base
4
4
  WORKDIR /app
5
5
  RUN apk add --no-cache libc6-compat
6
6
 
@@ -13,10 +13,16 @@ RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
13
13
  FROM base AS builder
14
14
  COPY --from=deps /app/node_modules ./node_modules
15
15
  COPY . .
16
+ {{#if (eq database 'prisma')}}
17
+ RUN DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres" npm run build
18
+ {{else if (eq database 'mongoose')}}
19
+ RUN MONGODB_URI="mongodb://localhost:27017/build" npm run build
20
+ {{else}}
16
21
  RUN npm run build
22
+ {{/if}}
17
23
 
18
24
  # Production stage
19
- FROM node:20-alpine AS runner
25
+ FROM node:24-alpine AS runner
20
26
  WORKDIR /app
21
27
  ENV NODE_ENV=production
22
28
 
@@ -33,9 +39,54 @@ ENV PORT={{port}} HOSTNAME=0.0.0.0
33
39
 
34
40
  CMD ["node", "server.js"]
35
41
 
42
+ {{else if (eq framework 'tanstack')}}
43
+ # Build stage
44
+ FROM node:24-alpine AS builder
45
+ WORKDIR /app
46
+
47
+ COPY package*.json ./
48
+ RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
49
+
50
+ COPY . .
51
+
52
+ # Only build if package.json has a build script
53
+ {{#if (eq database 'prisma')}}
54
+ RUN DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres" npm run build
55
+ {{else if (eq database 'mongoose')}}
56
+ RUN MONGODB_URI="mongodb://localhost:27017/build" npm run build
57
+ {{else}}
58
+ RUN npm run build
59
+ {{/if}}
60
+
61
+ # Production stage
62
+ FROM node:24-alpine
63
+ WORKDIR /app
64
+ ENV NODE_ENV=production
65
+
66
+ # Create non-root user for security
67
+ RUN addgroup --system --gid 1001 nodejs && \
68
+ adduser --system --uid 1001 tanstackuser
69
+
70
+ COPY package*.json ./
71
+ RUN if [ -f package-lock.json ]; then npm ci --omit=dev; else npm install --omit=dev; fi
72
+
73
+ # Copy built output (dist/server/server.js + dist/client)
74
+ COPY --from=builder --chown=tanstackuser:nodejs /app/dist ./dist
75
+
76
+ # Include the Prisma client generated during the build stage
77
+ {{#if (eq database 'prisma')}}
78
+ COPY --from=builder --chown=tanstackuser:nodejs /app/generated ./generated
79
+ {{/if}}
80
+
81
+ USER tanstackuser
82
+ EXPOSE {{port}}
83
+ ENV PORT={{port}}
84
+
85
+ CMD ["node_modules/.bin/srvx", "--prod", "-s", "../client", "dist/server/server.js"]
86
+
36
87
  {{else}}
37
88
  # Build stage
38
- FROM node:20-alpine AS builder
89
+ FROM node:24-alpine AS builder
39
90
  WORKDIR /app
40
91
 
41
92
  COPY package*.json ./
@@ -44,10 +95,16 @@ RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
44
95
  COPY . .
45
96
 
46
97
  # Only build if package.json has a build script
47
- RUN npm run build || echo "No build script found, skipping build step"
98
+ {{#if (eq database 'prisma')}}
99
+ RUN DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres" npm run build
100
+ {{else if (eq database 'mongoose')}}
101
+ RUN MONGODB_URI="mongodb://localhost:27017/build" npm run build
102
+ {{else}}
103
+ RUN npm run build
104
+ {{/if}}
48
105
 
49
106
  # Production stage
50
- FROM node:20-alpine
107
+ FROM node:24-alpine
51
108
  WORKDIR /app
52
109
  ENV NODE_ENV=production
53
110
 
@@ -59,13 +116,11 @@ COPY package*.json ./
59
116
  RUN if [ -f package-lock.json ]; then npm ci --omit=dev; else npm install --omit=dev; fi
60
117
 
61
118
  # Copy built files (if TypeScript) or source files (if JavaScript)
62
- COPY --from=builder --chown=expressuser:nodejs /app/dist ./dist 2>/dev/null || \
63
- COPY --chown=expressuser:nodejs /app/src ./src 2>/dev/null || \
64
- COPY --chown=expressuser:nodejs /app/*.js ./
119
+ COPY --from=builder --chown=expressuser:nodejs /app/dist ./dist
65
120
 
66
121
  USER expressuser
67
122
  EXPOSE {{port}}
68
123
  ENV PORT={{port}}
69
124
 
70
- CMD ["node", "{{entrypoint}}"]
125
+ CMD ["node", "dist/index.js"]
71
126
  {{/if}}
@@ -1,16 +1,19 @@
1
- {
2
- "id": "docker",
3
- "name": "Docker",
4
- "description": "Docker containerization with multi-stage build and docker-compose",
5
- "type": "feature",
6
- "dependencies": {},
7
- "devDependencies": {},
8
- "scripts": {
9
- "docker:build": "docker build -t {{projectName}} .",
10
- "docker:up": "docker-compose up -d",
11
- "docker:down": "docker-compose down",
12
- "docker:logs": "docker-compose logs -f"
13
- },
14
- "envVars": {},
15
- "templateFiles": ["docker-compose.yml.hbs", "Dockerfile.hbs"]
16
- }
1
+ {
2
+ "id": "docker",
3
+ "name": "Docker",
4
+ "description": "Docker containerization with multi-stage build and docker-compose",
5
+ "type": "feature",
6
+ "dependencies": {},
7
+ "devDependencies": {},
8
+ "scripts": {
9
+ "docker:build": "docker build -t {{projectName}} .",
10
+ "docker:up": "docker compose up -d",
11
+ "docker:down": "docker compose down",
12
+ "docker:logs": "docker compose logs -f"
13
+ },
14
+ "envVars": {},
15
+ "templateFiles": [
16
+ "docker-compose.yml.hbs",
17
+ "Dockerfile.hbs"
18
+ ]
19
+ }
@@ -1,10 +1,10 @@
1
- version: '3.8'
2
-
3
- services:
4
- {{projectName}}:
5
- build: .
6
- ports:
7
- - "{{port}}:{{port}}"
8
- environment:
9
- - NODE_ENV=production
1
+ services:
2
+ {{projectName}}:
3
+ build: .
4
+ ports:
5
+ - "{{port}}:{{port}}"
6
+ env_file:
7
+ - .env
8
+ environment:
9
+ - NODE_ENV=production
10
10
  restart: unless-stopped
@@ -0,0 +1,27 @@
1
+ {
2
+ "id": "drizzle",
3
+ "name": "Drizzle ORM",
4
+ "description": "Drizzle ORM for Express with PostgreSQL",
5
+ "type": "database",
6
+ "dependencies": {
7
+ "drizzle-orm": "^0.45.2",
8
+ "pg": "^8.23.0",
9
+ "dotenv": "^17.4.2"
10
+ },
11
+ "devDependencies": {
12
+ "drizzle-kit": "^0.31.10",
13
+ "@types/pg": "^8.23.1"
14
+ },
15
+ "scripts": {
16
+ "db:generate": "drizzle-kit generate",
17
+ "db:migrate": "drizzle-kit migrate",
18
+ "db:studio": "drizzle-kit studio"
19
+ },
20
+ "envVars": {
21
+ "DATABASE_URL": "postgresql://user:password@localhost:5432/mydb?schema=public"
22
+ },
23
+ "templateFiles": [],
24
+ "overrides": {
25
+ "esbuild": "^0.28.2"
26
+ }
27
+ }
@@ -0,0 +1,13 @@
1
+ import { config } from "dotenv";
2
+ import { defineConfig } from "drizzle-kit";
3
+
4
+ config({ path: ".env" });
5
+
6
+ export default defineConfig({
7
+ schema: "./src/lib/schema.ts",
8
+ out: "./migrations",
9
+ dialect: "postgresql",
10
+ dbCredentials: {
11
+ url: process.env.DATABASE_URL!,
12
+ },
13
+ });
@@ -0,0 +1,13 @@
1
+ import { config } from "dotenv";
2
+ import { drizzle } from "drizzle-orm/node-postgres";
3
+ import { Pool } from "pg";
4
+
5
+ import * as schema from "./schema";
6
+
7
+ config({ path: ".env" }); // or .env.local
8
+
9
+ const pool = new Pool({
10
+ connectionString: process.env.DATABASE_URL,
11
+ });
12
+
13
+ export const db = drizzle(pool, { schema });
@@ -0,0 +1,10 @@
1
+ import { pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
2
+
3
+ export const users = pgTable("users", {
4
+ id: uuid("id").primaryKey().defaultRandom(),
5
+ email: text("email").notNull().unique(),
6
+ name: text("name"),
7
+ password: text("password").notNull(),
8
+ createdAt: timestamp("created_at", { withTimezone: true }).defaultNow(),
9
+ updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow(),
10
+ });
@@ -1,21 +1,29 @@
1
- {
2
- "id": "drizzle",
3
- "name": "Drizzle ORM",
4
- "description": "Drizzle ORM for Next.js with PostgreSQL",
5
- "type": "database",
1
+ {
2
+ "id": "drizzle",
3
+ "name": "Drizzle ORM",
4
+ "description": "Drizzle ORM for Next.js with PostgreSQL",
5
+ "type": "database",
6
6
  "dependencies": {
7
- "drizzle-orm": "^0.41.0",
8
- "pg": "^8.13.0",
9
- "dotenv": "^17.3.1"
7
+ "drizzle-orm": "^0.45.2",
8
+ "pg": "^8.23.0",
9
+ "dotenv": "^17.4.2"
10
10
  },
11
- "devDependencies": { "drizzle-kit": "^0.31.4", "@types/pg": "^8.11.0" },
12
- "scripts": {
13
- "db:generate": "drizzle-kit generate",
14
- "db:migrate": "drizzle-kit migrate",
15
- "db:studio": "drizzle-kit studio"
16
- },
17
- "envVars": {
18
- "DATABASE_URL": "postgresql://user:password@localhost:5432/mydb?schema=public"
19
- },
20
- "templateFiles": ["lib/schema.ts.hbs"]
21
- }
11
+ "devDependencies": {
12
+ "drizzle-kit": "^0.31.10",
13
+ "@types/pg": "^8.23.1"
14
+ },
15
+ "scripts": {
16
+ "db:generate": "drizzle-kit generate",
17
+ "db:migrate": "drizzle-kit migrate",
18
+ "db:studio": "drizzle-kit studio"
19
+ },
20
+ "envVars": {
21
+ "DATABASE_URL": "postgresql://user:password@localhost:5432/mydb?schema=public"
22
+ },
23
+ "templateFiles": [
24
+ "lib/schema.ts.hbs"
25
+ ],
26
+ "overrides": {
27
+ "esbuild": "^0.28.2"
28
+ }
29
+ }
@@ -2,10 +2,12 @@ import { config } from "dotenv";
2
2
  import { drizzle } from "drizzle-orm/node-postgres";
3
3
  import { Pool } from "pg";
4
4
 
5
+ import * as schema from "./schema";
6
+
5
7
  config({ path: ".env" }); // or .env.local
6
8
 
7
9
  const pool = new Pool({
8
10
  connectionString: process.env.DATABASE_URL,
9
11
  });
10
12
 
11
- export const db = drizzle(pool);
13
+ export const db = drizzle(pool, { schema });