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.
- package/README.md +43 -35
- package/dist/cli.mjs +1 -1
- package/dist/{create-H6Tk0JlE.mjs → create-CfH21J9-.mjs} +529 -914
- package/dist/index.d.mts +28 -25
- package/dist/index.mjs +3 -3
- package/package.json +2 -2
- package/templates/create/_shared/packages/db/prisma/seed.ts.hbs +43 -0
- package/templates/create/_shared/prisma/seed.ts.hbs +55 -0
- package/templates/create/astro/README.md.hbs +23 -12
- package/templates/create/astro/deno.json.hbs +1 -1
- package/templates/create/astro/prisma/contract.prisma.hbs +44 -0
- package/templates/create/astro/prisma/contract.ts.hbs +85 -0
- package/templates/create/astro/prisma-next.config.ts.hbs +13 -0
- package/templates/create/astro/src/lib/prisma.ts.hbs +49 -43
- package/templates/create/astro/src/pages/api/users.ts.hbs +5 -12
- package/templates/create/astro/src/pages/index.astro.hbs +19 -21
- package/templates/create/elysia/.yarnrc.yml.hbs +3 -0
- package/templates/create/elysia/README.md.hbs +27 -18
- package/templates/create/elysia/deno.json.hbs +1 -1
- package/templates/create/elysia/prisma/contract.prisma.hbs +44 -0
- package/templates/create/elysia/prisma/contract.ts.hbs +85 -0
- package/templates/create/elysia/prisma-next.config.ts.hbs +13 -0
- package/templates/create/elysia/src/index.ts.hbs +12 -7
- package/templates/create/elysia/src/lib/prisma.ts.hbs +49 -46
- package/templates/create/elysia/tsconfig.json +1 -0
- package/templates/create/hono/README.md.hbs +27 -18
- package/templates/create/hono/deno.json.hbs +1 -1
- package/templates/create/hono/prisma/contract.prisma.hbs +44 -0
- package/templates/create/hono/prisma/contract.ts.hbs +85 -0
- package/templates/create/hono/prisma-next.config.ts.hbs +13 -0
- package/templates/create/hono/src/index.ts.hbs +8 -6
- package/templates/create/hono/src/lib/prisma.ts.hbs +49 -46
- package/templates/create/hono/tsconfig.json +1 -0
- package/templates/create/nest/README.md.hbs +28 -18
- package/templates/create/nest/deno.json.hbs +1 -1
- package/templates/create/nest/prisma/contract.prisma.hbs +44 -0
- package/templates/create/nest/prisma/contract.ts.hbs +85 -0
- package/templates/create/nest/prisma-next.config.ts.hbs +13 -0
- package/templates/create/nest/src/lib/prisma.ts.hbs +49 -48
- package/templates/create/nest/src/prisma.service.ts.hbs +6 -5
- package/templates/create/nest/src/users.service.ts.hbs +1 -6
- package/templates/create/nest/tsconfig.json +1 -0
- package/templates/create/next/README.md.hbs +22 -11
- package/templates/create/next/deno.json.hbs +1 -1
- package/templates/create/next/prisma/contract.prisma.hbs +44 -0
- package/templates/create/next/prisma/contract.ts.hbs +85 -0
- package/templates/create/next/prisma-next.config.ts.hbs +13 -0
- package/templates/create/next/src/app/page.tsx.hbs +21 -26
- package/templates/create/next/src/lib/prisma.ts.hbs +49 -43
- package/templates/create/next/tsconfig.json +1 -0
- package/templates/create/nuxt/README.md.hbs +22 -11
- package/templates/create/nuxt/app/pages/index.vue.hbs +14 -12
- package/templates/create/nuxt/deno.json.hbs +1 -1
- package/templates/create/nuxt/nuxt.config.ts +16 -0
- package/templates/create/nuxt/prisma/contract.prisma.hbs +44 -0
- package/templates/create/nuxt/prisma/contract.ts.hbs +85 -0
- package/templates/create/nuxt/prisma-next.config.ts.hbs +13 -0
- package/templates/create/nuxt/server/api/users.get.ts.hbs +3 -9
- package/templates/create/nuxt/server/utils/prisma.ts.hbs +49 -43
- package/templates/create/svelte/README.md.hbs +23 -12
- package/templates/create/svelte/deno.json.hbs +1 -1
- package/templates/create/svelte/prisma/contract.prisma.hbs +44 -0
- package/templates/create/svelte/prisma/contract.ts.hbs +85 -0
- package/templates/create/svelte/prisma-next.config.ts.hbs +13 -0
- package/templates/create/svelte/src/lib/server/prisma.ts.hbs +50 -44
- package/templates/create/svelte/src/routes/+page.server.ts.hbs +3 -9
- package/templates/create/svelte/src/routes/+page.svelte.hbs +21 -16
- package/templates/create/tanstack-start/README.md.hbs +22 -11
- package/templates/create/tanstack-start/deno.json.hbs +1 -2
- package/templates/create/tanstack-start/prisma/contract.prisma.hbs +44 -0
- package/templates/create/tanstack-start/prisma/contract.ts.hbs +85 -0
- package/templates/create/tanstack-start/prisma-next.config.ts.hbs +13 -0
- package/templates/create/tanstack-start/src/lib/prisma.server.ts.hbs +49 -43
- package/templates/create/tanstack-start/src/routes/__root.tsx.hbs +2 -3
- package/templates/create/tanstack-start/src/routes/index.tsx.hbs +27 -38
- package/templates/create/tanstack-start/tsconfig.json +1 -0
- package/templates/create/turborepo/README.md.hbs +25 -14
- package/templates/create/turborepo/apps/api/deno.json.hbs +6 -0
- package/templates/create/turborepo/apps/api/package.json.hbs +7 -0
- package/templates/create/turborepo/apps/api/src/index.ts.hbs +6 -13
- package/templates/create/turborepo/deno.json.hbs +5 -1
- package/templates/create/turborepo/package.json.hbs +12 -4
- package/templates/create/turborepo/packages/db/deno.json.hbs +6 -0
- package/templates/create/turborepo/packages/db/package.json.hbs +5 -0
- package/templates/create/turborepo/packages/db/prisma/contract.prisma.hbs +44 -0
- package/templates/create/turborepo/packages/db/prisma/contract.ts.hbs +85 -0
- package/templates/create/turborepo/packages/db/prisma-next.config.ts.hbs +13 -0
- package/templates/create/turborepo/packages/db/src/client.ts.hbs +56 -44
- package/templates/create/turborepo/packages/db/src/index.ts +1 -1
- package/templates/create/turborepo/packages/db/tsconfig.json +2 -1
- package/templates/create/turborepo/pnpm-workspace.yaml.hbs +5 -0
- package/templates/create/turborepo/turbo.json +9 -3
- package/templates/create/astro/prisma/schema.prisma.hbs +0 -21
- package/templates/create/astro/prisma/seed.ts.hbs +0 -38
- package/templates/create/astro/prisma.config.ts +0 -13
- package/templates/create/elysia/prisma/schema.prisma.hbs +0 -25
- package/templates/create/elysia/prisma/seed.ts.hbs +0 -42
- package/templates/create/elysia/prisma.config.ts.hbs +0 -15
- package/templates/create/hono/prisma/schema.prisma.hbs +0 -25
- package/templates/create/hono/prisma/seed.ts.hbs +0 -42
- package/templates/create/hono/prisma.config.ts.hbs +0 -15
- package/templates/create/nest/prisma/schema.prisma.hbs +0 -25
- package/templates/create/nest/prisma/seed.ts.hbs +0 -44
- package/templates/create/nest/prisma.config.ts.hbs +0 -15
- package/templates/create/next/prisma/schema.prisma.hbs +0 -21
- package/templates/create/next/prisma/seed.ts.hbs +0 -38
- package/templates/create/next/prisma.config.ts +0 -13
- package/templates/create/nuxt/prisma/schema.prisma.hbs +0 -21
- package/templates/create/nuxt/prisma/seed.ts.hbs +0 -38
- package/templates/create/nuxt/prisma.config.ts +0 -13
- package/templates/create/svelte/prisma/schema.prisma.hbs +0 -21
- package/templates/create/svelte/prisma/seed.ts.hbs +0 -87
- package/templates/create/svelte/prisma.config.ts +0 -13
- package/templates/create/tanstack-start/prisma/schema.prisma.hbs +0 -21
- package/templates/create/tanstack-start/prisma/seed.ts.hbs +0 -37
- package/templates/create/tanstack-start/prisma.config.ts +0 -13
- package/templates/create/turborepo/packages/db/prisma/schema.prisma.hbs +0 -21
- package/templates/create/turborepo/packages/db/prisma/seed.ts.hbs +0 -38
- 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
|
|
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
|
|
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
|
|
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>
|
|
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
|
|
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
|
-
|
|
59
|
-
{
|
|
60
|
-
|
|
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
|
|
70
|
-
in server components with the
|
|
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
|
|
84
|
-
<p>Use the shared
|
|
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>
|
|
90
|
-
<p>Run
|
|
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>
|
|
96
|
-
<p>Prisma
|
|
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
|
-
|
|
3
|
-
|
|
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
|
-
|
|
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 "
|
|
29
|
-
const
|
|
30
|
-
|
|
10
|
+
{{#if (eq provider "mongo")}}
|
|
11
|
+
export const db = mongo<Contract>({
|
|
12
|
+
contractJson,
|
|
13
|
+
url: process.env["DATABASE_URL"],
|
|
31
14
|
});
|
|
32
|
-
{{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
15
|
+
{{else}}
|
|
16
|
+
export const db = postgres<Contract>({
|
|
17
|
+
contractJson,
|
|
18
|
+
url: process.env["DATABASE_URL"],
|
|
36
19
|
});
|
|
37
20
|
{{/if}}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
{{
|
|
47
|
-
|
|
54
|
+
{{else}}
|
|
55
|
+
return [];
|
|
48
56
|
{{/if}}
|
|
57
|
+
}
|
|
49
58
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
export { prisma };
|
|
53
|
-
export default prisma;
|
|
59
|
+
export default db;
|
|
@@ -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
|
|
14
|
+
Prisma Next setup is scaffolded in:
|
|
15
15
|
|
|
16
|
-
- `prisma/
|
|
17
|
-
- `prisma
|
|
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
|
-
- `
|
|
26
|
-
|
|
27
|
-
- `db:
|
|
28
|
-
- `db:
|
|
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
|
|
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
|
|
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
|
|
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>
|
|
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
|
|
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
|
|
70
|
-
Nitro routes or server utilities with the
|
|
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
|
|
84
|
-
<p>Use the shared server
|
|
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>
|
|
96
|
-
<p>Prisma
|
|
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;
|
|
@@ -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
|
|
2
|
+
import { listUsers } from "../utils/prisma";
|
|
3
3
|
|
|
4
4
|
export default defineEventHandler(async () => {
|
|
5
|
-
const users = await
|
|
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
|
|
9
|
+
createdAt: user.createdAt?.toISOString() ?? null,
|
|
16
10
|
}))
|
|
17
11
|
)
|
|
18
12
|
.catch((error) => {
|