Skip to content

Commit d18bcfb

Browse files
refactor(cli): improve Turso database setup workflow
1 parent efb669d commit d18bcfb

File tree

1 file changed

+74
-41
lines changed

1 file changed

+74
-41
lines changed

apps/cli/src/helpers/db-setup.ts

Lines changed: 74 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import ora, { type Ora } from "ora";
77
import { logger } from "../utils/logger";
88
import { isTursoInstalled, isTursoLoggedIn } from "../utils/turso-cli";
99

10+
interface TursoConfig {
11+
dbUrl: string;
12+
authToken: string;
13+
}
14+
1015
async function loginToTurso(spinner: Ora) {
1116
try {
1217
spinner.start("Logging in to Turso...");
@@ -25,74 +30,74 @@ async function installTursoCLI(isMac: boolean, spinner: Ora) {
2530
if (isMac) {
2631
await execa("brew", ["install", "tursodatabase/tap/turso"]);
2732
} else {
28-
const installScript = await execa("curl", [
33+
const { stdout: installScript } = await execa("curl", [
2934
"-sSfL",
3035
"https://get.tur.so/install.sh",
3136
]);
32-
await execa("bash", [], { input: installScript.stdout });
37+
await execa("bash", [], { input: installScript });
3338
}
3439

3540
spinner.succeed("Turso CLI installed successfully!");
3641
} catch (error) {
3742
if (error instanceof Error && error.message.includes("User force closed")) {
3843
spinner.stop();
39-
console.log("\n");
40-
logger.warn("Turso CLI installation cancelled by user");
41-
throw error;
44+
logger.warn("\nTurso CLI installation cancelled by user");
45+
throw new Error("Installation cancelled");
4246
}
4347
spinner.fail("Failed to install Turso CLI");
4448
throw error;
4549
}
4650
}
4751

48-
async function createTursoDatabase(projectDir: string, spinner: Ora) {
52+
async function createTursoDatabase(dbName: string): Promise<TursoConfig> {
4953
try {
50-
const defaultDbName = path.basename(projectDir);
51-
const dbName = await input({
52-
message: `Enter database name (default: ${defaultDbName}):`,
53-
default: defaultDbName,
54-
});
55-
56-
spinner.start(`Creating Turso database "${dbName}"...`);
5754
await execa("turso", ["db", "create", dbName]);
58-
59-
const { stdout: dbUrl } = await execa("turso", [
60-
"db",
61-
"show",
62-
dbName,
63-
"--url",
64-
]);
65-
const { stdout: authToken } = await execa("turso", [
66-
"db",
67-
"tokens",
68-
"create",
69-
dbName,
70-
]);
71-
72-
const envPath = path.join(projectDir, "packages/server", ".env");
73-
const envContent = `TURSO_DATABASE_URL="${dbUrl.trim()}"
74-
TURSO_AUTH_TOKEN="${authToken.trim()}"`;
75-
76-
await fs.writeFile(envPath, envContent);
77-
spinner.succeed("Turso database configured successfully!");
7855
} catch (error) {
79-
spinner.fail("Failed to create Turso database");
56+
if (error instanceof Error && error.message.includes("already exists")) {
57+
throw new Error("DATABASE_EXISTS");
58+
}
8059
throw error;
8160
}
61+
62+
const { stdout: dbUrl } = await execa("turso", [
63+
"db",
64+
"show",
65+
dbName,
66+
"--url",
67+
]);
68+
69+
const { stdout: authToken } = await execa("turso", [
70+
"db",
71+
"tokens",
72+
"create",
73+
dbName,
74+
]);
75+
76+
return {
77+
dbUrl: dbUrl.trim(),
78+
authToken: authToken.trim(),
79+
};
8280
}
8381

84-
async function setupManualConfig(projectDir: string) {
82+
async function writeEnvFile(projectDir: string, config?: TursoConfig) {
8583
const envPath = path.join(projectDir, "packages/server", ".env");
86-
const envContent = `TURSO_DATABASE_URL=
84+
const envContent = config
85+
? `TURSO_DATABASE_URL="${config.dbUrl}"
86+
TURSO_AUTH_TOKEN="${config.authToken}"`
87+
: `TURSO_DATABASE_URL=
8788
TURSO_AUTH_TOKEN=`;
8889

8990
await fs.writeFile(envPath, envContent);
91+
}
9092

93+
function displayManualSetupInstructions() {
9194
logger.info("\n📝 Manual Turso Setup Instructions:");
9295
logger.info("1. Visit https://turso.tech and create an account");
9396
logger.info("2. Create a new database from the dashboard");
9497
logger.info("3. Get your database URL and authentication token");
95-
logger.info("4. Add these credentials to the .env file in your project root");
98+
logger.info(
99+
"4. Add these credentials to the .env file in packages/server/.env",
100+
);
96101
logger.info("\nThe .env file has been created with placeholder variables:");
97102
logger.info("TURSO_DATABASE_URL=your_database_url");
98103
logger.info("TURSO_AUTH_TOKEN=your_auth_token");
@@ -105,7 +110,8 @@ export async function setupTurso(projectDir: string) {
105110
const canInstallCLI = platform !== "win32";
106111

107112
if (!canInstallCLI) {
108-
await setupManualConfig(projectDir);
113+
await writeEnvFile(projectDir);
114+
displayManualSetupInstructions();
109115
return;
110116
}
111117

@@ -119,7 +125,8 @@ export async function setupTurso(projectDir: string) {
119125
});
120126

121127
if (!shouldInstall) {
122-
await setupManualConfig(projectDir);
128+
await writeEnvFile(projectDir);
129+
displayManualSetupInstructions();
123130
return;
124131
}
125132

@@ -131,9 +138,35 @@ export async function setupTurso(projectDir: string) {
131138
await loginToTurso(spinner);
132139
}
133140

134-
await createTursoDatabase(projectDir, spinner);
141+
const defaultDbName = path.basename(projectDir);
142+
let dbName = await input({
143+
message: `Enter database name (default: ${defaultDbName}):`,
144+
default: defaultDbName,
145+
});
146+
147+
let success = false;
148+
while (!success) {
149+
try {
150+
spinner.start(`Creating Turso database "${dbName}"...`);
151+
const config = await createTursoDatabase(dbName);
152+
await writeEnvFile(projectDir, config);
153+
spinner.succeed("Turso database configured successfully!");
154+
success = true;
155+
} catch (error) {
156+
if (error instanceof Error && error.message === "DATABASE_EXISTS") {
157+
spinner.warn(`Database "${dbName}" already exists`);
158+
dbName = await input({
159+
message: "Please enter a different database name:",
160+
default: `${dbName}-${Math.floor(Math.random() * 1000)}`,
161+
});
162+
} else {
163+
throw error;
164+
}
165+
}
166+
}
135167
} catch (error) {
136168
logger.error("Error during Turso setup:", error);
137-
await setupManualConfig(projectDir);
169+
await writeEnvFile(projectDir);
170+
displayManualSetupInstructions();
138171
}
139172
}

0 commit comments

Comments
 (0)