chore: Removed initial commit for git initialization 462c56f3
Removes `git add .` and `git commit -m` from the git initialization
option per #1
Steve · 2025-05-09 19:08 1 file(s) · +322 −292
index.js +322 −292
1 1
#!/usr/bin/env node
2 2
3 -
import fs from 'fs-extra';
4 -
import path from 'path';
5 -
import { fileURLToPath } from 'url';
6 -
import prompts from 'prompts';
7 -
import { program } from 'commander';
8 -
import chalk from 'chalk';
9 -
import ora from 'ora';
10 -
import { execa } from 'execa';
11 -
import degit from 'degit';
12 -
import figlet from 'figlet';
13 -
import { defaultTemplate, shadcnTemplate, tailwindTemplate } from './utils/templates.js';
3 +
import fs from "fs-extra";
4 +
import path from "path";
5 +
import { fileURLToPath } from "url";
6 +
import prompts from "prompts";
7 +
import { program } from "commander";
8 +
import chalk from "chalk";
9 +
import ora from "ora";
10 +
import { execa } from "execa";
11 +
import degit from "degit";
12 +
import figlet from "figlet";
13 +
import {
14 +
	defaultTemplate,
15 +
	shadcnTemplate,
16 +
	tailwindTemplate,
17 +
} from "./utils/templates.js";
14 18
15 19
const __filename = fileURLToPath(import.meta.url);
16 20
const __dirname = path.dirname(__filename);
17 21
18 22
// GitHub repository for the template
19 -
const DEFAULT_REPO = 'stevedylandev/bhvr';
23 +
const DEFAULT_REPO = "stevedylandev/bhvr";
20 24
21 25
// Available templates
22 26
const TEMPLATES = {
23 -
  default: { branch: 'main', description: 'Basic setup with Bun, Hono, Vite and React' },
24 -
  tailwind: { branch: 'tailwindcss', description: 'Basic setup + TailwindCSS' },
25 -
  shadcn: { branch: 'shadcn-ui', description: 'Basic setup + TailwindCSS + shadcn/ui' }
27 +
	default: {
28 +
		branch: "main",
29 +
		description: "Basic setup with Bun, Hono, Vite and React",
30 +
	},
31 +
	tailwind: { branch: "tailwindcss", description: "Basic setup + TailwindCSS" },
32 +
	shadcn: {
33 +
		branch: "shadcn-ui",
34 +
		description: "Basic setup + TailwindCSS + shadcn/ui",
35 +
	},
26 36
};
27 37
28 38
// Function to display a fun banner
29 39
function displayBanner() {
30 -
  const text = figlet.textSync('bhvr', {
31 -
    font: 'Big',
32 -
    horizontalLayout: 'default',
33 -
    verticalLayout: 'default',
34 -
    width: 80,
35 -
    whitespaceBreak: true
36 -
  });
40 +
	const text = figlet.textSync("bhvr", {
41 +
		font: "Big",
42 +
		horizontalLayout: "default",
43 +
		verticalLayout: "default",
44 +
		width: 80,
45 +
		whitespaceBreak: true,
46 +
	});
37 47
38 -
  console.log('\n');
39 -
  console.log(chalk.yellowBright(text));
40 -
  console.log(`\n${chalk.cyan('🦫 Lets build 🦫')}\n`);
41 -
  console.log(`${chalk.blue('https://github.com/stevedylandev/bhvr')}\n`);
48 +
	console.log("\n");
49 +
	console.log(chalk.yellowBright(text));
50 +
	console.log(`\n${chalk.cyan("🦫 Lets build 🦫")}\n`);
51 +
	console.log(`${chalk.blue("https://github.com/stevedylandev/bhvr")}\n`);
42 52
}
43 53
44 54
// Set up the CLI program
45 55
program
46 -
  .name('create-bhvr')
47 -
  .description('Create a bhvr monorepo starter project')
48 -
  .argument('[project-directory]', 'directory to create the project in')
49 -
  .option('-y, --yes', 'skip confirmation prompts')
50 -
  .option('--ts, --typescript', 'use TypeScript (default)')
51 -
  .option('--repo <repo>', 'specify a custom GitHub repository as source', DEFAULT_REPO)
52 -
  .option('--template <template>', 'specify a template (default, tailwind, shadcn)', 'default')
53 -
  .option('--branch <branch>', 'specify a branch to use from the repository')
54 -
  .option('--rpc', 'use Hono RPC client for type-safe API communication')
55 -
  .action(async (projectDirectory, options) => {
56 -
    try {
57 -
      displayBanner();
58 -
      const result = await createProject(projectDirectory, options);
59 -
      if (result) {
60 -
        console.log(chalk.green.bold('🎉 Project created successfully!'));
61 -
        console.log('\nNext steps:');
56 +
	.name("create-bhvr")
57 +
	.description("Create a bhvr monorepo starter project")
58 +
	.argument("[project-directory]", "directory to create the project in")
59 +
	.option("-y, --yes", "skip confirmation prompts")
60 +
	.option("--ts, --typescript", "use TypeScript (default)")
61 +
	.option(
62 +
		"--repo <repo>",
63 +
		"specify a custom GitHub repository as source",
64 +
		DEFAULT_REPO,
65 +
	)
66 +
	.option(
67 +
		"--template <template>",
68 +
		"specify a template (default, tailwind, shadcn)",
69 +
		"default",
70 +
	)
71 +
	.option("--branch <branch>", "specify a branch to use from the repository")
72 +
	.option("--rpc", "use Hono RPC client for type-safe API communication")
73 +
	.action(async (projectDirectory, options) => {
74 +
		try {
75 +
			displayBanner();
76 +
			const result = await createProject(projectDirectory, options);
77 +
			if (result) {
78 +
				console.log(chalk.green.bold("🎉 Project created successfully!"));
79 +
				console.log("\nNext steps:");
62 80
63 -
        if (!result.dependenciesInstalled) {
64 -
          console.log(chalk.cyan(`  cd ${result.projectName}`));
65 -
          console.log(chalk.cyan('  bun install'));
66 -
        } else {
67 -
          console.log(chalk.cyan(`  cd ${result.projectName}`));
68 -
        }
81 +
				if (!result.dependenciesInstalled) {
82 +
					console.log(chalk.cyan(`  cd ${result.projectName}`));
83 +
					console.log(chalk.cyan("  bun install"));
84 +
				} else {
85 +
					console.log(chalk.cyan(`  cd ${result.projectName}`));
86 +
				}
69 87
70 -
        console.log(chalk.cyan('  bun run dev:client   # Start the client'));
71 -
        console.log(chalk.cyan('  bun run dev:server   # Start the server in another terminal'));
72 -
        console.log(chalk.cyan('  bun run dev          # Start all'));
73 -
        process.exit(0);
74 -
      }
75 -
    } catch (err) {
76 -
      console.error(chalk.red('Error creating project:'), err);
77 -
      process.exit(1);
78 -
    }
79 -
  });
88 +
				console.log(chalk.cyan("  bun run dev:client   # Start the client"));
89 +
				console.log(
90 +
					chalk.cyan(
91 +
						"  bun run dev:server   # Start the server in another terminal",
92 +
					),
93 +
				);
94 +
				console.log(chalk.cyan("  bun run dev          # Start all"));
95 +
				process.exit(0);
96 +
			}
97 +
		} catch (err) {
98 +
			console.error(chalk.red("Error creating project:"), err);
99 +
			process.exit(1);
100 +
		}
101 +
	});
80 102
81 103
program.parse();
82 104
83 105
async function createProject(projectDirectory, options) {
84 -
  // If project directory not provided, prompt for it
85 -
  let projectName = projectDirectory;
106 +
	// If project directory not provided, prompt for it
107 +
	let projectName = projectDirectory;
86 108
87 -
  if (!projectName && !options.yes) {
88 -
    const response = await prompts({
89 -
      type: 'text',
90 -
      name: 'projectName',
91 -
      message: 'What is the name of your project?',
92 -
      initial: 'my-bhvr-app'
93 -
    });
109 +
	if (!projectName && !options.yes) {
110 +
		const response = await prompts({
111 +
			type: "text",
112 +
			name: "projectName",
113 +
			message: "What is the name of your project?",
114 +
			initial: "my-bhvr-app",
115 +
		});
94 116
95 -
    if (!response.projectName) {
96 -
      console.log(chalk.yellow('Project creation cancelled.'));
97 -
      return null;
98 -
    }
117 +
		if (!response.projectName) {
118 +
			console.log(chalk.yellow("Project creation cancelled."));
119 +
			return null;
120 +
		}
99 121
100 -
    projectName = response.projectName;
101 -
  } else if (!projectName) {
102 -
    projectName = 'my-bhvr-app';
103 -
  }
122 +
		projectName = response.projectName;
123 +
	} else if (!projectName) {
124 +
		projectName = "my-bhvr-app";
125 +
	}
104 126
105 -
  // Template selection
106 -
  let templateChoice = options.template;
127 +
	// Template selection
128 +
	let templateChoice = options.template;
107 129
108 -
  if (!options.yes && !options.branch) {
109 -
    const templateChoices = Object.keys(TEMPLATES).map(key => ({
110 -
      title: `${key} (${TEMPLATES[key].description})`,
111 -
      value: key
112 -
    }));
130 +
	if (!options.yes && !options.branch) {
131 +
		const templateChoices = Object.keys(TEMPLATES).map((key) => ({
132 +
			title: `${key} (${TEMPLATES[key].description})`,
133 +
			value: key,
134 +
		}));
113 135
114 -
    const templateResponse = await prompts({
115 -
      type: 'select',
116 -
      name: 'template',
117 -
      message: 'Select a template:',
118 -
      choices: templateChoices,
119 -
      initial: 0
120 -
    });
136 +
		const templateResponse = await prompts({
137 +
			type: "select",
138 +
			name: "template",
139 +
			message: "Select a template:",
140 +
			choices: templateChoices,
141 +
			initial: 0,
142 +
		});
121 143
122 -
    if (templateResponse.template === undefined) {
123 -
      console.log(chalk.yellow('Project creation cancelled.'));
124 -
      return null;
125 -
    }
144 +
		if (templateResponse.template === undefined) {
145 +
			console.log(chalk.yellow("Project creation cancelled."));
146 +
			return null;
147 +
		}
126 148
127 -
    templateChoice = templateResponse.template;
128 -
  }
149 +
		templateChoice = templateResponse.template;
150 +
	}
129 151
130 -
  // Create the project directory
131 -
  const projectPath = path.resolve(process.cwd(), projectName);
152 +
	// Create the project directory
153 +
	const projectPath = path.resolve(process.cwd(), projectName);
132 154
133 -
  // Check if directory exists and is not empty
134 -
  if (fs.existsSync(projectPath)) {
135 -
    const files = fs.readdirSync(projectPath);
155 +
	// Check if directory exists and is not empty
156 +
	if (fs.existsSync(projectPath)) {
157 +
		const files = fs.readdirSync(projectPath);
136 158
137 -
    if (files.length > 0 && !options.yes) {
138 -
      const { overwrite } = await prompts({
139 -
        type: 'confirm',
140 -
        name: 'overwrite',
141 -
        message: `The directory ${projectName} already exists and is not empty. Do you want to overwrite it?`,
142 -
        initial: false
143 -
      });
159 +
		if (files.length > 0 && !options.yes) {
160 +
			const { overwrite } = await prompts({
161 +
				type: "confirm",
162 +
				name: "overwrite",
163 +
				message: `The directory ${projectName} already exists and is not empty. Do you want to overwrite it?`,
164 +
				initial: false,
165 +
			});
144 166
145 -
      if (!overwrite) {
146 -
        console.log(chalk.yellow('Project creation cancelled.'));
147 -
        return null;
148 -
      }
167 +
			if (!overwrite) {
168 +
				console.log(chalk.yellow("Project creation cancelled."));
169 +
				return null;
170 +
			}
149 171
150 -
      // Clear directory if overwriting
151 -
      await fs.emptyDir(projectPath);
152 -
    }
153 -
  }
172 +
			// Clear directory if overwriting
173 +
			await fs.emptyDir(projectPath);
174 +
		}
175 +
	}
154 176
155 -
  // Create directory if it doesn't exist
156 -
  fs.ensureDirSync(projectPath);
177 +
	// Create directory if it doesn't exist
178 +
	fs.ensureDirSync(projectPath);
157 179
158 -
  // Clone template from GitHub
159 -
  const repoPath = options.repo || DEFAULT_REPO;
160 -
  // Use provided branch, template branch, or default
161 -
  const branch = options.branch || (TEMPLATES[templateChoice] ? TEMPLATES[templateChoice].branch : 'main');
162 -
  const repoUrl = `${repoPath}#${branch}`;
180 +
	// Clone template from GitHub
181 +
	const repoPath = options.repo || DEFAULT_REPO;
182 +
	// Use provided branch, template branch, or default
183 +
	const branch =
184 +
		options.branch ||
185 +
		(TEMPLATES[templateChoice] ? TEMPLATES[templateChoice].branch : "main");
186 +
	const repoUrl = `${repoPath}#${branch}`;
163 187
164 -
  const spinner = ora('Downloading template...').start();
188 +
	const spinner = ora("Downloading template...").start();
165 189
166 -
  try {
167 -
    const emitter = degit(repoUrl, {
168 -
      cache: false,
169 -
      force: true,
170 -
      verbose: false,
171 -
    });
190 +
	try {
191 +
		const emitter = degit(repoUrl, {
192 +
			cache: false,
193 +
			force: true,
194 +
			verbose: false,
195 +
		});
172 196
173 -
    await emitter.clone(projectPath);
174 -
    spinner.succeed(`Template downloaded successfully (${templateChoice} template)`);
197 +
		await emitter.clone(projectPath);
198 +
		spinner.succeed(
199 +
			`Template downloaded successfully (${templateChoice} template)`,
200 +
		);
175 201
176 -
    // Update package.json with project name
177 -
    const pkgJsonPath = path.join(projectPath, 'package.json');
178 -
    if (fs.existsSync(pkgJsonPath)) {
179 -
      const pkgJson = await fs.readJson(pkgJsonPath);
180 -
      pkgJson.name = projectName;
181 -
      await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
182 -
    }
202 +
		// Update package.json with project name
203 +
		const pkgJsonPath = path.join(projectPath, "package.json");
204 +
		if (fs.existsSync(pkgJsonPath)) {
205 +
			const pkgJson = await fs.readJson(pkgJsonPath);
206 +
			pkgJson.name = projectName;
207 +
			await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
208 +
		}
183 209
184 -
    // Remove the .git directory if it exists
185 -
    const gitDir = path.join(projectPath, '.git');
186 -
    if (fs.existsSync(gitDir)) {
187 -
      await fs.remove(gitDir);
188 -
      console.log(chalk.blue('Removed .git directory'));
189 -
    }
210 +
		// Remove the .git directory if it exists
211 +
		const gitDir = path.join(projectPath, ".git");
212 +
		if (fs.existsSync(gitDir)) {
213 +
			await fs.remove(gitDir);
214 +
			console.log(chalk.blue("Removed .git directory"));
215 +
		}
190 216
191 -
    if (options.rpc) {
192 -
      await patchFilesForRPC(projectPath);
193 -
    }
217 +
		if (options.rpc) {
218 +
			await patchFilesForRPC(projectPath);
219 +
		}
194 220
195 -
    // Initialize git repository?
196 -
    let gitInitialized = false;
221 +
		// Initialize git repository?
222 +
		let gitInitialized = false;
197 223
198 -
    if (!options.yes) {
199 -
      const gitResponse = await prompts({
200 -
        type: 'confirm',
201 -
        name: 'initGit',
202 -
        message: 'Initialize a git repository?',
203 -
        initial: true
204 -
      });
224 +
		if (!options.yes) {
225 +
			const gitResponse = await prompts({
226 +
				type: "confirm",
227 +
				name: "initGit",
228 +
				message: "Initialize a git repository?",
229 +
				initial: true,
230 +
			});
205 231
206 -
      if (gitResponse.initGit) {
207 -
        try {
208 -
          spinner.start('Initializing git repository...');
209 -
          await execa('git', ['init'], { cwd: projectPath });
210 -
          await execa('git', ['add', '.'], { cwd: projectPath });
211 -
          await execa('git', ['commit', '-m', 'Initial commit from create-bhvr'], { cwd: projectPath });
212 -
          spinner.succeed('Git repository initialized');
213 -
          gitInitialized = true;
214 -
        } catch (err) {
215 -
          spinner.fail('Failed to initialize git repository. Is git installed?');
216 -
          console.error(chalk.red('Git error:'), err.message);
217 -
        }
218 -
      }
219 -
    } else {
220 -
      // If using --yes, automatically initialize git
221 -
      try {
222 -
        spinner.start('Initializing git repository...');
223 -
        await execa('git', ['init'], { cwd: projectPath });
224 -
        await execa('git', ['add', '.'], { cwd: projectPath });
225 -
        await execa('git', ['commit', '-m', 'Initial commit from create-bhvr'], { cwd: projectPath });
226 -
        spinner.succeed('Git repository initialized');
227 -
        gitInitialized = true;
228 -
      } catch (err) {
229 -
        spinner.fail('Failed to initialize git repository. Is git installed?');
230 -
      }
231 -
    }
232 +
			if (gitResponse.initGit) {
233 +
				try {
234 +
					spinner.start("Initializing git repository...");
235 +
					await execa("git", ["init"], { cwd: projectPath });
236 +
					spinner.succeed("Git repository initialized");
237 +
					gitInitialized = true;
238 +
				} catch (err) {
239 +
					spinner.fail(
240 +
						"Failed to initialize git repository. Is git installed?",
241 +
					);
242 +
					console.error(chalk.red("Git error:"), err.message);
243 +
				}
244 +
			}
245 +
		} else {
246 +
			// If using --yes, automatically initialize git
247 +
			try {
248 +
				spinner.start("Initializing git repository...");
249 +
				await execa("git", ["init"], { cwd: projectPath });
250 +
				spinner.succeed("Git repository initialized");
251 +
				gitInitialized = true;
252 +
			} catch (err) {
253 +
				spinner.fail("Failed to initialize git repository. Is git installed?");
254 +
			}
255 +
		}
232 256
233 -
    // Install dependencies?
234 -
    let dependenciesInstalled = false;
257 +
		// Install dependencies?
258 +
		let dependenciesInstalled = false;
235 259
236 -
    if (!options.yes) {
237 -
      const depsResponse = await prompts({
238 -
        type: 'confirm',
239 -
        name: 'installDeps',
240 -
        message: 'Install dependencies?',
241 -
        initial: true
242 -
      });
260 +
		if (!options.yes) {
261 +
			const depsResponse = await prompts({
262 +
				type: "confirm",
263 +
				name: "installDeps",
264 +
				message: "Install dependencies?",
265 +
				initial: true,
266 +
			});
243 267
244 -
      if (depsResponse.installDeps) {
245 -
        spinner.start('Installing dependencies...');
246 -
        try {
247 -
          // Try with bun first
248 -
          await execa('bun', ['install'], { cwd: projectPath });
249 -
          spinner.succeed('Dependencies installed with bun');
250 -
          dependenciesInstalled = true;
251 -
        } catch (bunErr) {
252 -
          // If bun fails, try with npm
253 -
          try {
254 -
            spinner.text = 'Installing dependencies with npm...';
255 -
            await execa('npm', ['install'], { cwd: projectPath });
256 -
            spinner.succeed('Dependencies installed with npm');
257 -
            dependenciesInstalled = true;
258 -
          } catch (npmErr) {
259 -
            spinner.fail('Failed to install dependencies.');
260 -
            console.log(chalk.yellow('You can install them manually after navigating to the project directory.'));
261 -
          }
262 -
        }
263 -
      }
264 -
    } else {
265 -
      // If using --yes, automatically install dependencies
266 -
      spinner.start('Installing dependencies...');
267 -
      try {
268 -
        await execa('bun', ['install'], { cwd: projectPath });
269 -
        spinner.succeed('Dependencies installed with bun');
270 -
        dependenciesInstalled = true;
271 -
      } catch (bunErr) {
272 -
        try {
273 -
          spinner.text = 'Installing dependencies with npm...';
274 -
          await execa('npm', ['install'], { cwd: projectPath });
275 -
          spinner.succeed('Dependencies installed with npm');
276 -
          dependenciesInstalled = true;
277 -
        } catch (npmErr) {
278 -
          spinner.fail('Failed to install dependencies. You can install them manually later.');
279 -
        }
280 -
      }
281 -
    }
268 +
			if (depsResponse.installDeps) {
269 +
				spinner.start("Installing dependencies...");
270 +
				try {
271 +
					// Try with bun first
272 +
					await execa("bun", ["install"], { cwd: projectPath });
273 +
					spinner.succeed("Dependencies installed with bun");
274 +
					dependenciesInstalled = true;
275 +
				} catch (bunErr) {
276 +
					// If bun fails, try with npm
277 +
					try {
278 +
						spinner.text = "Installing dependencies with npm...";
279 +
						await execa("npm", ["install"], { cwd: projectPath });
280 +
						spinner.succeed("Dependencies installed with npm");
281 +
						dependenciesInstalled = true;
282 +
					} catch (npmErr) {
283 +
						spinner.fail("Failed to install dependencies.");
284 +
						console.log(
285 +
							chalk.yellow(
286 +
								"You can install them manually after navigating to the project directory.",
287 +
							),
288 +
						);
289 +
					}
290 +
				}
291 +
			}
292 +
		} else {
293 +
			// If using --yes, automatically install dependencies
294 +
			spinner.start("Installing dependencies...");
295 +
			try {
296 +
				await execa("bun", ["install"], { cwd: projectPath });
297 +
				spinner.succeed("Dependencies installed with bun");
298 +
				dependenciesInstalled = true;
299 +
			} catch (bunErr) {
300 +
				try {
301 +
					spinner.text = "Installing dependencies with npm...";
302 +
					await execa("npm", ["install"], { cwd: projectPath });
303 +
					spinner.succeed("Dependencies installed with npm");
304 +
					dependenciesInstalled = true;
305 +
				} catch (npmErr) {
306 +
					spinner.fail(
307 +
						"Failed to install dependencies. You can install them manually later.",
308 +
					);
309 +
				}
310 +
			}
311 +
		}
282 312
283 -
    if (!options.yes && !options.rpc) {
284 -
      const { useRpc } = await prompts({
285 -
        type: 'confirm',
286 -
        name: 'useRpc',
287 -
        message: 'Use Hono RPC client for type-safe API communication?',
288 -
        initial: false
289 -
      });
313 +
		if (!options.yes && !options.rpc) {
314 +
			const { useRpc } = await prompts({
315 +
				type: "confirm",
316 +
				name: "useRpc",
317 +
				message: "Use Hono RPC client for type-safe API communication?",
318 +
				initial: false,
319 +
			});
290 320
291 -
      if (useRpc) {
292 -
        await patchFilesForRPC(projectPath, templateChoice);
293 -
      }
294 -
    }
321 +
			if (useRpc) {
322 +
				await patchFilesForRPC(projectPath, templateChoice);
323 +
			}
324 +
		}
295 325
296 -
    return {
297 -
      projectName,
298 -
      gitInitialized,
299 -
      dependenciesInstalled,
300 -
      template: templateChoice,
301 -
    };
302 -
  } catch (err) {
303 -
    spinner.fail('Failed to download template');
304 -
    throw err;
305 -
  }
326 +
		return {
327 +
			projectName,
328 +
			gitInitialized,
329 +
			dependenciesInstalled,
330 +
			template: templateChoice,
331 +
		};
332 +
	} catch (err) {
333 +
		spinner.fail("Failed to download template");
334 +
		throw err;
335 +
	}
306 336
}
307 337
308 338
async function patchFilesForRPC(projectPath, templateChoice) {
309 -
  const spinner = ora('Setting up RPC client...').start();
339 +
	const spinner = ora("Setting up RPC client...").start();
310 340
311 -
  try {
312 -
    // 1. Update client package.json to ensure hono client is installed
313 -
    const clientPkgPath = path.join(projectPath, 'client', 'package.json');
314 -
    const clientPkg = await fs.readJson(clientPkgPath);
341 +
	try {
342 +
		// 1. Update client package.json to ensure hono client is installed
343 +
		const clientPkgPath = path.join(projectPath, "client", "package.json");
344 +
		const clientPkg = await fs.readJson(clientPkgPath);
315 345
316 -
    if (!clientPkg.dependencies.hono) {
317 -
      await execa('bun', ['install','hono'], { cwd: projectPath });
318 -
    }
346 +
		if (!clientPkg.dependencies.hono) {
347 +
			await execa("bun", ["install", "hono"], { cwd: projectPath });
348 +
		}
319 349
320 -
    await fs.writeJson(clientPkgPath, clientPkg, { spaces: 2 });
350 +
		await fs.writeJson(clientPkgPath, clientPkg, { spaces: 2 });
321 351
322 -
    // 2. Server modification for RPC export type
323 -
    const serverIndexPath = path.join(projectPath, 'server', 'src', 'index.ts');
324 -
    let serverContent = await fs.readFile(serverIndexPath, 'utf8');
352 +
		// 2. Server modification for RPC export type
353 +
		const serverIndexPath = path.join(projectPath, "server", "src", "index.ts");
354 +
		let serverContent = await fs.readFile(serverIndexPath, "utf8");
325 355
326 -
    if (!serverContent.includes('export type AppType')) {
327 -
      // Update server content to export the type
328 -
      const updatedServerContent = `import { Hono } from 'hono'
356 +
		if (!serverContent.includes("export type AppType")) {
357 +
			// Update server content to export the type
358 +
			const updatedServerContent = `import { Hono } from 'hono'
329 359
import { cors } from 'hono/cors'
330 360
import type { ApiResponse } from 'shared/dist'
331 361
350 380
export type AppType = typeof routes
351 381
export default app`;
352 382
353 -
      await fs.writeFile(serverIndexPath, updatedServerContent, 'utf8');
354 -
    }
383 +
			await fs.writeFile(serverIndexPath, updatedServerContent, "utf8");
384 +
		}
355 385
356 -
    // 3. Update App.tsx based on template selection using switch statement
357 -
    const appTsxPath = path.join(projectPath, 'client', 'src', 'App.tsx');
386 +
		// 3. Update App.tsx based on template selection using switch statement
387 +
		const appTsxPath = path.join(projectPath, "client", "src", "App.tsx");
358 388
359 -
    // Determine template content based on the template type
360 -
    let updatedAppContent;
389 +
		// Determine template content based on the template type
390 +
		let updatedAppContent;
361 391
362 -
    // Select template based on choice
363 -
    switch (templateChoice) {
364 -
      case 'shadcn':
365 -
        updatedAppContent = shadcnTemplate;
366 -
        break;
367 -
      case 'tailwind':
368 -
        updatedAppContent = tailwindTemplate;
369 -
        break;
370 -
      case 'default':
371 -
      default:
372 -
        updatedAppContent = defaultTemplate;
373 -
        break;
374 -
    }
392 +
		// Select template based on choice
393 +
		switch (templateChoice) {
394 +
			case "shadcn":
395 +
				updatedAppContent = shadcnTemplate;
396 +
				break;
397 +
			case "tailwind":
398 +
				updatedAppContent = tailwindTemplate;
399 +
				break;
400 +
			case "default":
401 +
			default:
402 +
				updatedAppContent = defaultTemplate;
403 +
				break;
404 +
		}
375 405
376 -
    await fs.writeFile(appTsxPath, updatedAppContent, 'utf8');
377 -
    spinner.succeed('RPC client setup completed');
378 -
    return true;
379 -
  } catch (err) {
380 -
    spinner.fail('Failed to set up RPC client');
381 -
    console.error(chalk.red('Error:'), err.message);
382 -
    return false;
383 -
  }
406 +
		await fs.writeFile(appTsxPath, updatedAppContent, "utf8");
407 +
		spinner.succeed("RPC client setup completed");
408 +
		return true;
409 +
	} catch (err) {
410 +
		spinner.fail("Failed to set up RPC client");
411 +
		console.error(chalk.red("Error:"), err.message);
412 +
		return false;
413 +
	}
384 414
}