feat(cli): display pre-selected flags before prompts

This commit is contained in:
Aman Varshney
2025-02-14 11:54:20 +05:30
parent e758b26fbd
commit 0983fc1746
3 changed files with 97 additions and 57 deletions

View File

@@ -0,0 +1,5 @@
---
"create-better-t-stack": minor
---
feat(cli): display pre-selected flags before prompts

View File

@@ -64,10 +64,10 @@ export async function createProject(options: ProjectConfig) {
if (shouldInstallDeps) { if (shouldInstallDeps) {
s.start(`📦 Installing dependencies using ${options.packageManager}...`); s.start(`📦 Installing dependencies using ${options.packageManager}...`);
try { try {
await $({ const { stdout } = await $({
cwd: projectDir, cwd: projectDir,
stdio: "inherit",
})`${options.packageManager} install`; })`${options.packageManager} install`;
log.step(stdout);
s.stop("✅ Dependencies installed successfully"); s.stop("✅ Dependencies installed successfully");
} catch (error) { } catch (error) {
s.stop("Failed to install dependencies"); s.stop("Failed to install dependencies");

View File

@@ -40,6 +40,7 @@ async function gatherConfig(
const result = await group( const result = await group(
{ {
projectName: async () => { projectName: async () => {
if (flags.projectName) return flags.projectName;
let isValid = false; let isValid = false;
let projectName: string | symbol = ""; let projectName: string | symbol = "";
let defaultName = DEFAULT_CONFIG.projectName; let defaultName = DEFAULT_CONFIG.projectName;
@@ -83,8 +84,9 @@ async function gatherConfig(
return projectName as string; return projectName as string;
}, },
database: () => database: () =>
!flags.database flags.database !== undefined
? select<ProjectDatabase>({ ? Promise.resolve(flags.database)
: select<ProjectDatabase>({
message: "💾 Which database would you like to use?", message: "💾 Which database would you like to use?",
options: [ options: [
{ {
@@ -98,18 +100,19 @@ async function gatherConfig(
hint: "Traditional relational database", hint: "Traditional relational database",
}, },
], ],
}) }),
: Promise.resolve(flags.database),
auth: () => auth: () =>
flags.auth === undefined flags.auth !== undefined
? confirm({ ? Promise.resolve(flags.auth)
: confirm({
message: message:
"🔐 Would you like to add authentication with Better-Auth?", "🔐 Would you like to add authentication with Better-Auth?",
}) initialValue: DEFAULT_CONFIG.auth,
: Promise.resolve(flags.auth), }),
features: () => features: () =>
!flags.features flags.features !== undefined
? multiselect<ProjectFeature>({ ? Promise.resolve(flags.features)
: multiselect<ProjectFeature>({
message: "✨ Which features would you like to add?", message: "✨ Which features would you like to add?",
options: [ options: [
{ {
@@ -128,16 +131,18 @@ async function gatherConfig(
hint: "Search engine optimization configuration", hint: "Search engine optimization configuration",
}, },
], ],
}) }),
: Promise.resolve(flags.features),
git: () => git: () =>
flags.git !== false flags.git !== undefined
? confirm({ ? Promise.resolve(flags.git)
: confirm({
message: "🗃️ Initialize a new git repository?", message: "🗃️ Initialize a new git repository?",
initialValue: true, initialValue: DEFAULT_CONFIG.git,
}) }),
: Promise.resolve(false),
packageManager: async () => { packageManager: async () => {
if (flags.packageManager !== undefined) {
return flags.packageManager;
}
const detectedPackageManager = getUserPkgManager(); const detectedPackageManager = getUserPkgManager();
const useDetected = await confirm({ const useDetected = await confirm({
@@ -179,15 +184,52 @@ async function gatherConfig(
); );
return { return {
projectName: result.projectName ?? "", projectName: result.projectName ?? DEFAULT_CONFIG.projectName,
database: result.database ?? "libsql", database: result.database ?? DEFAULT_CONFIG.database,
auth: result.auth ?? true, auth: result.auth ?? DEFAULT_CONFIG.auth,
features: result.features ?? [], features: result.features ?? DEFAULT_CONFIG.features,
git: result.git ?? true, git: result.git ?? DEFAULT_CONFIG.git,
packageManager: result.packageManager ?? "npm", packageManager: result.packageManager ?? DEFAULT_CONFIG.packageManager,
}; };
} }
function displayConfig(config: Partial<ProjectConfig>) {
const configDisplay = [];
if (config.projectName) {
configDisplay.push(
`${chalk.blue("📝 Project Name: ")}${chalk.green(config.projectName)}`,
);
}
if (config.database) {
configDisplay.push(
`${chalk.blue("💾 Database: ")}${chalk.yellow(config.database)}`,
);
}
if (config.auth !== undefined) {
configDisplay.push(
`${chalk.blue("🔐 Authentication: ")}${chalk.cyan(config.auth)}`,
);
}
if (config.features?.length) {
configDisplay.push(
`${chalk.blue("✨ Features: ")}${config.features.map((f) => chalk.magenta(f)).join(", ")}`,
);
}
if (config.git !== undefined) {
configDisplay.push(
`${chalk.blue("🗃️ Git Init: ")}${chalk.cyan(config.git)}`,
);
}
if (config.packageManager) {
configDisplay.push(
`${chalk.blue("📦 Package Manager: ")}${chalk.yellow(config.packageManager)}`,
);
}
return configDisplay.join("\n");
}
async function main() { async function main() {
const s = spinner(); const s = spinner();
try { try {
@@ -217,18 +259,30 @@ async function main() {
const projectDirectory = program.args[0]; const projectDirectory = program.args[0];
const flagConfig: Partial<ProjectConfig> = { const flagConfig: Partial<ProjectConfig> = {
projectName: projectDirectory, projectName: projectDirectory || undefined,
database: options.database as ProjectDatabase, database: options.database as ProjectDatabase | undefined,
auth: options.auth, auth: "auth" in options ? options.auth : undefined,
packageManager: options.packageManager as PackageManager, packageManager: options.packageManager as PackageManager | undefined,
git: options.git ?? true, git: "git" in options ? options.git : undefined,
features: [ features:
options.docker || options.githubActions || options.seo
? ([
...(options.docker ? ["docker"] : []), ...(options.docker ? ["docker"] : []),
...(options.githubActions ? ["github-actions"] : []), ...(options.githubActions ? ["github-actions"] : []),
...(options.seo ? ["SEO"] : []), ...(options.seo ? ["SEO"] : []),
] as ProjectFeature[], ] as ProjectFeature[])
: undefined,
}; };
if (
!options.yes &&
Object.values(flagConfig).some((v) => v !== undefined)
) {
log.message(chalk.bold("\n🎯 Using these pre-selected options:"));
log.message(displayConfig(flagConfig));
log.message("");
}
const config = options.yes const config = options.yes
? { ? {
...DEFAULT_CONFIG, ...DEFAULT_CONFIG,
@@ -248,28 +302,9 @@ async function main() {
: await gatherConfig(flagConfig); : await gatherConfig(flagConfig);
if (options.yes) { if (options.yes) {
s.start("Using default configuration"); log.message(chalk.bold("\n🎯 Using these default options:"));
const colorizedConfig = { log.message(displayConfig(config));
projectName: chalk.green(config.projectName), log.message("");
database: chalk.yellow(config.database),
auth: chalk.cyan(config.auth),
features: config.features.map((feature) => chalk.magenta(feature)),
git: chalk.cyan(config.git),
};
log.message(
`${chalk.blue("📝 Project Name: ")}${
colorizedConfig.projectName
}\n${chalk.blue("💾 Database: ")}${colorizedConfig.database}\n${chalk.blue(
"🔐 Authentication: ",
)}${colorizedConfig.auth}\n${chalk.blue("✨ Features: ")}${
colorizedConfig.features.length
? colorizedConfig.features.join(", ")
: chalk.gray("none")
}\n${chalk.blue("🗃️ Git Init: ")}${colorizedConfig.git}\n`,
);
s.stop("Configuration loaded");
} }
await createProject(config); await createProject(config);