feat: add project name validation

This commit is contained in:
Aman Varshney
2025-02-13 23:12:20 +05:30
parent 432f9163ae
commit ecd7db9e48
3 changed files with 59 additions and 18 deletions

View File

@@ -0,0 +1,5 @@
---
"create-better-t-stack": patch
---
feat: add project name validation

View File

@@ -170,6 +170,8 @@ export async function setupTurso(projectDir: string) {
const dbNameResponse = await text({ const dbNameResponse = await text({
message: "Enter database name:", message: "Enter database name:",
defaultValue: suggestedName, defaultValue: suggestedName,
initialValue: suggestedName,
placeholder: suggestedName,
}); });
if (isCancel(dbNameResponse)) { if (isCancel(dbNameResponse)) {

View File

@@ -1,3 +1,4 @@
import path from "node:path";
import { import {
cancel, cancel,
confirm, confirm,
@@ -12,6 +13,7 @@ import {
} from "@clack/prompts"; } from "@clack/prompts";
import chalk from "chalk"; import chalk from "chalk";
import { Command } from "commander"; import { Command } from "commander";
import fs from "fs-extra";
import { DEFAULT_CONFIG } from "./consts"; import { DEFAULT_CONFIG } from "./consts";
import { createProject } from "./helpers/create-project"; import { createProject } from "./helpers/create-project";
import { renderTitle } from "./render-title"; import { renderTitle } from "./render-title";
@@ -35,19 +37,51 @@ const program = new Command();
async function gatherConfig( async function gatherConfig(
flags: Partial<ProjectConfig>, flags: Partial<ProjectConfig>,
): Promise<ProjectConfig> { ): Promise<ProjectConfig> {
const shouldAskGit = flags.git !== false;
const result = await group( const result = await group(
{ {
projectName: () => projectName: async () => {
text({ let isValid = false;
message: "📝 Project name", let projectName: string | symbol = "";
placeholder: "my-better-t-app", let defaultName = DEFAULT_CONFIG.projectName;
initialValue: flags.projectName, let counter = 1;
validate: (value) => {
if (!value) return "Project name is required"; while (fs.pathExistsSync(path.resolve(process.cwd(), defaultName))) {
}, defaultName = `${DEFAULT_CONFIG.projectName}-${counter}`;
}), counter++;
}
while (!isValid) {
const response = await text({
message: "📝 Project name",
placeholder: defaultName,
initialValue: flags.projectName || defaultName,
defaultValue: defaultName,
validate: (value) => {
const nameToUse = value.trim() || defaultName;
const projectDir = path.resolve(process.cwd(), nameToUse);
if (fs.pathExistsSync(projectDir)) {
const dirContents = fs.readdirSync(projectDir);
if (dirContents.length > 0) {
return `Directory "${nameToUse}" already exists and is not empty. Please choose a different name.`;
}
}
isValid = true;
return undefined;
},
});
if (typeof response === "symbol") {
cancel("Operation cancelled.");
process.exit(0);
}
projectName = response || defaultName;
}
return projectName as string;
},
database: () => database: () =>
!flags.database !flags.database
? select<ProjectDatabase>({ ? select<ProjectDatabase>({
@@ -96,7 +130,7 @@ async function gatherConfig(
}) })
: Promise.resolve(flags.features), : Promise.resolve(flags.features),
git: () => git: () =>
shouldAskGit flags.git !== false
? confirm({ ? confirm({
message: "🗃️ Initialize Git repository?", message: "🗃️ Initialize Git repository?",
initialValue: true, initialValue: true,
@@ -143,12 +177,12 @@ async function gatherConfig(
); );
return { return {
projectName: result.projectName as string, projectName: result.projectName ?? "",
database: (result.database as ProjectDatabase) ?? "libsql", database: result.database ?? "libsql",
auth: (result.auth as boolean) ?? true, auth: result.auth ?? true,
features: (result.features as ProjectFeature[]) ?? [], features: result.features ?? [],
git: (result.git as boolean) ?? true, git: result.git ?? true,
packageManager: (result.packageManager as PackageManager) ?? "npm", packageManager: result.packageManager ?? "npm",
}; };
} }