@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
@@ -0,0 +1,273 @@
1
+ // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true,
8
+ configurable: true,
9
+ set: (newValue) => all[name] = () => newValue
10
+ });
11
+ };
12
+ var __legacyDecorateClassTS = function(decorators, target, key, desc) {
13
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
15
+ r = Reflect.decorate(decorators, target, key, desc);
16
+ else
17
+ for (var i = decorators.length - 1;i >= 0; i--)
18
+ if (d = decorators[i])
19
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
20
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
21
+ };
22
+ var __legacyMetadataTS = (k, v) => {
23
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
24
+ return Reflect.metadata(k, v);
25
+ };
26
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
27
+ var __require = import.meta.require;
28
+
29
+ // src/container/forward-ref.ts
30
+ function forwardRef(fn) {
31
+ return {
32
+ __forwardRef: FORWARD_REF_SYMBOL,
33
+ forwardRef: fn
34
+ };
35
+ }
36
+ function isForwardRef(value) {
37
+ return typeof value === "object" && value !== null && "__forwardRef" in value && "forwardRef" in value && typeof value.forwardRef === "function";
38
+ }
39
+ function resolveForwardRef(ref) {
40
+ if (isForwardRef(ref)) {
41
+ return ref.forwardRef();
42
+ }
43
+ return ref;
44
+ }
45
+ var FORWARD_REF_SYMBOL;
46
+ var init_forward_ref = __esm(() => {
47
+ FORWARD_REF_SYMBOL = Symbol.for("buno.forwardRef");
48
+ });
49
+
50
+ // src/container/index.ts
51
+ var exports_container = {};
52
+ __export(exports_container, {
53
+ setContainerMetadata: () => setContainerMetadata,
54
+ resolveForwardRef: () => resolveForwardRef,
55
+ isForwardRef: () => isForwardRef,
56
+ getInjectTokens: () => getContainerMetadata,
57
+ getContainerMetadata: () => getContainerMetadata,
58
+ forwardRef: () => forwardRef,
59
+ createToken: () => createToken,
60
+ Token: () => Token,
61
+ Injectable: () => Injectable,
62
+ Inject: () => Inject,
63
+ Container: () => Container
64
+ });
65
+ function createToken(description) {
66
+ return Symbol(description);
67
+ }
68
+
69
+ class ResolutionStack {
70
+ stack = new Set;
71
+ lazyResolutions = new Map;
72
+ push(token) {
73
+ if (this.stack.has(token)) {
74
+ throw new Error("Circular dependency detected: Token already in resolution stack");
75
+ }
76
+ this.stack.add(token);
77
+ }
78
+ pop(token) {
79
+ this.stack.delete(token);
80
+ }
81
+ has(token) {
82
+ return this.stack.has(token);
83
+ }
84
+ markLazy(token, placeholder) {
85
+ this.lazyResolutions.set(token, placeholder);
86
+ }
87
+ hasLazy(token) {
88
+ return this.lazyResolutions.has(token);
89
+ }
90
+ getLazy(token) {
91
+ return this.lazyResolutions.get(token);
92
+ }
93
+ clearLazy(token) {
94
+ this.lazyResolutions.delete(token);
95
+ }
96
+ }
97
+
98
+ class Container {
99
+ providers = new Map;
100
+ resolutionStack = new ResolutionStack;
101
+ register(provider) {
102
+ if (this.providers.has(provider.token)) {
103
+ throw new Error(`Provider already registered for token: ${String(provider.token)}`);
104
+ }
105
+ this.providers.set(provider.token, {
106
+ provider: {
107
+ ...provider,
108
+ scope: provider.scope ?? "singleton"
109
+ }
110
+ });
111
+ }
112
+ registerAll(providers) {
113
+ for (const provider of providers) {
114
+ this.register(provider);
115
+ }
116
+ }
117
+ has(token) {
118
+ return this.providers.has(token);
119
+ }
120
+ resolve(token) {
121
+ const resolved = this.providers.get(token);
122
+ if (!resolved) {
123
+ throw new Error(`No provider registered for token: ${String(token)}`);
124
+ }
125
+ const { provider } = resolved;
126
+ if (this.resolutionStack.has(token)) {
127
+ return this.createLazyProxy(token, resolved);
128
+ }
129
+ if (provider.scope === "singleton" && resolved.instance !== undefined) {
130
+ return resolved.instance;
131
+ }
132
+ this.resolutionStack.push(token);
133
+ try {
134
+ const instance = this.createInstance(provider);
135
+ if (provider.scope === "singleton") {
136
+ resolved.instance = instance;
137
+ }
138
+ return instance;
139
+ } finally {
140
+ this.resolutionStack.pop(token);
141
+ }
142
+ }
143
+ createLazyProxy(token, resolved) {
144
+ const existingLazy = this.resolutionStack.getLazy(token);
145
+ if (existingLazy && existingLazy.instance) {
146
+ return existingLazy.instance;
147
+ }
148
+ const placeholder = {
149
+ resolved: false
150
+ };
151
+ this.resolutionStack.markLazy(token, placeholder);
152
+ const proxy = new Proxy({}, {
153
+ get: (target, prop) => {
154
+ if (placeholder.resolved && placeholder.instance) {
155
+ const value = placeholder.instance[prop];
156
+ return typeof value === "function" ? value.bind(placeholder.instance) : value;
157
+ }
158
+ if (resolved.instance !== undefined) {
159
+ placeholder.instance = resolved.instance;
160
+ placeholder.resolved = true;
161
+ } else {
162
+ if (prop === "then") {
163
+ return;
164
+ }
165
+ }
166
+ if (placeholder.instance) {
167
+ const value = placeholder.instance[prop];
168
+ return typeof value === "function" ? value.bind(placeholder.instance) : value;
169
+ }
170
+ return () => {
171
+ return;
172
+ };
173
+ },
174
+ set: (target, prop, value) => {
175
+ if (placeholder.instance) {
176
+ placeholder.instance[prop] = value;
177
+ return true;
178
+ }
179
+ return false;
180
+ },
181
+ has: (target, prop) => {
182
+ if (placeholder.instance) {
183
+ return prop in placeholder.instance;
184
+ }
185
+ return false;
186
+ }
187
+ });
188
+ placeholder.instance = proxy;
189
+ return proxy;
190
+ }
191
+ createInstance(provider) {
192
+ if (provider.useValue !== undefined) {
193
+ return provider.useValue;
194
+ }
195
+ if (provider.useFactory) {
196
+ const deps = this.resolveDeps(provider.inject ?? []);
197
+ return provider.useFactory(...deps);
198
+ }
199
+ if (provider.useClass) {
200
+ const deps = this.resolveDeps(provider.inject ?? []);
201
+ return new provider.useClass(...deps);
202
+ }
203
+ throw new Error(`Invalid provider configuration for token: ${String(provider.token)}`);
204
+ }
205
+ resolveDeps(tokens) {
206
+ return tokens.map((tokenOrRef) => {
207
+ const token = resolveForwardRef(tokenOrRef);
208
+ return this.resolve(token);
209
+ });
210
+ }
211
+ clear() {
212
+ this.providers.clear();
213
+ }
214
+ getTokens() {
215
+ return Array.from(this.providers.keys());
216
+ }
217
+ createChild() {
218
+ const child = new Container;
219
+ for (const [token, resolved] of this.providers) {
220
+ if (resolved.provider.scope === "singleton") {
221
+ child.providers.set(token, resolved);
222
+ }
223
+ }
224
+ return child;
225
+ }
226
+ }
227
+ function setContainerMetadata(target, key, value) {
228
+ if (!containerMetadata.has(target)) {
229
+ containerMetadata.set(target, new Map);
230
+ }
231
+ containerMetadata.get(target)?.set(key, value);
232
+ }
233
+ function getContainerMetadata(target, key) {
234
+ return containerMetadata.get(target)?.get(key);
235
+ }
236
+ function Injectable(token) {
237
+ return (target) => {
238
+ setContainerMetadata(target, "injectable", true);
239
+ if (token) {
240
+ setContainerMetadata(target, "token", token);
241
+ }
242
+ return target;
243
+ };
244
+ }
245
+ function Inject(token) {
246
+ return (target, propertyKey, parameterIndex) => {
247
+ const targetObj = target;
248
+ const existingTokens = getContainerMetadata(targetObj, "inject:tokens") ?? [];
249
+ existingTokens[parameterIndex] = token;
250
+ setContainerMetadata(targetObj, "inject:tokens", existingTokens);
251
+ };
252
+ }
253
+ var Token, containerMetadata;
254
+ var init_container = __esm(() => {
255
+ init_forward_ref();
256
+ Token = createToken;
257
+ containerMetadata = new WeakMap;
258
+ });
259
+ init_container();
260
+
261
+ export {
262
+ setContainerMetadata,
263
+ resolveForwardRef,
264
+ isForwardRef,
265
+ getContainerMetadata as getInjectTokens,
266
+ getContainerMetadata,
267
+ forwardRef,
268
+ createToken,
269
+ Token,
270
+ Injectable,
271
+ Inject,
272
+ Container
273
+ };
@@ -0,0 +1,219 @@
1
+ // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true,
8
+ configurable: true,
9
+ set: (newValue) => all[name] = () => newValue
10
+ });
11
+ };
12
+ var __legacyDecorateClassTS = function(decorators, target, key, desc) {
13
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
15
+ r = Reflect.decorate(decorators, target, key, desc);
16
+ else
17
+ for (var i = decorators.length - 1;i >= 0; i--)
18
+ if (d = decorators[i])
19
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
20
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
21
+ };
22
+ var __legacyMetadataTS = (k, v) => {
23
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
24
+ return Reflect.metadata(k, v);
25
+ };
26
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
27
+ var __require = import.meta.require;
28
+
29
+ // src/context/index.ts
30
+ var exports_context = {};
31
+ __export(exports_context, {
32
+ createContext: () => createContext,
33
+ Context: () => Context
34
+ });
35
+ function parseCookies(cookieHeader) {
36
+ const cookies = {};
37
+ for (const part of cookieHeader.split(";")) {
38
+ const trimmed = part.trim();
39
+ if (trimmed) {
40
+ const [name, ...rest] = trimmed.split("=");
41
+ if (name && rest.length > 0) {
42
+ cookies[name.trim()] = rest.join("=").trim();
43
+ }
44
+ }
45
+ }
46
+ return cookies;
47
+ }
48
+
49
+ class Context {
50
+ req;
51
+ params;
52
+ query;
53
+ _cookies;
54
+ _bodyCache;
55
+ _response;
56
+ _variables = {};
57
+ constructor(request, params = {}) {
58
+ this.req = request;
59
+ this.params = params;
60
+ this.query = this.parseQuery(request.url);
61
+ this._response = {
62
+ status: 200,
63
+ headers: new Headers
64
+ };
65
+ }
66
+ get method() {
67
+ return this.req.method;
68
+ }
69
+ get url() {
70
+ return new URL(this.req.url);
71
+ }
72
+ get path() {
73
+ return this.url.pathname;
74
+ }
75
+ getHeader(name) {
76
+ return this.req.headers.get(name) ?? undefined;
77
+ }
78
+ getCookie(name) {
79
+ if (!this._cookies) {
80
+ const cookieHeader = this.req.headers.get("Cookie");
81
+ this._cookies = cookieHeader ? parseCookies(cookieHeader) : {};
82
+ }
83
+ return this._cookies[name];
84
+ }
85
+ get cookies() {
86
+ if (!this._cookies) {
87
+ const cookieHeader = this.req.headers.get("Cookie");
88
+ this._cookies = cookieHeader ? parseCookies(cookieHeader) : {};
89
+ }
90
+ return this._cookies;
91
+ }
92
+ async body() {
93
+ if (this._bodyCache !== undefined) {
94
+ return this._bodyCache;
95
+ }
96
+ const text = await this.req.text();
97
+ this._bodyCache = text ? JSON.parse(text) : null;
98
+ return this._bodyCache;
99
+ }
100
+ async parseBody() {
101
+ return this.body();
102
+ }
103
+ async bodyText() {
104
+ return this.req.text();
105
+ }
106
+ async bodyFormData() {
107
+ return this.req.formData();
108
+ }
109
+ async bodyArrayBuffer() {
110
+ return this.req.arrayBuffer();
111
+ }
112
+ async bodyBlob() {
113
+ return this.req.blob();
114
+ }
115
+ set(key, value) {
116
+ this._variables[key] = value;
117
+ return this;
118
+ }
119
+ get(key) {
120
+ return this._variables[key];
121
+ }
122
+ has(key) {
123
+ return key in this._variables;
124
+ }
125
+ status(code) {
126
+ this._response.status = code;
127
+ return this;
128
+ }
129
+ setHeader(name, value) {
130
+ this._response.headers.set(name, value);
131
+ return this;
132
+ }
133
+ appendHeader(name, value) {
134
+ this._response.headers.append(name, value);
135
+ return this;
136
+ }
137
+ json(data) {
138
+ this._response.headers.set("Content-Type", "application/json");
139
+ return new Response(JSON.stringify(data), {
140
+ status: this._response.status,
141
+ headers: this._response.headers
142
+ });
143
+ }
144
+ text(data) {
145
+ if (!this._response.headers.has("Content-Type")) {
146
+ this._response.headers.set("Content-Type", "text/plain");
147
+ }
148
+ return new Response(data, {
149
+ status: this._response.status,
150
+ headers: this._response.headers
151
+ });
152
+ }
153
+ html(data) {
154
+ this._response.headers.set("Content-Type", "text/html; charset=utf-8");
155
+ return new Response(data, {
156
+ status: this._response.status,
157
+ headers: this._response.headers
158
+ });
159
+ }
160
+ redirect(url, status = 302) {
161
+ return new Response(null, {
162
+ status,
163
+ headers: {
164
+ Location: url
165
+ }
166
+ });
167
+ }
168
+ notFound(message = "Not Found") {
169
+ return new Response(JSON.stringify({ error: message }), {
170
+ status: 404,
171
+ headers: { "Content-Type": "application/json" }
172
+ });
173
+ }
174
+ error(message, status = 500) {
175
+ return new Response(JSON.stringify({ error: message }), {
176
+ status,
177
+ headers: { "Content-Type": "application/json" }
178
+ });
179
+ }
180
+ newResponse(body, options) {
181
+ return new Response(body, {
182
+ status: this._response.status,
183
+ headers: this._response.headers,
184
+ ...options
185
+ });
186
+ }
187
+ parseQuery(url) {
188
+ const query = {};
189
+ const searchParams = new URL(url).searchParams;
190
+ for (const [key, value] of searchParams.entries()) {
191
+ query[key] = value;
192
+ }
193
+ return query;
194
+ }
195
+ accepts(...types) {
196
+ const acceptHeader = this.req.headers.get("Accept");
197
+ if (!acceptHeader)
198
+ return types[0];
199
+ for (const type of types) {
200
+ if (acceptHeader.includes(type) || acceptHeader.includes("*/*")) {
201
+ return type;
202
+ }
203
+ }
204
+ return;
205
+ }
206
+ get isXHR() {
207
+ return this.req.headers.get("X-Requested-With") === "XMLHttpRequest";
208
+ }
209
+ get ip() {
210
+ return this.req.headers.get("x-forwarded-for")?.split(",")[0].trim() ?? this.req.headers.get("x-real-ip") ?? undefined;
211
+ }
212
+ }
213
+ function createContext(request, params = {}) {
214
+ return new Context(request, params);
215
+ }
216
+ export {
217
+ createContext,
218
+ Context
219
+ };