cli for setting up better-t-stack

This commit is contained in:
fgrreloaded
2025-02-10 22:37:40 +05:30
commit a73630b6ee
7 changed files with 4115 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/node_modules
/dist

3933
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

36
package.json Normal file
View File

@@ -0,0 +1,36 @@
{
"name": "create-better-t",
"version": "1.0.0",
"description": "CLI tool to scaffold Better-T Stack projects",
"type": "module",
"bin": {
"create-better-t": "./dist/index.js"
},
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"typecheck": "tsc --noEmit",
"test": "vitest run",
"prepublishOnly": "npm run build"
},
"files": [
"dist",
"templates"
],
"dependencies": {
"chalk": "^5.3.0",
"commander": "^11.1.0",
"inquirer": "^9.2.12",
"ora": "^7.0.1",
"execa": "^8.0.1",
"fs-extra": "^11.2.0"
},
"devDependencies": {
"@types/fs-extra": "^11.0.4",
"@types/inquirer": "^9.0.7",
"@types/node": "^20.10.5",
"tsup": "^8.0.1",
"typescript": "^5.3.3",
"vitest": "^1.1.0"
}
}

56
src/create-project.ts Normal file
View File

@@ -0,0 +1,56 @@
import { execa } from 'execa';
import fs from 'fs-extra';
import ora from 'ora';
import path from 'path';
interface ProjectOptions {
projectName: string;
typescript: boolean;
git: boolean;
database: 'libsql' | 'postgres';
auth: boolean;
features: string[];
}
export async function createProject(options: ProjectOptions) {
const spinner = ora('Creating project directory...').start();
const projectDir = path.resolve(process.cwd(), options.projectName);
try {
await fs.ensureDir(projectDir);
spinner.succeed();
spinner.start('Cloning template repository...');
await execa('git', ['clone', '--depth', '1', 'https://github.com/AmanVarshney01/Better-T-Stack.git', projectDir]);
spinner.succeed();
spinner.start('Removing template .git folder...');
await fs.remove(path.join(projectDir, '.git'));
spinner.succeed();
if (options.git) {
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();
spinner.start('Setting up database...');
if (options.database === 'libsql') {
await execa('bun', ['run', 'db:local'], { cwd: projectDir });
await execa('bun', ['run', 'db:push'], { cwd: projectDir });
}
spinner.succeed();
console.log('\n✨ Project created successfully!\n');
console.log('Next steps:');
console.log(` cd ${options.projectName}`);
console.log(' bun dev');
} catch (error) {
spinner.fail('Failed to create project');
console.error(error);
process.exit(1);
}
}

64
src/index.ts Normal file
View File

@@ -0,0 +1,64 @@
#!/usr/bin/env node
import { Command } from 'commander';
import chalk from 'chalk';
import inquirer from 'inquirer';
import { createProject } from './create-project';
const program = new Command();
program
.name('create-better-t')
.description('Create a new Better-T Stack project')
.argument('[project-directory]', 'project name')
.option('--typescript', 'use TypeScript (default)', true)
.option('--js, --javascript', 'use JavaScript')
.option('--git', 'initialize git repository (default)', true)
.option('--no-git', 'skip git initialization')
.action(async (projectName?: string, options?: any) => {
console.log(chalk.bold('\n🚀 Creating a new Better-T Stack project...\n'));
const answers = await inquirer.prompt([
{
type: 'input',
name: 'projectName',
message: 'Project name:',
default: projectName || 'my-better-t-app',
when: !projectName,
},
{
type: 'list',
name: 'database',
message: 'Select database:',
choices: [
{ name: 'libSQL (recommended)', value: 'libsql' },
{ name: 'PostgreSQL', value: 'postgres' },
],
},
{
type: 'confirm',
name: 'auth',
message: 'Add authentication with Better-Auth?',
default: true,
},
{
type: 'list',
name: 'features',
message: 'Select additional features:',
choices: [
{ name: 'Docker setup', value: 'docker' },
{ name: 'GitHub Actions', value: 'github-actions' },
{ name: 'Basic SEO setup', value: 'seo' },
],
},
]);
const projectOptions = {
...options,
...answers,
projectName: projectName || answers.projectName,
};
await createProject(projectOptions);
});
program.parse();

12
tsconfig.json Normal file
View File

@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true,
"outDir": "dist"
},
"include": ["src"]
}

12
tsup.config.ts Normal file
View File

@@ -0,0 +1,12 @@
// tsup.config.ts
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
clean: true,
dts: true,
shims: true,
splitting: false,
outDir: 'dist'
});