create-prisma 0.4.1 → 0.4.2-next.37.80.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-CfH21J9-.mjs} +529 -914
  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,6 +1,3 @@
1
- {{#if (eq schemaPreset "basic")}}
2
- import { prisma } from "../lib/prisma";
3
- {{/if}}
4
1
  {{#if (eq packageManager "deno")}}
5
2
 
6
3
  export const dynamic = "force-dynamic";
@@ -8,28 +5,22 @@ export const dynamic = "force-dynamic";
8
5
 
9
6
  export default async function Home() {
10
7
  {{#if (eq schemaPreset "basic")}}
8
+ const { listUsers } = await import("../lib/prisma");
11
9
  const formatter = new Intl.DateTimeFormat("en", {
12
10
  dateStyle: "medium",
13
11
  timeStyle: "short",
14
12
  });
15
- const users = await prisma.user
16
- .findMany({
17
- take: 10,
18
- orderBy: {
19
- createdAt: "desc",
20
- },
21
- })
22
- .catch(() => undefined);
13
+ const users = await listUsers(10).catch(() => undefined);
23
14
  {{/if}}
24
15
 
25
16
  return (
26
17
  <main className="shell">
27
18
  <div className="hero">
28
- <p className="eyebrow">Next.js + Prisma 7</p>
19
+ <p className="eyebrow">Next.js + Prisma Next</p>
29
20
  {{#if (eq schemaPreset "basic")}}
30
21
  <h1>Users from your database, loaded on the server.</h1>
31
22
  <p className="lede">
32
- This page reads from <code>src/app/page.tsx</code> using the Prisma instance in{" "}
23
+ This page reads from <code>src/app/page.tsx</code> using the Prisma Next helper in{" "}
33
24
  <code>src/lib/prisma.ts</code>.
34
25
  </p>
35
26
  </div>
@@ -42,11 +33,11 @@ export default async function Home() {
42
33
 
43
34
  {!users ? (
44
35
  <p className="empty">
45
- Could not query users yet. Run <code>db:migrate</code>, then <code>db:seed</code>,
36
+ Could not query users yet. Run <code>contract:emit</code> and apply your schema,
46
37
  then refresh.
47
38
  </p>
48
39
  ) : users.length === 0 ? (
49
- <p className="empty">No users yet. Run <code>db:seed</code> after your first migration.</p>
40
+ <p className="empty">No users yet. Run db:seed after applying your first migration.</p>
50
41
  ) : (
51
42
  <ul className="users">
52
43
  {users.map((user) => (
@@ -55,9 +46,13 @@ export default async function Home() {
55
46
  <strong>{user.name ?? "Unnamed user"}</strong>
56
47
  <p>{user.email}</p>
57
48
  </div>
58
- <time dateTime={user.createdAt.toISOString()}>
59
- {formatter.format(user.createdAt)}
60
- </time>
49
+ {user.createdAt ? (
50
+ <time dateTime={user.createdAt.toISOString()}>
51
+ {formatter.format(user.createdAt)}
52
+ </time>
53
+ ) : (
54
+ <span className="empty">No timestamp</span>
55
+ )}
61
56
  </li>
62
57
  ))}
63
58
  </ul>
@@ -66,8 +61,8 @@ export default async function Home() {
66
61
  {{else}}
67
62
  <h1>Your Next.js app is ready.</h1>
68
63
  <p className="lede">
69
- Edit <code>prisma/schema.prisma</code>, run <code>db:migrate</code>, then load your data
70
- in server components with the Prisma instance in <code>src/lib/prisma.ts</code>.
64
+ Edit your Prisma Next contract, run <code>contract:emit</code>, then load your data
65
+ in server components with the helper in <code>src/lib/prisma.ts</code>.
71
66
  </p>
72
67
  </div>
73
68
 
@@ -80,20 +75,20 @@ export default async function Home() {
80
75
  <ul className="users">
81
76
  <li>
82
77
  <div>
83
- <strong>Prisma client</strong>
84
- <p>Use the shared instance from <code>src/lib/prisma.ts</code>.</p>
78
+ <strong>Prisma Next runtime</strong>
79
+ <p>Use the shared helper from <code>src/lib/prisma.ts</code>.</p>
85
80
  </div>
86
81
  </li>
87
82
  <li>
88
83
  <div>
89
- <strong>Seed script</strong>
90
- <p>Run <code>db:seed</code> after your first migration.</p>
84
+ <strong>Manual database setup</strong>
85
+ <p>Run the schema setup commands when you are ready.</p>
91
86
  </div>
92
87
  </li>
93
88
  <li>
94
89
  <div>
95
- <strong>Generated client output</strong>
96
- <p>Prisma Client is generated into <code>src/generated/prisma</code>.</p>
90
+ <strong>Contract output</strong>
91
+ <p>Prisma Next emits contract artifacts next to your contract file.</p>
97
92
  </div>
98
93
  </li>
99
94
  </ul>
@@ -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;
@@ -9,6 +9,7 @@
9
9
  "esModuleInterop": true,
10
10
  "module": "esnext",
11
11
  "moduleResolution": "bundler",
12
+ "allowImportingTsExtensions": true,
12
13
  "resolveJsonModule": true,
13
14
  "isolatedModules": true,
14
15
  "jsx": "react-jsx",
@@ -9,24 +9,35 @@ Generated by `create-prisma` with the Nuxt template.
9
9
  - `{{runScriptCommand packageManager "preview"}}` - preview the production build
10
10
  - `{{runScriptCommand packageManager "typecheck"}}` - run Nuxt type checks
11
11
 
12
- ## Prisma
12
+ ## Prisma Next
13
13
 
14
- Prisma setup is scaffolded automatically in:
14
+ Prisma Next setup is scaffolded in:
15
15
 
16
- - `prisma/schema.prisma`
17
- - `prisma/seed.ts`
16
+ - `prisma/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}`
17
+ - `prisma-next.config.ts`
18
18
  - `server/utils/prisma.ts`
19
19
  - `server/api/users.get.ts`
20
- - `prisma.config.ts`
21
- - `server/generated/prisma`
22
20
 
23
21
  Database helper scripts are added to `package.json`:
24
22
 
25
- - `db:generate`
26
- - `db:push`
27
- - `db:migrate`
28
- - `db:seed`
23
+ - `{{runScriptCommand packageManager "contract:emit"}}` - emit contract artifacts after contract changes
24
+ {{#if (eq provider "mongo")}}
25
+ - `{{runScriptCommand packageManager "db:up"}}` - start the local MongoDB replica set
26
+ - `{{runScriptCommand packageManager "db:down"}}` - stop the local MongoDB replica set
27
+ - `{{runScriptCommand packageManager "migration:plan"}}` - create a MongoDB migration plan
28
+ - `{{runScriptCommand packageManager "migration:apply"}}` - apply the planned MongoDB migration
29
+ {{else}}
30
+ - `{{runScriptCommand packageManager "db:init"}}` - initialize database state manually
31
+ - `{{runScriptCommand packageManager "db:update"}}` - update database state manually
32
+ - `{{runScriptCommand packageManager "migration:plan"}}` - create a migration plan
33
+ - `{{runScriptCommand packageManager "migration:apply"}}` - apply a planned migration
34
+ {{/if}}
35
+ {{#if (eq schemaPreset "basic")}}
36
+ - `{{runScriptCommand packageManager "db:seed"}}` - insert sample users manually
37
+ {{/if}}
38
+
39
+ Node-based Prisma Next projects expect Node.js 24 LTS or newer.
29
40
  {{#if (eq schemaPreset "basic")}}
30
41
 
31
- The starter page in `app/pages/index.vue` fetches seeded users from `server/api/users.get.ts`, and `prisma/seed.ts` inserts starter users.
42
+ The starter page in `app/pages/index.vue` fetches users from `server/api/users.get.ts` after you initialize and apply your schema.
32
43
  {{/if}}
@@ -8,7 +8,7 @@ type User = {
8
8
  id: string;
9
9
  email: string;
10
10
  name: string | null;
11
- createdAt: string;
11
+ createdAt: string | null;
12
12
  };
13
13
 
14
14
  type UsersPayload = {
@@ -32,12 +32,12 @@ function formatCreatedAt(value: string): string {
32
32
  <template>
33
33
  <main class="shell">
34
34
  <div class="hero">
35
- <p class="eyebrow">Nuxt + Prisma 7</p>
35
+ <p class="eyebrow">Nuxt + Prisma Next</p>
36
36
  {{#if (eq schemaPreset "basic")}}
37
37
  <h1>Users from your database, loaded through Nitro.</h1>
38
38
  <p class="lede">
39
39
  This page fetches <code>/api/users</code> from <code>server/api/users.get.ts</code> using
40
- the Prisma instance in <code>server/utils/prisma.ts</code>.
40
+ the Prisma Next helper in <code>server/utils/prisma.ts</code>.
41
41
  </p>
42
42
  </div>
43
43
 
@@ -48,10 +48,10 @@ function formatCreatedAt(value: string): string {
48
48
  </div>
49
49
 
50
50
  <p v-if="data?.error" class="empty">
51
- \{{ data.error }} Run <code>db:migrate</code>, then <code>db:seed</code>, then refresh.
51
+ \{{ data.error }} Run <code>contract:emit</code> and apply your schema, then refresh.
52
52
  </p>
53
53
  <p v-else-if="!data?.users?.length" class="empty">
54
- No users yet. Run <code>db:seed</code> after your first migration.
54
+ No users yet. Run db:seed after applying your first migration.
55
55
  </p>
56
56
  <ul v-else class="users">
57
57
  <li v-for="user in data.users" :key="user.id">
@@ -59,15 +59,16 @@ function formatCreatedAt(value: string): string {
59
59
  <strong>\{{ user.name ?? "Unnamed user" }}</strong>
60
60
  <p>\{{ user.email }}</p>
61
61
  </div>
62
- <time :datetime="user.createdAt">\{{ formatCreatedAt(user.createdAt) }}</time>
62
+ <time v-if="user.createdAt" :datetime="user.createdAt">\{{ formatCreatedAt(user.createdAt) }}</time>
63
+ <span v-else class="muted">No timestamp</span>
63
64
  </li>
64
65
  </ul>
65
66
  </section>
66
67
  {{else}}
67
68
  <h1>Your Nuxt app is ready.</h1>
68
69
  <p class="lede">
69
- Edit <code>prisma/schema.prisma</code>, run <code>db:migrate</code>, then query data in
70
- Nitro routes or server utilities with the Prisma instance in <code>server/utils/prisma.ts</code>.
70
+ Edit your Prisma Next contract, run <code>contract:emit</code>, then query data in
71
+ Nitro routes or server utilities with the helper in <code>server/utils/prisma.ts</code>.
71
72
  </p>
72
73
  </div>
73
74
 
@@ -80,8 +81,8 @@ function formatCreatedAt(value: string): string {
80
81
  <ul class="users">
81
82
  <li>
82
83
  <div>
83
- <strong>Prisma client</strong>
84
- <p>Use the shared server instance from <code>server/utils/prisma.ts</code>.</p>
84
+ <strong>Prisma Next runtime</strong>
85
+ <p>Use the shared server helper from <code>server/utils/prisma.ts</code>.</p>
85
86
  </div>
86
87
  </li>
87
88
  <li>
@@ -92,8 +93,8 @@ function formatCreatedAt(value: string): string {
92
93
  </li>
93
94
  <li>
94
95
  <div>
95
- <strong>Generated client output</strong>
96
- <p>Prisma Client is generated into <code>server/generated/prisma</code>.</p>
96
+ <strong>Contract output</strong>
97
+ <p>Prisma Next emits contract artifacts next to your contract file.</p>
97
98
  </div>
98
99
  </li>
99
100
  </ul>
@@ -165,6 +166,7 @@ h2 {
165
166
 
166
167
  .panel-header span,
167
168
  .empty,
169
+ .muted,
168
170
  time {
169
171
  color: #888;
170
172
  font-size: 0.8rem;
@@ -1,5 +1,5 @@
1
1
  {{#if (eq packageManager "deno")}}
2
2
  {
3
- "nodeModulesDir": "auto"
3
+ "nodeModulesDir": "manual"
4
4
  }
5
5
  {{/if}}
@@ -2,4 +2,20 @@
2
2
  export default defineNuxtConfig({
3
3
  compatibilityDate: "2025-07-15",
4
4
  devtools: { enabled: true },
5
+ typescript: {
6
+ tsConfig: {
7
+ compilerOptions: {
8
+ allowImportingTsExtensions: true,
9
+ },
10
+ },
11
+ },
12
+ nitro: {
13
+ typescript: {
14
+ tsConfig: {
15
+ compilerOptions: {
16
+ allowImportingTsExtensions: true,
17
+ },
18
+ },
19
+ },
20
+ },
5
21
  });
@@ -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}}
@@ -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,18 +1,12 @@
1
1
  {{#if (eq schemaPreset "basic")}}
2
- import prisma from "../utils/prisma";
2
+ import { listUsers } from "../utils/prisma";
3
3
 
4
4
  export default defineEventHandler(async () => {
5
- const users = await prisma.user
6
- .findMany({
7
- take: 10,
8
- orderBy: {
9
- createdAt: "desc",
10
- },
11
- })
5
+ const users = await listUsers(10)
12
6
  .then((rows) =>
13
7
  rows.map((user) => ({
14
8
  ...user,
15
- createdAt: user.createdAt.toISOString(),
9
+ createdAt: user.createdAt?.toISOString() ?? null,
16
10
  }))
17
11
  )
18
12
  .catch((error) => {