create-prisma 0.4.1 → 0.4.2-next.37.79.1

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 (119) hide show
  1. package/README.md +43 -35
  2. package/dist/cli.mjs +1 -1
  3. package/dist/{create-H6Tk0JlE.mjs → create-Btn7yJR3.mjs} +513 -913
  4. package/dist/index.d.mts +28 -25
  5. package/dist/index.mjs +3 -3
  6. package/package.json +2 -2
  7. package/templates/create/_shared/packages/db/prisma/seed.ts.hbs +43 -0
  8. package/templates/create/_shared/prisma/seed.ts.hbs +55 -0
  9. package/templates/create/astro/README.md.hbs +23 -12
  10. package/templates/create/astro/deno.json.hbs +1 -1
  11. package/templates/create/astro/prisma/contract.prisma.hbs +44 -0
  12. package/templates/create/astro/prisma/contract.ts.hbs +85 -0
  13. package/templates/create/astro/prisma-next.config.ts.hbs +13 -0
  14. package/templates/create/astro/src/lib/prisma.ts.hbs +49 -43
  15. package/templates/create/astro/src/pages/api/users.ts.hbs +5 -12
  16. package/templates/create/astro/src/pages/index.astro.hbs +19 -21
  17. package/templates/create/elysia/.yarnrc.yml.hbs +3 -0
  18. package/templates/create/elysia/README.md.hbs +27 -18
  19. package/templates/create/elysia/deno.json.hbs +1 -1
  20. package/templates/create/elysia/prisma/contract.prisma.hbs +44 -0
  21. package/templates/create/elysia/prisma/contract.ts.hbs +85 -0
  22. package/templates/create/elysia/prisma-next.config.ts.hbs +13 -0
  23. package/templates/create/elysia/src/index.ts.hbs +12 -7
  24. package/templates/create/elysia/src/lib/prisma.ts.hbs +49 -46
  25. package/templates/create/elysia/tsconfig.json +1 -0
  26. package/templates/create/hono/README.md.hbs +27 -18
  27. package/templates/create/hono/deno.json.hbs +1 -1
  28. package/templates/create/hono/prisma/contract.prisma.hbs +44 -0
  29. package/templates/create/hono/prisma/contract.ts.hbs +85 -0
  30. package/templates/create/hono/prisma-next.config.ts.hbs +13 -0
  31. package/templates/create/hono/src/index.ts.hbs +8 -6
  32. package/templates/create/hono/src/lib/prisma.ts.hbs +49 -46
  33. package/templates/create/hono/tsconfig.json +1 -0
  34. package/templates/create/nest/README.md.hbs +28 -18
  35. package/templates/create/nest/deno.json.hbs +1 -1
  36. package/templates/create/nest/prisma/contract.prisma.hbs +44 -0
  37. package/templates/create/nest/prisma/contract.ts.hbs +85 -0
  38. package/templates/create/nest/prisma-next.config.ts.hbs +13 -0
  39. package/templates/create/nest/src/lib/prisma.ts.hbs +49 -48
  40. package/templates/create/nest/src/prisma.service.ts.hbs +6 -5
  41. package/templates/create/nest/src/users.service.ts.hbs +1 -6
  42. package/templates/create/nest/tsconfig.json +1 -0
  43. package/templates/create/next/README.md.hbs +22 -11
  44. package/templates/create/next/deno.json.hbs +1 -1
  45. package/templates/create/next/prisma/contract.prisma.hbs +44 -0
  46. package/templates/create/next/prisma/contract.ts.hbs +85 -0
  47. package/templates/create/next/prisma-next.config.ts.hbs +13 -0
  48. package/templates/create/next/src/app/page.tsx.hbs +21 -26
  49. package/templates/create/next/src/lib/prisma.ts.hbs +49 -43
  50. package/templates/create/next/tsconfig.json +1 -0
  51. package/templates/create/nuxt/README.md.hbs +22 -11
  52. package/templates/create/nuxt/app/pages/index.vue.hbs +14 -12
  53. package/templates/create/nuxt/deno.json.hbs +1 -1
  54. package/templates/create/nuxt/nuxt.config.ts +16 -0
  55. package/templates/create/nuxt/prisma/contract.prisma.hbs +44 -0
  56. package/templates/create/nuxt/prisma/contract.ts.hbs +85 -0
  57. package/templates/create/nuxt/prisma-next.config.ts.hbs +13 -0
  58. package/templates/create/nuxt/server/api/users.get.ts.hbs +3 -9
  59. package/templates/create/nuxt/server/utils/prisma.ts.hbs +49 -43
  60. package/templates/create/svelte/README.md.hbs +23 -12
  61. package/templates/create/svelte/deno.json.hbs +1 -1
  62. package/templates/create/svelte/prisma/contract.prisma.hbs +44 -0
  63. package/templates/create/svelte/prisma/contract.ts.hbs +85 -0
  64. package/templates/create/svelte/prisma-next.config.ts.hbs +13 -0
  65. package/templates/create/svelte/src/lib/server/prisma.ts.hbs +50 -44
  66. package/templates/create/svelte/src/routes/+page.server.ts.hbs +3 -9
  67. package/templates/create/svelte/src/routes/+page.svelte.hbs +21 -16
  68. package/templates/create/tanstack-start/README.md.hbs +22 -11
  69. package/templates/create/tanstack-start/deno.json.hbs +1 -2
  70. package/templates/create/tanstack-start/prisma/contract.prisma.hbs +44 -0
  71. package/templates/create/tanstack-start/prisma/contract.ts.hbs +85 -0
  72. package/templates/create/tanstack-start/prisma-next.config.ts.hbs +13 -0
  73. package/templates/create/tanstack-start/src/lib/prisma.server.ts.hbs +49 -43
  74. package/templates/create/tanstack-start/src/routes/__root.tsx.hbs +2 -3
  75. package/templates/create/tanstack-start/src/routes/index.tsx.hbs +27 -38
  76. package/templates/create/tanstack-start/tsconfig.json +1 -0
  77. package/templates/create/turborepo/README.md.hbs +25 -14
  78. package/templates/create/turborepo/apps/api/deno.json.hbs +6 -0
  79. package/templates/create/turborepo/apps/api/package.json.hbs +7 -0
  80. package/templates/create/turborepo/apps/api/src/index.ts.hbs +6 -13
  81. package/templates/create/turborepo/deno.json.hbs +5 -1
  82. package/templates/create/turborepo/package.json.hbs +12 -4
  83. package/templates/create/turborepo/packages/db/deno.json.hbs +6 -0
  84. package/templates/create/turborepo/packages/db/package.json.hbs +5 -0
  85. package/templates/create/turborepo/packages/db/prisma/contract.prisma.hbs +44 -0
  86. package/templates/create/turborepo/packages/db/prisma/contract.ts.hbs +85 -0
  87. package/templates/create/turborepo/packages/db/prisma-next.config.ts.hbs +13 -0
  88. package/templates/create/turborepo/packages/db/src/client.ts.hbs +56 -44
  89. package/templates/create/turborepo/packages/db/src/index.ts +1 -1
  90. package/templates/create/turborepo/packages/db/tsconfig.json +2 -1
  91. package/templates/create/turborepo/pnpm-workspace.yaml.hbs +5 -0
  92. package/templates/create/turborepo/turbo.json +9 -3
  93. package/templates/create/astro/prisma/schema.prisma.hbs +0 -21
  94. package/templates/create/astro/prisma/seed.ts.hbs +0 -38
  95. package/templates/create/astro/prisma.config.ts +0 -13
  96. package/templates/create/elysia/prisma/schema.prisma.hbs +0 -25
  97. package/templates/create/elysia/prisma/seed.ts.hbs +0 -42
  98. package/templates/create/elysia/prisma.config.ts.hbs +0 -15
  99. package/templates/create/hono/prisma/schema.prisma.hbs +0 -25
  100. package/templates/create/hono/prisma/seed.ts.hbs +0 -42
  101. package/templates/create/hono/prisma.config.ts.hbs +0 -15
  102. package/templates/create/nest/prisma/schema.prisma.hbs +0 -25
  103. package/templates/create/nest/prisma/seed.ts.hbs +0 -44
  104. package/templates/create/nest/prisma.config.ts.hbs +0 -15
  105. package/templates/create/next/prisma/schema.prisma.hbs +0 -21
  106. package/templates/create/next/prisma/seed.ts.hbs +0 -38
  107. package/templates/create/next/prisma.config.ts +0 -13
  108. package/templates/create/nuxt/prisma/schema.prisma.hbs +0 -21
  109. package/templates/create/nuxt/prisma/seed.ts.hbs +0 -38
  110. package/templates/create/nuxt/prisma.config.ts +0 -13
  111. package/templates/create/svelte/prisma/schema.prisma.hbs +0 -21
  112. package/templates/create/svelte/prisma/seed.ts.hbs +0 -87
  113. package/templates/create/svelte/prisma.config.ts +0 -13
  114. package/templates/create/tanstack-start/prisma/schema.prisma.hbs +0 -21
  115. package/templates/create/tanstack-start/prisma/seed.ts.hbs +0 -37
  116. package/templates/create/tanstack-start/prisma.config.ts +0 -13
  117. package/templates/create/turborepo/packages/db/prisma/schema.prisma.hbs +0 -21
  118. package/templates/create/turborepo/packages/db/prisma/seed.ts.hbs +0 -38
  119. package/templates/create/turborepo/packages/db/prisma.config.ts +0 -13
@@ -0,0 +1,85 @@
1
+ {{#if (eq authoring "typescript")}}
2
+ {{#if (eq provider "mongo")}}
3
+ import mongoFamily from "@prisma-next/family-mongo/pack";
4
+ import { defineContract } from "@prisma-next/mongo-contract-ts/contract-builder";
5
+ import mongoTarget from "@prisma-next/target-mongo/pack";
6
+
7
+ export const contract = defineContract(
8
+ { family: mongoFamily, target: mongoTarget },
9
+ ({ field, index, model, rel }) => ({
10
+ models: {
11
+ {{#if (eq schemaPreset "basic")}}
12
+ User: model("User", {
13
+ collection: "users",
14
+ fields: {
15
+ _id: field.objectId(),
16
+ email: field.string(),
17
+ name: field.string().optional(),
18
+ },
19
+ indexes: [
20
+ index({ email: 1 }, { unique: true }),
21
+ ],
22
+ relations: {
23
+ posts: rel.hasMany("Post", { from: "_id", to: "authorId" }),
24
+ },
25
+ }),
26
+
27
+ Post: model("Post", {
28
+ collection: "posts",
29
+ fields: {
30
+ _id: field.objectId(),
31
+ title: field.string(),
32
+ content: field.string().optional(),
33
+ authorId: field.objectId(),
34
+ },
35
+ indexes: [
36
+ index({ authorId: 1 }),
37
+ ],
38
+ relations: {
39
+ author: rel.belongsTo("User", { from: "authorId", to: "_id" }),
40
+ },
41
+ }),
42
+ {{/if}}
43
+ },
44
+ }),
45
+ );
46
+ {{else}}
47
+ import sqlFamily from "@prisma-next/family-sql/pack";
48
+ import { defineContract } from "@prisma-next/sql-contract-ts/contract-builder";
49
+ import postgresPack from "@prisma-next/target-postgres/pack";
50
+
51
+ export const contract = defineContract(
52
+ { family: sqlFamily, target: postgresPack },
53
+ ({ field, model, rel }) => ({
54
+ models: {
55
+ {{#if (eq schemaPreset "basic")}}
56
+ User: model("User", {
57
+ fields: {
58
+ id: field.id.uuidv7(),
59
+ email: field.text().unique(),
60
+ name: field.text().optional(),
61
+ createdAt: field.createdAt(),
62
+ },
63
+ relations: {
64
+ posts: rel.hasMany("Post", { by: "authorId" }),
65
+ },
66
+ }),
67
+
68
+ Post: model("Post", {
69
+ fields: {
70
+ id: field.id.uuidv7(),
71
+ title: field.text(),
72
+ content: field.text().optional(),
73
+ authorId: field.uuid(),
74
+ createdAt: field.createdAt(),
75
+ },
76
+ relations: {
77
+ author: rel.belongsTo("User", { from: "authorId", to: "id" }),
78
+ },
79
+ }),
80
+ {{/if}}
81
+ },
82
+ }),
83
+ );
84
+ {{/if}}
85
+ {{/if}}
@@ -0,0 +1,13 @@
1
+ import "dotenv/config";
2
+ {{#if (eq provider "mongo")}}
3
+ import { defineConfig } from "@prisma-next/mongo/config";
4
+ {{else}}
5
+ import { defineConfig } from "@prisma-next/postgres/config";
6
+ {{/if}}
7
+
8
+ export default defineConfig({
9
+ contract: "./prisma/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}",
10
+ db: {
11
+ connection: process.env["DATABASE_URL"],
12
+ },
13
+ });
@@ -1,53 +1,59 @@
1
1
  import "dotenv/config";
2
- import { PrismaClient } from "../generated/prisma/client";
3
- {{#if (eq provider "postgresql")}}
4
- import { PrismaPg } from "@prisma/adapter-pg";
5
- {{/if}}
6
- {{#if (eq provider "cockroachdb")}}
7
- import { PrismaPg } from "@prisma/adapter-pg";
8
- {{/if}}
9
- {{#if (eq provider "mysql")}}
10
- import { PrismaMariaDb } from "@prisma/adapter-mariadb";
11
- {{/if}}
12
- {{#if (eq provider "sqlite")}}
13
- import { PrismaBetterSqlite3 } from "@prisma/adapter-better-sqlite3";
14
- {{/if}}
15
- {{#if (eq provider "sqlserver")}}
16
- import { PrismaMssql } from "@prisma/adapter-mssql";
17
- {{/if}}
18
-
19
- {{#if (eq provider "sqlite")}}
20
- const databaseUrl = process.env.DATABASE_URL ?? "file:./dev.db";
2
+ {{#if (eq provider "mongo")}}
3
+ import mongo from "@prisma-next/mongo/runtime";
21
4
  {{else}}
22
- const databaseUrl = process.env.DATABASE_URL;
23
- if (!databaseUrl) {
24
- throw new Error("DATABASE_URL is required");
25
- }
5
+ import postgres from "@prisma-next/postgres/runtime";
26
6
  {{/if}}
7
+ import type { Contract } from "../../prisma/contract.d";
8
+ import contractJson from "../../prisma/contract.json" with { type: "json" };
27
9
 
28
- {{#if (eq provider "postgresql")}}
29
- const adapter = new PrismaPg({
30
- connectionString: databaseUrl,
10
+ {{#if (eq provider "mongo")}}
11
+ export const db = mongo<Contract>({
12
+ contractJson,
13
+ url: process.env["DATABASE_URL"],
31
14
  });
32
- {{/if}}
33
- {{#if (eq provider "cockroachdb")}}
34
- const adapter = new PrismaPg({
35
- connectionString: databaseUrl,
15
+ {{else}}
16
+ export const db = postgres<Contract>({
17
+ contractJson,
18
+ url: process.env["DATABASE_URL"],
36
19
  });
37
20
  {{/if}}
38
- {{#if (eq provider "mysql")}}
39
- const adapter = new PrismaMariaDb(databaseUrl);
40
- {{/if}}
41
- {{#if (eq provider "sqlite")}}
42
- const adapter = new PrismaBetterSqlite3({
43
- url: databaseUrl,
44
- });
21
+
22
+ export type StarterUser = {
23
+ id: string;
24
+ email: string;
25
+ name: string | null;
26
+ createdAt: Date | null;
27
+ };
28
+
29
+ export async function listUsers(limit = 10): Promise<StarterUser[]> {
30
+ {{#if (eq schemaPreset "basic")}}
31
+ {{#if (eq provider "mongo")}}
32
+ const users: StarterUser[] = [];
33
+
34
+ for await (const user of db.orm.users.select("_id", "email", "name").take(limit).all()) {
35
+ users.push({
36
+ id: String(user._id),
37
+ email: user.email,
38
+ name: user.name ?? null,
39
+ createdAt: null,
40
+ });
41
+ }
42
+
43
+ return users;
44
+ {{else}}
45
+ const users = await db.orm.User.select("id", "email", "name", "createdAt").take(limit).all();
46
+
47
+ return users.map((user) => ({
48
+ id: String(user.id),
49
+ email: user.email,
50
+ name: user.name ?? null,
51
+ createdAt: user.createdAt,
52
+ }));
45
53
  {{/if}}
46
- {{#if (eq provider "sqlserver")}}
47
- const adapter = new PrismaMssql(databaseUrl);
54
+ {{else}}
55
+ return [];
48
56
  {{/if}}
57
+ }
49
58
 
50
- const prisma = new PrismaClient({ adapter });
51
-
52
- export { prisma };
53
- export default prisma;
59
+ export default db;
@@ -18,7 +18,7 @@ export const Route = createRootRoute({
18
18
  },
19
19
  {
20
20
  name: "description",
21
- content: "TanStack Start + Prisma starter generated by create-prisma.",
21
+ content: "TanStack Start + Prisma Next starter generated by create-prisma.",
22
22
  },
23
23
  ],
24
24
  links: [
@@ -42,7 +42,7 @@ function RootDocument({ children }: { children: ReactNode }) {
42
42
  <header className="topbar">
43
43
  <div>
44
44
  <p className="eyebrow">create-prisma</p>
45
- <h1>TanStack Start + Prisma</h1>
45
+ <h1>TanStack Start + Prisma Next</h1>
46
46
  </div>
47
47
 
48
48
  <nav className="nav">
@@ -68,4 +68,3 @@ function RootDocument({ children }: { children: ReactNode }) {
68
68
  </html>
69
69
  );
70
70
  }
71
-
@@ -1,34 +1,19 @@
1
1
  import { createFileRoute } from "@tanstack/react-router";
2
2
  import { createServerFn } from "@tanstack/react-start";
3
3
  {{#if (eq schemaPreset "basic")}}
4
- import { prisma } from "../lib/prisma.server";
4
+ import { listUsers as listStarterUsers } from "../lib/prisma.server";
5
5
  {{/if}}
6
6
 
7
7
  {{#if (eq schemaPreset "basic")}}
8
- function isBootstrapQueryError(error: unknown): error is { code?: string } {
9
- return (
10
- typeof error === "object" &&
11
- error !== null &&
12
- "code" in error &&
13
- (error as { code?: string }).code === "P2021"
14
- );
15
- }
16
-
17
8
  const listUsers = createServerFn({ method: "GET" }).handler(async () => {
18
- try {
19
- return await prisma.user.findMany({
20
- take: 10,
21
- orderBy: {
22
- createdAt: "desc",
23
- },
24
- });
25
- } catch (error) {
26
- if (isBootstrapQueryError(error)) {
27
- return undefined;
28
- }
29
-
30
- throw error;
31
- }
9
+ return listStarterUsers(10)
10
+ .then((rows) =>
11
+ rows.map((user) => ({
12
+ ...user,
13
+ createdAt: user.createdAt?.toISOString() ?? null,
14
+ }))
15
+ )
16
+ .catch(() => undefined);
32
17
  });
33
18
  {{/if}}
34
19
 
@@ -52,11 +37,11 @@ function Home() {
52
37
  return (
53
38
  <main className="shell">
54
39
  <div className="hero">
55
- <p className="eyebrow">TanStack Start + Prisma 7</p>
40
+ <p className="eyebrow">TanStack Start + Prisma Next</p>
56
41
  {{#if (eq schemaPreset "basic")}}
57
42
  <h1>Users from your database, loaded through a server function.</h1>
58
43
  <p className="lede">
59
- This route uses TanStack Start&apos;s server function API and the Prisma client in{" "}
44
+ This route uses TanStack Start&apos;s server function API and the Prisma Next helper in{" "}
60
45
  <code>src/lib/prisma.server.ts</code>.
61
46
  </p>
62
47
  </div>
@@ -69,11 +54,11 @@ function Home() {
69
54
 
70
55
  {!users ? (
71
56
  <p className="empty">
72
- Could not query users yet. Run <code>db:migrate</code>, then <code>db:seed</code>,
57
+ Could not query users yet. Run <code>contract:emit</code> and apply your schema,
73
58
  then refresh.
74
59
  </p>
75
60
  ) : users.length === 0 ? (
76
- <p className="empty">No users yet. Run <code>db:seed</code> after your first migration.</p>
61
+ <p className="empty">No users yet. Run db:seed after applying your first migration.</p>
77
62
  ) : (
78
63
  <ul className="users">
79
64
  {users.map((user) => (
@@ -82,9 +67,13 @@ function Home() {
82
67
  <strong>{user.name ?? "Unnamed user"}</strong>
83
68
  <p>{user.email}</p>
84
69
  </div>
85
- <time dateTime={user.createdAt.toISOString()}>
86
- {formatter.format(user.createdAt)}
87
- </time>
70
+ {user.createdAt ? (
71
+ <time dateTime={user.createdAt}>
72
+ {formatter.format(new Date(user.createdAt))}
73
+ </time>
74
+ ) : (
75
+ <span className="empty">No timestamp</span>
76
+ )}
88
77
  </li>
89
78
  ))}
90
79
  </ul>
@@ -93,8 +82,8 @@ function Home() {
93
82
  {{else}}
94
83
  <h1>Your TanStack Start app is ready.</h1>
95
84
  <p className="lede">
96
- Edit <code>prisma/schema.prisma</code>, run <code>db:migrate</code>, then query your
97
- database from server functions or route loaders.
85
+ Edit your Prisma Next contract, run <code>contract:emit</code>, then query your database
86
+ from server functions or route loaders.
98
87
  </p>
99
88
  </div>
100
89
 
@@ -113,14 +102,14 @@ function Home() {
113
102
  </li>
114
103
  <li>
115
104
  <div>
116
- <strong>Prisma client</strong>
117
- <p>Use the shared instance from <code>src/lib/prisma.server.ts</code>.</p>
105
+ <strong>Prisma Next runtime</strong>
106
+ <p>Use the shared helper from <code>src/lib/prisma.server.ts</code>.</p>
118
107
  </div>
119
108
  </li>
120
109
  <li>
121
110
  <div>
122
- <strong>Seed script</strong>
123
- <p>Run <code>db:seed</code> after your first migration.</p>
111
+ <strong>Manual database setup</strong>
112
+ <p>Run the schema setup commands when you are ready.</p>
124
113
  </div>
125
114
  </li>
126
115
  </ul>
@@ -133,7 +122,7 @@ function Home() {
133
122
  </div>
134
123
 
135
124
  <ul className="steps">
136
- <li>Run <code>db:generate</code> after schema changes.</li>
125
+ <li>Run <code>contract:emit</code> after contract changes.</li>
137
126
  <li>Use TanStack Start server functions for server-only logic.</li>
138
127
  <li>Preview production output with <code>preview</code>.</li>
139
128
  </ul>
@@ -4,6 +4,7 @@
4
4
  "jsx": "react-jsx",
5
5
  "module": "ESNext",
6
6
  "moduleResolution": "Bundler",
7
+ "resolveJsonModule": true,
7
8
  "allowImportingTsExtensions": true,
8
9
  "strict": true,
9
10
  "noEmit": true,
@@ -5,25 +5,36 @@ Generated by `create-prisma` with the Turborepo template.
5
5
  ## Structure
6
6
 
7
7
  - `apps/api` - Hono API app
8
- - `packages/db` - shared Prisma package
8
+ - `packages/db` - shared Prisma Next package
9
9
 
10
10
  ## Scripts
11
11
 
12
12
  - `{{runScriptCommand packageManager "dev"}}` - run API dev server through Turborepo
13
13
  - `{{runScriptCommand packageManager "build"}}` - run package builds through Turborepo
14
14
  - `{{runScriptCommand packageManager "typecheck"}}` - run TypeScript checks through Turborepo
15
- - `{{runScriptCommand packageManager "db:generate"}}` - generate Prisma Client in `packages/db`
16
- - `{{runScriptCommand packageManager "db:migrate"}}` - create/apply migrations in `packages/db`
17
- - `{{runScriptCommand packageManager "db:seed"}}` - run seed script in `packages/db`
18
-
19
- ## Prisma
20
-
21
- Prisma is scaffolded inside `packages/db`:
22
-
23
- - `packages/db/prisma/schema.prisma`
24
- - `packages/db/prisma/seed.ts`
15
+ - `{{runScriptCommand packageManager "contract:emit"}}` - emit Prisma Next contract artifacts in `packages/db`
16
+ {{#if (eq provider "mongo")}}
17
+ - `{{runScriptCommand packageManager "db:up"}}` - start the local MongoDB replica set
18
+ - `{{runScriptCommand packageManager "db:down"}}` - stop the local MongoDB replica set
19
+ - `{{runScriptCommand packageManager "migration:plan"}}` - create a MongoDB migration plan in `packages/db`
20
+ - `{{runScriptCommand packageManager "migration:apply"}}` - apply the planned MongoDB migration in `packages/db`
21
+ {{else}}
22
+ - `{{runScriptCommand packageManager "db:init"}}` - initialize database state manually in `packages/db`
23
+ - `{{runScriptCommand packageManager "migration:plan"}}` - create a migration plan in `packages/db`
24
+ - `{{runScriptCommand packageManager "migration:apply"}}` - apply a planned migration in `packages/db`
25
+ {{/if}}
26
+ {{#if (eq schemaPreset "basic")}}
27
+ - `{{runScriptCommand packageManager "db:seed"}}` - insert sample users manually in `packages/db`
28
+ {{/if}}
29
+
30
+ ## Prisma Next
31
+
32
+ Prisma Next is scaffolded inside `packages/db`:
33
+
34
+ - `packages/db/prisma/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}`
35
+ - `packages/db/prisma-next.config.ts`
25
36
  - `packages/db/src/client.ts`
26
- - `packages/db/prisma.config.ts`
27
- - `packages/db/src/generated/prisma`
28
37
 
29
- `apps/api/src/index.ts` imports the shared Prisma client from `@repo/db`.
38
+ `apps/api/src/index.ts` imports the shared Prisma Next helper from `@repo/db`.
39
+
40
+ Node-based Prisma Next projects expect Node.js 24 LTS or newer.
@@ -0,0 +1,6 @@
1
+ {{#if (eq packageManager "deno")}}
2
+ {
3
+ "name": "@repo/api",
4
+ "exports": "./src/index.ts"
5
+ }
6
+ {{/if}}
@@ -3,10 +3,17 @@
3
3
  "private": true,
4
4
  "type": "module",
5
5
  "scripts": {
6
+ {{#if (eq packageManager "deno")}}
7
+ "dev": "deno run -A --env-file=.env --watch src/index.ts",
8
+ "build": "deno check src/index.ts",
9
+ "start": "deno run -A --env-file=.env src/index.ts",
10
+ "typecheck": "deno check src/index.ts"
11
+ {{else}}
6
12
  "dev": "tsx watch src/index.ts",
7
13
  "build": "tsc",
8
14
  "start": "node dist/src/index.js",
9
15
  "typecheck": "tsc --noEmit"
16
+ {{/if}}
10
17
  },
11
18
  "dependencies": {
12
19
  "@hono/node-server": "^1.19.9",
@@ -4,7 +4,7 @@ import "dotenv/config";
4
4
  import { serve } from "@hono/node-server";
5
5
  import { Hono } from "hono";
6
6
  {{#if (eq schemaPreset "basic")}}
7
- import { prisma } from "@repo/db";
7
+ import { listUsers } from "@repo/db";
8
8
  {{/if}}
9
9
 
10
10
  const app = new Hono();
@@ -18,22 +18,15 @@ app.get("/", (c) => {
18
18
  {{#if (eq schemaPreset "basic")}}
19
19
 
20
20
  app.get("/users", async (c) => {
21
- const users = await prisma.user
22
- .findMany({
23
- take: 10,
24
- orderBy: {
25
- createdAt: "desc",
26
- },
27
- })
28
- .catch((error) => {
29
- console.error("Failed to query users:", error);
30
- return undefined;
31
- });
21
+ const users = await listUsers(10).catch((error) => {
22
+ console.error("Failed to query users:", error);
23
+ return undefined;
24
+ });
32
25
 
33
26
  if (!users) {
34
27
  return c.json(
35
28
  {
36
- error: "Could not query users yet. Run db:migrate and db:seed first.",
29
+ error: "Could not query users yet. Run contract:emit and apply your schema first.",
37
30
  },
38
31
  500
39
32
  );
@@ -1,5 +1,9 @@
1
1
  {{#if (eq packageManager "deno")}}
2
2
  {
3
- "nodeModulesDir": "auto"
3
+ "nodeModulesDir": "manual",
4
+ "workspace": [
5
+ "apps/*",
6
+ "packages/*"
7
+ ]
4
8
  }
5
9
  {{/if}}
@@ -10,13 +10,21 @@
10
10
  "packages/*"
11
11
  ],
12
12
  "scripts": {
13
+ {{#if (eq packageManager "deno")}}
14
+ "build": "deno task --filter=@repo/db build && deno task --filter=@repo/api build",
15
+ "dev": "deno task --filter=@repo/api dev",
16
+ "typecheck": "deno task --filter=@repo/db typecheck && deno task --filter=@repo/api typecheck",
17
+ {{else}}
13
18
  "build": "turbo run build",
14
19
  "dev": "turbo run dev --filter=@repo/api",
15
20
  "typecheck": "turbo run typecheck",
16
- "db:generate": "turbo run db:generate --filter=@repo/db",
17
- "db:push": "turbo run db:push --filter=@repo/db",
18
- "db:migrate": "turbo run db:migrate --filter=@repo/db",
19
- "db:seed": "turbo run db:seed --filter=@repo/db"
21
+ {{/if}}
22
+ "contract:emit": "{{runScriptInDirectoryCommand packageManager "packages/db" "contract:emit"}}",
23
+ "db:init": "{{runScriptInDirectoryCommand packageManager "packages/db" "db:init"}}",
24
+ "db:update": "{{runScriptInDirectoryCommand packageManager "packages/db" "db:update"}}",
25
+ "db:seed": "{{runScriptInDirectoryCommand packageManager "packages/db" "db:seed"}}",
26
+ "migration:plan": "{{runScriptInDirectoryCommandWithArgsPassthrough packageManager "packages/db" "migration:plan"}}",
27
+ "migration:apply": "{{runScriptInDirectoryCommand packageManager "packages/db" "migration:apply"}}"
20
28
  },
21
29
  "devDependencies": {
22
30
  "turbo": "^2.5.6"
@@ -0,0 +1,6 @@
1
+ {{#if (eq packageManager "deno")}}
2
+ {
3
+ "name": "@repo/db",
4
+ "exports": "./src/index.ts"
5
+ }
6
+ {{/if}}
@@ -6,8 +6,13 @@
6
6
  ".": "./src/index.ts"
7
7
  },
8
8
  "scripts": {
9
+ {{#if (eq packageManager "deno")}}
10
+ "build": "deno check src/index.ts",
11
+ "typecheck": "deno check src/index.ts"
12
+ {{else}}
9
13
  "build": "tsc",
10
14
  "typecheck": "tsc --noEmit"
15
+ {{/if}}
11
16
  },
12
17
  "devDependencies": {
13
18
  "@types/node": "^24.3.0",
@@ -0,0 +1,44 @@
1
+ {{#if (eq authoring "psl")}}
2
+ // use prisma-next
3
+ {{#if (eq schemaPreset "basic")}}
4
+ {{#if (eq provider "mongo")}}
5
+
6
+ model User {
7
+ id ObjectId @id @map("_id")
8
+ email String @unique
9
+ name String?
10
+ posts Post[]
11
+
12
+ @@map("users")
13
+ }
14
+
15
+ model Post {
16
+ id ObjectId @id @map("_id")
17
+ title String
18
+ content String?
19
+ author User @relation(fields: [authorId], references: [id])
20
+ authorId ObjectId
21
+
22
+ @@map("posts")
23
+ }
24
+ {{else}}
25
+
26
+ model User {
27
+ id Int @id @default(autoincrement())
28
+ email String @unique
29
+ name String?
30
+ posts Post[]
31
+ createdAt DateTime @default(now())
32
+ }
33
+
34
+ model Post {
35
+ id Int @id @default(autoincrement())
36
+ title String
37
+ content String?
38
+ author User @relation(fields: [authorId], references: [id])
39
+ authorId Int
40
+ createdAt DateTime @default(now())
41
+ }
42
+ {{/if}}
43
+ {{/if}}
44
+ {{/if}}
@@ -0,0 +1,85 @@
1
+ {{#if (eq authoring "typescript")}}
2
+ {{#if (eq provider "mongo")}}
3
+ import mongoFamily from "@prisma-next/family-mongo/pack";
4
+ import { defineContract } from "@prisma-next/mongo-contract-ts/contract-builder";
5
+ import mongoTarget from "@prisma-next/target-mongo/pack";
6
+
7
+ export const contract = defineContract(
8
+ { family: mongoFamily, target: mongoTarget },
9
+ ({ field, index, model, rel }) => ({
10
+ models: {
11
+ {{#if (eq schemaPreset "basic")}}
12
+ User: model("User", {
13
+ collection: "users",
14
+ fields: {
15
+ _id: field.objectId(),
16
+ email: field.string(),
17
+ name: field.string().optional(),
18
+ },
19
+ indexes: [
20
+ index({ email: 1 }, { unique: true }),
21
+ ],
22
+ relations: {
23
+ posts: rel.hasMany("Post", { from: "_id", to: "authorId" }),
24
+ },
25
+ }),
26
+
27
+ Post: model("Post", {
28
+ collection: "posts",
29
+ fields: {
30
+ _id: field.objectId(),
31
+ title: field.string(),
32
+ content: field.string().optional(),
33
+ authorId: field.objectId(),
34
+ },
35
+ indexes: [
36
+ index({ authorId: 1 }),
37
+ ],
38
+ relations: {
39
+ author: rel.belongsTo("User", { from: "authorId", to: "_id" }),
40
+ },
41
+ }),
42
+ {{/if}}
43
+ },
44
+ }),
45
+ );
46
+ {{else}}
47
+ import sqlFamily from "@prisma-next/family-sql/pack";
48
+ import { defineContract } from "@prisma-next/sql-contract-ts/contract-builder";
49
+ import postgresPack from "@prisma-next/target-postgres/pack";
50
+
51
+ export const contract = defineContract(
52
+ { family: sqlFamily, target: postgresPack },
53
+ ({ field, model, rel }) => ({
54
+ models: {
55
+ {{#if (eq schemaPreset "basic")}}
56
+ User: model("User", {
57
+ fields: {
58
+ id: field.id.uuidv7(),
59
+ email: field.text().unique(),
60
+ name: field.text().optional(),
61
+ createdAt: field.createdAt(),
62
+ },
63
+ relations: {
64
+ posts: rel.hasMany("Post", { by: "authorId" }),
65
+ },
66
+ }),
67
+
68
+ Post: model("Post", {
69
+ fields: {
70
+ id: field.id.uuidv7(),
71
+ title: field.text(),
72
+ content: field.text().optional(),
73
+ authorId: field.uuid(),
74
+ createdAt: field.createdAt(),
75
+ },
76
+ relations: {
77
+ author: rel.belongsTo("User", { from: "authorId", to: "id" }),
78
+ },
79
+ }),
80
+ {{/if}}
81
+ },
82
+ }),
83
+ );
84
+ {{/if}}
85
+ {{/if}}