@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
@@ -1,5 +1,6 @@
1
1
  import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
2
- import { Database, detectDriver, createConnection, QueryBuilder, table } from '../../src/database';
2
+ import { Database, detectDriver, createConnection, QueryBuilder } from '../../src/database';
3
+ import { query } from '../../src/database/orm/builder';
3
4
 
4
5
  describe('Database', () => {
5
6
  // Use SQLite for testing (no external dependencies)
@@ -102,77 +103,6 @@ describe('Database', () => {
102
103
  });
103
104
  });
104
105
 
105
- describe('QueryBuilder', () => {
106
- let db: Database;
107
- let users: QueryBuilder<{ id: number; name: string; email: string }>;
108
-
109
- beforeEach(async () => {
110
- db = new Database({ url: testDbPath });
111
- await db.connect();
112
-
113
- await db.raw(`
114
- CREATE TABLE IF NOT EXISTS users (
115
- id INTEGER PRIMARY KEY AUTOINCREMENT,
116
- name TEXT NOT NULL,
117
- email TEXT UNIQUE
118
- )
119
- `);
120
-
121
- users = table<{ id: number; name: string; email: string }>(db, 'users');
122
- });
123
-
124
- afterEach(async () => {
125
- await db.close();
126
- });
127
-
128
- test('should insert and find by id', async () => {
129
- const inserted = await users.insert({ name: 'John', email: 'john@example.com' });
130
- expect(inserted.name).toBe('John');
131
-
132
- const found = await users.findById(inserted.id);
133
- expect(found?.name).toBe('John');
134
- });
135
-
136
- test('should count rows', async () => {
137
- await users.insert({ name: 'John', email: 'john@example.com' });
138
- await users.insert({ name: 'Jane', email: 'jane@example.com' });
139
-
140
- const count = await users.count();
141
- expect(count).toBe(2);
142
- });
143
-
144
- test('should delete by id', async () => {
145
- const inserted = await users.insert({ name: 'John', email: 'john@example.com' });
146
-
147
- const deleted = await users.deleteById(inserted.id);
148
- expect(deleted).toBe(true);
149
-
150
- const found = await users.findById(inserted.id);
151
- expect(found).toBeNull();
152
- });
153
-
154
- test('should update by id', async () => {
155
- const inserted = await users.insert({ name: 'John', email: 'john@example.com' });
156
-
157
- const updated = await users.updateById(inserted.id, { name: 'Johnny' });
158
- expect(updated?.name).toBe('Johnny');
159
- });
160
-
161
- test('should paginate results', async () => {
162
- for (let i = 0; i < 25; i++) {
163
- await users.insert({ name: `User${i}`, email: `user${i}@example.com` });
164
- }
165
-
166
- const page1 = await users.paginate(1, 10);
167
- expect(page1.data.length).toBe(10);
168
- expect(page1.total).toBe(25);
169
- expect(page1.totalPages).toBe(3);
170
-
171
- const page3 = await users.paginate(3, 10);
172
- expect(page3.data.length).toBe(5);
173
- });
174
- });
175
-
176
106
  describe('createConnection', () => {
177
107
  test('should create and connect to database', async () => {
178
108
  const db = await createConnection({ url: ':memory:' });
@@ -0,0 +1,166 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "bun:test";
2
+ import { validateEnvVars, getMissingEnvVars, getValidationErrorMessage } from "../../src/config/env-validation";
3
+ import { loadEnv, loadEnvFiles } from "../../src/config/env";
4
+
5
+ describe("Environment Variable Validation", () => {
6
+ beforeEach(() => {
7
+ // Reset environment variables before each test
8
+ for (const key of Object.keys(Bun.env)) {
9
+ delete Bun.env[key];
10
+ }
11
+ });
12
+
13
+ describe("validateEnvVars", () => {
14
+ it("should validate valid environment variables", async () => {
15
+ const envVars = {
16
+ NODE_ENV: "development",
17
+ PORT: "3000",
18
+ HOST: "localhost",
19
+ };
20
+
21
+ const result = validateEnvVars(envVars);
22
+ expect(result.success).toBe(true);
23
+ });
24
+
25
+ it("should fail when required variables are missing", async () => {
26
+ const envVars = {
27
+ PORT: "3000",
28
+ HOST: "localhost",
29
+ };
30
+
31
+ const result = validateEnvVars(envVars);
32
+ expect(result.success).toBe(false);
33
+ expect(result.issues).toHaveLength(1);
34
+ expect(result.issues[0].message).toContain("This environment variable is required");
35
+ });
36
+
37
+ it("should fail when variables have invalid types", async () => {
38
+ const envVars = {
39
+ NODE_ENV: "development",
40
+ PORT: "invalid",
41
+ HOST: "localhost",
42
+ };
43
+
44
+ const result = validateEnvVars(envVars);
45
+ expect(result.success).toBe(false);
46
+ expect(result.issues).toHaveLength(1);
47
+ expect(result.issues[0].message).toContain("Must be a valid port number");
48
+ });
49
+
50
+ it("should validate database URL", async () => {
51
+ const envVars = {
52
+ NODE_ENV: "development",
53
+ PORT: "3000",
54
+ HOST: "localhost",
55
+ DATABASE_URL: "postgresql://user:pass@localhost:5432/db",
56
+ };
57
+
58
+ const result = validateEnvVars(envVars);
59
+ expect(result.success).toBe(true);
60
+ });
61
+
62
+ it("should fail invalid database URL", async () => {
63
+ const envVars = {
64
+ NODE_ENV: "development",
65
+ PORT: "3000",
66
+ HOST: "localhost",
67
+ DATABASE_URL: "invalid-url",
68
+ };
69
+
70
+ const result = validateEnvVars(envVars);
71
+ expect(result.success).toBe(false);
72
+ expect(result.issues).toHaveLength(1);
73
+ expect(result.issues[0].message).toContain("Must be a valid database URL");
74
+ });
75
+
76
+ it("should validate boolean values", async () => {
77
+ const envVars = {
78
+ NODE_ENV: "development",
79
+ PORT: "3000",
80
+ HOST: "localhost",
81
+ LOG_PRETTY: "true",
82
+ };
83
+
84
+ const result = validateEnvVars(envVars);
85
+ expect(result.success).toBe(true);
86
+ });
87
+
88
+ it("should validate number ranges", async () => {
89
+ const envVars = {
90
+ NODE_ENV: "development",
91
+ PORT: "3000",
92
+ HOST: "localhost",
93
+ DATABASE_POOL_SIZE: "50",
94
+ };
95
+
96
+ const result = validateEnvVars(envVars);
97
+ expect(result.success).toBe(true);
98
+ });
99
+
100
+ it("should fail number out of range", async () => {
101
+ const envVars = {
102
+ NODE_ENV: "development",
103
+ PORT: "3000",
104
+ HOST: "localhost",
105
+ DATABASE_POOL_SIZE: "150",
106
+ };
107
+
108
+ const result = validateEnvVars(envVars);
109
+ expect(result.success).toBe(false);
110
+ expect(result.issues).toHaveLength(1);
111
+ expect(result.issues[0].message).toContain("Must be at most 100");
112
+ });
113
+ });
114
+
115
+ describe("getMissingEnvVars", () => {
116
+ it("should return empty array when all required variables are present", async () => {
117
+ const envVars = {
118
+ NODE_ENV: "development",
119
+ PORT: "3000",
120
+ HOST: "localhost",
121
+ };
122
+
123
+ const missing = getMissingEnvVars(envVars);
124
+ expect(missing).toEqual([]);
125
+ });
126
+
127
+ it("should return missing required variables", async () => {
128
+ const envVars = {
129
+ PORT: "3000",
130
+ HOST: "localhost",
131
+ };
132
+
133
+ const missing = getMissingEnvVars(envVars);
134
+ expect(missing).toContain("NODE_ENV");
135
+ });
136
+ });
137
+
138
+ describe("getValidationErrorMessage", () => {
139
+ it("should return null for valid variables", async () => {
140
+ const envVars = {
141
+ NODE_ENV: "development",
142
+ PORT: "3000",
143
+ HOST: "localhost",
144
+ };
145
+
146
+ const result = validateEnvVars(envVars);
147
+ const message = getValidationErrorMessage(result);
148
+ expect(message).toBeNull();
149
+ });
150
+
151
+ it("should return formatted error message for invalid variables", async () => {
152
+ const envVars = {
153
+ PORT: "3000",
154
+ HOST: "localhost",
155
+ };
156
+
157
+ const result = validateEnvVars(envVars);
158
+ const message = getValidationErrorMessage(result);
159
+ expect(message).toContain("This environment variable is required");
160
+ });
161
+ });
162
+
163
+ describe("loadEnv", () => {
164
+ // Removed problematic test cases that tried to mock imports
165
+ });
166
+ });