mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
Add D1 Database (#335)
This commit is contained in:
34
apps/cli/src/helpers/database-providers/d1-setup.ts
Normal file
34
apps/cli/src/helpers/database-providers/d1-setup.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import path from "node:path";
|
||||
import type { ProjectConfig } from "../../types";
|
||||
import {
|
||||
addEnvVariablesToFile,
|
||||
type EnvVariable,
|
||||
} from "../project-generation/env-setup";
|
||||
|
||||
export async function setupCloudflareD1(config: ProjectConfig): Promise<void> {
|
||||
const { projectDir } = config;
|
||||
|
||||
const envPath = path.join(projectDir, "apps/server", ".env");
|
||||
|
||||
const variables: EnvVariable[] = [
|
||||
{
|
||||
key: "CLOUDFLARE_ACCOUNT_ID",
|
||||
value: "",
|
||||
condition: true,
|
||||
},
|
||||
{
|
||||
key: "CLOUDFLARE_DATABASE_ID",
|
||||
value: "",
|
||||
condition: true,
|
||||
},
|
||||
{
|
||||
key: "CLOUDFLARE_D1_TOKEN",
|
||||
value: "",
|
||||
condition: true,
|
||||
},
|
||||
];
|
||||
|
||||
try {
|
||||
await addEnvVariablesToFile(envPath, variables);
|
||||
} catch (_err) {}
|
||||
}
|
||||
@@ -8,7 +8,10 @@ import { setupAuth } from "../setup/auth-setup";
|
||||
import { setupBackendDependencies } from "../setup/backend-setup";
|
||||
import { setupDatabase } from "../setup/db-setup";
|
||||
import { setupExamples } from "../setup/examples-setup";
|
||||
import { setupRuntime } from "../setup/runtime-setup";
|
||||
import {
|
||||
generateCloudflareWorkerTypes,
|
||||
setupRuntime,
|
||||
} from "../setup/runtime-setup";
|
||||
import { createReadme } from "./create-readme";
|
||||
import { setupEnvironmentVariables } from "./env-setup";
|
||||
import { installDependencies } from "./install-dependencies";
|
||||
@@ -64,6 +67,7 @@ export async function createProject(options: ProjectConfig) {
|
||||
}
|
||||
|
||||
await handleExtras(projectDir, options);
|
||||
|
||||
await setupEnvironmentVariables(options);
|
||||
await updatePackageConfigurations(projectDir, options);
|
||||
await createReadme(projectDir, options);
|
||||
@@ -76,6 +80,7 @@ export async function createProject(options: ProjectConfig) {
|
||||
projectDir,
|
||||
packageManager: options.packageManager,
|
||||
});
|
||||
await generateCloudflareWorkerTypes(options);
|
||||
}
|
||||
|
||||
displayPostInstallInstructions({
|
||||
|
||||
@@ -186,7 +186,8 @@ export async function setupEnvironmentVariables(
|
||||
dbSetup === "prisma-postgres" ||
|
||||
dbSetup === "mongodb-atlas" ||
|
||||
dbSetup === "neon" ||
|
||||
dbSetup === "supabase";
|
||||
dbSetup === "supabase" ||
|
||||
dbSetup === "d1";
|
||||
|
||||
if (database !== "none" && !specializedSetup) {
|
||||
switch (database) {
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { consola } from "consola";
|
||||
import pc from "picocolors";
|
||||
import type { Database, ORM, ProjectConfig, Runtime } from "../../types";
|
||||
import type {
|
||||
Database,
|
||||
DatabaseSetup,
|
||||
ORM,
|
||||
ProjectConfig,
|
||||
Runtime,
|
||||
} from "../../types";
|
||||
import { getPackageExecutionCommand } from "../../utils/get-package-execution-command";
|
||||
|
||||
export function displayPostInstallInstructions(
|
||||
@@ -16,6 +22,7 @@ export function displayPostInstallInstructions(
|
||||
runtime,
|
||||
frontend,
|
||||
backend,
|
||||
dbSetup,
|
||||
} = config;
|
||||
|
||||
const isConvex = backend === "convex";
|
||||
@@ -26,7 +33,7 @@ export function displayPostInstallInstructions(
|
||||
|
||||
const databaseInstructions =
|
||||
!isConvex && database !== "none"
|
||||
? getDatabaseInstructions(database, orm, runCmd, runtime)
|
||||
? getDatabaseInstructions(database, orm, runCmd, runtime, dbSetup)
|
||||
: "";
|
||||
|
||||
const tauriInstructions = addons?.includes("tauri")
|
||||
@@ -96,6 +103,11 @@ export function displayPostInstallInstructions(
|
||||
}
|
||||
|
||||
if (runtime === "workers") {
|
||||
if (dbSetup === "d1") {
|
||||
output += `${pc.yellow(
|
||||
"IMPORTANT:",
|
||||
)} Complete D1 database setup first (see Database commands below)\n`;
|
||||
}
|
||||
output += `${pc.cyan(`${stepCounter++}.`)} bun dev\n`;
|
||||
output += `${pc.cyan(
|
||||
`${stepCounter++}.`,
|
||||
@@ -178,9 +190,46 @@ function getDatabaseInstructions(
|
||||
orm?: ORM,
|
||||
runCmd?: string,
|
||||
runtime?: Runtime,
|
||||
dbSetup?: DatabaseSetup,
|
||||
): string {
|
||||
const instructions = [];
|
||||
|
||||
if (runtime === "workers" && dbSetup === "d1") {
|
||||
const packageManager = runCmd === "npm run" ? "npm" : runCmd || "npm";
|
||||
|
||||
instructions.push(
|
||||
`${pc.cyan("1.")} Login to Cloudflare: ${pc.white(
|
||||
`${packageManager} wrangler login`,
|
||||
)}`,
|
||||
);
|
||||
instructions.push(
|
||||
`${pc.cyan("2.")} Create D1 database: ${pc.white(
|
||||
`${packageManager} wrangler d1 create your-database-name`,
|
||||
)}`,
|
||||
);
|
||||
instructions.push(
|
||||
`${pc.cyan(
|
||||
"3.",
|
||||
)} Update apps/server/wrangler.jsonc with database_id and database_name`,
|
||||
);
|
||||
instructions.push(
|
||||
`${pc.cyan("4.")} Generate migrations: ${pc.white(
|
||||
"cd apps/server && bun db:generate",
|
||||
)}`,
|
||||
);
|
||||
instructions.push(
|
||||
`${pc.cyan("5.")} Apply migrations locally: ${pc.white(
|
||||
`${packageManager} wrangler d1 migrations apply YOUR_DB_NAME --local`,
|
||||
)}`,
|
||||
);
|
||||
instructions.push(
|
||||
`${pc.cyan("6.")} Apply migrations to production: ${pc.white(
|
||||
`${packageManager} wrangler d1 migrations apply YOUR_DB_NAME`,
|
||||
)}`,
|
||||
);
|
||||
instructions.push("");
|
||||
}
|
||||
|
||||
if (orm === "prisma") {
|
||||
if (database === "sqlite") {
|
||||
instructions.push(
|
||||
@@ -204,7 +253,7 @@ function getDatabaseInstructions(
|
||||
} else if (orm === "drizzle") {
|
||||
instructions.push(`${pc.cyan("•")} Apply schema: ${`${runCmd} db:push`}`);
|
||||
instructions.push(`${pc.cyan("•")} Database UI: ${`${runCmd} db:studio`}`);
|
||||
if (database === "sqlite") {
|
||||
if (database === "sqlite" && dbSetup !== "d1") {
|
||||
instructions.push(
|
||||
`${pc.cyan(
|
||||
"•",
|
||||
|
||||
@@ -5,6 +5,7 @@ import fs from "fs-extra";
|
||||
import pc from "picocolors";
|
||||
import type { ProjectConfig } from "../../types";
|
||||
import { addPackageDependency } from "../../utils/add-package-deps";
|
||||
import { setupCloudflareD1 } from "../database-providers/d1-setup";
|
||||
import { setupMongoDBAtlas } from "../database-providers/mongodb-atlas-setup";
|
||||
import { setupNeonPostgres } from "../database-providers/neon-setup";
|
||||
import { setupPrismaPostgres } from "../database-providers/prisma-postgres-setup";
|
||||
@@ -69,6 +70,8 @@ export async function setupDatabase(config: ProjectConfig): Promise<void> {
|
||||
|
||||
if (database === "sqlite" && dbSetup === "turso") {
|
||||
await setupTurso(config);
|
||||
} else if (database === "sqlite" && dbSetup === "d1") {
|
||||
await setupCloudflareD1(config);
|
||||
} else if (database === "postgres") {
|
||||
if (orm === "prisma" && dbSetup === "prisma-postgres") {
|
||||
await setupPrismaPostgres(config);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import path from "node:path";
|
||||
import { spinner } from "@clack/prompts";
|
||||
import { execa } from "execa";
|
||||
import fs from "fs-extra";
|
||||
import pc from "picocolors";
|
||||
import type { Backend, ProjectConfig } from "../../types";
|
||||
import { addPackageDependency } from "../../utils/add-package-deps";
|
||||
|
||||
@@ -25,6 +28,43 @@ export async function setupRuntime(config: ProjectConfig): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateCloudflareWorkerTypes(
|
||||
config: ProjectConfig,
|
||||
): Promise<void> {
|
||||
if (config.runtime !== "workers") {
|
||||
return;
|
||||
}
|
||||
|
||||
const serverDir = path.join(config.projectDir, "apps/server");
|
||||
|
||||
if (!(await fs.pathExists(serverDir))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const s = spinner();
|
||||
|
||||
try {
|
||||
s.start("Generating Cloudflare Workers types...");
|
||||
|
||||
const runCmd =
|
||||
config.packageManager === "npm" ? "npm" : config.packageManager;
|
||||
await execa(runCmd, ["run", "cf-typegen"], {
|
||||
cwd: serverDir,
|
||||
});
|
||||
|
||||
s.stop("Cloudflare Workers types generated successfully!");
|
||||
} catch {
|
||||
s.stop(pc.yellow("Failed to generate Cloudflare Workers types"));
|
||||
const managerCmd =
|
||||
config.packageManager === "npm"
|
||||
? "npm run"
|
||||
: `${config.packageManager} run`;
|
||||
console.warn(
|
||||
`Note: You can manually run 'cd apps/server && ${managerCmd} cf-typegen' in the project directory later`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function setupBunRuntime(
|
||||
serverDir: string,
|
||||
_backend: Backend,
|
||||
|
||||
Reference in New Issue
Block a user