@buenojs/bueno 0.8.3 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/README.md +136 -16
  2. package/dist/cli/{index.js → bin.js} +3036 -1421
  3. package/dist/container/index.js +250 -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/health/index.js +364 -0
  8. package/dist/i18n/index.js +345 -0
  9. package/dist/index.js +11043 -6482
  10. package/dist/jobs/index.js +819 -0
  11. package/dist/lock/index.js +367 -0
  12. package/dist/logger/index.js +281 -0
  13. package/dist/metrics/index.js +289 -0
  14. package/dist/middleware/index.js +77 -0
  15. package/dist/migrations/index.js +571 -0
  16. package/dist/modules/index.js +3346 -0
  17. package/dist/notification/index.js +484 -0
  18. package/dist/observability/index.js +331 -0
  19. package/dist/openapi/index.js +776 -0
  20. package/dist/orm/index.js +1356 -0
  21. package/dist/router/index.js +886 -0
  22. package/dist/rpc/index.js +691 -0
  23. package/dist/schema/index.js +400 -0
  24. package/dist/telemetry/index.js +595 -0
  25. package/dist/template/index.js +640 -0
  26. package/dist/templates/index.js +640 -0
  27. package/dist/testing/index.js +1111 -0
  28. package/dist/types/index.js +60 -0
  29. package/package.json +121 -27
  30. package/src/cache/index.ts +2 -1
  31. package/src/cli/bin.ts +2 -2
  32. package/src/cli/commands/build.ts +183 -165
  33. package/src/cli/commands/dev.ts +96 -89
  34. package/src/cli/commands/generate.ts +142 -111
  35. package/src/cli/commands/help.ts +20 -16
  36. package/src/cli/commands/index.ts +3 -6
  37. package/src/cli/commands/migration.ts +124 -105
  38. package/src/cli/commands/new.ts +392 -438
  39. package/src/cli/commands/start.ts +81 -79
  40. package/src/cli/core/args.ts +68 -50
  41. package/src/cli/core/console.ts +89 -95
  42. package/src/cli/core/index.ts +4 -4
  43. package/src/cli/core/prompt.ts +65 -62
  44. package/src/cli/core/spinner.ts +23 -20
  45. package/src/cli/index.ts +46 -38
  46. package/src/cli/templates/database/index.ts +61 -0
  47. package/src/cli/templates/database/mysql.ts +14 -0
  48. package/src/cli/templates/database/none.ts +16 -0
  49. package/src/cli/templates/database/postgresql.ts +14 -0
  50. package/src/cli/templates/database/sqlite.ts +14 -0
  51. package/src/cli/templates/deploy.ts +29 -26
  52. package/src/cli/templates/docker.ts +41 -30
  53. package/src/cli/templates/frontend/index.ts +63 -0
  54. package/src/cli/templates/frontend/none.ts +17 -0
  55. package/src/cli/templates/frontend/react.ts +140 -0
  56. package/src/cli/templates/frontend/solid.ts +134 -0
  57. package/src/cli/templates/frontend/svelte.ts +131 -0
  58. package/src/cli/templates/frontend/vue.ts +130 -0
  59. package/src/cli/templates/generators/index.ts +339 -0
  60. package/src/cli/templates/generators/types.ts +56 -0
  61. package/src/cli/templates/index.ts +35 -2
  62. package/src/cli/templates/project/api.ts +81 -0
  63. package/src/cli/templates/project/default.ts +140 -0
  64. package/src/cli/templates/project/fullstack.ts +111 -0
  65. package/src/cli/templates/project/index.ts +95 -0
  66. package/src/cli/templates/project/minimal.ts +45 -0
  67. package/src/cli/templates/project/types.ts +94 -0
  68. package/src/cli/templates/project/website.ts +263 -0
  69. package/src/cli/utils/fs.ts +55 -41
  70. package/src/cli/utils/index.ts +3 -2
  71. package/src/cli/utils/strings.ts +47 -33
  72. package/src/cli/utils/version.ts +47 -0
  73. package/src/config/env-validation.ts +100 -0
  74. package/src/config/env.ts +169 -41
  75. package/src/config/index.ts +28 -20
  76. package/src/config/loader.ts +25 -16
  77. package/src/config/merge.ts +21 -10
  78. package/src/config/types.ts +545 -25
  79. package/src/config/validation.ts +215 -7
  80. package/src/container/forward-ref.ts +22 -22
  81. package/src/container/index.ts +34 -12
  82. package/src/context/index.ts +11 -1
  83. package/src/database/index.ts +7 -190
  84. package/src/database/orm/builder.ts +457 -0
  85. package/src/database/orm/casts/index.ts +130 -0
  86. package/src/database/orm/casts/types.ts +25 -0
  87. package/src/database/orm/compiler.ts +304 -0
  88. package/src/database/orm/hooks/index.ts +114 -0
  89. package/src/database/orm/index.ts +61 -0
  90. package/src/database/orm/model-registry.ts +59 -0
  91. package/src/database/orm/model.ts +821 -0
  92. package/src/database/orm/relationships/base.ts +146 -0
  93. package/src/database/orm/relationships/belongs-to-many.ts +179 -0
  94. package/src/database/orm/relationships/belongs-to.ts +56 -0
  95. package/src/database/orm/relationships/has-many.ts +45 -0
  96. package/src/database/orm/relationships/has-one.ts +41 -0
  97. package/src/database/orm/relationships/index.ts +11 -0
  98. package/src/database/orm/scopes/index.ts +55 -0
  99. package/src/events/__tests__/event-system.test.ts +235 -0
  100. package/src/events/config.ts +238 -0
  101. package/src/events/example-usage.ts +185 -0
  102. package/src/events/index.ts +278 -0
  103. package/src/events/manager.ts +385 -0
  104. package/src/events/registry.ts +182 -0
  105. package/src/events/types.ts +124 -0
  106. package/src/frontend/api-routes.ts +65 -23
  107. package/src/frontend/bundler.ts +76 -34
  108. package/src/frontend/console-client.ts +2 -2
  109. package/src/frontend/console-stream.ts +94 -38
  110. package/src/frontend/dev-server.ts +94 -46
  111. package/src/frontend/file-router.ts +61 -19
  112. package/src/frontend/frameworks/index.ts +37 -10
  113. package/src/frontend/frameworks/react.ts +10 -8
  114. package/src/frontend/frameworks/solid.ts +11 -9
  115. package/src/frontend/frameworks/svelte.ts +15 -9
  116. package/src/frontend/frameworks/vue.ts +13 -11
  117. package/src/frontend/hmr-client.ts +12 -10
  118. package/src/frontend/hmr.ts +146 -103
  119. package/src/frontend/index.ts +14 -5
  120. package/src/frontend/islands.ts +41 -22
  121. package/src/frontend/isr.ts +59 -37
  122. package/src/frontend/layout.ts +36 -21
  123. package/src/frontend/ssr/react.ts +74 -27
  124. package/src/frontend/ssr/solid.ts +54 -20
  125. package/src/frontend/ssr/svelte.ts +48 -14
  126. package/src/frontend/ssr/vue.ts +50 -18
  127. package/src/frontend/ssr.ts +83 -39
  128. package/src/frontend/types.ts +91 -56
  129. package/src/health/index.ts +21 -9
  130. package/src/i18n/engine.ts +305 -0
  131. package/src/i18n/index.ts +38 -0
  132. package/src/i18n/loader.ts +218 -0
  133. package/src/i18n/middleware.ts +164 -0
  134. package/src/i18n/negotiator.ts +162 -0
  135. package/src/i18n/types.ts +158 -0
  136. package/src/index.ts +179 -27
  137. package/src/jobs/drivers/memory.ts +315 -0
  138. package/src/jobs/drivers/redis.ts +459 -0
  139. package/src/jobs/index.ts +30 -0
  140. package/src/jobs/queue.ts +281 -0
  141. package/src/jobs/types.ts +295 -0
  142. package/src/jobs/worker.ts +380 -0
  143. package/src/logger/index.ts +1 -3
  144. package/src/logger/transports/index.ts +62 -22
  145. package/src/metrics/index.ts +25 -16
  146. package/src/migrations/index.ts +9 -0
  147. package/src/modules/filters.ts +13 -17
  148. package/src/modules/guards.ts +49 -26
  149. package/src/modules/index.ts +409 -298
  150. package/src/modules/interceptors.ts +58 -20
  151. package/src/modules/lazy.ts +11 -19
  152. package/src/modules/lifecycle.ts +15 -7
  153. package/src/modules/metadata.ts +15 -5
  154. package/src/modules/pipes.ts +94 -72
  155. package/src/notification/channels/base.ts +68 -0
  156. package/src/notification/channels/email.ts +105 -0
  157. package/src/notification/channels/push.ts +104 -0
  158. package/src/notification/channels/sms.ts +105 -0
  159. package/src/notification/channels/whatsapp.ts +104 -0
  160. package/src/notification/index.ts +48 -0
  161. package/src/notification/service.ts +354 -0
  162. package/src/notification/types.ts +344 -0
  163. package/src/observability/__tests__/observability.test.ts +483 -0
  164. package/src/observability/breadcrumbs.ts +114 -0
  165. package/src/observability/index.ts +136 -0
  166. package/src/observability/interceptor.ts +85 -0
  167. package/src/observability/service.ts +303 -0
  168. package/src/observability/trace.ts +37 -0
  169. package/src/observability/types.ts +196 -0
  170. package/src/openapi/__tests__/decorators.test.ts +335 -0
  171. package/src/openapi/__tests__/document-builder.test.ts +285 -0
  172. package/src/openapi/__tests__/route-scanner.test.ts +334 -0
  173. package/src/openapi/__tests__/schema-generator.test.ts +275 -0
  174. package/src/openapi/decorators.ts +328 -0
  175. package/src/openapi/document-builder.ts +274 -0
  176. package/src/openapi/index.ts +112 -0
  177. package/src/openapi/metadata.ts +112 -0
  178. package/src/openapi/route-scanner.ts +289 -0
  179. package/src/openapi/schema-generator.ts +256 -0
  180. package/src/openapi/swagger-module.ts +166 -0
  181. package/src/openapi/types.ts +398 -0
  182. package/src/orm/index.ts +10 -0
  183. package/src/rpc/index.ts +3 -1
  184. package/src/schema/index.ts +9 -0
  185. package/src/security/index.ts +15 -6
  186. package/src/ssg/index.ts +9 -8
  187. package/src/telemetry/index.ts +76 -22
  188. package/src/template/index.ts +7 -0
  189. package/src/templates/engine.ts +224 -0
  190. package/src/templates/index.ts +9 -0
  191. package/src/templates/loader.ts +331 -0
  192. package/src/templates/renderers/markdown.ts +212 -0
  193. package/src/templates/renderers/simple.ts +269 -0
  194. package/src/templates/types.ts +154 -0
  195. package/src/testing/index.ts +100 -27
  196. package/src/types/optional-deps.d.ts +347 -187
  197. package/src/validation/index.ts +92 -2
  198. package/src/validation/schemas.ts +536 -0
  199. package/tests/integration/fullstack.test.ts +4 -4
  200. package/tests/unit/database.test.ts +2 -72
  201. package/tests/unit/env-validation.test.ts +166 -0
  202. package/tests/unit/events.test.ts +910 -0
  203. package/tests/unit/i18n.test.ts +455 -0
  204. package/tests/unit/jobs.test.ts +493 -0
  205. package/tests/unit/notification.test.ts +988 -0
  206. package/tests/unit/observability.test.ts +453 -0
  207. package/tests/unit/orm/builder.test.ts +323 -0
  208. package/tests/unit/orm/casts.test.ts +179 -0
  209. package/tests/unit/orm/compiler.test.ts +220 -0
  210. package/tests/unit/orm/eager-loading.test.ts +285 -0
  211. package/tests/unit/orm/hooks.test.ts +191 -0
  212. package/tests/unit/orm/model.test.ts +373 -0
  213. package/tests/unit/orm/relationships.test.ts +303 -0
  214. package/tests/unit/orm/scopes.test.ts +74 -0
  215. package/tests/unit/templates-simple.test.ts +53 -0
  216. package/tests/unit/templates.test.ts +454 -0
  217. package/tests/unit/validation.test.ts +18 -24
  218. package/tsconfig.json +11 -3
@@ -0,0 +1,3346 @@
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
+
217
+ // src/middleware/index.ts
218
+ var exports_middleware = {};
219
+ __export(exports_middleware, {
220
+ createPipeline: () => createPipeline,
221
+ compose: () => compose,
222
+ Pipeline: () => Pipeline
223
+ });
224
+ function compose(middleware) {
225
+ return async (context, handler) => {
226
+ let index = -1;
227
+ const dispatch = async (i) => {
228
+ if (i <= index) {
229
+ throw new Error("next() called multiple times");
230
+ }
231
+ index = i;
232
+ if (i >= middleware.length) {
233
+ return handler(context);
234
+ }
235
+ const fn = middleware[i];
236
+ return fn(context, async () => {
237
+ return dispatch(i + 1);
238
+ });
239
+ };
240
+ return dispatch(0);
241
+ };
242
+ }
243
+
244
+ class Pipeline {
245
+ middleware = [];
246
+ use(middleware) {
247
+ this.middleware.push(middleware);
248
+ return this;
249
+ }
250
+ async execute(context, handler) {
251
+ const fn = compose(this.middleware);
252
+ return fn(context, handler);
253
+ }
254
+ get length() {
255
+ return this.middleware.length;
256
+ }
257
+ }
258
+ function createPipeline() {
259
+ return new Pipeline;
260
+ }
261
+
262
+ // src/validation/index.ts
263
+ async function validate(schema, data) {
264
+ try {
265
+ const result = await Promise.resolve(schema["~standard"].validate(data));
266
+ if ("value" in result) {
267
+ return { success: true, data: result.value };
268
+ }
269
+ return {
270
+ success: false,
271
+ issues: [...result.issues]
272
+ };
273
+ } catch (error) {
274
+ return {
275
+ success: false,
276
+ issues: [
277
+ {
278
+ message: error instanceof Error ? error.message : "Validation failed"
279
+ }
280
+ ]
281
+ };
282
+ }
283
+ }
284
+ function validateSync(schema, data) {
285
+ const result = schema["~standard"].validate(data);
286
+ if (result instanceof Promise) {
287
+ throw new Error("Schema uses async validation. Use validate() instead.");
288
+ }
289
+ if ("value" in result) {
290
+ return { success: true, data: result.value };
291
+ }
292
+ return { success: false, issues: [...result.issues] };
293
+ }
294
+ async function validateBody(context, schema) {
295
+ try {
296
+ const body = await context.body();
297
+ return validate(schema, body);
298
+ } catch (error) {
299
+ return {
300
+ success: false,
301
+ issues: [{ message: "Failed to parse request body" }]
302
+ };
303
+ }
304
+ }
305
+ function validateQuery(context, schema) {
306
+ return validateSync(schema, context.query);
307
+ }
308
+ function validateParams(context, schema) {
309
+ return validateSync(schema, context.params);
310
+ }
311
+ function validateHeaders(context, schema) {
312
+ const headers = {};
313
+ context.req.headers.forEach((value, key) => {
314
+ headers[key] = value;
315
+ });
316
+ return validateSync(schema, headers);
317
+ }
318
+ function createValidator(options) {
319
+ return async (context, next) => {
320
+ if (options.body) {
321
+ const result = await validateBody(context, options.body);
322
+ if (!result.success) {
323
+ return context.status(400).json({ error: "Validation failed", issues: result.issues });
324
+ }
325
+ context.set("validatedBody", result.data);
326
+ }
327
+ if (options.query) {
328
+ const result = validateQuery(context, options.query);
329
+ if (!result.success) {
330
+ return context.status(400).json({ error: "Validation failed", issues: result.issues });
331
+ }
332
+ context.set("validatedQuery", result.data);
333
+ }
334
+ if (options.params) {
335
+ const result = validateParams(context, options.params);
336
+ if (!result.success) {
337
+ return context.status(400).json({ error: "Validation failed", issues: result.issues });
338
+ }
339
+ context.set("validatedParams", result.data);
340
+ }
341
+ if (options.headers) {
342
+ const result = validateHeaders(context, options.headers);
343
+ if (!result.success) {
344
+ return context.status(400).json({ error: "Validation failed", issues: result.issues });
345
+ }
346
+ context.set("validatedHeaders", result.data);
347
+ }
348
+ return next();
349
+ };
350
+ }
351
+ function WithBody(schema) {
352
+ return (target, propertyKey, descriptor) => {
353
+ const original = descriptor.value;
354
+ descriptor.value = async function(context) {
355
+ const result = await validateBody(context, schema);
356
+ if (!result.success) {
357
+ return context.status(400).json({ error: "Validation failed", issues: result.issues });
358
+ }
359
+ context.set("body", result.data);
360
+ return original.call(this, context);
361
+ };
362
+ return descriptor;
363
+ };
364
+ }
365
+ function WithQuery(schema) {
366
+ return (target, propertyKey, descriptor) => {
367
+ const original = descriptor.value;
368
+ descriptor.value = async function(context) {
369
+ const result = validateQuery(context, schema);
370
+ if (!result.success) {
371
+ return context.status(400).json({ error: "Validation failed", issues: result.issues });
372
+ }
373
+ context.set("query", result.data);
374
+ return original.call(this, context);
375
+ };
376
+ return descriptor;
377
+ };
378
+ }
379
+ function isStandardSchema(value) {
380
+ return typeof value === "object" && value !== null && "~standard" in value && typeof value["~standard"]?.validate === "function";
381
+ }
382
+ function assertStandardSchema(schema, name = "Schema") {
383
+ if (!isStandardSchema(schema)) {
384
+ throw new Error(`${name} must implement Standard Schema interface. Supported: Zod 4+, Valibot v1+, ArkType, Typia 7+`);
385
+ }
386
+ }
387
+ function validateEnvSync(schema, envVars) {
388
+ try {
389
+ const result = validateSync(schema, envVars);
390
+ if (!result.success) {
391
+ const formattedIssues = result.issues.map((issue) => {
392
+ const path = issue.path?.join(".") || "root";
393
+ return {
394
+ ...issue,
395
+ message: `Environment variable validation failed for ${path}: ${issue.message}`
396
+ };
397
+ });
398
+ return {
399
+ success: false,
400
+ issues: formattedIssues
401
+ };
402
+ }
403
+ return result;
404
+ } catch (error) {
405
+ return {
406
+ success: false,
407
+ issues: [
408
+ {
409
+ message: `Environment variable validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
410
+ }
411
+ ]
412
+ };
413
+ }
414
+ }
415
+
416
+ // src/container/forward-ref.ts
417
+ var FORWARD_REF_SYMBOL = Symbol.for("buno.forwardRef");
418
+ function forwardRef(fn) {
419
+ return {
420
+ __forwardRef: FORWARD_REF_SYMBOL,
421
+ forwardRef: fn
422
+ };
423
+ }
424
+ function isForwardRef(value) {
425
+ return typeof value === "object" && value !== null && "__forwardRef" in value && "forwardRef" in value && typeof value.forwardRef === "function";
426
+ }
427
+ function resolveForwardRef(ref) {
428
+ if (isForwardRef(ref)) {
429
+ return ref.forwardRef();
430
+ }
431
+ return ref;
432
+ }
433
+
434
+ // src/container/index.ts
435
+ function createToken(description) {
436
+ return Symbol(description);
437
+ }
438
+ var Token = createToken;
439
+
440
+ class ResolutionStack {
441
+ stack = new Set;
442
+ lazyResolutions = new Map;
443
+ push(token) {
444
+ if (this.stack.has(token)) {
445
+ throw new Error("Circular dependency detected: Token already in resolution stack");
446
+ }
447
+ this.stack.add(token);
448
+ }
449
+ pop(token) {
450
+ this.stack.delete(token);
451
+ }
452
+ has(token) {
453
+ return this.stack.has(token);
454
+ }
455
+ markLazy(token, placeholder) {
456
+ this.lazyResolutions.set(token, placeholder);
457
+ }
458
+ hasLazy(token) {
459
+ return this.lazyResolutions.has(token);
460
+ }
461
+ getLazy(token) {
462
+ return this.lazyResolutions.get(token);
463
+ }
464
+ clearLazy(token) {
465
+ this.lazyResolutions.delete(token);
466
+ }
467
+ }
468
+
469
+ class Container2 {
470
+ providers = new Map;
471
+ resolutionStack = new ResolutionStack;
472
+ register(provider) {
473
+ if (this.providers.has(provider.token)) {
474
+ throw new Error(`Provider already registered for token: ${String(provider.token)}`);
475
+ }
476
+ this.providers.set(provider.token, {
477
+ provider: {
478
+ ...provider,
479
+ scope: provider.scope ?? "singleton"
480
+ }
481
+ });
482
+ }
483
+ registerAll(providers) {
484
+ for (const provider of providers) {
485
+ this.register(provider);
486
+ }
487
+ }
488
+ has(token) {
489
+ return this.providers.has(token);
490
+ }
491
+ resolve(token) {
492
+ const resolved = this.providers.get(token);
493
+ if (!resolved) {
494
+ throw new Error(`No provider registered for token: ${String(token)}`);
495
+ }
496
+ const { provider } = resolved;
497
+ if (this.resolutionStack.has(token)) {
498
+ return this.createLazyProxy(token, resolved);
499
+ }
500
+ if (provider.scope === "singleton" && resolved.instance !== undefined) {
501
+ return resolved.instance;
502
+ }
503
+ this.resolutionStack.push(token);
504
+ try {
505
+ const instance = this.createInstance(provider);
506
+ if (provider.scope === "singleton") {
507
+ resolved.instance = instance;
508
+ }
509
+ return instance;
510
+ } finally {
511
+ this.resolutionStack.pop(token);
512
+ }
513
+ }
514
+ createLazyProxy(token, resolved) {
515
+ const existingLazy = this.resolutionStack.getLazy(token);
516
+ if (existingLazy && existingLazy.instance) {
517
+ return existingLazy.instance;
518
+ }
519
+ const placeholder = {
520
+ resolved: false
521
+ };
522
+ this.resolutionStack.markLazy(token, placeholder);
523
+ const proxy = new Proxy({}, {
524
+ get: (target, prop) => {
525
+ if (placeholder.resolved && placeholder.instance) {
526
+ const value = placeholder.instance[prop];
527
+ return typeof value === "function" ? value.bind(placeholder.instance) : value;
528
+ }
529
+ if (resolved.instance !== undefined) {
530
+ placeholder.instance = resolved.instance;
531
+ placeholder.resolved = true;
532
+ } else {
533
+ if (prop === "then") {
534
+ return;
535
+ }
536
+ }
537
+ if (placeholder.instance) {
538
+ const value = placeholder.instance[prop];
539
+ return typeof value === "function" ? value.bind(placeholder.instance) : value;
540
+ }
541
+ return () => {
542
+ return;
543
+ };
544
+ },
545
+ set: (target, prop, value) => {
546
+ if (placeholder.instance) {
547
+ placeholder.instance[prop] = value;
548
+ return true;
549
+ }
550
+ return false;
551
+ },
552
+ has: (target, prop) => {
553
+ if (placeholder.instance) {
554
+ return prop in placeholder.instance;
555
+ }
556
+ return false;
557
+ }
558
+ });
559
+ placeholder.instance = proxy;
560
+ return proxy;
561
+ }
562
+ createInstance(provider) {
563
+ if (provider.useValue !== undefined) {
564
+ return provider.useValue;
565
+ }
566
+ if (provider.useFactory) {
567
+ const deps = this.resolveDeps(provider.inject ?? []);
568
+ return provider.useFactory(...deps);
569
+ }
570
+ if (provider.useClass) {
571
+ const deps = this.resolveDeps(provider.inject ?? []);
572
+ return new provider.useClass(...deps);
573
+ }
574
+ throw new Error(`Invalid provider configuration for token: ${String(provider.token)}`);
575
+ }
576
+ resolveDeps(tokens) {
577
+ return tokens.map((tokenOrRef) => {
578
+ const token = resolveForwardRef(tokenOrRef);
579
+ return this.resolve(token);
580
+ });
581
+ }
582
+ clear() {
583
+ this.providers.clear();
584
+ }
585
+ getTokens() {
586
+ return Array.from(this.providers.keys());
587
+ }
588
+ createChild() {
589
+ const child = new Container2;
590
+ for (const [token, resolved] of this.providers) {
591
+ if (resolved.provider.scope === "singleton") {
592
+ child.providers.set(token, resolved);
593
+ }
594
+ }
595
+ return child;
596
+ }
597
+ }
598
+ var containerMetadata = new WeakMap;
599
+ function setContainerMetadata(target, key, value) {
600
+ if (!containerMetadata.has(target)) {
601
+ containerMetadata.set(target, new Map);
602
+ }
603
+ containerMetadata.get(target)?.set(key, value);
604
+ }
605
+ function getContainerMetadata(target, key) {
606
+ return containerMetadata.get(target)?.get(key);
607
+ }
608
+ function Injectable(token) {
609
+ return (target) => {
610
+ setContainerMetadata(target, "injectable", true);
611
+ if (token) {
612
+ setContainerMetadata(target, "token", token);
613
+ }
614
+ return target;
615
+ };
616
+ }
617
+ function Inject(token) {
618
+ return (target, propertyKey, parameterIndex) => {
619
+ const targetObj = target;
620
+ const existingTokens = getContainerMetadata(targetObj, "inject:tokens") ?? [];
621
+ existingTokens[parameterIndex] = token;
622
+ setContainerMetadata(targetObj, "inject:tokens", existingTokens);
623
+ };
624
+ }
625
+ // src/router/linear.ts
626
+ function patternToRegex(pattern) {
627
+ const paramNames = [];
628
+ let isStatic = true;
629
+ let hasWildcard = false;
630
+ const segments = [];
631
+ let i = 0;
632
+ while (i < pattern.length) {
633
+ if (pattern[i] === ":") {
634
+ i++;
635
+ let name = "";
636
+ while (i < pattern.length && /[a-zA-Z0-9_]/.test(pattern[i])) {
637
+ name += pattern[i];
638
+ i++;
639
+ }
640
+ let optional = false;
641
+ if (i < pattern.length && pattern[i] === "?") {
642
+ optional = true;
643
+ i++;
644
+ }
645
+ let customRegex = "";
646
+ if (i < pattern.length && pattern[i] === "<") {
647
+ i++;
648
+ while (i < pattern.length && pattern[i] !== ">") {
649
+ customRegex += pattern[i];
650
+ i++;
651
+ }
652
+ i++;
653
+ }
654
+ paramNames.push(name);
655
+ isStatic = false;
656
+ if (optional) {
657
+ if (segments.length > 0 && segments[segments.length - 1] === "/") {
658
+ segments.pop();
659
+ }
660
+ segments.push("(?:/([^/]*))?");
661
+ } else if (customRegex) {
662
+ segments.push(`(${customRegex})`);
663
+ } else {
664
+ segments.push("([^/]+)");
665
+ }
666
+ } else if (pattern[i] === "*") {
667
+ hasWildcard = true;
668
+ isStatic = false;
669
+ paramNames.push("*");
670
+ segments.push("(.*)");
671
+ i++;
672
+ } else {
673
+ const char = pattern[i];
674
+ if (/[.+^${}()|[\]\\]/.test(char)) {
675
+ segments.push(`\\${char}`);
676
+ } else {
677
+ segments.push(char);
678
+ }
679
+ i++;
680
+ }
681
+ }
682
+ const regexStr = `^${segments.join("")}/?$`;
683
+ return {
684
+ regex: new RegExp(regexStr, "i"),
685
+ paramNames,
686
+ isStatic,
687
+ hasWildcard
688
+ };
689
+ }
690
+ function extractParams(regex, paramNames, pathname) {
691
+ const params = {};
692
+ const match = pathname.match(regex);
693
+ if (match) {
694
+ paramNames.forEach((name, index) => {
695
+ if (match[index + 1] !== undefined) {
696
+ params[name] = match[index + 1];
697
+ }
698
+ });
699
+ }
700
+ return params;
701
+ }
702
+
703
+ class LinearRouter {
704
+ staticRoutes = new Map;
705
+ dynamicRoutes = [];
706
+ groupPrefix = "";
707
+ groupMiddleware = [];
708
+ routeCounter = 0;
709
+ addRoute(method, pattern, handler, options) {
710
+ const fullPattern = this.groupPrefix + pattern;
711
+ const { regex, paramNames, isStatic } = patternToRegex(fullPattern);
712
+ const optsMiddleware = options?.middleware;
713
+ const routeMiddleware = optsMiddleware ? Array.isArray(optsMiddleware) ? optsMiddleware : [optsMiddleware] : [];
714
+ const middleware = [...this.groupMiddleware, ...routeMiddleware];
715
+ if (isStatic) {
716
+ const normalizedPath = fullPattern.toLowerCase();
717
+ const key = `${method}:${normalizedPath}`;
718
+ this.staticRoutes.set(key, { handler, middleware, name: options?.name });
719
+ if (!normalizedPath.endsWith("/")) {
720
+ this.staticRoutes.set(`${method}:${normalizedPath}/`, {
721
+ handler,
722
+ middleware,
723
+ name: options?.name
724
+ });
725
+ } else if (normalizedPath.length > 1) {
726
+ this.staticRoutes.set(`${method}:${normalizedPath.slice(0, -1)}`, {
727
+ handler,
728
+ middleware,
729
+ name: options?.name
730
+ });
731
+ }
732
+ } else {
733
+ this.dynamicRoutes.push({
734
+ method,
735
+ pattern: fullPattern,
736
+ handler,
737
+ middleware,
738
+ name: options?.name,
739
+ regex,
740
+ paramNames,
741
+ priority: this.routeCounter++
742
+ });
743
+ this.sortDynamicRoutes();
744
+ }
745
+ }
746
+ sortDynamicRoutes() {
747
+ this.dynamicRoutes.sort((a, b) => {
748
+ if (a.paramNames.length !== b.paramNames.length) {
749
+ return a.paramNames.length - b.paramNames.length;
750
+ }
751
+ return a.priority - b.priority;
752
+ });
753
+ }
754
+ match(method, pathname) {
755
+ const normalizedPath = pathname.toLowerCase();
756
+ const staticKey = `${method}:${normalizedPath}`;
757
+ const staticRoute = this.staticRoutes.get(staticKey);
758
+ if (staticRoute) {
759
+ return {
760
+ handler: staticRoute.handler,
761
+ params: {},
762
+ middleware: staticRoute.middleware,
763
+ name: staticRoute.name
764
+ };
765
+ }
766
+ const allKey = `ALL:${normalizedPath}`;
767
+ const allRoute = this.staticRoutes.get(allKey);
768
+ if (allRoute) {
769
+ return {
770
+ handler: allRoute.handler,
771
+ params: {},
772
+ middleware: allRoute.middleware,
773
+ name: allRoute.name
774
+ };
775
+ }
776
+ for (const route of this.dynamicRoutes) {
777
+ if (route.method !== "ALL" && route.method !== method) {
778
+ continue;
779
+ }
780
+ if (route.regex.test(pathname)) {
781
+ const params = extractParams(route.regex, route.paramNames, pathname);
782
+ return {
783
+ handler: route.handler,
784
+ params,
785
+ middleware: route.middleware,
786
+ name: route.name
787
+ };
788
+ }
789
+ }
790
+ return;
791
+ }
792
+ group(prefix, options) {
793
+ const childRouter = new LinearRouter;
794
+ childRouter.staticRoutes = this.staticRoutes;
795
+ childRouter.dynamicRoutes = this.dynamicRoutes;
796
+ childRouter.groupPrefix = this.groupPrefix + prefix;
797
+ const optsMiddleware = options?.middleware;
798
+ const middlewareArray = optsMiddleware ? Array.isArray(optsMiddleware) ? optsMiddleware : [optsMiddleware] : [];
799
+ childRouter.groupMiddleware = [...this.groupMiddleware, ...middlewareArray];
800
+ childRouter.routeCounter = this.routeCounter;
801
+ return childRouter;
802
+ }
803
+ getRoutes() {
804
+ const routes = [];
805
+ const seenPatterns = new Set;
806
+ for (const [key, value] of this.staticRoutes) {
807
+ const [method, path] = key.split(":");
808
+ const pattern = path.endsWith("/") && path.length > 1 ? path.slice(0, -1) : path;
809
+ const dedupeKey = `${method}:${pattern}`;
810
+ if (!seenPatterns.has(dedupeKey)) {
811
+ seenPatterns.add(dedupeKey);
812
+ routes.push({ method, pattern: pattern || "/", name: value.name });
813
+ }
814
+ }
815
+ for (const route of this.dynamicRoutes) {
816
+ routes.push({
817
+ method: route.method,
818
+ pattern: route.pattern,
819
+ name: route.name
820
+ });
821
+ }
822
+ return routes;
823
+ }
824
+ getRouterType() {
825
+ return "linear";
826
+ }
827
+ getRouteCount() {
828
+ const staticCount = Math.floor(this.staticRoutes.size / 2);
829
+ return {
830
+ static: staticCount,
831
+ dynamic: this.dynamicRoutes.length,
832
+ total: staticCount + this.dynamicRoutes.length
833
+ };
834
+ }
835
+ get(pattern, handler, options) {
836
+ this.addRoute("GET", pattern, handler, options);
837
+ }
838
+ post(pattern, handler, options) {
839
+ this.addRoute("POST", pattern, handler, options);
840
+ }
841
+ put(pattern, handler, options) {
842
+ this.addRoute("PUT", pattern, handler, options);
843
+ }
844
+ patch(pattern, handler, options) {
845
+ this.addRoute("PATCH", pattern, handler, options);
846
+ }
847
+ delete(pattern, handler, options) {
848
+ this.addRoute("DELETE", pattern, handler, options);
849
+ }
850
+ head(pattern, handler, options) {
851
+ this.addRoute("HEAD", pattern, handler, options);
852
+ }
853
+ options(pattern, handler, options) {
854
+ this.addRoute("OPTIONS", pattern, handler, options);
855
+ }
856
+ all(pattern, handler, options) {
857
+ this.addRoute("ALL", pattern, handler, options);
858
+ }
859
+ }
860
+
861
+ // src/router/regex.ts
862
+ function patternToRegex2(pattern) {
863
+ const paramNames = [];
864
+ let isStatic = true;
865
+ let hasWildcard = false;
866
+ const segments = [];
867
+ let i = 0;
868
+ while (i < pattern.length) {
869
+ if (pattern[i] === ":") {
870
+ i++;
871
+ let name = "";
872
+ while (i < pattern.length && /[a-zA-Z0-9_]/.test(pattern[i])) {
873
+ name += pattern[i];
874
+ i++;
875
+ }
876
+ let optional = false;
877
+ if (i < pattern.length && pattern[i] === "?") {
878
+ optional = true;
879
+ i++;
880
+ }
881
+ let customRegex = "";
882
+ if (i < pattern.length && pattern[i] === "<") {
883
+ i++;
884
+ while (i < pattern.length && pattern[i] !== ">") {
885
+ customRegex += pattern[i];
886
+ i++;
887
+ }
888
+ i++;
889
+ }
890
+ paramNames.push(name);
891
+ isStatic = false;
892
+ if (optional) {
893
+ if (segments.length > 0 && segments[segments.length - 1] === "/") {
894
+ segments.pop();
895
+ }
896
+ segments.push("(?:/([^/]*))?");
897
+ } else if (customRegex) {
898
+ segments.push(`(${customRegex})`);
899
+ } else {
900
+ segments.push("([^/]+)");
901
+ }
902
+ } else if (pattern[i] === "*") {
903
+ hasWildcard = true;
904
+ isStatic = false;
905
+ paramNames.push("*");
906
+ segments.push("(.*)");
907
+ i++;
908
+ } else {
909
+ const char = pattern[i];
910
+ if (/[.+^${}()|[\]\\]/.test(char)) {
911
+ segments.push(`\\${char}`);
912
+ } else {
913
+ segments.push(char);
914
+ }
915
+ i++;
916
+ }
917
+ }
918
+ const regexStr = `^${segments.join("")}/?$`;
919
+ return {
920
+ regex: new RegExp(regexStr, "i"),
921
+ paramNames,
922
+ isStatic,
923
+ hasWildcard
924
+ };
925
+ }
926
+ function extractParams2(regex, paramNames, pathname) {
927
+ const params = {};
928
+ const match = pathname.match(regex);
929
+ if (match) {
930
+ paramNames.forEach((name, index) => {
931
+ if (match[index + 1] !== undefined) {
932
+ params[name] = match[index + 1];
933
+ }
934
+ });
935
+ }
936
+ return params;
937
+ }
938
+
939
+ class RegexRouter {
940
+ routes = [];
941
+ groupPrefix = "";
942
+ groupMiddleware = [];
943
+ routeCounter = 0;
944
+ addRoute(method, pattern, handler, options) {
945
+ const fullPattern = this.groupPrefix + pattern;
946
+ const { regex, paramNames, isStatic } = patternToRegex2(fullPattern);
947
+ const optsMiddleware = options?.middleware;
948
+ const routeMiddleware = optsMiddleware ? Array.isArray(optsMiddleware) ? optsMiddleware : [optsMiddleware] : [];
949
+ this.routes.push({
950
+ method,
951
+ pattern: fullPattern,
952
+ handler,
953
+ middleware: [...this.groupMiddleware, ...routeMiddleware],
954
+ name: options?.name,
955
+ regex,
956
+ paramNames,
957
+ isStatic,
958
+ priority: this.routeCounter++
959
+ });
960
+ this.sortRoutes();
961
+ }
962
+ sortRoutes() {
963
+ this.routes.sort((a, b) => {
964
+ if (a.isStatic !== b.isStatic) {
965
+ return a.isStatic ? -1 : 1;
966
+ }
967
+ if (a.paramNames.length !== b.paramNames.length) {
968
+ return a.paramNames.length - b.paramNames.length;
969
+ }
970
+ return a.priority - b.priority;
971
+ });
972
+ }
973
+ match(method, pathname) {
974
+ for (const route of this.routes) {
975
+ if (route.method !== "ALL" && route.method !== method) {
976
+ continue;
977
+ }
978
+ if (route.regex.test(pathname)) {
979
+ const params = extractParams2(route.regex, route.paramNames, pathname);
980
+ return {
981
+ handler: route.handler,
982
+ params,
983
+ middleware: route.middleware,
984
+ name: route.name
985
+ };
986
+ }
987
+ }
988
+ return;
989
+ }
990
+ group(prefix, options) {
991
+ const childRouter = new RegexRouter;
992
+ childRouter.routes = this.routes;
993
+ childRouter.groupPrefix = this.groupPrefix + prefix;
994
+ const optsMiddleware = options?.middleware;
995
+ const middlewareArray = optsMiddleware ? Array.isArray(optsMiddleware) ? optsMiddleware : [optsMiddleware] : [];
996
+ childRouter.groupMiddleware = [...this.groupMiddleware, ...middlewareArray];
997
+ childRouter.routeCounter = this.routeCounter;
998
+ return childRouter;
999
+ }
1000
+ getRoutes() {
1001
+ return this.routes.map((r) => ({
1002
+ method: r.method,
1003
+ pattern: r.pattern,
1004
+ name: r.name
1005
+ }));
1006
+ }
1007
+ getRouterType() {
1008
+ return "regex";
1009
+ }
1010
+ getRouteCount() {
1011
+ return this.routes.length;
1012
+ }
1013
+ get(pattern, handler, options) {
1014
+ this.addRoute("GET", pattern, handler, options);
1015
+ }
1016
+ post(pattern, handler, options) {
1017
+ this.addRoute("POST", pattern, handler, options);
1018
+ }
1019
+ put(pattern, handler, options) {
1020
+ this.addRoute("PUT", pattern, handler, options);
1021
+ }
1022
+ patch(pattern, handler, options) {
1023
+ this.addRoute("PATCH", pattern, handler, options);
1024
+ }
1025
+ delete(pattern, handler, options) {
1026
+ this.addRoute("DELETE", pattern, handler, options);
1027
+ }
1028
+ head(pattern, handler, options) {
1029
+ this.addRoute("HEAD", pattern, handler, options);
1030
+ }
1031
+ options(pattern, handler, options) {
1032
+ this.addRoute("OPTIONS", pattern, handler, options);
1033
+ }
1034
+ all(pattern, handler, options) {
1035
+ this.addRoute("ALL", pattern, handler, options);
1036
+ }
1037
+ }
1038
+
1039
+ // src/router/tree.ts
1040
+ class TreeRouter {
1041
+ root;
1042
+ groupPrefix = "";
1043
+ groupMiddleware = [];
1044
+ routeCount = 0;
1045
+ constructor() {
1046
+ this.root = this.createNode("");
1047
+ }
1048
+ createNode(path, paramName, paramRegex, isWildcard = false) {
1049
+ return {
1050
+ path,
1051
+ children: new Map,
1052
+ handlers: new Map,
1053
+ paramName,
1054
+ paramRegex,
1055
+ isWildcard
1056
+ };
1057
+ }
1058
+ addRoute(method, pattern, handler, options) {
1059
+ const fullPattern = this.groupPrefix + pattern;
1060
+ const optsMiddleware = options?.middleware;
1061
+ const routeMiddleware = optsMiddleware ? Array.isArray(optsMiddleware) ? optsMiddleware : [optsMiddleware] : [];
1062
+ const middleware = [...this.groupMiddleware, ...routeMiddleware];
1063
+ const segments = this.parsePattern(fullPattern);
1064
+ const node = this.insertSegments(this.root, segments, 0);
1065
+ node.handlers.set(method, {
1066
+ handler,
1067
+ middleware,
1068
+ name: options?.name
1069
+ });
1070
+ this.routeCount++;
1071
+ }
1072
+ parsePattern(pattern) {
1073
+ const segments = [];
1074
+ let normalized = pattern;
1075
+ if (!normalized.startsWith("/")) {
1076
+ normalized = `/${normalized}`;
1077
+ }
1078
+ if (normalized.length > 1 && normalized.endsWith("/")) {
1079
+ normalized = normalized.slice(0, -1);
1080
+ }
1081
+ if (normalized === "/") {
1082
+ return [{ type: "static", value: "" }];
1083
+ }
1084
+ const parts = normalized.split("/").filter(Boolean);
1085
+ for (const part of parts) {
1086
+ if (part === "*") {
1087
+ segments.push({ type: "wildcard" });
1088
+ } else if (part.startsWith(":")) {
1089
+ let name = part.slice(1);
1090
+ let regex;
1091
+ let optional = false;
1092
+ if (name.endsWith("?")) {
1093
+ optional = true;
1094
+ name = name.slice(0, -1);
1095
+ }
1096
+ const regexMatch = name.match(/^(\w+)<(.+)>$/);
1097
+ if (regexMatch) {
1098
+ name = regexMatch[1];
1099
+ regex = new RegExp(`^(${regexMatch[2]})$`);
1100
+ }
1101
+ segments.push({ type: "param", name, regex, optional });
1102
+ } else {
1103
+ segments.push({ type: "static", value: part.toLowerCase() });
1104
+ }
1105
+ }
1106
+ return segments;
1107
+ }
1108
+ insertSegments(node, segments, index) {
1109
+ if (index >= segments.length) {
1110
+ return node;
1111
+ }
1112
+ const segment = segments[index];
1113
+ if (segment.type === "wildcard") {
1114
+ if (!node.wildcardChild) {
1115
+ node.wildcardChild = this.createNode("*", "*", undefined, true);
1116
+ }
1117
+ return node.wildcardChild;
1118
+ }
1119
+ if (segment.type === "param") {
1120
+ if (!node.paramChild) {
1121
+ node.paramChild = this.createNode(`:${segment.name}`, segment.name, segment.regex);
1122
+ }
1123
+ return this.insertSegments(node.paramChild, segments, index + 1);
1124
+ }
1125
+ const value = segment.value;
1126
+ let child = node.children.get(value);
1127
+ if (!child) {
1128
+ child = this.createNode(value);
1129
+ node.children.set(value, child);
1130
+ }
1131
+ return this.insertSegments(child, segments, index + 1);
1132
+ }
1133
+ match(method, pathname) {
1134
+ const params = {};
1135
+ let normalized = pathname.toLowerCase();
1136
+ if (normalized.length > 1 && normalized.endsWith("/")) {
1137
+ normalized = normalized.slice(0, -1);
1138
+ }
1139
+ const parts = normalized === "/" ? [""] : normalized.split("/").filter(Boolean);
1140
+ const result = this.searchTree(this.root, parts, 0, method, params);
1141
+ return result;
1142
+ }
1143
+ searchTree(node, parts, partIndex, method, params) {
1144
+ if (partIndex >= parts.length) {
1145
+ const handlerEntry = node.handlers.get(method) || node.handlers.get("ALL");
1146
+ if (handlerEntry) {
1147
+ return {
1148
+ handler: handlerEntry.handler,
1149
+ params: { ...params },
1150
+ middleware: handlerEntry.middleware,
1151
+ name: handlerEntry.name
1152
+ };
1153
+ }
1154
+ return;
1155
+ }
1156
+ const part = parts[partIndex];
1157
+ const staticChild = node.children.get(part);
1158
+ if (staticChild) {
1159
+ const result = this.searchTree(staticChild, parts, partIndex + 1, method, params);
1160
+ if (result)
1161
+ return result;
1162
+ }
1163
+ if (node.paramChild) {
1164
+ const paramNode = node.paramChild;
1165
+ if (paramNode.paramRegex) {
1166
+ if (paramNode.paramRegex.test(part)) {
1167
+ params[paramNode.paramName] = part;
1168
+ const result = this.searchTree(paramNode, parts, partIndex + 1, method, params);
1169
+ if (result)
1170
+ return result;
1171
+ delete params[paramNode.paramName];
1172
+ }
1173
+ } else {
1174
+ params[paramNode.paramName] = part;
1175
+ const result = this.searchTree(paramNode, parts, partIndex + 1, method, params);
1176
+ if (result)
1177
+ return result;
1178
+ delete params[paramNode.paramName];
1179
+ }
1180
+ }
1181
+ if (node.wildcardChild) {
1182
+ const wildcardNode = node.wildcardChild;
1183
+ params["*"] = parts.slice(partIndex).join("/");
1184
+ const handlerEntry = wildcardNode.handlers.get(method) || wildcardNode.handlers.get("ALL");
1185
+ if (handlerEntry) {
1186
+ return {
1187
+ handler: handlerEntry.handler,
1188
+ params: { ...params },
1189
+ middleware: handlerEntry.middleware,
1190
+ name: handlerEntry.name
1191
+ };
1192
+ }
1193
+ }
1194
+ return;
1195
+ }
1196
+ group(prefix, options) {
1197
+ const childRouter = new TreeRouter;
1198
+ childRouter.root = this.root;
1199
+ childRouter.groupPrefix = this.groupPrefix + prefix;
1200
+ const optsMiddleware = options?.middleware;
1201
+ const middlewareArray = optsMiddleware ? Array.isArray(optsMiddleware) ? optsMiddleware : [optsMiddleware] : [];
1202
+ childRouter.groupMiddleware = [...this.groupMiddleware, ...middlewareArray];
1203
+ childRouter.routeCount = this.routeCount;
1204
+ return childRouter;
1205
+ }
1206
+ getRoutes() {
1207
+ const routes = [];
1208
+ this.traverseTree(this.root, "", routes);
1209
+ return routes;
1210
+ }
1211
+ traverseTree(node, currentPath, routes) {
1212
+ for (const [method, entry] of node.handlers) {
1213
+ routes.push({
1214
+ method,
1215
+ pattern: currentPath || "/",
1216
+ name: entry.name
1217
+ });
1218
+ }
1219
+ for (const [path, child] of node.children) {
1220
+ const childPath = `${currentPath}/${path}`;
1221
+ this.traverseTree(child, childPath, routes);
1222
+ }
1223
+ if (node.paramChild) {
1224
+ const childPath = `${currentPath}/:${node.paramChild.paramName}`;
1225
+ this.traverseTree(node.paramChild, childPath, routes);
1226
+ }
1227
+ if (node.wildcardChild) {
1228
+ const childPath = `${currentPath}/*`;
1229
+ this.traverseTree(node.wildcardChild, childPath, routes);
1230
+ }
1231
+ }
1232
+ getRouterType() {
1233
+ return "tree";
1234
+ }
1235
+ getRouteCount() {
1236
+ return this.routeCount;
1237
+ }
1238
+ getTreeStats() {
1239
+ return {
1240
+ nodes: this.countNodes(this.root),
1241
+ depth: this.getTreeDepth(this.root),
1242
+ routes: this.routeCount
1243
+ };
1244
+ }
1245
+ countNodes(node) {
1246
+ let count = 1;
1247
+ for (const child of node.children.values()) {
1248
+ count += this.countNodes(child);
1249
+ }
1250
+ if (node.paramChild) {
1251
+ count += this.countNodes(node.paramChild);
1252
+ }
1253
+ if (node.wildcardChild) {
1254
+ count += this.countNodes(node.wildcardChild);
1255
+ }
1256
+ return count;
1257
+ }
1258
+ getTreeDepth(node) {
1259
+ let maxDepth = 0;
1260
+ for (const child of node.children.values()) {
1261
+ maxDepth = Math.max(maxDepth, this.getTreeDepth(child));
1262
+ }
1263
+ if (node.paramChild) {
1264
+ maxDepth = Math.max(maxDepth, this.getTreeDepth(node.paramChild));
1265
+ }
1266
+ if (node.wildcardChild) {
1267
+ maxDepth = Math.max(maxDepth, this.getTreeDepth(node.wildcardChild));
1268
+ }
1269
+ return maxDepth + 1;
1270
+ }
1271
+ get(pattern, handler, options) {
1272
+ this.addRoute("GET", pattern, handler, options);
1273
+ }
1274
+ post(pattern, handler, options) {
1275
+ this.addRoute("POST", pattern, handler, options);
1276
+ }
1277
+ put(pattern, handler, options) {
1278
+ this.addRoute("PUT", pattern, handler, options);
1279
+ }
1280
+ patch(pattern, handler, options) {
1281
+ this.addRoute("PATCH", pattern, handler, options);
1282
+ }
1283
+ delete(pattern, handler, options) {
1284
+ this.addRoute("DELETE", pattern, handler, options);
1285
+ }
1286
+ head(pattern, handler, options) {
1287
+ this.addRoute("HEAD", pattern, handler, options);
1288
+ }
1289
+ options(pattern, handler, options) {
1290
+ this.addRoute("OPTIONS", pattern, handler, options);
1291
+ }
1292
+ all(pattern, handler, options) {
1293
+ this.addRoute("ALL", pattern, handler, options);
1294
+ }
1295
+ }
1296
+
1297
+ // src/router/index.ts
1298
+ var DEFAULT_LINEAR_THRESHOLD = 10;
1299
+ var DEFAULT_REGEX_THRESHOLD = 50;
1300
+
1301
+ class Router {
1302
+ router;
1303
+ config;
1304
+ pendingRoutes = [];
1305
+ isBuilt = false;
1306
+ groupPrefix = "";
1307
+ groupMiddleware = [];
1308
+ constructor(config = {}) {
1309
+ this.config = {
1310
+ type: config.type ?? "auto",
1311
+ linearThreshold: config.linearThreshold ?? DEFAULT_LINEAR_THRESHOLD,
1312
+ regexThreshold: config.regexThreshold ?? DEFAULT_REGEX_THRESHOLD
1313
+ };
1314
+ if (this.config.type !== "auto") {
1315
+ this.router = this.createRouter(this.config.type);
1316
+ } else {
1317
+ this.router = new LinearRouter;
1318
+ }
1319
+ }
1320
+ createRouter(type) {
1321
+ switch (type) {
1322
+ case "linear":
1323
+ return new LinearRouter;
1324
+ case "regex":
1325
+ return new RegexRouter;
1326
+ case "tree":
1327
+ return new TreeRouter;
1328
+ default:
1329
+ return new LinearRouter;
1330
+ }
1331
+ }
1332
+ getOptimalRouterType(count) {
1333
+ if (count <= this.config.linearThreshold) {
1334
+ return "linear";
1335
+ }
1336
+ if (count <= this.config.regexThreshold) {
1337
+ return "regex";
1338
+ }
1339
+ return "tree";
1340
+ }
1341
+ migrateRouter(newType) {
1342
+ this.router = this.createRouter(newType);
1343
+ for (const route of this.pendingRoutes) {
1344
+ this.addToRouter(route.method, route.pattern, route.handler, route.options);
1345
+ }
1346
+ }
1347
+ addToRouter(method, pattern, handler, options) {
1348
+ switch (method) {
1349
+ case "GET":
1350
+ this.router.get(pattern, handler, options);
1351
+ break;
1352
+ case "POST":
1353
+ this.router.post(pattern, handler, options);
1354
+ break;
1355
+ case "PUT":
1356
+ this.router.put(pattern, handler, options);
1357
+ break;
1358
+ case "PATCH":
1359
+ this.router.patch(pattern, handler, options);
1360
+ break;
1361
+ case "DELETE":
1362
+ this.router.delete(pattern, handler, options);
1363
+ break;
1364
+ case "HEAD":
1365
+ this.router.head(pattern, handler, options);
1366
+ break;
1367
+ case "OPTIONS":
1368
+ this.router.options(pattern, handler, options);
1369
+ break;
1370
+ case "ALL":
1371
+ this.router.all(pattern, handler, options);
1372
+ break;
1373
+ }
1374
+ }
1375
+ addRoute(method, pattern, handler, options) {
1376
+ const fullPattern = this.groupPrefix + pattern;
1377
+ const optsMiddleware = options?.middleware;
1378
+ const routeMiddleware = optsMiddleware ? Array.isArray(optsMiddleware) ? optsMiddleware : [optsMiddleware] : [];
1379
+ const allMiddleware = [...this.groupMiddleware, ...routeMiddleware];
1380
+ const fullOptions = options?.name || allMiddleware.length > 0 ? {
1381
+ name: options?.name,
1382
+ middleware: allMiddleware
1383
+ } : undefined;
1384
+ this.pendingRoutes.push({
1385
+ method,
1386
+ pattern: fullPattern,
1387
+ handler,
1388
+ options: fullOptions
1389
+ });
1390
+ this.addToRouter(method, fullPattern, handler, fullOptions);
1391
+ if (this.config.type === "auto" && !this.isBuilt) {
1392
+ const routeCount = this.pendingRoutes.length;
1393
+ const optimalType = this.getOptimalRouterType(routeCount);
1394
+ const currentType = this.router.getRouterType();
1395
+ if (currentType !== optimalType) {
1396
+ this.migrateRouter(optimalType);
1397
+ }
1398
+ }
1399
+ }
1400
+ match(method, pathname) {
1401
+ this.isBuilt = true;
1402
+ return this.router.match(method, pathname);
1403
+ }
1404
+ group(prefix, options) {
1405
+ const childRouter = new Router(this.config);
1406
+ childRouter.router = this.router;
1407
+ childRouter.pendingRoutes = this.pendingRoutes;
1408
+ childRouter.groupPrefix = this.groupPrefix + prefix;
1409
+ childRouter.isBuilt = this.isBuilt;
1410
+ const optsMiddleware = options?.middleware;
1411
+ const middlewareArray = optsMiddleware ? Array.isArray(optsMiddleware) ? optsMiddleware : [optsMiddleware] : [];
1412
+ childRouter.groupMiddleware = [...this.groupMiddleware, ...middlewareArray];
1413
+ return childRouter;
1414
+ }
1415
+ getRoutes() {
1416
+ return this.router.getRoutes();
1417
+ }
1418
+ getRouterType() {
1419
+ return this.router.getRouterType();
1420
+ }
1421
+ getRouteCount() {
1422
+ return this.pendingRoutes.length;
1423
+ }
1424
+ getConfig() {
1425
+ return { ...this.config };
1426
+ }
1427
+ get(pattern, handler, options) {
1428
+ this.addRoute("GET", pattern, handler, options);
1429
+ }
1430
+ post(pattern, handler, options) {
1431
+ this.addRoute("POST", pattern, handler, options);
1432
+ }
1433
+ put(pattern, handler, options) {
1434
+ this.addRoute("PUT", pattern, handler, options);
1435
+ }
1436
+ patch(pattern, handler, options) {
1437
+ this.addRoute("PATCH", pattern, handler, options);
1438
+ }
1439
+ delete(pattern, handler, options) {
1440
+ this.addRoute("DELETE", pattern, handler, options);
1441
+ }
1442
+ head(pattern, handler, options) {
1443
+ this.addRoute("HEAD", pattern, handler, options);
1444
+ }
1445
+ options(pattern, handler, options) {
1446
+ this.addRoute("OPTIONS", pattern, handler, options);
1447
+ }
1448
+ all(pattern, handler, options) {
1449
+ this.addRoute("ALL", pattern, handler, options);
1450
+ }
1451
+ }
1452
+ function generateUrl(pattern, params = {}) {
1453
+ return pattern.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)\?/g, (_, name) => params[name] ?? "").replace(/:([a-zA-Z_][a-zA-Z0-9_]*)<[^>]+>/g, (_, name) => params[name] ?? "").replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, name) => {
1454
+ if (params[name] === undefined) {
1455
+ throw new Error(`Missing required parameter: ${name}`);
1456
+ }
1457
+ return params[name];
1458
+ }).replace(/\*/g, () => params["*"] ?? "");
1459
+ }
1460
+ function createRouter(config) {
1461
+ return new Router(config);
1462
+ }
1463
+ function createLinearRouter() {
1464
+ return new LinearRouter;
1465
+ }
1466
+ function createRegexRouter() {
1467
+ return new RegexRouter;
1468
+ }
1469
+ function createTreeRouter() {
1470
+ return new TreeRouter;
1471
+ }
1472
+
1473
+ // src/types/index.ts
1474
+ class BuenoError extends Error {
1475
+ statusCode;
1476
+ code;
1477
+ constructor(message, statusCode = 500, code) {
1478
+ super(message);
1479
+ this.statusCode = statusCode;
1480
+ this.code = code;
1481
+ this.name = "BuenoError";
1482
+ }
1483
+ }
1484
+
1485
+ class ValidationError extends BuenoError {
1486
+ issues;
1487
+ constructor(message, issues) {
1488
+ super(message, 422, "VALIDATION_ERROR");
1489
+ this.issues = issues;
1490
+ this.name = "ValidationError";
1491
+ }
1492
+ }
1493
+
1494
+ class NotFoundError extends BuenoError {
1495
+ constructor(message = "Not Found") {
1496
+ super(message, 404, "NOT_FOUND");
1497
+ this.name = "NotFoundError";
1498
+ }
1499
+ }
1500
+
1501
+ // src/modules/filters.ts
1502
+ var filterMetadataStore = new WeakMap;
1503
+ var catchMetadataStore = new WeakMap;
1504
+ var filterPrototypeStore = new WeakMap;
1505
+ function setFilterMetadata(target, key, value) {
1506
+ if (!filterMetadataStore.has(target)) {
1507
+ filterMetadataStore.set(target, new Map);
1508
+ }
1509
+ filterMetadataStore.get(target)?.set(key, value);
1510
+ }
1511
+ function getFilterMetadata(target, key) {
1512
+ return filterMetadataStore.get(target)?.get(key);
1513
+ }
1514
+ function setFilterPrototypeMetadata(target, key, value) {
1515
+ if (!filterPrototypeStore.has(target)) {
1516
+ filterPrototypeStore.set(target, new Map);
1517
+ }
1518
+ filterPrototypeStore.get(target)?.set(key, value);
1519
+ }
1520
+ function getFilterPrototypeMetadata(target, key) {
1521
+ return filterPrototypeStore.get(target)?.get(key);
1522
+ }
1523
+ function UseFilters(...filters) {
1524
+ const decorator = (target, propertyKey, descriptor) => {
1525
+ if (descriptor && propertyKey !== undefined) {
1526
+ const targetObj = target;
1527
+ const existingFilters = getFilterPrototypeMetadata(targetObj, "filters:method") ?? [];
1528
+ setFilterPrototypeMetadata(targetObj, "filters:method", [
1529
+ ...existingFilters,
1530
+ ...filters
1531
+ ]);
1532
+ return descriptor;
1533
+ } else {
1534
+ const targetClass = target;
1535
+ const existingFilters = getFilterMetadata(targetClass, "filters:class") ?? [];
1536
+ setFilterMetadata(targetClass, "filters:class", [
1537
+ ...existingFilters,
1538
+ ...filters
1539
+ ]);
1540
+ }
1541
+ };
1542
+ return decorator;
1543
+ }
1544
+ function Catch(exceptionType) {
1545
+ const decorator = (target) => {
1546
+ catchMetadataStore.set(target, {
1547
+ exceptionType
1548
+ });
1549
+ };
1550
+ return decorator;
1551
+ }
1552
+ function getClassFilters(target) {
1553
+ return getFilterMetadata(target, "filters:class");
1554
+ }
1555
+ function getMethodFilters(target, propertyKey) {
1556
+ const methodFilters = getFilterPrototypeMetadata(target, `filters:method:${String(propertyKey)}`);
1557
+ if (methodFilters) {
1558
+ return methodFilters;
1559
+ }
1560
+ return getFilterPrototypeMetadata(target, "filters:method");
1561
+ }
1562
+ function getCatchType(filter) {
1563
+ if (typeof filter === "function" && filter.prototype !== undefined) {
1564
+ const metadata = catchMetadataStore.get(filter);
1565
+ return metadata?.exceptionType;
1566
+ }
1567
+ if (typeof filter === "object" && filter !== null && "catch" in filter) {
1568
+ const constructor = filter.constructor;
1569
+ const metadata = catchMetadataStore.get(constructor);
1570
+ return metadata?.exceptionType;
1571
+ }
1572
+ return;
1573
+ }
1574
+ function canHandleException(filter, exception) {
1575
+ const catchType = getCatchType(filter);
1576
+ if (!catchType) {
1577
+ return true;
1578
+ }
1579
+ return exception instanceof catchType;
1580
+ }
1581
+ function isExceptionFilter(value) {
1582
+ return typeof value === "object" && value !== null && "catch" in value && typeof value.catch === "function";
1583
+ }
1584
+ function isFilterFn(value) {
1585
+ return typeof value === "function" && value.length === 2;
1586
+ }
1587
+ async function executeFilter(filter, exception, context, resolveFilter) {
1588
+ let filterInstance = null;
1589
+ if (isExceptionFilter(filter)) {
1590
+ filterInstance = filter;
1591
+ } else if (isFilterFn(filter)) {
1592
+ return filter(exception, context);
1593
+ } else if (typeof filter === "function") {
1594
+ if (resolveFilter) {
1595
+ filterInstance = resolveFilter(filter);
1596
+ }
1597
+ if (!filterInstance) {
1598
+ try {
1599
+ const Constructor = filter;
1600
+ filterInstance = new Constructor;
1601
+ } catch {}
1602
+ }
1603
+ } else if (typeof filter === "object" && filter !== null && !isExceptionFilter(filter)) {
1604
+ if (resolveFilter) {
1605
+ filterInstance = resolveFilter(filter);
1606
+ }
1607
+ }
1608
+ if (filterInstance && isExceptionFilter(filterInstance)) {
1609
+ return filterInstance.catch(exception, context);
1610
+ }
1611
+ return createInternalErrorResponse(exception);
1612
+ }
1613
+ async function findAndExecuteFilter(exception, context, options) {
1614
+ const { globalFilters, classFilters, methodFilters, resolveFilter } = options;
1615
+ const allFilters = [...methodFilters, ...classFilters, ...globalFilters];
1616
+ for (const filter of allFilters) {
1617
+ if (canHandleException(filter, exception)) {
1618
+ return executeFilter(filter, exception, context, resolveFilter);
1619
+ }
1620
+ }
1621
+ return createDefaultErrorResponse(exception, context);
1622
+ }
1623
+
1624
+ class HttpExceptionFilter {
1625
+ catch(exception, context) {
1626
+ return context.status(exception.statusCode).json({
1627
+ error: exception.name,
1628
+ message: exception.message,
1629
+ code: exception.code,
1630
+ statusCode: exception.statusCode
1631
+ });
1632
+ }
1633
+ }
1634
+ HttpExceptionFilter = __legacyDecorateClassTS([
1635
+ Catch(BuenoError)
1636
+ ], HttpExceptionFilter);
1637
+
1638
+ class ValidationFilter {
1639
+ catch(exception, context) {
1640
+ return context.status(422).json({
1641
+ error: "Validation Failed",
1642
+ message: exception.message,
1643
+ code: "VALIDATION_ERROR",
1644
+ issues: exception.issues
1645
+ });
1646
+ }
1647
+ }
1648
+ ValidationFilter = __legacyDecorateClassTS([
1649
+ Catch(ValidationError)
1650
+ ], ValidationFilter);
1651
+
1652
+ class NotFoundFilter {
1653
+ catch(exception, context) {
1654
+ return context.status(404).json({
1655
+ error: "Not Found",
1656
+ message: exception.message,
1657
+ code: "NOT_FOUND"
1658
+ });
1659
+ }
1660
+ }
1661
+ NotFoundFilter = __legacyDecorateClassTS([
1662
+ Catch(NotFoundError)
1663
+ ], NotFoundFilter);
1664
+
1665
+ class AllExceptionsFilter {
1666
+ catch(exception, context) {
1667
+ console.error("Unhandled exception:", exception);
1668
+ if (exception instanceof BuenoError) {
1669
+ return context.status(exception.statusCode).json({
1670
+ error: exception.name,
1671
+ message: exception.message,
1672
+ code: exception.code
1673
+ });
1674
+ }
1675
+ return context.status(500).json({
1676
+ error: "Internal Server Error",
1677
+ message: exception.message || "An unexpected error occurred"
1678
+ });
1679
+ }
1680
+ }
1681
+ function createDefaultErrorResponse(exception, context) {
1682
+ console.error("Unhandled exception (no filter matched):", exception);
1683
+ return context.status(500).json({
1684
+ error: "Internal Server Error",
1685
+ message: exception.message || "An unexpected error occurred"
1686
+ });
1687
+ }
1688
+ function createInternalErrorResponse(exception) {
1689
+ console.error("Internal server error:", exception);
1690
+ return new Response(JSON.stringify({
1691
+ error: "Internal Server Error",
1692
+ message: "An unexpected error occurred"
1693
+ }), {
1694
+ status: 500,
1695
+ headers: {
1696
+ "Content-Type": "application/json"
1697
+ }
1698
+ });
1699
+ }
1700
+
1701
+ // src/modules/guards.ts
1702
+ var guardsClassMetadata = new WeakMap;
1703
+ var guardsMethodMetadata = new WeakMap;
1704
+ function setClassGuards(target, guards) {
1705
+ guardsClassMetadata.set(target, guards);
1706
+ }
1707
+ function getClassGuards(target) {
1708
+ return guardsClassMetadata.get(target);
1709
+ }
1710
+ function setMethodGuards(target, propertyKey, guards) {
1711
+ if (!guardsMethodMetadata.has(target)) {
1712
+ guardsMethodMetadata.set(target, new Map);
1713
+ }
1714
+ guardsMethodMetadata.get(target)?.set(propertyKey, guards);
1715
+ }
1716
+ function getMethodGuards(target, propertyKey) {
1717
+ return guardsMethodMetadata.get(target)?.get(propertyKey);
1718
+ }
1719
+ function UseGuards(...guards) {
1720
+ const decorator = (target, propertyKey, descriptor) => {
1721
+ if (propertyKey !== undefined && descriptor !== undefined) {
1722
+ const targetObj = target;
1723
+ const existingGuards = getMethodGuards(targetObj, propertyKey) ?? [];
1724
+ setMethodGuards(targetObj, propertyKey, [...existingGuards, ...guards]);
1725
+ return descriptor;
1726
+ } else {
1727
+ const targetClass = target;
1728
+ const existingGuards = getClassGuards(targetClass) ?? [];
1729
+ setClassGuards(targetClass, [...existingGuards, ...guards]);
1730
+ }
1731
+ };
1732
+ return decorator;
1733
+ }
1734
+
1735
+ class AuthGuard {
1736
+ canActivate(context) {
1737
+ const authHeader = context.req.headers.get("Authorization");
1738
+ return authHeader !== null && authHeader.length > 0;
1739
+ }
1740
+ }
1741
+ var rolesMethodMetadata = new WeakMap;
1742
+ function setMethodRoles(target, propertyKey, roles) {
1743
+ if (!rolesMethodMetadata.has(target)) {
1744
+ rolesMethodMetadata.set(target, new Map);
1745
+ }
1746
+ rolesMethodMetadata.get(target)?.set(propertyKey, roles);
1747
+ }
1748
+ function getMethodRoles(target, propertyKey) {
1749
+ return rolesMethodMetadata.get(target)?.get(propertyKey);
1750
+ }
1751
+ function Roles(...roles) {
1752
+ return (target, propertyKey, descriptor) => {
1753
+ const targetObj = target;
1754
+ setMethodRoles(targetObj, propertyKey, roles);
1755
+ return descriptor;
1756
+ };
1757
+ }
1758
+
1759
+ class RolesGuard {
1760
+ canActivate(context) {
1761
+ const requiredRoles = context.requiredRoles;
1762
+ if (!requiredRoles || requiredRoles.length === 0) {
1763
+ return true;
1764
+ }
1765
+ const user = context.user;
1766
+ if (!user || !user.roles) {
1767
+ return false;
1768
+ }
1769
+ return requiredRoles.some((role) => user.roles?.includes(role));
1770
+ }
1771
+ }
1772
+ async function executeGuards(context, options) {
1773
+ const {
1774
+ globalGuards = [],
1775
+ classGuards = [],
1776
+ methodGuards = [],
1777
+ resolveGuard
1778
+ } = options;
1779
+ const allGuards = [...globalGuards, ...classGuards, ...methodGuards];
1780
+ for (const guard of allGuards) {
1781
+ let guardInstance = null;
1782
+ if (typeof guard === "function") {
1783
+ const funcGuard = guard;
1784
+ if (funcGuard.prototype && typeof funcGuard.prototype === "object" && "canActivate" in funcGuard.prototype) {
1785
+ guardInstance = resolveGuard ? resolveGuard(guard) : null;
1786
+ if (!guardInstance) {
1787
+ const GuardClass = guard;
1788
+ guardInstance = new GuardClass;
1789
+ }
1790
+ } else {
1791
+ guardInstance = guard;
1792
+ }
1793
+ } else if (typeof guard === "object" && guard !== null) {
1794
+ const objGuard = guard;
1795
+ if ("canActivate" in objGuard && typeof objGuard.canActivate === "function") {
1796
+ guardInstance = guard;
1797
+ } else {
1798
+ guardInstance = resolveGuard ? resolveGuard(guard) : null;
1799
+ }
1800
+ }
1801
+ if (!guardInstance) {
1802
+ console.warn("Guard could not be resolved:", guard);
1803
+ continue;
1804
+ }
1805
+ let result;
1806
+ if (typeof guardInstance === "function") {
1807
+ result = await guardInstance(context);
1808
+ } else {
1809
+ result = await guardInstance.canActivate(context);
1810
+ }
1811
+ if (!result) {
1812
+ return false;
1813
+ }
1814
+ }
1815
+ return true;
1816
+ }
1817
+ function createForbiddenResponse() {
1818
+ return new Response(JSON.stringify({
1819
+ statusCode: 403,
1820
+ error: "Forbidden",
1821
+ message: "Access denied"
1822
+ }), {
1823
+ status: 403,
1824
+ headers: {
1825
+ "Content-Type": "application/json"
1826
+ }
1827
+ });
1828
+ }
1829
+
1830
+ // src/modules/interceptors.ts
1831
+ var interceptorsClassMetadata = new WeakMap;
1832
+ var interceptorsMethodMetadata = new WeakMap;
1833
+ function setClassInterceptors(target, interceptors) {
1834
+ interceptorsClassMetadata.set(target, interceptors);
1835
+ }
1836
+ function getClassInterceptors(target) {
1837
+ return interceptorsClassMetadata.get(target);
1838
+ }
1839
+ function setMethodInterceptors(target, propertyKey, interceptors) {
1840
+ if (!interceptorsMethodMetadata.has(target)) {
1841
+ interceptorsMethodMetadata.set(target, new Map);
1842
+ }
1843
+ interceptorsMethodMetadata.get(target)?.set(propertyKey, interceptors);
1844
+ }
1845
+ function getMethodInterceptors(target, propertyKey) {
1846
+ return interceptorsMethodMetadata.get(target)?.get(propertyKey);
1847
+ }
1848
+ function UseInterceptors(...interceptors) {
1849
+ const decorator = (target, propertyKey, descriptor) => {
1850
+ if (propertyKey !== undefined && descriptor !== undefined) {
1851
+ const targetObj = target;
1852
+ const existingInterceptors = getMethodInterceptors(targetObj, propertyKey) ?? [];
1853
+ setMethodInterceptors(targetObj, propertyKey, [
1854
+ ...existingInterceptors,
1855
+ ...interceptors
1856
+ ]);
1857
+ return descriptor;
1858
+ } else {
1859
+ const targetClass = target;
1860
+ const existingInterceptors = getClassInterceptors(targetClass) ?? [];
1861
+ setClassInterceptors(targetClass, [
1862
+ ...existingInterceptors,
1863
+ ...interceptors
1864
+ ]);
1865
+ }
1866
+ };
1867
+ return decorator;
1868
+ }
1869
+
1870
+ class LoggingInterceptor {
1871
+ async intercept(context, next) {
1872
+ const method = context.method;
1873
+ const path = context.path;
1874
+ const startTime = Date.now();
1875
+ console.log(`[${method}] ${path} - Started`);
1876
+ try {
1877
+ const result = await next.handle();
1878
+ const duration = Date.now() - startTime;
1879
+ console.log(`[${method}] ${path} - Completed in ${duration}ms`);
1880
+ return result;
1881
+ } catch (error) {
1882
+ const duration = Date.now() - startTime;
1883
+ console.error(`[${method}] ${path} - Failed in ${duration}ms`, error);
1884
+ throw error;
1885
+ }
1886
+ }
1887
+ }
1888
+
1889
+ class TransformInterceptor {
1890
+ async intercept(context, next) {
1891
+ const result = await next.handle();
1892
+ return {
1893
+ data: result,
1894
+ timestamp: new Date().toISOString()
1895
+ };
1896
+ }
1897
+ }
1898
+
1899
+ class TimeoutInterceptor {
1900
+ timeoutMs;
1901
+ constructor(timeoutMs) {
1902
+ this.timeoutMs = timeoutMs;
1903
+ }
1904
+ async intercept(context, next) {
1905
+ const timeoutPromise = new Promise((_, reject) => {
1906
+ setTimeout(() => {
1907
+ reject(new Error(`Request timeout after ${this.timeoutMs}ms`));
1908
+ }, this.timeoutMs);
1909
+ });
1910
+ return Promise.race([next.handle(), timeoutPromise]);
1911
+ }
1912
+ }
1913
+
1914
+ class CacheInterceptor {
1915
+ ttlMs;
1916
+ static cache = new Map;
1917
+ static cleanupInterval = null;
1918
+ constructor(ttlMs = 60000) {
1919
+ this.ttlMs = ttlMs;
1920
+ CacheInterceptor.setupCleanup();
1921
+ }
1922
+ static setupCleanup() {
1923
+ if (CacheInterceptor.cleanupInterval === null) {
1924
+ CacheInterceptor.cleanupInterval = setInterval(() => {
1925
+ const now = Date.now();
1926
+ for (const [key, entry] of CacheInterceptor.cache.entries()) {
1927
+ if (entry.expiresAt < now) {
1928
+ CacheInterceptor.cache.delete(key);
1929
+ }
1930
+ }
1931
+ }, 60000);
1932
+ }
1933
+ }
1934
+ getCacheKey(context) {
1935
+ return `${context.method}:${context.path}:${context.url.search}`;
1936
+ }
1937
+ static clearCache() {
1938
+ CacheInterceptor.cache.clear();
1939
+ }
1940
+ static clearCachePattern(pattern) {
1941
+ for (const key of CacheInterceptor.cache.keys()) {
1942
+ if (key.includes(pattern)) {
1943
+ CacheInterceptor.cache.delete(key);
1944
+ }
1945
+ }
1946
+ }
1947
+ async intercept(context, next) {
1948
+ const cacheKey = this.getCacheKey(context);
1949
+ const now = Date.now();
1950
+ const cached = CacheInterceptor.cache.get(cacheKey);
1951
+ if (cached && cached.expiresAt > now) {
1952
+ return cached.value;
1953
+ }
1954
+ const result = await next.handle();
1955
+ CacheInterceptor.cache.set(cacheKey, {
1956
+ value: result,
1957
+ expiresAt: now + this.ttlMs
1958
+ });
1959
+ return result;
1960
+ }
1961
+ }
1962
+
1963
+ class HeaderInterceptor {
1964
+ headers;
1965
+ constructor(headers) {
1966
+ this.headers = headers;
1967
+ }
1968
+ async intercept(context, next) {
1969
+ const result = await next.handle();
1970
+ if (result instanceof Response) {
1971
+ const newHeaders = new Headers(result.headers);
1972
+ for (const [key, value] of Object.entries(this.headers)) {
1973
+ newHeaders.set(key, value);
1974
+ }
1975
+ return new Response(result.body, {
1976
+ status: result.status,
1977
+ statusText: result.statusText,
1978
+ headers: newHeaders
1979
+ });
1980
+ }
1981
+ return result;
1982
+ }
1983
+ }
1984
+ function createCallHandler(interceptors, context, finalHandler, resolveInterceptor) {
1985
+ let index = 0;
1986
+ const execute = async () => {
1987
+ if (index >= interceptors.length) {
1988
+ return finalHandler();
1989
+ }
1990
+ const interceptor = interceptors[index++];
1991
+ let interceptorInstance = interceptor;
1992
+ if (resolveInterceptor && !isNestInterceptor(interceptor) && !isInterceptorFn(interceptor)) {
1993
+ interceptorInstance = resolveInterceptor(interceptor);
1994
+ }
1995
+ if (!interceptorInstance) {
1996
+ console.warn("Interceptor could not be resolved:", interceptor);
1997
+ return execute();
1998
+ }
1999
+ const next = {
2000
+ handle: () => execute()
2001
+ };
2002
+ if (isInterceptorFn(interceptorInstance)) {
2003
+ return interceptorInstance(context, () => execute());
2004
+ } else {
2005
+ return interceptorInstance.intercept(context, next);
2006
+ }
2007
+ };
2008
+ return {
2009
+ handle: execute
2010
+ };
2011
+ }
2012
+ async function executeInterceptors(context, handler, options) {
2013
+ const {
2014
+ globalInterceptors = [],
2015
+ classInterceptors = [],
2016
+ methodInterceptors = [],
2017
+ resolveInterceptor
2018
+ } = options;
2019
+ const allInterceptors = [
2020
+ ...globalInterceptors,
2021
+ ...classInterceptors,
2022
+ ...methodInterceptors
2023
+ ];
2024
+ if (allInterceptors.length === 0) {
2025
+ return handler();
2026
+ }
2027
+ const resolvedInterceptors = [];
2028
+ for (const interceptor of allInterceptors) {
2029
+ let instance = null;
2030
+ if (typeof interceptor === "function") {
2031
+ const funcInterceptor = interceptor;
2032
+ if (funcInterceptor.prototype && typeof funcInterceptor.prototype === "object" && "intercept" in funcInterceptor.prototype) {
2033
+ instance = resolveInterceptor ? resolveInterceptor(interceptor) : null;
2034
+ if (!instance) {
2035
+ const InterceptorClass = interceptor;
2036
+ instance = new InterceptorClass;
2037
+ }
2038
+ } else {
2039
+ instance = interceptor;
2040
+ }
2041
+ } else if (typeof interceptor === "object" && interceptor !== null) {
2042
+ const objInterceptor = interceptor;
2043
+ if ("intercept" in objInterceptor && typeof objInterceptor.intercept === "function") {
2044
+ instance = interceptor;
2045
+ } else {
2046
+ instance = resolveInterceptor ? resolveInterceptor(interceptor) : null;
2047
+ }
2048
+ }
2049
+ if (instance) {
2050
+ resolvedInterceptors.push(instance);
2051
+ } else {
2052
+ console.warn("Interceptor could not be resolved:", interceptor);
2053
+ }
2054
+ }
2055
+ const callHandler = createCallHandler(resolvedInterceptors, context, handler, resolveInterceptor);
2056
+ return callHandler.handle();
2057
+ }
2058
+ function isNestInterceptor(value) {
2059
+ return typeof value === "object" && value !== null && "intercept" in value && typeof value.intercept === "function";
2060
+ }
2061
+ function isInterceptorFn(value) {
2062
+ return typeof value === "function" && !isNestInterceptor(value);
2063
+ }
2064
+
2065
+ // src/modules/metadata.ts
2066
+ var metadataStore = new WeakMap;
2067
+ function setMetadata(target, key, value) {
2068
+ if (!metadataStore.has(target)) {
2069
+ metadataStore.set(target, new Map);
2070
+ }
2071
+ metadataStore.get(target)?.set(key, value);
2072
+ }
2073
+ function getMetadata(target, key) {
2074
+ return metadataStore.get(target)?.get(key);
2075
+ }
2076
+ var prototypeMetadataStore = new WeakMap;
2077
+ function setPrototypeMetadata(target, key, value) {
2078
+ if (!prototypeMetadataStore.has(target)) {
2079
+ prototypeMetadataStore.set(target, new Map);
2080
+ }
2081
+ prototypeMetadataStore.get(target)?.set(key, value);
2082
+ }
2083
+ function getPrototypeMetadata(target, key) {
2084
+ return prototypeMetadataStore.get(target)?.get(key);
2085
+ }
2086
+ function Injectable2() {
2087
+ return (target) => {
2088
+ setMetadata(target, "injectable", true);
2089
+ return target;
2090
+ };
2091
+ }
2092
+ function Controller(path = "") {
2093
+ return (target) => {
2094
+ setMetadata(target, "controller", true);
2095
+ setMetadata(target, "path", path);
2096
+ return target;
2097
+ };
2098
+ }
2099
+ function Module(metadata) {
2100
+ return (target) => {
2101
+ setMetadata(target, "module", metadata);
2102
+ return target;
2103
+ };
2104
+ }
2105
+
2106
+ // src/modules/lazy.ts
2107
+ var lazyModuleMetadata = new WeakMap;
2108
+ function setLazyMetadata(target, metadata) {
2109
+ lazyModuleMetadata.set(target, metadata);
2110
+ }
2111
+ function getLazyMetadata(target) {
2112
+ return lazyModuleMetadata.get(target);
2113
+ }
2114
+ function isLazyModule(target) {
2115
+ return lazyModuleMetadata.has(target);
2116
+ }
2117
+
2118
+ class LazyModuleLoaderImpl {
2119
+ loaded = false;
2120
+ loadingPromise = null;
2121
+ loader;
2122
+ onModuleLoaded;
2123
+ constructor(loader, onModuleLoaded) {
2124
+ this.loader = loader;
2125
+ this.onModuleLoaded = onModuleLoaded;
2126
+ }
2127
+ async load() {
2128
+ if (this.loadingPromise) {
2129
+ return this.loadingPromise;
2130
+ }
2131
+ if (this.loaded) {
2132
+ return;
2133
+ }
2134
+ this.loadingPromise = this.doLoad();
2135
+ await this.loadingPromise;
2136
+ this.loadingPromise = null;
2137
+ }
2138
+ async doLoad() {
2139
+ try {
2140
+ const moduleClass = await this.loader();
2141
+ this.loaded = true;
2142
+ if (this.onModuleLoaded) {
2143
+ await this.onModuleLoaded(moduleClass);
2144
+ }
2145
+ } catch (error) {
2146
+ this.loadingPromise = null;
2147
+ throw new Error(`Failed to load lazy module: ${error instanceof Error ? error.message : String(error)}`);
2148
+ }
2149
+ }
2150
+ isLoaded() {
2151
+ return this.loaded;
2152
+ }
2153
+ }
2154
+ function LazyModule(loader) {
2155
+ return (target) => {
2156
+ setLazyMetadata(target, {
2157
+ loader,
2158
+ loaded: false
2159
+ });
2160
+ return target;
2161
+ };
2162
+ }
2163
+ var MODULE_LOADER_TOKEN = Symbol.for("ModuleLoader");
2164
+
2165
+ class ModuleLoader {
2166
+ container;
2167
+ loadedModules = new Set;
2168
+ moduleLoaders = new Map;
2169
+ onModuleLoadCallback;
2170
+ constructor(container) {
2171
+ this.container = container;
2172
+ }
2173
+ setOnModuleLoadCallback(callback) {
2174
+ this.onModuleLoadCallback = callback;
2175
+ }
2176
+ async load(moduleToken, options = {}) {
2177
+ const moduleClass = typeof moduleToken === "function" ? moduleToken : null;
2178
+ if (!moduleClass) {
2179
+ throw new Error("Module token must be a class constructor");
2180
+ }
2181
+ if (this.isLoaded(moduleClass)) {
2182
+ return;
2183
+ }
2184
+ const metadata = getLazyMetadata(moduleClass);
2185
+ if (!metadata) {
2186
+ throw new Error(`Module ${moduleClass.name} is not a lazy module. Use @LazyModule decorator.`);
2187
+ }
2188
+ let loader = this.moduleLoaders.get(moduleClass);
2189
+ if (!loader) {
2190
+ loader = new LazyModuleLoaderImpl(metadata.loader, async (loadedModule) => {
2191
+ metadata.loaded = true;
2192
+ metadata.loadedModule = loadedModule;
2193
+ if (this.onModuleLoadCallback && !options.skipLifecycle) {
2194
+ await this.onModuleLoadCallback(loadedModule);
2195
+ }
2196
+ });
2197
+ this.moduleLoaders.set(moduleClass, loader);
2198
+ }
2199
+ await loader.load();
2200
+ this.loadedModules.add(moduleClass);
2201
+ }
2202
+ isLoaded(moduleToken) {
2203
+ if (typeof moduleToken === "function") {
2204
+ const metadata = getLazyMetadata(moduleToken);
2205
+ if (metadata) {
2206
+ return metadata.loaded;
2207
+ }
2208
+ return this.loadedModules.has(moduleToken);
2209
+ }
2210
+ return this.loadedModules.has(moduleToken);
2211
+ }
2212
+ getLoadedModules() {
2213
+ return Array.from(this.loadedModules);
2214
+ }
2215
+ async preload(moduleTokens) {
2216
+ await Promise.all(moduleTokens.map((token) => this.load(token)));
2217
+ }
2218
+ }
2219
+ ModuleLoader = __legacyDecorateClassTS([
2220
+ Injectable2(),
2221
+ __legacyMetadataTS("design:paramtypes", [
2222
+ typeof Container === "undefined" ? Object : Container
2223
+ ])
2224
+ ], ModuleLoader);
2225
+
2226
+ class LazyModuleRegistry {
2227
+ static instance;
2228
+ lazyModules = new Map;
2229
+ constructor() {}
2230
+ static getInstance() {
2231
+ if (!LazyModuleRegistry.instance) {
2232
+ LazyModuleRegistry.instance = new LazyModuleRegistry;
2233
+ }
2234
+ return LazyModuleRegistry.instance;
2235
+ }
2236
+ register(token, metadata) {
2237
+ this.lazyModules.set(token, metadata);
2238
+ }
2239
+ get(token) {
2240
+ return this.lazyModules.get(token);
2241
+ }
2242
+ has(token) {
2243
+ return this.lazyModules.has(token);
2244
+ }
2245
+ getAllTokens() {
2246
+ return Array.from(this.lazyModules.keys());
2247
+ }
2248
+ clear() {
2249
+ this.lazyModules.clear();
2250
+ }
2251
+ }
2252
+ function createLazyLoader(importFn, exportName = "default") {
2253
+ return async () => {
2254
+ const module = await importFn();
2255
+ const moduleClass = module[exportName];
2256
+ if (!moduleClass) {
2257
+ throw new Error(`Export "${exportName}" not found in lazy loaded module`);
2258
+ }
2259
+ return moduleClass;
2260
+ };
2261
+ }
2262
+ function areAllLazyModulesLoaded(modules) {
2263
+ return modules.every((module) => {
2264
+ const metadata = getLazyMetadata(module);
2265
+ return !metadata || metadata.loaded;
2266
+ });
2267
+ }
2268
+ function getUnloadedLazyModules(modules) {
2269
+ return modules.filter((module) => {
2270
+ const metadata = getLazyMetadata(module);
2271
+ return metadata && !metadata.loaded;
2272
+ });
2273
+ }
2274
+
2275
+ // src/modules/lifecycle.ts
2276
+ function isOnModuleInit(instance) {
2277
+ return typeof instance === "object" && instance !== null && "onModuleInit" in instance && typeof instance.onModuleInit === "function";
2278
+ }
2279
+ function isOnApplicationBootstrap(instance) {
2280
+ return typeof instance === "object" && instance !== null && "onApplicationBootstrap" in instance && typeof instance.onApplicationBootstrap === "function";
2281
+ }
2282
+ function isOnModuleDestroy(instance) {
2283
+ return typeof instance === "object" && instance !== null && "onModuleDestroy" in instance && typeof instance.onModuleDestroy === "function";
2284
+ }
2285
+ function isBeforeApplicationShutdown(instance) {
2286
+ return typeof instance === "object" && instance !== null && "beforeApplicationShutdown" in instance && typeof instance.beforeApplicationShutdown === "function";
2287
+ }
2288
+ function isOnApplicationShutdown(instance) {
2289
+ return typeof instance === "object" && instance !== null && "onApplicationShutdown" in instance && typeof instance.onApplicationShutdown === "function";
2290
+ }
2291
+ function isOnBeforeRequest(instance) {
2292
+ return typeof instance === "object" && instance !== null && "onBeforeRequest" in instance && typeof instance.onBeforeRequest === "function";
2293
+ }
2294
+ function isOnAfterRequest(instance) {
2295
+ return typeof instance === "object" && instance !== null && "onAfterRequest" in instance && typeof instance.onAfterRequest === "function";
2296
+ }
2297
+ function isOnRequestError(instance) {
2298
+ return typeof instance === "object" && instance !== null && "onRequestError" in instance && typeof instance.onRequestError === "function";
2299
+ }
2300
+
2301
+ class LifecycleHookManager {
2302
+ instancesWithModuleInit = [];
2303
+ instancesWithBootstrap = [];
2304
+ instancesWithModuleDestroy = [];
2305
+ instancesWithBeforeShutdown = [];
2306
+ instancesWithShutdown = [];
2307
+ instancesWithBeforeRequest = [];
2308
+ instancesWithAfterRequest = [];
2309
+ instancesWithRequestError = [];
2310
+ registerInstance(instance) {
2311
+ if (isOnModuleInit(instance)) {
2312
+ this.instancesWithModuleInit.push(instance);
2313
+ }
2314
+ if (isOnApplicationBootstrap(instance)) {
2315
+ this.instancesWithBootstrap.push(instance);
2316
+ }
2317
+ if (isOnModuleDestroy(instance)) {
2318
+ this.instancesWithModuleDestroy.push(instance);
2319
+ }
2320
+ if (isBeforeApplicationShutdown(instance)) {
2321
+ this.instancesWithBeforeShutdown.push(instance);
2322
+ }
2323
+ if (isOnApplicationShutdown(instance)) {
2324
+ this.instancesWithShutdown.push(instance);
2325
+ }
2326
+ if (isOnBeforeRequest(instance)) {
2327
+ this.instancesWithBeforeRequest.push(instance);
2328
+ }
2329
+ if (isOnAfterRequest(instance)) {
2330
+ this.instancesWithAfterRequest.push(instance);
2331
+ }
2332
+ if (isOnRequestError(instance)) {
2333
+ this.instancesWithRequestError.push(instance);
2334
+ }
2335
+ }
2336
+ registerInstances(instances) {
2337
+ for (const instance of instances) {
2338
+ this.registerInstance(instance);
2339
+ }
2340
+ }
2341
+ async executeOnModuleInit() {
2342
+ for (const instance of this.instancesWithModuleInit) {
2343
+ await instance.onModuleInit();
2344
+ }
2345
+ }
2346
+ async executeOnApplicationBootstrap() {
2347
+ for (const instance of this.instancesWithBootstrap) {
2348
+ await instance.onApplicationBootstrap();
2349
+ }
2350
+ }
2351
+ async executeBeforeApplicationShutdown(signal) {
2352
+ for (const instance of this.instancesWithBeforeShutdown) {
2353
+ await instance.beforeApplicationShutdown(signal);
2354
+ }
2355
+ }
2356
+ async executeOnModuleDestroy() {
2357
+ for (const instance of this.instancesWithModuleDestroy) {
2358
+ await instance.onModuleDestroy();
2359
+ }
2360
+ }
2361
+ async executeOnApplicationShutdown(signal) {
2362
+ for (const instance of this.instancesWithShutdown) {
2363
+ await instance.onApplicationShutdown(signal);
2364
+ }
2365
+ }
2366
+ async executeOnBeforeRequest(context) {
2367
+ for (const instance of this.instancesWithBeforeRequest) {
2368
+ await instance.onBeforeRequest(context);
2369
+ }
2370
+ }
2371
+ async executeOnAfterRequest(context, response) {
2372
+ for (const instance of this.instancesWithAfterRequest) {
2373
+ await instance.onAfterRequest(context, response);
2374
+ }
2375
+ }
2376
+ async executeOnRequestError(context, error) {
2377
+ for (const instance of this.instancesWithRequestError) {
2378
+ await instance.onRequestError(context, error);
2379
+ }
2380
+ }
2381
+ hasRegisteredHooks() {
2382
+ return this.instancesWithModuleInit.length > 0 || this.instancesWithBootstrap.length > 0 || this.instancesWithModuleDestroy.length > 0 || this.instancesWithBeforeShutdown.length > 0 || this.instancesWithShutdown.length > 0 || this.instancesWithBeforeRequest.length > 0 || this.instancesWithAfterRequest.length > 0 || this.instancesWithRequestError.length > 0;
2383
+ }
2384
+ getHookCounts() {
2385
+ return {
2386
+ onModuleInit: this.instancesWithModuleInit.length,
2387
+ onApplicationBootstrap: this.instancesWithBootstrap.length,
2388
+ onModuleDestroy: this.instancesWithModuleDestroy.length,
2389
+ beforeApplicationShutdown: this.instancesWithBeforeShutdown.length,
2390
+ onApplicationShutdown: this.instancesWithShutdown.length,
2391
+ onBeforeRequest: this.instancesWithBeforeRequest.length,
2392
+ onAfterRequest: this.instancesWithAfterRequest.length,
2393
+ onRequestError: this.instancesWithRequestError.length
2394
+ };
2395
+ }
2396
+ clear() {
2397
+ this.instancesWithModuleInit = [];
2398
+ this.instancesWithBootstrap = [];
2399
+ this.instancesWithModuleDestroy = [];
2400
+ this.instancesWithBeforeShutdown = [];
2401
+ this.instancesWithShutdown = [];
2402
+ this.instancesWithBeforeRequest = [];
2403
+ this.instancesWithAfterRequest = [];
2404
+ this.instancesWithRequestError = [];
2405
+ }
2406
+ }
2407
+
2408
+ class ShutdownSignalHandler {
2409
+ isShuttingDown = false;
2410
+ signalListeners = [];
2411
+ onSignal(listener) {
2412
+ this.signalListeners.push(listener);
2413
+ }
2414
+ offSignal(listener) {
2415
+ const index = this.signalListeners.indexOf(listener);
2416
+ if (index > -1) {
2417
+ this.signalListeners.splice(index, 1);
2418
+ }
2419
+ }
2420
+ startListening() {
2421
+ process.on("SIGTERM", () => this.handleSignal("SIGTERM"));
2422
+ process.on("SIGINT", () => this.handleSignal("SIGINT"));
2423
+ }
2424
+ stopListening() {
2425
+ process.off("SIGTERM", () => this.handleSignal("SIGTERM"));
2426
+ process.off("SIGINT", () => this.handleSignal("SIGINT"));
2427
+ }
2428
+ async handleSignal(signal) {
2429
+ if (this.isShuttingDown) {
2430
+ console.log(`Already shutting down, ignoring ${signal}`);
2431
+ return;
2432
+ }
2433
+ this.isShuttingDown = true;
2434
+ console.log(`
2435
+ Received ${signal}, starting graceful shutdown...`);
2436
+ for (const listener of this.signalListeners) {
2437
+ try {
2438
+ await listener(signal);
2439
+ } catch (error) {
2440
+ console.error("Error during shutdown:", error);
2441
+ }
2442
+ }
2443
+ process.exit(0);
2444
+ }
2445
+ isShuttingDownNow() {
2446
+ return this.isShuttingDown;
2447
+ }
2448
+ }
2449
+
2450
+ // src/modules/pipes.ts
2451
+ var pipesMethodMetadata = new WeakMap;
2452
+ function setMethodPipes(target, propertyKey, metadata) {
2453
+ if (!pipesMethodMetadata.has(target)) {
2454
+ pipesMethodMetadata.set(target, new Map);
2455
+ }
2456
+ pipesMethodMetadata.get(target)?.set(propertyKey, metadata);
2457
+ }
2458
+ function getMethodPipes(target, propertyKey) {
2459
+ return pipesMethodMetadata.get(target)?.get(propertyKey);
2460
+ }
2461
+ function UsePipes(...pipes) {
2462
+ return (target, propertyKey, parameterIndex) => {
2463
+ if (propertyKey === undefined) {
2464
+ throw new Error("UsePipes can only be used on method parameters");
2465
+ }
2466
+ const targetObj = target;
2467
+ const existing = getMethodPipes(targetObj, propertyKey) ?? [];
2468
+ const existingParam = existing.find((p) => p.index === parameterIndex);
2469
+ if (existingParam) {
2470
+ existingParam.pipes.push(...pipes);
2471
+ } else {
2472
+ existing.push({
2473
+ index: parameterIndex,
2474
+ decorator: "custom",
2475
+ pipes: [...pipes]
2476
+ });
2477
+ }
2478
+ setMethodPipes(targetObj, propertyKey, existing);
2479
+ };
2480
+ }
2481
+ function Body(schema) {
2482
+ return (target, propertyKey, parameterIndex) => {
2483
+ if (propertyKey === undefined) {
2484
+ throw new Error("Body can only be used on method parameters");
2485
+ }
2486
+ const targetObj = target;
2487
+ const existing = getMethodPipes(targetObj, propertyKey) ?? [];
2488
+ existing.push({
2489
+ index: parameterIndex,
2490
+ decorator: "body",
2491
+ schema,
2492
+ pipes: schema ? [new ValidationPipe(schema)] : []
2493
+ });
2494
+ setMethodPipes(targetObj, propertyKey, existing);
2495
+ };
2496
+ }
2497
+ function Query(key, schema) {
2498
+ return (target, propertyKey, parameterIndex) => {
2499
+ if (propertyKey === undefined) {
2500
+ throw new Error("Query can only be used on method parameters");
2501
+ }
2502
+ const targetObj = target;
2503
+ const existing = getMethodPipes(targetObj, propertyKey) ?? [];
2504
+ existing.push({
2505
+ index: parameterIndex,
2506
+ decorator: "query",
2507
+ key,
2508
+ schema,
2509
+ pipes: schema ? [new ValidationPipe(schema)] : []
2510
+ });
2511
+ setMethodPipes(targetObj, propertyKey, existing);
2512
+ };
2513
+ }
2514
+ function Param(key, ...pipes) {
2515
+ return (target, propertyKey, parameterIndex) => {
2516
+ if (propertyKey === undefined) {
2517
+ throw new Error("Param can only be used on method parameters");
2518
+ }
2519
+ const targetObj = target;
2520
+ const existing = getMethodPipes(targetObj, propertyKey) ?? [];
2521
+ existing.push({
2522
+ index: parameterIndex,
2523
+ decorator: "param",
2524
+ key,
2525
+ pipes: [...pipes]
2526
+ });
2527
+ setMethodPipes(targetObj, propertyKey, existing);
2528
+ };
2529
+ }
2530
+
2531
+ class ValidationPipe {
2532
+ schema;
2533
+ constructor(schema) {
2534
+ this.schema = schema;
2535
+ }
2536
+ async transform(value, context) {
2537
+ const result = await validate(this.schema, value);
2538
+ if (result.success) {
2539
+ return result.data;
2540
+ }
2541
+ const failedResult = result;
2542
+ const error = new Error("Validation failed");
2543
+ error.issues = [...failedResult.issues];
2544
+ throw error;
2545
+ }
2546
+ }
2547
+
2548
+ class ParseIntPipe {
2549
+ transform(value, context) {
2550
+ const parsed = Number.parseInt(value, 10);
2551
+ if (isNaN(parsed)) {
2552
+ throw new Error(`Validation failed: "${value}" is not a valid integer`);
2553
+ }
2554
+ return parsed;
2555
+ }
2556
+ }
2557
+
2558
+ class ParseFloatPipe {
2559
+ transform(value, context) {
2560
+ const parsed = Number.parseFloat(value);
2561
+ if (isNaN(parsed)) {
2562
+ throw new Error(`Validation failed: "${value}" is not a valid number`);
2563
+ }
2564
+ return parsed;
2565
+ }
2566
+ }
2567
+
2568
+ class ParseBoolPipe {
2569
+ truthyValues = ["true", "1", "yes", "on"];
2570
+ falsyValues = ["false", "0", "no", "off"];
2571
+ transform(value, context) {
2572
+ const lower = value.toLowerCase();
2573
+ if (this.truthyValues.includes(lower)) {
2574
+ return true;
2575
+ }
2576
+ if (this.falsyValues.includes(lower)) {
2577
+ return false;
2578
+ }
2579
+ throw new Error(`Validation failed: "${value}" is not a valid boolean`);
2580
+ }
2581
+ }
2582
+
2583
+ class DefaultValuePipe {
2584
+ defaultValue;
2585
+ constructor(defaultValue) {
2586
+ this.defaultValue = defaultValue;
2587
+ }
2588
+ transform(value, context) {
2589
+ if (value === undefined || value === null) {
2590
+ return this.defaultValue;
2591
+ }
2592
+ return value;
2593
+ }
2594
+ }
2595
+
2596
+ class TrimPipe {
2597
+ transform(value, context) {
2598
+ if (typeof value !== "string") {
2599
+ throw new Error("Value must be a string");
2600
+ }
2601
+ return value.trim();
2602
+ }
2603
+ }
2604
+
2605
+ class ParseJsonPipe {
2606
+ transform(value, context) {
2607
+ try {
2608
+ return JSON.parse(value);
2609
+ } catch {
2610
+ throw new Error(`Validation failed: "${value}" is not valid JSON`);
2611
+ }
2612
+ }
2613
+ }
2614
+
2615
+ class ParseArrayPipe {
2616
+ separator;
2617
+ constructor(separator = ",") {
2618
+ this.separator = separator;
2619
+ }
2620
+ transform(value, context) {
2621
+ if (typeof value !== "string") {
2622
+ throw new Error("Value must be a string");
2623
+ }
2624
+ return value.split(this.separator).map((s) => s.trim()).filter((s) => s.length > 0);
2625
+ }
2626
+ }
2627
+ async function executePipes(value, context, options) {
2628
+ const { globalPipes = [], parameterPipes = [], resolvePipe } = options;
2629
+ const allPipes = [...globalPipes, ...parameterPipes];
2630
+ let currentValue = value;
2631
+ for (const pipe of allPipes) {
2632
+ let pipeInstance = null;
2633
+ if (typeof pipe === "function") {
2634
+ const funcPipe = pipe;
2635
+ if (funcPipe.prototype && typeof funcPipe.prototype === "object" && "transform" in funcPipe.prototype) {
2636
+ pipeInstance = resolvePipe ? resolvePipe(pipe) : null;
2637
+ if (!pipeInstance) {
2638
+ const PipeClass = pipe;
2639
+ pipeInstance = new PipeClass;
2640
+ }
2641
+ } else {
2642
+ pipeInstance = pipe;
2643
+ }
2644
+ } else if (typeof pipe === "object" && pipe !== null) {
2645
+ const objPipe = pipe;
2646
+ if ("transform" in objPipe && typeof objPipe.transform === "function") {
2647
+ pipeInstance = pipe;
2648
+ } else {
2649
+ pipeInstance = resolvePipe ? resolvePipe(pipe) : null;
2650
+ }
2651
+ }
2652
+ if (!pipeInstance) {
2653
+ console.warn("Pipe could not be resolved:", pipe);
2654
+ continue;
2655
+ }
2656
+ if (typeof pipeInstance === "function") {
2657
+ currentValue = await pipeInstance(currentValue, context);
2658
+ } else {
2659
+ currentValue = await pipeInstance.transform(currentValue, context);
2660
+ }
2661
+ }
2662
+ return currentValue;
2663
+ }
2664
+ async function extractParameterValue(context, metadata) {
2665
+ switch (metadata.decorator) {
2666
+ case "body":
2667
+ return await context.body();
2668
+ case "query":
2669
+ if (metadata.key) {
2670
+ return context.query[metadata.key];
2671
+ }
2672
+ return context.query;
2673
+ case "param":
2674
+ if (metadata.key) {
2675
+ return context.params[metadata.key];
2676
+ }
2677
+ return context.params;
2678
+ case "custom":
2679
+ default:
2680
+ return;
2681
+ }
2682
+ }
2683
+ function createBadRequestResponse(error) {
2684
+ const issues = error.issues;
2685
+ return new Response(JSON.stringify({
2686
+ statusCode: 400,
2687
+ error: "Bad Request",
2688
+ message: error.message,
2689
+ ...issues && { issues }
2690
+ }), {
2691
+ status: 400,
2692
+ headers: {
2693
+ "Content-Type": "application/json"
2694
+ }
2695
+ });
2696
+ }
2697
+ function isPipeTransform(value) {
2698
+ return typeof value === "object" && value !== null && "transform" in value && typeof value.transform === "function";
2699
+ }
2700
+ function isPipeFn(value) {
2701
+ return typeof value === "function" && !isPipeTransform(value);
2702
+ }
2703
+ // src/modules/index.ts
2704
+ function Inject2(token) {
2705
+ return (target, propertyKey, parameterIndex) => {
2706
+ const targetObj = target;
2707
+ const existingTokens = getContainerMetadata(targetObj, "inject:tokens") ?? [];
2708
+ existingTokens[parameterIndex] = token;
2709
+ setContainerMetadata(targetObj, "inject:tokens", existingTokens);
2710
+ };
2711
+ }
2712
+ function createMethodDecorator(method) {
2713
+ return (path = "") => {
2714
+ return (target, propertyKey, descriptor) => {
2715
+ const targetObj = target;
2716
+ const routes = getPrototypeMetadata(targetObj, "routes") ?? [];
2717
+ routes.push({
2718
+ method,
2719
+ path,
2720
+ handler: propertyKey
2721
+ });
2722
+ setPrototypeMetadata(targetObj, "routes", routes);
2723
+ return descriptor;
2724
+ };
2725
+ };
2726
+ }
2727
+ var Get = createMethodDecorator("GET");
2728
+ var Post = createMethodDecorator("POST");
2729
+ var Put = createMethodDecorator("PUT");
2730
+ var Patch = createMethodDecorator("PATCH");
2731
+ var Delete = createMethodDecorator("DELETE");
2732
+ var Head = createMethodDecorator("HEAD");
2733
+ var Options = createMethodDecorator("OPTIONS");
2734
+
2735
+ class AppModule {
2736
+ moduleClass;
2737
+ metadata;
2738
+ providers = [];
2739
+ controllers = [];
2740
+ visitedModules = new Set;
2741
+ lazyModules = [];
2742
+ constructor(moduleClass) {
2743
+ this.moduleClass = moduleClass;
2744
+ this.metadata = getMetadata(moduleClass, "module") ?? {};
2745
+ this.processModule(moduleClass);
2746
+ }
2747
+ processModule(moduleClass) {
2748
+ if (this.visitedModules.has(moduleClass)) {
2749
+ return;
2750
+ }
2751
+ this.visitedModules.add(moduleClass);
2752
+ if (isLazyModule(moduleClass)) {
2753
+ this.lazyModules.push(moduleClass);
2754
+ return;
2755
+ }
2756
+ const metadata = getMetadata(moduleClass, "module") ?? {};
2757
+ if (metadata.imports) {
2758
+ for (const importedModule of metadata.imports) {
2759
+ this.processModule(importedModule);
2760
+ }
2761
+ }
2762
+ if (metadata.providers) {
2763
+ const normalizedProviders = metadata.providers.map((p) => {
2764
+ if (typeof p === "function" && !p.token) {
2765
+ return { token: p, useClass: p };
2766
+ }
2767
+ return p;
2768
+ });
2769
+ this.providers.push(...normalizedProviders);
2770
+ }
2771
+ if (metadata.controllers) {
2772
+ this.controllers.push(...metadata.controllers);
2773
+ }
2774
+ }
2775
+ getProviders() {
2776
+ return [...this.providers];
2777
+ }
2778
+ getControllers() {
2779
+ return [...this.controllers];
2780
+ }
2781
+ getLazyModules() {
2782
+ return [...this.lazyModules];
2783
+ }
2784
+ }
2785
+
2786
+ class Application {
2787
+ container;
2788
+ router;
2789
+ appModule;
2790
+ lifecycleManager;
2791
+ shutdownHandler;
2792
+ server = null;
2793
+ providerInstances = new Map;
2794
+ controllerInstances = [];
2795
+ isInitialized = false;
2796
+ isShuttingDown = false;
2797
+ globalGuards = [];
2798
+ globalPipes = [];
2799
+ globalFilters = [];
2800
+ globalInterceptors = [];
2801
+ routeGuardMetadata = new Map;
2802
+ routePipeMetadata = new Map;
2803
+ routeFilterMetadata = new Map;
2804
+ routeInterceptorMetadata = new Map;
2805
+ moduleLoader;
2806
+ loadedLazyModules = new Set;
2807
+ constructor(moduleClass) {
2808
+ this.container = new Container2;
2809
+ this.router = new Router;
2810
+ this.appModule = new AppModule(moduleClass);
2811
+ this.lifecycleManager = new LifecycleHookManager;
2812
+ this.shutdownHandler = new ShutdownSignalHandler;
2813
+ this.moduleLoader = new ModuleLoader(this.container);
2814
+ }
2815
+ useGlobalGuards(...guards) {
2816
+ this.globalGuards.push(...guards);
2817
+ return this;
2818
+ }
2819
+ useGlobalPipes(...pipes) {
2820
+ this.globalPipes.push(...pipes);
2821
+ return this;
2822
+ }
2823
+ useGlobalFilters(...filters) {
2824
+ this.globalFilters.push(...filters);
2825
+ return this;
2826
+ }
2827
+ useGlobalInterceptors(...interceptors) {
2828
+ this.globalInterceptors.push(...interceptors);
2829
+ return this;
2830
+ }
2831
+ registerProviders() {
2832
+ const providers = this.appModule.getProviders();
2833
+ this.container.registerAll(providers);
2834
+ }
2835
+ async resolveProviders() {
2836
+ const providers = this.appModule.getProviders();
2837
+ for (const provider of providers) {
2838
+ const token = provider.token;
2839
+ const instance = this.container.resolve(token);
2840
+ this.providerInstances.set(token, instance);
2841
+ this.lifecycleManager.registerInstance(instance);
2842
+ }
2843
+ }
2844
+ registerControllers() {
2845
+ const controllers = this.appModule.getControllers();
2846
+ for (const controllerClass of controllers) {
2847
+ const instance = this.registerController(controllerClass);
2848
+ this.controllerInstances.push(instance);
2849
+ this.lifecycleManager.registerInstance(instance);
2850
+ }
2851
+ }
2852
+ registerController(controllerClass) {
2853
+ const basePath = getMetadata(controllerClass, "path") ?? "";
2854
+ const routes = getPrototypeMetadata(controllerClass.prototype, "routes") ?? [];
2855
+ let injectTokens = getContainerMetadata(controllerClass, "inject:tokens") ?? [];
2856
+ if (injectTokens.length === 0 && typeof Reflect !== "undefined" && typeof Reflect.getMetadata === "function") {
2857
+ const paramTypes = Reflect.getMetadata("design:paramtypes", controllerClass);
2858
+ if (paramTypes) {
2859
+ injectTokens = paramTypes.map((paramType) => paramType);
2860
+ }
2861
+ }
2862
+ const deps = injectTokens.map((tokenOrRef) => {
2863
+ const token = isForwardRef(tokenOrRef) ? resolveForwardRef(tokenOrRef) : tokenOrRef;
2864
+ return this.container.resolve(token);
2865
+ });
2866
+ const instance = new controllerClass(...deps);
2867
+ const classGuards = getClassGuards(controllerClass) ?? [];
2868
+ const classInterceptors = getClassInterceptors(controllerClass) ?? [];
2869
+ for (const route of routes) {
2870
+ const fullPath = basePath + route.path;
2871
+ const handler = instance[route.handler];
2872
+ if (typeof handler === "function") {
2873
+ const method = route.method.toLowerCase();
2874
+ const routerMethod = method;
2875
+ const methodGuards = getMethodGuards(controllerClass.prototype, route.handler) ?? [];
2876
+ const parameterPipes = getMethodPipes(controllerClass.prototype, route.handler) ?? [];
2877
+ const classFilters = getClassFilters(controllerClass) ?? [];
2878
+ const methodFilters = getMethodFilters(controllerClass.prototype, route.handler) ?? [];
2879
+ const methodInterceptors = getMethodInterceptors(controllerClass.prototype, route.handler) ?? [];
2880
+ const routeKey = `${method.toUpperCase()}:${fullPath}`;
2881
+ this.routeGuardMetadata.set(routeKey, {
2882
+ controllerClass,
2883
+ handlerName: route.handler,
2884
+ classGuards,
2885
+ methodGuards
2886
+ });
2887
+ if (parameterPipes.length > 0) {
2888
+ this.routePipeMetadata.set(routeKey, {
2889
+ controllerClass,
2890
+ handlerName: route.handler,
2891
+ parameterPipes
2892
+ });
2893
+ }
2894
+ if (classFilters.length > 0 || methodFilters.length > 0) {
2895
+ this.routeFilterMetadata.set(routeKey, {
2896
+ controllerClass,
2897
+ handlerName: route.handler,
2898
+ classFilters,
2899
+ methodFilters
2900
+ });
2901
+ }
2902
+ if (classInterceptors.length > 0 || methodInterceptors.length > 0) {
2903
+ this.routeInterceptorMetadata.set(routeKey, {
2904
+ controllerClass,
2905
+ handlerName: route.handler,
2906
+ classInterceptors,
2907
+ methodInterceptors
2908
+ });
2909
+ }
2910
+ if (routerMethod in this.router && typeof this.router[routerMethod] === "function") {
2911
+ this.router[routerMethod](fullPath, (context) => handler.call(instance, context));
2912
+ }
2913
+ }
2914
+ }
2915
+ return instance;
2916
+ }
2917
+ async init() {
2918
+ if (this.isInitialized) {
2919
+ return;
2920
+ }
2921
+ this.registerProviders();
2922
+ this.container.register({
2923
+ token: MODULE_LOADER_TOKEN,
2924
+ useValue: this.moduleLoader
2925
+ });
2926
+ await this.resolveProviders();
2927
+ await this.lifecycleManager.executeOnModuleInit();
2928
+ this.registerControllers();
2929
+ await this.lifecycleManager.executeOnApplicationBootstrap();
2930
+ this.moduleLoader.setOnModuleLoadCallback(async (moduleClass) => {
2931
+ await this.loadLazyModule(moduleClass);
2932
+ });
2933
+ this.isInitialized = true;
2934
+ }
2935
+ async loadLazyModule(moduleClass) {
2936
+ if (this.loadedLazyModules.has(moduleClass)) {
2937
+ return;
2938
+ }
2939
+ const metadata = getMetadata(moduleClass, "module") ?? {};
2940
+ if (metadata.providers) {
2941
+ for (const provider of metadata.providers) {
2942
+ this.container.register(provider);
2943
+ const instance = this.container.resolve(provider.token);
2944
+ this.providerInstances.set(provider.token, instance);
2945
+ this.lifecycleManager.registerInstance(instance);
2946
+ }
2947
+ await this.lifecycleManager.executeOnModuleInit();
2948
+ }
2949
+ if (metadata.controllers) {
2950
+ for (const controllerClass of metadata.controllers) {
2951
+ const instance = this.registerController(controllerClass);
2952
+ this.controllerInstances.push(instance);
2953
+ this.lifecycleManager.registerInstance(instance);
2954
+ }
2955
+ }
2956
+ await this.lifecycleManager.executeOnApplicationBootstrap();
2957
+ this.loadedLazyModules.add(moduleClass);
2958
+ }
2959
+ getModuleLoader() {
2960
+ return this.moduleLoader;
2961
+ }
2962
+ setupShutdownHandlers() {
2963
+ this.shutdownHandler.onSignal(async (signal) => {
2964
+ await this.shutdown(signal);
2965
+ });
2966
+ this.shutdownHandler.startListening();
2967
+ }
2968
+ async shutdown(signal) {
2969
+ if (this.isShuttingDown) {
2970
+ return;
2971
+ }
2972
+ this.isShuttingDown = true;
2973
+ console.log("Starting graceful shutdown...");
2974
+ if (this.server) {
2975
+ this.server.stop();
2976
+ console.log("Server stopped accepting new connections");
2977
+ }
2978
+ await this.lifecycleManager.executeBeforeApplicationShutdown(signal);
2979
+ await new Promise((resolve) => setTimeout(resolve, 100));
2980
+ await this.lifecycleManager.executeOnModuleDestroy();
2981
+ await this.lifecycleManager.executeOnApplicationShutdown(signal);
2982
+ console.log("Graceful shutdown complete");
2983
+ }
2984
+ async listen(port = 3000, hostname = "localhost") {
2985
+ await this.init();
2986
+ this.setupShutdownHandlers();
2987
+ const { Context: Context2 } = await Promise.resolve().then(() => exports_context);
2988
+ const { compose: compose2 } = await Promise.resolve().then(() => exports_middleware);
2989
+ this.server = Bun.serve({
2990
+ port,
2991
+ hostname,
2992
+ fetch: async (request) => {
2993
+ if (this.isShuttingDown) {
2994
+ return new Response("Service Unavailable", { status: 503 });
2995
+ }
2996
+ const url = new URL(request.url);
2997
+ const match = this.router.match(request.method, url.pathname);
2998
+ if (!match) {
2999
+ return new Response("Not Found", { status: 404 });
3000
+ }
3001
+ const context = new Context2(request, match.params);
3002
+ try {
3003
+ await this.lifecycleManager.executeOnBeforeRequest(context);
3004
+ } catch (error) {
3005
+ console.error("Error in onBeforeRequest hook:", error);
3006
+ }
3007
+ const routeKey = `${request.method}:${url.pathname}`;
3008
+ const guardMetadata = this.routeGuardMetadata.get(routeKey);
3009
+ if (guardMetadata || this.globalGuards.length > 0) {
3010
+ const guardsPassed = await executeGuards(context, {
3011
+ globalGuards: this.globalGuards,
3012
+ classGuards: guardMetadata?.classGuards ?? [],
3013
+ methodGuards: guardMetadata?.methodGuards ?? [],
3014
+ resolveGuard: (guard) => {
3015
+ if (typeof guard === "object" && guard !== null && !("canActivate" in guard)) {
3016
+ try {
3017
+ return this.container.resolve(guard);
3018
+ } catch {
3019
+ return null;
3020
+ }
3021
+ }
3022
+ return null;
3023
+ }
3024
+ });
3025
+ if (!guardsPassed) {
3026
+ return createForbiddenResponse();
3027
+ }
3028
+ }
3029
+ const interceptorMetadata = this.routeInterceptorMetadata.get(routeKey);
3030
+ const executeHandler = async () => {
3031
+ const pipeMetadata = this.routePipeMetadata.get(routeKey);
3032
+ if (pipeMetadata || this.globalPipes.length > 0) {
3033
+ try {
3034
+ const params = pipeMetadata?.parameterPipes ?? [];
3035
+ for (const paramMeta of params) {
3036
+ const initialValue = await extractParameterValue(context, paramMeta);
3037
+ const pipeContext = {
3038
+ context,
3039
+ metadata: {
3040
+ index: paramMeta.index,
3041
+ name: paramMeta.key,
3042
+ decorator: paramMeta.decorator
3043
+ }
3044
+ };
3045
+ const transformedValue = await executePipes(initialValue, pipeContext, {
3046
+ globalPipes: this.globalPipes,
3047
+ parameterPipes: paramMeta.pipes,
3048
+ resolvePipe: (pipe) => {
3049
+ if (typeof pipe === "object" && pipe !== null && !("transform" in pipe)) {
3050
+ try {
3051
+ return this.container.resolve(pipe);
3052
+ } catch {
3053
+ return null;
3054
+ }
3055
+ }
3056
+ return null;
3057
+ }
3058
+ });
3059
+ context.set(`pipe:param:${paramMeta.index}`, transformedValue);
3060
+ }
3061
+ } catch (error) {
3062
+ if (error instanceof Error) {
3063
+ return createBadRequestResponse(error);
3064
+ }
3065
+ return createBadRequestResponse(new Error("Pipe transformation failed"));
3066
+ }
3067
+ }
3068
+ const pipeline = compose2(match.middleware ?? []);
3069
+ return pipeline(context, match.handler);
3070
+ };
3071
+ try {
3072
+ const response = await executeInterceptors(context, executeHandler, {
3073
+ globalInterceptors: this.globalInterceptors,
3074
+ classInterceptors: interceptorMetadata?.classInterceptors ?? [],
3075
+ methodInterceptors: interceptorMetadata?.methodInterceptors ?? [],
3076
+ resolveInterceptor: (interceptor) => {
3077
+ if (typeof interceptor === "object" && interceptor !== null && !isNestInterceptor(interceptor) && !isInterceptorFn(interceptor)) {
3078
+ try {
3079
+ return this.container.resolve(interceptor);
3080
+ } catch {
3081
+ return null;
3082
+ }
3083
+ }
3084
+ if (typeof interceptor === "function" && !isInterceptorFn(interceptor)) {
3085
+ try {
3086
+ const Constructor = interceptor;
3087
+ const instance = new Constructor;
3088
+ if (isNestInterceptor(instance)) {
3089
+ return instance;
3090
+ }
3091
+ } catch {}
3092
+ }
3093
+ return null;
3094
+ }
3095
+ });
3096
+ try {
3097
+ await this.lifecycleManager.executeOnAfterRequest(context, response);
3098
+ } catch (error) {
3099
+ console.error("Error in onAfterRequest hook:", error);
3100
+ }
3101
+ return response;
3102
+ } catch (error) {
3103
+ try {
3104
+ await this.lifecycleManager.executeOnRequestError(context, error);
3105
+ } catch (hookError) {
3106
+ console.error("Error in onRequestError hook:", hookError);
3107
+ }
3108
+ return this.handleException(error, context, routeKey);
3109
+ }
3110
+ }
3111
+ });
3112
+ console.log(`Server running at http://${hostname}:${port}`);
3113
+ }
3114
+ async handle(request) {
3115
+ const { Context: Context2 } = await Promise.resolve().then(() => exports_context);
3116
+ const { compose: compose2 } = await Promise.resolve().then(() => exports_middleware);
3117
+ const url = new URL(request.url);
3118
+ const match = this.router.match(request.method, url.pathname);
3119
+ if (!match) {
3120
+ return new Response("Not Found", { status: 404 });
3121
+ }
3122
+ const context = new Context2(request, match.params);
3123
+ const routeKey = `${request.method}:${url.pathname}`;
3124
+ const guardMetadata = this.routeGuardMetadata.get(routeKey);
3125
+ if (guardMetadata || this.globalGuards.length > 0) {
3126
+ const guardsPassed = await executeGuards(context, {
3127
+ globalGuards: this.globalGuards,
3128
+ classGuards: guardMetadata?.classGuards ?? [],
3129
+ methodGuards: guardMetadata?.methodGuards ?? [],
3130
+ resolveGuard: (guard) => {
3131
+ if (typeof guard === "object" && guard !== null && !("canActivate" in guard)) {
3132
+ try {
3133
+ return this.container.resolve(guard);
3134
+ } catch {
3135
+ return null;
3136
+ }
3137
+ }
3138
+ return null;
3139
+ }
3140
+ });
3141
+ if (!guardsPassed) {
3142
+ return createForbiddenResponse();
3143
+ }
3144
+ }
3145
+ const interceptorMetadata = this.routeInterceptorMetadata.get(routeKey);
3146
+ const executeHandler = async () => {
3147
+ const pipeMetadata = this.routePipeMetadata.get(routeKey);
3148
+ if (pipeMetadata || this.globalPipes.length > 0) {
3149
+ try {
3150
+ const params = pipeMetadata?.parameterPipes ?? [];
3151
+ for (const paramMeta of params) {
3152
+ const initialValue = await extractParameterValue(context, paramMeta);
3153
+ const pipeContext = {
3154
+ context,
3155
+ metadata: {
3156
+ index: paramMeta.index,
3157
+ name: paramMeta.key,
3158
+ decorator: paramMeta.decorator
3159
+ }
3160
+ };
3161
+ const transformedValue = await executePipes(initialValue, pipeContext, {
3162
+ globalPipes: this.globalPipes,
3163
+ parameterPipes: paramMeta.pipes,
3164
+ resolvePipe: (pipe) => {
3165
+ if (typeof pipe === "object" && pipe !== null && !("transform" in pipe)) {
3166
+ try {
3167
+ return this.container.resolve(pipe);
3168
+ } catch {
3169
+ return null;
3170
+ }
3171
+ }
3172
+ return null;
3173
+ }
3174
+ });
3175
+ context.set(`pipe:param:${paramMeta.index}`, transformedValue);
3176
+ }
3177
+ } catch (error) {
3178
+ if (error instanceof Error) {
3179
+ return createBadRequestResponse(error);
3180
+ }
3181
+ return createBadRequestResponse(new Error("Pipe transformation failed"));
3182
+ }
3183
+ }
3184
+ const pipeline = compose2(match.middleware ?? []);
3185
+ return pipeline(context, match.handler);
3186
+ };
3187
+ try {
3188
+ const response = await executeInterceptors(context, executeHandler, {
3189
+ globalInterceptors: this.globalInterceptors,
3190
+ classInterceptors: interceptorMetadata?.classInterceptors ?? [],
3191
+ methodInterceptors: interceptorMetadata?.methodInterceptors ?? [],
3192
+ resolveInterceptor: (interceptor) => {
3193
+ if (typeof interceptor === "object" && interceptor !== null && !isNestInterceptor(interceptor) && !isInterceptorFn(interceptor)) {
3194
+ try {
3195
+ return this.container.resolve(interceptor);
3196
+ } catch {
3197
+ return null;
3198
+ }
3199
+ }
3200
+ if (typeof interceptor === "function" && !isInterceptorFn(interceptor)) {
3201
+ try {
3202
+ const Constructor = interceptor;
3203
+ const instance = new Constructor;
3204
+ if (isNestInterceptor(instance)) {
3205
+ return instance;
3206
+ }
3207
+ } catch {}
3208
+ }
3209
+ return null;
3210
+ }
3211
+ });
3212
+ return response;
3213
+ } catch (error) {
3214
+ return this.handleException(error, context, routeKey);
3215
+ }
3216
+ }
3217
+ getLifecycleManager() {
3218
+ return this.lifecycleManager;
3219
+ }
3220
+ isShuttingDownNow() {
3221
+ return this.isShuttingDown;
3222
+ }
3223
+ async handleException(exception, context, routeKey) {
3224
+ const filterMetadata = this.routeFilterMetadata.get(routeKey);
3225
+ return findAndExecuteFilter(exception, context, {
3226
+ globalFilters: this.globalFilters,
3227
+ classFilters: filterMetadata?.classFilters ?? [],
3228
+ methodFilters: filterMetadata?.methodFilters ?? [],
3229
+ resolveFilter: (filter) => {
3230
+ if (typeof filter === "object" && filter !== null && !isExceptionFilter(filter)) {
3231
+ try {
3232
+ return this.container.resolve(filter);
3233
+ } catch {
3234
+ return null;
3235
+ }
3236
+ }
3237
+ if (typeof filter === "function" && !isFilterFn(filter)) {
3238
+ try {
3239
+ const Constructor = filter;
3240
+ const instance = new Constructor;
3241
+ if (isExceptionFilter(instance)) {
3242
+ return instance;
3243
+ }
3244
+ } catch {}
3245
+ }
3246
+ return null;
3247
+ }
3248
+ });
3249
+ }
3250
+ }
3251
+ function createApp(moduleClass) {
3252
+ return new Application(moduleClass);
3253
+ }
3254
+ export {
3255
+ resolveForwardRef,
3256
+ isPipeTransform,
3257
+ isPipeFn,
3258
+ isOnRequestError,
3259
+ isOnModuleInit,
3260
+ isOnModuleDestroy,
3261
+ isOnBeforeRequest,
3262
+ isOnApplicationShutdown,
3263
+ isOnApplicationBootstrap,
3264
+ isOnAfterRequest,
3265
+ isNestInterceptor,
3266
+ isLazyModule,
3267
+ isInterceptorFn,
3268
+ isForwardRef,
3269
+ isFilterFn,
3270
+ isExceptionFilter,
3271
+ isBeforeApplicationShutdown,
3272
+ getUnloadedLazyModules,
3273
+ getMethodRoles,
3274
+ getMethodPipes,
3275
+ getMethodInterceptors,
3276
+ getMethodGuards,
3277
+ getMethodFilters,
3278
+ getLazyMetadata,
3279
+ getClassInterceptors,
3280
+ getClassGuards,
3281
+ getClassFilters,
3282
+ getCatchType,
3283
+ forwardRef,
3284
+ findAndExecuteFilter,
3285
+ extractParameterValue,
3286
+ executePipes,
3287
+ executeInterceptors,
3288
+ executeGuards,
3289
+ executeFilter,
3290
+ createLazyLoader,
3291
+ createInternalErrorResponse,
3292
+ createForbiddenResponse,
3293
+ createDefaultErrorResponse,
3294
+ createBadRequestResponse,
3295
+ createApp,
3296
+ canHandleException,
3297
+ areAllLazyModulesLoaded,
3298
+ ValidationPipe,
3299
+ ValidationFilter,
3300
+ UsePipes,
3301
+ UseInterceptors,
3302
+ UseGuards,
3303
+ UseFilters,
3304
+ TrimPipe,
3305
+ TransformInterceptor,
3306
+ TimeoutInterceptor,
3307
+ ShutdownSignalHandler,
3308
+ RolesGuard,
3309
+ Roles,
3310
+ Query,
3311
+ Put,
3312
+ Post,
3313
+ Patch,
3314
+ ParseJsonPipe,
3315
+ ParseIntPipe,
3316
+ ParseFloatPipe,
3317
+ ParseBoolPipe,
3318
+ ParseArrayPipe,
3319
+ Param,
3320
+ Options,
3321
+ NotFoundFilter,
3322
+ ModuleLoader,
3323
+ Module,
3324
+ MODULE_LOADER_TOKEN,
3325
+ LoggingInterceptor,
3326
+ LifecycleHookManager,
3327
+ LazyModuleRegistry,
3328
+ LazyModuleLoaderImpl,
3329
+ LazyModule,
3330
+ Injectable2 as Injectable,
3331
+ Inject2 as Inject,
3332
+ HttpExceptionFilter,
3333
+ HeaderInterceptor,
3334
+ Head,
3335
+ Get,
3336
+ Delete,
3337
+ DefaultValuePipe,
3338
+ Controller,
3339
+ Catch,
3340
+ CacheInterceptor,
3341
+ Body,
3342
+ AuthGuard,
3343
+ Application,
3344
+ AppModule,
3345
+ AllExceptionsFilter
3346
+ };