@buenojs/bueno 0.8.3 → 0.8.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/dist/cli/index.js +2949 -1415
- package/package.json +1 -1
- package/src/cli/commands/new.ts +155 -263
- package/src/cli/templates/database/index.ts +42 -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/frontend/index.ts +45 -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 +34 -1
- package/src/cli/templates/project/api.ts +80 -0
- package/src/cli/templates/project/default.ts +140 -0
- package/src/cli/templates/project/fullstack.ts +109 -0
- package/src/cli/templates/project/index.ts +56 -0
- package/src/cli/templates/project/minimal.ts +40 -0
- package/src/cli/templates/project/types.ts +89 -0
- package/src/cli/templates/project/website.ts +263 -0
- package/src/cli/utils/index.ts +2 -1
- package/src/cli/utils/version.ts +41 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vue Frontend Template
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { FrontendTemplateResult } from '../project/types';
|
|
6
|
+
|
|
7
|
+
export function vueTemplate(): FrontendTemplateResult {
|
|
8
|
+
return {
|
|
9
|
+
files: [
|
|
10
|
+
{
|
|
11
|
+
path: 'client/index.html',
|
|
12
|
+
content: `<!DOCTYPE html>
|
|
13
|
+
<html lang="en">
|
|
14
|
+
<head>
|
|
15
|
+
<meta charset="UTF-8">
|
|
16
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
17
|
+
<title>Bueno App</title>
|
|
18
|
+
</head>
|
|
19
|
+
<body>
|
|
20
|
+
<div id="app"></div>
|
|
21
|
+
<script type="module" src="./src/main.ts"></script>
|
|
22
|
+
</body>
|
|
23
|
+
</html>
|
|
24
|
+
`,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
path: 'client/src/main.ts',
|
|
28
|
+
content: `import { createApp } from 'vue';
|
|
29
|
+
import App from './App.vue';
|
|
30
|
+
import './styles/globals.css';
|
|
31
|
+
|
|
32
|
+
createApp(App).mount('#app');
|
|
33
|
+
`,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
path: 'client/src/App.vue',
|
|
37
|
+
content: `<script setup lang="ts">
|
|
38
|
+
import { ref } from 'vue';
|
|
39
|
+
|
|
40
|
+
const count = ref(0);
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<template>
|
|
44
|
+
<main class="min-h-screen bg-gradient-to-br from-slate-900 to-slate-800 text-white">
|
|
45
|
+
<div class="container mx-auto px-4 py-16">
|
|
46
|
+
<div class="max-w-2xl mx-auto text-center">
|
|
47
|
+
<h1 class="text-5xl font-bold mb-4 bg-gradient-to-r from-green-400 to-emerald-500 bg-clip-text text-transparent">
|
|
48
|
+
Welcome to Bueno
|
|
49
|
+
</h1>
|
|
50
|
+
<p class="text-xl text-slate-300 mb-8">
|
|
51
|
+
A Bun-native full-stack framework
|
|
52
|
+
</p>
|
|
53
|
+
|
|
54
|
+
<div class="bg-slate-800/50 rounded-xl p-8 backdrop-blur-sm border border-slate-700">
|
|
55
|
+
<button
|
|
56
|
+
@click="count++"
|
|
57
|
+
class="px-6 py-3 bg-green-500 hover:bg-green-600 rounded-lg font-medium transition-colors"
|
|
58
|
+
>
|
|
59
|
+
Count: {{ count }}
|
|
60
|
+
</button>
|
|
61
|
+
<p class="mt-4 text-slate-400 text-sm">
|
|
62
|
+
Click the button to test Vue reactivity
|
|
63
|
+
</p>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<div class="mt-8 grid grid-cols-2 gap-4 text-left">
|
|
67
|
+
<a
|
|
68
|
+
href="https://bueno.github.io"
|
|
69
|
+
class="p-4 bg-slate-800/50 rounded-lg border border-slate-700 hover:border-green-500 transition-colors"
|
|
70
|
+
>
|
|
71
|
+
<h3 class="font-semibold text-green-400">Documentation</h3>
|
|
72
|
+
<p class="text-sm text-slate-400">Learn more about Bueno</p>
|
|
73
|
+
</a>
|
|
74
|
+
<a
|
|
75
|
+
href="https://github.com/buenojs/bueno"
|
|
76
|
+
class="p-4 bg-slate-800/50 rounded-lg border border-slate-700 hover:border-green-500 transition-colors"
|
|
77
|
+
>
|
|
78
|
+
<h3 class="font-semibold text-green-400">GitHub</h3>
|
|
79
|
+
<p class="text-sm text-slate-400">View the source code</p>
|
|
80
|
+
</a>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
</main>
|
|
85
|
+
</template>
|
|
86
|
+
`,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
path: 'client/src/styles/globals.css',
|
|
90
|
+
content: `@tailwind base;
|
|
91
|
+
@tailwind components;
|
|
92
|
+
@tailwind utilities;
|
|
93
|
+
|
|
94
|
+
:root {
|
|
95
|
+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
96
|
+
line-height: 1.5;
|
|
97
|
+
font-weight: 400;
|
|
98
|
+
font-synthesis: none;
|
|
99
|
+
text-rendering: optimizeLegibility;
|
|
100
|
+
-webkit-font-smoothing: antialiased;
|
|
101
|
+
-moz-osx-font-smoothing: grayscale;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
body {
|
|
105
|
+
margin: 0;
|
|
106
|
+
min-width: 320px;
|
|
107
|
+
min-height: 100vh;
|
|
108
|
+
}
|
|
109
|
+
`,
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
directories: [
|
|
113
|
+
'client/src/components',
|
|
114
|
+
'client/src/styles',
|
|
115
|
+
'client/public',
|
|
116
|
+
],
|
|
117
|
+
dependencies: {
|
|
118
|
+
vue: '^3.4.0',
|
|
119
|
+
},
|
|
120
|
+
devDependencies: {
|
|
121
|
+
tailwindcss: '^3.4.0',
|
|
122
|
+
postcss: '^8.4.0',
|
|
123
|
+
autoprefixer: '^10.4.0',
|
|
124
|
+
},
|
|
125
|
+
scripts: {
|
|
126
|
+
'dev:client': 'bun run --watch client/index.html',
|
|
127
|
+
'build:client': 'bun build ./client/src/main.ts --outdir ./dist/client',
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generators Templates
|
|
3
|
+
*
|
|
4
|
+
* Code generator templates registry
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Re-export types
|
|
8
|
+
export type {
|
|
9
|
+
GeneratorType,
|
|
10
|
+
GeneratorConfig,
|
|
11
|
+
GeneratorResult,
|
|
12
|
+
} from './types';
|
|
13
|
+
|
|
14
|
+
export { GENERATOR_ALIASES } from './types';
|
|
15
|
+
|
|
16
|
+
import type { GeneratorType, GeneratorConfig, GeneratorResult } from './types';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Generator template function type
|
|
20
|
+
*/
|
|
21
|
+
type GeneratorTemplate = (config: GeneratorConfig) => string;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Generator template registry
|
|
25
|
+
*/
|
|
26
|
+
const generatorTemplates: Record<GeneratorType, GeneratorTemplate> = {
|
|
27
|
+
controller: (config) => getControllerTemplate(config),
|
|
28
|
+
service: () => getServiceTemplate(),
|
|
29
|
+
module: (config) => getModuleTemplate(config),
|
|
30
|
+
guard: (config) => getGuardTemplate(config),
|
|
31
|
+
interceptor: (config) => getInterceptorTemplate(config),
|
|
32
|
+
pipe: (config) => getPipeTemplate(config),
|
|
33
|
+
filter: (config) => getFilterTemplate(config),
|
|
34
|
+
dto: (config) => getDtoTemplate(config),
|
|
35
|
+
middleware: (config) => getMiddlewareTemplate(config),
|
|
36
|
+
migration: (config) => getMigrationTemplate(config),
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get generator template
|
|
41
|
+
*/
|
|
42
|
+
export function getGeneratorTemplate(type: GeneratorType): GeneratorTemplate {
|
|
43
|
+
return generatorTemplates[type];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get all available generator types
|
|
48
|
+
*/
|
|
49
|
+
export function getGeneratorTypes(): GeneratorType[] {
|
|
50
|
+
return Object.keys(generatorTemplates) as GeneratorType[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get default directory for generator type
|
|
55
|
+
*/
|
|
56
|
+
export function getDefaultDirectory(type: GeneratorType): string {
|
|
57
|
+
switch (type) {
|
|
58
|
+
case 'controller':
|
|
59
|
+
case 'service':
|
|
60
|
+
case 'module':
|
|
61
|
+
case 'dto':
|
|
62
|
+
return 'modules';
|
|
63
|
+
case 'guard':
|
|
64
|
+
return 'common/guards';
|
|
65
|
+
case 'interceptor':
|
|
66
|
+
return 'common/interceptors';
|
|
67
|
+
case 'pipe':
|
|
68
|
+
return 'common/pipes';
|
|
69
|
+
case 'filter':
|
|
70
|
+
return 'common/filters';
|
|
71
|
+
case 'middleware':
|
|
72
|
+
return 'common/middleware';
|
|
73
|
+
case 'migration':
|
|
74
|
+
return 'database/migrations';
|
|
75
|
+
default:
|
|
76
|
+
return '';
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get file extension for generator type
|
|
82
|
+
*/
|
|
83
|
+
export function getFileExtension(type: GeneratorType): string {
|
|
84
|
+
return type === 'dto' ? '.dto.ts' : '.ts';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ============= Template Functions =============
|
|
88
|
+
|
|
89
|
+
function getControllerTemplate(config: GeneratorConfig): string {
|
|
90
|
+
return `import { Controller, Get, Post, Put, Delete{{#if path}} } from '@buenojs/bueno'{{/if}}{{#if service}}, { {{pascalCase service}}Service } from './{{kebabCase service}}.service'{{/if}};
|
|
91
|
+
import type { Context } from '@buenojs/bueno';
|
|
92
|
+
|
|
93
|
+
@Controller('{{path}}')
|
|
94
|
+
export class {{pascalCase name}}Controller {
|
|
95
|
+
{{#if service}}
|
|
96
|
+
constructor(private readonly {{camelCase service}}Service: {{pascalCase service}}Service) {}
|
|
97
|
+
{{/if}}
|
|
98
|
+
|
|
99
|
+
@Get()
|
|
100
|
+
async findAll(ctx: Context) {
|
|
101
|
+
return { message: '{{pascalCase name}} controller' };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@Get(':id')
|
|
105
|
+
async findOne(ctx: Context) {
|
|
106
|
+
const id = ctx.params.id;
|
|
107
|
+
return { id, message: '{{pascalCase name}} item' };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@Post()
|
|
111
|
+
async create(ctx: Context) {
|
|
112
|
+
const body = await ctx.body();
|
|
113
|
+
return { message: 'Created', data: body };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@Put(':id')
|
|
117
|
+
async update(ctx: Context) {
|
|
118
|
+
const id = ctx.params.id;
|
|
119
|
+
const body = await ctx.body();
|
|
120
|
+
return { id, message: 'Updated', data: body };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@Delete(':id')
|
|
124
|
+
async remove(ctx: Context) {
|
|
125
|
+
const id = ctx.params.id;
|
|
126
|
+
return { id, message: 'Deleted' };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function getServiceTemplate(): string {
|
|
133
|
+
return `import { Injectable } from '@buenojs/bueno';
|
|
134
|
+
|
|
135
|
+
@Injectable()
|
|
136
|
+
export class {{pascalCase name}}Service {
|
|
137
|
+
async findAll() {
|
|
138
|
+
// TODO: Implement findAll
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async findOne(id: string) {
|
|
143
|
+
// TODO: Implement findOne
|
|
144
|
+
return { id };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async create(data: unknown) {
|
|
148
|
+
// TODO: Implement create
|
|
149
|
+
return data;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async update(id: string, data: unknown) {
|
|
153
|
+
// TODO: Implement update
|
|
154
|
+
return { id, ...data };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async remove(id: string) {
|
|
158
|
+
// TODO: Implement remove
|
|
159
|
+
return { id };
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
`;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function getModuleTemplate(config: GeneratorConfig): string {
|
|
166
|
+
return `import { Module } from '@buenojs/bueno';
|
|
167
|
+
import { {{pascalCase name}}Controller } from './{{kebabCase name}}.controller';
|
|
168
|
+
import { {{pascalCase name}}Service } from './{{kebabCase name}}.service';
|
|
169
|
+
|
|
170
|
+
@Module({
|
|
171
|
+
controllers: [{{pascalCase name}}Controller],
|
|
172
|
+
providers: [{{pascalCase name}}Service],
|
|
173
|
+
exports: [{{pascalCase name}}Service],
|
|
174
|
+
})
|
|
175
|
+
export class {{pascalCase name}}Module {}
|
|
176
|
+
`;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function getGuardTemplate(config: GeneratorConfig): string {
|
|
180
|
+
return `import { Injectable, type CanActivate, type Context } from '@buenojs/bueno';
|
|
181
|
+
|
|
182
|
+
@Injectable()
|
|
183
|
+
export class {{pascalCase name}}Guard implements CanActivate {
|
|
184
|
+
async canActivate(ctx: Context): Promise<boolean> {
|
|
185
|
+
// TODO: Implement guard logic
|
|
186
|
+
// Return true to allow access, false to deny
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
`;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function getInterceptorTemplate(config: GeneratorConfig): string {
|
|
194
|
+
return `import { Injectable, type NestInterceptor, type CallHandler, type Context } from '@buenojs/bueno';
|
|
195
|
+
import type { Observable } from 'rxjs';
|
|
196
|
+
|
|
197
|
+
@Injectable()
|
|
198
|
+
export class {{pascalCase name}}Interceptor implements NestInterceptor {
|
|
199
|
+
async intercept(ctx: Context, next: CallHandler): Promise<Observable<unknown>> {
|
|
200
|
+
// Before handler execution
|
|
201
|
+
console.log('{{pascalCase name}}Interceptor - Before');
|
|
202
|
+
|
|
203
|
+
// Call the handler
|
|
204
|
+
const result = await next.handle();
|
|
205
|
+
|
|
206
|
+
// After handler execution
|
|
207
|
+
console.log('{{pascalCase name}}Interceptor - After');
|
|
208
|
+
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
`;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function getPipeTemplate(config: GeneratorConfig): string {
|
|
216
|
+
return `import { Injectable, type PipeTransform, type Context } from '@buenojs/bueno';
|
|
217
|
+
|
|
218
|
+
@Injectable()
|
|
219
|
+
export class {{pascalCase name}}Pipe implements PipeTransform {
|
|
220
|
+
async transform(value: unknown, ctx: Context): Promise<unknown> {
|
|
221
|
+
// TODO: Implement transformation/validation logic
|
|
222
|
+
// Throw an error to reject the value
|
|
223
|
+
return value;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
`;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function getFilterTemplate(config: GeneratorConfig): string {
|
|
230
|
+
return `import { Injectable, type ExceptionFilter, type Context } from '@buenojs/bueno';
|
|
231
|
+
import type { Response } from '@buenojs/bueno';
|
|
232
|
+
|
|
233
|
+
@Injectable()
|
|
234
|
+
export class {{pascalCase name}}Filter implements ExceptionFilter {
|
|
235
|
+
async catch(exception: Error, ctx: Context): Promise<Response> {
|
|
236
|
+
// TODO: Implement exception handling
|
|
237
|
+
console.error('{{pascalCase name}}Filter caught:', exception);
|
|
238
|
+
|
|
239
|
+
return new Response(
|
|
240
|
+
JSON.stringify({
|
|
241
|
+
statusCode: 500,
|
|
242
|
+
message: 'Internal Server Error',
|
|
243
|
+
error: exception.message,
|
|
244
|
+
}),
|
|
245
|
+
{
|
|
246
|
+
status: 500,
|
|
247
|
+
headers: { 'Content-Type': 'application/json' },
|
|
248
|
+
}
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
`;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function getDtoTemplate(config: GeneratorConfig): string {
|
|
256
|
+
return `/**
|
|
257
|
+
* {{pascalCase name}} DTO
|
|
258
|
+
*/
|
|
259
|
+
export interface {{pascalCase name}}Dto {
|
|
260
|
+
// TODO: Define properties
|
|
261
|
+
id?: string;
|
|
262
|
+
createdAt?: Date;
|
|
263
|
+
updatedAt?: Date;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Create {{pascalCase name}} DTO
|
|
268
|
+
*/
|
|
269
|
+
export interface Create{{pascalCase name}}Dto {
|
|
270
|
+
// TODO: Define required properties for creation
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Update {{pascalCase name}} DTO
|
|
275
|
+
*/
|
|
276
|
+
export interface Update{{pascalCase name}}Dto extends Partial<Create{{pascalCase name}}Dto> {
|
|
277
|
+
// TODO: Define optional properties for update
|
|
278
|
+
}
|
|
279
|
+
`;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function getMiddlewareTemplate(config: GeneratorConfig): string {
|
|
283
|
+
return `import type { Middleware, Context, Handler } from '@buenojs/bueno';
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* {{pascalCase name}} Middleware
|
|
287
|
+
*/
|
|
288
|
+
export const {{camelCase name}}Middleware: Middleware = async (
|
|
289
|
+
ctx: Context,
|
|
290
|
+
next: Handler
|
|
291
|
+
) => {
|
|
292
|
+
// Before handler execution
|
|
293
|
+
console.log('{{pascalCase name}}Middleware - Before');
|
|
294
|
+
|
|
295
|
+
// Call the next handler
|
|
296
|
+
const result = await next();
|
|
297
|
+
|
|
298
|
+
// After handler execution
|
|
299
|
+
console.log('{{pascalCase name}}Middleware - After');
|
|
300
|
+
|
|
301
|
+
return result;
|
|
302
|
+
};
|
|
303
|
+
`;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function getMigrationTemplate(config: GeneratorConfig): string {
|
|
307
|
+
const migrationId = generateMigrationId();
|
|
308
|
+
return `import { createMigration, type MigrationRunner } from '@buenojs/bueno';
|
|
309
|
+
|
|
310
|
+
export default createMigration('${migrationId}', '{{migrationName}}')
|
|
311
|
+
.up(async (db: MigrationRunner) => {
|
|
312
|
+
// TODO: Add migration logic
|
|
313
|
+
// Example:
|
|
314
|
+
// await db.createTable({
|
|
315
|
+
// name: '{{tableName}}',
|
|
316
|
+
// columns: [
|
|
317
|
+
// { name: 'id', type: 'uuid', primary: true },
|
|
318
|
+
// { name: 'created_at', type: 'timestamp', default: 'NOW()' },
|
|
319
|
+
// ],
|
|
320
|
+
// });
|
|
321
|
+
})
|
|
322
|
+
.down(async (db: MigrationRunner) => {
|
|
323
|
+
// TODO: Add rollback logic
|
|
324
|
+
// Example:
|
|
325
|
+
// await db.dropTable('{{tableName}}');
|
|
326
|
+
});
|
|
327
|
+
`;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function generateMigrationId(): string {
|
|
331
|
+
const now = new Date();
|
|
332
|
+
const year = now.getFullYear();
|
|
333
|
+
const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
334
|
+
const day = String(now.getDate()).padStart(2, '0');
|
|
335
|
+
const hour = String(now.getHours()).padStart(2, '0');
|
|
336
|
+
const minute = String(now.getMinutes()).padStart(2, '0');
|
|
337
|
+
const second = String(now.getSeconds()).padStart(2, '0');
|
|
338
|
+
return `${year}${month}${day}${hour}${minute}${second}`;
|
|
339
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generator Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for code generators
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generator types available
|
|
9
|
+
*/
|
|
10
|
+
export type GeneratorType =
|
|
11
|
+
| 'controller'
|
|
12
|
+
| 'service'
|
|
13
|
+
| 'module'
|
|
14
|
+
| 'guard'
|
|
15
|
+
| 'interceptor'
|
|
16
|
+
| 'pipe'
|
|
17
|
+
| 'filter'
|
|
18
|
+
| 'dto'
|
|
19
|
+
| 'middleware'
|
|
20
|
+
| 'migration';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Generator aliases
|
|
24
|
+
*/
|
|
25
|
+
export const GENERATOR_ALIASES: Record<string, GeneratorType> = {
|
|
26
|
+
c: 'controller',
|
|
27
|
+
s: 'service',
|
|
28
|
+
m: 'module',
|
|
29
|
+
gu: 'guard',
|
|
30
|
+
i: 'interceptor',
|
|
31
|
+
p: 'pipe',
|
|
32
|
+
f: 'filter',
|
|
33
|
+
d: 'dto',
|
|
34
|
+
mw: 'middleware',
|
|
35
|
+
mi: 'migration',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Generator configuration
|
|
40
|
+
*/
|
|
41
|
+
export interface GeneratorConfig {
|
|
42
|
+
type: GeneratorType;
|
|
43
|
+
name: string;
|
|
44
|
+
module?: string;
|
|
45
|
+
path?: string;
|
|
46
|
+
dryRun: boolean;
|
|
47
|
+
force: boolean;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Generator result
|
|
52
|
+
*/
|
|
53
|
+
export interface GeneratorResult {
|
|
54
|
+
filePath: string;
|
|
55
|
+
content: string;
|
|
56
|
+
}
|
|
@@ -21,4 +21,37 @@ export {
|
|
|
21
21
|
getDeployTemplate,
|
|
22
22
|
getDeployFilename,
|
|
23
23
|
getDeployPlatformName,
|
|
24
|
-
} from './deploy';
|
|
24
|
+
} from './deploy';
|
|
25
|
+
|
|
26
|
+
// Project templates
|
|
27
|
+
export {
|
|
28
|
+
type ProjectTemplate,
|
|
29
|
+
type ProjectConfig,
|
|
30
|
+
type FrontendFramework,
|
|
31
|
+
type DatabaseDriver,
|
|
32
|
+
getProjectTemplate,
|
|
33
|
+
getTemplateOptions,
|
|
34
|
+
} from './project';
|
|
35
|
+
|
|
36
|
+
// Database templates
|
|
37
|
+
export {
|
|
38
|
+
getDatabaseTemplate,
|
|
39
|
+
getDatabaseOptions,
|
|
40
|
+
} from './database';
|
|
41
|
+
|
|
42
|
+
// Frontend templates
|
|
43
|
+
export {
|
|
44
|
+
getFrontendTemplate,
|
|
45
|
+
getFrontendOptions,
|
|
46
|
+
} from './frontend';
|
|
47
|
+
|
|
48
|
+
// Generator templates
|
|
49
|
+
export {
|
|
50
|
+
type GeneratorType,
|
|
51
|
+
type GeneratorConfig,
|
|
52
|
+
GENERATOR_ALIASES,
|
|
53
|
+
getGeneratorTemplate,
|
|
54
|
+
getGeneratorTypes,
|
|
55
|
+
getDefaultDirectory,
|
|
56
|
+
getFileExtension,
|
|
57
|
+
} from './generators';
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Project Template
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ProjectConfig, ProjectTemplateResult } from './types';
|
|
6
|
+
import { getBuenoDependency } from '../../utils/version';
|
|
7
|
+
|
|
8
|
+
export function apiTemplate(config: ProjectConfig): ProjectTemplateResult {
|
|
9
|
+
return {
|
|
10
|
+
files: [
|
|
11
|
+
{
|
|
12
|
+
path: 'server/main.ts',
|
|
13
|
+
content: `import { createApp, Module, Controller, Get, Post, Injectable } from '@buenojs/bueno';
|
|
14
|
+
import type { Context } from '@buenojs/bueno';
|
|
15
|
+
|
|
16
|
+
// Services
|
|
17
|
+
@Injectable()
|
|
18
|
+
export class AppService {
|
|
19
|
+
findAll() {
|
|
20
|
+
return { message: 'Welcome to Bueno API!', items: [] };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Controllers
|
|
25
|
+
@Controller()
|
|
26
|
+
export class AppController {
|
|
27
|
+
constructor(private readonly appService: AppService) {}
|
|
28
|
+
|
|
29
|
+
@Get()
|
|
30
|
+
hello() {
|
|
31
|
+
return { message: 'Welcome to Bueno API!', version: '1.0.0' };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@Get('health')
|
|
35
|
+
health(ctx: Context) {
|
|
36
|
+
return { status: 'ok', timestamp: new Date().toISOString() };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Module
|
|
41
|
+
@Module({
|
|
42
|
+
controllers: [AppController],
|
|
43
|
+
providers: [AppService],
|
|
44
|
+
})
|
|
45
|
+
export class AppModule {}
|
|
46
|
+
|
|
47
|
+
// Bootstrap
|
|
48
|
+
const app = createApp(AppModule);
|
|
49
|
+
await app.listen(3000);
|
|
50
|
+
`,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
directories: [
|
|
54
|
+
'server/modules/app',
|
|
55
|
+
'server/common/middleware',
|
|
56
|
+
'server/common/guards',
|
|
57
|
+
'server/common/interceptors',
|
|
58
|
+
'server/common/pipes',
|
|
59
|
+
'server/common/filters',
|
|
60
|
+
'server/database/migrations',
|
|
61
|
+
'server/config',
|
|
62
|
+
'tests/unit',
|
|
63
|
+
'tests/integration',
|
|
64
|
+
],
|
|
65
|
+
dependencies: {
|
|
66
|
+
...getBuenoDependency(),
|
|
67
|
+
zod: '^3.24.0',
|
|
68
|
+
},
|
|
69
|
+
devDependencies: {
|
|
70
|
+
'@types/bun': 'latest',
|
|
71
|
+
typescript: '^5.3.0',
|
|
72
|
+
},
|
|
73
|
+
scripts: {
|
|
74
|
+
dev: 'bun run --watch server/main.ts',
|
|
75
|
+
build: 'bun build ./server/main.ts --outdir ./dist --target bun',
|
|
76
|
+
start: 'bun run dist/main.js',
|
|
77
|
+
test: 'bun test',
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|