@buenojs/bueno 0.8.3 → 0.8.5

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.
Files changed (218) hide show
  1. package/README.md +136 -16
  2. package/dist/cli/{index.js → bin.js} +3036 -1421
  3. package/dist/container/index.js +250 -0
  4. package/dist/context/index.js +219 -0
  5. package/dist/database/index.js +493 -0
  6. package/dist/frontend/index.js +7697 -0
  7. package/dist/health/index.js +364 -0
  8. package/dist/i18n/index.js +345 -0
  9. package/dist/index.js +11043 -6482
  10. package/dist/jobs/index.js +819 -0
  11. package/dist/lock/index.js +367 -0
  12. package/dist/logger/index.js +281 -0
  13. package/dist/metrics/index.js +289 -0
  14. package/dist/middleware/index.js +77 -0
  15. package/dist/migrations/index.js +571 -0
  16. package/dist/modules/index.js +3346 -0
  17. package/dist/notification/index.js +484 -0
  18. package/dist/observability/index.js +331 -0
  19. package/dist/openapi/index.js +776 -0
  20. package/dist/orm/index.js +1356 -0
  21. package/dist/router/index.js +886 -0
  22. package/dist/rpc/index.js +691 -0
  23. package/dist/schema/index.js +400 -0
  24. package/dist/telemetry/index.js +595 -0
  25. package/dist/template/index.js +640 -0
  26. package/dist/templates/index.js +640 -0
  27. package/dist/testing/index.js +1111 -0
  28. package/dist/types/index.js +60 -0
  29. package/package.json +121 -27
  30. package/src/cache/index.ts +2 -1
  31. package/src/cli/bin.ts +2 -2
  32. package/src/cli/commands/build.ts +183 -165
  33. package/src/cli/commands/dev.ts +96 -89
  34. package/src/cli/commands/generate.ts +142 -111
  35. package/src/cli/commands/help.ts +20 -16
  36. package/src/cli/commands/index.ts +3 -6
  37. package/src/cli/commands/migration.ts +124 -105
  38. package/src/cli/commands/new.ts +392 -438
  39. package/src/cli/commands/start.ts +81 -79
  40. package/src/cli/core/args.ts +68 -50
  41. package/src/cli/core/console.ts +89 -95
  42. package/src/cli/core/index.ts +4 -4
  43. package/src/cli/core/prompt.ts +65 -62
  44. package/src/cli/core/spinner.ts +23 -20
  45. package/src/cli/index.ts +46 -38
  46. package/src/cli/templates/database/index.ts +61 -0
  47. package/src/cli/templates/database/mysql.ts +14 -0
  48. package/src/cli/templates/database/none.ts +16 -0
  49. package/src/cli/templates/database/postgresql.ts +14 -0
  50. package/src/cli/templates/database/sqlite.ts +14 -0
  51. package/src/cli/templates/deploy.ts +29 -26
  52. package/src/cli/templates/docker.ts +41 -30
  53. package/src/cli/templates/frontend/index.ts +63 -0
  54. package/src/cli/templates/frontend/none.ts +17 -0
  55. package/src/cli/templates/frontend/react.ts +140 -0
  56. package/src/cli/templates/frontend/solid.ts +134 -0
  57. package/src/cli/templates/frontend/svelte.ts +131 -0
  58. package/src/cli/templates/frontend/vue.ts +130 -0
  59. package/src/cli/templates/generators/index.ts +339 -0
  60. package/src/cli/templates/generators/types.ts +56 -0
  61. package/src/cli/templates/index.ts +35 -2
  62. package/src/cli/templates/project/api.ts +81 -0
  63. package/src/cli/templates/project/default.ts +140 -0
  64. package/src/cli/templates/project/fullstack.ts +111 -0
  65. package/src/cli/templates/project/index.ts +95 -0
  66. package/src/cli/templates/project/minimal.ts +45 -0
  67. package/src/cli/templates/project/types.ts +94 -0
  68. package/src/cli/templates/project/website.ts +263 -0
  69. package/src/cli/utils/fs.ts +55 -41
  70. package/src/cli/utils/index.ts +3 -2
  71. package/src/cli/utils/strings.ts +47 -33
  72. package/src/cli/utils/version.ts +47 -0
  73. package/src/config/env-validation.ts +100 -0
  74. package/src/config/env.ts +169 -41
  75. package/src/config/index.ts +28 -20
  76. package/src/config/loader.ts +25 -16
  77. package/src/config/merge.ts +21 -10
  78. package/src/config/types.ts +545 -25
  79. package/src/config/validation.ts +215 -7
  80. package/src/container/forward-ref.ts +22 -22
  81. package/src/container/index.ts +34 -12
  82. package/src/context/index.ts +11 -1
  83. package/src/database/index.ts +7 -190
  84. package/src/database/orm/builder.ts +457 -0
  85. package/src/database/orm/casts/index.ts +130 -0
  86. package/src/database/orm/casts/types.ts +25 -0
  87. package/src/database/orm/compiler.ts +304 -0
  88. package/src/database/orm/hooks/index.ts +114 -0
  89. package/src/database/orm/index.ts +61 -0
  90. package/src/database/orm/model-registry.ts +59 -0
  91. package/src/database/orm/model.ts +821 -0
  92. package/src/database/orm/relationships/base.ts +146 -0
  93. package/src/database/orm/relationships/belongs-to-many.ts +179 -0
  94. package/src/database/orm/relationships/belongs-to.ts +56 -0
  95. package/src/database/orm/relationships/has-many.ts +45 -0
  96. package/src/database/orm/relationships/has-one.ts +41 -0
  97. package/src/database/orm/relationships/index.ts +11 -0
  98. package/src/database/orm/scopes/index.ts +55 -0
  99. package/src/events/__tests__/event-system.test.ts +235 -0
  100. package/src/events/config.ts +238 -0
  101. package/src/events/example-usage.ts +185 -0
  102. package/src/events/index.ts +278 -0
  103. package/src/events/manager.ts +385 -0
  104. package/src/events/registry.ts +182 -0
  105. package/src/events/types.ts +124 -0
  106. package/src/frontend/api-routes.ts +65 -23
  107. package/src/frontend/bundler.ts +76 -34
  108. package/src/frontend/console-client.ts +2 -2
  109. package/src/frontend/console-stream.ts +94 -38
  110. package/src/frontend/dev-server.ts +94 -46
  111. package/src/frontend/file-router.ts +61 -19
  112. package/src/frontend/frameworks/index.ts +37 -10
  113. package/src/frontend/frameworks/react.ts +10 -8
  114. package/src/frontend/frameworks/solid.ts +11 -9
  115. package/src/frontend/frameworks/svelte.ts +15 -9
  116. package/src/frontend/frameworks/vue.ts +13 -11
  117. package/src/frontend/hmr-client.ts +12 -10
  118. package/src/frontend/hmr.ts +146 -103
  119. package/src/frontend/index.ts +14 -5
  120. package/src/frontend/islands.ts +41 -22
  121. package/src/frontend/isr.ts +59 -37
  122. package/src/frontend/layout.ts +36 -21
  123. package/src/frontend/ssr/react.ts +74 -27
  124. package/src/frontend/ssr/solid.ts +54 -20
  125. package/src/frontend/ssr/svelte.ts +48 -14
  126. package/src/frontend/ssr/vue.ts +50 -18
  127. package/src/frontend/ssr.ts +83 -39
  128. package/src/frontend/types.ts +91 -56
  129. package/src/health/index.ts +21 -9
  130. package/src/i18n/engine.ts +305 -0
  131. package/src/i18n/index.ts +38 -0
  132. package/src/i18n/loader.ts +218 -0
  133. package/src/i18n/middleware.ts +164 -0
  134. package/src/i18n/negotiator.ts +162 -0
  135. package/src/i18n/types.ts +158 -0
  136. package/src/index.ts +179 -27
  137. package/src/jobs/drivers/memory.ts +315 -0
  138. package/src/jobs/drivers/redis.ts +459 -0
  139. package/src/jobs/index.ts +30 -0
  140. package/src/jobs/queue.ts +281 -0
  141. package/src/jobs/types.ts +295 -0
  142. package/src/jobs/worker.ts +380 -0
  143. package/src/logger/index.ts +1 -3
  144. package/src/logger/transports/index.ts +62 -22
  145. package/src/metrics/index.ts +25 -16
  146. package/src/migrations/index.ts +9 -0
  147. package/src/modules/filters.ts +13 -17
  148. package/src/modules/guards.ts +49 -26
  149. package/src/modules/index.ts +409 -298
  150. package/src/modules/interceptors.ts +58 -20
  151. package/src/modules/lazy.ts +11 -19
  152. package/src/modules/lifecycle.ts +15 -7
  153. package/src/modules/metadata.ts +15 -5
  154. package/src/modules/pipes.ts +94 -72
  155. package/src/notification/channels/base.ts +68 -0
  156. package/src/notification/channels/email.ts +105 -0
  157. package/src/notification/channels/push.ts +104 -0
  158. package/src/notification/channels/sms.ts +105 -0
  159. package/src/notification/channels/whatsapp.ts +104 -0
  160. package/src/notification/index.ts +48 -0
  161. package/src/notification/service.ts +354 -0
  162. package/src/notification/types.ts +344 -0
  163. package/src/observability/__tests__/observability.test.ts +483 -0
  164. package/src/observability/breadcrumbs.ts +114 -0
  165. package/src/observability/index.ts +136 -0
  166. package/src/observability/interceptor.ts +85 -0
  167. package/src/observability/service.ts +303 -0
  168. package/src/observability/trace.ts +37 -0
  169. package/src/observability/types.ts +196 -0
  170. package/src/openapi/__tests__/decorators.test.ts +335 -0
  171. package/src/openapi/__tests__/document-builder.test.ts +285 -0
  172. package/src/openapi/__tests__/route-scanner.test.ts +334 -0
  173. package/src/openapi/__tests__/schema-generator.test.ts +275 -0
  174. package/src/openapi/decorators.ts +328 -0
  175. package/src/openapi/document-builder.ts +274 -0
  176. package/src/openapi/index.ts +112 -0
  177. package/src/openapi/metadata.ts +112 -0
  178. package/src/openapi/route-scanner.ts +289 -0
  179. package/src/openapi/schema-generator.ts +256 -0
  180. package/src/openapi/swagger-module.ts +166 -0
  181. package/src/openapi/types.ts +398 -0
  182. package/src/orm/index.ts +10 -0
  183. package/src/rpc/index.ts +3 -1
  184. package/src/schema/index.ts +9 -0
  185. package/src/security/index.ts +15 -6
  186. package/src/ssg/index.ts +9 -8
  187. package/src/telemetry/index.ts +76 -22
  188. package/src/template/index.ts +7 -0
  189. package/src/templates/engine.ts +224 -0
  190. package/src/templates/index.ts +9 -0
  191. package/src/templates/loader.ts +331 -0
  192. package/src/templates/renderers/markdown.ts +212 -0
  193. package/src/templates/renderers/simple.ts +269 -0
  194. package/src/templates/types.ts +154 -0
  195. package/src/testing/index.ts +100 -27
  196. package/src/types/optional-deps.d.ts +347 -187
  197. package/src/validation/index.ts +92 -2
  198. package/src/validation/schemas.ts +536 -0
  199. package/tests/integration/fullstack.test.ts +4 -4
  200. package/tests/unit/database.test.ts +2 -72
  201. package/tests/unit/env-validation.test.ts +166 -0
  202. package/tests/unit/events.test.ts +910 -0
  203. package/tests/unit/i18n.test.ts +455 -0
  204. package/tests/unit/jobs.test.ts +493 -0
  205. package/tests/unit/notification.test.ts +988 -0
  206. package/tests/unit/observability.test.ts +453 -0
  207. package/tests/unit/orm/builder.test.ts +323 -0
  208. package/tests/unit/orm/casts.test.ts +179 -0
  209. package/tests/unit/orm/compiler.test.ts +220 -0
  210. package/tests/unit/orm/eager-loading.test.ts +285 -0
  211. package/tests/unit/orm/hooks.test.ts +191 -0
  212. package/tests/unit/orm/model.test.ts +373 -0
  213. package/tests/unit/orm/relationships.test.ts +303 -0
  214. package/tests/unit/orm/scopes.test.ts +74 -0
  215. package/tests/unit/templates-simple.test.ts +53 -0
  216. package/tests/unit/templates.test.ts +454 -0
  217. package/tests/unit/validation.test.ts +18 -24
  218. package/tsconfig.json +11 -3
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Fullstack Project Template
3
+ */
4
+
5
+ import { noneTemplate } from "../frontend/none";
6
+ import { reactTemplate } from "../frontend/react";
7
+ import { solidTemplate } from "../frontend/solid";
8
+ import { svelteTemplate } from "../frontend/svelte";
9
+ import { vueTemplate } from "../frontend/vue";
10
+ import type { ProjectConfig, ProjectTemplateResult } from "./types";
11
+
12
+ export function fullstackTemplate(
13
+ config: ProjectConfig,
14
+ ): ProjectTemplateResult {
15
+ // Get frontend template based on framework
16
+ const frontendTemplates: Record<string, () => ProjectTemplateResult> = {
17
+ react: reactTemplate,
18
+ vue: vueTemplate,
19
+ svelte: svelteTemplate,
20
+ solid: solidTemplate,
21
+ none: noneTemplate,
22
+ };
23
+
24
+ const frontendTemplate = frontendTemplates[config.framework]
25
+ ? frontendTemplates[config.framework]()
26
+ : reactTemplate();
27
+
28
+ return {
29
+ files: [
30
+ {
31
+ path: "server/main.ts",
32
+ content: `import { createApp, Module, Controller, Get, Post, Injectable } from '@buenojs/bueno';
33
+ import type { Context } from '@buenojs/bueno';
34
+
35
+ // Services
36
+ @Injectable()
37
+ export class AppService {
38
+ findAll() {
39
+ return { message: 'Welcome to Bueno!', items: [] };
40
+ }
41
+ }
42
+
43
+ // Controllers
44
+ @Controller('/api')
45
+ export class AppController {
46
+ constructor(private readonly appService: AppService) {}
47
+
48
+ @Get()
49
+ hello() {
50
+ return { message: 'Welcome to Bueno API!', version: '1.0.0' };
51
+ }
52
+
53
+ @Get('health')
54
+ health(ctx: Context) {
55
+ return { status: 'ok', timestamp: new Date().toISOString() };
56
+ }
57
+ }
58
+
59
+ // Module
60
+ @Module({
61
+ controllers: [AppController],
62
+ providers: [AppService],
63
+ })
64
+ export class AppModule {}
65
+
66
+ // Bootstrap
67
+ const app = createApp(AppModule);
68
+
69
+ // Serve static files in production
70
+ // app.serveStatic('./dist/client');
71
+
72
+ await app.listen(3000);
73
+ console.log('🚀 Server running at http://localhost:3000');
74
+ `,
75
+ },
76
+ // Include frontend files
77
+ ...frontendTemplate.files,
78
+ ],
79
+ directories: [
80
+ "server/modules/app",
81
+ "server/common/middleware",
82
+ "server/common/guards",
83
+ "server/common/interceptors",
84
+ "server/common/pipes",
85
+ "server/common/filters",
86
+ "server/database/migrations",
87
+ "server/config",
88
+ "tests/unit",
89
+ "tests/integration",
90
+ // Include frontend directories
91
+ ...frontendTemplate.directories,
92
+ ],
93
+ dependencies: {
94
+ zod: "^3.24.0",
95
+ // Include frontend dependencies
96
+ ...frontendTemplate.dependencies,
97
+ },
98
+ devDependencies: {
99
+ // Include frontend dev dependencies
100
+ ...frontendTemplate.devDependencies,
101
+ },
102
+ scripts: {
103
+ dev: "bun run --watch server/main.ts",
104
+ build: "bun build ./server/main.ts --outdir ./dist --target bun",
105
+ start: "bun run dist/main.js",
106
+ test: "bun test",
107
+ // Include frontend scripts
108
+ ...frontendTemplate.scripts,
109
+ },
110
+ };
111
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Project Templates
3
+ *
4
+ * Project template registry and exports
5
+ */
6
+
7
+ // Re-export types
8
+ export type {
9
+ ProjectTemplate,
10
+ ProjectConfig,
11
+ ProjectTemplateResult,
12
+ FrontendFramework,
13
+ DatabaseDriver,
14
+ TemplateFile,
15
+ SelectOption,
16
+ } from "./types";
17
+
18
+ import { apiTemplate } from "./api";
19
+ import { defaultTemplate } from "./default";
20
+ import { fullstackTemplate } from "./fullstack";
21
+ import { minimalTemplate } from "./minimal";
22
+ import type {
23
+ ProjectConfig,
24
+ ProjectTemplate,
25
+ ProjectTemplateResult,
26
+ } from "./types";
27
+ import { websiteTemplate } from "./website";
28
+
29
+ /**
30
+ * Project template registry
31
+ */
32
+ const projectTemplates: Record<
33
+ ProjectTemplate,
34
+ (config: ProjectConfig) => ProjectTemplateResult
35
+ > = {
36
+ default: defaultTemplate,
37
+ minimal: minimalTemplate,
38
+ fullstack: fullstackTemplate,
39
+ api: apiTemplate,
40
+ website: websiteTemplate,
41
+ };
42
+
43
+ /**
44
+ * Get project template based on template type
45
+ */
46
+ export function getProjectTemplate(
47
+ template: ProjectTemplate,
48
+ ): (config: ProjectConfig) => ProjectTemplateResult {
49
+ return projectTemplates[template];
50
+ }
51
+
52
+ /**
53
+ * Get template selection options for prompts
54
+ */
55
+ export function getTemplateOptions(): {
56
+ value: ProjectTemplate;
57
+ name: string;
58
+ description: string;
59
+ }[] {
60
+ return [
61
+ {
62
+ value: "default",
63
+ name: "Default",
64
+ description: "Standard project with modules and database",
65
+ },
66
+ {
67
+ value: "minimal",
68
+ name: "Minimal",
69
+ description: "Bare minimum project structure",
70
+ },
71
+ {
72
+ value: "fullstack",
73
+ name: "Fullstack",
74
+ description: "Full-stack project with SSR and frontend",
75
+ },
76
+ {
77
+ value: "api",
78
+ name: "API",
79
+ description: "API-only project without frontend",
80
+ },
81
+ {
82
+ value: "website",
83
+ name: "Website",
84
+ description: "Static website with SSG",
85
+ },
86
+ ];
87
+ }
88
+
89
+ export {
90
+ defaultTemplate,
91
+ minimalTemplate,
92
+ fullstackTemplate,
93
+ apiTemplate,
94
+ websiteTemplate,
95
+ };
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Minimal Project Template
3
+ */
4
+
5
+ import { getBuenoDependency } from "../../utils/version";
6
+ import type { ProjectConfig, ProjectTemplateResult } from "./types";
7
+
8
+ export function minimalTemplate(config: ProjectConfig): ProjectTemplateResult {
9
+ return {
10
+ files: [
11
+ {
12
+ path: "server/main.ts",
13
+ content: `import { createServer } from '@buenojs/bueno';
14
+
15
+ const app = createServer();
16
+
17
+ app.router.get('/', () => {
18
+ return Response.json({ message: 'Hello, Bueno!' });
19
+ });
20
+
21
+ app.router.get('/health', () => {
22
+ return Response.json({ status: 'ok', timestamp: new Date().toISOString() });
23
+ });
24
+
25
+ await app.listen(3000);
26
+ console.log('🚀 Server running at http://localhost:3000');
27
+ `,
28
+ },
29
+ ],
30
+ directories: ["server", "tests"],
31
+ dependencies: {
32
+ ...getBuenoDependency(),
33
+ },
34
+ devDependencies: {
35
+ "@types/bun": "latest",
36
+ typescript: "^5.3.0",
37
+ },
38
+ scripts: {
39
+ dev: "bun run --watch server/main.ts",
40
+ build: "bun build ./server/main.ts --outdir ./dist --target bun",
41
+ start: "bun run dist/main.js",
42
+ test: "bun test",
43
+ },
44
+ };
45
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Project Template Types
3
+ *
4
+ * Type definitions for project scaffolding
5
+ */
6
+
7
+ /**
8
+ * Project templates
9
+ */
10
+ export type ProjectTemplate =
11
+ | "default"
12
+ | "minimal"
13
+ | "fullstack"
14
+ | "api"
15
+ | "website";
16
+
17
+ /**
18
+ * Frontend frameworks
19
+ */
20
+ export type FrontendFramework = "react" | "vue" | "svelte" | "solid" | "none";
21
+
22
+ /**
23
+ * Database drivers
24
+ */
25
+ export type DatabaseDriver = "sqlite" | "postgresql" | "mysql" | "none";
26
+
27
+ /**
28
+ * Deploy platforms
29
+ */
30
+ export type DeployPlatform = "render" | "fly" | "railway";
31
+
32
+ /**
33
+ * Project configuration interface
34
+ */
35
+ export interface ProjectConfig {
36
+ name: string;
37
+ template: ProjectTemplate;
38
+ framework: FrontendFramework;
39
+ database: DatabaseDriver;
40
+ skipInstall: boolean;
41
+ skipGit: boolean;
42
+ docker: boolean;
43
+ deploy: DeployPlatform[];
44
+ link: boolean;
45
+ }
46
+
47
+ /**
48
+ * Template file representation
49
+ */
50
+ export interface TemplateFile {
51
+ path: string;
52
+ content: string;
53
+ }
54
+
55
+ /**
56
+ * Project template result
57
+ */
58
+ export interface ProjectTemplateResult {
59
+ files: TemplateFile[];
60
+ directories: string[];
61
+ dependencies?: Record<string, string>;
62
+ devDependencies?: Record<string, string>;
63
+ scripts?: Record<string, string>;
64
+ }
65
+
66
+ /**
67
+ * Database template result
68
+ */
69
+ export interface DatabaseTemplateResult {
70
+ files: TemplateFile[];
71
+ directories: string[];
72
+ envConfig?: string;
73
+ configCode?: string;
74
+ }
75
+
76
+ /**
77
+ * Frontend template result
78
+ */
79
+ export interface FrontendTemplateResult {
80
+ files: TemplateFile[];
81
+ directories: string[];
82
+ dependencies: Record<string, string>;
83
+ devDependencies: Record<string, string>;
84
+ scripts: Record<string, string>;
85
+ }
86
+
87
+ /**
88
+ * Option for interactive selection
89
+ */
90
+ export interface SelectOption<T> {
91
+ value: T;
92
+ name: string;
93
+ description?: string;
94
+ }
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Website Project Template
3
+ *
4
+ * Static website template using SSG (Static Site Generation)
5
+ */
6
+
7
+ import { getBuenoDependency } from "../../utils/version";
8
+ import type { ProjectConfig, ProjectTemplateResult } from "./types";
9
+
10
+ export function websiteTemplate(config: ProjectConfig): ProjectTemplateResult {
11
+ return {
12
+ files: [
13
+ {
14
+ path: "src/build.ts",
15
+ content: `/**
16
+ * Build script for ${config.name}
17
+ *
18
+ * Uses Bueno's SSG module to generate static HTML from markdown content
19
+ */
20
+
21
+ import { SSG, createSSG, type SiteConfig, type LayoutContext } from 'bueno';
22
+
23
+ // Site configuration
24
+ const siteConfig: Partial<SiteConfig> = {
25
+ title: '${config.name}',
26
+ description: 'A static website built with Bueno',
27
+ baseUrl: '/',
28
+ };
29
+
30
+ // Create SSG instance
31
+ const ssg = createSSG(
32
+ {
33
+ contentDir: './content',
34
+ outputDir: './dist',
35
+ publicDir: './public',
36
+ defaultLayout: 'default',
37
+ },
38
+ siteConfig
39
+ );
40
+
41
+ // Register custom layouts
42
+ ssg.registerLayout('default', renderDefaultLayout);
43
+
44
+ // Build the site
45
+ console.log('Building website...');
46
+ await ssg.build();
47
+ console.log('Build complete!');
48
+
49
+ // ============= Layout Templates =============
50
+
51
+ function renderDefaultLayout(ctx: LayoutContext): string {
52
+ const title = ctx.page.frontmatter.title || ctx.site.title;
53
+ const description = ctx.page.frontmatter.description || ctx.site.description;
54
+
55
+ return \`<!DOCTYPE html>
56
+ <html lang="en">
57
+ <head>
58
+ <meta charset="UTF-8">
59
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
60
+ <title>\${title}</title>
61
+ <meta name="description" content="\${description}">
62
+ <link rel="stylesheet" href="\${ctx.site.baseUrl}styles/main.css">
63
+ </head>
64
+ <body>
65
+ <header>
66
+ <nav>
67
+ <a href="\${ctx.site.baseUrl}">Home</a>
68
+ <a href="\${ctx.site.baseUrl}about">About</a>
69
+ </nav>
70
+ </header>
71
+ <main>
72
+ \${ctx.content}
73
+ </main>
74
+ <footer>
75
+ <p>&copy; \${new Date().getFullYear()} \${ctx.site.title}</p>
76
+ </footer>
77
+ </body>
78
+ </html>\`;
79
+ }
80
+ `,
81
+ },
82
+ {
83
+ path: "src/serve.ts",
84
+ content: `/**
85
+ * Development server for serving the built website
86
+ */
87
+
88
+ const PORT = 3001;
89
+
90
+ async function serve() {
91
+ console.log(\`Starting server at http://localhost:\${PORT}\`);
92
+
93
+ Bun.serve({
94
+ port: PORT,
95
+ async fetch(request) {
96
+ const url = new URL(request.url);
97
+ let path = url.pathname;
98
+
99
+ // Serve index.html for root
100
+ if (path === '/') {
101
+ path = '/index.html';
102
+ }
103
+
104
+ // Try to serve from dist directory
105
+ const filePath = \`./dist\${path}\`;
106
+ const file = Bun.file(filePath);
107
+
108
+ if (await file.exists()) {
109
+ return new Response(file);
110
+ }
111
+
112
+ // For SPA-like behavior, try adding .html extension
113
+ if (!path.includes('.')) {
114
+ const htmlPath = \`./dist\${path}/index.html\`;
115
+ const htmlFile = Bun.file(htmlPath);
116
+
117
+ if (await htmlFile.exists()) {
118
+ return new Response(htmlFile);
119
+ }
120
+ }
121
+
122
+ // 404
123
+ return new Response('Not Found', { status: 404 });
124
+ },
125
+ });
126
+
127
+ console.log(\`Server running at http://localhost:\${PORT}\`);
128
+ }
129
+
130
+ serve();
131
+ `,
132
+ },
133
+ {
134
+ path: "content/index.md",
135
+ content: `---
136
+ title: Welcome
137
+ description: Welcome to my website
138
+ layout: default
139
+ ---
140
+
141
+ # Welcome to ${config.name}
142
+
143
+ This is a static website built with [Bueno Framework](https://buenojs.dev).
144
+
145
+ ## Getting Started
146
+
147
+ 1. Edit content in the \`content/\` directory
148
+ 2. Run \`bun run dev\` to start development
149
+ 3. Run \`bun run build\` to generate static files
150
+ `,
151
+ },
152
+ {
153
+ path: "public/styles/main.css",
154
+ content: `/* Main styles for the website */
155
+ * {
156
+ box-sizing: border-box;
157
+ margin: 0;
158
+ padding: 0;
159
+ }
160
+
161
+ body {
162
+ font-family: system-ui, -apple-system, sans-serif;
163
+ line-height: 1.6;
164
+ color: #333;
165
+ max-width: 800px;
166
+ margin: 0 auto;
167
+ padding: 20px;
168
+ }
169
+
170
+ header {
171
+ padding: 20px 0;
172
+ border-bottom: 1px solid #eee;
173
+ margin-bottom: 20px;
174
+ }
175
+
176
+ nav {
177
+ display: flex;
178
+ gap: 20px;
179
+ }
180
+
181
+ nav a {
182
+ color: #2563eb;
183
+ text-decoration: none;
184
+ }
185
+
186
+ nav a:hover {
187
+ text-decoration: underline;
188
+ }
189
+
190
+ main {
191
+ min-height: 60vh;
192
+ }
193
+
194
+ footer {
195
+ padding: 20px 0;
196
+ border-top: 1px solid #eee;
197
+ margin-top: 40px;
198
+ text-align: center;
199
+ color: #666;
200
+ }
201
+
202
+ h1 {
203
+ color: #2563eb;
204
+ margin-bottom: 20px;
205
+ }
206
+
207
+ h2 {
208
+ margin-top: 30px;
209
+ margin-bottom: 15px;
210
+ }
211
+
212
+ p {
213
+ margin-bottom: 15px;
214
+ }
215
+
216
+ ul, ol {
217
+ margin-left: 20px;
218
+ margin-bottom: 15px;
219
+ }
220
+
221
+ code {
222
+ background: #f3f4f6;
223
+ padding: 2px 6px;
224
+ border-radius: 4px;
225
+ }
226
+
227
+ pre {
228
+ background: #f3f4f6;
229
+ padding: 16px;
230
+ border-radius: 8px;
231
+ overflow-x: auto;
232
+ margin-bottom: 15px;
233
+ }
234
+ `,
235
+ },
236
+ {
237
+ path: ".env.example",
238
+ content: `# ${config.name} Environment Variables
239
+ # Copy this file to .env and customize as needed
240
+
241
+ # Site Configuration
242
+ SITE_URL=http://localhost:3001
243
+
244
+ # Build Configuration
245
+ NODE_ENV=development
246
+ `,
247
+ },
248
+ ],
249
+ directories: ["src", "content", "public/styles", "layouts"],
250
+ dependencies: {
251
+ ...getBuenoDependency(),
252
+ },
253
+ devDependencies: {
254
+ "@types/bun": "latest",
255
+ typescript: "^5.3.0",
256
+ },
257
+ scripts: {
258
+ dev: "bun run --watch src/build.ts --dev",
259
+ build: "bun run src/build.ts",
260
+ serve: "bun run src/serve.ts",
261
+ },
262
+ };
263
+ }