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.
- package/README.md +43 -35
- package/dist/cli.mjs +1 -1
- package/dist/{create-H6Tk0JlE.mjs → create-Btn7yJR3.mjs} +513 -913
- 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,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;
|
|
@@ -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 {
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
createdAt:
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
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
|
|
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's server function API and the Prisma
|
|
44
|
+
This route uses TanStack Start'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>
|
|
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
|
|
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
|
-
|
|
86
|
-
{
|
|
87
|
-
|
|
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
|
|
97
|
-
|
|
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
|
|
117
|
-
<p>Use the shared
|
|
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>
|
|
123
|
-
<p>Run
|
|
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>
|
|
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>
|
|
@@ -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 "
|
|
16
|
-
|
|
17
|
-
- `{{runScriptCommand packageManager "db:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- `packages/db
|
|
24
|
-
- `packages/db
|
|
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
|
|
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.
|
|
@@ -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 {
|
|
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
|
|
22
|
-
.
|
|
23
|
-
|
|
24
|
-
|
|
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
|
|
29
|
+
error: "Could not query users yet. Run contract:emit and apply your schema first.",
|
|
37
30
|
},
|
|
38
31
|
500
|
|
39
32
|
);
|
|
@@ -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
|
-
|
|
17
|
-
"
|
|
18
|
-
"db:
|
|
19
|
-
"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"
|
|
@@ -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}}
|