@buenojs/bueno 0.8.4 → 0.8.6

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 (234) hide show
  1. package/README.md +264 -17
  2. package/dist/cli/{index.js → bin.js} +413 -332
  3. package/dist/container/index.js +273 -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/graphql/index.js +2156 -0
  8. package/dist/health/index.js +364 -0
  9. package/dist/i18n/index.js +345 -0
  10. package/dist/index.js +9694 -5047
  11. package/dist/jobs/index.js +819 -0
  12. package/dist/lock/index.js +367 -0
  13. package/dist/logger/index.js +281 -0
  14. package/dist/metrics/index.js +289 -0
  15. package/dist/middleware/index.js +77 -0
  16. package/dist/migrations/index.js +571 -0
  17. package/dist/modules/index.js +3411 -0
  18. package/dist/notification/index.js +484 -0
  19. package/dist/observability/index.js +331 -0
  20. package/dist/openapi/index.js +795 -0
  21. package/dist/orm/index.js +1356 -0
  22. package/dist/router/index.js +886 -0
  23. package/dist/rpc/index.js +691 -0
  24. package/dist/schema/index.js +400 -0
  25. package/dist/telemetry/index.js +595 -0
  26. package/dist/template/index.js +640 -0
  27. package/dist/templates/index.js +640 -0
  28. package/dist/testing/index.js +1111 -0
  29. package/dist/types/index.js +60 -0
  30. package/llms.txt +231 -0
  31. package/package.json +125 -27
  32. package/src/cache/index.ts +2 -1
  33. package/src/cli/ARCHITECTURE.md +3 -3
  34. package/src/cli/bin.ts +2 -2
  35. package/src/cli/commands/build.ts +183 -165
  36. package/src/cli/commands/dev.ts +96 -89
  37. package/src/cli/commands/generate.ts +142 -111
  38. package/src/cli/commands/help.ts +20 -16
  39. package/src/cli/commands/index.ts +3 -6
  40. package/src/cli/commands/migration.ts +124 -105
  41. package/src/cli/commands/new.ts +294 -232
  42. package/src/cli/commands/start.ts +81 -79
  43. package/src/cli/core/args.ts +68 -50
  44. package/src/cli/core/console.ts +89 -95
  45. package/src/cli/core/index.ts +4 -4
  46. package/src/cli/core/prompt.ts +65 -62
  47. package/src/cli/core/spinner.ts +23 -20
  48. package/src/cli/index.ts +46 -38
  49. package/src/cli/templates/database/index.ts +37 -18
  50. package/src/cli/templates/database/mysql.ts +3 -3
  51. package/src/cli/templates/database/none.ts +2 -2
  52. package/src/cli/templates/database/postgresql.ts +3 -3
  53. package/src/cli/templates/database/sqlite.ts +3 -3
  54. package/src/cli/templates/deploy.ts +29 -26
  55. package/src/cli/templates/docker.ts +41 -30
  56. package/src/cli/templates/frontend/index.ts +33 -15
  57. package/src/cli/templates/frontend/none.ts +2 -2
  58. package/src/cli/templates/frontend/react.ts +18 -18
  59. package/src/cli/templates/frontend/solid.ts +15 -15
  60. package/src/cli/templates/frontend/svelte.ts +17 -17
  61. package/src/cli/templates/frontend/vue.ts +15 -15
  62. package/src/cli/templates/generators/index.ts +29 -29
  63. package/src/cli/templates/generators/types.ts +21 -21
  64. package/src/cli/templates/index.ts +6 -6
  65. package/src/cli/templates/project/api.ts +37 -36
  66. package/src/cli/templates/project/default.ts +25 -25
  67. package/src/cli/templates/project/fullstack.ts +28 -26
  68. package/src/cli/templates/project/index.ts +55 -16
  69. package/src/cli/templates/project/minimal.ts +17 -12
  70. package/src/cli/templates/project/types.ts +10 -5
  71. package/src/cli/templates/project/website.ts +15 -15
  72. package/src/cli/utils/fs.ts +55 -41
  73. package/src/cli/utils/index.ts +3 -3
  74. package/src/cli/utils/strings.ts +47 -33
  75. package/src/cli/utils/version.ts +14 -8
  76. package/src/config/env-validation.ts +100 -0
  77. package/src/config/env.ts +169 -41
  78. package/src/config/index.ts +28 -20
  79. package/src/config/loader.ts +25 -16
  80. package/src/config/merge.ts +21 -10
  81. package/src/config/types.ts +566 -25
  82. package/src/config/validation.ts +215 -7
  83. package/src/container/forward-ref.ts +22 -22
  84. package/src/container/index.ts +34 -12
  85. package/src/context/index.ts +11 -1
  86. package/src/database/index.ts +7 -190
  87. package/src/database/orm/builder.ts +457 -0
  88. package/src/database/orm/casts/index.ts +130 -0
  89. package/src/database/orm/casts/types.ts +25 -0
  90. package/src/database/orm/compiler.ts +304 -0
  91. package/src/database/orm/hooks/index.ts +114 -0
  92. package/src/database/orm/index.ts +61 -0
  93. package/src/database/orm/model-registry.ts +59 -0
  94. package/src/database/orm/model.ts +821 -0
  95. package/src/database/orm/relationships/base.ts +146 -0
  96. package/src/database/orm/relationships/belongs-to-many.ts +179 -0
  97. package/src/database/orm/relationships/belongs-to.ts +56 -0
  98. package/src/database/orm/relationships/has-many.ts +45 -0
  99. package/src/database/orm/relationships/has-one.ts +41 -0
  100. package/src/database/orm/relationships/index.ts +11 -0
  101. package/src/database/orm/scopes/index.ts +55 -0
  102. package/src/events/__tests__/event-system.test.ts +235 -0
  103. package/src/events/config.ts +238 -0
  104. package/src/events/example-usage.ts +185 -0
  105. package/src/events/index.ts +278 -0
  106. package/src/events/manager.ts +385 -0
  107. package/src/events/registry.ts +182 -0
  108. package/src/events/types.ts +124 -0
  109. package/src/frontend/api-routes.ts +65 -23
  110. package/src/frontend/bundler.ts +76 -34
  111. package/src/frontend/console-client.ts +2 -2
  112. package/src/frontend/console-stream.ts +94 -38
  113. package/src/frontend/dev-server.ts +94 -46
  114. package/src/frontend/file-router.ts +61 -19
  115. package/src/frontend/frameworks/index.ts +37 -10
  116. package/src/frontend/frameworks/react.ts +10 -8
  117. package/src/frontend/frameworks/solid.ts +11 -9
  118. package/src/frontend/frameworks/svelte.ts +15 -9
  119. package/src/frontend/frameworks/vue.ts +13 -11
  120. package/src/frontend/hmr-client.ts +12 -10
  121. package/src/frontend/hmr.ts +146 -103
  122. package/src/frontend/index.ts +14 -5
  123. package/src/frontend/islands.ts +41 -22
  124. package/src/frontend/isr.ts +59 -37
  125. package/src/frontend/layout.ts +36 -21
  126. package/src/frontend/ssr/react.ts +74 -27
  127. package/src/frontend/ssr/solid.ts +54 -20
  128. package/src/frontend/ssr/svelte.ts +48 -14
  129. package/src/frontend/ssr/vue.ts +50 -18
  130. package/src/frontend/ssr.ts +83 -39
  131. package/src/frontend/types.ts +91 -56
  132. package/src/graphql/built-in-engine.ts +598 -0
  133. package/src/graphql/context-builder.ts +110 -0
  134. package/src/graphql/decorators.ts +358 -0
  135. package/src/graphql/execution-pipeline.ts +227 -0
  136. package/src/graphql/graphql-module.ts +563 -0
  137. package/src/graphql/index.ts +101 -0
  138. package/src/graphql/metadata.ts +237 -0
  139. package/src/graphql/schema-builder.ts +319 -0
  140. package/src/graphql/subscription-handler.ts +283 -0
  141. package/src/graphql/types.ts +324 -0
  142. package/src/health/index.ts +21 -9
  143. package/src/i18n/engine.ts +305 -0
  144. package/src/i18n/index.ts +38 -0
  145. package/src/i18n/loader.ts +218 -0
  146. package/src/i18n/middleware.ts +164 -0
  147. package/src/i18n/negotiator.ts +162 -0
  148. package/src/i18n/types.ts +158 -0
  149. package/src/index.ts +182 -27
  150. package/src/jobs/drivers/memory.ts +315 -0
  151. package/src/jobs/drivers/redis.ts +459 -0
  152. package/src/jobs/index.ts +30 -0
  153. package/src/jobs/queue.ts +281 -0
  154. package/src/jobs/types.ts +295 -0
  155. package/src/jobs/worker.ts +380 -0
  156. package/src/logger/index.ts +1 -3
  157. package/src/logger/transports/index.ts +62 -22
  158. package/src/metrics/index.ts +25 -16
  159. package/src/migrations/index.ts +9 -0
  160. package/src/modules/filters.ts +13 -17
  161. package/src/modules/guards.ts +49 -26
  162. package/src/modules/index.ts +457 -299
  163. package/src/modules/interceptors.ts +58 -20
  164. package/src/modules/lazy.ts +11 -19
  165. package/src/modules/lifecycle.ts +15 -7
  166. package/src/modules/metadata.ts +15 -5
  167. package/src/modules/pipes.ts +94 -72
  168. package/src/notification/channels/base.ts +68 -0
  169. package/src/notification/channels/email.ts +105 -0
  170. package/src/notification/channels/push.ts +104 -0
  171. package/src/notification/channels/sms.ts +105 -0
  172. package/src/notification/channels/whatsapp.ts +104 -0
  173. package/src/notification/index.ts +48 -0
  174. package/src/notification/service.ts +354 -0
  175. package/src/notification/types.ts +344 -0
  176. package/src/observability/__tests__/observability.test.ts +483 -0
  177. package/src/observability/breadcrumbs.ts +114 -0
  178. package/src/observability/index.ts +136 -0
  179. package/src/observability/interceptor.ts +85 -0
  180. package/src/observability/service.ts +303 -0
  181. package/src/observability/trace.ts +37 -0
  182. package/src/observability/types.ts +196 -0
  183. package/src/openapi/__tests__/decorators.test.ts +335 -0
  184. package/src/openapi/__tests__/document-builder.test.ts +285 -0
  185. package/src/openapi/__tests__/route-scanner.test.ts +334 -0
  186. package/src/openapi/__tests__/schema-generator.test.ts +275 -0
  187. package/src/openapi/decorators.ts +328 -0
  188. package/src/openapi/document-builder.ts +274 -0
  189. package/src/openapi/index.ts +112 -0
  190. package/src/openapi/metadata.ts +112 -0
  191. package/src/openapi/route-scanner.ts +289 -0
  192. package/src/openapi/schema-generator.ts +256 -0
  193. package/src/openapi/swagger-module.ts +166 -0
  194. package/src/openapi/types.ts +398 -0
  195. package/src/orm/index.ts +10 -0
  196. package/src/rpc/index.ts +3 -1
  197. package/src/schema/index.ts +9 -0
  198. package/src/security/index.ts +15 -6
  199. package/src/ssg/index.ts +9 -8
  200. package/src/telemetry/index.ts +76 -22
  201. package/src/template/index.ts +7 -0
  202. package/src/templates/engine.ts +224 -0
  203. package/src/templates/index.ts +9 -0
  204. package/src/templates/loader.ts +331 -0
  205. package/src/templates/renderers/markdown.ts +212 -0
  206. package/src/templates/renderers/simple.ts +269 -0
  207. package/src/templates/types.ts +154 -0
  208. package/src/testing/index.ts +100 -27
  209. package/src/types/optional-deps.d.ts +347 -187
  210. package/src/validation/index.ts +92 -2
  211. package/src/validation/schemas.ts +536 -0
  212. package/tests/integration/cli.test.ts +19 -19
  213. package/tests/integration/fullstack.test.ts +4 -4
  214. package/tests/unit/cli.test.ts +1 -1
  215. package/tests/unit/database.test.ts +2 -72
  216. package/tests/unit/env-validation.test.ts +166 -0
  217. package/tests/unit/events.test.ts +910 -0
  218. package/tests/unit/graphql.test.ts +991 -0
  219. package/tests/unit/i18n.test.ts +455 -0
  220. package/tests/unit/jobs.test.ts +493 -0
  221. package/tests/unit/notification.test.ts +988 -0
  222. package/tests/unit/observability.test.ts +453 -0
  223. package/tests/unit/orm/builder.test.ts +323 -0
  224. package/tests/unit/orm/casts.test.ts +179 -0
  225. package/tests/unit/orm/compiler.test.ts +220 -0
  226. package/tests/unit/orm/eager-loading.test.ts +285 -0
  227. package/tests/unit/orm/hooks.test.ts +191 -0
  228. package/tests/unit/orm/model.test.ts +373 -0
  229. package/tests/unit/orm/relationships.test.ts +303 -0
  230. package/tests/unit/orm/scopes.test.ts +74 -0
  231. package/tests/unit/templates-simple.test.ts +53 -0
  232. package/tests/unit/templates.test.ts +454 -0
  233. package/tests/unit/validation.test.ts +18 -24
  234. package/tsconfig.json +11 -3
@@ -27,31 +27,6 @@ var __legacyMetadataTS = (k, v) => {
27
27
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
28
28
  var __require = import.meta.require;
29
29
 
30
- // src/cli/utils/version.ts
31
- import { readFileSync as readFileSync2 } from "fs";
32
- import { join as join2 } from "path";
33
- function getBuenoVersion() {
34
- if (cachedVersion) {
35
- return cachedVersion;
36
- }
37
- try {
38
- const packageJsonPath = join2(import.meta.dir, "..", "..", "..", "package.json");
39
- const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
40
- cachedVersion = `^${packageJson.version}`;
41
- return cachedVersion;
42
- } catch {
43
- console.warn("Could not read version from package.json, using default");
44
- return "^0.8.0";
45
- }
46
- }
47
- function getBuenoDependency() {
48
- return {
49
- "@buenojs/bueno": getBuenoVersion()
50
- };
51
- }
52
- var cachedVersion = null;
53
- var init_version = () => {};
54
-
55
30
  // src/cli/templates/docker.ts
56
31
  function getDockerfileTemplate(projectName, database) {
57
32
  return `# ${projectName} - Production Dockerfile
@@ -565,6 +540,121 @@ function getDeployPlatformName(platform) {
565
540
  }
566
541
  }
567
542
 
543
+ // src/cli/utils/version.ts
544
+ import { readFileSync } from "fs";
545
+ import { join } from "path";
546
+ function getBuenoVersion() {
547
+ if (cachedVersion) {
548
+ return cachedVersion;
549
+ }
550
+ try {
551
+ const packageJsonPath = join(import.meta.dir, "..", "..", "..", "package.json");
552
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
553
+ cachedVersion = `^${packageJson.version}`;
554
+ return cachedVersion;
555
+ } catch {
556
+ console.warn("Could not read version from package.json, using default");
557
+ return "^0.8.0";
558
+ }
559
+ }
560
+ function getBuenoDependency() {
561
+ return {
562
+ "@buenojs/bueno": getBuenoVersion()
563
+ };
564
+ }
565
+ var cachedVersion = null;
566
+ var init_version = () => {};
567
+
568
+ // src/cli/templates/project/api.ts
569
+ function apiTemplate(config) {
570
+ return {
571
+ files: [
572
+ {
573
+ path: "server/main.ts",
574
+ content: `import { createApp, Module, Controller, Get, Post, Injectable } from '@buenojs/bueno';
575
+ import type { Context } from '@buenojs/bueno';
576
+
577
+ // Services
578
+ @Injectable()
579
+ export class AppService {
580
+ findAll() {
581
+ return { message: 'Welcome to Bueno API!', items: [] };
582
+ }
583
+ }
584
+
585
+ // Controllers
586
+ @Controller('/api')
587
+ export class AppController {
588
+ constructor(private readonly appService: AppService) {}
589
+
590
+ @Get()
591
+ hello() {
592
+ return Response.json({ message: 'Welcome to Bueno API!', version: '1.0.0' });
593
+ }
594
+
595
+ @Get('health')
596
+ health(ctx: Context) {
597
+ return Response.json({ status: 'ok', timestamp: new Date().toISOString() });
598
+ }
599
+ }
600
+
601
+ // Module
602
+ @Module({
603
+ controllers: [AppController],
604
+ providers: [AppService],
605
+ })
606
+ export class AppModule {}
607
+
608
+ // Bootstrap
609
+ const app = createApp(AppModule);
610
+ await app.listen(3000);
611
+ console.log('\uD83D\uDE80 API server running at http://localhost:3000/api');
612
+ `
613
+ }
614
+ ],
615
+ directories: [
616
+ "server/modules/app",
617
+ "server/common/middleware",
618
+ "server/common/guards",
619
+ "server/common/interceptors",
620
+ "server/common/pipes",
621
+ "server/common/filters",
622
+ "server/database/migrations",
623
+ "server/config",
624
+ "tests/unit",
625
+ "tests/integration"
626
+ ],
627
+ dependencies: {
628
+ ...getBuenoDependency(),
629
+ zod: "^3.24.0"
630
+ },
631
+ devDependencies: {
632
+ "@types/bun": "latest",
633
+ typescript: "^5.3.0"
634
+ },
635
+ scripts: {
636
+ dev: "bun run --watch server/main.ts",
637
+ build: "bun build ./server/main.ts --outdir ./dist --target bun",
638
+ start: "bun run dist/main.js",
639
+ test: "bun test"
640
+ }
641
+ };
642
+ }
643
+ var init_api = __esm(() => {
644
+ init_version();
645
+ });
646
+
647
+ // src/cli/templates/frontend/none.ts
648
+ function noneTemplate() {
649
+ return {
650
+ files: [],
651
+ directories: [],
652
+ dependencies: {},
653
+ devDependencies: {},
654
+ scripts: {}
655
+ };
656
+ }
657
+
568
658
  // src/cli/templates/frontend/react.ts
569
659
  function reactTemplate() {
570
660
  return {
@@ -701,8 +791,8 @@ body {
701
791
  };
702
792
  }
703
793
 
704
- // src/cli/templates/frontend/vue.ts
705
- function vueTemplate() {
794
+ // src/cli/templates/frontend/solid.ts
795
+ function solidTemplate() {
706
796
  return {
707
797
  files: [
708
798
  {
@@ -715,72 +805,76 @@ function vueTemplate() {
715
805
  <title>Bueno App</title>
716
806
  </head>
717
807
  <body>
718
- <div id="app"></div>
719
- <script type="module" src="./src/main.ts"></script>
808
+ <div id="root"></div>
809
+ <script type="module" src="./src/main.tsx"></script>
720
810
  </body>
721
811
  </html>
722
812
  `
723
813
  },
724
814
  {
725
- path: "client/src/main.ts",
726
- content: `import { createApp } from 'vue';
727
- import App from './App.vue';
815
+ path: "client/src/main.tsx",
816
+ content: `import { render } from 'solid-js/web';
817
+ import { App } from './App';
728
818
  import './styles/globals.css';
729
819
 
730
- createApp(App).mount('#app');
820
+ const root = document.getElementById('root');
821
+
822
+ if (root) {
823
+ render(() => <App />, root);
824
+ }
731
825
  `
732
826
  },
733
827
  {
734
- path: "client/src/App.vue",
735
- content: `<script setup lang="ts">
736
- import { ref } from 'vue';
828
+ path: "client/src/App.tsx",
829
+ content: `import { createSignal } from 'solid-js';
737
830
 
738
- const count = ref(0);
739
- </script>
831
+ export function App() {
832
+ const [count, setCount] = createSignal(0);
740
833
 
741
- <template>
742
- <main class="min-h-screen bg-gradient-to-br from-slate-900 to-slate-800 text-white">
743
- <div class="container mx-auto px-4 py-16">
744
- <div class="max-w-2xl mx-auto text-center">
745
- <h1 class="text-5xl font-bold mb-4 bg-gradient-to-r from-green-400 to-emerald-500 bg-clip-text text-transparent">
746
- Welcome to Bueno
747
- </h1>
748
- <p class="text-xl text-slate-300 mb-8">
749
- A Bun-native full-stack framework
750
- </p>
751
-
752
- <div class="bg-slate-800/50 rounded-xl p-8 backdrop-blur-sm border border-slate-700">
753
- <button
754
- @click="count++"
755
- class="px-6 py-3 bg-green-500 hover:bg-green-600 rounded-lg font-medium transition-colors"
756
- >
757
- Count: {{ count }}
758
- </button>
759
- <p class="mt-4 text-slate-400 text-sm">
760
- Click the button to test Vue reactivity
834
+ return (
835
+ <main class="min-h-screen bg-gradient-to-br from-slate-900 to-slate-800 text-white">
836
+ <div class="container mx-auto px-4 py-16">
837
+ <div class="max-w-2xl mx-auto text-center">
838
+ <h1 class="text-5xl font-bold mb-4 bg-gradient-to-r from-cyan-400 to-blue-500 bg-clip-text text-transparent">
839
+ Welcome to Bueno
840
+ </h1>
841
+ <p class="text-xl text-slate-300 mb-8">
842
+ A Bun-native full-stack framework
761
843
  </p>
762
- </div>
844
+
845
+ <div class="bg-slate-800/50 rounded-xl p-8 backdrop-blur-sm border border-slate-700">
846
+ <button
847
+ onClick={() => setCount(c => c + 1)}
848
+ class="px-6 py-3 bg-cyan-500 hover:bg-cyan-600 rounded-lg font-medium transition-colors"
849
+ >
850
+ Count: {count()}
851
+ </button>
852
+ <p class="mt-4 text-slate-400 text-sm">
853
+ Click the button to test Solid reactivity
854
+ </p>
855
+ </div>
763
856
 
764
- <div class="mt-8 grid grid-cols-2 gap-4 text-left">
765
- <a
766
- href="https://bueno.github.io"
767
- class="p-4 bg-slate-800/50 rounded-lg border border-slate-700 hover:border-green-500 transition-colors"
768
- >
769
- <h3 class="font-semibold text-green-400">Documentation</h3>
770
- <p class="text-sm text-slate-400">Learn more about Bueno</p>
771
- </a>
772
- <a
773
- href="https://github.com/buenojs/bueno"
774
- class="p-4 bg-slate-800/50 rounded-lg border border-slate-700 hover:border-green-500 transition-colors"
775
- >
776
- <h3 class="font-semibold text-green-400">GitHub</h3>
777
- <p class="text-sm text-slate-400">View the source code</p>
778
- </a>
857
+ <div class="mt-8 grid grid-cols-2 gap-4 text-left">
858
+ <a
859
+ href="https://bueno.github.io"
860
+ class="p-4 bg-slate-800/50 rounded-lg border border-slate-700 hover:border-cyan-500 transition-colors"
861
+ >
862
+ <h3 class="font-semibold text-cyan-400">Documentation</h3>
863
+ <p class="text-sm text-slate-400">Learn more about Bueno</p>
864
+ </a>
865
+ <a
866
+ href="https://github.com/buenojs/bueno"
867
+ class="p-4 bg-slate-800/50 rounded-lg border border-slate-700 hover:border-cyan-500 transition-colors"
868
+ >
869
+ <h3 class="font-semibold text-cyan-400">GitHub</h3>
870
+ <p class="text-sm text-slate-400">View the source code</p>
871
+ </a>
872
+ </div>
779
873
  </div>
780
874
  </div>
781
- </div>
782
- </main>
783
- </template>
875
+ </main>
876
+ );
877
+ }
784
878
  `
785
879
  },
786
880
  {
@@ -813,7 +907,7 @@ body {
813
907
  "client/public"
814
908
  ],
815
909
  dependencies: {
816
- vue: "^3.4.0"
910
+ "solid-js": "^1.8.0"
817
911
  },
818
912
  devDependencies: {
819
913
  tailwindcss: "^3.4.0",
@@ -822,7 +916,7 @@ body {
822
916
  },
823
917
  scripts: {
824
918
  "dev:client": "bun run --watch client/index.html",
825
- "build:client": "bun build ./client/src/main.ts --outdir ./dist/client"
919
+ "build:client": "bun build ./client/src/main.tsx --outdir ./dist/client"
826
920
  }
827
921
  };
828
922
  }
@@ -954,8 +1048,8 @@ body {
954
1048
  };
955
1049
  }
956
1050
 
957
- // src/cli/templates/frontend/solid.ts
958
- function solidTemplate() {
1051
+ // src/cli/templates/frontend/vue.ts
1052
+ function vueTemplate() {
959
1053
  return {
960
1054
  files: [
961
1055
  {
@@ -968,76 +1062,72 @@ function solidTemplate() {
968
1062
  <title>Bueno App</title>
969
1063
  </head>
970
1064
  <body>
971
- <div id="root"></div>
972
- <script type="module" src="./src/main.tsx"></script>
1065
+ <div id="app"></div>
1066
+ <script type="module" src="./src/main.ts"></script>
973
1067
  </body>
974
1068
  </html>
975
1069
  `
976
1070
  },
977
1071
  {
978
- path: "client/src/main.tsx",
979
- content: `import { render } from 'solid-js/web';
980
- import { App } from './App';
1072
+ path: "client/src/main.ts",
1073
+ content: `import { createApp } from 'vue';
1074
+ import App from './App.vue';
981
1075
  import './styles/globals.css';
982
1076
 
983
- const root = document.getElementById('root');
984
-
985
- if (root) {
986
- render(() => <App />, root);
987
- }
1077
+ createApp(App).mount('#app');
988
1078
  `
989
1079
  },
990
1080
  {
991
- path: "client/src/App.tsx",
992
- content: `import { createSignal } from 'solid-js';
1081
+ path: "client/src/App.vue",
1082
+ content: `<script setup lang="ts">
1083
+ import { ref } from 'vue';
993
1084
 
994
- export function App() {
995
- const [count, setCount] = createSignal(0);
1085
+ const count = ref(0);
1086
+ </script>
996
1087
 
997
- return (
998
- <main class="min-h-screen bg-gradient-to-br from-slate-900 to-slate-800 text-white">
999
- <div class="container mx-auto px-4 py-16">
1000
- <div class="max-w-2xl mx-auto text-center">
1001
- <h1 class="text-5xl font-bold mb-4 bg-gradient-to-r from-cyan-400 to-blue-500 bg-clip-text text-transparent">
1002
- Welcome to Bueno
1003
- </h1>
1004
- <p class="text-xl text-slate-300 mb-8">
1005
- A Bun-native full-stack framework
1088
+ <template>
1089
+ <main class="min-h-screen bg-gradient-to-br from-slate-900 to-slate-800 text-white">
1090
+ <div class="container mx-auto px-4 py-16">
1091
+ <div class="max-w-2xl mx-auto text-center">
1092
+ <h1 class="text-5xl font-bold mb-4 bg-gradient-to-r from-green-400 to-emerald-500 bg-clip-text text-transparent">
1093
+ Welcome to Bueno
1094
+ </h1>
1095
+ <p class="text-xl text-slate-300 mb-8">
1096
+ A Bun-native full-stack framework
1097
+ </p>
1098
+
1099
+ <div class="bg-slate-800/50 rounded-xl p-8 backdrop-blur-sm border border-slate-700">
1100
+ <button
1101
+ @click="count++"
1102
+ class="px-6 py-3 bg-green-500 hover:bg-green-600 rounded-lg font-medium transition-colors"
1103
+ >
1104
+ Count: {{ count }}
1105
+ </button>
1106
+ <p class="mt-4 text-slate-400 text-sm">
1107
+ Click the button to test Vue reactivity
1006
1108
  </p>
1007
-
1008
- <div class="bg-slate-800/50 rounded-xl p-8 backdrop-blur-sm border border-slate-700">
1009
- <button
1010
- onClick={() => setCount(c => c + 1)}
1011
- class="px-6 py-3 bg-cyan-500 hover:bg-cyan-600 rounded-lg font-medium transition-colors"
1012
- >
1013
- Count: {count()}
1014
- </button>
1015
- <p class="mt-4 text-slate-400 text-sm">
1016
- Click the button to test Solid reactivity
1017
- </p>
1018
- </div>
1109
+ </div>
1019
1110
 
1020
- <div class="mt-8 grid grid-cols-2 gap-4 text-left">
1021
- <a
1022
- href="https://bueno.github.io"
1023
- class="p-4 bg-slate-800/50 rounded-lg border border-slate-700 hover:border-cyan-500 transition-colors"
1024
- >
1025
- <h3 class="font-semibold text-cyan-400">Documentation</h3>
1026
- <p class="text-sm text-slate-400">Learn more about Bueno</p>
1027
- </a>
1028
- <a
1029
- href="https://github.com/buenojs/bueno"
1030
- class="p-4 bg-slate-800/50 rounded-lg border border-slate-700 hover:border-cyan-500 transition-colors"
1031
- >
1032
- <h3 class="font-semibold text-cyan-400">GitHub</h3>
1033
- <p class="text-sm text-slate-400">View the source code</p>
1034
- </a>
1035
- </div>
1111
+ <div class="mt-8 grid grid-cols-2 gap-4 text-left">
1112
+ <a
1113
+ href="https://bueno.github.io"
1114
+ class="p-4 bg-slate-800/50 rounded-lg border border-slate-700 hover:border-green-500 transition-colors"
1115
+ >
1116
+ <h3 class="font-semibold text-green-400">Documentation</h3>
1117
+ <p class="text-sm text-slate-400">Learn more about Bueno</p>
1118
+ </a>
1119
+ <a
1120
+ href="https://github.com/buenojs/bueno"
1121
+ class="p-4 bg-slate-800/50 rounded-lg border border-slate-700 hover:border-green-500 transition-colors"
1122
+ >
1123
+ <h3 class="font-semibold text-green-400">GitHub</h3>
1124
+ <p class="text-sm text-slate-400">View the source code</p>
1125
+ </a>
1036
1126
  </div>
1037
1127
  </div>
1038
- </main>
1039
- );
1040
- }
1128
+ </div>
1129
+ </main>
1130
+ </template>
1041
1131
  `
1042
1132
  },
1043
1133
  {
@@ -1070,28 +1160,17 @@ body {
1070
1160
  "client/public"
1071
1161
  ],
1072
1162
  dependencies: {
1073
- "solid-js": "^1.8.0"
1074
- },
1075
- devDependencies: {
1076
- tailwindcss: "^3.4.0",
1077
- postcss: "^8.4.0",
1078
- autoprefixer: "^10.4.0"
1079
- },
1080
- scripts: {
1081
- "dev:client": "bun run --watch client/index.html",
1082
- "build:client": "bun build ./client/src/main.tsx --outdir ./dist/client"
1083
- }
1084
- };
1085
- }
1086
-
1087
- // src/cli/templates/frontend/none.ts
1088
- function noneTemplate() {
1089
- return {
1090
- files: [],
1091
- directories: [],
1092
- dependencies: {},
1093
- devDependencies: {},
1094
- scripts: {}
1163
+ vue: "^3.4.0"
1164
+ },
1165
+ devDependencies: {
1166
+ tailwindcss: "^3.4.0",
1167
+ postcss: "^8.4.0",
1168
+ autoprefixer: "^10.4.0"
1169
+ },
1170
+ scripts: {
1171
+ "dev:client": "bun run --watch client/index.html",
1172
+ "build:client": "bun build ./client/src/main.ts --outdir ./dist/client"
1173
+ }
1095
1174
  };
1096
1175
  }
1097
1176
 
@@ -1217,44 +1296,6 @@ await app.listen(3000);
1217
1296
  }
1218
1297
  var init_default = () => {};
1219
1298
 
1220
- // src/cli/templates/project/minimal.ts
1221
- function minimalTemplate(config) {
1222
- return {
1223
- files: [
1224
- {
1225
- path: "server/main.ts",
1226
- content: `import { createServer } from '@buenojs/bueno';
1227
-
1228
- const app = createServer();
1229
-
1230
- app.router.get('/', () => {
1231
- return { message: 'Hello, Bueno!' };
1232
- });
1233
-
1234
- await app.listen(3000);
1235
- `
1236
- }
1237
- ],
1238
- directories: ["server", "tests"],
1239
- dependencies: {
1240
- ...getBuenoDependency()
1241
- },
1242
- devDependencies: {
1243
- "@types/bun": "latest",
1244
- typescript: "^5.3.0"
1245
- },
1246
- scripts: {
1247
- dev: "bun run --watch server/main.ts",
1248
- build: "bun build ./server/main.ts --outdir ./dist --target bun",
1249
- start: "bun run dist/main.js",
1250
- test: "bun test"
1251
- }
1252
- };
1253
- }
1254
- var init_minimal = __esm(() => {
1255
- init_version();
1256
- });
1257
-
1258
1299
  // src/cli/templates/project/fullstack.ts
1259
1300
  function fullstackTemplate(config) {
1260
1301
  const frontendTemplates = {
@@ -1346,67 +1387,32 @@ console.log('\uD83D\uDE80 Server running at http://localhost:3000');
1346
1387
  }
1347
1388
  var init_fullstack = () => {};
1348
1389
 
1349
- // src/cli/templates/project/api.ts
1350
- function apiTemplate(config) {
1390
+ // src/cli/templates/project/minimal.ts
1391
+ function minimalTemplate(config) {
1351
1392
  return {
1352
1393
  files: [
1353
1394
  {
1354
1395
  path: "server/main.ts",
1355
- content: `import { createApp, Module, Controller, Get, Post, Injectable } from '@buenojs/bueno';
1356
- import type { Context } from '@buenojs/bueno';
1357
-
1358
- // Services
1359
- @Injectable()
1360
- export class AppService {
1361
- findAll() {
1362
- return { message: 'Welcome to Bueno API!', items: [] };
1363
- }
1364
- }
1365
-
1366
- // Controllers
1367
- @Controller()
1368
- export class AppController {
1369
- constructor(private readonly appService: AppService) {}
1396
+ content: `import { createServer } from '@buenojs/bueno';
1370
1397
 
1371
- @Get()
1372
- hello() {
1373
- return { message: 'Welcome to Bueno API!', version: '1.0.0' };
1374
- }
1398
+ const app = createServer();
1375
1399
 
1376
- @Get('health')
1377
- health(ctx: Context) {
1378
- return { status: 'ok', timestamp: new Date().toISOString() };
1379
- }
1380
- }
1400
+ app.router.get('/', () => {
1401
+ return Response.json({ message: 'Hello, Bueno!' });
1402
+ });
1381
1403
 
1382
- // Module
1383
- @Module({
1384
- controllers: [AppController],
1385
- providers: [AppService],
1386
- })
1387
- export class AppModule {}
1404
+ app.router.get('/health', () => {
1405
+ return Response.json({ status: 'ok', timestamp: new Date().toISOString() });
1406
+ });
1388
1407
 
1389
- // Bootstrap
1390
- const app = createApp(AppModule);
1391
1408
  await app.listen(3000);
1409
+ console.log('\uD83D\uDE80 Server running at http://localhost:3000');
1392
1410
  `
1393
1411
  }
1394
1412
  ],
1395
- directories: [
1396
- "server/modules/app",
1397
- "server/common/middleware",
1398
- "server/common/guards",
1399
- "server/common/interceptors",
1400
- "server/common/pipes",
1401
- "server/common/filters",
1402
- "server/database/migrations",
1403
- "server/config",
1404
- "tests/unit",
1405
- "tests/integration"
1406
- ],
1413
+ directories: ["server", "tests"],
1407
1414
  dependencies: {
1408
- ...getBuenoDependency(),
1409
- zod: "^3.24.0"
1415
+ ...getBuenoDependency()
1410
1416
  },
1411
1417
  devDependencies: {
1412
1418
  "@types/bun": "latest",
@@ -1420,7 +1426,7 @@ await app.listen(3000);
1420
1426
  }
1421
1427
  };
1422
1428
  }
1423
- var init_api = __esm(() => {
1429
+ var init_minimal = __esm(() => {
1424
1430
  init_version();
1425
1431
  });
1426
1432
 
@@ -1436,7 +1442,7 @@ function websiteTemplate(config) {
1436
1442
  * Uses Bueno's SSG module to generate static HTML from markdown content
1437
1443
  */
1438
1444
 
1439
- import { SSG, createSSG, type SiteConfig, type LayoutContext } from 'bueno';
1445
+ import { SSG, createSSG, type SiteConfig, type LayoutContext } from '@buenojs/bueno';
1440
1446
 
1441
1447
  // Site configuration
1442
1448
  const siteConfig: Partial<SiteConfig> = {
@@ -1689,19 +1695,39 @@ function getProjectTemplate(template) {
1689
1695
  }
1690
1696
  function getTemplateOptions() {
1691
1697
  return [
1692
- { value: "default", name: "Default", description: "Standard project with modules and database" },
1693
- { value: "minimal", name: "Minimal", description: "Bare minimum project structure" },
1694
- { value: "fullstack", name: "Fullstack", description: "Full-stack project with SSR and frontend" },
1695
- { value: "api", name: "API", description: "API-only project without frontend" },
1696
- { value: "website", name: "Website", description: "Static website with SSG" }
1698
+ {
1699
+ value: "default",
1700
+ name: "Default",
1701
+ description: "Standard project with modules and database"
1702
+ },
1703
+ {
1704
+ value: "minimal",
1705
+ name: "Minimal",
1706
+ description: "Bare minimum project structure"
1707
+ },
1708
+ {
1709
+ value: "fullstack",
1710
+ name: "Fullstack",
1711
+ description: "Full-stack project with SSR and frontend"
1712
+ },
1713
+ {
1714
+ value: "api",
1715
+ name: "API",
1716
+ description: "API-only project without frontend"
1717
+ },
1718
+ {
1719
+ value: "website",
1720
+ name: "Website",
1721
+ description: "Static website with SSG"
1722
+ }
1697
1723
  ];
1698
1724
  }
1699
1725
  var projectTemplates;
1700
1726
  var init_project = __esm(() => {
1727
+ init_api();
1701
1728
  init_default();
1702
- init_minimal();
1703
1729
  init_fullstack();
1704
- init_api();
1730
+ init_minimal();
1705
1731
  init_website();
1706
1732
  projectTemplates = {
1707
1733
  default: defaultTemplate,
@@ -1712,43 +1738,43 @@ var init_project = __esm(() => {
1712
1738
  };
1713
1739
  });
1714
1740
 
1715
- // src/cli/templates/database/sqlite.ts
1716
- function sqliteTemplate() {
1741
+ // src/cli/templates/database/mysql.ts
1742
+ function mysqlTemplate() {
1717
1743
  return {
1718
1744
  files: [],
1719
1745
  directories: [],
1720
- envConfig: "DATABASE_URL=sqlite:./data.db",
1721
- configCode: `{ url: 'sqlite:./data.db' }`
1746
+ envConfig: "DATABASE_URL=mysql://user:password@localhost:3306/dbname",
1747
+ configCode: `{ url: process.env.DATABASE_URL ?? 'mysql://localhost/dbname' }`
1722
1748
  };
1723
1749
  }
1724
1750
 
1725
- // src/cli/templates/database/postgresql.ts
1726
- function postgresqlTemplate() {
1751
+ // src/cli/templates/database/none.ts
1752
+ function noneTemplate2() {
1727
1753
  return {
1728
1754
  files: [],
1729
1755
  directories: [],
1730
- envConfig: "DATABASE_URL=postgresql://user:password@localhost:5432/dbname",
1731
- configCode: `{ url: process.env.DATABASE_URL ?? 'postgresql://localhost/dbname' }`
1756
+ envConfig: undefined,
1757
+ configCode: undefined
1732
1758
  };
1733
1759
  }
1734
1760
 
1735
- // src/cli/templates/database/mysql.ts
1736
- function mysqlTemplate() {
1761
+ // src/cli/templates/database/postgresql.ts
1762
+ function postgresqlTemplate() {
1737
1763
  return {
1738
1764
  files: [],
1739
1765
  directories: [],
1740
- envConfig: "DATABASE_URL=mysql://user:password@localhost:3306/dbname",
1741
- configCode: `{ url: process.env.DATABASE_URL ?? 'mysql://localhost/dbname' }`
1766
+ envConfig: "DATABASE_URL=postgresql://user:password@localhost:5432/dbname",
1767
+ configCode: `{ url: process.env.DATABASE_URL ?? 'postgresql://localhost/dbname' }`
1742
1768
  };
1743
1769
  }
1744
1770
 
1745
- // src/cli/templates/database/none.ts
1746
- function noneTemplate2() {
1771
+ // src/cli/templates/database/sqlite.ts
1772
+ function sqliteTemplate() {
1747
1773
  return {
1748
1774
  files: [],
1749
1775
  directories: [],
1750
- envConfig: undefined,
1751
- configCode: undefined
1776
+ envConfig: "DATABASE_URL=sqlite:./data.db",
1777
+ configCode: `{ url: 'sqlite:./data.db' }`
1752
1778
  };
1753
1779
  }
1754
1780
 
@@ -1759,9 +1785,21 @@ function getDatabaseTemplate(driver) {
1759
1785
  function getDatabaseOptions() {
1760
1786
  return [
1761
1787
  { value: "none", name: "None", description: "No database required" },
1762
- { value: "sqlite", name: "SQLite", description: "Local file-based database" },
1763
- { value: "postgresql", name: "PostgreSQL", description: "Production-ready relational database" },
1764
- { value: "mysql", name: "MySQL", description: "Popular relational database" }
1788
+ {
1789
+ value: "sqlite",
1790
+ name: "SQLite",
1791
+ description: "Local file-based database"
1792
+ },
1793
+ {
1794
+ value: "postgresql",
1795
+ name: "PostgreSQL",
1796
+ description: "Production-ready relational database"
1797
+ },
1798
+ {
1799
+ value: "mysql",
1800
+ name: "MySQL",
1801
+ description: "Popular relational database"
1802
+ }
1765
1803
  ];
1766
1804
  }
1767
1805
  var databaseTemplates;
@@ -2058,7 +2096,7 @@ export const {{camelCase name}}Middleware: Middleware = async (
2058
2096
  }
2059
2097
  function getMigrationTemplate(config) {
2060
2098
  const migrationId = generateMigrationId();
2061
- return `import { createMigration, type MigrationRunner } from '@buenojs/bueno';
2099
+ return `import { createMigration, type MigrationRunner } from '@buenojs/bueno/migrations';
2062
2100
 
2063
2101
  export default createMigration('${migrationId}', '{{migrationName}}')
2064
2102
  .up(async (db: MigrationRunner) => {
@@ -2142,6 +2180,46 @@ var init_templates = __esm(() => {
2142
2180
  import { readFileSync as readFileSync3 } from "fs";
2143
2181
  import { join as join3 } from "path";
2144
2182
 
2183
+ // src/cli/commands/index.ts
2184
+ class CommandRegistry {
2185
+ commands = new Map;
2186
+ aliases = new Map;
2187
+ register(definition, handler) {
2188
+ this.commands.set(definition.name, {
2189
+ definition,
2190
+ handler
2191
+ });
2192
+ if (definition.alias) {
2193
+ this.aliases.set(definition.alias, definition.name);
2194
+ }
2195
+ }
2196
+ get(name) {
2197
+ const commandName = this.aliases.get(name) ?? name;
2198
+ return this.commands.get(commandName);
2199
+ }
2200
+ has(name) {
2201
+ const commandName = this.aliases.get(name) ?? name;
2202
+ return this.commands.has(commandName);
2203
+ }
2204
+ getAll() {
2205
+ return Array.from(this.commands.values()).map((c) => c.definition);
2206
+ }
2207
+ getCommands() {
2208
+ return new Map(this.commands);
2209
+ }
2210
+ async execute(name, args) {
2211
+ const command = this.get(name);
2212
+ if (!command) {
2213
+ throw new Error(`Unknown command: ${name}`);
2214
+ }
2215
+ await command.handler(args);
2216
+ }
2217
+ }
2218
+ var registry = new CommandRegistry;
2219
+ function defineCommand(definition, handler) {
2220
+ registry.register(definition, handler);
2221
+ }
2222
+
2145
2223
  // src/cli/core/args.ts
2146
2224
  function parseArgs(argv = process.argv.slice(2)) {
2147
2225
  const result = {
@@ -2208,7 +2286,7 @@ function getOption(parsed, name, definition) {
2208
2286
  return value === true || value === "true";
2209
2287
  }
2210
2288
  if (definition.type === "number") {
2211
- return typeof value === "number" ? value : typeof value === "string" ? parseInt(value, 10) : NaN;
2289
+ return typeof value === "number" ? value : typeof value === "string" ? Number.parseInt(value, 10) : Number.NaN;
2212
2290
  }
2213
2291
  return value;
2214
2292
  }
@@ -2424,11 +2502,7 @@ function formatTable(headers, rows, options = {}) {
2424
2502
  const headerLine = headers.map((h, i) => h.padEnd(widths[i] ?? 0)).join(pad);
2425
2503
  const separator = widths.map((w) => "\u2500".repeat(w)).join(pad);
2426
2504
  const rowLines = rows.map((row) => row.map((cell, i) => (cell ?? "").padEnd(widths[i] ?? 0)).join(pad));
2427
- return [
2428
- colors.bold(headerLine),
2429
- colors.dim(separator),
2430
- ...rowLines
2431
- ].join(`
2505
+ return [colors.bold(headerLine), colors.dim(separator), ...rowLines].join(`
2432
2506
  `);
2433
2507
  }
2434
2508
  function printTable(headers, rows, options) {
@@ -2452,46 +2526,6 @@ function formatDuration(ms) {
2452
2526
  return `${(ms / 60000).toFixed(1)}m`;
2453
2527
  }
2454
2528
 
2455
- // src/cli/commands/index.ts
2456
- class CommandRegistry {
2457
- commands = new Map;
2458
- aliases = new Map;
2459
- register(definition, handler) {
2460
- this.commands.set(definition.name, {
2461
- definition,
2462
- handler
2463
- });
2464
- if (definition.alias) {
2465
- this.aliases.set(definition.alias, definition.name);
2466
- }
2467
- }
2468
- get(name) {
2469
- const commandName = this.aliases.get(name) ?? name;
2470
- return this.commands.get(commandName);
2471
- }
2472
- has(name) {
2473
- const commandName = this.aliases.get(name) ?? name;
2474
- return this.commands.has(commandName);
2475
- }
2476
- getAll() {
2477
- return Array.from(this.commands.values()).map((c) => c.definition);
2478
- }
2479
- getCommands() {
2480
- return new Map(this.commands);
2481
- }
2482
- async execute(name, args) {
2483
- const command = this.get(name);
2484
- if (!command) {
2485
- throw new Error(`Unknown command: ${name}`);
2486
- }
2487
- await command.handler(args);
2488
- }
2489
- }
2490
- var registry = new CommandRegistry;
2491
- function defineCommand(definition, handler) {
2492
- registry.register(definition, handler);
2493
- }
2494
-
2495
2529
  // src/cli/core/prompt.ts
2496
2530
  import * as readline from "readline";
2497
2531
  function isInteractive() {
@@ -2769,6 +2803,10 @@ async function runTasks(tasks) {
2769
2803
  }
2770
2804
  }
2771
2805
 
2806
+ // src/cli/commands/new.ts
2807
+ init_templates();
2808
+ init_templates();
2809
+
2772
2810
  // src/cli/utils/fs.ts
2773
2811
  import * as fs from "fs";
2774
2812
  import * as path from "path";
@@ -2920,8 +2958,6 @@ function kebabCase(str) {
2920
2958
  // src/cli/commands/new.ts
2921
2959
  init_version();
2922
2960
  init_templates();
2923
- init_templates();
2924
- init_templates();
2925
2961
  function validateProjectName(name) {
2926
2962
  if (!name || name.length === 0) {
2927
2963
  return "Project name is required";
@@ -3297,9 +3333,18 @@ async function handleNew(args) {
3297
3333
  ["Framework", isWebsite ? "N/A (Static Site)" : framework],
3298
3334
  ["Database", isWebsite ? "N/A" : database],
3299
3335
  ["Docker", docker ? colors.green("Yes") : colors.red("No")],
3300
- ["Deploy", deploy.length > 0 ? colors.green(deploy.map(getDeployPlatformName).join(", ")) : colors.red("None")],
3301
- ["Install dependencies", skipInstall ? colors.red("No") : colors.green("Yes")],
3302
- ["Use local package", link ? colors.green("Yes (bun link)") : colors.red("No")]
3336
+ [
3337
+ "Deploy",
3338
+ deploy.length > 0 ? colors.green(deploy.map(getDeployPlatformName).join(", ")) : colors.red("None")
3339
+ ],
3340
+ [
3341
+ "Install dependencies",
3342
+ skipInstall ? colors.red("No") : colors.green("Yes")
3343
+ ],
3344
+ [
3345
+ "Use local package",
3346
+ link ? colors.green("Yes (bun link)") : colors.red("No")
3347
+ ]
3303
3348
  ];
3304
3349
  printTable(["Setting", "Value"], rows);
3305
3350
  cliConsole.log("");
@@ -3455,7 +3500,9 @@ var GENERATOR_ALIASES2 = {
3455
3500
  f: "filter",
3456
3501
  d: "dto",
3457
3502
  mw: "middleware",
3458
- mi: "migration"
3503
+ mi: "migration",
3504
+ j: "job",
3505
+ jh: "job-handler"
3459
3506
  };
3460
3507
  function getTemplate(type) {
3461
3508
  const templates = {
@@ -3649,7 +3696,7 @@ export const {{camelCase name}}Middleware: Middleware = async (
3649
3696
  return result;
3650
3697
  };
3651
3698
  `,
3652
- migration: `import { createMigration, type MigrationRunner } from '@buenojs/bueno';
3699
+ migration: `import { createMigration, type MigrationRunner } from '@buenojs/bueno/migrations';
3653
3700
 
3654
3701
  export default createMigration('{{migrationId}}', '{{migrationName}}')
3655
3702
  .up(async (db: MigrationRunner) => {
@@ -3668,12 +3715,35 @@ export default createMigration('{{migrationId}}', '{{migrationName}}')
3668
3715
  // Example:
3669
3716
  // await db.dropTable('{{tableName}}');
3670
3717
  });
3718
+ `,
3719
+ job: `export interface {{pascalCase name}}JobData {
3720
+ // TODO: Define job data properties
3721
+ }
3722
+
3723
+ export const {{camelCase name}} = (data: {{pascalCase name}}JobData) => ({
3724
+ name: '{{camelCase name}}',
3725
+ data,
3726
+ });
3727
+ `,
3728
+ "job-handler": `import { type JobHandler } from '@buenojs/bueno/jobs';
3729
+ import type { {{pascalCase name}}JobData } from './{{kebabCase name}}.job';
3730
+
3731
+ export const handle{{pascalCase name}}: JobHandler<{{pascalCase name}}JobData> = async (job) => {
3732
+ const { data } = job;
3733
+ // TODO: Implement job logic
3734
+ };
3671
3735
  `
3672
3736
  };
3673
3737
  return templates[type];
3674
3738
  }
3675
3739
  function getFileExtension2(type) {
3676
- return type === "dto" ? ".dto.ts" : ".ts";
3740
+ if (type === "dto")
3741
+ return ".dto.ts";
3742
+ if (type === "job")
3743
+ return ".job.ts";
3744
+ if (type === "job-handler")
3745
+ return ".handler.ts";
3746
+ return ".ts";
3677
3747
  }
3678
3748
  function getDefaultDirectory2(type) {
3679
3749
  switch (type) {
@@ -3694,6 +3764,10 @@ function getDefaultDirectory2(type) {
3694
3764
  return "common/middleware";
3695
3765
  case "migration":
3696
3766
  return "database/migrations";
3767
+ case "job":
3768
+ return "modules/jobs";
3769
+ case "job-handler":
3770
+ return "modules/jobs/handlers";
3697
3771
  default:
3698
3772
  return "";
3699
3773
  }
@@ -3905,7 +3979,7 @@ async function createMigration(name, dryRun) {
3905
3979
  const kebabName = name.toLowerCase().replace(/\s+/g, "-");
3906
3980
  const fileName = `${id}_${kebabName}.ts`;
3907
3981
  const filePath = joinPaths(migrationsDir, fileName);
3908
- const template = `import { createMigration, type MigrationRunner } from '@buenojs/bueno';
3982
+ const template = `import { createMigration, type MigrationRunner } from '@buenojs/bueno/migrations';
3909
3983
 
3910
3984
  export default createMigration('${id}', '${kebabName}')
3911
3985
  .up(async (db: MigrationRunner) => {
@@ -3957,7 +4031,14 @@ async function handleMigration(args) {
3957
4031
  if (!action) {
3958
4032
  throw new CLIError("Action is required. Usage: bueno migration <action>", "INVALID_ARGS" /* INVALID_ARGS */);
3959
4033
  }
3960
- const validActions = ["create", "up", "down", "reset", "refresh", "status"];
4034
+ const validActions = [
4035
+ "create",
4036
+ "up",
4037
+ "down",
4038
+ "reset",
4039
+ "refresh",
4040
+ "status"
4041
+ ];
3961
4042
  if (!validActions.includes(action)) {
3962
4043
  throw new CLIError(`Unknown action: ${action}. Valid actions: ${validActions.join(", ")}`, "INVALID_ARGS" /* INVALID_ARGS */);
3963
4044
  }
@@ -4001,7 +4082,7 @@ async function handleMigration(args) {
4001
4082
  cliConsole.log("");
4002
4083
  cliConsole.log("Example:");
4003
4084
  cliConsole.log(colors.cyan(`
4004
- import { createMigrationRunner, loadMigrations } from '@buenojs/bueno';
4085
+ import { createMigrationRunner, loadMigrations } from '@buenojs/bueno/migrations';
4005
4086
  import { db } from './database';
4006
4087
 
4007
4088
  const runner = createMigrationRunner(db);
@@ -4017,7 +4098,7 @@ await runner.migrate(migrations);
4017
4098
  cliConsole.log("");
4018
4099
  cliConsole.log("Example:");
4019
4100
  cliConsole.log(colors.cyan(`
4020
- import { createMigrationRunner, loadMigrations } from '@buenojs/bueno';
4101
+ import { createMigrationRunner, loadMigrations } from '@buenojs/bueno/migrations';
4021
4102
  import { db } from './database';
4022
4103
 
4023
4104
  const runner = createMigrationRunner(db);
@@ -4033,7 +4114,7 @@ await runner.rollback(migrations, ${steps});
4033
4114
  cliConsole.log("");
4034
4115
  cliConsole.log("Example:");
4035
4116
  cliConsole.log(colors.cyan(`
4036
- import { createMigrationRunner, loadMigrations } from '@buenojs/bueno';
4117
+ import { createMigrationRunner, loadMigrations } from '@buenojs/bueno/migrations';
4037
4118
  import { db } from './database';
4038
4119
 
4039
4120
  const runner = createMigrationRunner(db);
@@ -4049,7 +4130,7 @@ await runner.reset(migrations);
4049
4130
  cliConsole.log("");
4050
4131
  cliConsole.log("Example:");
4051
4132
  cliConsole.log(colors.cyan(`
4052
- import { createMigrationRunner, loadMigrations } from '@buenojs/bueno';
4133
+ import { createMigrationRunner, loadMigrations } from '@buenojs/bueno/migrations';
4053
4134
  import { db } from './database';
4054
4135
 
4055
4136
  const runner = createMigrationRunner(db);