Skip to content

Commit b2b9050

Browse files
feat(cli): improve prisma postgres create db setup (#558)
1 parent 0fbb7ef commit b2b9050

File tree

2 files changed

+76
-29
lines changed

2 files changed

+76
-29
lines changed

.cursor/rules/better-t-stack-repo.mdc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
alwaysApply: true
3+
---
4+
5+
- use functional programming
6+
- use normal function syntax for functions do not use arrow functions
7+
- no emojis
8+
- use type syntax, dont use interface syntax for types

apps/cli/src/helpers/database-providers/prisma-postgres-setup.ts

Lines changed: 68 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import path from "node:path";
2-
import { isCancel, log, select, text } from "@clack/prompts";
2+
import { isCancel, log, select, spinner, text } from "@clack/prompts";
33
import { consola } from "consola";
44
import { execa } from "execa";
55
import fs from "fs-extra";
@@ -12,56 +12,77 @@ import { addEnvVariablesToFile, type EnvVariable } from "../core/env-setup";
1212

1313
type PrismaConfig = {
1414
databaseUrl: string;
15+
claimUrl?: string;
1516
};
1617

18+
type CreateDbResponse = {
19+
connectionString: string;
20+
directConnectionString: string;
21+
claimUrl: string;
22+
deletionDate: string;
23+
region: string;
24+
name: string;
25+
projectId: string;
26+
};
27+
28+
const AVAILABLE_REGIONS = [
29+
{ value: "ap-southeast-1", label: "Asia Pacific (Singapore)" },
30+
{ value: "ap-northeast-1", label: "Asia Pacific (Tokyo)" },
31+
{ value: "eu-central-1", label: "Europe (Frankfurt)" },
32+
{ value: "eu-west-3", label: "Europe (Paris)" },
33+
{ value: "us-east-1", label: "US East (N. Virginia)" },
34+
{ value: "us-west-1", label: "US West (N. California)" },
35+
];
36+
1737
async function setupWithCreateDb(
1838
serverDir: string,
1939
packageManager: PackageManager,
2040
orm: ORM,
2141
) {
2242
try {
2343
log.info(
24-
"Starting Prisma Postgres setup. Please follow the instructions below:",
44+
"Starting Prisma Postgres setup with create-db. Please follow the instructions below:",
2545
);
2646

47+
const selectedRegion = await select({
48+
message: "Select your preferred region:",
49+
options: AVAILABLE_REGIONS,
50+
initialValue: "ap-southeast-1",
51+
});
52+
53+
if (isCancel(selectedRegion)) return null;
54+
2755
const createDbCommand = getPackageExecutionCommand(
2856
packageManager,
29-
"create-db@latest -i",
57+
`create-db@latest --json --region ${selectedRegion}`,
3058
);
3159

32-
await execa(createDbCommand, {
60+
const s = spinner();
61+
s.start("Creating Prisma Postgres database...");
62+
63+
const { stdout } = await execa(createDbCommand, {
3364
cwd: serverDir,
34-
stdio: "inherit",
3565
shell: true,
3666
});
3767

38-
log.info(
39-
orm === "drizzle"
40-
? pc.yellow(
41-
"Please copy the database URL from the output above and append ?sslmode=require for Drizzle.",
42-
)
43-
: pc.yellow(
44-
"Please copy the Prisma Postgres URL from the output above.",
45-
),
46-
);
68+
s.stop("Database created successfully!");
4769

48-
const databaseUrl = await text({
49-
message:
50-
orm === "drizzle"
51-
? "Paste your database URL (append ?sslmode=require for Drizzle):"
52-
: "Paste your Prisma Postgres database URL:",
53-
validate(value) {
54-
if (!value) return "Please enter a database URL";
55-
if (orm === "drizzle" && !value.includes("?sslmode=require")) {
56-
return "Please append ?sslmode=require to your database URL when using Drizzle";
57-
}
58-
},
59-
});
70+
let createDbResponse: CreateDbResponse;
71+
try {
72+
createDbResponse = JSON.parse(stdout) as CreateDbResponse;
73+
} catch {
74+
consola.error("Failed to parse create-db response");
75+
return null;
76+
}
6077

61-
if (isCancel(databaseUrl)) return null;
78+
const databaseUrl =
79+
orm === "drizzle"
80+
? createDbResponse.directConnectionString
81+
: createDbResponse.connectionString;
6282

6383
return {
64-
databaseUrl: databaseUrl as string,
84+
databaseUrl,
85+
claimUrl: createDbResponse.claimUrl,
6586
};
6687
} catch (error) {
6788
if (error instanceof Error) {
@@ -135,6 +156,15 @@ async function writeEnvFile(projectDir: string, config?: PrismaConfig) {
135156
condition: true,
136157
},
137158
];
159+
160+
if (config?.claimUrl) {
161+
variables.push({
162+
key: "CLAIM_URL",
163+
value: config.claimUrl,
164+
condition: true,
165+
});
166+
}
167+
138168
await addEnvVariablesToFile(envPath, variables);
139169
} catch (_error) {
140170
consola.error("Failed to update environment configuration");
@@ -254,9 +284,18 @@ export async function setupPrismaPostgres(config: ProjectConfig) {
254284
await addDotenvImportToPrismaConfig(projectDir);
255285
await addPrismaAccelerateExtension(serverDir);
256286
}
287+
288+
const connectionType =
289+
orm === "drizzle" ? "direct connection" : "Prisma Accelerate";
257290
log.success(
258-
pc.green("Prisma Postgres database configured successfully!"),
291+
pc.green(
292+
`Prisma Postgres database configured successfully with ${connectionType}!`,
293+
),
259294
);
295+
296+
if (prismaConfig.claimUrl) {
297+
log.info(pc.blue(`Claim URL saved to .env: ${prismaConfig.claimUrl}`));
298+
}
260299
} else {
261300
await writeEnvFile(projectDir);
262301
displayManualSetupInstructions();

0 commit comments

Comments
 (0)