create-better-t-stack 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +316 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Create Better-T-Stack
|
|
2
|
+
|
|
3
|
+
A CLI tool to scaffold Better-T Stack projects with best practices and modern tooling.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 Quick project setup with one command
|
|
8
|
+
- 📦 TypeScript/JavaScript support
|
|
9
|
+
- 🗄️ Database options (libSQL/PostgreSQL)
|
|
10
|
+
- 🔒 Optional authentication setup
|
|
11
|
+
- 🐳 Docker configuration
|
|
12
|
+
- 🔄 GitHub Actions workflows
|
|
13
|
+
- 🎯 SEO optimization
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Using npm
|
|
19
|
+
npx create-better-t my-app
|
|
20
|
+
|
|
21
|
+
# Using bun
|
|
22
|
+
bunx create-better-t my-app
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Just follow the interactive prompts!
|
|
26
|
+
|
|
27
|
+
## Options
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
Usage: create-better-t [project-directory] [options]
|
|
31
|
+
|
|
32
|
+
Options:
|
|
33
|
+
--typescript Use TypeScript (default)
|
|
34
|
+
--javascript Use JavaScript
|
|
35
|
+
--git Initialize git repository (default)
|
|
36
|
+
--no-git Skip git initialization
|
|
37
|
+
-h, --help Display help
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Project Structure
|
|
41
|
+
|
|
42
|
+
The generated project follows the Better-T Stack architecture:
|
|
43
|
+
- Built with Bun
|
|
44
|
+
- Type-safe database with DrizzleORM
|
|
45
|
+
- Simple authentication system
|
|
46
|
+
- Modern development practices
|
|
47
|
+
|
|
48
|
+
## Development
|
|
49
|
+
|
|
50
|
+
To contribute to this CLI:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Clone the repository
|
|
54
|
+
git clone https://github.com/your-username/better-t-stack-cli.git
|
|
55
|
+
|
|
56
|
+
# Install dependencies
|
|
57
|
+
bun install
|
|
58
|
+
|
|
59
|
+
# Start development
|
|
60
|
+
bun dev
|
|
61
|
+
|
|
62
|
+
# Build
|
|
63
|
+
bun run build
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## License
|
|
67
|
+
|
|
68
|
+
MIT
|
|
69
|
+
|
|
70
|
+
## Credits
|
|
71
|
+
|
|
72
|
+
Developed by Nitish Singh & Aman Varshney – Built on top of the Better-T Stack by [Aman Varshney](https://github.com/AmanVarshney01/Better-T-Stack)
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { checkbox, confirm as confirm2, input as input2, select } from "@inquirer/prompts";
|
|
5
|
+
import chalk2 from "chalk";
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
|
|
8
|
+
// src/create-project.ts
|
|
9
|
+
import path2 from "node:path";
|
|
10
|
+
import { execa as execa2 } from "execa";
|
|
11
|
+
import fs2 from "fs-extra";
|
|
12
|
+
import ora2 from "ora";
|
|
13
|
+
|
|
14
|
+
// src/helpers/db-setup.ts
|
|
15
|
+
import os from "node:os";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { confirm, input } from "@inquirer/prompts";
|
|
18
|
+
import { execa } from "execa";
|
|
19
|
+
import fs from "fs-extra";
|
|
20
|
+
import ora from "ora";
|
|
21
|
+
|
|
22
|
+
// src/utils/logger.ts
|
|
23
|
+
import chalk from "chalk";
|
|
24
|
+
var logger = {
|
|
25
|
+
error(...args) {
|
|
26
|
+
console.log(chalk.red(...args));
|
|
27
|
+
},
|
|
28
|
+
warn(...args) {
|
|
29
|
+
console.log(chalk.yellow(...args));
|
|
30
|
+
},
|
|
31
|
+
info(...args) {
|
|
32
|
+
console.log(chalk.cyan(...args));
|
|
33
|
+
},
|
|
34
|
+
success(...args) {
|
|
35
|
+
console.log(chalk.green(...args));
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/helpers/db-setup.ts
|
|
40
|
+
async function isTursoInstalled() {
|
|
41
|
+
try {
|
|
42
|
+
await execa("turso", ["--version"]);
|
|
43
|
+
return true;
|
|
44
|
+
} catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function isTursoLoggedIn() {
|
|
49
|
+
try {
|
|
50
|
+
await execa("turso", ["auth", "whoami"]);
|
|
51
|
+
return true;
|
|
52
|
+
} catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function installTursoCLI(isMac, spinner) {
|
|
57
|
+
try {
|
|
58
|
+
if (await isTursoLoggedIn()) {
|
|
59
|
+
spinner.succeed("Turso CLI already logged in!");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
spinner.start("Installing Turso CLI...");
|
|
63
|
+
if (isMac) {
|
|
64
|
+
await execa("brew", ["install", "tursodatabase/tap/turso"]);
|
|
65
|
+
} else {
|
|
66
|
+
const installScript = await execa("curl", [
|
|
67
|
+
"-sSfL",
|
|
68
|
+
"https://get.tur.so/install.sh"
|
|
69
|
+
]);
|
|
70
|
+
await execa("bash", [], { input: installScript.stdout });
|
|
71
|
+
}
|
|
72
|
+
spinner.succeed("Turso CLI installed successfully!");
|
|
73
|
+
spinner.start("Logging in to Turso...");
|
|
74
|
+
await execa("turso", ["auth", "login"]);
|
|
75
|
+
spinner.succeed("Logged in to Turso!");
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (error instanceof Error && error.message.includes("User force closed")) {
|
|
78
|
+
spinner.stop();
|
|
79
|
+
console.log("\n");
|
|
80
|
+
logger.warn("Turso CLI installation cancelled by user");
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
logger.error("Error during Turso CLI installation:", error);
|
|
84
|
+
spinner.fail(
|
|
85
|
+
"Failed to install Turso CLI. Proceeding with manual setup..."
|
|
86
|
+
);
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function setupTurso(projectDir) {
|
|
91
|
+
const spinner = ora();
|
|
92
|
+
const platform = os.platform();
|
|
93
|
+
const isMac = platform === "darwin";
|
|
94
|
+
let canInstallCLI = platform !== "win32";
|
|
95
|
+
let installTurso = true;
|
|
96
|
+
const isCliInstalled = await isTursoInstalled();
|
|
97
|
+
if (canInstallCLI && !isCliInstalled) {
|
|
98
|
+
installTurso = await confirm({
|
|
99
|
+
message: "Would you like to install Turso CLI?",
|
|
100
|
+
default: true
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
canInstallCLI = canInstallCLI && installTurso;
|
|
104
|
+
if (canInstallCLI) {
|
|
105
|
+
try {
|
|
106
|
+
await installTursoCLI(isMac, spinner);
|
|
107
|
+
const defaultDbName = path.basename(projectDir);
|
|
108
|
+
const dbName = await input({
|
|
109
|
+
message: `Enter database name (default: ${defaultDbName}):`,
|
|
110
|
+
default: defaultDbName
|
|
111
|
+
});
|
|
112
|
+
spinner.start(`Creating Turso database "${dbName}"...`);
|
|
113
|
+
await execa("turso", ["db", "create", dbName]);
|
|
114
|
+
const { stdout: dbUrl } = await execa("turso", [
|
|
115
|
+
"db",
|
|
116
|
+
"show",
|
|
117
|
+
dbName,
|
|
118
|
+
"--url"
|
|
119
|
+
]);
|
|
120
|
+
const { stdout: authToken } = await execa("turso", [
|
|
121
|
+
"db",
|
|
122
|
+
"tokens",
|
|
123
|
+
"create",
|
|
124
|
+
dbName
|
|
125
|
+
]);
|
|
126
|
+
const envPath = path.join(projectDir, "packages/server", ".env");
|
|
127
|
+
const envContent = `TURSO_DATABASE_URL="${dbUrl.trim()}"
|
|
128
|
+
TURSO_AUTH_TOKEN="${authToken.trim()}"`;
|
|
129
|
+
await fs.writeFile(envPath, envContent);
|
|
130
|
+
spinner.succeed("Turso database configured successfully!");
|
|
131
|
+
return;
|
|
132
|
+
} catch (error) {
|
|
133
|
+
logger.error("Error during Turso database creation:", error);
|
|
134
|
+
spinner.fail(
|
|
135
|
+
"Failed to install Turso CLI. Proceeding with manual setup..."
|
|
136
|
+
);
|
|
137
|
+
installTurso = false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (!installTurso) {
|
|
141
|
+
const envPath = path.join(projectDir, "packages/server", ".env");
|
|
142
|
+
const envContent = `TURSO_DATABASE_URL=
|
|
143
|
+
TURSO_AUTH_TOKEN=`;
|
|
144
|
+
await fs.writeFile(envPath, envContent);
|
|
145
|
+
logger.info("\n\u{1F4DD} Manual Turso Setup Instructions:");
|
|
146
|
+
logger.info("1. Visit https://turso.tech and create an account");
|
|
147
|
+
logger.info("2. Create a new database from the dashboard");
|
|
148
|
+
logger.info("3. Get your database URL and authentication token");
|
|
149
|
+
logger.info(
|
|
150
|
+
"4. Add these credentials to the .env file in your project root"
|
|
151
|
+
);
|
|
152
|
+
logger.info("\nThe .env file has been created with placeholder variables:");
|
|
153
|
+
logger.info("TURSO_DATABASE_URL=your_database_url");
|
|
154
|
+
logger.info("TURSO_AUTH_TOKEN=your_auth_token");
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/create-project.ts
|
|
159
|
+
async function createProject(options) {
|
|
160
|
+
const spinner = ora2("Creating project directory...").start();
|
|
161
|
+
const projectDir = path2.resolve(process.cwd(), options.projectName);
|
|
162
|
+
try {
|
|
163
|
+
await fs2.ensureDir(projectDir);
|
|
164
|
+
spinner.succeed();
|
|
165
|
+
spinner.start("Cloning template repository...");
|
|
166
|
+
await execa2("npx", [
|
|
167
|
+
"degit",
|
|
168
|
+
"https://github.com/AmanVarshney01/Better-T-Stack.git",
|
|
169
|
+
projectDir
|
|
170
|
+
]);
|
|
171
|
+
spinner.succeed();
|
|
172
|
+
if (options.git) {
|
|
173
|
+
spinner.start("Initializing git repository...");
|
|
174
|
+
await execa2("git", ["init"], { cwd: projectDir });
|
|
175
|
+
spinner.succeed();
|
|
176
|
+
}
|
|
177
|
+
spinner.start("Installing dependencies...");
|
|
178
|
+
await execa2("bun", ["install"], { cwd: projectDir });
|
|
179
|
+
spinner.succeed();
|
|
180
|
+
if (options.database === "libsql") {
|
|
181
|
+
await setupTurso(projectDir);
|
|
182
|
+
}
|
|
183
|
+
logger.success("\n\u2728 Project created successfully!\n");
|
|
184
|
+
logger.info("Next steps:");
|
|
185
|
+
logger.info(` cd ${options.projectName}`);
|
|
186
|
+
logger.info(" bun dev");
|
|
187
|
+
} catch (error) {
|
|
188
|
+
spinner.fail("Failed to create project");
|
|
189
|
+
logger.error("Error during project creation:", error);
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// src/render-title.ts
|
|
195
|
+
import gradient from "gradient-string";
|
|
196
|
+
|
|
197
|
+
// src/consts.ts
|
|
198
|
+
var TITLE_TEXT = `
|
|
199
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
200
|
+
\u2551 \u2551
|
|
201
|
+
\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2551
|
|
202
|
+
\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2551
|
|
203
|
+
\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2551
|
|
204
|
+
\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2551
|
|
205
|
+
\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2551
|
|
206
|
+
\u2551 \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u2551
|
|
207
|
+
\u2551 \u2551
|
|
208
|
+
\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2551
|
|
209
|
+
\u2551 \u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2554\u255D \u2551
|
|
210
|
+
\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2551
|
|
211
|
+
\u2551 \u2588\u2588\u2551 \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2588\u2588\u2557 \u2551
|
|
212
|
+
\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2557 \u2551
|
|
213
|
+
\u2551 \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u2551
|
|
214
|
+
\u2551 \u2551
|
|
215
|
+
\u2551 The Modern Full-Stack Framework \u2551
|
|
216
|
+
\u2551 \u2551
|
|
217
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
218
|
+
`;
|
|
219
|
+
|
|
220
|
+
// src/render-title.ts
|
|
221
|
+
var catppuccinTheme = {
|
|
222
|
+
rosewater: "#F5E0DC",
|
|
223
|
+
flamingo: "#F2CDCD",
|
|
224
|
+
pink: "#F5C2E7",
|
|
225
|
+
mauve: "#CBA6F7",
|
|
226
|
+
red: "#F38BA8",
|
|
227
|
+
maroon: "#E78284",
|
|
228
|
+
peach: "#FAB387",
|
|
229
|
+
yellow: "#F9E2AF",
|
|
230
|
+
green: "#A6E3A1",
|
|
231
|
+
teal: "#94E2D5",
|
|
232
|
+
sky: "#89DCEB",
|
|
233
|
+
sapphire: "#74C7EC",
|
|
234
|
+
lavender: "#B4BEFE"
|
|
235
|
+
};
|
|
236
|
+
var renderTitle = () => {
|
|
237
|
+
const catppuccinGradient = gradient(Object.values(catppuccinTheme));
|
|
238
|
+
console.log(catppuccinGradient.multiline(TITLE_TEXT));
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
// src/index.ts
|
|
242
|
+
var program = new Command();
|
|
243
|
+
async function main() {
|
|
244
|
+
try {
|
|
245
|
+
renderTitle();
|
|
246
|
+
console.log(chalk2.bold("\n\u{1F680} Creating a new Better-T Stack project...\n"));
|
|
247
|
+
const projectName = await input2({
|
|
248
|
+
message: "Project name:",
|
|
249
|
+
default: "my-better-t-app"
|
|
250
|
+
});
|
|
251
|
+
const database = await select({
|
|
252
|
+
message: chalk2.cyan("Select database:"),
|
|
253
|
+
choices: [
|
|
254
|
+
{
|
|
255
|
+
value: "libsql",
|
|
256
|
+
name: "libSQL",
|
|
257
|
+
description: chalk2.dim(
|
|
258
|
+
"(Recommended) - Turso's embedded SQLite database"
|
|
259
|
+
)
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
value: "postgres",
|
|
263
|
+
name: "PostgreSQL",
|
|
264
|
+
description: chalk2.dim("Traditional relational database")
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
});
|
|
268
|
+
const auth = await confirm2({
|
|
269
|
+
message: "Add authentication with Better-Auth?",
|
|
270
|
+
default: true
|
|
271
|
+
});
|
|
272
|
+
const features = await checkbox({
|
|
273
|
+
message: chalk2.cyan("Select additional features:"),
|
|
274
|
+
choices: [
|
|
275
|
+
{
|
|
276
|
+
value: "docker",
|
|
277
|
+
name: "Docker setup",
|
|
278
|
+
description: chalk2.dim("Containerize your application")
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
value: "github-actions",
|
|
282
|
+
name: "GitHub Actions",
|
|
283
|
+
description: chalk2.dim("CI/CD workflows")
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
value: "SEO",
|
|
287
|
+
name: "Basic SEO setup",
|
|
288
|
+
description: chalk2.dim("Search engine optimization configuration")
|
|
289
|
+
}
|
|
290
|
+
]
|
|
291
|
+
});
|
|
292
|
+
const projectOptions = {
|
|
293
|
+
projectName,
|
|
294
|
+
git: true,
|
|
295
|
+
database,
|
|
296
|
+
auth,
|
|
297
|
+
features
|
|
298
|
+
};
|
|
299
|
+
await createProject(projectOptions);
|
|
300
|
+
} catch (error) {
|
|
301
|
+
if (error instanceof Error && error.message.includes("User force closed")) {
|
|
302
|
+
console.log("\n");
|
|
303
|
+
logger.warn("Operation cancelled by user");
|
|
304
|
+
process.exit(0);
|
|
305
|
+
}
|
|
306
|
+
logger.error("An unexpected error occurred:", error);
|
|
307
|
+
process.exit(1);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
process.on("SIGINT", () => {
|
|
311
|
+
console.log("\n");
|
|
312
|
+
logger.warn("Operation cancelled by user");
|
|
313
|
+
process.exit(0);
|
|
314
|
+
});
|
|
315
|
+
program.name("create-better-t-stack").description("Create a new Better-T Stack project").version("1.0.0").action(main);
|
|
316
|
+
program.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-better-t-stack",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI tool to scaffold Better-T Stack projects",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"bin": {
|
|
8
|
+
"create-better-t-stack": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsup",
|
|
13
|
+
"dev": "tsup --watch",
|
|
14
|
+
"check-types": "tsc --noEmit",
|
|
15
|
+
"check": "biome check --write .",
|
|
16
|
+
"test": "vitest run",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"files": ["dist", "templates"],
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@inquirer/prompts": "^7.3.1",
|
|
22
|
+
"chalk": "^5.3.0",
|
|
23
|
+
"commander": "^13.1.0",
|
|
24
|
+
"execa": "^8.0.1",
|
|
25
|
+
"fs-extra": "^11.2.0",
|
|
26
|
+
"gradient-string": "^3.0.0",
|
|
27
|
+
"ora": "^7.0.1"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/fs-extra": "^11.0.4",
|
|
31
|
+
"@types/inquirer": "^9.0.7",
|
|
32
|
+
"@types/node": "^20.10.5",
|
|
33
|
+
"tsup": "^8.0.1",
|
|
34
|
+
"typescript": "^5.3.3",
|
|
35
|
+
"vitest": "^1.1.0"
|
|
36
|
+
}
|
|
37
|
+
}
|