@grupodiariodaregiao/bunstone 0.2.2 → 0.2.4

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/bin/cli.ts CHANGED
@@ -1,240 +1,86 @@
1
1
  #!/usr/bin/env bun
2
- import { mkdir, writeFile } from "node:fs/promises";
2
+ import {
3
+ copyFile,
4
+ mkdir as fsMkdir,
5
+ readdir,
6
+ readFile,
7
+ writeFile,
8
+ } from "node:fs/promises";
3
9
  import { join } from "node:path";
4
- import { execSync } from "node:child_process";
10
+ import { cwd } from "../lib/utils/cwd";
5
11
 
6
- const args = process.argv.slice(2);
12
+ const args = Bun.argv.slice(2);
7
13
  let command = args[0];
8
14
  let projectName = args[1];
9
15
 
10
16
  // Default to "new" command if only project name is provided
11
17
  if (command && command !== "new" && !projectName) {
12
- projectName = command;
13
- command = "new";
18
+ projectName = command;
19
+ command = "new";
14
20
  }
15
21
 
16
22
  // Default project name if none provided
17
23
  if (!projectName && command === "new") {
18
- projectName = "my-bunstone-app";
24
+ projectName = "my-bunstone-app";
19
25
  }
20
26
 
21
- const projectPath = join(process.cwd(), projectName || "");
27
+ const projectPath = join(cwd(), projectName || "");
28
+ const starterPath = join(import.meta.dir, "..", "starter");
22
29
 
23
- async function scaffold() {
24
- if (command !== "new" || !projectName) {
25
- console.log("Usage: bunstone new <project-name>");
26
- console.log(" or: bunstone <project-name>");
27
- process.exit(1);
28
- }
29
-
30
- console.log(`šŸš€ Scaffolding new Bunstone project in ${projectPath}...`);
31
-
32
- try {
33
- await mkdir(projectPath, { recursive: true });
34
- await mkdir(join(projectPath, "src"), { recursive: true });
35
- await mkdir(join(projectPath, "src/controllers"), { recursive: true });
36
- await mkdir(join(projectPath, "src/services"), { recursive: true });
37
- await mkdir(join(projectPath, "src/views"), { recursive: true });
38
-
39
- // package.json
40
- const pkg = {
41
- name: projectName,
42
- version: "1.0.0",
43
- main: "src/main.ts",
44
- type: "module",
45
- scripts: {
46
- start: "bun run src/main.ts",
47
- dev: "bun --watch src/main.ts",
48
- test: "bun test",
49
- },
50
- dependencies: {
51
- "@elysiajs/html": "^1.4.0",
52
- "@grupodiariodaregiao/bunstone": "latest",
53
- "reflect-metadata": "^0.2.2",
54
- react: "^19.0.0",
55
- "react-dom": "^19.0.0",
56
- zod: "^4.3.2",
57
- },
58
- devDependencies: {
59
- "@types/bun": "latest",
60
- "@types/react": "^19.0.0",
61
- "@types/react-dom": "^19.0.0",
62
- },
63
- };
64
-
65
- await writeFile(
66
- join(projectPath, "package.json"),
67
- JSON.stringify(pkg, null, 2)
68
- );
69
-
70
- // tsconfig.json
71
- const tsconfig = {
72
- compilerOptions: {
73
- lib: ["ESNext"],
74
- module: "esnext",
75
- target: "esnext",
76
- moduleResolution: "bundler",
77
- moduleDetection: "force",
78
- allowImportingTsExtensions: true,
79
- noEmit: true,
80
- composite: true,
81
- strict: true,
82
- downlevelIteration: true,
83
- skipLibCheck: true,
84
- jsx: "react-jsx",
85
- jsxImportSource: "react",
86
- allowSyntheticDefaultImports: true,
87
- forceConsistentCasingInFileNames: true,
88
- allowJs: true,
89
- types: ["bun-types"],
90
- experimentalDecorators: true,
91
- emitDecoratorMetadata: true,
92
- baseUrl: ".",
93
- paths: {
94
- "@/*": ["./src/*"],
95
- },
96
- },
97
- };
98
-
99
- await writeFile(
100
- join(projectPath, "tsconfig.json"),
101
- JSON.stringify(tsconfig, null, 2)
102
- );
103
-
104
- // src/main.ts
105
- const mainTs = `import { AppStartup } from "@grupodiariodaregiao/bunstone";
106
- import { AppModule } from "@/app.module";
107
-
108
- async function bootstrap() {
109
- const app = AppStartup.create(AppModule);
110
- app.listen(3000);
111
- }
112
- bootstrap();
113
- `;
114
-
115
- await writeFile(join(projectPath, "src/main.ts"), mainTs);
116
-
117
- // src/app.module.ts
118
- const appModuleTs = `import { Module } from "@grupodiariodaregiao/bunstone";
119
- import { AppController } from "@/controllers/app.controller";
120
- import { AppService } from "@/services/app.service";
121
-
122
- @Module({
123
- controllers: [AppController],
124
- providers: [AppService],
125
- })
126
- export class AppModule {}
127
- `;
128
-
129
- await writeFile(join(projectPath, "src/app.module.ts"), appModuleTs);
130
-
131
- // src/controllers/app.controller.ts
132
- const controllerTs = `import { Controller, Get, Render } from "@grupodiariodaregiao/bunstone";
133
- import { AppService } from "@/services/app.service";
134
- import { Welcome } from "@/views/Welcome";
135
-
136
- @Controller()
137
- export class AppController {
138
- constructor(private readonly appService: AppService) {}
30
+ async function copyDir(src: string, dest: string) {
31
+ await fsMkdir(dest, { recursive: true });
32
+ const entries = await readdir(src, { withFileTypes: true });
139
33
 
140
- @Get()
141
- @Render(Welcome)
142
- getHello() {
143
- return this.appService.getHello();
144
- }
145
- }
146
- `;
147
-
148
- await writeFile(
149
- join(projectPath, "src/controllers/app.controller.ts"),
150
- controllerTs
151
- );
34
+ for (const entry of entries) {
35
+ const srcPath = join(src, entry.name);
36
+ const destPath = join(dest, entry.name);
152
37
 
153
- // src/services/app.service.ts
154
- const serviceTs = `import { Injectable } from "@grupodiariodaregiao/bunstone";
155
-
156
- @Injectable()
157
- export class AppService {
158
- getHello() {
159
- return {
160
- message: "Hello from Bunstone!",
161
- timestamp: new Date().toISOString()
162
- };
163
- }
38
+ if (entry.isDirectory()) {
39
+ await copyDir(srcPath, destPath);
40
+ } else {
41
+ await copyFile(srcPath, destPath);
42
+ }
43
+ }
164
44
  }
165
- `;
166
-
167
- await writeFile(
168
- join(projectPath, "src/services/app.service.ts"),
169
- serviceTs
170
- );
171
-
172
- // src/main.ts
173
- const mainTsContent = `import "reflect-metadata";
174
- import { AppStartup } from "@grupodiariodaregiao/bunstone";
175
- import { AppModule } from "@/app.module";
176
-
177
- const app = AppStartup.create(AppModule, {
178
- viewsDir: "src/views"
179
- });
180
-
181
- app.listen(3000);
182
- `;
183
-
184
- await writeFile(join(projectPath, "src/main.ts"), mainTsContent);
185
45
 
186
- // src/views/Welcome.tsx
187
- const welcomeTsx = `import React, { useState } from "react";
188
-
189
- export const Welcome = ({ message, timestamp }: { message: string, timestamp: string }) => {
190
- const [count, setCount] = useState(0);
191
-
192
- return (
193
- <div className="max-w-md mx-auto mt-10 p-6 bg-white rounded-xl shadow-md border border-gray-200 text-center">
194
- <h1 className="text-3xl font-bold text-indigo-600 mb-2">Bunstone MVC</h1>
195
- <p className="text-gray-600 mb-6">{message}</p>
196
-
197
- <div className="bg-indigo-50 p-4 rounded-lg mb-6">
198
- <p className="text-sm text-indigo-400 mb-2 font-mono">Interactive Hooks Example</p>
199
- <div className="flex items-center justify-center gap-4">
200
- <button
201
- onClick={() => setCount(count - 1)}
202
- className="bg-white border border-indigo-200 px-3 py-1 rounded shadow-sm hover:bg-indigo-100"
203
- >-</button>
204
- <span className="text-2xl font-mono font-bold text-indigo-700 min-w-[2ch]">{count}</span>
205
- <button
206
- onClick={() => setCount(count + 1)}
207
- className="bg-white border border-indigo-200 px-3 py-1 rounded shadow-sm hover:bg-indigo-100"
208
- >+</button>
209
- </div>
210
- </div>
211
-
212
- <p className="text-gray-400 text-xs italic">Server time: {timestamp}</p>
213
- </div>
214
- );
215
- };
216
- `;
217
-
218
- await writeFile(join(projectPath, "src/views/Welcome.tsx"), welcomeTsx);
219
-
220
- // .gitignore
221
- await writeFile(
222
- join(projectPath, ".gitignore"),
223
- "node_modules\n.DS_Store\ndist\n.env\n.bunstone\n"
224
- );
225
-
226
- console.log("šŸ“¦ Installing dependencies...");
227
- try {
228
- execSync("bun install", { cwd: projectPath, stdio: "inherit" });
229
- } catch (e) {
230
- console.warn("āš ļø Could not run 'bun install'. Please run it manually.");
231
- }
232
-
233
- console.log("\nāœ… Project created successfully!");
234
- console.log("\nNext steps:\n cd " + projectName + "\n bun dev\n");
235
- } catch (error) {
236
- console.error("āŒ Error scaffolding project:", error);
237
- }
46
+ async function scaffold() {
47
+ if (command !== "new" || !projectName) {
48
+ console.log("Usage: bunstone new <project-name>");
49
+ console.log(" or: bunstone <project-name>");
50
+ process.exit(1);
51
+ }
52
+
53
+ console.log(`šŸš€ Scaffolding new Bunstone project in ${projectPath}...`);
54
+
55
+ try {
56
+ // Copy the entire starter directory
57
+ await copyDir(starterPath, projectPath);
58
+
59
+ // Update package.json name
60
+ const pkgPath = join(projectPath, "package.json");
61
+ const pkgContent = await readFile(pkgPath, "utf-8");
62
+ const pkg = JSON.parse(pkgContent);
63
+ pkg.name = projectName;
64
+ await writeFile(pkgPath, JSON.stringify(pkg, null, 2));
65
+
66
+ console.log("šŸ“¦ Installing dependencies...");
67
+ try {
68
+ const installProc = Bun.spawn({
69
+ cmd: ["bun", "install"],
70
+ cwd: projectPath,
71
+ stdout: "inherit",
72
+ stderr: "inherit",
73
+ });
74
+ await installProc.exited;
75
+ } catch (_e) {
76
+ console.warn("āš ļø Could not run 'bun install'. Please run it manually.");
77
+ }
78
+
79
+ console.log("\nāœ… Project created successfully!");
80
+ console.log(`\nNext steps:\n cd ${projectName}\n bun dev\n`);
81
+ } catch (error) {
82
+ console.error("āŒ Error scaffolding project:", error);
83
+ }
238
84
  }
239
85
 
240
86
  scaffold();