create-prisma 0.7.1-pr.52.181.1 → 0.7.2

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 (129) hide show
  1. package/README.md +25 -19
  2. package/dist/cli.mjs +2 -32
  3. package/dist/index.d.mts +25 -1
  4. package/dist/index.mjs +2 -2290
  5. package/dist/src-B3hRLZ0U.mjs +2527 -0
  6. package/package.json +2 -4
  7. package/templates/create/astro/README.md.hbs +14 -7
  8. package/templates/create/astro/astro.config.mjs.hbs +0 -11
  9. package/templates/create/astro/deno.json.hbs +5 -0
  10. package/templates/create/astro/prisma/schema.prisma.hbs +5 -0
  11. package/templates/create/astro/prisma/seed.ts.hbs +5 -1
  12. package/templates/create/astro/prisma.compute.ts.hbs +10 -0
  13. package/templates/create/astro/src/lib/prisma.ts.hbs +4 -18
  14. package/templates/create/astro/src/pages/api/users.ts.hbs +11 -1
  15. package/templates/create/astro/src/pages/index.astro.hbs +176 -36
  16. package/templates/create/elysia/README.md.hbs +13 -7
  17. package/templates/create/elysia/deno.json.hbs +5 -0
  18. package/templates/create/elysia/package.json.hbs +3 -4
  19. package/templates/create/elysia/prisma/schema.prisma.hbs +6 -0
  20. package/templates/create/elysia/prisma/seed.ts.hbs +5 -1
  21. package/templates/create/elysia/prisma.compute.ts.hbs +11 -0
  22. package/templates/create/elysia/src/index.ts.hbs +17 -13
  23. package/templates/create/elysia/src/lib/prisma.ts.hbs +4 -18
  24. package/templates/create/elysia/tsconfig.json +0 -1
  25. package/templates/create/hono/README.md.hbs +13 -7
  26. package/templates/create/hono/deno.json.hbs +5 -0
  27. package/templates/create/hono/package.json.hbs +2 -2
  28. package/templates/create/hono/prisma/schema.prisma.hbs +6 -0
  29. package/templates/create/hono/prisma/seed.ts.hbs +5 -1
  30. package/templates/create/hono/prisma.compute.ts.hbs +10 -0
  31. package/templates/create/hono/src/index.ts.hbs +7 -9
  32. package/templates/create/hono/src/lib/prisma.ts.hbs +4 -18
  33. package/templates/create/hono/tsconfig.json +0 -1
  34. package/templates/create/nest/README.md.hbs +12 -6
  35. package/templates/create/nest/deno.json.hbs +5 -0
  36. package/templates/create/nest/package.json.hbs +2 -2
  37. package/templates/create/nest/prisma/schema.prisma.hbs +6 -0
  38. package/templates/create/nest/prisma/seed.ts.hbs +5 -1
  39. package/templates/create/nest/prisma.compute.ts.hbs +10 -0
  40. package/templates/create/nest/src/app.controller.ts.hbs +1 -6
  41. package/templates/create/nest/src/app.module.ts.hbs +14 -7
  42. package/templates/create/nest/src/lib/prisma.ts.hbs +4 -17
  43. package/templates/create/nest/src/main.ts.hbs +6 -2
  44. package/templates/create/nest/src/prisma.service.ts.hbs +2 -2
  45. package/templates/create/nest/src/users.controller.ts.hbs +3 -1
  46. package/templates/create/nest/src/users.service.ts.hbs +3 -1
  47. package/templates/create/nest/tsconfig.json +0 -1
  48. package/templates/create/next/README.md.hbs +11 -7
  49. package/templates/create/next/deno.json.hbs +12 -0
  50. package/templates/create/next/prisma/schema.prisma.hbs +5 -0
  51. package/templates/create/next/prisma/seed.ts.hbs +5 -1
  52. package/templates/create/next/prisma.compute.ts.hbs +9 -0
  53. package/templates/create/next/src/app/globals.css +122 -0
  54. package/templates/create/next/src/app/layout.tsx.hbs +2 -2
  55. package/templates/create/next/src/app/page.tsx.hbs +58 -34
  56. package/templates/create/next/src/lib/prisma.ts.hbs +4 -18
  57. package/templates/create/nuxt/README.md.hbs +11 -7
  58. package/templates/create/nuxt/app/pages/index.vue.hbs +175 -43
  59. package/templates/create/nuxt/deno.json.hbs +5 -0
  60. package/templates/create/nuxt/nuxt.config.ts +0 -1
  61. package/templates/create/nuxt/prisma/schema.prisma.hbs +5 -0
  62. package/templates/create/nuxt/prisma/seed.ts.hbs +5 -1
  63. package/templates/create/nuxt/prisma.compute.ts.hbs +9 -0
  64. package/templates/create/nuxt/server/api/users.get.ts.hbs +6 -0
  65. package/templates/create/nuxt/server/utils/prisma.ts.hbs +4 -18
  66. package/templates/create/svelte/README.md.hbs +13 -4
  67. package/templates/create/svelte/deno.json.hbs +5 -0
  68. package/templates/create/svelte/package.json.hbs +1 -2
  69. package/templates/create/svelte/prisma/schema.prisma.hbs +5 -0
  70. package/templates/create/svelte/prisma/seed.ts.hbs +5 -1
  71. package/templates/create/svelte/src/lib/server/prisma.ts.hbs +2 -18
  72. package/templates/create/svelte/src/routes/+layout.svelte +0 -1
  73. package/templates/create/svelte/src/routes/+page.server.ts.hbs +7 -1
  74. package/templates/create/svelte/src/routes/+page.svelte.hbs +297 -41
  75. package/templates/create/svelte/svelte.config.js +13 -0
  76. package/templates/create/svelte/vite.config.ts +0 -3
  77. package/templates/create/tanstack-start/README.md.hbs +11 -7
  78. package/templates/create/tanstack-start/deno.json.hbs +13 -0
  79. package/templates/create/tanstack-start/prisma/schema.prisma.hbs +5 -0
  80. package/templates/create/tanstack-start/prisma/seed.ts.hbs +5 -1
  81. package/templates/create/tanstack-start/prisma.compute.ts.hbs +9 -0
  82. package/templates/create/tanstack-start/src/lib/prisma.server.ts.hbs +4 -18
  83. package/templates/create/tanstack-start/src/routes/__root.tsx.hbs +29 -4
  84. package/templates/create/tanstack-start/src/routes/index.tsx.hbs +76 -35
  85. package/templates/create/tanstack-start/src/styles.css +146 -0
  86. package/templates/create/tanstack-start/tsconfig.json +1 -1
  87. package/templates/create/turborepo/README.md.hbs +9 -7
  88. package/templates/create/turborepo/apps/api/package.json.hbs +9 -2
  89. package/templates/create/turborepo/apps/api/src/index.ts.hbs +12 -28
  90. package/templates/create/turborepo/apps/api/tsconfig.json +0 -1
  91. package/templates/create/turborepo/deno.json.hbs +5 -0
  92. package/templates/create/turborepo/package.json.hbs +6 -0
  93. package/templates/create/turborepo/packages/db/package.json.hbs +5 -4
  94. package/templates/create/turborepo/packages/db/prisma/schema.prisma.hbs +5 -0
  95. package/templates/create/turborepo/packages/db/prisma/seed.ts.hbs +5 -1
  96. package/templates/create/turborepo/packages/db/src/client.ts.hbs +5 -2
  97. package/templates/create/turborepo/packages/db/tsconfig.json +0 -1
  98. package/templates/create/turborepo/prisma.compute.ts.hbs +14 -0
  99. package/templates/create/astro/module.ts.hbs +0 -30
  100. package/templates/create/astro/prisma-composer.config.ts.hbs +0 -8
  101. package/templates/create/astro/service.ts.hbs +0 -19
  102. package/templates/create/elysia/.yarnrc.yml.hbs +0 -3
  103. package/templates/create/elysia/module.ts.hbs +0 -30
  104. package/templates/create/elysia/prisma-composer.config.ts.hbs +0 -8
  105. package/templates/create/elysia/service.ts.hbs +0 -19
  106. package/templates/create/hono/module.ts.hbs +0 -30
  107. package/templates/create/hono/prisma-composer.config.ts.hbs +0 -8
  108. package/templates/create/hono/service.ts.hbs +0 -19
  109. package/templates/create/nest/module.ts.hbs +0 -30
  110. package/templates/create/nest/prisma-composer.config.ts.hbs +0 -8
  111. package/templates/create/nest/src/service.ts.hbs +0 -19
  112. package/templates/create/next/module.ts.hbs +0 -30
  113. package/templates/create/next/prisma-composer.config.ts.hbs +0 -8
  114. package/templates/create/next/service.ts.hbs +0 -19
  115. package/templates/create/nuxt/module.ts.hbs +0 -30
  116. package/templates/create/nuxt/prisma-composer.config.ts.hbs +0 -8
  117. package/templates/create/nuxt/service.ts.hbs +0 -19
  118. package/templates/create/svelte/module.ts.hbs +0 -30
  119. package/templates/create/svelte/prisma-composer.config.ts.hbs +0 -8
  120. package/templates/create/svelte/service.ts.hbs +0 -19
  121. package/templates/create/svelte/svelte.config.js.hbs +0 -10
  122. package/templates/create/tanstack-start/module.ts.hbs +0 -30
  123. package/templates/create/tanstack-start/prisma-composer.config.ts.hbs +0 -8
  124. package/templates/create/tanstack-start/service.ts.hbs +0 -19
  125. package/templates/create/turborepo/apps/api/src/service.ts.hbs +0 -19
  126. package/templates/create/turborepo/module.ts.hbs +0 -30
  127. package/templates/create/turborepo/prisma-composer.config.ts.hbs +0 -8
  128. package/templates/shared/setup-composer-postgres.mjs.hbs +0 -179
  129. package/templates/shared/starter.css +0 -276
@@ -0,0 +1,2527 @@
1
+ #!/usr/bin/env node
2
+ import { os } from "@orpc/server";
3
+ import { createCli } from "trpc-cli";
4
+ import { cancel, confirm, intro, isCancel, log, multiselect, outro, select, spinner, text } from "@clack/prompts";
5
+ import fs from "fs-extra";
6
+ import path from "node:path";
7
+ import Handlebars from "handlebars";
8
+ import { existsSync } from "node:fs";
9
+ import { fileURLToPath } from "node:url";
10
+ import { z } from "zod";
11
+ import { execa } from "execa";
12
+ import { randomUUID } from "node:crypto";
13
+ import os$1 from "node:os";
14
+ import { PostHog } from "posthog-node";
15
+ import { styleText } from "node:util";
16
+ //#region src/utils/runtime.ts
17
+ function usesNodeStyleRuntime(packageManager) {
18
+ return packageManager !== void 0 && packageManager !== "bun" && packageManager !== "deno";
19
+ }
20
+ function requiresDotenvConfigImport(packageManager) {
21
+ return usesNodeStyleRuntime(packageManager);
22
+ }
23
+ function requiresPrismaConfigDotenvImport(packageManager) {
24
+ return packageManager !== "deno";
25
+ }
26
+ //#endregion
27
+ //#region src/constants/dependencies.ts
28
+ const dependencyVersionMap = {
29
+ "@elysiajs/node": "^1.4.5",
30
+ "@libsql/client": "^0.17.4",
31
+ "@prisma/client": "^7.8.0",
32
+ "@prisma/adapter-pg": "^7.8.0",
33
+ "@prisma/adapter-libsql": "^7.8.0",
34
+ "@prisma/adapter-mariadb": "^7.8.0",
35
+ "@prisma/adapter-mssql": "^7.8.0",
36
+ "@prisma/compute-sdk": "latest",
37
+ "@types/node": "^26.0.0",
38
+ dotenv: "^17.4.2",
39
+ prisma: "^7.8.0",
40
+ tsx: "^4.22.4"
41
+ };
42
+ const computeConfigTemplates = /* @__PURE__ */ new Set([
43
+ "hono",
44
+ "elysia",
45
+ "nest",
46
+ "next",
47
+ "astro",
48
+ "nuxt",
49
+ "tanstack-start",
50
+ "turborepo"
51
+ ]);
52
+ function getWorkspaceDependencyVersion(packageManager) {
53
+ return packageManager === "npm" ? "*" : "workspace:*";
54
+ }
55
+ function getCreateTemplateDependencies(template, packageManager) {
56
+ const targets = [];
57
+ if (template === "hono" || template === "elysia" || template === "nest") {
58
+ const runtimeDevDependencies = usesNodeStyleRuntime(packageManager) ? ["tsx"] : [];
59
+ if (template === "elysia" && packageManager !== "deno") targets.push({
60
+ packageJsonPath: "package.json",
61
+ dependencies: ["@elysiajs/node"],
62
+ devDependencies: ["@types/node", ...runtimeDevDependencies]
63
+ });
64
+ else if (runtimeDevDependencies.length > 0) targets.push({
65
+ packageJsonPath: "package.json",
66
+ dependencies: [],
67
+ devDependencies: runtimeDevDependencies
68
+ });
69
+ }
70
+ if (template === "turborepo") targets.push({
71
+ packageJsonPath: "apps/api/package.json",
72
+ dependencies: ["dotenv"],
73
+ devDependencies: ["tsx"],
74
+ customDependencies: { "@repo/db": getWorkspaceDependencyVersion(packageManager) }
75
+ });
76
+ if (computeConfigTemplates.has(template)) targets.push({
77
+ packageJsonPath: "package.json",
78
+ dependencies: [],
79
+ devDependencies: ["@prisma/compute-sdk"]
80
+ });
81
+ return targets;
82
+ }
83
+ //#endregion
84
+ //#region src/types.ts
85
+ const databaseProviders = [
86
+ "postgresql",
87
+ "mysql",
88
+ "sqlite",
89
+ "sqlserver",
90
+ "cockroachdb"
91
+ ];
92
+ const packageManagers = [
93
+ "npm",
94
+ "pnpm",
95
+ "yarn",
96
+ "bun",
97
+ "deno"
98
+ ];
99
+ const schemaPresets = ["empty", "basic"];
100
+ const createTemplates = [
101
+ "hono",
102
+ "elysia",
103
+ "nest",
104
+ "next",
105
+ "svelte",
106
+ "astro",
107
+ "nuxt",
108
+ "tanstack-start",
109
+ "turborepo"
110
+ ];
111
+ const createAddons = [
112
+ "skills",
113
+ "mcp",
114
+ "extension"
115
+ ];
116
+ const addonInstallScopes = ["project", "global"];
117
+ const extensionTargets = [
118
+ "vscode",
119
+ "cursor",
120
+ "windsurf"
121
+ ];
122
+ const prismaSkillNames = [
123
+ "prisma-cli",
124
+ "prisma-client-api",
125
+ "prisma-compute",
126
+ "prisma-database-setup",
127
+ "prisma-upgrade-v7",
128
+ "prisma-postgres"
129
+ ];
130
+ const DatabaseProviderSchema = z.enum(databaseProviders);
131
+ const PackageManagerSchema = z.enum(packageManagers);
132
+ const SchemaPresetSchema = z.enum(schemaPresets);
133
+ const CreateTemplateSchema = z.enum(createTemplates);
134
+ z.enum(createAddons);
135
+ z.enum(addonInstallScopes);
136
+ z.enum(extensionTargets);
137
+ z.enum(prismaSkillNames);
138
+ const DatabaseUrlSchema = z.string().trim().min(1, "Please enter a valid database URL");
139
+ const CommonCommandOptionsSchema = z.object({
140
+ yes: z.boolean().optional().describe("Skip prompts and accept default choices"),
141
+ verbose: z.boolean().optional().describe("Show verbose command output during setup")
142
+ });
143
+ const PrismaSetupOptionsSchema = z.object({
144
+ provider: DatabaseProviderSchema.optional().describe("Database provider"),
145
+ packageManager: PackageManagerSchema.optional().describe("Package manager used for dependency installation"),
146
+ prismaPostgres: z.boolean().optional().describe("Use Prisma Postgres when provider is postgresql"),
147
+ databaseUrl: DatabaseUrlSchema.optional().describe("DATABASE_URL value"),
148
+ install: z.boolean().optional().describe("Install dependencies with selected package manager"),
149
+ generate: z.boolean().optional().describe("Generate Prisma Client after scaffolding"),
150
+ migrateAndSeed: z.boolean().optional().describe("Run an initial migration and seed after Prisma Client generation"),
151
+ schemaPreset: SchemaPresetSchema.optional().describe("Schema preset to scaffold in prisma/schema.prisma")
152
+ });
153
+ const PrismaSetupCommandInputSchema = CommonCommandOptionsSchema.extend(PrismaSetupOptionsSchema.shape);
154
+ const CreateScaffoldOptionsSchema = z.object({
155
+ name: z.string().trim().min(1, "Please enter a valid project name").optional().describe("Project name / directory"),
156
+ template: CreateTemplateSchema.optional().describe("Project template"),
157
+ skills: z.boolean().optional().describe("Enable skills addon"),
158
+ mcp: z.boolean().optional().describe("Enable MCP addon"),
159
+ extension: z.boolean().optional().describe("Enable extension addon"),
160
+ deploy: z.boolean().optional().describe("Deploy the scaffolded project to Prisma Compute"),
161
+ force: z.boolean().optional().describe("Allow scaffolding into a non-empty target directory")
162
+ });
163
+ const COMPUTE_DEPLOYABLE_TEMPLATES = /* @__PURE__ */ new Set([
164
+ "hono",
165
+ "elysia",
166
+ "nest",
167
+ "next",
168
+ "astro",
169
+ "nuxt",
170
+ "tanstack-start",
171
+ "turborepo"
172
+ ]);
173
+ function isComputeDeployableTemplate(template) {
174
+ return COMPUTE_DEPLOYABLE_TEMPLATES.has(template);
175
+ }
176
+ const CreateCommandInputSchema = PrismaSetupCommandInputSchema.extend(CreateScaffoldOptionsSchema.shape);
177
+ //#endregion
178
+ //#region src/utils/package-manager.ts
179
+ const packageManagerManifestValues = {
180
+ npm: "npm@11.17.0",
181
+ pnpm: "pnpm@11.8.0",
182
+ yarn: "yarn@4.17.0",
183
+ bun: "bun@1.3.14"
184
+ };
185
+ function parseUserAgent(userAgent) {
186
+ if (userAgent?.startsWith("pnpm")) return "pnpm";
187
+ if (userAgent?.startsWith("yarn")) return "yarn";
188
+ if (userAgent?.startsWith("bun")) return "bun";
189
+ if (userAgent?.startsWith("deno")) return "deno";
190
+ if (userAgent?.startsWith("npm")) return "npm";
191
+ return null;
192
+ }
193
+ function parsePackageManagerField(packageManagerField) {
194
+ if (typeof packageManagerField !== "string" || packageManagerField.length === 0) return null;
195
+ const managerName = packageManagerField.split("@")[0];
196
+ const parsed = PackageManagerSchema.safeParse(managerName);
197
+ return parsed.success ? parsed.data : null;
198
+ }
199
+ async function detectFromPackageJson(projectDir) {
200
+ const packageJsonPath = path.join(projectDir, "package.json");
201
+ if (!await fs.pathExists(packageJsonPath)) return null;
202
+ return parsePackageManagerField((await fs.readJson(packageJsonPath)).packageManager);
203
+ }
204
+ async function detectFromDenoConfig(projectDir) {
205
+ for (const configFile of ["deno.json", "deno.jsonc"]) if (await fs.pathExists(path.join(projectDir, configFile))) return "deno";
206
+ return null;
207
+ }
208
+ async function detectFromLockfile(projectDir) {
209
+ for (const check of [
210
+ {
211
+ manager: "pnpm",
212
+ lockfile: "pnpm-lock.yaml"
213
+ },
214
+ {
215
+ manager: "yarn",
216
+ lockfile: "yarn.lock"
217
+ },
218
+ {
219
+ manager: "bun",
220
+ lockfile: "bun.lockb"
221
+ },
222
+ {
223
+ manager: "bun",
224
+ lockfile: "bun.lock"
225
+ },
226
+ {
227
+ manager: "npm",
228
+ lockfile: "package-lock.json"
229
+ },
230
+ {
231
+ manager: "npm",
232
+ lockfile: "npm-shrinkwrap.json"
233
+ },
234
+ {
235
+ manager: "deno",
236
+ lockfile: "deno.lock"
237
+ }
238
+ ]) if (await fs.pathExists(path.join(projectDir, check.lockfile))) return check.manager;
239
+ return null;
240
+ }
241
+ async function detectPackageManager(projectDir = process.cwd()) {
242
+ const fromPackageJson = await detectFromPackageJson(projectDir);
243
+ if (fromPackageJson) return fromPackageJson;
244
+ const fromLockfile = await detectFromLockfile(projectDir);
245
+ if (fromLockfile) return fromLockfile;
246
+ const fromDenoConfig = await detectFromDenoConfig(projectDir);
247
+ if (fromDenoConfig) return fromDenoConfig;
248
+ const fromUserAgent = parseUserAgent(process.env.npm_config_user_agent);
249
+ if (fromUserAgent) return fromUserAgent;
250
+ return "npm";
251
+ }
252
+ function getPackageManagerManifestValue(packageManager) {
253
+ if (!packageManager || packageManager === "deno") return;
254
+ return packageManagerManifestValues[packageManager];
255
+ }
256
+ function getDenoPrismaSpecifier() {
257
+ return `npm:prisma@${dependencyVersionMap.prisma}`;
258
+ }
259
+ function getDenoAllowedScriptSpecifiers() {
260
+ return [
261
+ `npm:prisma@${dependencyVersionMap.prisma}`,
262
+ `npm:@prisma/client@${dependencyVersionMap["@prisma/client"]}`,
263
+ `npm:@prisma/engines@${dependencyVersionMap.prisma}`
264
+ ].join(",");
265
+ }
266
+ function getInstallCommand(packageManager) {
267
+ if (packageManager === "deno") return `deno install --allow-scripts=${getDenoAllowedScriptSpecifiers()}`;
268
+ return `${packageManager} install`;
269
+ }
270
+ function getRunScriptCommand(packageManager, scriptName) {
271
+ switch (packageManager) {
272
+ case "deno": return `deno task ${scriptName}`;
273
+ case "bun": return `bun run ${scriptName}`;
274
+ case "pnpm": return `pnpm run ${scriptName}`;
275
+ case "yarn": return `yarn run ${scriptName}`;
276
+ default: return `npm run ${scriptName}`;
277
+ }
278
+ }
279
+ function getRunScriptInDirectoryCommand(packageManager, directory, scriptName) {
280
+ switch (packageManager) {
281
+ case "deno": return `deno task --cwd ${directory} ${scriptName}`;
282
+ case "bun": return `bun run --cwd ${directory} ${scriptName}`;
283
+ case "pnpm": return `pnpm --dir ${directory} run ${scriptName}`;
284
+ case "yarn": return `yarn --cwd ${directory} run ${scriptName}`;
285
+ default: return `npm --prefix ${directory} run ${scriptName}`;
286
+ }
287
+ }
288
+ function joinCommandParts(parts) {
289
+ return parts.filter((part) => typeof part === "string" && part.length > 0).join(" ");
290
+ }
291
+ function getRuntimeScriptCommand(packageManager, kind, options) {
292
+ const { sourceEntrypoint, builtEntrypoint, denoFlags = [], emit = false } = options;
293
+ if (packageManager === "deno") switch (kind) {
294
+ case "dev": return joinCommandParts([
295
+ "deno",
296
+ "run",
297
+ "-A",
298
+ "--env-file=.env",
299
+ ...denoFlags,
300
+ "--watch",
301
+ sourceEntrypoint
302
+ ]);
303
+ case "build": return `deno check ${sourceEntrypoint}`;
304
+ case "start": return joinCommandParts([
305
+ "deno",
306
+ "run",
307
+ "-A",
308
+ "--env-file=.env",
309
+ ...denoFlags,
310
+ sourceEntrypoint
311
+ ]);
312
+ }
313
+ if (packageManager === "bun") switch (kind) {
314
+ case "dev": return `bun --watch ${sourceEntrypoint}`;
315
+ case "build": return emit ? "tsc" : "tsc --noEmit";
316
+ case "start": return `bun ${sourceEntrypoint}`;
317
+ }
318
+ switch (kind) {
319
+ case "dev": return `tsx watch ${sourceEntrypoint}`;
320
+ case "build": return "tsc";
321
+ case "start": return builtEntrypoint ? `node ${builtEntrypoint}` : `tsx ${sourceEntrypoint}`;
322
+ }
323
+ }
324
+ function getInstallArgs(packageManager) {
325
+ if (packageManager === "deno") return {
326
+ command: "deno",
327
+ args: ["install", `--allow-scripts=${getDenoAllowedScriptSpecifiers()}`]
328
+ };
329
+ return {
330
+ command: packageManager,
331
+ args: ["install"]
332
+ };
333
+ }
334
+ function getPackageExecutionArgs(packageManager, commandArgs, options = {}) {
335
+ switch (packageManager) {
336
+ case "pnpm": return {
337
+ command: "pnpm",
338
+ args: [
339
+ ...options.silent ? ["--silent"] : [],
340
+ "dlx",
341
+ ...commandArgs
342
+ ]
343
+ };
344
+ case "yarn": return {
345
+ command: "yarn",
346
+ args: [
347
+ "dlx",
348
+ ...options.silent ? ["--quiet"] : [],
349
+ ...commandArgs
350
+ ]
351
+ };
352
+ case "bun": return {
353
+ command: "bunx",
354
+ args: [...options.silent ? ["--silent"] : [], ...commandArgs]
355
+ };
356
+ case "deno": {
357
+ const [packageName, ...args] = commandArgs;
358
+ if (!packageName) throw new Error("Package execution requires a package name.");
359
+ return {
360
+ command: "deno",
361
+ args: [
362
+ "run",
363
+ "-A",
364
+ `npm:${packageName}`,
365
+ ...args
366
+ ]
367
+ };
368
+ }
369
+ default: return {
370
+ command: "npx",
371
+ args: [...options.silent ? ["--yes", "--no-update-notifier"] : [], ...commandArgs]
372
+ };
373
+ }
374
+ }
375
+ function getPackageExecutionCommand(packageManager, commandArgs, options = {}) {
376
+ const execution = getPackageExecutionArgs(packageManager, commandArgs, options);
377
+ return [execution.command, ...execution.args].join(" ");
378
+ }
379
+ function getPrismaCliArgs(packageManager, prismaArgs) {
380
+ if (packageManager === "deno") return {
381
+ command: "deno",
382
+ args: [
383
+ "run",
384
+ "-A",
385
+ "--env-file=.env",
386
+ getDenoPrismaSpecifier(),
387
+ ...prismaArgs
388
+ ]
389
+ };
390
+ if (packageManager === "bun") return {
391
+ command: "bun",
392
+ args: [
393
+ "--env-file=.env",
394
+ "./node_modules/.bin/prisma",
395
+ ...prismaArgs
396
+ ]
397
+ };
398
+ if (packageManager === "pnpm") return {
399
+ command: "pnpm",
400
+ args: [
401
+ "exec",
402
+ "prisma",
403
+ ...prismaArgs
404
+ ]
405
+ };
406
+ if (packageManager === "yarn") return {
407
+ command: "yarn",
408
+ args: [
409
+ "exec",
410
+ "prisma",
411
+ ...prismaArgs
412
+ ]
413
+ };
414
+ return getPackageExecutionArgs(packageManager, ["prisma", ...prismaArgs]);
415
+ }
416
+ function getPrismaCliCommand$1(packageManager, prismaArgs) {
417
+ const execution = getPrismaCliArgs(packageManager, prismaArgs);
418
+ return [execution.command, ...execution.args].join(" ");
419
+ }
420
+ //#endregion
421
+ //#region src/templates/shared.ts
422
+ function getOptionalHashString(hash, key) {
423
+ const value = hash[key];
424
+ return typeof value === "string" && value.length > 0 ? value : void 0;
425
+ }
426
+ function getOptionalHashStringList(hash, key) {
427
+ return getOptionalHashString(hash, key)?.split(" ") ?? [];
428
+ }
429
+ function getSeedCommand(packageManager) {
430
+ if (packageManager === "deno") return "deno run -A --env-file=.env ./prisma/seed.ts";
431
+ if (packageManager === "bun") return "bun ./prisma/seed.ts";
432
+ return "tsx ./prisma/seed.ts";
433
+ }
434
+ function getPrismaCommand(packageManager, subcommand) {
435
+ if (packageManager === "deno") return `deno run -A --env-file=.env npm:prisma@${dependencyVersionMap.prisma} ${subcommand}`;
436
+ if (packageManager === "bun") return `bun --env-file=.env ./node_modules/.bin/prisma ${subcommand}`;
437
+ return `prisma ${subcommand}`;
438
+ }
439
+ Handlebars.registerHelper("eq", (left, right) => left === right);
440
+ Handlebars.registerHelper("runScriptCommand", (packageManager, scriptName) => packageManager ? getRunScriptCommand(packageManager, scriptName) : "");
441
+ Handlebars.registerHelper("runScriptInDirectoryCommand", (packageManager, directory, scriptName) => packageManager ? getRunScriptInDirectoryCommand(packageManager, directory, scriptName) : "");
442
+ Handlebars.registerHelper("packageManagerManifestValue", (packageManager) => getPackageManagerManifestValue(packageManager) ?? "");
443
+ Handlebars.registerHelper("requiresDotenvConfigImport", (packageManager) => requiresDotenvConfigImport(packageManager));
444
+ Handlebars.registerHelper("requiresPrismaConfigDotenvImport", (packageManager) => requiresPrismaConfigDotenvImport(packageManager));
445
+ Handlebars.registerHelper("sqliteAdapterPackage", () => "@prisma/adapter-libsql");
446
+ Handlebars.registerHelper("sqliteAdapterClass", () => "PrismaLibSql");
447
+ Handlebars.registerHelper("seedCommand", (packageManager) => getSeedCommand(packageManager));
448
+ Handlebars.registerHelper("prismaCommand", (packageManager, subcommand) => getPrismaCommand(packageManager, subcommand));
449
+ Handlebars.registerHelper("runtimeScript", (packageManager, kind, sourceEntrypoint, builtEntrypoint, options) => {
450
+ if (!packageManager) return "";
451
+ const hash = options.hash;
452
+ return getRuntimeScriptCommand(packageManager, kind, {
453
+ sourceEntrypoint,
454
+ builtEntrypoint,
455
+ denoFlags: getOptionalHashStringList(hash, "denoFlags"),
456
+ emit: hash.emit === true
457
+ });
458
+ });
459
+ function findPackageRoot(startDir) {
460
+ let currentDir = startDir;
461
+ while (true) {
462
+ if (existsSync(path.join(currentDir, "package.json"))) return currentDir;
463
+ const parentDir = path.dirname(currentDir);
464
+ if (parentDir === currentDir) break;
465
+ currentDir = parentDir;
466
+ }
467
+ throw new Error(`Unable to locate package root from: ${startDir}`);
468
+ }
469
+ function resolveTemplatesDir(relativeTemplatesDir) {
470
+ const currentFilePath = fileURLToPath(import.meta.url);
471
+ const packageRoot = findPackageRoot(path.dirname(currentFilePath));
472
+ const templatePath = path.join(packageRoot, relativeTemplatesDir);
473
+ if (!existsSync(templatePath)) throw new Error(`Template directory not found at: ${templatePath}`);
474
+ return templatePath;
475
+ }
476
+ async function getTemplateFilesRecursively(dir) {
477
+ const entries = await fs.readdir(dir, { withFileTypes: true });
478
+ return (await Promise.all(entries.map(async (entry) => {
479
+ const entryPath = path.join(dir, entry.name);
480
+ if (entry.isDirectory()) return getTemplateFilesRecursively(entryPath);
481
+ if (!entry.isFile()) return [];
482
+ return [entryPath];
483
+ }))).flat();
484
+ }
485
+ function stripHbsExtension(filePath) {
486
+ return filePath.endsWith(".hbs") ? filePath.slice(0, -4) : filePath;
487
+ }
488
+ function ensureTrailingNewline(content) {
489
+ return content.endsWith("\n") ? content : `${content}\n`;
490
+ }
491
+ async function renderTemplateFile(opts) {
492
+ const { templateFilePath, outputPath, context } = opts;
493
+ const templateContent = await fs.readFile(templateFilePath, "utf8");
494
+ const outputContent = templateFilePath.endsWith(".hbs") ? Handlebars.compile(templateContent, {
495
+ noEscape: true,
496
+ strict: true
497
+ })(context) : templateContent;
498
+ if (templateFilePath.endsWith(".hbs") && outputContent.trim().length === 0) return;
499
+ await fs.outputFile(outputPath, ensureTrailingNewline(outputContent), "utf8");
500
+ }
501
+ async function renderTemplateTree(opts) {
502
+ const { templateRoot, outputDir, context } = opts;
503
+ const templateFiles = await getTemplateFilesRecursively(templateRoot);
504
+ for (const templateFilePath of templateFiles) {
505
+ const relativeOutputPath = stripHbsExtension(path.relative(templateRoot, templateFilePath));
506
+ await renderTemplateFile({
507
+ templateFilePath,
508
+ outputPath: path.join(outputDir, relativeOutputPath),
509
+ context
510
+ });
511
+ }
512
+ }
513
+ //#endregion
514
+ //#region src/templates/render-create-template.ts
515
+ function getCreateTemplateDir(template) {
516
+ return resolveTemplatesDir(`templates/create/${template}`);
517
+ }
518
+ function createTemplateContext(projectName, provider, schemaPreset, packageManager, compute) {
519
+ return {
520
+ projectName,
521
+ provider,
522
+ schemaPreset,
523
+ packageManager,
524
+ compute
525
+ };
526
+ }
527
+ async function scaffoldCreateTemplate(opts) {
528
+ const { projectDir, projectName, template, provider, schemaPreset, packageManager } = opts;
529
+ await renderTemplateTree({
530
+ templateRoot: getCreateTemplateDir(template),
531
+ outputDir: projectDir,
532
+ context: createTemplateContext(projectName, provider, schemaPreset, packageManager, opts.compute === true)
533
+ });
534
+ }
535
+ //#endregion
536
+ //#region src/constants/db-packages.ts
537
+ function getDbPackages(provider, _packageManager) {
538
+ switch (provider) {
539
+ case "postgresql":
540
+ case "cockroachdb": return "@prisma/adapter-pg";
541
+ case "mysql": return "@prisma/adapter-mariadb";
542
+ case "sqlite": return "@prisma/adapter-libsql";
543
+ case "sqlserver": return "@prisma/adapter-mssql";
544
+ default: throw new Error(`Unsupported database provider: ${String(provider)}`);
545
+ }
546
+ }
547
+ //#endregion
548
+ //#region src/tasks/install.ts
549
+ function getPrismaScriptMap(packageManager) {
550
+ if (packageManager === "deno") {
551
+ const prismaCli = `deno run -A --env-file=.env ${getDenoPrismaSpecifier()}`;
552
+ return {
553
+ "db:generate": `${prismaCli} generate`,
554
+ "db:push": `${prismaCli} db push`,
555
+ "db:migrate": `${prismaCli} migrate dev`,
556
+ "db:seed": `${prismaCli} db seed`
557
+ };
558
+ }
559
+ if (packageManager === "bun") {
560
+ const prismaCli = "bun --env-file=.env ./node_modules/.bin/prisma";
561
+ return {
562
+ "db:generate": `${prismaCli} generate`,
563
+ "db:push": `${prismaCli} db push`,
564
+ "db:migrate": `${prismaCli} migrate dev`,
565
+ "db:seed": `${prismaCli} db seed`
566
+ };
567
+ }
568
+ return {
569
+ "db:generate": "prisma generate",
570
+ "db:push": "prisma db push",
571
+ "db:migrate": "prisma migrate dev",
572
+ "db:seed": "prisma db seed"
573
+ };
574
+ }
575
+ function getVersion(packageName) {
576
+ return dependencyVersionMap[packageName];
577
+ }
578
+ function unique(items) {
579
+ return [...new Set(items)];
580
+ }
581
+ function sortRecord(record) {
582
+ return Object.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));
583
+ }
584
+ async function projectContainsText(projectDir, text) {
585
+ const directories = [projectDir];
586
+ while (directories.length > 0) {
587
+ const currentDirectory = directories.pop();
588
+ if (!currentDirectory) continue;
589
+ const entries = await fs.readdir(currentDirectory, { withFileTypes: true });
590
+ for (const entry of entries) {
591
+ if (entry.name === "node_modules" || entry.name === ".git") continue;
592
+ const entryPath = path.join(currentDirectory, entry.name);
593
+ if (entry.isDirectory()) {
594
+ directories.push(entryPath);
595
+ continue;
596
+ }
597
+ if (!entry.isFile() || !/\.(c|m)?[jt]sx?$/.test(entry.name)) continue;
598
+ if ((await fs.readFile(entryPath, "utf8")).includes(text)) return true;
599
+ }
600
+ }
601
+ return false;
602
+ }
603
+ async function addPackageDependency(opts) {
604
+ const { dependencies = [], devDependencies = [], customDependencies = {}, scripts = {}, scriptMode, projectDir } = opts;
605
+ const pkgJsonPath = path.join(projectDir, "package.json");
606
+ if (!await fs.pathExists(pkgJsonPath)) throw new Error(`No package.json found in ${projectDir}. Run this command inside an existing JavaScript/TypeScript project.`);
607
+ const pkgJson = await fs.readJson(pkgJsonPath);
608
+ if (!pkgJson.dependencies) pkgJson.dependencies = {};
609
+ if (!pkgJson.devDependencies) pkgJson.devDependencies = {};
610
+ if (!pkgJson.scripts) pkgJson.scripts = {};
611
+ for (const pkgName of unique(dependencies)) {
612
+ const version = getVersion(pkgName);
613
+ if (version) pkgJson.dependencies[pkgName] = version;
614
+ else console.warn(`Warning: Dependency ${pkgName} not found in version map.`);
615
+ }
616
+ for (const pkgName of unique(devDependencies)) {
617
+ const version = getVersion(pkgName);
618
+ if (version) pkgJson.devDependencies[pkgName] = version;
619
+ else console.warn(`Warning: Dev dependency ${pkgName} not found in version map.`);
620
+ }
621
+ for (const [pkgName, version] of Object.entries(customDependencies)) pkgJson.dependencies[pkgName] = version;
622
+ for (const [scriptName, command] of Object.entries(scripts)) {
623
+ if (scriptMode === "if-missing") {
624
+ if (typeof pkgJson.scripts[scriptName] !== "string" || pkgJson.scripts[scriptName].trim().length === 0) pkgJson.scripts[scriptName] = command;
625
+ continue;
626
+ }
627
+ pkgJson.scripts[scriptName] = command;
628
+ }
629
+ pkgJson.dependencies = sortRecord(pkgJson.dependencies);
630
+ pkgJson.devDependencies = sortRecord(pkgJson.devDependencies);
631
+ await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
632
+ }
633
+ async function writePrismaDependencies(provider, packageManager, projectDir = process.cwd()) {
634
+ const dependencies = ["@prisma/client"];
635
+ const devDependencies = ["prisma"];
636
+ dependencies.push(getDbPackages(provider, packageManager));
637
+ if (provider === "sqlite") dependencies.push("@libsql/client");
638
+ if (requiresDotenvConfigImport(packageManager) || await projectContainsText(projectDir, "dotenv/config")) dependencies.push("dotenv");
639
+ await addPackageDependency({
640
+ dependencies,
641
+ devDependencies,
642
+ scripts: getPrismaScriptMap(packageManager),
643
+ scriptMode: "if-missing",
644
+ projectDir
645
+ });
646
+ }
647
+ async function writeCreateTemplateDependencies(opts) {
648
+ const { template, packageManager, projectDir = process.cwd() } = opts;
649
+ const targets = getCreateTemplateDependencies(template, packageManager);
650
+ for (const dependencyTarget of targets) {
651
+ const targetDirectory = path.join(projectDir, path.dirname(dependencyTarget.packageJsonPath));
652
+ await addPackageDependency({
653
+ dependencies: dependencyTarget.dependencies,
654
+ devDependencies: dependencyTarget.devDependencies,
655
+ customDependencies: dependencyTarget.customDependencies,
656
+ projectDir: targetDirectory
657
+ });
658
+ }
659
+ }
660
+ async function installProjectDependencies(packageManager, projectDir = process.cwd(), options = {}) {
661
+ const verbose = options.verbose === true;
662
+ const installCommand = getInstallArgs(packageManager);
663
+ await execa(installCommand.command, installCommand.args, {
664
+ cwd: projectDir,
665
+ stdio: verbose ? "inherit" : "pipe"
666
+ });
667
+ }
668
+ //#endregion
669
+ //#region src/tasks/prisma-postgres.ts
670
+ const PRISMA_POSTGRES_TEMPORARY_NOTICE = "Prisma Postgres is temporary for 24 hours. Claim this database before it expires using CLAIM_URL.";
671
+ const CREATE_DB_COMMAND_ARGS = ["create-db@latest", "--json"];
672
+ function parseCreateDbJson(rawOutput) {
673
+ const trimmed = rawOutput.trim();
674
+ if (!trimmed) throw new Error("create-db returned empty output.");
675
+ const jsonCandidates = [trimmed];
676
+ const firstBrace = trimmed.indexOf("{");
677
+ const lastBrace = trimmed.lastIndexOf("}");
678
+ if (firstBrace !== -1 && lastBrace > firstBrace) jsonCandidates.push(trimmed.slice(firstBrace, lastBrace + 1));
679
+ for (const candidate of jsonCandidates) try {
680
+ return JSON.parse(candidate);
681
+ } catch {}
682
+ throw new Error(`Unable to parse create-db JSON output: ${trimmed}`);
683
+ }
684
+ function pickConnectionString(payload) {
685
+ if (typeof payload.connectionString === "string" && payload.connectionString.length > 0) return payload.connectionString;
686
+ if (typeof payload.databaseUrl === "string" && payload.databaseUrl.length > 0) return payload.databaseUrl;
687
+ }
688
+ function extractErrorMessage(payload, fallback) {
689
+ if (typeof payload.message === "string" && payload.message.length > 0) return payload.message;
690
+ if (typeof payload.error === "string" && payload.error.length > 0) return payload.error;
691
+ return fallback;
692
+ }
693
+ async function provisionPrismaPostgres(packageManager, projectDir = process.cwd()) {
694
+ const command = getPackageExecutionArgs(packageManager, [...CREATE_DB_COMMAND_ARGS]);
695
+ const commandString = getCreateDbCommand(packageManager);
696
+ let stdout;
697
+ try {
698
+ stdout = (await execa(command.command, command.args, {
699
+ cwd: projectDir,
700
+ stdio: "pipe"
701
+ })).stdout;
702
+ } catch (error) {
703
+ if (error instanceof Error && "stderr" in error) {
704
+ const stderr = String(error.stderr ?? "").trim();
705
+ const message = stderr.length > 0 ? stderr : error.message;
706
+ throw new Error(`Failed to run ${commandString}: ${message}`);
707
+ }
708
+ throw error;
709
+ }
710
+ const payload = parseCreateDbJson(stdout);
711
+ if (payload.success === false) throw new Error(extractErrorMessage(payload, "create-db reported failure."));
712
+ const databaseUrl = pickConnectionString(payload);
713
+ if (!databaseUrl) throw new Error("create-db did not return a connection string.");
714
+ return {
715
+ databaseUrl,
716
+ claimUrl: typeof payload.claimUrl === "string" && payload.claimUrl.length > 0 ? payload.claimUrl : typeof payload.claimURL === "string" && payload.claimURL.length > 0 ? payload.claimURL : void 0
717
+ };
718
+ }
719
+ function getCreateDbCommand(packageManager) {
720
+ return getPackageExecutionCommand(packageManager, [...CREATE_DB_COMMAND_ARGS]);
721
+ }
722
+ //#endregion
723
+ //#region src/tasks/setup-prisma.ts
724
+ const DEFAULT_DATABASE_PROVIDER = "postgresql";
725
+ const DEFAULT_SCHEMA_PRESET$1 = "empty";
726
+ const DEFAULT_PRISMA_POSTGRES = true;
727
+ const DEFAULT_INSTALL = true;
728
+ const DEFAULT_GENERATE = true;
729
+ const DEFAULT_MIGRATE_AND_SEED = true;
730
+ const PRISMA_POSTGRES_MIGRATION_DELAY_MS = 2e3;
731
+ const requiredPrismaFileGroups = [
732
+ ["prisma/schema.prisma", "packages/db/prisma/schema.prisma"],
733
+ ["prisma/seed.ts", "packages/db/prisma/seed.ts"],
734
+ ["prisma.config.ts", "packages/db/prisma.config.ts"],
735
+ [
736
+ "src/lib/prisma.ts",
737
+ "src/lib/prisma.server.ts",
738
+ "src/lib/server/prisma.ts",
739
+ "server/utils/prisma.ts",
740
+ "packages/db/src/client.ts"
741
+ ]
742
+ ];
743
+ async function resolvePrismaProjectDir(projectDir) {
744
+ const monorepoDbDir = path.join(projectDir, "packages/db");
745
+ if (await fs.pathExists(path.join(monorepoDbDir, "prisma/schema.prisma"))) return monorepoDbDir;
746
+ return projectDir;
747
+ }
748
+ async function promptForDatabaseProvider() {
749
+ const databaseProvider = await select({
750
+ message: "Select your database",
751
+ initialValue: DEFAULT_DATABASE_PROVIDER,
752
+ options: [
753
+ {
754
+ value: "postgresql",
755
+ label: "PostgreSQL",
756
+ hint: "Default"
757
+ },
758
+ {
759
+ value: "mysql",
760
+ label: "MySQL"
761
+ },
762
+ {
763
+ value: "sqlite",
764
+ label: "SQLite"
765
+ },
766
+ {
767
+ value: "sqlserver",
768
+ label: "SQL Server"
769
+ },
770
+ {
771
+ value: "cockroachdb",
772
+ label: "CockroachDB"
773
+ }
774
+ ]
775
+ });
776
+ if (isCancel(databaseProvider)) {
777
+ cancel("Operation cancelled.");
778
+ return;
779
+ }
780
+ return DatabaseProviderSchema.parse(databaseProvider);
781
+ }
782
+ function getPackageManagerHint(option, detected) {
783
+ if (option === detected) return "Detected";
784
+ if (option === "bun") return "Fast runtime + package manager";
785
+ if (option === "deno") return "Runtime + package manager";
786
+ }
787
+ async function promptForPackageManager(detectedPackageManager) {
788
+ const packageManager = await select({
789
+ message: "Choose package manager",
790
+ initialValue: detectedPackageManager,
791
+ options: [
792
+ {
793
+ value: "npm",
794
+ label: "npm",
795
+ hint: getPackageManagerHint("npm", detectedPackageManager)
796
+ },
797
+ {
798
+ value: "pnpm",
799
+ label: "pnpm",
800
+ hint: getPackageManagerHint("pnpm", detectedPackageManager)
801
+ },
802
+ {
803
+ value: "yarn",
804
+ label: "yarn",
805
+ hint: getPackageManagerHint("yarn", detectedPackageManager)
806
+ },
807
+ {
808
+ value: "bun",
809
+ label: "bun",
810
+ hint: getPackageManagerHint("bun", detectedPackageManager)
811
+ },
812
+ {
813
+ value: "deno",
814
+ label: "deno",
815
+ hint: getPackageManagerHint("deno", detectedPackageManager)
816
+ }
817
+ ]
818
+ });
819
+ if (isCancel(packageManager)) {
820
+ cancel("Operation cancelled.");
821
+ return;
822
+ }
823
+ return PackageManagerSchema.parse(packageManager);
824
+ }
825
+ async function promptForDependencyInstall(packageManager) {
826
+ const shouldInstall = await confirm({
827
+ message: `Install dependencies now with ${getInstallCommand(packageManager)}?`,
828
+ initialValue: true
829
+ });
830
+ if (isCancel(shouldInstall)) {
831
+ cancel("Operation cancelled.");
832
+ return;
833
+ }
834
+ return Boolean(shouldInstall);
835
+ }
836
+ async function promptForMigrateAndSeed() {
837
+ const shouldMigrateAndSeed = await confirm({
838
+ message: "Run an initial migration and seed your database now?",
839
+ initialValue: DEFAULT_MIGRATE_AND_SEED
840
+ });
841
+ if (isCancel(shouldMigrateAndSeed)) {
842
+ cancel("Operation cancelled.");
843
+ return;
844
+ }
845
+ return Boolean(shouldMigrateAndSeed);
846
+ }
847
+ async function promptForPrismaPostgres() {
848
+ const shouldUsePrismaPostgres = await confirm({
849
+ message: "Use Prisma Postgres and write DATABASE_URL automatically?",
850
+ initialValue: true
851
+ });
852
+ if (isCancel(shouldUsePrismaPostgres)) {
853
+ cancel("Operation cancelled.");
854
+ return;
855
+ }
856
+ return Boolean(shouldUsePrismaPostgres);
857
+ }
858
+ function getCommandErrorMessage(error) {
859
+ if (error instanceof Error && "stderr" in error) {
860
+ const stderr = String(error.stderr ?? "").trim();
861
+ if (stderr.length > 0) return stderr;
862
+ }
863
+ return error instanceof Error ? error.message : String(error);
864
+ }
865
+ async function collectPrismaSetupInitialContext(input, options = {}) {
866
+ const projectDir = path.resolve(options.projectDir ?? process.cwd());
867
+ const useDefaults = input.yes === true;
868
+ const verbose = input.verbose === true;
869
+ const shouldGenerate = input.generate ?? DEFAULT_GENERATE;
870
+ const databaseProvider = input.provider ?? (useDefaults ? DEFAULT_DATABASE_PROVIDER : await promptForDatabaseProvider());
871
+ if (!databaseProvider) return;
872
+ const schemaPreset = input.schemaPreset ?? options.defaultSchemaPreset ?? DEFAULT_SCHEMA_PRESET$1;
873
+ const databaseUrl = input.databaseUrl;
874
+ const detectedPackageManager = await detectPackageManager(projectDir);
875
+ const packageManager = input.packageManager ?? (useDefaults ? detectedPackageManager : await promptForPackageManager(detectedPackageManager));
876
+ if (!packageManager) return;
877
+ const shouldInstall = input.install ?? (useDefaults ? DEFAULT_INSTALL : await promptForDependencyInstall(packageManager));
878
+ if (shouldInstall === void 0) return;
879
+ return {
880
+ projectDir,
881
+ verbose,
882
+ shouldGenerate,
883
+ databaseProvider,
884
+ schemaPreset,
885
+ databaseUrl,
886
+ packageManager,
887
+ shouldInstall
888
+ };
889
+ }
890
+ async function completePrismaSetupContext(input, context, options = {}) {
891
+ const useDefaults = input.yes === true;
892
+ let shouldUsePrismaPostgres = false;
893
+ const shouldUseComputePostgres = context.databaseProvider === "postgresql" && !context.databaseUrl && options.useComputePostgres === true;
894
+ if (context.databaseProvider === "postgresql" && !context.databaseUrl && !shouldUseComputePostgres) {
895
+ const prismaPostgresChoice = input.prismaPostgres ?? (useDefaults ? DEFAULT_PRISMA_POSTGRES : await promptForPrismaPostgres());
896
+ if (prismaPostgresChoice === void 0) return;
897
+ shouldUsePrismaPostgres = prismaPostgresChoice;
898
+ }
899
+ const shouldMigrateAndSeed = !(context.shouldInstall && context.shouldGenerate && !(shouldUseComputePostgres && options.skipMigrateAndSeedPrompt)) ? false : input.migrateAndSeed ?? (useDefaults ? DEFAULT_MIGRATE_AND_SEED : await promptForMigrateAndSeed());
900
+ if (shouldMigrateAndSeed === void 0) return;
901
+ return {
902
+ ...context,
903
+ shouldUsePrismaPostgres,
904
+ shouldMigrateAndSeed
905
+ };
906
+ }
907
+ function getDefaultDatabaseUrl(provider) {
908
+ switch (provider) {
909
+ case "postgresql": return "postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public";
910
+ case "cockroachdb": return "postgresql://johndoe:randompassword@localhost:26257/mydb?schema=public";
911
+ case "mysql": return "mysql://johndoe:randompassword@localhost:3306/mydb";
912
+ case "sqlite": return "file:./dev.db";
913
+ case "sqlserver": return "sqlserver://localhost:1433;database=mydb;user=SA;password=randompassword;";
914
+ default: throw new Error(`Unsupported provider: ${String(provider)}`);
915
+ }
916
+ }
917
+ function escapeRegExp(value) {
918
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
919
+ }
920
+ function escapeEnvValue(value) {
921
+ if (/[\r\n]/.test(value)) throw new Error("Environment variable values must be single-line.");
922
+ return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
923
+ }
924
+ function hasEnvVar(content, envVarName) {
925
+ const escapedName = escapeRegExp(envVarName);
926
+ return new RegExp(`(^|\\n)\\s*${escapedName}\\s*=`).test(content);
927
+ }
928
+ function hasEnvComment(content, comment) {
929
+ const escapedComment = escapeRegExp(comment);
930
+ return new RegExp(`(^|\\n)\\s*#\\s*${escapedComment}\\s*(?=\\n|$)`).test(content);
931
+ }
932
+ async function ensureEnvVarInEnv(projectDir, envVarName, envVarValue, opts) {
933
+ const envPath = path.join(projectDir, ".env");
934
+ const envLine = `${envVarName}="${escapeEnvValue(envVarValue)}"`;
935
+ if (!await fs.pathExists(envPath)) {
936
+ const content = opts.comment ? `# ${opts.comment}\n${envLine}\n` : `${envLine}\n`;
937
+ await fs.writeFile(envPath, content, "utf8");
938
+ return;
939
+ }
940
+ const existingContent = await fs.readFile(envPath, "utf8");
941
+ if (hasEnvVar(existingContent, envVarName)) {
942
+ if (opts.mode === "keep-existing") return;
943
+ const escapedName = escapeRegExp(envVarName);
944
+ const lineRegex = new RegExp(`(^|\\n)\\s*${escapedName}\\s*=.*(?=\\n|$)`, "gm");
945
+ const updatedContent = existingContent.replace(lineRegex, `$1${envLine}`);
946
+ if (updatedContent === existingContent) return;
947
+ await fs.writeFile(envPath, updatedContent, "utf8");
948
+ return;
949
+ }
950
+ const insertion = `${existingContent.endsWith("\n") ? "" : "\n"}${opts.comment ? `\n# ${opts.comment}\n` : "\n"}${envLine}\n`;
951
+ await fs.appendFile(envPath, insertion, "utf8");
952
+ }
953
+ async function ensureEnvComment(projectDir, comment) {
954
+ const envPath = path.join(projectDir, ".env");
955
+ const commentLine = `# ${comment}`;
956
+ if (!await fs.pathExists(envPath)) {
957
+ await fs.writeFile(envPath, `${commentLine}\n`, "utf8");
958
+ return;
959
+ }
960
+ const existingContent = await fs.readFile(envPath, "utf8");
961
+ if (hasEnvComment(existingContent, comment)) return;
962
+ const separator = existingContent.endsWith("\n") ? "" : "\n";
963
+ await fs.appendFile(envPath, `${separator}${commentLine}\n`, "utf8");
964
+ }
965
+ function hasGitignoreEntry(content, entry) {
966
+ const escapedEntry = escapeRegExp(entry);
967
+ const escapedWithLeadingSlash = escapeRegExp(`/${entry}`);
968
+ const escapedWithTrailingSlash = escapeRegExp(`${entry}/`);
969
+ const escapedWithLeadingAndTrailingSlash = escapeRegExp(`/${entry}/`);
970
+ return new RegExp(`(^|\\n)\\s*(?:${escapedEntry}|${escapedWithLeadingSlash}|${escapedWithTrailingSlash}|${escapedWithLeadingAndTrailingSlash})\\s*(?=\\n|$)`).test(content);
971
+ }
972
+ async function ensureGitignoreEntry(projectDir, entry) {
973
+ const gitignorePath = path.join(projectDir, ".gitignore");
974
+ if (!await fs.pathExists(gitignorePath)) {
975
+ await fs.writeFile(gitignorePath, `${entry}\n`, "utf8");
976
+ return;
977
+ }
978
+ const existingContent = await fs.readFile(gitignorePath, "utf8");
979
+ if (hasGitignoreEntry(existingContent, entry)) return;
980
+ const separator = existingContent.endsWith("\n") ? "" : "\n";
981
+ await fs.appendFile(gitignorePath, `${separator}${entry}\n`, "utf8");
982
+ }
983
+ async function ensureRequiredPrismaFiles(projectDir) {
984
+ const missingFiles = [];
985
+ for (const candidates of requiredPrismaFileGroups) {
986
+ let foundCandidate = false;
987
+ for (const relativePath of candidates) {
988
+ const absolutePath = path.join(projectDir, relativePath);
989
+ if (await fs.pathExists(absolutePath)) {
990
+ foundCandidate = true;
991
+ break;
992
+ }
993
+ }
994
+ if (!foundCandidate) missingFiles.push(candidates.join(" or "));
995
+ }
996
+ if (missingFiles.length > 0) throw new Error(`Template is missing required Prisma files: ${missingFiles.join(", ")}`);
997
+ }
998
+ async function finalizePrismaFiles(options) {
999
+ const projectDir = options.projectDir ?? process.cwd();
1000
+ const prismaProjectDir = await resolvePrismaProjectDir(projectDir);
1001
+ await ensureRequiredPrismaFiles(projectDir);
1002
+ const generatedDir = await fs.pathExists(path.join(prismaProjectDir, "server/utils/prisma.ts")) ? "server/generated" : "src/generated";
1003
+ await ensureEnvVarInEnv(prismaProjectDir, "DATABASE_URL", options.databaseUrl ?? getDefaultDatabaseUrl(options.provider), {
1004
+ mode: options.databaseUrl ? "upsert" : "keep-existing",
1005
+ comment: "Added by create-prisma"
1006
+ });
1007
+ if (options.claimUrl) {
1008
+ await ensureEnvVarInEnv(prismaProjectDir, "CLAIM_URL", options.claimUrl, {
1009
+ mode: "upsert",
1010
+ comment: PRISMA_POSTGRES_TEMPORARY_NOTICE
1011
+ });
1012
+ await ensureEnvComment(prismaProjectDir, PRISMA_POSTGRES_TEMPORARY_NOTICE);
1013
+ }
1014
+ await ensureGitignoreEntry(prismaProjectDir, generatedDir);
1015
+ }
1016
+ async function provisionPrismaPostgresIfNeeded(context, projectDir) {
1017
+ if (!context.shouldUsePrismaPostgres) return { databaseUrl: context.databaseUrl };
1018
+ const createDbCommand = getCreateDbCommand(context.packageManager);
1019
+ const prismaPostgresSpinner = spinner();
1020
+ prismaPostgresSpinner.start(`Provisioning Prisma Postgres with ${createDbCommand}...`);
1021
+ try {
1022
+ const prismaPostgresResult = await provisionPrismaPostgres(context.packageManager, projectDir);
1023
+ prismaPostgresSpinner.stop("Prisma Postgres database provisioned.");
1024
+ return {
1025
+ databaseUrl: prismaPostgresResult.databaseUrl,
1026
+ claimUrl: prismaPostgresResult.claimUrl
1027
+ };
1028
+ } catch (error) {
1029
+ const errorMessage = error instanceof Error ? error.message : String(error);
1030
+ prismaPostgresSpinner.stop("Could not provision Prisma Postgres.");
1031
+ return {
1032
+ databaseUrl: context.databaseUrl,
1033
+ warning: `Prisma Postgres provisioning failed: ${errorMessage}`
1034
+ };
1035
+ }
1036
+ }
1037
+ async function writeDependenciesForContext(context, projectDir) {
1038
+ const prismaProjectDir = await resolvePrismaProjectDir(projectDir);
1039
+ try {
1040
+ await writePrismaDependencies(context.databaseProvider, context.packageManager, prismaProjectDir);
1041
+ return true;
1042
+ } catch (error) {
1043
+ cancel(getCommandErrorMessage(error));
1044
+ return false;
1045
+ }
1046
+ }
1047
+ async function installDependenciesForContext(context, projectDir) {
1048
+ if (!context.shouldInstall) return true;
1049
+ const installCommand = getInstallCommand(context.packageManager);
1050
+ if (context.verbose) {
1051
+ log.step(`Running ${installCommand}`);
1052
+ try {
1053
+ await installProjectDependencies(context.packageManager, projectDir, { verbose: context.verbose });
1054
+ log.success("Dependencies installed.");
1055
+ return true;
1056
+ } catch (error) {
1057
+ cancel(`Failed to run ${installCommand}: ${getCommandErrorMessage(error)}`);
1058
+ return false;
1059
+ }
1060
+ }
1061
+ const installSpinner = spinner();
1062
+ installSpinner.start(`Running ${installCommand}...`);
1063
+ try {
1064
+ await installProjectDependencies(context.packageManager, projectDir, { verbose: context.verbose });
1065
+ installSpinner.stop("Dependencies installed.");
1066
+ return true;
1067
+ } catch (error) {
1068
+ installSpinner.stop("Could not install dependencies.");
1069
+ cancel(`Failed to run ${installCommand}: ${getCommandErrorMessage(error)}`);
1070
+ return false;
1071
+ }
1072
+ }
1073
+ async function finalizePrismaFilesForContext(context, projectDir, provisionResult) {
1074
+ const initSpinner = spinner();
1075
+ initSpinner.start("Preparing Prisma files...");
1076
+ try {
1077
+ await finalizePrismaFiles({
1078
+ provider: context.databaseProvider,
1079
+ databaseUrl: provisionResult.databaseUrl,
1080
+ claimUrl: provisionResult.claimUrl,
1081
+ projectDir
1082
+ });
1083
+ initSpinner.stop("Prisma files ready.");
1084
+ return true;
1085
+ } catch (error) {
1086
+ initSpinner.stop("Could not prepare Prisma files.");
1087
+ cancel(getCommandErrorMessage(error));
1088
+ return false;
1089
+ }
1090
+ }
1091
+ async function generatePrismaClientForContext(context, projectDir) {
1092
+ const prismaProjectDir = await resolvePrismaProjectDir(projectDir);
1093
+ if (!context.shouldGenerate) return { didGenerateClient: false };
1094
+ const generateCommand = getPrismaCliCommand$1(context.packageManager, ["generate"]);
1095
+ if (context.verbose) log.step(`Running ${generateCommand}`);
1096
+ const generateSpinner = context.verbose ? void 0 : spinner();
1097
+ generateSpinner?.start("Generating Prisma Client...");
1098
+ try {
1099
+ const generateArgs = getPrismaCliArgs(context.packageManager, ["generate"]);
1100
+ await execa(generateArgs.command, generateArgs.args, {
1101
+ cwd: prismaProjectDir,
1102
+ stdio: context.verbose ? "inherit" : "pipe"
1103
+ });
1104
+ if (context.verbose) log.success("Prisma Client generated.");
1105
+ else generateSpinner?.stop("Prisma Client generated.");
1106
+ return { didGenerateClient: true };
1107
+ } catch (error) {
1108
+ if (context.verbose) log.warn("Could not generate Prisma Client.");
1109
+ else generateSpinner?.stop("Could not generate Prisma Client.");
1110
+ return {
1111
+ didGenerateClient: false,
1112
+ warning: `Prisma generate failed: ${getCommandErrorMessage(error)}`
1113
+ };
1114
+ }
1115
+ }
1116
+ function buildWarningLines(provisionWarning, generateWarning, migrateAndSeedWarning) {
1117
+ const warningLines = [];
1118
+ if (provisionWarning) warningLines.push(`- ${provisionWarning}`);
1119
+ if (generateWarning) warningLines.push(`- ${generateWarning}`);
1120
+ if (migrateAndSeedWarning) warningLines.push(`- ${migrateAndSeedWarning}`);
1121
+ return warningLines;
1122
+ }
1123
+ function buildNextStepsForContext(opts) {
1124
+ const { context, options, didGenerateClient, didMigrate, didSeed } = opts;
1125
+ const nextSteps = [...options.prependNextSteps ?? []];
1126
+ if (!context.shouldInstall) nextSteps.push(`- ${getInstallCommand(context.packageManager)}`);
1127
+ if (!didGenerateClient || !context.shouldGenerate) nextSteps.push(`- ${getRunScriptCommand(context.packageManager, "db:generate")}`);
1128
+ if (options.includeMigrationAndSeedNextSteps !== false && !didMigrate) nextSteps.push(`- ${getRunScriptCommand(context.packageManager, "db:migrate")}`);
1129
+ if (options.includeMigrationAndSeedNextSteps !== false && !didSeed) nextSteps.push(`- ${getRunScriptCommand(context.packageManager, "db:seed")}`);
1130
+ if (options.includeDevNextStep) nextSteps.push(`- ${getRunScriptCommand(context.packageManager, "dev")}`);
1131
+ return nextSteps;
1132
+ }
1133
+ async function executePrismaSetupContext(context, options = {}) {
1134
+ const projectDir = path.resolve(options.projectDir ?? context.projectDir);
1135
+ const provisionResult = await provisionPrismaPostgresIfNeeded(context, projectDir);
1136
+ if (!provisionResult) return { ok: false };
1137
+ if (!await writeDependenciesForContext(context, projectDir)) return { ok: false };
1138
+ if (!await installDependenciesForContext(context, projectDir)) return { ok: false };
1139
+ if (!await finalizePrismaFilesForContext(context, projectDir, provisionResult)) return { ok: false };
1140
+ const databaseUrl = provisionResult.databaseUrl ?? context.databaseUrl ?? getDefaultDatabaseUrl(context.databaseProvider);
1141
+ const generateResult = await generatePrismaClientForContext(context, projectDir);
1142
+ const migrateAndSeedResult = await migrateAndSeedIfRequested(context, projectDir, {
1143
+ databaseUrl,
1144
+ didGenerateClient: generateResult.didGenerateClient
1145
+ });
1146
+ const warningLines = buildWarningLines(provisionResult.warning, generateResult.warning, migrateAndSeedResult.warning);
1147
+ return {
1148
+ ok: true,
1149
+ nextSteps: buildNextStepsForContext({
1150
+ context,
1151
+ options,
1152
+ didGenerateClient: generateResult.didGenerateClient,
1153
+ didMigrate: migrateAndSeedResult.didMigrate,
1154
+ didSeed: migrateAndSeedResult.didSeed
1155
+ }),
1156
+ warningSection: warningLines.length > 0 ? `\n\n${warningLines.join("\n")}` : "",
1157
+ databaseUrl: provisionResult.databaseUrl ?? context.databaseUrl
1158
+ };
1159
+ }
1160
+ async function migrateAndSeedIfRequested(context, projectDir, options) {
1161
+ const prismaProjectDir = await resolvePrismaProjectDir(projectDir);
1162
+ if (!context.shouldMigrateAndSeed) return {
1163
+ didMigrate: false,
1164
+ didSeed: false
1165
+ };
1166
+ if (!options.didGenerateClient) return {
1167
+ didMigrate: false,
1168
+ didSeed: false,
1169
+ warning: "Skipped migrate + seed because the Prisma Client was not generated."
1170
+ };
1171
+ if (!options.databaseUrl) return {
1172
+ didMigrate: false,
1173
+ didSeed: false,
1174
+ warning: "Skipped migrate + seed because no DATABASE_URL is available."
1175
+ };
1176
+ const migrateInvocation = getPrismaCliArgs(context.packageManager, [
1177
+ "migrate",
1178
+ "dev",
1179
+ "--name",
1180
+ "init"
1181
+ ]);
1182
+ const seedInvocation = getPrismaCliArgs(context.packageManager, ["db", "seed"]);
1183
+ const migrateSpinner = spinner();
1184
+ migrateSpinner.start("Creating and applying initial migration...");
1185
+ let didMigrate = false;
1186
+ try {
1187
+ if (context.shouldUsePrismaPostgres) await new Promise((resolve) => setTimeout(resolve, PRISMA_POSTGRES_MIGRATION_DELAY_MS));
1188
+ await execa(migrateInvocation.command, migrateInvocation.args, {
1189
+ cwd: prismaProjectDir,
1190
+ stdio: context.verbose ? "inherit" : "pipe"
1191
+ });
1192
+ migrateSpinner.stop("Initial migration applied.");
1193
+ didMigrate = true;
1194
+ } catch (error) {
1195
+ migrateSpinner.stop(`Migration failed${error instanceof Error ? `: ${error.message}` : "."}`);
1196
+ return {
1197
+ didMigrate: false,
1198
+ didSeed: false,
1199
+ warning: `Migration failed; run \`${getRunScriptCommand(context.packageManager, "db:migrate")}\` manually.`
1200
+ };
1201
+ }
1202
+ const seedSpinner = spinner();
1203
+ seedSpinner.start("Seeding database...");
1204
+ let didSeed = false;
1205
+ try {
1206
+ await execa(seedInvocation.command, seedInvocation.args, {
1207
+ cwd: prismaProjectDir,
1208
+ stdio: context.verbose ? "inherit" : "pipe"
1209
+ });
1210
+ seedSpinner.stop("Database seeded.");
1211
+ didSeed = true;
1212
+ } catch (error) {
1213
+ seedSpinner.stop(`Seed failed${error instanceof Error ? `: ${error.message}` : "."}`);
1214
+ return {
1215
+ didMigrate,
1216
+ didSeed: false,
1217
+ warning: `Seed failed; run \`${getRunScriptCommand(context.packageManager, "db:seed")}\` manually.`
1218
+ };
1219
+ }
1220
+ return {
1221
+ didMigrate,
1222
+ didSeed
1223
+ };
1224
+ }
1225
+ //#endregion
1226
+ //#region src/tasks/setup-addons.ts
1227
+ const DEFAULT_ADDON_SCOPE = "project";
1228
+ const DEFAULT_SKILLS_AGENTS = [
1229
+ "claude-code",
1230
+ "codex",
1231
+ "cursor"
1232
+ ];
1233
+ const DEFAULT_MCP_AGENTS = [
1234
+ "claude-code",
1235
+ "codex",
1236
+ "cursor"
1237
+ ];
1238
+ const DEFAULT_EXTENSION_TARGETS = ["vscode", "cursor"];
1239
+ const PRISMA_MCP_SERVER = "https://mcp.prisma.io/mcp";
1240
+ const ADDON_OPTIONS = [
1241
+ {
1242
+ value: "skills",
1243
+ label: "Skills",
1244
+ hint: "Install curated Prisma skills to your selected coding agents"
1245
+ },
1246
+ {
1247
+ value: "mcp",
1248
+ label: "MCP",
1249
+ hint: "Configure Prisma MCP server in agent MCP config files"
1250
+ },
1251
+ {
1252
+ value: "extension",
1253
+ label: "IDE Extension",
1254
+ hint: "Install Prisma extension in selected IDEs (VS Code, Cursor, Windsurf)"
1255
+ }
1256
+ ];
1257
+ const SKILLS_AGENT_OPTIONS = [
1258
+ {
1259
+ value: "cursor",
1260
+ label: "Cursor"
1261
+ },
1262
+ {
1263
+ value: "claude-code",
1264
+ label: "Claude Code"
1265
+ },
1266
+ {
1267
+ value: "cline",
1268
+ label: "Cline"
1269
+ },
1270
+ {
1271
+ value: "github-copilot",
1272
+ label: "GitHub Copilot"
1273
+ },
1274
+ {
1275
+ value: "codex",
1276
+ label: "Codex"
1277
+ },
1278
+ {
1279
+ value: "opencode",
1280
+ label: "OpenCode"
1281
+ },
1282
+ {
1283
+ value: "windsurf",
1284
+ label: "Windsurf"
1285
+ },
1286
+ {
1287
+ value: "goose",
1288
+ label: "Goose"
1289
+ },
1290
+ {
1291
+ value: "roo",
1292
+ label: "Roo Code"
1293
+ },
1294
+ {
1295
+ value: "kilo",
1296
+ label: "Kilo Code"
1297
+ },
1298
+ {
1299
+ value: "gemini-cli",
1300
+ label: "Gemini CLI"
1301
+ },
1302
+ {
1303
+ value: "antigravity",
1304
+ label: "Antigravity"
1305
+ },
1306
+ {
1307
+ value: "openhands",
1308
+ label: "OpenHands"
1309
+ },
1310
+ {
1311
+ value: "trae",
1312
+ label: "Trae"
1313
+ },
1314
+ {
1315
+ value: "amp",
1316
+ label: "Amp"
1317
+ },
1318
+ {
1319
+ value: "pi",
1320
+ label: "Pi"
1321
+ },
1322
+ {
1323
+ value: "qoder",
1324
+ label: "Qoder"
1325
+ },
1326
+ {
1327
+ value: "qwen-code",
1328
+ label: "Qwen Code"
1329
+ },
1330
+ {
1331
+ value: "kiro-cli",
1332
+ label: "Kiro CLI"
1333
+ },
1334
+ {
1335
+ value: "droid",
1336
+ label: "Droid"
1337
+ },
1338
+ {
1339
+ value: "command-code",
1340
+ label: "Command Code"
1341
+ },
1342
+ {
1343
+ value: "clawdbot",
1344
+ label: "Clawdbot"
1345
+ },
1346
+ {
1347
+ value: "zencoder",
1348
+ label: "Zencoder"
1349
+ },
1350
+ {
1351
+ value: "neovate",
1352
+ label: "Neovate"
1353
+ },
1354
+ {
1355
+ value: "mcpjam",
1356
+ label: "MCPJam"
1357
+ }
1358
+ ];
1359
+ const MCP_AGENT_OPTIONS = [
1360
+ {
1361
+ value: "claude-code",
1362
+ label: "Claude Code"
1363
+ },
1364
+ {
1365
+ value: "codex",
1366
+ label: "Codex"
1367
+ },
1368
+ {
1369
+ value: "cursor",
1370
+ label: "Cursor"
1371
+ },
1372
+ {
1373
+ value: "vscode",
1374
+ label: "VS Code"
1375
+ },
1376
+ {
1377
+ value: "github-copilot-cli",
1378
+ label: "GitHub Copilot CLI"
1379
+ },
1380
+ {
1381
+ value: "opencode",
1382
+ label: "OpenCode"
1383
+ },
1384
+ {
1385
+ value: "gemini-cli",
1386
+ label: "Gemini CLI"
1387
+ },
1388
+ {
1389
+ value: "goose",
1390
+ label: "Goose"
1391
+ },
1392
+ {
1393
+ value: "zed",
1394
+ label: "Zed"
1395
+ },
1396
+ {
1397
+ value: "antigravity",
1398
+ label: "Antigravity"
1399
+ },
1400
+ {
1401
+ value: "cline",
1402
+ label: "Cline VS Code Extension"
1403
+ },
1404
+ {
1405
+ value: "cline-cli",
1406
+ label: "Cline CLI"
1407
+ },
1408
+ {
1409
+ value: "claude-desktop",
1410
+ label: "Claude Desktop"
1411
+ },
1412
+ {
1413
+ value: "mcporter",
1414
+ label: "MCPorter"
1415
+ }
1416
+ ];
1417
+ const SHARED_PRISMA_SKILLS = [
1418
+ "prisma-cli",
1419
+ "prisma-client-api",
1420
+ "prisma-database-setup",
1421
+ "prisma-upgrade-v7"
1422
+ ];
1423
+ function getAvailablePrismaSkills(provider) {
1424
+ const skills = [...SHARED_PRISMA_SKILLS, "prisma-compute"];
1425
+ if (provider === "postgresql") return [...skills, "prisma-postgres"];
1426
+ return skills;
1427
+ }
1428
+ function getSkillOptions(provider) {
1429
+ const available = getAvailablePrismaSkills(provider);
1430
+ const options = {
1431
+ "prisma-cli": {
1432
+ value: "prisma-cli",
1433
+ label: "prisma-cli",
1434
+ hint: "Prisma CLI reference"
1435
+ },
1436
+ "prisma-client-api": {
1437
+ value: "prisma-client-api",
1438
+ label: "prisma-client-api",
1439
+ hint: "Prisma Client query patterns"
1440
+ },
1441
+ "prisma-compute": {
1442
+ value: "prisma-compute",
1443
+ label: "prisma-compute",
1444
+ hint: "Prisma Compute deploy and hosting workflows"
1445
+ },
1446
+ "prisma-database-setup": {
1447
+ value: "prisma-database-setup",
1448
+ label: "prisma-database-setup",
1449
+ hint: "Database provider setup guides"
1450
+ },
1451
+ "prisma-upgrade-v7": {
1452
+ value: "prisma-upgrade-v7",
1453
+ label: "prisma-upgrade-v7",
1454
+ hint: "v6 to v7 migration guide"
1455
+ },
1456
+ "prisma-postgres": {
1457
+ value: "prisma-postgres",
1458
+ label: "prisma-postgres",
1459
+ hint: "Prisma Postgres workflows"
1460
+ }
1461
+ };
1462
+ return available.map((skill) => options[skill]);
1463
+ }
1464
+ function collectAddonsFromInput(input) {
1465
+ const addons = [];
1466
+ if (input.skills === true) addons.push("skills");
1467
+ if (input.mcp === true) addons.push("mcp");
1468
+ if (input.extension === true) addons.push("extension");
1469
+ return uniqueValues(addons);
1470
+ }
1471
+ const EXTENSION_TARGET_OPTIONS = [
1472
+ {
1473
+ value: "vscode",
1474
+ label: "VS Code",
1475
+ hint: "Uses the `code` CLI"
1476
+ },
1477
+ {
1478
+ value: "cursor",
1479
+ label: "Cursor",
1480
+ hint: "Uses the `cursor` CLI"
1481
+ },
1482
+ {
1483
+ value: "windsurf",
1484
+ label: "Windsurf",
1485
+ hint: "Uses the `windsurf` CLI"
1486
+ }
1487
+ ];
1488
+ function uniqueValues(values) {
1489
+ return Array.from(new Set(values));
1490
+ }
1491
+ function getRecommendedPrismaSkills(provider, shouldUsePrismaPostgres, shouldUseComputeDeploy) {
1492
+ const skills = [...SHARED_PRISMA_SKILLS];
1493
+ if (provider === "postgresql" && shouldUsePrismaPostgres) skills.push("prisma-postgres");
1494
+ if (shouldUseComputeDeploy) skills.push("prisma-compute");
1495
+ return uniqueValues(skills);
1496
+ }
1497
+ async function promptForAddons() {
1498
+ const selectedAddons = await multiselect({
1499
+ message: "Select add-ons (optional)",
1500
+ options: ADDON_OPTIONS,
1501
+ required: false
1502
+ });
1503
+ if (isCancel(selectedAddons)) {
1504
+ cancel("Operation cancelled.");
1505
+ return;
1506
+ }
1507
+ return uniqueValues(selectedAddons);
1508
+ }
1509
+ async function promptForAddonScope() {
1510
+ const selectedScope = await select({
1511
+ message: "Where should add-ons write config?",
1512
+ initialValue: DEFAULT_ADDON_SCOPE,
1513
+ options: [{
1514
+ value: "project",
1515
+ label: "Project",
1516
+ hint: "Recommended for teams (checked into the project when applicable)"
1517
+ }, {
1518
+ value: "global",
1519
+ label: "Global",
1520
+ hint: "Personal machine-level setup"
1521
+ }]
1522
+ });
1523
+ if (isCancel(selectedScope)) {
1524
+ cancel("Operation cancelled.");
1525
+ return;
1526
+ }
1527
+ return selectedScope;
1528
+ }
1529
+ async function promptForPrismaSkills(provider, recommendedSkills) {
1530
+ const options = getSkillOptions(provider);
1531
+ const optionValues = new Set(options.map((option) => option.value));
1532
+ const selectedSkills = await multiselect({
1533
+ message: "Select Prisma skills",
1534
+ options,
1535
+ required: false,
1536
+ initialValues: recommendedSkills.filter((skill) => optionValues.has(skill))
1537
+ });
1538
+ if (isCancel(selectedSkills)) {
1539
+ cancel("Operation cancelled.");
1540
+ return;
1541
+ }
1542
+ return uniqueValues(selectedSkills);
1543
+ }
1544
+ async function promptForSkillsAgents() {
1545
+ const selectedAgents = await multiselect({
1546
+ message: "Select agents for skills",
1547
+ options: SKILLS_AGENT_OPTIONS,
1548
+ required: false,
1549
+ initialValues: [...DEFAULT_SKILLS_AGENTS]
1550
+ });
1551
+ if (isCancel(selectedAgents)) {
1552
+ cancel("Operation cancelled.");
1553
+ return;
1554
+ }
1555
+ return uniqueValues(selectedAgents);
1556
+ }
1557
+ async function promptForMcpAgents() {
1558
+ const selectedAgents = await multiselect({
1559
+ message: "Select agents for MCP",
1560
+ options: MCP_AGENT_OPTIONS,
1561
+ required: false,
1562
+ initialValues: [...DEFAULT_MCP_AGENTS]
1563
+ });
1564
+ if (isCancel(selectedAgents)) {
1565
+ cancel("Operation cancelled.");
1566
+ return;
1567
+ }
1568
+ return uniqueValues(selectedAgents);
1569
+ }
1570
+ async function promptForExtensionTargets() {
1571
+ const selectedTargets = await multiselect({
1572
+ message: "Select IDEs for extension install",
1573
+ options: EXTENSION_TARGET_OPTIONS,
1574
+ required: false,
1575
+ initialValues: DEFAULT_EXTENSION_TARGETS
1576
+ });
1577
+ if (isCancel(selectedTargets)) {
1578
+ cancel("Operation cancelled.");
1579
+ return;
1580
+ }
1581
+ return uniqueValues(selectedTargets);
1582
+ }
1583
+ async function collectCreateAddonSetupContext(input, options) {
1584
+ const hasExplicitAddonSelection = input.skills !== void 0 || input.mcp !== void 0 || input.extension !== void 0;
1585
+ const selectedFromInput = collectAddonsFromInput(input);
1586
+ const selectedAddons = selectedFromInput.length > 0 ? selectedFromInput : hasExplicitAddonSelection ? [] : options.useDefaults ? [] : await promptForAddons();
1587
+ if (!selectedAddons) return;
1588
+ const addons = uniqueValues(selectedAddons);
1589
+ if (addons.length === 0) return null;
1590
+ const scope = addons.includes("skills") || addons.includes("mcp") ? options.useDefaults ? DEFAULT_ADDON_SCOPE : await promptForAddonScope() : DEFAULT_ADDON_SCOPE;
1591
+ if (!scope) return;
1592
+ const recommendedSkills = getRecommendedPrismaSkills(options.provider, options.shouldUsePrismaPostgres, options.shouldUseComputeDeploy);
1593
+ const skills = !addons.includes("skills") ? [] : options.useDefaults ? recommendedSkills : await promptForPrismaSkills(options.provider, recommendedSkills);
1594
+ if (!skills) return;
1595
+ const skillsAgents = !addons.includes("skills") ? [] : options.useDefaults ? [...DEFAULT_SKILLS_AGENTS] : await promptForSkillsAgents();
1596
+ if (!skillsAgents) return;
1597
+ const mcpAgents = !addons.includes("mcp") ? [] : options.useDefaults ? [...DEFAULT_MCP_AGENTS] : await promptForMcpAgents();
1598
+ if (!mcpAgents) return;
1599
+ const extensionTargets = !addons.includes("extension") ? [] : options.useDefaults ? [...DEFAULT_EXTENSION_TARGETS] : await promptForExtensionTargets();
1600
+ if (!extensionTargets) return;
1601
+ return {
1602
+ addons,
1603
+ scope,
1604
+ skills,
1605
+ skillsAgents: uniqueValues(skillsAgents),
1606
+ mcpAgents: uniqueValues(mcpAgents),
1607
+ extensionTargets: uniqueValues(extensionTargets)
1608
+ };
1609
+ }
1610
+ async function executeExternalCommand(params) {
1611
+ await execa(params.command, params.args, {
1612
+ cwd: params.cwd,
1613
+ stdio: params.verbose ? "inherit" : "pipe",
1614
+ env: {
1615
+ ...process.env,
1616
+ CI: "true"
1617
+ }
1618
+ });
1619
+ }
1620
+ async function installSkillsAddon(params) {
1621
+ if (params.agents.length === 0 || params.skills.length === 0) return "Skipped skills addon because no skills or agents were selected.";
1622
+ const scopeArgs = params.scope === "global" ? ["-g"] : [];
1623
+ const skillArgs = params.skills.flatMap((skill) => ["-s", skill]);
1624
+ const agentArgs = params.agents.flatMap((agent) => ["-a", agent]);
1625
+ const commandArgs = [
1626
+ "skills@latest",
1627
+ "add",
1628
+ "prisma/skills",
1629
+ ...scopeArgs,
1630
+ ...skillArgs,
1631
+ ...agentArgs,
1632
+ "-y"
1633
+ ];
1634
+ const execution = getPackageExecutionArgs(params.packageManager, commandArgs);
1635
+ try {
1636
+ await executeExternalCommand({
1637
+ command: execution.command,
1638
+ args: execution.args,
1639
+ cwd: params.projectDir,
1640
+ verbose: params.verbose
1641
+ });
1642
+ return;
1643
+ } catch (error) {
1644
+ return `Skills addon failed: ${error instanceof Error ? error.message : String(error)}`;
1645
+ }
1646
+ }
1647
+ async function installMcpAddon(params) {
1648
+ if (params.agents.length === 0) return "Skipped MCP addon because no agents were selected.";
1649
+ const scopeArgs = params.scope === "global" ? ["-g"] : [];
1650
+ const agentArgs = params.agents.flatMap((agent) => ["-a", agent]);
1651
+ const commandArgs = [
1652
+ "add-mcp@latest",
1653
+ PRISMA_MCP_SERVER,
1654
+ ...scopeArgs,
1655
+ ...agentArgs,
1656
+ "--name",
1657
+ "prisma",
1658
+ "--gitignore",
1659
+ "-y"
1660
+ ];
1661
+ const execution = getPackageExecutionArgs(params.packageManager, commandArgs);
1662
+ try {
1663
+ await executeExternalCommand({
1664
+ command: execution.command,
1665
+ args: execution.args,
1666
+ cwd: params.projectDir,
1667
+ verbose: params.verbose
1668
+ });
1669
+ return;
1670
+ } catch (error) {
1671
+ return `MCP addon failed: ${error instanceof Error ? error.message : String(error)}`;
1672
+ }
1673
+ }
1674
+ function getExtensionInstallBinary(target) {
1675
+ switch (target) {
1676
+ case "vscode": return "code";
1677
+ case "cursor": return "cursor";
1678
+ case "windsurf": return "windsurf";
1679
+ default: throw new Error(`Unsupported extension target: ${String(target)}`);
1680
+ }
1681
+ }
1682
+ async function installExtensionAddon(params) {
1683
+ if (params.targets.length === 0) return ["Skipped extension addon because no IDE targets were selected."];
1684
+ const warnings = [];
1685
+ for (const target of params.targets) {
1686
+ const binary = getExtensionInstallBinary(target);
1687
+ try {
1688
+ await executeExternalCommand({
1689
+ command: binary,
1690
+ args: ["--version"],
1691
+ cwd: params.projectDir,
1692
+ verbose: false
1693
+ });
1694
+ } catch {
1695
+ warnings.push(`Skipped ${target} extension install because the \`${binary}\` CLI is not available.`);
1696
+ continue;
1697
+ }
1698
+ try {
1699
+ await executeExternalCommand({
1700
+ command: binary,
1701
+ args: [
1702
+ "--install-extension",
1703
+ "Prisma.prisma",
1704
+ "--force"
1705
+ ],
1706
+ cwd: params.projectDir,
1707
+ verbose: params.verbose
1708
+ });
1709
+ } catch (error) {
1710
+ warnings.push(`${target} extension install failed: ${error instanceof Error ? error.message : String(error)}`);
1711
+ }
1712
+ }
1713
+ return warnings;
1714
+ }
1715
+ async function executeCreateAddonSetupContext(params) {
1716
+ const { context, packageManager, projectDir, verbose } = params;
1717
+ const addonSpinner = spinner();
1718
+ addonSpinner.start("Applying selected add-ons...");
1719
+ const warnings = [];
1720
+ if (context.addons.includes("skills")) {
1721
+ const warning = await installSkillsAddon({
1722
+ packageManager,
1723
+ projectDir,
1724
+ scope: context.scope,
1725
+ skills: context.skills,
1726
+ agents: context.skillsAgents,
1727
+ verbose
1728
+ });
1729
+ if (warning) warnings.push(warning);
1730
+ }
1731
+ if (context.addons.includes("mcp")) {
1732
+ const warning = await installMcpAddon({
1733
+ packageManager,
1734
+ projectDir,
1735
+ scope: context.scope,
1736
+ agents: context.mcpAgents,
1737
+ verbose
1738
+ });
1739
+ if (warning) warnings.push(warning);
1740
+ }
1741
+ if (context.addons.includes("extension")) {
1742
+ const extensionWarnings = await installExtensionAddon({
1743
+ projectDir,
1744
+ verbose,
1745
+ targets: context.extensionTargets
1746
+ });
1747
+ warnings.push(...extensionWarnings);
1748
+ }
1749
+ if (warnings.length > 0) {
1750
+ addonSpinner.stop("Add-ons applied with warnings.");
1751
+ for (const warning of warnings) log.warn(warning);
1752
+ return;
1753
+ }
1754
+ addonSpinner.stop("Add-ons applied.");
1755
+ }
1756
+ //#endregion
1757
+ //#region src/tasks/deploy-to-compute.ts
1758
+ const PRISMA_CLI_PACKAGE = "@prisma/cli@latest";
1759
+ const DEPLOY_OPTIONS_BY_TEMPLATE = {
1760
+ hono: {},
1761
+ elysia: {},
1762
+ nest: {},
1763
+ next: {},
1764
+ astro: {},
1765
+ nuxt: {},
1766
+ "tanstack-start": {},
1767
+ turborepo: { configTarget: "api" }
1768
+ };
1769
+ function getPrismaCliCommand(packageManager) {
1770
+ return getPackageExecutionCommand(getPrismaCliExecutionPackageManager(packageManager), [PRISMA_CLI_PACKAGE]);
1771
+ }
1772
+ function getPrismaCliAppDeployCommand(packageManager) {
1773
+ return getPackageExecutionCommand(getPrismaCliExecutionPackageManager(packageManager), [
1774
+ PRISMA_CLI_PACKAGE,
1775
+ "app",
1776
+ "deploy"
1777
+ ], { silent: true });
1778
+ }
1779
+ function getComputeDeployScriptMap(context) {
1780
+ const deployArgs = [
1781
+ ...getComputeDeployTargetArgs(context),
1782
+ "--prod",
1783
+ "--yes"
1784
+ ];
1785
+ return { "compute:deploy": [getPrismaCliAppDeployCommand(context.packageManager), ...deployArgs].join(" ") };
1786
+ }
1787
+ function getComputeDeployTargetArgs(context) {
1788
+ return context.configTarget ? [context.configTarget] : [];
1789
+ }
1790
+ function runPrismaCli(packageManager, args, options = {}) {
1791
+ const { silentPackageRunner, ...execaOptions } = options;
1792
+ const execution = getPackageExecutionArgs(getPrismaCliExecutionPackageManager(packageManager), [PRISMA_CLI_PACKAGE, ...args], { silent: silentPackageRunner });
1793
+ return execa(execution.command, execution.args, execaOptions);
1794
+ }
1795
+ function getPrismaCliExecutionPackageManager(packageManager) {
1796
+ return packageManager === "deno" ? "npm" : packageManager;
1797
+ }
1798
+ async function isAuthenticated(packageManager) {
1799
+ try {
1800
+ await runPrismaCli(packageManager, [
1801
+ "project",
1802
+ "list",
1803
+ "--json"
1804
+ ], { stdio: "pipe" });
1805
+ return true;
1806
+ } catch {
1807
+ return false;
1808
+ }
1809
+ }
1810
+ async function ensurePrismaCliAvailable(packageManager) {
1811
+ try {
1812
+ await runPrismaCli(packageManager, ["--help"], { stdio: "pipe" });
1813
+ return true;
1814
+ } catch (error) {
1815
+ const command = getPrismaCliCommand(packageManager);
1816
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
1817
+ log.warn(`Could not find the selected package manager. Re-run ${command} manually.`);
1818
+ return false;
1819
+ }
1820
+ log.warn(`Could not run ${command}${error instanceof Error ? `: ${redactSecrets(error.message)}` : "."}`);
1821
+ return false;
1822
+ }
1823
+ }
1824
+ async function collectComputeDeployContext(input, options) {
1825
+ if (!isComputeDeployableTemplate(options.template)) return null;
1826
+ if (input.deploy === false) return null;
1827
+ let wantsDeploy;
1828
+ if (input.deploy === true) wantsDeploy = true;
1829
+ else if (options.useDefaults) return null;
1830
+ else {
1831
+ const confirmed = await confirm({
1832
+ message: "Deploy to Prisma Compute now?",
1833
+ initialValue: false
1834
+ });
1835
+ if (isCancel(confirmed)) {
1836
+ cancel("Operation cancelled.");
1837
+ return;
1838
+ }
1839
+ wantsDeploy = confirmed;
1840
+ }
1841
+ if (!wantsDeploy) return null;
1842
+ if (!await ensurePrismaCliAvailable(options.packageManager)) {
1843
+ if (input.deploy === true) throw createExplicitDeployError("the Prisma CLI is not available");
1844
+ return null;
1845
+ }
1846
+ if (!await isAuthenticated(options.packageManager)) {
1847
+ log.info("Authenticating with Prisma...");
1848
+ try {
1849
+ await runPrismaCli(options.packageManager, ["auth", "login"], { stdio: "inherit" });
1850
+ } catch (error) {
1851
+ log.warn(`Prisma login was not completed${error instanceof Error ? `: ${redactSecrets(error.message)}` : "."}`);
1852
+ if (input.deploy === true) throw createExplicitDeployError("authentication failed", error);
1853
+ return null;
1854
+ }
1855
+ }
1856
+ const deployOptions = DEPLOY_OPTIONS_BY_TEMPLATE[options.template];
1857
+ if (!deployOptions) {
1858
+ if (input.deploy === true) throw createExplicitDeployError(`${options.template} is not supported by prisma app deploy yet`);
1859
+ return null;
1860
+ }
1861
+ return {
1862
+ template: options.template,
1863
+ packageManager: options.packageManager,
1864
+ createProjectName: options.defaultServiceName,
1865
+ configTarget: deployOptions.configTarget
1866
+ };
1867
+ }
1868
+ function redactSecrets(message) {
1869
+ return message.replace(/(['"])([A-Z0-9_]*(?:DATABASE_URL|DIRECT_URL|TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY|ACCESS_KEY)[A-Z0-9_]*=)(.*?)\1/g, "$1$2<redacted>$1").replace(/\b([A-Z0-9_]*(?:DATABASE_URL|DIRECT_URL|TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY|ACCESS_KEY)[A-Z0-9_]*=)[^\s]+/g, "$1<redacted>");
1870
+ }
1871
+ function parseJson(stdout) {
1872
+ if (typeof stdout !== "string" || stdout.trim().length === 0) return null;
1873
+ try {
1874
+ return JSON.parse(stdout);
1875
+ } catch {
1876
+ return null;
1877
+ }
1878
+ }
1879
+ function getJsonErrorMessage(error, fallback) {
1880
+ return error?.summary ?? error?.message ?? error?.name ?? fallback;
1881
+ }
1882
+ function getErrorMessage(error) {
1883
+ return redactSecrets(error instanceof Error ? error.message : String(error));
1884
+ }
1885
+ function createDeployError(message) {
1886
+ return new Error(redactSecrets(message ?? "unknown error"));
1887
+ }
1888
+ function createExplicitDeployError(reason, error) {
1889
+ const detail = error instanceof Error ? `: ${redactSecrets(error.message)}` : "";
1890
+ return /* @__PURE__ */ new Error(`Deploy requested but ${reason}${detail}`);
1891
+ }
1892
+ async function runPrismaCliJson(params) {
1893
+ try {
1894
+ const { stdout, exitCode } = await runPrismaCli(params.packageManager, params.args, {
1895
+ cwd: params.cwd,
1896
+ reject: false,
1897
+ stdio: [
1898
+ "ignore",
1899
+ "pipe",
1900
+ "pipe"
1901
+ ],
1902
+ silentPackageRunner: true
1903
+ });
1904
+ const parsed = parseJson(stdout);
1905
+ if (!parsed) return {
1906
+ ok: false,
1907
+ error: new Error(params.invalidOutputError)
1908
+ };
1909
+ if (exitCode !== 0 || !parsed.ok) return {
1910
+ ok: false,
1911
+ error: createDeployError(parsed.ok ? params.fallbackError : getJsonErrorMessage(parsed.error, params.fallbackError))
1912
+ };
1913
+ return {
1914
+ ok: true,
1915
+ result: parsed.result
1916
+ };
1917
+ } catch (error) {
1918
+ return {
1919
+ ok: false,
1920
+ error: new Error(getErrorMessage(error))
1921
+ };
1922
+ }
1923
+ }
1924
+ function toComputeDeployResult(data) {
1925
+ return {
1926
+ appUrl: data.deployment.url,
1927
+ appId: data.app.id,
1928
+ appName: data.app.name,
1929
+ deploymentId: data.deployment.id,
1930
+ projectId: data.project.id,
1931
+ projectName: data.project.name,
1932
+ branchName: data.branch.name,
1933
+ database: data.branchDatabase?.database
1934
+ };
1935
+ }
1936
+ async function executeComputeDatabaseSetup(params) {
1937
+ const projectSpinner = spinner();
1938
+ projectSpinner.start("Creating Prisma Compute project...");
1939
+ const projectResult = await runPrismaCliJson({
1940
+ packageManager: params.context.packageManager,
1941
+ args: [
1942
+ "project",
1943
+ "create",
1944
+ params.context.createProjectName,
1945
+ "--json"
1946
+ ],
1947
+ cwd: params.projectDir,
1948
+ fallbackError: "Prisma project create failed.",
1949
+ invalidOutputError: "Invalid prisma project create output"
1950
+ });
1951
+ if (!projectResult.ok) {
1952
+ projectSpinner.error(`Project creation failed: ${projectResult.error.message}`);
1953
+ return {
1954
+ ok: false,
1955
+ cancelled: false,
1956
+ error: projectResult.error
1957
+ };
1958
+ }
1959
+ projectSpinner.stop("Prisma Compute project created.");
1960
+ const databaseSpinner = spinner();
1961
+ databaseSpinner.start("Creating Prisma Postgres database...");
1962
+ const databaseResult = await runPrismaCliJson({
1963
+ packageManager: params.context.packageManager,
1964
+ args: [
1965
+ "database",
1966
+ "create",
1967
+ "main",
1968
+ "--branch",
1969
+ "main",
1970
+ "--json"
1971
+ ],
1972
+ cwd: params.projectDir,
1973
+ fallbackError: "Prisma database create failed.",
1974
+ invalidOutputError: "Invalid prisma database create output"
1975
+ });
1976
+ if (!databaseResult.ok) {
1977
+ databaseSpinner.error(`Database creation failed: ${databaseResult.error.message}`);
1978
+ return {
1979
+ ok: false,
1980
+ cancelled: false,
1981
+ error: databaseResult.error
1982
+ };
1983
+ }
1984
+ databaseSpinner.stop("Prisma Postgres database created.");
1985
+ return {
1986
+ ok: true,
1987
+ result: {
1988
+ databaseUrl: databaseResult.result.connectionString,
1989
+ projectId: databaseResult.result.projectId,
1990
+ projectName: databaseResult.result.projectName,
1991
+ database: databaseResult.result.database
1992
+ }
1993
+ };
1994
+ }
1995
+ async function executeComputeDeployContext(params) {
1996
+ const deploySpinner = spinner();
1997
+ deploySpinner.start("Deploying to Prisma Compute...");
1998
+ const args = [
1999
+ "app",
2000
+ "deploy",
2001
+ ...getComputeDeployTargetArgs(params.context),
2002
+ "--json",
2003
+ "--yes",
2004
+ "--prod",
2005
+ ...params.createProject === false ? [] : ["--create-project", params.context.createProjectName]
2006
+ ];
2007
+ const deployResult = await runPrismaCliJson({
2008
+ packageManager: params.context.packageManager,
2009
+ args,
2010
+ cwd: params.projectDir,
2011
+ fallbackError: "Prisma app deploy failed.",
2012
+ invalidOutputError: "Invalid prisma app deploy output"
2013
+ });
2014
+ if (!deployResult.ok) {
2015
+ deploySpinner.error(`Deploy failed: ${deployResult.error.message}`);
2016
+ return {
2017
+ ok: false,
2018
+ cancelled: false,
2019
+ error: deployResult.error
2020
+ };
2021
+ }
2022
+ deploySpinner.stop("Deployed to Prisma Compute.");
2023
+ return {
2024
+ ok: true,
2025
+ result: toComputeDeployResult(deployResult.result)
2026
+ };
2027
+ }
2028
+ //#endregion
2029
+ //#region src/telemetry/client.ts
2030
+ const TELEMETRY_API_KEY = "phc_cmc85avbWyuJ2JyKdGPdv7dxXli8xLdWDBPbvIXWJfs";
2031
+ const TELEMETRY_HOST = "https://us.i.posthog.com";
2032
+ const TELEMETRY_CONFIG_FILE = "telemetry.json";
2033
+ const UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
2034
+ function isTruthyEnvValue(value) {
2035
+ return [
2036
+ "1",
2037
+ "true",
2038
+ "yes",
2039
+ "on"
2040
+ ].includes(String(value ?? "").trim().toLowerCase());
2041
+ }
2042
+ function shouldDisableTelemetry() {
2043
+ if (isTruthyEnvValue(process.env.CI) || isTruthyEnvValue(process.env.GITHUB_ACTIONS)) return true;
2044
+ return process.env.CREATE_PRISMA_DISABLE_TELEMETRY !== void 0 || process.env.CREATE_PRISMA_TELEMETRY_DISABLED !== void 0 || process.env.DO_NOT_TRACK !== void 0;
2045
+ }
2046
+ function getTelemetryConfigDir() {
2047
+ if (process.platform === "darwin") return path.join(os$1.homedir(), "Library", "Application Support", "create-prisma");
2048
+ if (process.platform === "win32") return path.join(process.env.APPDATA ?? path.join(os$1.homedir(), "AppData", "Roaming"), "create-prisma");
2049
+ return path.join(process.env.XDG_CONFIG_HOME ?? path.join(os$1.homedir(), ".config"), "create-prisma");
2050
+ }
2051
+ async function getAnonymousId() {
2052
+ const telemetryConfigPath = path.join(getTelemetryConfigDir(), TELEMETRY_CONFIG_FILE);
2053
+ try {
2054
+ const config = await fs.readJSON(telemetryConfigPath);
2055
+ if (typeof config.anonymousId === "string" && UUID_V4_REGEX.test(config.anonymousId)) return config.anonymousId;
2056
+ } catch {}
2057
+ const anonymousId = randomUUID();
2058
+ try {
2059
+ await fs.ensureDir(path.dirname(telemetryConfigPath));
2060
+ await fs.writeJSON(telemetryConfigPath, { anonymousId }, { spaces: 2 });
2061
+ } catch {}
2062
+ return anonymousId;
2063
+ }
2064
+ function getCommonProperties() {
2065
+ return {
2066
+ "cli-version": "0.7.2",
2067
+ "node-version": process.version,
2068
+ platform: process.platform,
2069
+ arch: process.arch
2070
+ };
2071
+ }
2072
+ function sanitizeProperties(properties) {
2073
+ return Object.fromEntries(Object.entries(properties).filter(([, value]) => value !== void 0));
2074
+ }
2075
+ async function trackCliTelemetry(event, properties) {
2076
+ if (shouldDisableTelemetry()) return;
2077
+ let client;
2078
+ try {
2079
+ const distinctId = await getAnonymousId();
2080
+ const sanitizedProperties = sanitizeProperties({
2081
+ ...getCommonProperties(),
2082
+ ...properties,
2083
+ $process_person_profile: false
2084
+ });
2085
+ client = new PostHog(TELEMETRY_API_KEY, {
2086
+ host: TELEMETRY_HOST,
2087
+ disableGeoip: true,
2088
+ flushAt: 1,
2089
+ flushInterval: 0
2090
+ });
2091
+ await client.captureImmediate({
2092
+ distinctId,
2093
+ event,
2094
+ properties: sanitizedProperties,
2095
+ disableGeoip: true
2096
+ });
2097
+ } catch {} finally {
2098
+ if (client) await client.shutdown().catch(() => {});
2099
+ }
2100
+ }
2101
+ //#endregion
2102
+ //#region src/telemetry/create.ts
2103
+ function getRequestedAddons(input) {
2104
+ const addons = [];
2105
+ if (input.skills === true) addons.push("skills");
2106
+ if (input.mcp === true) addons.push("mcp");
2107
+ if (input.extension === true) addons.push("extension");
2108
+ return addons;
2109
+ }
2110
+ function getTargetDirectoryState(context) {
2111
+ if (!context.targetPathState.exists) return "new";
2112
+ if (context.targetPathState.isEmptyDirectory) return "empty_directory";
2113
+ return "non_empty_directory";
2114
+ }
2115
+ function getBaseCreateProperties(input, context) {
2116
+ const resolvedAddons = context?.addonSetupContext?.addons ?? getRequestedAddons(input);
2117
+ return {
2118
+ command: "create",
2119
+ "uses-defaults": input.yes === true,
2120
+ verbose: input.verbose === true,
2121
+ force: input.force === true,
2122
+ template: context?.template ?? input.template ?? null,
2123
+ "database-provider": context?.prismaSetupContext.databaseProvider ?? input.provider ?? null,
2124
+ "package-manager": context?.prismaSetupContext.packageManager ?? input.packageManager ?? null,
2125
+ "schema-preset": context?.prismaSetupContext.schemaPreset ?? input.schemaPreset ?? null,
2126
+ "should-install": context?.prismaSetupContext.shouldInstall ?? input.install ?? null,
2127
+ "should-generate": context?.prismaSetupContext.shouldGenerate ?? input.generate ?? null,
2128
+ "uses-prisma-postgres": context?.prismaSetupContext.shouldUsePrismaPostgres ?? input.prismaPostgres ?? null,
2129
+ addons: resolvedAddons,
2130
+ "addon-count": resolvedAddons.length,
2131
+ "addon-scope": context?.addonSetupContext?.scope ?? null,
2132
+ "skills-count": context?.addonSetupContext?.skills.length ?? null,
2133
+ "skills-agents-count": context?.addonSetupContext?.skillsAgents.length ?? null,
2134
+ "mcp-agents-count": context?.addonSetupContext?.mcpAgents.length ?? null,
2135
+ "extension-target-count": context?.addonSetupContext?.extensionTargets.length ?? null,
2136
+ "target-directory-state": context ? getTargetDirectoryState(context) : null
2137
+ };
2138
+ }
2139
+ function getErrorName(error) {
2140
+ if (error instanceof Error) return error.name;
2141
+ return error === void 0 ? null : "UnknownError";
2142
+ }
2143
+ function getErrorCode(error) {
2144
+ if (typeof error !== "object" || error === null) return null;
2145
+ const exitCode = Reflect.get(error, "exitCode");
2146
+ if (typeof exitCode === "number") return exitCode;
2147
+ const code = Reflect.get(error, "code");
2148
+ return typeof code === "number" || typeof code === "string" ? code : null;
2149
+ }
2150
+ async function trackCreateCompleted(params) {
2151
+ await trackCliTelemetry("cli:create_command_completed", {
2152
+ ...getBaseCreateProperties(params.input, params.context),
2153
+ "duration-ms": params.durationMs
2154
+ });
2155
+ }
2156
+ async function trackCreateFailed(params) {
2157
+ await trackCliTelemetry("cli:create_command_failed", {
2158
+ ...getBaseCreateProperties(params.input, params.context),
2159
+ "duration-ms": params.durationMs,
2160
+ "failure-stage": params.stage,
2161
+ "error-name": getErrorName(params.error),
2162
+ "error-code": getErrorCode(params.error)
2163
+ });
2164
+ }
2165
+ //#endregion
2166
+ //#region src/ui/branding.ts
2167
+ const prismaTitle = `${styleText(["bold", "cyan"], "Create")} ${styleText(["bold", "magenta"], "Prisma")}`;
2168
+ function getCreatePrismaIntro() {
2169
+ return prismaTitle;
2170
+ }
2171
+ //#endregion
2172
+ //#region src/commands/create.ts
2173
+ const DEFAULT_PROJECT_NAME = "my-app";
2174
+ const DEFAULT_TEMPLATE = "hono";
2175
+ const DEFAULT_SCHEMA_PRESET = "basic";
2176
+ function toPackageName(projectName) {
2177
+ return projectName.toLowerCase().replace(/[^a-z0-9._-]/g, "-").replace(/^-+/, "").replace(/-+$/, "") || "app";
2178
+ }
2179
+ function formatPathForDisplay(filePath) {
2180
+ return path.relative(process.cwd(), filePath) || ".";
2181
+ }
2182
+ function validateProjectName(value) {
2183
+ const trimmed = String(value ?? "").trim();
2184
+ if (trimmed.length === 0) return "Please enter a project name.";
2185
+ if (trimmed === "..") return "Project name cannot be '..'.";
2186
+ if (path.isAbsolute(trimmed)) return "Use a relative project name instead of an absolute path.";
2187
+ }
2188
+ async function promptForProjectName() {
2189
+ const projectName = await text({
2190
+ message: "Project name",
2191
+ placeholder: DEFAULT_PROJECT_NAME,
2192
+ initialValue: DEFAULT_PROJECT_NAME,
2193
+ validate: validateProjectName
2194
+ });
2195
+ if (isCancel(projectName)) {
2196
+ cancel("Operation cancelled.");
2197
+ return;
2198
+ }
2199
+ return String(projectName).trim();
2200
+ }
2201
+ async function promptForCreateTemplate() {
2202
+ const template = await select({
2203
+ message: "Select template",
2204
+ initialValue: DEFAULT_TEMPLATE,
2205
+ options: [
2206
+ {
2207
+ value: "hono",
2208
+ label: "Hono",
2209
+ hint: "TypeScript API starter"
2210
+ },
2211
+ {
2212
+ value: "elysia",
2213
+ label: "Elysia",
2214
+ hint: "TypeScript API starter with Elysia's Node adapter"
2215
+ },
2216
+ {
2217
+ value: "nest",
2218
+ label: "NestJS",
2219
+ hint: "Official Nest-style API starter with a Prisma service"
2220
+ },
2221
+ {
2222
+ value: "next",
2223
+ label: "Next.js",
2224
+ hint: "App Router + TypeScript starter"
2225
+ },
2226
+ {
2227
+ value: "svelte",
2228
+ label: "SvelteKit",
2229
+ hint: "Official minimal SvelteKit + TypeScript starter"
2230
+ },
2231
+ {
2232
+ value: "astro",
2233
+ label: "Astro",
2234
+ hint: "Official minimal Astro starter with API route example"
2235
+ },
2236
+ {
2237
+ value: "nuxt",
2238
+ label: "Nuxt",
2239
+ hint: "Official minimal Nuxt starter with Nitro API route example"
2240
+ },
2241
+ {
2242
+ value: "tanstack-start",
2243
+ label: "TanStack Start",
2244
+ hint: "TanStack Start React app with file routes and server functions"
2245
+ },
2246
+ {
2247
+ value: "turborepo",
2248
+ label: "Turborepo",
2249
+ hint: "Monorepo starter with apps + packages/db Prisma package"
2250
+ }
2251
+ ]
2252
+ });
2253
+ if (isCancel(template)) {
2254
+ cancel("Operation cancelled.");
2255
+ return;
2256
+ }
2257
+ return CreateTemplateSchema.parse(template);
2258
+ }
2259
+ async function inspectTargetPath(targetPath) {
2260
+ if (!await fs.pathExists(targetPath)) return {
2261
+ exists: false,
2262
+ isDirectory: true,
2263
+ isEmptyDirectory: true
2264
+ };
2265
+ if (!(await fs.stat(targetPath)).isDirectory()) return {
2266
+ exists: true,
2267
+ isDirectory: false,
2268
+ isEmptyDirectory: false
2269
+ };
2270
+ return {
2271
+ exists: true,
2272
+ isDirectory: true,
2273
+ isEmptyDirectory: (await fs.readdir(targetPath)).length === 0
2274
+ };
2275
+ }
2276
+ async function runCreateCommand(rawInput = {}) {
2277
+ const startedAt = Date.now();
2278
+ let input = {};
2279
+ let context;
2280
+ let failureStage = "validate_input";
2281
+ try {
2282
+ input = CreateCommandInputSchema.parse(rawInput);
2283
+ intro(getCreatePrismaIntro());
2284
+ failureStage = "collect_context";
2285
+ context = await collectCreateContext(input);
2286
+ if (!context) return;
2287
+ failureStage = "unknown";
2288
+ const executionResult = await executeCreateContext(context);
2289
+ if (!executionResult.ok) {
2290
+ if (executionResult.error) cancel(`Create command failed: ${executionResult.error instanceof Error ? executionResult.error.message : String(executionResult.error)}`);
2291
+ await trackCreateFailed({
2292
+ input,
2293
+ context,
2294
+ durationMs: Date.now() - startedAt,
2295
+ error: executionResult.error,
2296
+ stage: executionResult.stage
2297
+ });
2298
+ return;
2299
+ }
2300
+ await trackCreateCompleted({
2301
+ input,
2302
+ context,
2303
+ durationMs: Date.now() - startedAt
2304
+ });
2305
+ } catch (error) {
2306
+ cancel(`Create command failed: ${error instanceof Error ? error.message : String(error)}`);
2307
+ await trackCreateFailed({
2308
+ input,
2309
+ context,
2310
+ durationMs: Date.now() - startedAt,
2311
+ error,
2312
+ stage: failureStage
2313
+ });
2314
+ }
2315
+ }
2316
+ async function collectCreateContext(input) {
2317
+ const useDefaults = input.yes === true;
2318
+ const force = input.force === true;
2319
+ const projectNameInput = input.name ?? (useDefaults ? DEFAULT_PROJECT_NAME : await promptForProjectName());
2320
+ if (projectNameInput === void 0) return;
2321
+ const projectName = String(projectNameInput).trim();
2322
+ const projectNameValidationError = validateProjectName(projectName);
2323
+ if (projectNameValidationError) {
2324
+ cancel(projectNameValidationError);
2325
+ return;
2326
+ }
2327
+ const template = input.template ?? (useDefaults ? DEFAULT_TEMPLATE : await promptForCreateTemplate());
2328
+ if (!template) return;
2329
+ const targetDirectory = path.resolve(process.cwd(), projectName);
2330
+ const targetPathState = await inspectTargetPath(targetDirectory);
2331
+ if (targetPathState.exists && !targetPathState.isDirectory) {
2332
+ cancel(`Target path ${formatPathForDisplay(targetDirectory)} already exists and is not a directory. Choose a different project name.`);
2333
+ return;
2334
+ }
2335
+ if (targetPathState.exists && !targetPathState.isEmptyDirectory && !force) {
2336
+ cancel(`Target directory ${formatPathForDisplay(targetDirectory)} is not empty. Use --force to continue.`);
2337
+ return;
2338
+ }
2339
+ const prismaSetupInitialContext = await collectPrismaSetupInitialContext(input, {
2340
+ projectDir: targetDirectory,
2341
+ defaultSchemaPreset: DEFAULT_SCHEMA_PRESET
2342
+ });
2343
+ if (!prismaSetupInitialContext) return;
2344
+ const projectPackageName = toPackageName(path.basename(targetDirectory));
2345
+ const computeDeployContext = await collectComputeDeployContext(input, {
2346
+ template,
2347
+ packageManager: prismaSetupInitialContext.packageManager,
2348
+ useDefaults,
2349
+ defaultServiceName: projectPackageName
2350
+ });
2351
+ if (computeDeployContext === void 0) return;
2352
+ const prismaSetupContext = await completePrismaSetupContext(input, prismaSetupInitialContext);
2353
+ if (!prismaSetupContext) return;
2354
+ const useComputeDatabase = Boolean(computeDeployContext && prismaSetupContext.shouldUsePrismaPostgres);
2355
+ if (useComputeDatabase) log.info("Prisma Postgres selected: create-prisma will provision a database and write DATABASE_URL to the template env file before deploying.");
2356
+ const addonSetupContext = await collectCreateAddonSetupContext(input, {
2357
+ useDefaults,
2358
+ provider: prismaSetupContext.databaseProvider,
2359
+ shouldUsePrismaPostgres: prismaSetupContext.shouldUsePrismaPostgres,
2360
+ shouldUseComputeDeploy: Boolean(computeDeployContext)
2361
+ });
2362
+ if (addonSetupContext === void 0) return;
2363
+ return {
2364
+ targetDirectory,
2365
+ targetPathState,
2366
+ force,
2367
+ template,
2368
+ projectPackageName,
2369
+ prismaSetupContext,
2370
+ addonSetupContext: addonSetupContext ?? void 0,
2371
+ computeDeployContext: computeDeployContext ?? void 0,
2372
+ useComputeDatabase
2373
+ };
2374
+ }
2375
+ async function executeCreateContext(context) {
2376
+ const scaffoldSpinner = spinner();
2377
+ scaffoldSpinner.start(`Scaffolding ${context.template} project...`);
2378
+ try {
2379
+ await scaffoldCreateTemplate({
2380
+ projectDir: context.targetDirectory,
2381
+ projectName: context.projectPackageName,
2382
+ template: context.template,
2383
+ schemaPreset: context.prismaSetupContext.schemaPreset,
2384
+ provider: context.prismaSetupContext.databaseProvider,
2385
+ packageManager: context.prismaSetupContext.packageManager,
2386
+ compute: Boolean(context.computeDeployContext)
2387
+ });
2388
+ scaffoldSpinner.stop("Project files scaffolded.");
2389
+ } catch (error) {
2390
+ scaffoldSpinner.stop("Could not scaffold project files.");
2391
+ return {
2392
+ ok: false,
2393
+ stage: "scaffold_template",
2394
+ error
2395
+ };
2396
+ }
2397
+ try {
2398
+ await writeCreateTemplateDependencies({
2399
+ template: context.template,
2400
+ packageManager: context.prismaSetupContext.packageManager,
2401
+ projectDir: context.targetDirectory
2402
+ });
2403
+ if (context.computeDeployContext) await addPackageDependency({
2404
+ scripts: getComputeDeployScriptMap(context.computeDeployContext),
2405
+ scriptMode: "if-missing",
2406
+ projectDir: context.targetDirectory
2407
+ });
2408
+ } catch (error) {
2409
+ return {
2410
+ ok: false,
2411
+ stage: "scaffold_template",
2412
+ error
2413
+ };
2414
+ }
2415
+ if (context.targetPathState.exists && !context.targetPathState.isEmptyDirectory && context.force) log.warn(`Used --force in non-empty directory ${formatPathForDisplay(context.targetDirectory)}.`);
2416
+ const nextSteps = formatPathForDisplay(context.targetDirectory) === "." ? [] : [`- cd ${formatPathForDisplay(context.targetDirectory)}`];
2417
+ if (context.addonSetupContext) try {
2418
+ await executeCreateAddonSetupContext({
2419
+ context: context.addonSetupContext,
2420
+ packageManager: context.prismaSetupContext.packageManager,
2421
+ projectDir: context.targetDirectory,
2422
+ verbose: context.prismaSetupContext.verbose
2423
+ });
2424
+ } catch (error) {
2425
+ return {
2426
+ ok: false,
2427
+ stage: "addons",
2428
+ error
2429
+ };
2430
+ }
2431
+ let computeDatabaseResult;
2432
+ if (context.useComputeDatabase && context.computeDeployContext) try {
2433
+ const result = await executeComputeDatabaseSetup({
2434
+ context: context.computeDeployContext,
2435
+ projectDir: context.targetDirectory
2436
+ });
2437
+ if (!result.ok && !result.cancelled) return {
2438
+ ok: false,
2439
+ stage: "compute_deploy",
2440
+ error: result.error
2441
+ };
2442
+ if (result.ok) computeDatabaseResult = result.result;
2443
+ } catch (error) {
2444
+ return {
2445
+ ok: false,
2446
+ stage: "compute_deploy",
2447
+ error
2448
+ };
2449
+ }
2450
+ const prismaSetupContext = computeDatabaseResult ? {
2451
+ ...context.prismaSetupContext,
2452
+ databaseUrl: computeDatabaseResult.databaseUrl,
2453
+ shouldUsePrismaPostgres: false
2454
+ } : context.prismaSetupContext;
2455
+ let prismaResult;
2456
+ try {
2457
+ prismaResult = await executePrismaSetupContext(prismaSetupContext, {
2458
+ prependNextSteps: nextSteps,
2459
+ projectDir: context.targetDirectory,
2460
+ includeDevNextStep: !context.useComputeDatabase
2461
+ });
2462
+ if (!prismaResult.ok) return {
2463
+ ok: false,
2464
+ stage: "prisma_setup"
2465
+ };
2466
+ } catch (error) {
2467
+ return {
2468
+ ok: false,
2469
+ stage: "prisma_setup",
2470
+ error
2471
+ };
2472
+ }
2473
+ let deployResult;
2474
+ if (context.computeDeployContext) try {
2475
+ const result = await executeComputeDeployContext({
2476
+ context: context.computeDeployContext,
2477
+ projectDir: context.targetDirectory,
2478
+ createProject: !computeDatabaseResult
2479
+ });
2480
+ if (!result.ok && !result.cancelled) return {
2481
+ ok: false,
2482
+ stage: "compute_deploy",
2483
+ error: result.error
2484
+ };
2485
+ if (result.ok) {
2486
+ deployResult = result.result;
2487
+ prismaResult.nextSteps.push(`- ${getRunScriptCommand(context.prismaSetupContext.packageManager, "compute:deploy")}`);
2488
+ }
2489
+ } catch (error) {
2490
+ return {
2491
+ ok: false,
2492
+ stage: "compute_deploy",
2493
+ error
2494
+ };
2495
+ }
2496
+ const summaryLines = [];
2497
+ summaryLines.push(`Setup complete.${prismaResult.warningSection}`);
2498
+ if (deployResult) {
2499
+ const database = computeDatabaseResult?.database ?? deployResult.database;
2500
+ summaryLines.push("", "Deployed to Prisma Compute:", ...deployResult.appUrl ? [`- App URL: ${deployResult.appUrl}`] : [], `- App: ${deployResult.appName} (${deployResult.appId})`, `- Deployment: ${deployResult.deploymentId}`, ...database ? [`- Database: ${database.name} (${database.id})`] : []);
2501
+ }
2502
+ summaryLines.push("", "Next steps:", prismaResult.nextSteps.join("\n"));
2503
+ outro(summaryLines.join("\n"));
2504
+ return { ok: true };
2505
+ }
2506
+ //#endregion
2507
+ //#region src/index.ts
2508
+ const CLI_VERSION = "0.7.2";
2509
+ const router = os.router({ create: os.meta({
2510
+ description: "Create a new project with Prisma setup",
2511
+ default: true,
2512
+ negateBooleans: true
2513
+ }).input(CreateCommandInputSchema.optional()).handler(async ({ input }) => {
2514
+ await runCreateCommand(input ?? {});
2515
+ }) });
2516
+ function createCreatePrismaCli() {
2517
+ return createCli({
2518
+ router,
2519
+ name: "create-prisma",
2520
+ version: CLI_VERSION
2521
+ });
2522
+ }
2523
+ async function create(input = {}) {
2524
+ await runCreateCommand(input);
2525
+ }
2526
+ //#endregion
2527
+ export { CreateTemplateSchema as a, PackageManagerSchema as c, CreateCommandInputSchema as i, SchemaPresetSchema as l, createCreatePrismaCli as n, DatabaseProviderSchema as o, router as r, DatabaseUrlSchema as s, create as t };