create-prisma 0.0.0 → 0.1.4

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.
@@ -0,0 +1,1090 @@
1
+ #!/usr/bin/env node
2
+ import { cancel, confirm, intro, isCancel, log, outro, select, spinner, text } from "@clack/prompts";
3
+ import fs from "fs-extra";
4
+ import path from "node:path";
5
+ import Handlebars from "handlebars";
6
+ import { existsSync } from "node:fs";
7
+ import { fileURLToPath } from "node:url";
8
+ import { z } from "zod";
9
+ import { execa } from "execa";
10
+ import { styleText } from "node:util";
11
+
12
+ //#region src/templates/shared.ts
13
+ Handlebars.registerHelper("eq", (left, right) => left === right);
14
+ function findPackageRoot(startDir) {
15
+ let currentDir = startDir;
16
+ while (true) {
17
+ if (existsSync(path.join(currentDir, "package.json"))) return currentDir;
18
+ const parentDir = path.dirname(currentDir);
19
+ if (parentDir === currentDir) break;
20
+ currentDir = parentDir;
21
+ }
22
+ throw new Error(`Unable to locate package root from: ${startDir}`);
23
+ }
24
+ function resolveTemplatesDir(relativeTemplatesDir) {
25
+ const currentFilePath = fileURLToPath(import.meta.url);
26
+ const packageRoot = findPackageRoot(path.dirname(currentFilePath));
27
+ const templatePath = path.join(packageRoot, relativeTemplatesDir);
28
+ if (!existsSync(templatePath)) throw new Error(`Template directory not found at: ${templatePath}`);
29
+ return templatePath;
30
+ }
31
+ async function getTemplateFilesRecursively(dir) {
32
+ const entries = await fs.readdir(dir, { withFileTypes: true });
33
+ return (await Promise.all(entries.map(async (entry) => {
34
+ const entryPath = path.join(dir, entry.name);
35
+ if (entry.isDirectory()) return getTemplateFilesRecursively(entryPath);
36
+ if (!entry.isFile()) return [];
37
+ return [entryPath];
38
+ }))).flat();
39
+ }
40
+ function stripHbsExtension(filePath) {
41
+ return filePath.endsWith(".hbs") ? filePath.slice(0, -4) : filePath;
42
+ }
43
+ function ensureTrailingNewline(content) {
44
+ return content.endsWith("\n") ? content : `${content}\n`;
45
+ }
46
+ async function renderTemplateFile(opts) {
47
+ const { templateFilePath, outputPath, context } = opts;
48
+ const templateContent = await fs.readFile(templateFilePath, "utf8");
49
+ const outputContent = templateFilePath.endsWith(".hbs") ? Handlebars.compile(templateContent, {
50
+ noEscape: true,
51
+ strict: true
52
+ })(context) : templateContent;
53
+ await fs.outputFile(outputPath, ensureTrailingNewline(outputContent), "utf8");
54
+ }
55
+ async function renderTemplateTree(opts) {
56
+ const { templateRoot, outputDir, context } = opts;
57
+ const templateFiles = await getTemplateFilesRecursively(templateRoot);
58
+ for (const templateFilePath of templateFiles) {
59
+ const relativeOutputPath = stripHbsExtension(path.relative(templateRoot, templateFilePath));
60
+ await renderTemplateFile({
61
+ templateFilePath,
62
+ outputPath: path.join(outputDir, relativeOutputPath),
63
+ context
64
+ });
65
+ }
66
+ }
67
+
68
+ //#endregion
69
+ //#region src/templates/render-create-template.ts
70
+ function getCreateTemplateDir(template) {
71
+ return resolveTemplatesDir(`templates/create/${template}`);
72
+ }
73
+ function createTemplateContext$1(projectName, schemaPreset, packageManager) {
74
+ return {
75
+ projectName,
76
+ schemaPreset,
77
+ packageManager
78
+ };
79
+ }
80
+ async function scaffoldCreateTemplate(opts) {
81
+ const { projectDir, projectName, template, schemaPreset, packageManager } = opts;
82
+ await renderTemplateTree({
83
+ templateRoot: getCreateTemplateDir(template),
84
+ outputDir: projectDir,
85
+ context: createTemplateContext$1(projectName, schemaPreset, packageManager)
86
+ });
87
+ }
88
+
89
+ //#endregion
90
+ //#region src/types.ts
91
+ const databaseProviders = [
92
+ "postgresql",
93
+ "mysql",
94
+ "sqlite",
95
+ "sqlserver",
96
+ "cockroachdb"
97
+ ];
98
+ const packageManagers = [
99
+ "npm",
100
+ "pnpm",
101
+ "bun"
102
+ ];
103
+ const schemaPresets = ["empty", "basic"];
104
+ const createTemplates = ["hono", "next"];
105
+ const DatabaseProviderSchema = z.enum(databaseProviders);
106
+ const PackageManagerSchema = z.enum(packageManagers);
107
+ const SchemaPresetSchema = z.enum(schemaPresets);
108
+ const CreateTemplateSchema = z.enum(createTemplates);
109
+ const DatabaseUrlSchema = z.string().trim().min(1, "Please enter a valid database URL");
110
+ const CommonCommandOptionsSchema = z.object({
111
+ yes: z.boolean().optional().describe("Skip prompts and accept default choices"),
112
+ verbose: z.boolean().optional().describe("Show verbose command output during setup")
113
+ });
114
+ const PrismaSetupOptionsSchema = z.object({
115
+ provider: DatabaseProviderSchema.optional().describe("Database provider"),
116
+ packageManager: PackageManagerSchema.optional().describe("Package manager used for dependency installation"),
117
+ prismaPostgres: z.boolean().optional().describe("Provision Prisma Postgres with create-db when provider is postgresql"),
118
+ databaseUrl: DatabaseUrlSchema.optional().describe("DATABASE_URL value"),
119
+ install: z.boolean().optional().describe("Install dependencies with selected package manager"),
120
+ generate: z.boolean().optional().describe("Generate Prisma Client after scaffolding"),
121
+ schemaPreset: SchemaPresetSchema.optional().describe("Schema preset to scaffold in prisma/schema.prisma")
122
+ });
123
+ const InitCommandInputSchema = CommonCommandOptionsSchema.extend(PrismaSetupOptionsSchema.shape);
124
+ const CreateScaffoldOptionsSchema = z.object({
125
+ name: z.string().trim().min(1, "Please enter a valid project name").optional().describe("Project name / directory"),
126
+ template: CreateTemplateSchema.optional().describe("Project template"),
127
+ force: z.boolean().optional().describe("Allow scaffolding into a non-empty target directory")
128
+ });
129
+ const CreateCommandInputSchema = CommonCommandOptionsSchema.extend(CreateScaffoldOptionsSchema.shape).extend(PrismaSetupOptionsSchema.shape);
130
+
131
+ //#endregion
132
+ //#region src/utils/package-manager.ts
133
+ function parseUserAgent(userAgent) {
134
+ if (userAgent?.startsWith("pnpm")) return "pnpm";
135
+ if (userAgent?.startsWith("bun")) return "bun";
136
+ if (userAgent?.startsWith("npm")) return "npm";
137
+ return null;
138
+ }
139
+ function parsePackageManagerField(packageManagerField) {
140
+ if (typeof packageManagerField !== "string" || packageManagerField.length === 0) return null;
141
+ const managerName = packageManagerField.split("@")[0];
142
+ const parsed = PackageManagerSchema.safeParse(managerName);
143
+ return parsed.success ? parsed.data : null;
144
+ }
145
+ async function detectFromPackageJson(projectDir) {
146
+ const packageJsonPath = path.join(projectDir, "package.json");
147
+ if (!await fs.pathExists(packageJsonPath)) return null;
148
+ return parsePackageManagerField((await fs.readJson(packageJsonPath)).packageManager);
149
+ }
150
+ async function detectFromLockfile(projectDir) {
151
+ for (const check of [
152
+ {
153
+ manager: "pnpm",
154
+ lockfile: "pnpm-lock.yaml"
155
+ },
156
+ {
157
+ manager: "bun",
158
+ lockfile: "bun.lockb"
159
+ },
160
+ {
161
+ manager: "bun",
162
+ lockfile: "bun.lock"
163
+ },
164
+ {
165
+ manager: "npm",
166
+ lockfile: "package-lock.json"
167
+ },
168
+ {
169
+ manager: "npm",
170
+ lockfile: "npm-shrinkwrap.json"
171
+ }
172
+ ]) if (await fs.pathExists(path.join(projectDir, check.lockfile))) return check.manager;
173
+ return null;
174
+ }
175
+ async function detectPackageManager(projectDir = process.cwd()) {
176
+ const fromPackageJson = await detectFromPackageJson(projectDir);
177
+ if (fromPackageJson) return fromPackageJson;
178
+ const fromLockfile = await detectFromLockfile(projectDir);
179
+ if (fromLockfile) return fromLockfile;
180
+ const fromUserAgent = parseUserAgent(process.env.npm_config_user_agent);
181
+ if (fromUserAgent) return fromUserAgent;
182
+ return "npm";
183
+ }
184
+ function getInstallCommand(packageManager) {
185
+ return `${packageManager} install`;
186
+ }
187
+ function getRunScriptCommand(packageManager, scriptName) {
188
+ switch (packageManager) {
189
+ case "bun": return `bun run ${scriptName}`;
190
+ case "pnpm": return `pnpm run ${scriptName}`;
191
+ default: return `npm run ${scriptName}`;
192
+ }
193
+ }
194
+ function getInstallArgs(packageManager) {
195
+ return {
196
+ command: packageManager,
197
+ args: ["install"]
198
+ };
199
+ }
200
+ function getPackageExecutor(packageManager) {
201
+ switch (packageManager) {
202
+ case "pnpm": return {
203
+ command: "pnpm",
204
+ args: ["dlx"]
205
+ };
206
+ case "bun": return {
207
+ command: "bunx",
208
+ args: []
209
+ };
210
+ default: return {
211
+ command: "npx",
212
+ args: []
213
+ };
214
+ }
215
+ }
216
+ function getPackageExecutionArgs(packageManager, commandArgs) {
217
+ const executor = getPackageExecutor(packageManager);
218
+ return {
219
+ command: executor.command,
220
+ args: [...executor.args, ...commandArgs]
221
+ };
222
+ }
223
+ function getPackageExecutionCommand(packageManager, commandArgs) {
224
+ const execution = getPackageExecutionArgs(packageManager, commandArgs);
225
+ return [execution.command, ...execution.args].join(" ");
226
+ }
227
+ function getPrismaCliArgs(packageManager, prismaArgs) {
228
+ if (packageManager === "bun") return getPackageExecutionArgs(packageManager, [
229
+ "--bun",
230
+ "prisma",
231
+ ...prismaArgs
232
+ ]);
233
+ return getPackageExecutionArgs(packageManager, ["prisma", ...prismaArgs]);
234
+ }
235
+ function getPrismaCliCommand(packageManager, prismaArgs) {
236
+ const execution = getPrismaCliArgs(packageManager, prismaArgs);
237
+ return [execution.command, ...execution.args].join(" ");
238
+ }
239
+
240
+ //#endregion
241
+ //#region src/tasks/prisma-postgres.ts
242
+ const PRISMA_POSTGRES_TEMPORARY_NOTICE = "Prisma Postgres is temporary for 24 hours. Claim this database before it expires using CLAIM_URL.";
243
+ const CREATE_DB_COMMAND_ARGS = ["create-db@latest", "--json"];
244
+ function parseCreateDbJson(rawOutput) {
245
+ const trimmed = rawOutput.trim();
246
+ if (!trimmed) throw new Error("create-db returned empty output.");
247
+ const jsonCandidates = [trimmed];
248
+ const firstBrace = trimmed.indexOf("{");
249
+ const lastBrace = trimmed.lastIndexOf("}");
250
+ if (firstBrace !== -1 && lastBrace > firstBrace) jsonCandidates.push(trimmed.slice(firstBrace, lastBrace + 1));
251
+ for (const candidate of jsonCandidates) try {
252
+ return JSON.parse(candidate);
253
+ } catch {}
254
+ throw new Error(`Unable to parse create-db JSON output: ${trimmed}`);
255
+ }
256
+ function pickConnectionString(payload) {
257
+ if (typeof payload.connectionString === "string" && payload.connectionString.length > 0) return payload.connectionString;
258
+ if (typeof payload.databaseUrl === "string" && payload.databaseUrl.length > 0) return payload.databaseUrl;
259
+ }
260
+ function extractErrorMessage(payload, fallback) {
261
+ if (typeof payload.message === "string" && payload.message.length > 0) return payload.message;
262
+ if (typeof payload.error === "string" && payload.error.length > 0) return payload.error;
263
+ return fallback;
264
+ }
265
+ async function provisionPrismaPostgres(packageManager, projectDir = process.cwd()) {
266
+ const command = getPackageExecutionArgs(packageManager, [...CREATE_DB_COMMAND_ARGS]);
267
+ const commandString = getCreateDbCommand(packageManager);
268
+ let stdout;
269
+ try {
270
+ stdout = (await execa(command.command, command.args, {
271
+ cwd: projectDir,
272
+ stdio: "pipe"
273
+ })).stdout;
274
+ } catch (error) {
275
+ if (error instanceof Error && "stderr" in error) {
276
+ const stderr = String(error.stderr ?? "").trim();
277
+ const message = stderr.length > 0 ? stderr : error.message;
278
+ throw new Error(`Failed to run ${commandString}: ${message}`);
279
+ }
280
+ throw error;
281
+ }
282
+ const payload = parseCreateDbJson(stdout);
283
+ if (payload.success === false) throw new Error(extractErrorMessage(payload, "create-db reported failure."));
284
+ const databaseUrl = pickConnectionString(payload);
285
+ if (!databaseUrl) throw new Error("create-db did not return a connection string.");
286
+ return {
287
+ databaseUrl,
288
+ claimUrl: typeof payload.claimUrl === "string" && payload.claimUrl.length > 0 ? payload.claimUrl : typeof payload.claimURL === "string" && payload.claimURL.length > 0 ? payload.claimURL : void 0
289
+ };
290
+ }
291
+ function getCreateDbCommand(packageManager) {
292
+ return getPackageExecutionCommand(packageManager, [...CREATE_DB_COMMAND_ARGS]);
293
+ }
294
+
295
+ //#endregion
296
+ //#region src/templates/render-init-templates.ts
297
+ function getInitTemplatesDir() {
298
+ return resolveTemplatesDir("templates/init");
299
+ }
300
+ function createTemplateContext(provider, envVar, schemaPreset) {
301
+ return {
302
+ envVar,
303
+ provider,
304
+ schemaPreset
305
+ };
306
+ }
307
+ async function scaffoldInitTemplates(projectDir, provider, envVar = "DATABASE_URL", schemaPreset = "empty") {
308
+ await renderTemplateTree({
309
+ templateRoot: getInitTemplatesDir(),
310
+ outputDir: projectDir,
311
+ context: createTemplateContext(provider, envVar, schemaPreset)
312
+ });
313
+ return {
314
+ schemaPath: path.join(projectDir, "prisma/schema.prisma"),
315
+ configPath: path.join(projectDir, "prisma.config.ts"),
316
+ singletonPath: path.join(projectDir, "prisma/index.ts")
317
+ };
318
+ }
319
+
320
+ //#endregion
321
+ //#region src/tasks/init-prisma.ts
322
+ const prismaManagedFiles = [
323
+ "schema.prisma",
324
+ "prisma/schema.prisma",
325
+ "prisma/index.ts",
326
+ "prisma.config.ts"
327
+ ];
328
+ const prismaTemplateFiles = [
329
+ "prisma/schema.prisma",
330
+ "prisma/index.ts",
331
+ "prisma.config.ts"
332
+ ];
333
+ var PrismaAlreadyInitializedError = class extends Error {
334
+ existingFiles;
335
+ constructor(existingFiles) {
336
+ super(`This project already appears to be Prisma-initialized: ${existingFiles.join(", ")}`);
337
+ this.name = "PrismaAlreadyInitializedError";
338
+ this.existingFiles = existingFiles;
339
+ }
340
+ };
341
+ function findExistingPrismaFiles(projectDir = process.cwd()) {
342
+ return prismaManagedFiles.map((relativePath) => path.join(projectDir, relativePath)).filter((absolutePath) => fs.existsSync(absolutePath));
343
+ }
344
+ function canReusePrismaFiles(projectDir = process.cwd()) {
345
+ return prismaTemplateFiles.every((relativePath) => fs.existsSync(path.join(projectDir, relativePath)));
346
+ }
347
+ function getDefaultDatabaseUrl(provider) {
348
+ switch (provider) {
349
+ case "postgresql": return "postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public";
350
+ case "cockroachdb": return "postgresql://johndoe:randompassword@localhost:26257/mydb?schema=public";
351
+ case "mysql": return "mysql://johndoe:randompassword@localhost:3306/mydb";
352
+ case "sqlite": return "file:./dev.db";
353
+ case "sqlserver": return "sqlserver://localhost:1433;database=mydb;user=SA;password=randompassword;";
354
+ default: {
355
+ const exhaustiveCheck = provider;
356
+ throw new Error(`Unsupported provider: ${String(exhaustiveCheck)}`);
357
+ }
358
+ }
359
+ }
360
+ function escapeRegExp(value) {
361
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
362
+ }
363
+ function hasEnvVar(content, envVarName) {
364
+ const escapedName = escapeRegExp(envVarName);
365
+ return new RegExp(`(^|\\n)\\s*${escapedName}\\s*=`).test(content);
366
+ }
367
+ function hasEnvComment(content, comment) {
368
+ const escapedComment = escapeRegExp(comment);
369
+ return new RegExp(`(^|\\n)\\s*#\\s*${escapedComment}\\s*(?=\\n|$)`).test(content);
370
+ }
371
+ async function ensureEnvVarInEnv(projectDir, envVarName, envVarValue, opts) {
372
+ const envPath = path.join(projectDir, ".env");
373
+ const envLine = `${envVarName}="${envVarValue}"`;
374
+ if (!await fs.pathExists(envPath)) {
375
+ await fs.writeFile(envPath, `${envLine}\n`, "utf8");
376
+ return {
377
+ envPath,
378
+ status: "created"
379
+ };
380
+ }
381
+ const existingContent = await fs.readFile(envPath, "utf8");
382
+ if (hasEnvVar(existingContent, envVarName)) {
383
+ if (opts.mode === "keep-existing") return {
384
+ envPath,
385
+ status: "existing"
386
+ };
387
+ const escapedName = escapeRegExp(envVarName);
388
+ const lineRegex = new RegExp(`(^|\\n)\\s*${escapedName}\\s*=.*(?=\\n|$)`, "m");
389
+ const updatedContent = existingContent.replace(lineRegex, `$1${envLine}`);
390
+ if (updatedContent === existingContent) return {
391
+ envPath,
392
+ status: "existing"
393
+ };
394
+ await fs.writeFile(envPath, updatedContent, "utf8");
395
+ return {
396
+ envPath,
397
+ status: "updated"
398
+ };
399
+ }
400
+ const insertion = `${existingContent.endsWith("\n") ? "" : "\n"}${opts.comment ? `\n# ${opts.comment}\n` : "\n"}${envLine}\n`;
401
+ await fs.appendFile(envPath, insertion, "utf8");
402
+ return {
403
+ envPath,
404
+ status: "appended"
405
+ };
406
+ }
407
+ async function ensureEnvComment(projectDir, comment) {
408
+ const envPath = path.join(projectDir, ".env");
409
+ const commentLine = `# ${comment}`;
410
+ if (!await fs.pathExists(envPath)) {
411
+ await fs.writeFile(envPath, `${commentLine}\n`, "utf8");
412
+ return;
413
+ }
414
+ const existingContent = await fs.readFile(envPath, "utf8");
415
+ if (hasEnvComment(existingContent, comment)) return;
416
+ const separator = existingContent.endsWith("\n") ? "" : "\n";
417
+ await fs.appendFile(envPath, `${separator}${commentLine}\n`, "utf8");
418
+ }
419
+ function hasGitignoreEntry(content, entry) {
420
+ const escapedEntry = escapeRegExp(entry);
421
+ const escapedWithLeadingSlash = escapeRegExp(`/${entry}`);
422
+ return new RegExp(`(^|\\n)\\s*(?:${escapedEntry}|${escapedWithLeadingSlash})\\s*(?=\\n|$)`).test(content);
423
+ }
424
+ async function ensureGitignoreEntry(projectDir, entry) {
425
+ const gitignorePath = path.join(projectDir, ".gitignore");
426
+ if (!await fs.pathExists(gitignorePath)) {
427
+ await fs.writeFile(gitignorePath, `${entry}\n`, "utf8");
428
+ return {
429
+ gitignorePath,
430
+ status: "created"
431
+ };
432
+ }
433
+ const existingContent = await fs.readFile(gitignorePath, "utf8");
434
+ if (hasGitignoreEntry(existingContent, entry)) return {
435
+ gitignorePath,
436
+ status: "existing"
437
+ };
438
+ const separator = existingContent.endsWith("\n") ? "" : "\n";
439
+ await fs.appendFile(gitignorePath, `${separator}${entry}\n`, "utf8");
440
+ return {
441
+ gitignorePath,
442
+ status: "appended"
443
+ };
444
+ }
445
+ async function initializePrismaFiles(options) {
446
+ const projectDir = options.projectDir ?? process.cwd();
447
+ const prismaFilesMode = options.prismaFilesMode ?? "create";
448
+ const existingPrismaFiles = findExistingPrismaFiles(projectDir);
449
+ if (prismaFilesMode === "create" && existingPrismaFiles.length > 0) throw new PrismaAlreadyInitializedError(existingPrismaFiles);
450
+ if (prismaFilesMode === "reuse" && existingPrismaFiles.length === 0) throw new Error("Cannot reuse Prisma files because no existing Prisma files were found.");
451
+ if (prismaFilesMode === "reuse" && !canReusePrismaFiles(projectDir)) throw new Error("Cannot reuse Prisma files because required files are missing.");
452
+ const schemaPath = path.join(projectDir, "prisma/schema.prisma");
453
+ const configPath = path.join(projectDir, "prisma.config.ts");
454
+ const singletonPath = path.join(projectDir, "prisma/index.ts");
455
+ if (prismaFilesMode !== "reuse") await scaffoldInitTemplates(projectDir, options.provider, "DATABASE_URL", options.schemaPreset ?? "empty");
456
+ const envResult = await ensureEnvVarInEnv(projectDir, "DATABASE_URL", options.databaseUrl ?? getDefaultDatabaseUrl(options.provider), {
457
+ mode: options.databaseUrl ? "upsert" : "keep-existing",
458
+ comment: "Added by create-prisma init"
459
+ });
460
+ let claimEnvStatus;
461
+ if (options.claimUrl) {
462
+ claimEnvStatus = (await ensureEnvVarInEnv(projectDir, "CLAIM_URL", options.claimUrl, {
463
+ mode: "upsert",
464
+ comment: PRISMA_POSTGRES_TEMPORARY_NOTICE
465
+ })).status;
466
+ await ensureEnvComment(projectDir, PRISMA_POSTGRES_TEMPORARY_NOTICE);
467
+ }
468
+ const gitignoreResult = await ensureGitignoreEntry(projectDir, "prisma/generated");
469
+ return {
470
+ schemaPath,
471
+ configPath,
472
+ singletonPath,
473
+ prismaFilesMode,
474
+ envPath: envResult.envPath,
475
+ envStatus: envResult.status,
476
+ gitignorePath: gitignoreResult.gitignorePath,
477
+ gitignoreStatus: gitignoreResult.status,
478
+ claimEnvStatus
479
+ };
480
+ }
481
+
482
+ //#endregion
483
+ //#region src/constants/dependencies.ts
484
+ const dependencyVersionMap = {
485
+ "@prisma/client": "^7.4.0",
486
+ "@prisma/adapter-pg": "^7.4.0",
487
+ "@prisma/adapter-mariadb": "^7.4.0",
488
+ "@prisma/adapter-better-sqlite3": "^7.4.0",
489
+ "@prisma/adapter-mssql": "^7.4.0",
490
+ dotenv: "^17.2.3",
491
+ prisma: "^7.4.0"
492
+ };
493
+
494
+ //#endregion
495
+ //#region src/constants/db-packages.ts
496
+ function getDbPackages(provider) {
497
+ switch (provider) {
498
+ case "postgresql":
499
+ case "cockroachdb": return { adapterPackage: "@prisma/adapter-pg" };
500
+ case "mysql": return { adapterPackage: "@prisma/adapter-mariadb" };
501
+ case "sqlite": return { adapterPackage: "@prisma/adapter-better-sqlite3" };
502
+ case "sqlserver": return { adapterPackage: "@prisma/adapter-mssql" };
503
+ default: {
504
+ const exhaustiveCheck = provider;
505
+ throw new Error(`Unsupported database provider: ${String(exhaustiveCheck)}`);
506
+ }
507
+ }
508
+ }
509
+
510
+ //#endregion
511
+ //#region src/tasks/install.ts
512
+ const prismaScriptMap = {
513
+ "db:generate": "prisma generate",
514
+ "db:push": "prisma db push",
515
+ "db:migrate": "prisma migrate dev"
516
+ };
517
+ function getVersion(packageName) {
518
+ return dependencyVersionMap[packageName];
519
+ }
520
+ function unique(items) {
521
+ return [...new Set(items)];
522
+ }
523
+ function sortRecord(record) {
524
+ return Object.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));
525
+ }
526
+ async function addPackageDependency(opts) {
527
+ const { dependencies = [], devDependencies = [], customDependencies = {}, customDevDependencies = {}, scripts = {}, scriptMode = "upsert", projectDir } = opts;
528
+ const addedScripts = [];
529
+ const existingScripts = [];
530
+ const pkgJsonPath = path.join(projectDir, "package.json");
531
+ if (!await fs.pathExists(pkgJsonPath)) throw new Error(`No package.json found in ${projectDir}. Run this command inside an existing JavaScript/TypeScript project.`);
532
+ const pkgJson = await fs.readJson(pkgJsonPath);
533
+ if (!pkgJson.dependencies) pkgJson.dependencies = {};
534
+ if (!pkgJson.devDependencies) pkgJson.devDependencies = {};
535
+ if (!pkgJson.scripts) pkgJson.scripts = {};
536
+ for (const pkgName of unique(dependencies)) {
537
+ const version = getVersion(pkgName);
538
+ if (version) pkgJson.dependencies[pkgName] = version;
539
+ else console.warn(`Warning: Dependency ${pkgName} not found in version map.`);
540
+ }
541
+ for (const pkgName of unique(devDependencies)) {
542
+ const version = getVersion(pkgName);
543
+ if (version) pkgJson.devDependencies[pkgName] = version;
544
+ else console.warn(`Warning: Dev dependency ${pkgName} not found in version map.`);
545
+ }
546
+ for (const [pkgName, version] of Object.entries(customDependencies)) pkgJson.dependencies[pkgName] = version;
547
+ for (const [pkgName, version] of Object.entries(customDevDependencies)) pkgJson.devDependencies[pkgName] = version;
548
+ for (const [scriptName, command] of Object.entries(scripts)) {
549
+ if (scriptMode === "if-missing") {
550
+ if (typeof pkgJson.scripts[scriptName] !== "string" || pkgJson.scripts[scriptName].trim().length === 0) {
551
+ pkgJson.scripts[scriptName] = command;
552
+ addedScripts.push(scriptName);
553
+ } else existingScripts.push(scriptName);
554
+ continue;
555
+ }
556
+ if (pkgJson.scripts[scriptName] === command) existingScripts.push(scriptName);
557
+ else addedScripts.push(scriptName);
558
+ pkgJson.scripts[scriptName] = command;
559
+ }
560
+ pkgJson.dependencies = sortRecord(pkgJson.dependencies);
561
+ pkgJson.devDependencies = sortRecord(pkgJson.devDependencies);
562
+ await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
563
+ return {
564
+ addedScripts,
565
+ existingScripts
566
+ };
567
+ }
568
+ async function writePrismaDependencies(provider, projectDir = process.cwd()) {
569
+ const dependencies = ["@prisma/client", "dotenv"];
570
+ const devDependencies = ["prisma"];
571
+ const { adapterPackage } = getDbPackages(provider);
572
+ dependencies.push(adapterPackage);
573
+ const scriptWriteResult = await addPackageDependency({
574
+ dependencies,
575
+ devDependencies,
576
+ scripts: prismaScriptMap,
577
+ scriptMode: "if-missing",
578
+ projectDir
579
+ });
580
+ return {
581
+ dependencies,
582
+ devDependencies,
583
+ scripts: Object.keys(prismaScriptMap),
584
+ addedScripts: scriptWriteResult.addedScripts,
585
+ existingScripts: scriptWriteResult.existingScripts
586
+ };
587
+ }
588
+ async function installProjectDependencies(packageManager, projectDir = process.cwd(), options = {}) {
589
+ const verbose = options.verbose === true;
590
+ const installCommand = getInstallArgs(packageManager);
591
+ await execa(installCommand.command, installCommand.args, {
592
+ cwd: projectDir,
593
+ stdio: verbose ? "inherit" : "pipe"
594
+ });
595
+ }
596
+
597
+ //#endregion
598
+ //#region src/ui/branding.ts
599
+ const prismaTitle = `${styleText(["bold", "cyan"], "Create")} ${styleText(["bold", "magenta"], "Prisma")}`;
600
+ function getCreatePrismaIntro() {
601
+ return prismaTitle;
602
+ }
603
+
604
+ //#endregion
605
+ //#region src/commands/init.ts
606
+ const DEFAULT_DATABASE_PROVIDER = "postgresql";
607
+ const DEFAULT_SCHEMA_PRESET$1 = "empty";
608
+ const DEFAULT_PRISMA_POSTGRES = true;
609
+ const DEFAULT_INSTALL = true;
610
+ const DEFAULT_GENERATE = true;
611
+ async function promptForDatabaseProvider() {
612
+ const databaseProvider = await select({
613
+ message: "Select your database",
614
+ initialValue: DEFAULT_DATABASE_PROVIDER,
615
+ options: [
616
+ {
617
+ value: "postgresql",
618
+ label: "PostgreSQL",
619
+ hint: "Default"
620
+ },
621
+ {
622
+ value: "mysql",
623
+ label: "MySQL"
624
+ },
625
+ {
626
+ value: "sqlite",
627
+ label: "SQLite"
628
+ },
629
+ {
630
+ value: "sqlserver",
631
+ label: "SQL Server"
632
+ },
633
+ {
634
+ value: "cockroachdb",
635
+ label: "CockroachDB"
636
+ }
637
+ ]
638
+ });
639
+ if (isCancel(databaseProvider)) {
640
+ cancel("Operation cancelled.");
641
+ return;
642
+ }
643
+ return DatabaseProviderSchema.parse(databaseProvider);
644
+ }
645
+ function getPackageManagerHint(option, detected) {
646
+ if (option === detected) return "Detected";
647
+ if (option === "bun") return "Fast runtime + package manager";
648
+ }
649
+ async function promptForPackageManager(detectedPackageManager) {
650
+ const packageManager = await select({
651
+ message: "Choose package manager",
652
+ initialValue: detectedPackageManager,
653
+ options: [
654
+ {
655
+ value: "npm",
656
+ label: "npm",
657
+ hint: getPackageManagerHint("npm", detectedPackageManager)
658
+ },
659
+ {
660
+ value: "pnpm",
661
+ label: "pnpm",
662
+ hint: getPackageManagerHint("pnpm", detectedPackageManager)
663
+ },
664
+ {
665
+ value: "bun",
666
+ label: "bun",
667
+ hint: getPackageManagerHint("bun", detectedPackageManager)
668
+ }
669
+ ]
670
+ });
671
+ if (isCancel(packageManager)) {
672
+ cancel("Operation cancelled.");
673
+ return;
674
+ }
675
+ return PackageManagerSchema.parse(packageManager);
676
+ }
677
+ async function promptForDependencyInstall(packageManager) {
678
+ const shouldInstall = await confirm({
679
+ message: `Install dependencies now with ${getInstallCommand(packageManager)}?`,
680
+ initialValue: true
681
+ });
682
+ if (isCancel(shouldInstall)) {
683
+ cancel("Operation cancelled.");
684
+ return;
685
+ }
686
+ return Boolean(shouldInstall);
687
+ }
688
+ async function promptForPrismaPostgres() {
689
+ const shouldUsePrismaPostgres = await confirm({
690
+ message: "Use Prisma Postgres and auto-generate DATABASE_URL with create-db?",
691
+ initialValue: true
692
+ });
693
+ if (isCancel(shouldUsePrismaPostgres)) {
694
+ cancel("Operation cancelled.");
695
+ return;
696
+ }
697
+ return Boolean(shouldUsePrismaPostgres);
698
+ }
699
+ async function promptForPrismaFilesMode(existingFiles, canReuseExistingPrismaFiles, baseDir) {
700
+ const mode = await select({
701
+ message: `Prisma already exists (${existingFiles.map((filePath) => formatCreatedPath(filePath, baseDir)).join(", ")}). How should we continue?`,
702
+ initialValue: canReuseExistingPrismaFiles ? "reuse" : "overwrite",
703
+ options: canReuseExistingPrismaFiles ? [
704
+ {
705
+ value: "reuse",
706
+ label: "Keep existing Prisma files",
707
+ hint: "Recommended"
708
+ },
709
+ {
710
+ value: "overwrite",
711
+ label: "Overwrite Prisma files"
712
+ },
713
+ {
714
+ value: "cancel",
715
+ label: "Cancel"
716
+ }
717
+ ] : [{
718
+ value: "overwrite",
719
+ label: "Repair and overwrite Prisma files",
720
+ hint: "Recommended"
721
+ }, {
722
+ value: "cancel",
723
+ label: "Cancel"
724
+ }]
725
+ });
726
+ if (isCancel(mode)) {
727
+ cancel("Operation cancelled.");
728
+ return;
729
+ }
730
+ if (mode === "cancel") {
731
+ cancel("Operation cancelled.");
732
+ return;
733
+ }
734
+ if (mode !== "reuse" && mode !== "overwrite") {
735
+ cancel("Operation cancelled.");
736
+ return;
737
+ }
738
+ return mode;
739
+ }
740
+ function formatCreatedPath(filePath, baseDir) {
741
+ return path.relative(baseDir, filePath);
742
+ }
743
+ function getCommandErrorMessage(error) {
744
+ if (error instanceof Error && "stderr" in error) {
745
+ const stderr = String(error.stderr ?? "").trim();
746
+ if (stderr.length > 0) return stderr;
747
+ }
748
+ return error instanceof Error ? error.message : String(error);
749
+ }
750
+ async function collectInitContext(rawInput = {}, options = {}) {
751
+ const projectDir = path.resolve(options.projectDir ?? process.cwd());
752
+ const input = InitCommandInputSchema.parse(rawInput);
753
+ const useDefaults = input.yes === true;
754
+ const verbose = input.verbose === true;
755
+ const shouldGenerate = input.generate ?? DEFAULT_GENERATE;
756
+ if (!options.skipIntro) intro(getCreatePrismaIntro());
757
+ let prismaFilesMode = "create";
758
+ const existingPrismaFiles = findExistingPrismaFiles(projectDir);
759
+ const canReuseExistingPrismaFiles = canReusePrismaFiles(projectDir);
760
+ if (existingPrismaFiles.length > 0) if (useDefaults) prismaFilesMode = canReuseExistingPrismaFiles ? "reuse" : "overwrite";
761
+ else {
762
+ const selectedMode = await promptForPrismaFilesMode(existingPrismaFiles, canReuseExistingPrismaFiles, projectDir);
763
+ if (!selectedMode) return;
764
+ prismaFilesMode = selectedMode;
765
+ }
766
+ const databaseProvider = input.provider ?? (useDefaults ? DEFAULT_DATABASE_PROVIDER : await promptForDatabaseProvider());
767
+ if (!databaseProvider) return;
768
+ const schemaPreset = input.schemaPreset ?? DEFAULT_SCHEMA_PRESET$1;
769
+ const databaseUrl = input.databaseUrl;
770
+ let shouldUsePrismaPostgres = false;
771
+ if (databaseProvider === "postgresql" && !databaseUrl) {
772
+ const prismaPostgresChoice = input.prismaPostgres ?? (useDefaults ? DEFAULT_PRISMA_POSTGRES : await promptForPrismaPostgres());
773
+ if (prismaPostgresChoice === void 0) return;
774
+ shouldUsePrismaPostgres = prismaPostgresChoice;
775
+ }
776
+ const detectedPackageManager = await detectPackageManager(projectDir);
777
+ const packageManager = input.packageManager ?? (useDefaults ? detectedPackageManager : await promptForPackageManager(detectedPackageManager));
778
+ if (!packageManager) return;
779
+ const shouldInstall = input.install ?? (useDefaults ? DEFAULT_INSTALL : await promptForDependencyInstall(packageManager));
780
+ if (shouldInstall === void 0) return;
781
+ return {
782
+ projectDir,
783
+ verbose,
784
+ shouldGenerate,
785
+ prismaFilesMode,
786
+ databaseProvider,
787
+ schemaPreset,
788
+ databaseUrl,
789
+ shouldUsePrismaPostgres,
790
+ packageManager,
791
+ shouldInstall
792
+ };
793
+ }
794
+ async function provisionPrismaPostgresIfNeeded(context, projectDir) {
795
+ if (!context.shouldUsePrismaPostgres) return { databaseUrl: context.databaseUrl };
796
+ const createDbCommand = getCreateDbCommand(context.packageManager);
797
+ const prismaPostgresSpinner = spinner();
798
+ prismaPostgresSpinner.start(`Provisioning Prisma Postgres with ${createDbCommand}...`);
799
+ try {
800
+ const prismaPostgresResult = await provisionPrismaPostgres(context.packageManager, projectDir);
801
+ prismaPostgresSpinner.stop("Prisma Postgres database provisioned.");
802
+ return {
803
+ databaseUrl: prismaPostgresResult.databaseUrl,
804
+ claimUrl: prismaPostgresResult.claimUrl
805
+ };
806
+ } catch (error) {
807
+ const errorMessage = error instanceof Error ? error.message : String(error);
808
+ prismaPostgresSpinner.stop("Could not provision Prisma Postgres.");
809
+ return {
810
+ databaseUrl: context.databaseUrl,
811
+ warning: `Prisma Postgres provisioning failed: ${errorMessage}`
812
+ };
813
+ }
814
+ }
815
+ async function writeDependenciesForContext(context, projectDir) {
816
+ try {
817
+ return await writePrismaDependencies(context.databaseProvider, projectDir);
818
+ } catch (error) {
819
+ cancel(getCommandErrorMessage(error));
820
+ return;
821
+ }
822
+ }
823
+ async function installDependenciesForContext(context, projectDir) {
824
+ if (!context.shouldInstall) return true;
825
+ const installCommand = getInstallCommand(context.packageManager);
826
+ if (context.verbose) {
827
+ log.step(`Running ${installCommand}`);
828
+ try {
829
+ await installProjectDependencies(context.packageManager, projectDir, { verbose: context.verbose });
830
+ log.success("Dependencies installed.");
831
+ return true;
832
+ } catch (error) {
833
+ cancel(`Failed to run ${installCommand}: ${getCommandErrorMessage(error)}`);
834
+ return false;
835
+ }
836
+ }
837
+ const installSpinner = spinner();
838
+ installSpinner.start(`Running ${installCommand}...`);
839
+ try {
840
+ await installProjectDependencies(context.packageManager, projectDir, { verbose: context.verbose });
841
+ installSpinner.stop("Dependencies installed.");
842
+ return true;
843
+ } catch (error) {
844
+ installSpinner.stop("Could not install dependencies.");
845
+ cancel(`Failed to run ${installCommand}: ${getCommandErrorMessage(error)}`);
846
+ return false;
847
+ }
848
+ }
849
+ async function initializePrismaFilesForContext(context, projectDir, provisionResult) {
850
+ const initSpinner = spinner();
851
+ initSpinner.start("Preparing Prisma files...");
852
+ try {
853
+ const initResult = await initializePrismaFiles({
854
+ provider: context.databaseProvider,
855
+ databaseUrl: provisionResult.databaseUrl,
856
+ claimUrl: provisionResult.claimUrl,
857
+ schemaPreset: context.schemaPreset,
858
+ prismaFilesMode: context.prismaFilesMode,
859
+ projectDir
860
+ });
861
+ if (initResult.prismaFilesMode === "overwrite") initSpinner.stop("Prisma files updated.");
862
+ else if (initResult.prismaFilesMode === "reuse") initSpinner.stop("Using existing Prisma files.");
863
+ else initSpinner.stop("Prisma files ready.");
864
+ return initResult;
865
+ } catch (error) {
866
+ initSpinner.stop("Could not prepare Prisma files.");
867
+ cancel(getCommandErrorMessage(error));
868
+ return;
869
+ }
870
+ }
871
+ async function generatePrismaClientForContext(context, projectDir) {
872
+ if (!context.shouldGenerate) return { didGenerateClient: false };
873
+ const generateCommand = getPrismaCliCommand(context.packageManager, ["generate"]);
874
+ if (context.verbose) log.step(`Running ${generateCommand}`);
875
+ const generateSpinner = context.verbose ? void 0 : spinner();
876
+ generateSpinner?.start("Generating Prisma Client...");
877
+ try {
878
+ const generateArgs = getPrismaCliArgs(context.packageManager, ["generate"]);
879
+ await execa(generateArgs.command, generateArgs.args, {
880
+ cwd: projectDir,
881
+ stdio: context.verbose ? "inherit" : "pipe"
882
+ });
883
+ if (context.verbose) log.success("Prisma Client generated.");
884
+ else generateSpinner?.stop("Prisma Client generated.");
885
+ return { didGenerateClient: true };
886
+ } catch (error) {
887
+ if (context.verbose) log.warn("Could not generate Prisma Client.");
888
+ else generateSpinner?.stop("Could not generate Prisma Client.");
889
+ return {
890
+ didGenerateClient: false,
891
+ warning: `Prisma generate failed: ${getCommandErrorMessage(error)}`
892
+ };
893
+ }
894
+ }
895
+ function buildWarningLines(provisionWarning, generateWarning) {
896
+ const warningLines = [];
897
+ if (provisionWarning) warningLines.push(`- ${provisionWarning}`);
898
+ if (generateWarning) warningLines.push(`- ${generateWarning}`);
899
+ return warningLines;
900
+ }
901
+ function buildNextStepsForContext(opts) {
902
+ const { context, options, didGenerateClient } = opts;
903
+ const nextSteps = [...options.prependNextSteps ?? []];
904
+ if (!context.shouldInstall) nextSteps.push(`- ${getInstallCommand(context.packageManager)}`);
905
+ if (!didGenerateClient || !context.shouldGenerate) nextSteps.push(`- ${getRunScriptCommand(context.packageManager, "db:generate")}`);
906
+ nextSteps.push(`- ${getRunScriptCommand(context.packageManager, "db:migrate")}`);
907
+ if (options.includeDevNextStep) nextSteps.push(`- ${getRunScriptCommand(context.packageManager, "dev")}`);
908
+ return nextSteps;
909
+ }
910
+ async function executeInitContext(context, options = {}) {
911
+ const projectDir = path.resolve(options.projectDir ?? context.projectDir);
912
+ const provisionResult = await provisionPrismaPostgresIfNeeded(context, projectDir);
913
+ if (!provisionResult) return;
914
+ if (!await writeDependenciesForContext(context, projectDir)) return;
915
+ if (!await installDependenciesForContext(context, projectDir)) return;
916
+ if (!await initializePrismaFilesForContext(context, projectDir, provisionResult)) return;
917
+ const generateResult = await generatePrismaClientForContext(context, projectDir);
918
+ const warningLines = buildWarningLines(provisionResult.warning, generateResult.warning);
919
+ const nextSteps = buildNextStepsForContext({
920
+ context,
921
+ options,
922
+ didGenerateClient: generateResult.didGenerateClient
923
+ });
924
+ outro(`Setup complete.${warningLines.length > 0 ? `\n\n${warningLines.join("\n")}` : ""}
925
+
926
+ Next steps:
927
+ ${nextSteps.join("\n")}`);
928
+ return { packageManager: context.packageManager };
929
+ }
930
+ async function runInitCommand(rawInput = {}, options = {}) {
931
+ try {
932
+ const context = await collectInitContext(rawInput, options);
933
+ if (!context) return;
934
+ return executeInitContext(context, options);
935
+ } catch (error) {
936
+ cancel(`Init command failed: ${error instanceof Error ? error.message : String(error)}`);
937
+ return;
938
+ }
939
+ }
940
+
941
+ //#endregion
942
+ //#region src/commands/create.ts
943
+ const DEFAULT_PROJECT_NAME = "my-app";
944
+ const DEFAULT_TEMPLATE = "hono";
945
+ const DEFAULT_SCHEMA_PRESET = "basic";
946
+ function toPackageName(projectName) {
947
+ return projectName.toLowerCase().replace(/[^a-z0-9._-]/g, "-").replace(/^-+/, "").replace(/-+$/, "") || "app";
948
+ }
949
+ function formatPathForDisplay(filePath) {
950
+ return path.relative(process.cwd(), filePath) || ".";
951
+ }
952
+ function validateProjectName(value) {
953
+ const trimmed = String(value ?? "").trim();
954
+ if (trimmed.length === 0) return "Please enter a project name.";
955
+ if (trimmed === "." || trimmed === "..") return "Project name cannot be '.' or '..'.";
956
+ if (path.isAbsolute(trimmed)) return "Use a relative project name instead of an absolute path.";
957
+ }
958
+ async function promptForProjectName() {
959
+ const projectName = await text({
960
+ message: "Project name",
961
+ placeholder: DEFAULT_PROJECT_NAME,
962
+ initialValue: DEFAULT_PROJECT_NAME,
963
+ validate: validateProjectName
964
+ });
965
+ if (isCancel(projectName)) {
966
+ cancel("Operation cancelled.");
967
+ return;
968
+ }
969
+ return String(projectName).trim();
970
+ }
971
+ async function promptForCreateTemplate() {
972
+ const template = await select({
973
+ message: "Select template",
974
+ initialValue: DEFAULT_TEMPLATE,
975
+ options: [{
976
+ value: "hono",
977
+ label: "Hono",
978
+ hint: "Bun + TypeScript API starter"
979
+ }, {
980
+ value: "next",
981
+ label: "Next.js",
982
+ hint: "App Router + TypeScript starter"
983
+ }]
984
+ });
985
+ if (isCancel(template)) {
986
+ cancel("Operation cancelled.");
987
+ return;
988
+ }
989
+ return CreateTemplateSchema.parse(template);
990
+ }
991
+ async function inspectTargetPath(targetPath) {
992
+ if (!await fs.pathExists(targetPath)) return {
993
+ exists: false,
994
+ isDirectory: true,
995
+ isEmptyDirectory: true
996
+ };
997
+ if (!(await fs.stat(targetPath)).isDirectory()) return {
998
+ exists: true,
999
+ isDirectory: false,
1000
+ isEmptyDirectory: false
1001
+ };
1002
+ return {
1003
+ exists: true,
1004
+ isDirectory: true,
1005
+ isEmptyDirectory: (await fs.readdir(targetPath)).length === 0
1006
+ };
1007
+ }
1008
+ async function runCreateCommand(rawInput = {}) {
1009
+ try {
1010
+ const input = CreateCommandInputSchema.parse(rawInput);
1011
+ intro(getCreatePrismaIntro());
1012
+ const context = await collectCreateContext(input);
1013
+ if (!context) return;
1014
+ await executeCreateContext(context);
1015
+ } catch (error) {
1016
+ cancel(`Create command failed: ${error instanceof Error ? error.message : String(error)}`);
1017
+ }
1018
+ }
1019
+ async function collectCreateContext(input) {
1020
+ const useDefaults = input.yes === true;
1021
+ const force = input.force === true;
1022
+ const projectName = input.name ?? (useDefaults ? DEFAULT_PROJECT_NAME : await promptForProjectName());
1023
+ if (!projectName) return;
1024
+ const template = input.template ?? (useDefaults ? DEFAULT_TEMPLATE : await promptForCreateTemplate());
1025
+ if (!template) return;
1026
+ const schemaPreset = input.schemaPreset ?? DEFAULT_SCHEMA_PRESET;
1027
+ const targetDirectory = path.resolve(process.cwd(), projectName);
1028
+ const targetPathState = await inspectTargetPath(targetDirectory);
1029
+ if (targetPathState.exists && !targetPathState.isDirectory) {
1030
+ cancel(`Target path ${formatPathForDisplay(targetDirectory)} already exists and is not a directory. Choose a different project name.`);
1031
+ return;
1032
+ }
1033
+ if (targetPathState.exists && !targetPathState.isEmptyDirectory && !force) {
1034
+ cancel(`Target directory ${formatPathForDisplay(targetDirectory)} is not empty. Use --force to continue.`);
1035
+ return;
1036
+ }
1037
+ const initContext = await collectInitContext({
1038
+ yes: input.yes,
1039
+ verbose: input.verbose,
1040
+ provider: input.provider,
1041
+ packageManager: input.packageManager,
1042
+ prismaPostgres: input.prismaPostgres,
1043
+ databaseUrl: input.databaseUrl,
1044
+ install: input.install,
1045
+ generate: input.generate,
1046
+ schemaPreset
1047
+ }, {
1048
+ skipIntro: true,
1049
+ projectDir: targetDirectory
1050
+ });
1051
+ if (!initContext) return;
1052
+ return {
1053
+ targetDirectory,
1054
+ targetPathState,
1055
+ force,
1056
+ template,
1057
+ schemaPreset,
1058
+ projectPackageName: toPackageName(path.basename(targetDirectory)),
1059
+ initContext
1060
+ };
1061
+ }
1062
+ async function executeCreateContext(context) {
1063
+ const scaffoldSpinner = spinner();
1064
+ scaffoldSpinner.start(`Scaffolding ${context.template} project...`);
1065
+ try {
1066
+ await scaffoldCreateTemplate({
1067
+ projectDir: context.targetDirectory,
1068
+ projectName: context.projectPackageName,
1069
+ template: context.template,
1070
+ schemaPreset: context.schemaPreset,
1071
+ packageManager: context.initContext.packageManager
1072
+ });
1073
+ scaffoldSpinner.stop("Project files scaffolded.");
1074
+ } catch (error) {
1075
+ scaffoldSpinner.stop("Could not scaffold project files.");
1076
+ cancel(error instanceof Error ? error.message : String(error));
1077
+ return;
1078
+ }
1079
+ if (context.targetPathState.exists && !context.targetPathState.isEmptyDirectory && context.force) log.warn(`Used --force in non-empty directory ${formatPathForDisplay(context.targetDirectory)}.`);
1080
+ const cdStep = `- cd ${formatPathForDisplay(context.targetDirectory)}`;
1081
+ await executeInitContext(context.initContext, {
1082
+ skipIntro: true,
1083
+ prependNextSteps: [cdStep],
1084
+ projectDir: context.targetDirectory,
1085
+ includeDevNextStep: true
1086
+ });
1087
+ }
1088
+
1089
+ //#endregion
1090
+ export { DatabaseProviderSchema as a, PackageManagerSchema as c, CreateTemplateSchema as i, SchemaPresetSchema as l, runInitCommand as n, DatabaseUrlSchema as o, CreateCommandInputSchema as r, InitCommandInputSchema as s, runCreateCommand as t };