mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
feat: add package manager selection and configuration
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
"@inquirer/prompts": "^7.3.1",
|
||||
"chalk": "^5.3.0",
|
||||
"commander": "^13.1.0",
|
||||
"detect-package-manager": "^3.0.2",
|
||||
"execa": "^8.0.1",
|
||||
"fs-extra": "^11.2.0",
|
||||
"gradient-string": "^3.0.0",
|
||||
|
||||
@@ -34,4 +34,5 @@ export const DEFAULT_CONFIG: ProjectConfig = {
|
||||
auth: true,
|
||||
features: [],
|
||||
git: true,
|
||||
packageManager: "npm",
|
||||
};
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import path from "node:path";
|
||||
import { confirm, select } from "@inquirer/prompts";
|
||||
import { detect } from "detect-package-manager";
|
||||
import { execa } from "execa";
|
||||
import fs from "fs-extra";
|
||||
import ora from "ora";
|
||||
import { setupTurso } from "./helpers/db-setup";
|
||||
import type { ProjectConfig } from "./types";
|
||||
import type { PackageManager, ProjectConfig } from "./types";
|
||||
import { logger } from "./utils/logger";
|
||||
|
||||
export async function createProject(options: ProjectConfig) {
|
||||
@@ -22,15 +24,67 @@ export async function createProject(options: ProjectConfig) {
|
||||
]);
|
||||
spinner.succeed();
|
||||
|
||||
if (options.git) {
|
||||
const initGit = await confirm({
|
||||
message: "Initialize a git repository?",
|
||||
default: true,
|
||||
});
|
||||
|
||||
if (initGit) {
|
||||
spinner.start("Initializing git repository...");
|
||||
await execa("git", ["init"], { cwd: projectDir });
|
||||
spinner.succeed();
|
||||
}
|
||||
|
||||
spinner.start("Installing dependencies...");
|
||||
await execa("bun", ["install"], { cwd: projectDir });
|
||||
spinner.succeed();
|
||||
let packageManager = options.packageManager;
|
||||
|
||||
if (!packageManager) {
|
||||
const detectedPackageManager = await detect();
|
||||
|
||||
const useDetectedPackageManager = await confirm({
|
||||
message: `Use detected package manager (${detectedPackageManager})?`,
|
||||
default: true,
|
||||
});
|
||||
|
||||
if (useDetectedPackageManager) {
|
||||
packageManager = detectedPackageManager;
|
||||
} else {
|
||||
packageManager = await select<PackageManager>({
|
||||
message: "Select package manager:",
|
||||
choices: [
|
||||
{ value: "npm", name: "npm" },
|
||||
{ value: "yarn", name: "yarn" },
|
||||
{ value: "pnpm", name: "pnpm" },
|
||||
{ value: "bun", name: "bun" },
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const installDeps = await confirm({
|
||||
message: `Install dependencies using ${packageManager}?`,
|
||||
default: true,
|
||||
});
|
||||
|
||||
if (installDeps) {
|
||||
spinner.start(`Installing dependencies using ${packageManager}...`);
|
||||
switch (packageManager) {
|
||||
case "npm":
|
||||
await execa("npm", ["install"], { cwd: projectDir });
|
||||
break;
|
||||
case "yarn":
|
||||
await execa("yarn", ["install"], { cwd: projectDir });
|
||||
break;
|
||||
case "pnpm":
|
||||
await execa("pnpm", ["install"], { cwd: projectDir });
|
||||
break;
|
||||
case "bun":
|
||||
await execa("bun", ["install"], { cwd: projectDir });
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unsupported package manager");
|
||||
}
|
||||
spinner.succeed();
|
||||
}
|
||||
|
||||
if (options.database === "libsql") {
|
||||
await setupTurso(projectDir);
|
||||
@@ -39,7 +93,12 @@ export async function createProject(options: ProjectConfig) {
|
||||
logger.success("\n✨ Project created successfully!\n");
|
||||
logger.info("Next steps:");
|
||||
logger.info(` cd ${options.projectName}`);
|
||||
logger.info(" bun dev");
|
||||
if (!installDeps) {
|
||||
logger.info(` ${packageManager} install`);
|
||||
}
|
||||
logger.info(
|
||||
` ${packageManager === "npm" ? "npm run" : packageManager} dev`,
|
||||
);
|
||||
} catch (error) {
|
||||
spinner.fail("Failed to create project");
|
||||
logger.error("Error during project creation:", error);
|
||||
|
||||
@@ -4,7 +4,12 @@ import { Command } from "commander";
|
||||
import { DEFAULT_CONFIG } from "./consts";
|
||||
import { createProject } from "./create-project";
|
||||
import { renderTitle } from "./render-title";
|
||||
import type { ProjectConfig, ProjectDatabase, ProjectFeature } from "./types";
|
||||
import type {
|
||||
PackageManager,
|
||||
ProjectConfig,
|
||||
ProjectDatabase,
|
||||
ProjectFeature,
|
||||
} from "./types";
|
||||
import { generateReproducibleCommand } from "./utils/generate-reproducible-command";
|
||||
import { getVersion } from "./utils/get-version";
|
||||
import { logger } from "./utils/logger";
|
||||
@@ -103,6 +108,10 @@ async function main() {
|
||||
.option("--docker", "Include Docker setup")
|
||||
.option("--github-actions", "Include GitHub Actions")
|
||||
.option("--seo", "Include SEO setup")
|
||||
.option(
|
||||
"--package-manager <type>",
|
||||
"Package manager to use (npm, yarn, pnpm, or bun)",
|
||||
)
|
||||
.parse();
|
||||
|
||||
const options = program.opts();
|
||||
@@ -112,6 +121,7 @@ async function main() {
|
||||
projectName: projectDirectory,
|
||||
database: options.database as ProjectDatabase,
|
||||
auth: options.auth,
|
||||
packageManager: options.packageManager as PackageManager,
|
||||
features: [
|
||||
...(options.docker ? ["docker"] : []),
|
||||
...(options.githubActions ? ["github-actions"] : []),
|
||||
|
||||
@@ -7,5 +7,8 @@ export type ProjectConfig = {
|
||||
git: boolean;
|
||||
database: ProjectDatabase;
|
||||
auth: boolean;
|
||||
packageManager?: PackageManager;
|
||||
features: ProjectFeature[];
|
||||
};
|
||||
|
||||
export type PackageManager = "npm" | "yarn" | "pnpm" | "bun";
|
||||
|
||||
@@ -2,29 +2,26 @@ import { DEFAULT_CONFIG } from "../consts";
|
||||
import type { ProjectConfig } from "../types";
|
||||
|
||||
export function generateReproducibleCommand(config: ProjectConfig): string {
|
||||
const parts = ["bunx create-better-t-stack"];
|
||||
|
||||
if (config.projectName !== DEFAULT_CONFIG.projectName) {
|
||||
parts.push(config.projectName);
|
||||
}
|
||||
const flags: string[] = [];
|
||||
|
||||
if (config.database !== DEFAULT_CONFIG.database) {
|
||||
parts.push(`--database ${config.database}`);
|
||||
flags.push(`--database ${config.database}`);
|
||||
}
|
||||
|
||||
if (config.auth !== DEFAULT_CONFIG.auth) {
|
||||
parts.push(config.auth ? "--auth" : "--no-auth");
|
||||
flags.push("--no-auth");
|
||||
}
|
||||
if (
|
||||
config.packageManager &&
|
||||
config.packageManager !== DEFAULT_CONFIG.packageManager
|
||||
) {
|
||||
flags.push(`--package-manager ${config.packageManager}`);
|
||||
}
|
||||
|
||||
if (config.features.includes("docker")) {
|
||||
parts.push("--docker");
|
||||
}
|
||||
if (config.features.includes("github-actions")) {
|
||||
parts.push("--github-actions");
|
||||
}
|
||||
if (config.features.includes("SEO")) {
|
||||
parts.push("--seo");
|
||||
for (const feature of config.features) {
|
||||
flags.push(`--${feature}`);
|
||||
}
|
||||
|
||||
return parts.join(" ");
|
||||
return `npx create-better-t-stack${
|
||||
config.projectName ? ` ${config.projectName}` : ""
|
||||
}${flags.length > 0 ? ` ${flags.join(" ")}` : ""}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user