create-prisma 0.4.1 → 0.4.2-next.37.102.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 +50 -44
- package/dist/cli.mjs +1 -1
- package/dist/{create-H6Tk0JlE.mjs → create-DsDWZbPE.mjs} +875 -1010
- package/dist/index.d.mts +30 -39
- package/dist/index.mjs +3 -3
- package/package.json +7 -2
- package/templates/create/_shared/prisma/seed.ts.hbs +52 -0
- package/templates/create/astro/README.md.hbs +25 -15
- package/templates/create/astro/astro.config.mjs +6 -1
- package/templates/create/astro/deno.json.hbs +1 -1
- package/templates/create/astro/package.json.hbs +3 -2
- package/templates/create/astro/src/lib/prisma.ts.hbs +60 -40
- package/templates/create/astro/src/pages/api/users.ts.hbs +6 -22
- package/templates/create/astro/src/pages/index.astro.hbs +18 -55
- package/templates/create/elysia/README.md.hbs +27 -17
- package/templates/create/elysia/deno.json.hbs +1 -1
- package/templates/create/elysia/src/index.ts.hbs +15 -11
- package/templates/create/elysia/src/lib/prisma.ts.hbs +60 -43
- package/templates/create/elysia/tsconfig.json +1 -0
- package/templates/create/hono/README.md.hbs +27 -17
- package/templates/create/hono/deno.json.hbs +1 -1
- package/templates/create/hono/src/index.ts.hbs +9 -10
- package/templates/create/hono/src/lib/prisma.ts.hbs +60 -43
- package/templates/create/hono/tsconfig.json +1 -0
- package/templates/create/minimal/.yarnrc.yml.hbs +3 -0
- package/templates/create/minimal/README.md.hbs +39 -0
- package/templates/create/{turborepo → minimal}/deno.json.hbs +1 -1
- package/templates/create/minimal/package.json.hbs +13 -0
- package/templates/create/minimal/src/index.ts.hbs +43 -0
- package/templates/create/minimal/src/lib/prisma.ts.hbs +73 -0
- package/templates/create/{turborepo/apps/api → minimal}/tsconfig.json +3 -4
- package/templates/create/nest/README.md.hbs +28 -17
- package/templates/create/nest/deno.json.hbs +1 -1
- package/templates/create/nest/src/app.module.ts.hbs +5 -6
- package/templates/create/nest/src/lib/prisma.ts.hbs +60 -45
- package/templates/create/nest/src/prisma.service.ts.hbs +6 -5
- package/templates/create/nest/src/users.controller.ts.hbs +1 -2
- package/templates/create/nest/src/users.service.ts.hbs +2 -8
- package/templates/create/nest/tsconfig.json +1 -0
- package/templates/create/next/README.md.hbs +25 -13
- package/templates/create/next/deno.json.hbs +1 -1
- package/templates/create/next/src/app/page.tsx.hbs +16 -57
- package/templates/create/next/src/lib/prisma.ts.hbs +60 -40
- package/templates/create/next/tsconfig.json +1 -0
- package/templates/create/nuxt/README.md.hbs +26 -13
- package/templates/create/nuxt/app/pages/index.vue.hbs +12 -45
- package/templates/create/nuxt/deno.json.hbs +1 -1
- package/templates/create/nuxt/nuxt.config.ts +21 -0
- package/templates/create/nuxt/package.json.hbs +2 -1
- package/templates/create/nuxt/server/api/users.get.ts.hbs +4 -15
- package/templates/create/nuxt/server/utils/prisma.ts.hbs +60 -40
- package/templates/create/svelte/README.md.hbs +25 -15
- package/templates/create/svelte/deno.json.hbs +1 -1
- package/templates/create/svelte/package.json.hbs +1 -1
- package/templates/create/svelte/src/lib/server/prisma.ts.hbs +61 -41
- package/templates/create/svelte/src/routes/+page.server.ts.hbs +4 -15
- package/templates/create/svelte/src/routes/+page.svelte.hbs +13 -163
- package/templates/create/svelte/vite.config.ts +2 -1
- package/templates/create/tanstack-start/README.md.hbs +26 -13
- package/templates/create/tanstack-start/deno.json.hbs +1 -2
- package/templates/create/tanstack-start/package.json.hbs +1 -2
- package/templates/create/tanstack-start/src/lib/prisma.server.ts.hbs +60 -40
- package/templates/create/tanstack-start/src/routes/__root.tsx.hbs +2 -3
- package/templates/create/tanstack-start/src/routes/index.tsx.hbs +26 -77
- package/templates/create/tanstack-start/tsconfig.json +1 -0
- package/templates/create/tanstack-start/vite.config.ts +7 -1
- 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/README.md.hbs +0 -29
- package/templates/create/turborepo/apps/api/package.json.hbs +0 -19
- package/templates/create/turborepo/apps/api/src/index.ts.hbs +0 -51
- package/templates/create/turborepo/package.json.hbs +0 -24
- package/templates/create/turborepo/packages/db/package.json.hbs +0 -17
- 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
- package/templates/create/turborepo/packages/db/src/client.ts.hbs +0 -58
- package/templates/create/turborepo/packages/db/src/index.ts +0 -2
- package/templates/create/turborepo/packages/db/tsconfig.json +0 -15
- package/templates/create/turborepo/turbo.json +0 -28
- /package/templates/create/{turborepo → elysia}/.yarnrc.yml.hbs +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
{{#if (eq schemaPreset "basic")}}
|
|
2
1
|
<script lang="ts">
|
|
3
2
|
import type { PageProps } from './$types';
|
|
4
3
|
|
|
@@ -18,10 +17,10 @@
|
|
|
18
17
|
|
|
19
18
|
<section class="shell">
|
|
20
19
|
<div class="hero">
|
|
21
|
-
<p class="eyebrow">SvelteKit + Prisma
|
|
20
|
+
<p class="eyebrow">SvelteKit + Prisma Next</p>
|
|
22
21
|
<h1>Users from your database, loaded on the server.</h1>
|
|
23
22
|
<p class="lede">
|
|
24
|
-
This page reads from <code>+page.server.ts</code> using the Prisma
|
|
23
|
+
This page reads from <code>+page.server.ts</code> using the Prisma Next helper in
|
|
25
24
|
<code>src/lib/server/prisma.ts</code>.
|
|
26
25
|
</p>
|
|
27
26
|
</div>
|
|
@@ -34,22 +33,26 @@
|
|
|
34
33
|
|
|
35
34
|
{#if !data.users}
|
|
36
35
|
<p class="empty">
|
|
37
|
-
Could not query users yet. Run <code>
|
|
36
|
+
Could not query users yet. Run <code>contract:emit</code> and apply your schema, then
|
|
38
37
|
refresh.
|
|
39
38
|
</p>
|
|
40
39
|
{:else if data.users.length === 0}
|
|
41
|
-
<p class="empty">No users yet. Run
|
|
40
|
+
<p class="empty">No users yet. Run db:seed after applying your first migration.</p>
|
|
42
41
|
{:else}
|
|
43
42
|
<ul class="users">
|
|
44
43
|
{#each data.users as user}
|
|
45
44
|
<li>
|
|
46
45
|
<div>
|
|
47
46
|
<strong>{user.name ?? 'Unnamed user'}</strong>
|
|
48
|
-
<p>{user.email}</p>
|
|
47
|
+
<p>{user.username ? `@${user.username}` : user.email}</p>
|
|
49
48
|
</div>
|
|
50
|
-
|
|
51
|
-
{
|
|
52
|
-
|
|
49
|
+
{#if user.createdAt}
|
|
50
|
+
<time datetime={new Date(user.createdAt).toISOString()}>
|
|
51
|
+
{formatter.format(new Date(user.createdAt))}
|
|
52
|
+
</time>
|
|
53
|
+
{:else}
|
|
54
|
+
<span class="muted">No timestamp</span>
|
|
55
|
+
{/if}
|
|
53
56
|
</li>
|
|
54
57
|
{/each}
|
|
55
58
|
</ul>
|
|
@@ -120,6 +123,7 @@
|
|
|
120
123
|
|
|
121
124
|
.panel-header span,
|
|
122
125
|
.empty,
|
|
126
|
+
.muted,
|
|
123
127
|
time {
|
|
124
128
|
color: #888;
|
|
125
129
|
font-size: 0.8rem;
|
|
@@ -173,157 +177,3 @@
|
|
|
173
177
|
}
|
|
174
178
|
}
|
|
175
179
|
</style>
|
|
176
|
-
{{else}}
|
|
177
|
-
<svelte:head>
|
|
178
|
-
<title>create-prisma + sveltekit</title>
|
|
179
|
-
</svelte:head>
|
|
180
|
-
|
|
181
|
-
<section class="shell">
|
|
182
|
-
<div class="hero">
|
|
183
|
-
<p class="eyebrow">SvelteKit + Prisma 7</p>
|
|
184
|
-
<h1>Your SvelteKit app is ready.</h1>
|
|
185
|
-
<p class="lede">
|
|
186
|
-
Edit <code>prisma/schema.prisma</code>, run <code>db:migrate</code>, then load your data from
|
|
187
|
-
<code>+page.server.ts</code> with the Prisma instance in <code>src/lib/server/prisma.ts</code>.
|
|
188
|
-
</p>
|
|
189
|
-
</div>
|
|
190
|
-
|
|
191
|
-
<div class="panel">
|
|
192
|
-
<div class="panel-header">
|
|
193
|
-
<h2>What's included</h2>
|
|
194
|
-
<span>Starter kit</span>
|
|
195
|
-
</div>
|
|
196
|
-
|
|
197
|
-
<ul class="users">
|
|
198
|
-
<li>
|
|
199
|
-
<div>
|
|
200
|
-
<strong>Prisma client</strong>
|
|
201
|
-
<p>Use the server-only instance from <code>src/lib/server/prisma.ts</code>.</p>
|
|
202
|
-
</div>
|
|
203
|
-
</li>
|
|
204
|
-
<li>
|
|
205
|
-
<div>
|
|
206
|
-
<strong>Seed script</strong>
|
|
207
|
-
<p>Run <code>db:seed</code> after your first migration.</p>
|
|
208
|
-
</div>
|
|
209
|
-
</li>
|
|
210
|
-
<li>
|
|
211
|
-
<div>
|
|
212
|
-
<strong>Generated client output</strong>
|
|
213
|
-
<p>Prisma Client is generated into <code>src/generated/prisma</code>.</p>
|
|
214
|
-
</div>
|
|
215
|
-
</li>
|
|
216
|
-
</ul>
|
|
217
|
-
</div>
|
|
218
|
-
</section>
|
|
219
|
-
|
|
220
|
-
<style>
|
|
221
|
-
:global(body) {
|
|
222
|
-
margin: 0;
|
|
223
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
|
|
224
|
-
background: #fff;
|
|
225
|
-
color: #111;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
.shell {
|
|
229
|
-
max-width: 40rem;
|
|
230
|
-
margin: 0 auto;
|
|
231
|
-
padding: 3rem 1.5rem;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
.hero {
|
|
235
|
-
margin-bottom: 1.5rem;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
.eyebrow {
|
|
239
|
-
margin: 0 0 0.5rem;
|
|
240
|
-
color: #666;
|
|
241
|
-
font-size: 0.75rem;
|
|
242
|
-
font-weight: 600;
|
|
243
|
-
letter-spacing: 0.06em;
|
|
244
|
-
text-transform: uppercase;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
h1 {
|
|
248
|
-
margin: 0;
|
|
249
|
-
font-size: 1.25rem;
|
|
250
|
-
font-weight: 600;
|
|
251
|
-
line-height: 1.4;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
.lede {
|
|
255
|
-
margin: 0.5rem 0 0;
|
|
256
|
-
color: #666;
|
|
257
|
-
font-size: 0.875rem;
|
|
258
|
-
line-height: 1.6;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
.panel {
|
|
262
|
-
border: 1px solid #e5e5e5;
|
|
263
|
-
border-radius: 0.5rem;
|
|
264
|
-
padding: 1rem;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
.panel-header {
|
|
268
|
-
display: flex;
|
|
269
|
-
align-items: center;
|
|
270
|
-
justify-content: space-between;
|
|
271
|
-
gap: 1rem;
|
|
272
|
-
margin-bottom: 0.75rem;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
h2 {
|
|
276
|
-
margin: 0;
|
|
277
|
-
font-size: 0.875rem;
|
|
278
|
-
font-weight: 600;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
.panel-header span {
|
|
282
|
-
color: #888;
|
|
283
|
-
font-size: 0.8rem;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
.panel p {
|
|
287
|
-
color: #666;
|
|
288
|
-
font-size: 0.8rem;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
.users {
|
|
292
|
-
list-style: none;
|
|
293
|
-
margin: 0;
|
|
294
|
-
padding: 0;
|
|
295
|
-
display: grid;
|
|
296
|
-
gap: 0.5rem;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
.users li {
|
|
300
|
-
display: flex;
|
|
301
|
-
align-items: center;
|
|
302
|
-
justify-content: space-between;
|
|
303
|
-
gap: 1rem;
|
|
304
|
-
padding: 0.625rem 0.75rem;
|
|
305
|
-
border: 1px solid #eee;
|
|
306
|
-
border-radius: 0.375rem;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
.users p {
|
|
310
|
-
margin: 0.125rem 0 0;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
code {
|
|
314
|
-
padding: 0.125rem 0.25rem;
|
|
315
|
-
border-radius: 0.25rem;
|
|
316
|
-
background: #f5f5f5;
|
|
317
|
-
font-family: SFMono-Regular, Consolas, monospace;
|
|
318
|
-
font-size: 0.875em;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
@media (max-width: 640px) {
|
|
322
|
-
.users li,
|
|
323
|
-
.panel-header {
|
|
324
|
-
flex-direction: column;
|
|
325
|
-
align-items: flex-start;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
</style>
|
|
329
|
-
{{/if}}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { prismaVitePlugin } from "@prisma-next/vite-plugin-contract-emit";
|
|
1
2
|
import { sveltekit } from "@sveltejs/kit/vite";
|
|
2
3
|
import { defineConfig } from "vite";
|
|
3
4
|
|
|
4
5
|
export default defineConfig({
|
|
5
|
-
plugins: [sveltekit()],
|
|
6
|
+
plugins: [prismaVitePlugin(), sveltekit()],
|
|
6
7
|
});
|
|
@@ -9,23 +9,36 @@ Generated by `create-prisma` with the TanStack Start template.
|
|
|
9
9
|
- `{{runScriptCommand packageManager "preview"}}` - preview the production build
|
|
10
10
|
- `{{runScriptCommand packageManager "typecheck"}}` - run TypeScript 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
|
- `src/lib/prisma.server.ts`
|
|
19
|
-
- `prisma.config.ts`
|
|
20
|
-
- `src/generated/prisma`
|
|
21
19
|
|
|
22
20
|
Database helper scripts are added to `package.json`:
|
|
23
21
|
|
|
24
|
-
- `
|
|
25
|
-
|
|
26
|
-
- `db:
|
|
27
|
-
- `db:
|
|
28
|
-
{{
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
- `{{runScriptCommand packageManager "contract:emit"}}` - emit contract artifacts after contract changes
|
|
23
|
+
{{#if (eq provider "mongo")}}
|
|
24
|
+
- `{{runScriptCommand packageManager "db:up"}}` - start the local MongoDB replica set with `mongodb-memory-server`. Data persists in `.mongo-data/` across restarts.
|
|
25
|
+
- `{{runScriptCommand packageManager "db:down"}}` - stop the local MongoDB process (data preserved)
|
|
26
|
+
- `{{runScriptCommand packageManager "db:reset"}}` - stop and wipe `.mongo-data/` for a clean slate
|
|
27
|
+
- `{{runScriptCommand packageManager "migration:plan"}}` - create a MongoDB migration plan
|
|
28
|
+
- `{{runScriptCommand packageManager "migrate"}}` - 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 "migrate"}}` - apply a planned migration
|
|
31
34
|
{{/if}}
|
|
35
|
+
|
|
36
|
+
- `{{runScriptCommand packageManager "db:seed"}}` - insert sample users manually
|
|
37
|
+
|
|
38
|
+
For provider-specific Prisma Next reference docs, see `prisma-next.md`. Prisma Next skills live in the upstream `skills/` directory: https://github.com/prisma/prisma-next/tree/main/skills.
|
|
39
|
+
The TanStack Start Vite dev server also auto-emits Prisma Next contract artifacts when the contract changes.
|
|
40
|
+
|
|
41
|
+
Node-based Prisma Next projects expect Node.js 24 LTS or newer.
|
|
42
|
+
|
|
43
|
+
The home route uses a TanStack Start server function to load users through the Prisma Next helper in `src/lib/prisma.server.ts`.
|
|
44
|
+
|
|
@@ -1,53 +1,73 @@
|
|
|
1
1
|
import "dotenv/config";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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";
|
|
2
|
+
{{#if (eq provider "mongo")}}
|
|
3
|
+
import mongo from "@prisma-next/mongo/runtime";
|
|
4
|
+
{{else}}
|
|
5
|
+
import postgres from "@prisma-next/postgres/runtime";
|
|
17
6
|
{{/if}}
|
|
18
7
|
|
|
19
|
-
{{#if (eq provider "
|
|
20
|
-
|
|
8
|
+
{{#if (eq provider "mongo")}}
|
|
9
|
+
import type { DefaultModelRow } from "@prisma-next/mongo-orm";
|
|
21
10
|
{{else}}
|
|
22
|
-
|
|
23
|
-
if (!databaseUrl) {
|
|
24
|
-
throw new Error("DATABASE_URL is required");
|
|
25
|
-
}
|
|
11
|
+
import type { DefaultModelRow } from "@prisma-next/sql-orm-client";
|
|
26
12
|
{{/if}}
|
|
27
13
|
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
import type { Contract } from "../../prisma/contract.d";
|
|
15
|
+
import contractJson from "../../prisma/contract.json" with { type: "json" };
|
|
16
|
+
|
|
17
|
+
{{#if (eq provider "mongo")}}
|
|
18
|
+
export const db = mongo<Contract>({
|
|
19
|
+
contractJson,
|
|
20
|
+
url: process.env["DATABASE_URL"]!,
|
|
31
21
|
});
|
|
32
|
-
{{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
22
|
+
{{else}}
|
|
23
|
+
export const db = postgres<Contract>({
|
|
24
|
+
contractJson,
|
|
25
|
+
url: process.env["DATABASE_URL"]!,
|
|
36
26
|
});
|
|
37
27
|
{{/if}}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
{{#if (eq provider "
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
28
|
+
|
|
29
|
+
type UserRow = DefaultModelRow<Contract, "User">;
|
|
30
|
+
|
|
31
|
+
{{#if (eq provider "mongo")}}
|
|
32
|
+
function toStarterUser(user: Pick<UserRow, "_id" | "email" | "username" | "name">) {
|
|
33
|
+
return {
|
|
34
|
+
id: String(user._id),
|
|
35
|
+
email: user.email,
|
|
36
|
+
username: user.username ?? null,
|
|
37
|
+
name: user.name ?? null,
|
|
38
|
+
createdAt: null as Date | null,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
{{else}}
|
|
42
|
+
function toStarterUser(user: Pick<UserRow, "id" | "email" | "username" | "name" | "createdAt">) {
|
|
43
|
+
return {
|
|
44
|
+
id: String(user.id),
|
|
45
|
+
email: user.email,
|
|
46
|
+
username: user.username ?? null,
|
|
47
|
+
name: user.name ?? null,
|
|
48
|
+
createdAt: user.createdAt,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
45
51
|
{{/if}}
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
|
|
53
|
+
export async function listUsers(limit = 10) {
|
|
54
|
+
|
|
55
|
+
{{#if (eq provider "mongo")}}
|
|
56
|
+
const users: ReturnType<typeof toStarterUser>[] = [];
|
|
57
|
+
|
|
58
|
+
for await (const user of db.orm.users.select("_id", "email", "username", "name").take(limit).all()) {
|
|
59
|
+
users.push(toStarterUser(user));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return users;
|
|
63
|
+
{{else}}
|
|
64
|
+
const users = await db.orm.User.select("id", "email", "username", "name", "createdAt").take(limit).all();
|
|
65
|
+
|
|
66
|
+
return users.map(toStarterUser);
|
|
48
67
|
{{/if}}
|
|
49
68
|
|
|
50
|
-
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export type StarterUser = Awaited<ReturnType<typeof listUsers>>[number];
|
|
51
72
|
|
|
52
|
-
export
|
|
53
|
-
export default prisma;
|
|
73
|
+
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,62 +1,43 @@
|
|
|
1
1
|
import { createFileRoute } from "@tanstack/react-router";
|
|
2
2
|
import { createServerFn } from "@tanstack/react-start";
|
|
3
|
-
{{#if (eq schemaPreset "basic")}}
|
|
4
|
-
import { prisma } from "../lib/prisma.server";
|
|
5
|
-
{{/if}}
|
|
6
3
|
|
|
7
|
-
{
|
|
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
|
-
}
|
|
4
|
+
import { listUsers as listStarterUsers } from "../lib/prisma.server";
|
|
16
5
|
|
|
17
6
|
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
|
-
}
|
|
7
|
+
return listStarterUsers(10)
|
|
8
|
+
.then((rows) =>
|
|
9
|
+
rows.map((user) => ({
|
|
10
|
+
...user,
|
|
11
|
+
createdAt: user.createdAt?.toISOString() ?? null,
|
|
12
|
+
}))
|
|
13
|
+
)
|
|
14
|
+
.catch(() => undefined);
|
|
32
15
|
});
|
|
33
|
-
{{/if}}
|
|
34
16
|
|
|
35
17
|
export const Route = createFileRoute("/")({
|
|
36
|
-
|
|
18
|
+
|
|
37
19
|
loader: async () => listUsers(),
|
|
38
|
-
|
|
20
|
+
|
|
39
21
|
component: Home,
|
|
40
22
|
});
|
|
41
23
|
|
|
42
24
|
function Home() {
|
|
43
|
-
|
|
25
|
+
|
|
44
26
|
const formatter = new Intl.DateTimeFormat("en", {
|
|
45
27
|
dateStyle: "medium",
|
|
46
28
|
timeStyle: "short",
|
|
47
29
|
timeZone: "UTC",
|
|
48
30
|
});
|
|
49
31
|
const users = Route.useLoaderData();
|
|
50
|
-
{{/if}}
|
|
51
32
|
|
|
52
33
|
return (
|
|
53
34
|
<main className="shell">
|
|
54
35
|
<div className="hero">
|
|
55
|
-
<p className="eyebrow">TanStack Start + Prisma
|
|
56
|
-
|
|
36
|
+
<p className="eyebrow">TanStack Start + Prisma Next</p>
|
|
37
|
+
|
|
57
38
|
<h1>Users from your database, loaded through a server function.</h1>
|
|
58
39
|
<p className="lede">
|
|
59
|
-
This route uses TanStack Start's server function API and the Prisma
|
|
40
|
+
This route uses TanStack Start's server function API and the Prisma Next helper in{" "}
|
|
60
41
|
<code>src/lib/prisma.server.ts</code>.
|
|
61
42
|
</p>
|
|
62
43
|
</div>
|
|
@@ -69,63 +50,31 @@ function Home() {
|
|
|
69
50
|
|
|
70
51
|
{!users ? (
|
|
71
52
|
<p className="empty">
|
|
72
|
-
Could not query users yet. Run <code>
|
|
53
|
+
Could not query users yet. Run <code>contract:emit</code> and apply your schema,
|
|
73
54
|
then refresh.
|
|
74
55
|
</p>
|
|
75
56
|
) : users.length === 0 ? (
|
|
76
|
-
<p className="empty">No users yet. Run
|
|
57
|
+
<p className="empty">No users yet. Run db:seed after applying your first migration.</p>
|
|
77
58
|
) : (
|
|
78
59
|
<ul className="users">
|
|
79
60
|
{users.map((user) => (
|
|
80
61
|
<li key={user.id}>
|
|
81
62
|
<div>
|
|
82
63
|
<strong>{user.name ?? "Unnamed user"}</strong>
|
|
83
|
-
<p>{user.email}</p>
|
|
64
|
+
<p>{user.username ? `@${user.username}` : user.email}</p>
|
|
84
65
|
</div>
|
|
85
|
-
|
|
86
|
-
{
|
|
87
|
-
|
|
66
|
+
{user.createdAt ? (
|
|
67
|
+
<time dateTime={user.createdAt}>
|
|
68
|
+
{formatter.format(new Date(user.createdAt))}
|
|
69
|
+
</time>
|
|
70
|
+
) : (
|
|
71
|
+
<span className="empty">No timestamp</span>
|
|
72
|
+
)}
|
|
88
73
|
</li>
|
|
89
74
|
))}
|
|
90
75
|
</ul>
|
|
91
76
|
)}
|
|
92
77
|
</section>
|
|
93
|
-
{{else}}
|
|
94
|
-
<h1>Your TanStack Start app is ready.</h1>
|
|
95
|
-
<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.
|
|
98
|
-
</p>
|
|
99
|
-
</div>
|
|
100
|
-
|
|
101
|
-
<section className="panel">
|
|
102
|
-
<div className="panelHeader">
|
|
103
|
-
<h2>What's included</h2>
|
|
104
|
-
<span>Starter kit</span>
|
|
105
|
-
</div>
|
|
106
|
-
|
|
107
|
-
<ul className="users">
|
|
108
|
-
<li>
|
|
109
|
-
<div>
|
|
110
|
-
<strong>File-based routing</strong>
|
|
111
|
-
<p>Add new routes in <code>src/routes</code>.</p>
|
|
112
|
-
</div>
|
|
113
|
-
</li>
|
|
114
|
-
<li>
|
|
115
|
-
<div>
|
|
116
|
-
<strong>Prisma client</strong>
|
|
117
|
-
<p>Use the shared instance from <code>src/lib/prisma.server.ts</code>.</p>
|
|
118
|
-
</div>
|
|
119
|
-
</li>
|
|
120
|
-
<li>
|
|
121
|
-
<div>
|
|
122
|
-
<strong>Seed script</strong>
|
|
123
|
-
<p>Run <code>db:seed</code> after your first migration.</p>
|
|
124
|
-
</div>
|
|
125
|
-
</li>
|
|
126
|
-
</ul>
|
|
127
|
-
</section>
|
|
128
|
-
{{/if}}
|
|
129
78
|
|
|
130
79
|
<section className="panel">
|
|
131
80
|
<div className="panelHeader">
|
|
@@ -133,7 +82,7 @@ function Home() {
|
|
|
133
82
|
</div>
|
|
134
83
|
|
|
135
84
|
<ul className="steps">
|
|
136
|
-
<li>Run <code>
|
|
85
|
+
<li>Run <code>contract:emit</code> after contract changes.</li>
|
|
137
86
|
<li>Use TanStack Start server functions for server-only logic.</li>
|
|
138
87
|
<li>Preview production output with <code>preview</code>.</li>
|
|
139
88
|
</ul>
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
import { prismaVitePlugin } from "@prisma-next/vite-plugin-contract-emit";
|
|
1
2
|
import { defineConfig } from "vite";
|
|
2
3
|
import viteReact from "@vitejs/plugin-react";
|
|
3
4
|
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
|
|
4
5
|
import tsconfigPaths from "vite-tsconfig-paths";
|
|
5
6
|
|
|
6
7
|
export default defineConfig({
|
|
7
|
-
plugins: [
|
|
8
|
+
plugins: [
|
|
9
|
+
prismaVitePlugin(),
|
|
10
|
+
tsconfigPaths({ projects: ["./tsconfig.json"] }),
|
|
11
|
+
tanstackStart(),
|
|
12
|
+
viteReact(),
|
|
13
|
+
],
|
|
8
14
|
});
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
generator client {
|
|
2
|
-
provider = "prisma-client"
|
|
3
|
-
output = "../src/generated/prisma"
|
|
4
|
-
{{#if (eq packageManager "deno")}}
|
|
5
|
-
runtime = "deno"
|
|
6
|
-
{{/if}}
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
datasource db {
|
|
10
|
-
provider = "{{provider}}"
|
|
11
|
-
}
|
|
12
|
-
{{#if (eq schemaPreset "basic")}}
|
|
13
|
-
|
|
14
|
-
model User {
|
|
15
|
-
id String @id @default(cuid())
|
|
16
|
-
email String @unique
|
|
17
|
-
name String?
|
|
18
|
-
createdAt DateTime @default(now())
|
|
19
|
-
updatedAt DateTime @updatedAt
|
|
20
|
-
}
|
|
21
|
-
{{/if}}
|