create-prisma 0.3.2 → 0.4.1-pr.33.62.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -117
- package/dist/cli.mjs +1 -1
- package/dist/{create-DOr8R2_6.mjs → create-CDlZ32XO.mjs} +221 -120
- package/dist/index.d.mts +6 -0
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
- package/templates/create/astro/src/pages/index.astro.hbs +39 -49
- package/templates/create/elysia/README.md.hbs +32 -0
- package/templates/create/elysia/deno.json.hbs +5 -0
- package/templates/create/elysia/package.json.hbs +21 -0
- package/templates/create/elysia/prisma/schema.prisma.hbs +25 -0
- package/templates/create/elysia/prisma/seed.ts.hbs +42 -0
- package/templates/create/elysia/prisma.config.ts.hbs +15 -0
- package/templates/create/elysia/src/index.ts.hbs +43 -0
- package/templates/create/elysia/src/lib/prisma.ts.hbs +56 -0
- package/templates/create/elysia/tsconfig.json +14 -0
- package/templates/create/hono/README.md.hbs +3 -2
- package/templates/create/hono/package.json.hbs +3 -4
- package/templates/create/hono/prisma/schema.prisma.hbs +4 -0
- package/templates/create/hono/prisma/seed.ts.hbs +5 -1
- package/templates/create/hono/prisma.config.ts.hbs +15 -0
- package/templates/create/hono/src/index.ts.hbs +8 -2
- package/templates/create/hono/src/lib/prisma.ts.hbs +6 -3
- package/templates/create/nest/.yarnrc.yml.hbs +3 -0
- package/templates/create/nest/README.md.hbs +32 -0
- package/templates/create/nest/deno.json.hbs +5 -0
- package/templates/create/nest/package.json.hbs +24 -0
- package/templates/create/nest/prisma/schema.prisma.hbs +25 -0
- package/templates/create/nest/prisma/seed.ts.hbs +44 -0
- package/templates/create/nest/prisma.config.ts.hbs +15 -0
- package/templates/create/nest/src/app.controller.ts.hbs +11 -0
- package/templates/create/nest/src/app.module.ts.hbs +20 -0
- package/templates/create/nest/src/lib/prisma.ts.hbs +58 -0
- package/templates/create/nest/src/main.ts.hbs +27 -0
- package/templates/create/nest/src/prisma.service.ts.hbs +10 -0
- package/templates/create/nest/src/users.controller.ts.hbs +15 -0
- package/templates/create/nest/src/users.service.ts.hbs +19 -0
- package/templates/create/nest/tsconfig.json +16 -0
- package/templates/create/next/src/app/globals.css +38 -46
- package/templates/create/nuxt/app/pages/index.vue.hbs +45 -55
- package/templates/create/svelte/src/routes/+page.svelte.hbs +78 -99
- package/templates/create/tanstack-start/prisma/schema.prisma.hbs +0 -1
- package/templates/create/tanstack-start/src/routes/index.tsx.hbs +28 -30
- package/templates/create/tanstack-start/src/styles.css +80 -121
- package/templates/create/turborepo/apps/api/package.json.hbs +0 -2
- package/templates/create/turborepo/apps/api/src/index.ts.hbs +7 -1
- package/templates/create/hono/prisma.config.ts +0 -13
|
@@ -12,17 +12,55 @@ import os from "node:os";
|
|
|
12
12
|
import { PostHog } from "posthog-node";
|
|
13
13
|
import { styleText } from "node:util";
|
|
14
14
|
|
|
15
|
+
//#region src/utils/runtime.ts
|
|
16
|
+
function usesNodeStyleRuntime(packageManager) {
|
|
17
|
+
return packageManager !== void 0 && packageManager !== "bun" && packageManager !== "deno";
|
|
18
|
+
}
|
|
19
|
+
function requiresDotenvConfigImport(packageManager) {
|
|
20
|
+
return usesNodeStyleRuntime(packageManager);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
15
24
|
//#region src/constants/dependencies.ts
|
|
16
25
|
const dependencyVersionMap = {
|
|
26
|
+
"@elysiajs/node": "^1.4.5",
|
|
17
27
|
"@prisma/client": "^7.4.0",
|
|
18
28
|
"@prisma/adapter-pg": "^7.4.0",
|
|
19
29
|
"@prisma/adapter-mariadb": "^7.4.0",
|
|
20
30
|
"@prisma/adapter-better-sqlite3": "^7.4.0",
|
|
21
31
|
"@prisma/adapter-mssql": "^7.4.0",
|
|
32
|
+
"@types/node": "^24.3.0",
|
|
22
33
|
dotenv: "^17.2.3",
|
|
23
34
|
"node-gyp": "^11.5.0",
|
|
24
|
-
prisma: "^7.4.0"
|
|
35
|
+
prisma: "^7.4.0",
|
|
36
|
+
tsx: "^4.21.0"
|
|
25
37
|
};
|
|
38
|
+
function getWorkspaceDependencyVersion(packageManager) {
|
|
39
|
+
return packageManager === "npm" ? "*" : "workspace:*";
|
|
40
|
+
}
|
|
41
|
+
function getCreateTemplateDependencies(template, packageManager) {
|
|
42
|
+
const targets = [];
|
|
43
|
+
if (template === "hono" || template === "elysia" || template === "nest") {
|
|
44
|
+
const runtimeDevDependencies = usesNodeStyleRuntime(packageManager) ? ["tsx"] : [];
|
|
45
|
+
if (template === "elysia" && packageManager !== "deno") targets.push({
|
|
46
|
+
packageJsonPath: "package.json",
|
|
47
|
+
dependencies: ["@elysiajs/node"],
|
|
48
|
+
devDependencies: ["@types/node", ...runtimeDevDependencies]
|
|
49
|
+
});
|
|
50
|
+
else if (runtimeDevDependencies.length > 0) targets.push({
|
|
51
|
+
packageJsonPath: "package.json",
|
|
52
|
+
dependencies: [],
|
|
53
|
+
devDependencies: runtimeDevDependencies
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (template === "turborepo") targets.push({
|
|
57
|
+
packageJsonPath: "apps/api/package.json",
|
|
58
|
+
dependencies: [],
|
|
59
|
+
devDependencies: ["tsx"],
|
|
60
|
+
customDependencies: { "@repo/db": getWorkspaceDependencyVersion(packageManager) }
|
|
61
|
+
});
|
|
62
|
+
return targets;
|
|
63
|
+
}
|
|
26
64
|
|
|
27
65
|
//#endregion
|
|
28
66
|
//#region src/types.ts
|
|
@@ -43,6 +81,8 @@ const packageManagers = [
|
|
|
43
81
|
const schemaPresets = ["empty", "basic"];
|
|
44
82
|
const createTemplates = [
|
|
45
83
|
"hono",
|
|
84
|
+
"elysia",
|
|
85
|
+
"nest",
|
|
46
86
|
"next",
|
|
47
87
|
"svelte",
|
|
48
88
|
"astro",
|
|
@@ -181,10 +221,17 @@ function getPackageManagerManifestValue(packageManager) {
|
|
|
181
221
|
return packageManagerManifestValues[packageManager];
|
|
182
222
|
}
|
|
183
223
|
function getDenoPrismaSpecifier() {
|
|
184
|
-
return `npm:prisma@${dependencyVersionMap.prisma
|
|
224
|
+
return `npm:prisma@${dependencyVersionMap.prisma}`;
|
|
225
|
+
}
|
|
226
|
+
function getDenoAllowedScriptSpecifiers() {
|
|
227
|
+
return [
|
|
228
|
+
`npm:prisma@${dependencyVersionMap.prisma}`,
|
|
229
|
+
`npm:@prisma/client@${dependencyVersionMap["@prisma/client"]}`,
|
|
230
|
+
`npm:@prisma/engines@${dependencyVersionMap.prisma}`
|
|
231
|
+
].join(",");
|
|
185
232
|
}
|
|
186
233
|
function getInstallCommand(packageManager) {
|
|
187
|
-
if (packageManager === "deno") return
|
|
234
|
+
if (packageManager === "deno") return `deno install --allow-scripts=${getDenoAllowedScriptSpecifiers()}`;
|
|
188
235
|
return `${packageManager} install`;
|
|
189
236
|
}
|
|
190
237
|
function getRunScriptCommand(packageManager, scriptName) {
|
|
@@ -196,10 +243,46 @@ function getRunScriptCommand(packageManager, scriptName) {
|
|
|
196
243
|
default: return `npm run ${scriptName}`;
|
|
197
244
|
}
|
|
198
245
|
}
|
|
246
|
+
function joinCommandParts(parts) {
|
|
247
|
+
return parts.filter((part) => typeof part === "string" && part.length > 0).join(" ");
|
|
248
|
+
}
|
|
249
|
+
function getRuntimeScriptCommand(packageManager, kind, options) {
|
|
250
|
+
const { sourceEntrypoint, builtEntrypoint, denoFlags = [] } = options;
|
|
251
|
+
if (packageManager === "deno") switch (kind) {
|
|
252
|
+
case "dev": return joinCommandParts([
|
|
253
|
+
"deno",
|
|
254
|
+
"run",
|
|
255
|
+
"-A",
|
|
256
|
+
"--env-file=.env",
|
|
257
|
+
...denoFlags,
|
|
258
|
+
"--watch",
|
|
259
|
+
sourceEntrypoint
|
|
260
|
+
]);
|
|
261
|
+
case "build": return `deno check ${sourceEntrypoint}`;
|
|
262
|
+
case "start": return joinCommandParts([
|
|
263
|
+
"deno",
|
|
264
|
+
"run",
|
|
265
|
+
"-A",
|
|
266
|
+
"--env-file=.env",
|
|
267
|
+
...denoFlags,
|
|
268
|
+
sourceEntrypoint
|
|
269
|
+
]);
|
|
270
|
+
}
|
|
271
|
+
if (packageManager === "bun") switch (kind) {
|
|
272
|
+
case "dev": return `bun --watch ${sourceEntrypoint}`;
|
|
273
|
+
case "build": return "tsc --noEmit";
|
|
274
|
+
case "start": return `bun ${sourceEntrypoint}`;
|
|
275
|
+
}
|
|
276
|
+
switch (kind) {
|
|
277
|
+
case "dev": return `tsx watch ${sourceEntrypoint}`;
|
|
278
|
+
case "build": return "tsc";
|
|
279
|
+
case "start": return builtEntrypoint ? `node ${builtEntrypoint}` : `tsx ${sourceEntrypoint}`;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
199
282
|
function getInstallArgs(packageManager) {
|
|
200
283
|
if (packageManager === "deno") return {
|
|
201
284
|
command: "deno",
|
|
202
|
-
args: ["install",
|
|
285
|
+
args: ["install", `--allow-scripts=${getDenoAllowedScriptSpecifiers()}`]
|
|
203
286
|
};
|
|
204
287
|
return {
|
|
205
288
|
command: packageManager,
|
|
@@ -254,6 +337,7 @@ function getPrismaCliArgs(packageManager, prismaArgs) {
|
|
|
254
337
|
args: [
|
|
255
338
|
"run",
|
|
256
339
|
"-A",
|
|
340
|
+
"--env-file=.env",
|
|
257
341
|
getDenoPrismaSpecifier(),
|
|
258
342
|
...prismaArgs
|
|
259
343
|
]
|
|
@@ -267,10 +351,26 @@ function getPrismaCliCommand(packageManager, prismaArgs) {
|
|
|
267
351
|
|
|
268
352
|
//#endregion
|
|
269
353
|
//#region src/templates/shared.ts
|
|
354
|
+
function getOptionalHashString(hash, key) {
|
|
355
|
+
const value = hash[key];
|
|
356
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
357
|
+
}
|
|
358
|
+
function getOptionalHashStringList(hash, key) {
|
|
359
|
+
return getOptionalHashString(hash, key)?.split(" ") ?? [];
|
|
360
|
+
}
|
|
270
361
|
Handlebars.registerHelper("eq", (left, right) => left === right);
|
|
271
|
-
Handlebars.registerHelper("installCommand", (packageManager) => packageManager ? getInstallCommand(packageManager) : "");
|
|
272
362
|
Handlebars.registerHelper("runScriptCommand", (packageManager, scriptName) => packageManager ? getRunScriptCommand(packageManager, scriptName) : "");
|
|
273
363
|
Handlebars.registerHelper("packageManagerManifestValue", (packageManager) => getPackageManagerManifestValue(packageManager) ?? "");
|
|
364
|
+
Handlebars.registerHelper("requiresDotenvConfigImport", (packageManager) => requiresDotenvConfigImport(packageManager));
|
|
365
|
+
Handlebars.registerHelper("runtimeScript", (packageManager, kind, sourceEntrypoint, builtEntrypoint, options) => {
|
|
366
|
+
if (!packageManager) return "";
|
|
367
|
+
const hash = options.hash;
|
|
368
|
+
return getRuntimeScriptCommand(packageManager, kind, {
|
|
369
|
+
sourceEntrypoint,
|
|
370
|
+
builtEntrypoint,
|
|
371
|
+
denoFlags: getOptionalHashStringList(hash, "denoFlags")
|
|
372
|
+
});
|
|
373
|
+
});
|
|
274
374
|
function findPackageRoot(startDir) {
|
|
275
375
|
let currentDir = startDir;
|
|
276
376
|
while (true) {
|
|
@@ -353,10 +453,10 @@ async function scaffoldCreateTemplate(opts) {
|
|
|
353
453
|
function getDbPackages(provider) {
|
|
354
454
|
switch (provider) {
|
|
355
455
|
case "postgresql":
|
|
356
|
-
case "cockroachdb": return
|
|
357
|
-
case "mysql": return
|
|
358
|
-
case "sqlite": return
|
|
359
|
-
case "sqlserver": return
|
|
456
|
+
case "cockroachdb": return "@prisma/adapter-pg";
|
|
457
|
+
case "mysql": return "@prisma/adapter-mariadb";
|
|
458
|
+
case "sqlite": return "@prisma/adapter-better-sqlite3";
|
|
459
|
+
case "sqlserver": return "@prisma/adapter-mssql";
|
|
360
460
|
default: {
|
|
361
461
|
const exhaustiveCheck = provider;
|
|
362
462
|
throw new Error(`Unsupported database provider: ${String(exhaustiveCheck)}`);
|
|
@@ -370,10 +470,19 @@ function getPrismaScriptMap(packageManager) {
|
|
|
370
470
|
if (packageManager === "deno") {
|
|
371
471
|
const prismaSpecifier = getDenoPrismaSpecifier();
|
|
372
472
|
return {
|
|
373
|
-
"db:generate": `deno run -A ${prismaSpecifier} generate`,
|
|
374
|
-
"db:push": `deno run -A ${prismaSpecifier} db push`,
|
|
375
|
-
"db:migrate": `deno run -A ${prismaSpecifier} migrate dev`,
|
|
376
|
-
"db:seed": `deno run -A ${prismaSpecifier} db seed`
|
|
473
|
+
"db:generate": `deno run -A --env-file=.env ${prismaSpecifier} generate`,
|
|
474
|
+
"db:push": `deno run -A --env-file=.env ${prismaSpecifier} db push`,
|
|
475
|
+
"db:migrate": `deno run -A --env-file=.env ${prismaSpecifier} migrate dev`,
|
|
476
|
+
"db:seed": `deno run -A --env-file=.env ${prismaSpecifier} db seed`
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
if (packageManager === "bun") {
|
|
480
|
+
const prismaCli = "bun --env-file=.env ./node_modules/.bin/prisma";
|
|
481
|
+
return {
|
|
482
|
+
"db:generate": `${prismaCli} generate`,
|
|
483
|
+
"db:push": `${prismaCli} db push`,
|
|
484
|
+
"db:migrate": `${prismaCli} migrate dev`,
|
|
485
|
+
"db:seed": `${prismaCli} db seed`
|
|
377
486
|
};
|
|
378
487
|
}
|
|
379
488
|
return {
|
|
@@ -392,10 +501,27 @@ function unique(items) {
|
|
|
392
501
|
function sortRecord(record) {
|
|
393
502
|
return Object.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));
|
|
394
503
|
}
|
|
504
|
+
async function projectContainsText(projectDir, text) {
|
|
505
|
+
const directories = [projectDir];
|
|
506
|
+
while (directories.length > 0) {
|
|
507
|
+
const currentDirectory = directories.pop();
|
|
508
|
+
if (!currentDirectory) continue;
|
|
509
|
+
const entries = await fs.readdir(currentDirectory, { withFileTypes: true });
|
|
510
|
+
for (const entry of entries) {
|
|
511
|
+
if (entry.name === "node_modules" || entry.name === ".git") continue;
|
|
512
|
+
const entryPath = path.join(currentDirectory, entry.name);
|
|
513
|
+
if (entry.isDirectory()) {
|
|
514
|
+
directories.push(entryPath);
|
|
515
|
+
continue;
|
|
516
|
+
}
|
|
517
|
+
if (!entry.isFile() || !/\.(c|m)?[jt]sx?$/.test(entry.name)) continue;
|
|
518
|
+
if ((await fs.readFile(entryPath, "utf8")).includes(text)) return true;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return false;
|
|
522
|
+
}
|
|
395
523
|
async function addPackageDependency(opts) {
|
|
396
|
-
const { dependencies = [], devDependencies = [], customDependencies = {},
|
|
397
|
-
const addedScripts = [];
|
|
398
|
-
const existingScripts = [];
|
|
524
|
+
const { dependencies = [], devDependencies = [], customDependencies = {}, scripts = {}, scriptMode, projectDir } = opts;
|
|
399
525
|
const pkgJsonPath = path.join(projectDir, "package.json");
|
|
400
526
|
if (!await fs.pathExists(pkgJsonPath)) throw new Error(`No package.json found in ${projectDir}. Run this command inside an existing JavaScript/TypeScript project.`);
|
|
401
527
|
const pkgJson = await fs.readJson(pkgJsonPath);
|
|
@@ -413,48 +539,43 @@ async function addPackageDependency(opts) {
|
|
|
413
539
|
else console.warn(`Warning: Dev dependency ${pkgName} not found in version map.`);
|
|
414
540
|
}
|
|
415
541
|
for (const [pkgName, version] of Object.entries(customDependencies)) pkgJson.dependencies[pkgName] = version;
|
|
416
|
-
for (const [pkgName, version] of Object.entries(customDevDependencies)) pkgJson.devDependencies[pkgName] = version;
|
|
417
542
|
for (const [scriptName, command] of Object.entries(scripts)) {
|
|
418
543
|
if (scriptMode === "if-missing") {
|
|
419
|
-
if (typeof pkgJson.scripts[scriptName] !== "string" || pkgJson.scripts[scriptName].trim().length === 0)
|
|
420
|
-
pkgJson.scripts[scriptName] = command;
|
|
421
|
-
addedScripts.push(scriptName);
|
|
422
|
-
} else existingScripts.push(scriptName);
|
|
544
|
+
if (typeof pkgJson.scripts[scriptName] !== "string" || pkgJson.scripts[scriptName].trim().length === 0) pkgJson.scripts[scriptName] = command;
|
|
423
545
|
continue;
|
|
424
546
|
}
|
|
425
|
-
if (pkgJson.scripts[scriptName] === command) existingScripts.push(scriptName);
|
|
426
|
-
else addedScripts.push(scriptName);
|
|
427
547
|
pkgJson.scripts[scriptName] = command;
|
|
428
548
|
}
|
|
429
549
|
pkgJson.dependencies = sortRecord(pkgJson.dependencies);
|
|
430
550
|
pkgJson.devDependencies = sortRecord(pkgJson.devDependencies);
|
|
431
551
|
await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
|
|
432
|
-
return {
|
|
433
|
-
addedScripts,
|
|
434
|
-
existingScripts
|
|
435
|
-
};
|
|
436
552
|
}
|
|
437
553
|
async function writePrismaDependencies(provider, packageManager, projectDir = process.cwd()) {
|
|
438
|
-
const dependencies = ["@prisma/client"
|
|
554
|
+
const dependencies = ["@prisma/client"];
|
|
439
555
|
const devDependencies = ["prisma"];
|
|
440
|
-
|
|
441
|
-
dependencies.push(
|
|
556
|
+
dependencies.push(getDbPackages(provider));
|
|
557
|
+
if (requiresDotenvConfigImport(packageManager) || await projectContainsText(projectDir, "dotenv/config")) dependencies.push("dotenv");
|
|
442
558
|
if (provider === "sqlite" && packageManager === "deno") devDependencies.push("node-gyp");
|
|
443
|
-
|
|
444
|
-
const scriptWriteResult = await addPackageDependency({
|
|
559
|
+
await addPackageDependency({
|
|
445
560
|
dependencies,
|
|
446
561
|
devDependencies,
|
|
447
|
-
scripts:
|
|
562
|
+
scripts: getPrismaScriptMap(packageManager),
|
|
448
563
|
scriptMode: "if-missing",
|
|
449
564
|
projectDir
|
|
450
565
|
});
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
566
|
+
}
|
|
567
|
+
async function writeCreateTemplateDependencies(opts) {
|
|
568
|
+
const { template, packageManager, projectDir = process.cwd() } = opts;
|
|
569
|
+
const targets = getCreateTemplateDependencies(template, packageManager);
|
|
570
|
+
for (const dependencyTarget of targets) {
|
|
571
|
+
const targetDirectory = path.join(projectDir, path.dirname(dependencyTarget.packageJsonPath));
|
|
572
|
+
await addPackageDependency({
|
|
573
|
+
dependencies: dependencyTarget.dependencies,
|
|
574
|
+
devDependencies: dependencyTarget.devDependencies,
|
|
575
|
+
customDependencies: dependencyTarget.customDependencies,
|
|
576
|
+
projectDir: targetDirectory
|
|
577
|
+
});
|
|
578
|
+
}
|
|
458
579
|
}
|
|
459
580
|
async function installProjectDependencies(packageManager, projectDir = process.cwd(), options = {}) {
|
|
460
581
|
const verbose = options.verbose === true;
|
|
@@ -716,36 +837,20 @@ async function ensureEnvVarInEnv(projectDir, envVarName, envVarValue, opts) {
|
|
|
716
837
|
if (!await fs.pathExists(envPath)) {
|
|
717
838
|
const content = opts.comment ? `# ${opts.comment}\n${envLine}\n` : `${envLine}\n`;
|
|
718
839
|
await fs.writeFile(envPath, content, "utf8");
|
|
719
|
-
return
|
|
720
|
-
envPath,
|
|
721
|
-
status: "created"
|
|
722
|
-
};
|
|
840
|
+
return;
|
|
723
841
|
}
|
|
724
842
|
const existingContent = await fs.readFile(envPath, "utf8");
|
|
725
843
|
if (hasEnvVar(existingContent, envVarName)) {
|
|
726
|
-
if (opts.mode === "keep-existing") return
|
|
727
|
-
envPath,
|
|
728
|
-
status: "existing"
|
|
729
|
-
};
|
|
844
|
+
if (opts.mode === "keep-existing") return;
|
|
730
845
|
const escapedName = escapeRegExp(envVarName);
|
|
731
846
|
const lineRegex = new RegExp(`(^|\\n)\\s*${escapedName}\\s*=.*(?=\\n|$)`, "gm");
|
|
732
847
|
const updatedContent = existingContent.replace(lineRegex, `$1${envLine}`);
|
|
733
|
-
if (updatedContent === existingContent) return
|
|
734
|
-
envPath,
|
|
735
|
-
status: "existing"
|
|
736
|
-
};
|
|
848
|
+
if (updatedContent === existingContent) return;
|
|
737
849
|
await fs.writeFile(envPath, updatedContent, "utf8");
|
|
738
|
-
return
|
|
739
|
-
envPath,
|
|
740
|
-
status: "updated"
|
|
741
|
-
};
|
|
850
|
+
return;
|
|
742
851
|
}
|
|
743
852
|
const insertion = `${existingContent.endsWith("\n") ? "" : "\n"}${opts.comment ? `\n# ${opts.comment}\n` : "\n"}${envLine}\n`;
|
|
744
853
|
await fs.appendFile(envPath, insertion, "utf8");
|
|
745
|
-
return {
|
|
746
|
-
envPath,
|
|
747
|
-
status: "appended"
|
|
748
|
-
};
|
|
749
854
|
}
|
|
750
855
|
async function ensureEnvComment(projectDir, comment) {
|
|
751
856
|
const envPath = path.join(projectDir, ".env");
|
|
@@ -770,22 +875,12 @@ async function ensureGitignoreEntry(projectDir, entry) {
|
|
|
770
875
|
const gitignorePath = path.join(projectDir, ".gitignore");
|
|
771
876
|
if (!await fs.pathExists(gitignorePath)) {
|
|
772
877
|
await fs.writeFile(gitignorePath, `${entry}\n`, "utf8");
|
|
773
|
-
return
|
|
774
|
-
gitignorePath,
|
|
775
|
-
status: "created"
|
|
776
|
-
};
|
|
878
|
+
return;
|
|
777
879
|
}
|
|
778
880
|
const existingContent = await fs.readFile(gitignorePath, "utf8");
|
|
779
|
-
if (hasGitignoreEntry(existingContent, entry)) return
|
|
780
|
-
gitignorePath,
|
|
781
|
-
status: "existing"
|
|
782
|
-
};
|
|
881
|
+
if (hasGitignoreEntry(existingContent, entry)) return;
|
|
783
882
|
const separator = existingContent.endsWith("\n") ? "" : "\n";
|
|
784
883
|
await fs.appendFile(gitignorePath, `${separator}${entry}\n`, "utf8");
|
|
785
|
-
return {
|
|
786
|
-
gitignorePath,
|
|
787
|
-
status: "appended"
|
|
788
|
-
};
|
|
789
884
|
}
|
|
790
885
|
async function ensureRequiredPrismaFiles(projectDir) {
|
|
791
886
|
const missingFiles = [];
|
|
@@ -805,34 +900,20 @@ async function ensureRequiredPrismaFiles(projectDir) {
|
|
|
805
900
|
async function finalizePrismaFiles(options) {
|
|
806
901
|
const projectDir = options.projectDir ?? process.cwd();
|
|
807
902
|
const prismaProjectDir = await resolvePrismaProjectDir(projectDir);
|
|
808
|
-
const schemaPath = path.join(prismaProjectDir, "prisma/schema.prisma");
|
|
809
|
-
const configPath = path.join(prismaProjectDir, "prisma.config.ts");
|
|
810
903
|
await ensureRequiredPrismaFiles(projectDir);
|
|
811
|
-
const singletonPath = await fs.pathExists(path.join(prismaProjectDir, "src/lib/prisma.ts")) ? path.join(prismaProjectDir, "src/lib/prisma.ts") : await fs.pathExists(path.join(prismaProjectDir, "src/lib/prisma.server.ts")) ? path.join(prismaProjectDir, "src/lib/prisma.server.ts") : await fs.pathExists(path.join(prismaProjectDir, "src/lib/server/prisma.ts")) ? path.join(prismaProjectDir, "src/lib/server/prisma.ts") : await fs.pathExists(path.join(prismaProjectDir, "server/utils/prisma.ts")) ? path.join(prismaProjectDir, "server/utils/prisma.ts") : path.join(prismaProjectDir, "src/client.ts");
|
|
812
904
|
const generatedDir = await fs.pathExists(path.join(prismaProjectDir, "server/utils/prisma.ts")) ? "server/generated" : "src/generated";
|
|
813
|
-
|
|
905
|
+
await ensureEnvVarInEnv(prismaProjectDir, "DATABASE_URL", options.databaseUrl ?? getDefaultDatabaseUrl(options.provider), {
|
|
814
906
|
mode: options.databaseUrl ? "upsert" : "keep-existing",
|
|
815
907
|
comment: "Added by create-prisma"
|
|
816
908
|
});
|
|
817
|
-
let claimEnvStatus;
|
|
818
909
|
if (options.claimUrl) {
|
|
819
|
-
|
|
910
|
+
await ensureEnvVarInEnv(prismaProjectDir, "CLAIM_URL", options.claimUrl, {
|
|
820
911
|
mode: "upsert",
|
|
821
912
|
comment: PRISMA_POSTGRES_TEMPORARY_NOTICE
|
|
822
|
-
})
|
|
913
|
+
});
|
|
823
914
|
await ensureEnvComment(prismaProjectDir, PRISMA_POSTGRES_TEMPORARY_NOTICE);
|
|
824
915
|
}
|
|
825
|
-
|
|
826
|
-
return {
|
|
827
|
-
schemaPath,
|
|
828
|
-
configPath,
|
|
829
|
-
singletonPath,
|
|
830
|
-
envPath: envResult.envPath,
|
|
831
|
-
envStatus: envResult.status,
|
|
832
|
-
gitignorePath: gitignoreResult.gitignorePath,
|
|
833
|
-
gitignoreStatus: gitignoreResult.status,
|
|
834
|
-
claimEnvStatus
|
|
835
|
-
};
|
|
916
|
+
await ensureGitignoreEntry(prismaProjectDir, generatedDir);
|
|
836
917
|
}
|
|
837
918
|
async function provisionPrismaPostgresIfNeeded(context, projectDir) {
|
|
838
919
|
if (!context.shouldUsePrismaPostgres) return { databaseUrl: context.databaseUrl };
|
|
@@ -858,10 +939,11 @@ async function provisionPrismaPostgresIfNeeded(context, projectDir) {
|
|
|
858
939
|
async function writeDependenciesForContext(context, projectDir) {
|
|
859
940
|
const prismaProjectDir = await resolvePrismaProjectDir(projectDir);
|
|
860
941
|
try {
|
|
861
|
-
|
|
942
|
+
await writePrismaDependencies(context.databaseProvider, context.packageManager, prismaProjectDir);
|
|
943
|
+
return true;
|
|
862
944
|
} catch (error) {
|
|
863
945
|
cancel(getCommandErrorMessage(error));
|
|
864
|
-
return;
|
|
946
|
+
return false;
|
|
865
947
|
}
|
|
866
948
|
}
|
|
867
949
|
async function installDependenciesForContext(context, projectDir) {
|
|
@@ -894,18 +976,18 @@ async function finalizePrismaFilesForContext(context, projectDir, provisionResul
|
|
|
894
976
|
const initSpinner = spinner();
|
|
895
977
|
initSpinner.start("Preparing Prisma files...");
|
|
896
978
|
try {
|
|
897
|
-
|
|
979
|
+
await finalizePrismaFiles({
|
|
898
980
|
provider: context.databaseProvider,
|
|
899
981
|
databaseUrl: provisionResult.databaseUrl,
|
|
900
982
|
claimUrl: provisionResult.claimUrl,
|
|
901
983
|
projectDir
|
|
902
984
|
});
|
|
903
985
|
initSpinner.stop("Prisma files ready.");
|
|
904
|
-
return
|
|
986
|
+
return true;
|
|
905
987
|
} catch (error) {
|
|
906
988
|
initSpinner.stop("Could not prepare Prisma files.");
|
|
907
989
|
cancel(getCommandErrorMessage(error));
|
|
908
|
-
return;
|
|
990
|
+
return false;
|
|
909
991
|
}
|
|
910
992
|
}
|
|
911
993
|
async function generatePrismaClientForContext(context, projectDir) {
|
|
@@ -952,10 +1034,10 @@ function buildNextStepsForContext(opts) {
|
|
|
952
1034
|
async function executePrismaSetupContext(context, options = {}) {
|
|
953
1035
|
const projectDir = path.resolve(options.projectDir ?? context.projectDir);
|
|
954
1036
|
const provisionResult = await provisionPrismaPostgresIfNeeded(context, projectDir);
|
|
955
|
-
if (!provisionResult) return;
|
|
956
|
-
if (!await writeDependenciesForContext(context, projectDir)) return;
|
|
957
|
-
if (!await installDependenciesForContext(context, projectDir)) return;
|
|
958
|
-
if (!await finalizePrismaFilesForContext(context, projectDir, provisionResult)) return;
|
|
1037
|
+
if (!provisionResult) return false;
|
|
1038
|
+
if (!await writeDependenciesForContext(context, projectDir)) return false;
|
|
1039
|
+
if (!await installDependenciesForContext(context, projectDir)) return false;
|
|
1040
|
+
if (!await finalizePrismaFilesForContext(context, projectDir, provisionResult)) return false;
|
|
959
1041
|
const generateResult = await generatePrismaClientForContext(context, projectDir);
|
|
960
1042
|
const warningLines = buildWarningLines(provisionResult.warning, generateResult.warning);
|
|
961
1043
|
const nextSteps = buildNextStepsForContext({
|
|
@@ -967,7 +1049,7 @@ async function executePrismaSetupContext(context, options = {}) {
|
|
|
967
1049
|
|
|
968
1050
|
Next steps:
|
|
969
1051
|
${nextSteps.join("\n")}`);
|
|
970
|
-
return
|
|
1052
|
+
return true;
|
|
971
1053
|
}
|
|
972
1054
|
|
|
973
1055
|
//#endregion
|
|
@@ -1500,21 +1582,12 @@ async function executeCreateAddonSetupContext(params) {
|
|
|
1500
1582
|
|
|
1501
1583
|
//#endregion
|
|
1502
1584
|
//#region src/telemetry/client.ts
|
|
1503
|
-
const TELEMETRY_API_KEY = "
|
|
1585
|
+
const TELEMETRY_API_KEY = "";
|
|
1504
1586
|
const TELEMETRY_HOST = "https://us.i.posthog.com";
|
|
1505
1587
|
const TELEMETRY_CONFIG_FILE = "telemetry.json";
|
|
1506
1588
|
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;
|
|
1507
|
-
function isTruthyEnvValue(value) {
|
|
1508
|
-
return [
|
|
1509
|
-
"1",
|
|
1510
|
-
"true",
|
|
1511
|
-
"yes",
|
|
1512
|
-
"on"
|
|
1513
|
-
].includes(String(value ?? "").trim().toLowerCase());
|
|
1514
|
-
}
|
|
1515
1589
|
function shouldDisableTelemetry() {
|
|
1516
|
-
|
|
1517
|
-
return process.env.CREATE_PRISMA_DISABLE_TELEMETRY !== void 0 || process.env.CREATE_PRISMA_TELEMETRY_DISABLED !== void 0 || process.env.DO_NOT_TRACK !== void 0;
|
|
1590
|
+
return true;
|
|
1518
1591
|
}
|
|
1519
1592
|
function getTelemetryConfigDir() {
|
|
1520
1593
|
if (process.platform === "darwin") return path.join(os.homedir(), "Library", "Application Support", "create-prisma");
|
|
@@ -1536,7 +1609,7 @@ async function getAnonymousId() {
|
|
|
1536
1609
|
}
|
|
1537
1610
|
function getCommonProperties() {
|
|
1538
1611
|
return {
|
|
1539
|
-
"cli-version": "0.
|
|
1612
|
+
"cli-version": "0.4.1-pr.33.62.1",
|
|
1540
1613
|
"node-version": process.version,
|
|
1541
1614
|
platform: process.platform,
|
|
1542
1615
|
arch: process.arch
|
|
@@ -1596,7 +1669,7 @@ function getBaseCreateProperties(input, context) {
|
|
|
1596
1669
|
template: context?.template ?? input.template ?? null,
|
|
1597
1670
|
"database-provider": context?.prismaSetupContext.databaseProvider ?? input.provider ?? null,
|
|
1598
1671
|
"package-manager": context?.prismaSetupContext.packageManager ?? input.packageManager ?? null,
|
|
1599
|
-
"schema-preset": context?.schemaPreset ?? input.schemaPreset ?? null,
|
|
1672
|
+
"schema-preset": context?.prismaSetupContext.schemaPreset ?? input.schemaPreset ?? null,
|
|
1600
1673
|
"should-install": context?.prismaSetupContext.shouldInstall ?? input.install ?? null,
|
|
1601
1674
|
"should-generate": context?.prismaSetupContext.shouldGenerate ?? input.generate ?? null,
|
|
1602
1675
|
"uses-prisma-postgres": context?.prismaSetupContext.shouldUsePrismaPostgres ?? input.prismaPostgres ?? null,
|
|
@@ -1658,7 +1731,7 @@ function formatPathForDisplay(filePath) {
|
|
|
1658
1731
|
function validateProjectName(value) {
|
|
1659
1732
|
const trimmed = String(value ?? "").trim();
|
|
1660
1733
|
if (trimmed.length === 0) return "Please enter a project name.";
|
|
1661
|
-
if (trimmed === "
|
|
1734
|
+
if (trimmed === "..") return "Project name cannot be '..'.";
|
|
1662
1735
|
if (path.isAbsolute(trimmed)) return "Use a relative project name instead of an absolute path.";
|
|
1663
1736
|
}
|
|
1664
1737
|
async function promptForProjectName() {
|
|
@@ -1684,6 +1757,16 @@ async function promptForCreateTemplate() {
|
|
|
1684
1757
|
label: "Hono",
|
|
1685
1758
|
hint: "TypeScript API starter"
|
|
1686
1759
|
},
|
|
1760
|
+
{
|
|
1761
|
+
value: "elysia",
|
|
1762
|
+
label: "Elysia",
|
|
1763
|
+
hint: "TypeScript API starter with Elysia's Node adapter"
|
|
1764
|
+
},
|
|
1765
|
+
{
|
|
1766
|
+
value: "nest",
|
|
1767
|
+
label: "NestJS",
|
|
1768
|
+
hint: "Official Nest-style API starter with a Prisma service"
|
|
1769
|
+
},
|
|
1687
1770
|
{
|
|
1688
1771
|
value: "next",
|
|
1689
1772
|
label: "Next.js",
|
|
@@ -1782,8 +1865,14 @@ async function runCreateCommand(rawInput = {}) {
|
|
|
1782
1865
|
async function collectCreateContext(input) {
|
|
1783
1866
|
const useDefaults = input.yes === true;
|
|
1784
1867
|
const force = input.force === true;
|
|
1785
|
-
const
|
|
1786
|
-
if (
|
|
1868
|
+
const projectNameInput = input.name ?? (useDefaults ? DEFAULT_PROJECT_NAME : await promptForProjectName());
|
|
1869
|
+
if (projectNameInput === void 0) return;
|
|
1870
|
+
const projectName = String(projectNameInput).trim();
|
|
1871
|
+
const projectNameValidationError = validateProjectName(projectName);
|
|
1872
|
+
if (projectNameValidationError) {
|
|
1873
|
+
cancel(projectNameValidationError);
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1787
1876
|
const template = input.template ?? (useDefaults ? DEFAULT_TEMPLATE : await promptForCreateTemplate());
|
|
1788
1877
|
if (!template) return;
|
|
1789
1878
|
const targetDirectory = path.resolve(process.cwd(), projectName);
|
|
@@ -1812,7 +1901,6 @@ async function collectCreateContext(input) {
|
|
|
1812
1901
|
targetPathState,
|
|
1813
1902
|
force,
|
|
1814
1903
|
template,
|
|
1815
|
-
schemaPreset: prismaSetupContext.schemaPreset,
|
|
1816
1904
|
projectPackageName: toPackageName(path.basename(targetDirectory)),
|
|
1817
1905
|
prismaSetupContext,
|
|
1818
1906
|
addonSetupContext: addonSetupContext ?? void 0
|
|
@@ -1826,7 +1914,7 @@ async function executeCreateContext(context) {
|
|
|
1826
1914
|
projectDir: context.targetDirectory,
|
|
1827
1915
|
projectName: context.projectPackageName,
|
|
1828
1916
|
template: context.template,
|
|
1829
|
-
schemaPreset: context.schemaPreset,
|
|
1917
|
+
schemaPreset: context.prismaSetupContext.schemaPreset,
|
|
1830
1918
|
provider: context.prismaSetupContext.databaseProvider,
|
|
1831
1919
|
packageManager: context.prismaSetupContext.packageManager
|
|
1832
1920
|
});
|
|
@@ -1839,8 +1927,21 @@ async function executeCreateContext(context) {
|
|
|
1839
1927
|
error
|
|
1840
1928
|
};
|
|
1841
1929
|
}
|
|
1930
|
+
try {
|
|
1931
|
+
await writeCreateTemplateDependencies({
|
|
1932
|
+
template: context.template,
|
|
1933
|
+
packageManager: context.prismaSetupContext.packageManager,
|
|
1934
|
+
projectDir: context.targetDirectory
|
|
1935
|
+
});
|
|
1936
|
+
} catch (error) {
|
|
1937
|
+
return {
|
|
1938
|
+
ok: false,
|
|
1939
|
+
stage: "scaffold_template",
|
|
1940
|
+
error
|
|
1941
|
+
};
|
|
1942
|
+
}
|
|
1842
1943
|
if (context.targetPathState.exists && !context.targetPathState.isEmptyDirectory && context.force) log.warn(`Used --force in non-empty directory ${formatPathForDisplay(context.targetDirectory)}.`);
|
|
1843
|
-
const
|
|
1944
|
+
const nextSteps = formatPathForDisplay(context.targetDirectory) === "." ? [] : [`- cd ${formatPathForDisplay(context.targetDirectory)}`];
|
|
1844
1945
|
if (context.addonSetupContext) try {
|
|
1845
1946
|
await executeCreateAddonSetupContext({
|
|
1846
1947
|
context: context.addonSetupContext,
|
|
@@ -1857,7 +1958,7 @@ async function executeCreateContext(context) {
|
|
|
1857
1958
|
}
|
|
1858
1959
|
try {
|
|
1859
1960
|
if (!await executePrismaSetupContext(context.prismaSetupContext, {
|
|
1860
|
-
prependNextSteps:
|
|
1961
|
+
prependNextSteps: nextSteps,
|
|
1861
1962
|
projectDir: context.targetDirectory,
|
|
1862
1963
|
includeDevNextStep: true
|
|
1863
1964
|
})) return {
|
package/dist/index.d.mts
CHANGED
|
@@ -197,6 +197,8 @@ declare const SchemaPresetSchema: z.ZodEnum<{
|
|
|
197
197
|
}>;
|
|
198
198
|
declare const CreateTemplateSchema: z.ZodEnum<{
|
|
199
199
|
hono: "hono";
|
|
200
|
+
elysia: "elysia";
|
|
201
|
+
nest: "nest";
|
|
200
202
|
next: "next";
|
|
201
203
|
svelte: "svelte";
|
|
202
204
|
astro: "astro";
|
|
@@ -233,6 +235,8 @@ declare const CreateCommandInputSchema: z.ZodObject<{
|
|
|
233
235
|
name: z.ZodOptional<z.ZodString>;
|
|
234
236
|
template: z.ZodOptional<z.ZodEnum<{
|
|
235
237
|
hono: "hono";
|
|
238
|
+
elysia: "elysia";
|
|
239
|
+
nest: "nest";
|
|
236
240
|
next: "next";
|
|
237
241
|
svelte: "svelte";
|
|
238
242
|
astro: "astro";
|
|
@@ -277,6 +281,8 @@ declare const router: {
|
|
|
277
281
|
name: zod.ZodOptional<zod.ZodString>;
|
|
278
282
|
template: zod.ZodOptional<zod.ZodEnum<{
|
|
279
283
|
hono: "hono";
|
|
284
|
+
elysia: "elysia";
|
|
285
|
+
nest: "nest";
|
|
280
286
|
next: "next";
|
|
281
287
|
svelte: "svelte";
|
|
282
288
|
astro: "astro";
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as DatabaseUrlSchema, i as DatabaseProviderSchema, n as CreateCommandInputSchema, o as PackageManagerSchema, r as CreateTemplateSchema, s as SchemaPresetSchema, t as runCreateCommand } from "./create-
|
|
2
|
+
import { a as DatabaseUrlSchema, i as DatabaseProviderSchema, n as CreateCommandInputSchema, o as PackageManagerSchema, r as CreateTemplateSchema, s as SchemaPresetSchema, t as runCreateCommand } from "./create-CDlZ32XO.mjs";
|
|
3
3
|
import { os } from "@orpc/server";
|
|
4
4
|
import { createCli } from "trpc-cli";
|
|
5
5
|
|
|
6
6
|
//#region src/index.ts
|
|
7
|
-
const CLI_VERSION = "0.
|
|
7
|
+
const CLI_VERSION = "0.4.1-pr.33.62.1";
|
|
8
8
|
const router = os.router({ create: os.meta({
|
|
9
9
|
description: "Create a new project with Prisma setup",
|
|
10
10
|
default: true,
|
package/package.json
CHANGED