@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.
- package/README.md +136 -16
- package/dist/cli/{index.js → bin.js} +3036 -1421
- package/dist/container/index.js +250 -0
- package/dist/context/index.js +219 -0
- package/dist/database/index.js +493 -0
- package/dist/frontend/index.js +7697 -0
- package/dist/health/index.js +364 -0
- package/dist/i18n/index.js +345 -0
- package/dist/index.js +11043 -6482
- package/dist/jobs/index.js +819 -0
- package/dist/lock/index.js +367 -0
- package/dist/logger/index.js +281 -0
- package/dist/metrics/index.js +289 -0
- package/dist/middleware/index.js +77 -0
- package/dist/migrations/index.js +571 -0
- package/dist/modules/index.js +3346 -0
- package/dist/notification/index.js +484 -0
- package/dist/observability/index.js +331 -0
- package/dist/openapi/index.js +776 -0
- package/dist/orm/index.js +1356 -0
- package/dist/router/index.js +886 -0
- package/dist/rpc/index.js +691 -0
- package/dist/schema/index.js +400 -0
- package/dist/telemetry/index.js +595 -0
- package/dist/template/index.js +640 -0
- package/dist/templates/index.js +640 -0
- package/dist/testing/index.js +1111 -0
- package/dist/types/index.js +60 -0
- package/package.json +121 -27
- package/src/cache/index.ts +2 -1
- package/src/cli/bin.ts +2 -2
- package/src/cli/commands/build.ts +183 -165
- package/src/cli/commands/dev.ts +96 -89
- package/src/cli/commands/generate.ts +142 -111
- package/src/cli/commands/help.ts +20 -16
- package/src/cli/commands/index.ts +3 -6
- package/src/cli/commands/migration.ts +124 -105
- package/src/cli/commands/new.ts +392 -438
- package/src/cli/commands/start.ts +81 -79
- package/src/cli/core/args.ts +68 -50
- package/src/cli/core/console.ts +89 -95
- package/src/cli/core/index.ts +4 -4
- package/src/cli/core/prompt.ts +65 -62
- package/src/cli/core/spinner.ts +23 -20
- package/src/cli/index.ts +46 -38
- package/src/cli/templates/database/index.ts +61 -0
- package/src/cli/templates/database/mysql.ts +14 -0
- package/src/cli/templates/database/none.ts +16 -0
- package/src/cli/templates/database/postgresql.ts +14 -0
- package/src/cli/templates/database/sqlite.ts +14 -0
- package/src/cli/templates/deploy.ts +29 -26
- package/src/cli/templates/docker.ts +41 -30
- package/src/cli/templates/frontend/index.ts +63 -0
- package/src/cli/templates/frontend/none.ts +17 -0
- package/src/cli/templates/frontend/react.ts +140 -0
- package/src/cli/templates/frontend/solid.ts +134 -0
- package/src/cli/templates/frontend/svelte.ts +131 -0
- package/src/cli/templates/frontend/vue.ts +130 -0
- package/src/cli/templates/generators/index.ts +339 -0
- package/src/cli/templates/generators/types.ts +56 -0
- package/src/cli/templates/index.ts +35 -2
- package/src/cli/templates/project/api.ts +81 -0
- package/src/cli/templates/project/default.ts +140 -0
- package/src/cli/templates/project/fullstack.ts +111 -0
- package/src/cli/templates/project/index.ts +95 -0
- package/src/cli/templates/project/minimal.ts +45 -0
- package/src/cli/templates/project/types.ts +94 -0
- package/src/cli/templates/project/website.ts +263 -0
- package/src/cli/utils/fs.ts +55 -41
- package/src/cli/utils/index.ts +3 -2
- package/src/cli/utils/strings.ts +47 -33
- package/src/cli/utils/version.ts +47 -0
- package/src/config/env-validation.ts +100 -0
- package/src/config/env.ts +169 -41
- package/src/config/index.ts +28 -20
- package/src/config/loader.ts +25 -16
- package/src/config/merge.ts +21 -10
- package/src/config/types.ts +545 -25
- package/src/config/validation.ts +215 -7
- package/src/container/forward-ref.ts +22 -22
- package/src/container/index.ts +34 -12
- package/src/context/index.ts +11 -1
- package/src/database/index.ts +7 -190
- package/src/database/orm/builder.ts +457 -0
- package/src/database/orm/casts/index.ts +130 -0
- package/src/database/orm/casts/types.ts +25 -0
- package/src/database/orm/compiler.ts +304 -0
- package/src/database/orm/hooks/index.ts +114 -0
- package/src/database/orm/index.ts +61 -0
- package/src/database/orm/model-registry.ts +59 -0
- package/src/database/orm/model.ts +821 -0
- package/src/database/orm/relationships/base.ts +146 -0
- package/src/database/orm/relationships/belongs-to-many.ts +179 -0
- package/src/database/orm/relationships/belongs-to.ts +56 -0
- package/src/database/orm/relationships/has-many.ts +45 -0
- package/src/database/orm/relationships/has-one.ts +41 -0
- package/src/database/orm/relationships/index.ts +11 -0
- package/src/database/orm/scopes/index.ts +55 -0
- package/src/events/__tests__/event-system.test.ts +235 -0
- package/src/events/config.ts +238 -0
- package/src/events/example-usage.ts +185 -0
- package/src/events/index.ts +278 -0
- package/src/events/manager.ts +385 -0
- package/src/events/registry.ts +182 -0
- package/src/events/types.ts +124 -0
- package/src/frontend/api-routes.ts +65 -23
- package/src/frontend/bundler.ts +76 -34
- package/src/frontend/console-client.ts +2 -2
- package/src/frontend/console-stream.ts +94 -38
- package/src/frontend/dev-server.ts +94 -46
- package/src/frontend/file-router.ts +61 -19
- package/src/frontend/frameworks/index.ts +37 -10
- package/src/frontend/frameworks/react.ts +10 -8
- package/src/frontend/frameworks/solid.ts +11 -9
- package/src/frontend/frameworks/svelte.ts +15 -9
- package/src/frontend/frameworks/vue.ts +13 -11
- package/src/frontend/hmr-client.ts +12 -10
- package/src/frontend/hmr.ts +146 -103
- package/src/frontend/index.ts +14 -5
- package/src/frontend/islands.ts +41 -22
- package/src/frontend/isr.ts +59 -37
- package/src/frontend/layout.ts +36 -21
- package/src/frontend/ssr/react.ts +74 -27
- package/src/frontend/ssr/solid.ts +54 -20
- package/src/frontend/ssr/svelte.ts +48 -14
- package/src/frontend/ssr/vue.ts +50 -18
- package/src/frontend/ssr.ts +83 -39
- package/src/frontend/types.ts +91 -56
- package/src/health/index.ts +21 -9
- package/src/i18n/engine.ts +305 -0
- package/src/i18n/index.ts +38 -0
- package/src/i18n/loader.ts +218 -0
- package/src/i18n/middleware.ts +164 -0
- package/src/i18n/negotiator.ts +162 -0
- package/src/i18n/types.ts +158 -0
- package/src/index.ts +179 -27
- package/src/jobs/drivers/memory.ts +315 -0
- package/src/jobs/drivers/redis.ts +459 -0
- package/src/jobs/index.ts +30 -0
- package/src/jobs/queue.ts +281 -0
- package/src/jobs/types.ts +295 -0
- package/src/jobs/worker.ts +380 -0
- package/src/logger/index.ts +1 -3
- package/src/logger/transports/index.ts +62 -22
- package/src/metrics/index.ts +25 -16
- package/src/migrations/index.ts +9 -0
- package/src/modules/filters.ts +13 -17
- package/src/modules/guards.ts +49 -26
- package/src/modules/index.ts +409 -298
- package/src/modules/interceptors.ts +58 -20
- package/src/modules/lazy.ts +11 -19
- package/src/modules/lifecycle.ts +15 -7
- package/src/modules/metadata.ts +15 -5
- package/src/modules/pipes.ts +94 -72
- package/src/notification/channels/base.ts +68 -0
- package/src/notification/channels/email.ts +105 -0
- package/src/notification/channels/push.ts +104 -0
- package/src/notification/channels/sms.ts +105 -0
- package/src/notification/channels/whatsapp.ts +104 -0
- package/src/notification/index.ts +48 -0
- package/src/notification/service.ts +354 -0
- package/src/notification/types.ts +344 -0
- package/src/observability/__tests__/observability.test.ts +483 -0
- package/src/observability/breadcrumbs.ts +114 -0
- package/src/observability/index.ts +136 -0
- package/src/observability/interceptor.ts +85 -0
- package/src/observability/service.ts +303 -0
- package/src/observability/trace.ts +37 -0
- package/src/observability/types.ts +196 -0
- package/src/openapi/__tests__/decorators.test.ts +335 -0
- package/src/openapi/__tests__/document-builder.test.ts +285 -0
- package/src/openapi/__tests__/route-scanner.test.ts +334 -0
- package/src/openapi/__tests__/schema-generator.test.ts +275 -0
- package/src/openapi/decorators.ts +328 -0
- package/src/openapi/document-builder.ts +274 -0
- package/src/openapi/index.ts +112 -0
- package/src/openapi/metadata.ts +112 -0
- package/src/openapi/route-scanner.ts +289 -0
- package/src/openapi/schema-generator.ts +256 -0
- package/src/openapi/swagger-module.ts +166 -0
- package/src/openapi/types.ts +398 -0
- package/src/orm/index.ts +10 -0
- package/src/rpc/index.ts +3 -1
- package/src/schema/index.ts +9 -0
- package/src/security/index.ts +15 -6
- package/src/ssg/index.ts +9 -8
- package/src/telemetry/index.ts +76 -22
- package/src/template/index.ts +7 -0
- package/src/templates/engine.ts +224 -0
- package/src/templates/index.ts +9 -0
- package/src/templates/loader.ts +331 -0
- package/src/templates/renderers/markdown.ts +212 -0
- package/src/templates/renderers/simple.ts +269 -0
- package/src/templates/types.ts +154 -0
- package/src/testing/index.ts +100 -27
- package/src/types/optional-deps.d.ts +347 -187
- package/src/validation/index.ts +92 -2
- package/src/validation/schemas.ts +536 -0
- package/tests/integration/fullstack.test.ts +4 -4
- package/tests/unit/database.test.ts +2 -72
- package/tests/unit/env-validation.test.ts +166 -0
- package/tests/unit/events.test.ts +910 -0
- package/tests/unit/i18n.test.ts +455 -0
- package/tests/unit/jobs.test.ts +493 -0
- package/tests/unit/notification.test.ts +988 -0
- package/tests/unit/observability.test.ts +453 -0
- package/tests/unit/orm/builder.test.ts +323 -0
- package/tests/unit/orm/casts.test.ts +179 -0
- package/tests/unit/orm/compiler.test.ts +220 -0
- package/tests/unit/orm/eager-loading.test.ts +285 -0
- package/tests/unit/orm/hooks.test.ts +191 -0
- package/tests/unit/orm/model.test.ts +373 -0
- package/tests/unit/orm/relationships.test.ts +303 -0
- package/tests/unit/orm/scopes.test.ts +74 -0
- package/tests/unit/templates-simple.test.ts +53 -0
- package/tests/unit/templates.test.ts +454 -0
- package/tests/unit/validation.test.ts +18 -24
- 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>© \${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
|
+
}
|