the best lightweight web dev stack built on bun

chore: add version to prompt

dunkirk.sh 1c570f1e b219e256

verified
Changed files
+135 -133
+134 -132
cli.ts
··· 9 9 import { join } from "node:path"; 10 10 import * as p from "@clack/prompts"; 11 11 import { setTimeout } from "node:timers/promises"; 12 + import { version } from "./package.json"; 12 13 13 14 async function main() { 14 - console.clear(); 15 - 16 - p.intro("🥞 Tacy Stack Generator"); 17 - 18 - // Get project name 19 - const projectName = await p.text({ 20 - message: "What is your project name?", 21 - placeholder: "my-app", 22 - validate(value) { 23 - if (!value) return "Project name is required"; 24 - if (!/^[a-z0-9-_]+$/i.test(value)) { 25 - return "Project name can only contain letters, numbers, hyphens, and underscores"; 26 - } 27 - const targetDir = join(process.cwd(), value); 28 - if (existsSync(targetDir)) { 29 - return `Directory "${value}" already exists!`; 30 - } 31 - }, 32 - }); 33 - 34 - if (p.isCancel(projectName)) { 35 - p.cancel("Operation cancelled"); 36 - process.exit(0); 37 - } 38 - 39 - const targetDir = join(process.cwd(), projectName as string); 40 - const templateDir = import.meta.dir; 41 - 42 - const s = p.spinner(); 43 - 44 - try { 45 - // Create directory 46 - s.start("Creating project directory"); 47 - mkdirSync(targetDir, { recursive: true }); 48 - await setTimeout(200); 49 - s.stop("Created project directory"); 50 - 51 - // Copy template files 52 - s.start("Copying template files"); 53 - await $`cp -r ${templateDir}/* ${targetDir}/`.quiet(); 54 - 55 - // Copy dotfiles explicitly 56 - const dotfiles = [".env.example", ".gitignore", ".gitattributes"]; 57 - for (const dotfile of dotfiles) { 58 - const source = join(templateDir, dotfile); 59 - const dest = join(targetDir, dotfile); 60 - if (existsSync(source)) { 61 - await $`cp ${source} ${dest}`.quiet(); 62 - } 63 - } 64 - 65 - // Copy .github directory if it exists 66 - const githubDir = join(templateDir, ".github"); 67 - if (existsSync(githubDir)) { 68 - await $`cp -r ${githubDir} ${targetDir}/.github`.quiet(); 69 - } 70 - 71 - await setTimeout(200); 72 - s.stop("Copied template files"); 73 - 74 - // Remove CLI and template files 75 - s.start("Cleaning up template files"); 76 - const filesToRemove = [ 77 - "cli.ts", 78 - "TEMPLATE.md", 79 - "TEMPLATE_SETUP_SUMMARY.md", 80 - "CLI_SUMMARY.md", 81 - "PUBLISHING.md", 82 - "template.toml", 83 - ".github/TEMPLATE_SETUP.md", 84 - ]; 85 - 86 - for (const file of filesToRemove) { 87 - const filePath = join(targetDir, file); 88 - if (existsSync(filePath)) { 89 - await $`rm -rf ${filePath}`.quiet(); 90 - } 91 - } 92 - await setTimeout(200); 93 - s.stop("Cleaned up template files"); 94 - 95 - // Update package.json 96 - s.start("Configuring package.json"); 97 - const packageJsonPath = join(targetDir, "package.json"); 98 - const packageJson = await Bun.file(packageJsonPath).json(); 99 - packageJson.name = projectName; 100 - packageJson.version = "0.1.0"; 101 - delete packageJson.bin; 102 - // Remove @clack/prompts from dependencies since it's only for the CLI 103 - if (packageJson.dependencies?.["@clack/prompts"]) { 104 - delete packageJson.dependencies["@clack/prompts"]; 105 - } 106 - await Bun.write(packageJsonPath, JSON.stringify(packageJson, null, "\t") + "\n"); 107 - await setTimeout(200); 108 - s.stop("Configured package.json"); 109 - 110 - // Initialize git 111 - s.start("Initializing git repository"); 112 - await $`cd ${targetDir} && git init`.quiet(); 113 - await setTimeout(200); 114 - s.stop("Initialized git repository"); 115 - 116 - // Create .env 117 - s.start("Creating .env file"); 118 - await $`cd ${targetDir} && cp .env.example .env`.quiet(); 119 - await setTimeout(200); 120 - s.stop("Created .env file"); 121 - 122 - // Install dependencies 123 - s.start("Installing dependencies"); 124 - await $`cd ${targetDir} && bun install`.quiet(); 125 - s.stop("Installed dependencies"); 126 - 127 - // Setup database 128 - s.start("Setting up database"); 129 - await $`cd ${targetDir} && bun run db:push`.quiet(); 130 - s.stop("Set up database"); 131 - 132 - } catch (error) { 133 - s.stop("Failed"); 134 - p.cancel(`Error: ${error instanceof Error ? error.message : "Unknown error"}`); 135 - process.exit(1); 136 - } 137 - 138 - p.outro("🎉 Project created successfully!"); 139 - 140 - p.note( 141 - `cd ${projectName}\nbun dev`, 142 - "Next steps" 143 - ); 15 + console.clear(); 16 + 17 + p.intro(`🥞 Tacy Stack Generator @ ${version}`); 18 + 19 + // Get project name 20 + const projectName = await p.text({ 21 + message: "What is your project name?", 22 + placeholder: "my-app", 23 + validate(value) { 24 + if (!value) return "Project name is required"; 25 + if (!/^[a-z0-9-_]+$/i.test(value)) { 26 + return "Project name can only contain letters, numbers, hyphens, and underscores"; 27 + } 28 + const targetDir = join(process.cwd(), value); 29 + if (existsSync(targetDir)) { 30 + return `Directory "${value}" already exists!`; 31 + } 32 + }, 33 + }); 34 + 35 + if (p.isCancel(projectName)) { 36 + p.cancel("Operation cancelled"); 37 + process.exit(0); 38 + } 39 + 40 + const targetDir = join(process.cwd(), projectName as string); 41 + const templateDir = import.meta.dir; 42 + 43 + const s = p.spinner(); 44 + 45 + try { 46 + // Create directory 47 + s.start("Creating project directory"); 48 + mkdirSync(targetDir, { recursive: true }); 49 + await setTimeout(200); 50 + s.stop("Created project directory"); 51 + 52 + // Copy template files 53 + s.start("Copying template files"); 54 + await $`cp -r ${templateDir}/* ${targetDir}/`.quiet(); 55 + 56 + // Copy dotfiles explicitly 57 + const dotfiles = [".env.example", ".gitignore", ".gitattributes"]; 58 + for (const dotfile of dotfiles) { 59 + const source = join(templateDir, dotfile); 60 + const dest = join(targetDir, dotfile); 61 + if (existsSync(source)) { 62 + await $`cp ${source} ${dest}`.quiet(); 63 + } 64 + } 65 + 66 + // Copy .github directory if it exists 67 + const githubDir = join(templateDir, ".github"); 68 + if (existsSync(githubDir)) { 69 + await $`cp -r ${githubDir} ${targetDir}/.github`.quiet(); 70 + } 71 + 72 + await setTimeout(200); 73 + s.stop("Copied template files"); 74 + 75 + // Remove CLI and template files 76 + s.start("Cleaning up template files"); 77 + const filesToRemove = [ 78 + "cli.ts", 79 + "TEMPLATE.md", 80 + "TEMPLATE_SETUP_SUMMARY.md", 81 + "CLI_SUMMARY.md", 82 + "PUBLISHING.md", 83 + "template.toml", 84 + ".github/TEMPLATE_SETUP.md", 85 + ]; 86 + 87 + for (const file of filesToRemove) { 88 + const filePath = join(targetDir, file); 89 + if (existsSync(filePath)) { 90 + await $`rm -rf ${filePath}`.quiet(); 91 + } 92 + } 93 + await setTimeout(200); 94 + s.stop("Cleaned up template files"); 95 + 96 + // Update package.json 97 + s.start("Configuring package.json"); 98 + const packageJsonPath = join(targetDir, "package.json"); 99 + const packageJson = await Bun.file(packageJsonPath).json(); 100 + packageJson.name = projectName; 101 + packageJson.version = "0.1.0"; 102 + delete packageJson.bin; 103 + // Remove @clack/prompts from dependencies since it's only for the CLI 104 + if (packageJson.dependencies?.["@clack/prompts"]) { 105 + delete packageJson.dependencies["@clack/prompts"]; 106 + } 107 + await Bun.write( 108 + packageJsonPath, 109 + JSON.stringify(packageJson, null, "\t") + "\n", 110 + ); 111 + await setTimeout(200); 112 + s.stop("Configured package.json"); 113 + 114 + // Initialize git 115 + s.start("Initializing git repository"); 116 + await $`cd ${targetDir} && git init`.quiet(); 117 + await setTimeout(200); 118 + s.stop("Initialized git repository"); 119 + 120 + // Create .env 121 + s.start("Creating .env file"); 122 + await $`cd ${targetDir} && cp .env.example .env`.quiet(); 123 + await setTimeout(200); 124 + s.stop("Created .env file"); 125 + 126 + // Install dependencies 127 + s.start("Installing dependencies"); 128 + await $`cd ${targetDir} && bun install`.quiet(); 129 + s.stop("Installed dependencies"); 130 + 131 + // Setup database 132 + s.start("Setting up database"); 133 + await $`cd ${targetDir} && bun run db:push`.quiet(); 134 + s.stop("Set up database"); 135 + } catch (error) { 136 + s.stop("Failed"); 137 + p.cancel( 138 + `Error: ${error instanceof Error ? error.message : "Unknown error"}`, 139 + ); 140 + process.exit(1); 141 + } 142 + 143 + p.outro("🎉 Project created successfully!"); 144 + 145 + p.note(`cd ${projectName}\nbun dev`, "Next steps"); 144 146 } 145 147 146 148 main().catch((error) => { 147 - console.error(error); 148 - process.exit(1); 149 + console.error(error); 150 + process.exit(1); 149 151 });
+1 -1
package.json
··· 1 1 { 2 2 "name": "tacy-stack", 3 - "version": "0.1.1", 3 + "version": "0.1.2", 4 4 "module": "src/index.ts", 5 5 "type": "module", 6 6 "bin": {