mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
cli for setting up better-t-stack
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/node_modules
|
||||||
|
/dist
|
||||||
3933
package-lock.json
generated
Normal file
3933
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
36
package.json
Normal file
36
package.json
Normal 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
56
src/create-project.ts
Normal 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
64
src/index.ts
Normal 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
12
tsconfig.json
Normal 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
12
tsup.config.ts
Normal 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'
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user