@dangao/bun-server 0.2.0 → 0.4.0

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 (81) hide show
  1. package/dist/auth/controller.d.ts +1 -1
  2. package/dist/auth/controller.d.ts.map +1 -1
  3. package/dist/controller/controller.d.ts.map +1 -1
  4. package/dist/core/application.d.ts +10 -2
  5. package/dist/core/application.d.ts.map +1 -1
  6. package/dist/core/context.d.ts +6 -0
  7. package/dist/core/context.d.ts.map +1 -1
  8. package/dist/database/connection-manager.d.ts +72 -0
  9. package/dist/database/connection-manager.d.ts.map +1 -0
  10. package/dist/database/connection-pool.d.ts +79 -0
  11. package/dist/database/connection-pool.d.ts.map +1 -0
  12. package/dist/database/database-extension.d.ts +20 -0
  13. package/dist/database/database-extension.d.ts.map +1 -0
  14. package/dist/database/database-module.d.ts +18 -0
  15. package/dist/database/database-module.d.ts.map +1 -0
  16. package/dist/database/health-indicator.d.ts +15 -0
  17. package/dist/database/health-indicator.d.ts.map +1 -0
  18. package/dist/database/index.d.ts +9 -0
  19. package/dist/database/index.d.ts.map +1 -0
  20. package/dist/database/orm/decorators.d.ts +70 -0
  21. package/dist/database/orm/decorators.d.ts.map +1 -0
  22. package/dist/database/orm/drizzle-repository.d.ts +34 -0
  23. package/dist/database/orm/drizzle-repository.d.ts.map +1 -0
  24. package/dist/database/orm/index.d.ts +11 -0
  25. package/dist/database/orm/index.d.ts.map +1 -0
  26. package/dist/database/orm/repository-decorator.d.ts +21 -0
  27. package/dist/database/orm/repository-decorator.d.ts.map +1 -0
  28. package/dist/database/orm/repository.d.ts +36 -0
  29. package/dist/database/orm/repository.d.ts.map +1 -0
  30. package/dist/database/orm/service.d.ts +26 -0
  31. package/dist/database/orm/service.d.ts.map +1 -0
  32. package/dist/database/orm/transaction-decorator.d.ts +17 -0
  33. package/dist/database/orm/transaction-decorator.d.ts.map +1 -0
  34. package/dist/database/orm/transaction-interceptor.d.ts +28 -0
  35. package/dist/database/orm/transaction-interceptor.d.ts.map +1 -0
  36. package/dist/database/orm/transaction-manager.d.ts +77 -0
  37. package/dist/database/orm/transaction-manager.d.ts.map +1 -0
  38. package/dist/database/orm/transaction-types.d.ts +136 -0
  39. package/dist/database/orm/transaction-types.d.ts.map +1 -0
  40. package/dist/database/orm/types.d.ts +95 -0
  41. package/dist/database/orm/types.d.ts.map +1 -0
  42. package/dist/database/service.d.ts +71 -0
  43. package/dist/database/service.d.ts.map +1 -0
  44. package/dist/database/types.d.ts +168 -0
  45. package/dist/database/types.d.ts.map +1 -0
  46. package/dist/error/error-codes.d.ts +49 -3
  47. package/dist/error/error-codes.d.ts.map +1 -1
  48. package/dist/error/handler.d.ts.map +1 -1
  49. package/dist/error/http-exception.d.ts +26 -7
  50. package/dist/error/http-exception.d.ts.map +1 -1
  51. package/dist/error/i18n.d.ts +46 -2
  52. package/dist/error/i18n.d.ts.map +1 -1
  53. package/dist/error/index.d.ts +1 -1
  54. package/dist/error/index.d.ts.map +1 -1
  55. package/dist/index.d.ts +4 -2
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +1705 -36
  58. package/dist/metrics/collector.d.ts +47 -0
  59. package/dist/metrics/collector.d.ts.map +1 -0
  60. package/dist/metrics/controller.d.ts +17 -0
  61. package/dist/metrics/controller.d.ts.map +1 -0
  62. package/dist/metrics/index.d.ts +7 -0
  63. package/dist/metrics/index.d.ts.map +1 -0
  64. package/dist/metrics/metrics-module.d.ts +9 -0
  65. package/dist/metrics/metrics-module.d.ts.map +1 -0
  66. package/dist/metrics/middleware.d.ts +7 -0
  67. package/dist/metrics/middleware.d.ts.map +1 -0
  68. package/dist/metrics/prometheus.d.ts +23 -0
  69. package/dist/metrics/prometheus.d.ts.map +1 -0
  70. package/dist/metrics/types.d.ts +88 -0
  71. package/dist/metrics/types.d.ts.map +1 -0
  72. package/dist/middleware/builtin/index.d.ts +1 -0
  73. package/dist/middleware/builtin/index.d.ts.map +1 -1
  74. package/dist/middleware/builtin/rate-limit.d.ts +104 -0
  75. package/dist/middleware/builtin/rate-limit.d.ts.map +1 -0
  76. package/dist/middleware/decorators.d.ts +7 -0
  77. package/dist/middleware/decorators.d.ts.map +1 -1
  78. package/dist/middleware/index.d.ts +1 -1
  79. package/dist/middleware/index.d.ts.map +1 -1
  80. package/package.json +3 -3
  81. package/readme.md +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,20 @@
1
1
  // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
2
4
  var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
3
18
  var __export = (target, all) => {
4
19
  for (var name in all)
5
20
  __defProp(target, name, {
@@ -25,6 +40,7 @@ var __legacyMetadataTS = (k, v) => {
25
40
  return Reflect.metadata(k, v);
26
41
  };
27
42
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
43
+ var __require = import.meta.require;
28
44
 
29
45
  // src/validation/decorators.ts
30
46
  import"reflect-metadata";
@@ -175,38 +191,98 @@ var init_error_codes = __esm(() => {
175
191
  ["INVALID_REQUEST" /* INVALID_REQUEST */]: 400,
176
192
  ["RESOURCE_NOT_FOUND" /* RESOURCE_NOT_FOUND */]: 404,
177
193
  ["METHOD_NOT_ALLOWED" /* METHOD_NOT_ALLOWED */]: 405,
194
+ ["RATE_LIMIT_EXCEEDED" /* RATE_LIMIT_EXCEEDED */]: 429,
195
+ ["SERVICE_UNAVAILABLE" /* SERVICE_UNAVAILABLE */]: 503,
196
+ ["TIMEOUT" /* TIMEOUT */]: 408,
178
197
  ["AUTH_REQUIRED" /* AUTH_REQUIRED */]: 401,
179
198
  ["AUTH_INVALID_TOKEN" /* AUTH_INVALID_TOKEN */]: 401,
180
199
  ["AUTH_TOKEN_EXPIRED" /* AUTH_TOKEN_EXPIRED */]: 401,
181
200
  ["AUTH_INSUFFICIENT_PERMISSIONS" /* AUTH_INSUFFICIENT_PERMISSIONS */]: 403,
201
+ ["AUTH_INVALID_CREDENTIALS" /* AUTH_INVALID_CREDENTIALS */]: 401,
202
+ ["AUTH_ACCOUNT_LOCKED" /* AUTH_ACCOUNT_LOCKED */]: 423,
203
+ ["AUTH_ACCOUNT_DISABLED" /* AUTH_ACCOUNT_DISABLED */]: 403,
182
204
  ["VALIDATION_FAILED" /* VALIDATION_FAILED */]: 400,
183
205
  ["VALIDATION_REQUIRED_FIELD" /* VALIDATION_REQUIRED_FIELD */]: 400,
184
206
  ["VALIDATION_INVALID_FORMAT" /* VALIDATION_INVALID_FORMAT */]: 400,
185
207
  ["VALIDATION_OUT_OF_RANGE" /* VALIDATION_OUT_OF_RANGE */]: 400,
208
+ ["VALIDATION_TYPE_MISMATCH" /* VALIDATION_TYPE_MISMATCH */]: 400,
209
+ ["VALIDATION_CONSTRAINT_VIOLATION" /* VALIDATION_CONSTRAINT_VIOLATION */]: 400,
186
210
  ["OAUTH2_INVALID_CLIENT" /* OAUTH2_INVALID_CLIENT */]: 400,
187
211
  ["OAUTH2_INVALID_GRANT" /* OAUTH2_INVALID_GRANT */]: 400,
188
212
  ["OAUTH2_INVALID_SCOPE" /* OAUTH2_INVALID_SCOPE */]: 400,
189
213
  ["OAUTH2_INVALID_REDIRECT_URI" /* OAUTH2_INVALID_REDIRECT_URI */]: 400,
190
- ["OAUTH2_UNSUPPORTED_GRANT_TYPE" /* OAUTH2_UNSUPPORTED_GRANT_TYPE */]: 400
214
+ ["OAUTH2_UNSUPPORTED_GRANT_TYPE" /* OAUTH2_UNSUPPORTED_GRANT_TYPE */]: 400,
215
+ ["OAUTH2_ACCESS_DENIED" /* OAUTH2_ACCESS_DENIED */]: 403,
216
+ ["OAUTH2_SERVER_ERROR" /* OAUTH2_SERVER_ERROR */]: 500,
217
+ ["DATABASE_CONNECTION_FAILED" /* DATABASE_CONNECTION_FAILED */]: 503,
218
+ ["DATABASE_QUERY_FAILED" /* DATABASE_QUERY_FAILED */]: 500,
219
+ ["DATABASE_TRANSACTION_FAILED" /* DATABASE_TRANSACTION_FAILED */]: 500,
220
+ ["DATABASE_CONSTRAINT_VIOLATION" /* DATABASE_CONSTRAINT_VIOLATION */]: 409,
221
+ ["DATABASE_TIMEOUT" /* DATABASE_TIMEOUT */]: 504,
222
+ ["DATABASE_POOL_EXHAUSTED" /* DATABASE_POOL_EXHAUSTED */]: 503,
223
+ ["DATABASE_MIGRATION_FAILED" /* DATABASE_MIGRATION_FAILED */]: 500,
224
+ ["FILE_NOT_FOUND" /* FILE_NOT_FOUND */]: 404,
225
+ ["FILE_UPLOAD_FAILED" /* FILE_UPLOAD_FAILED */]: 500,
226
+ ["FILE_DOWNLOAD_FAILED" /* FILE_DOWNLOAD_FAILED */]: 500,
227
+ ["FILE_SIZE_EXCEEDED" /* FILE_SIZE_EXCEEDED */]: 413,
228
+ ["FILE_TYPE_NOT_ALLOWED" /* FILE_TYPE_NOT_ALLOWED */]: 415,
229
+ ["FILE_ACCESS_DENIED" /* FILE_ACCESS_DENIED */]: 403,
230
+ ["FILE_PATH_TRAVERSAL" /* FILE_PATH_TRAVERSAL */]: 400,
231
+ ["MIDDLEWARE_EXECUTION_FAILED" /* MIDDLEWARE_EXECUTION_FAILED */]: 500,
232
+ ["MIDDLEWARE_TIMEOUT" /* MIDDLEWARE_TIMEOUT */]: 504,
233
+ ["CORS_NOT_ALLOWED" /* CORS_NOT_ALLOWED */]: 403,
234
+ ["CONFIG_INVALID" /* CONFIG_INVALID */]: 500,
235
+ ["CONFIG_MISSING" /* CONFIG_MISSING */]: 500,
236
+ ["CONFIG_VALIDATION_FAILED" /* CONFIG_VALIDATION_FAILED */]: 500
191
237
  };
192
238
  ERROR_CODE_MESSAGES = {
193
239
  ["INTERNAL_ERROR" /* INTERNAL_ERROR */]: "Internal Server Error",
194
240
  ["INVALID_REQUEST" /* INVALID_REQUEST */]: "Invalid Request",
195
241
  ["RESOURCE_NOT_FOUND" /* RESOURCE_NOT_FOUND */]: "Resource Not Found",
196
242
  ["METHOD_NOT_ALLOWED" /* METHOD_NOT_ALLOWED */]: "Method Not Allowed",
243
+ ["RATE_LIMIT_EXCEEDED" /* RATE_LIMIT_EXCEEDED */]: "Rate Limit Exceeded",
244
+ ["SERVICE_UNAVAILABLE" /* SERVICE_UNAVAILABLE */]: "Service Unavailable",
245
+ ["TIMEOUT" /* TIMEOUT */]: "Request Timeout",
197
246
  ["AUTH_REQUIRED" /* AUTH_REQUIRED */]: "Authentication Required",
198
247
  ["AUTH_INVALID_TOKEN" /* AUTH_INVALID_TOKEN */]: "Invalid Authentication Token",
199
248
  ["AUTH_TOKEN_EXPIRED" /* AUTH_TOKEN_EXPIRED */]: "Authentication Token Expired",
200
249
  ["AUTH_INSUFFICIENT_PERMISSIONS" /* AUTH_INSUFFICIENT_PERMISSIONS */]: "Insufficient Permissions",
250
+ ["AUTH_INVALID_CREDENTIALS" /* AUTH_INVALID_CREDENTIALS */]: "Invalid Credentials",
251
+ ["AUTH_ACCOUNT_LOCKED" /* AUTH_ACCOUNT_LOCKED */]: "Account Locked",
252
+ ["AUTH_ACCOUNT_DISABLED" /* AUTH_ACCOUNT_DISABLED */]: "Account Disabled",
201
253
  ["VALIDATION_FAILED" /* VALIDATION_FAILED */]: "Validation Failed",
202
254
  ["VALIDATION_REQUIRED_FIELD" /* VALIDATION_REQUIRED_FIELD */]: "Required Field Missing",
203
255
  ["VALIDATION_INVALID_FORMAT" /* VALIDATION_INVALID_FORMAT */]: "Invalid Format",
204
256
  ["VALIDATION_OUT_OF_RANGE" /* VALIDATION_OUT_OF_RANGE */]: "Value Out of Range",
257
+ ["VALIDATION_TYPE_MISMATCH" /* VALIDATION_TYPE_MISMATCH */]: "Type Mismatch",
258
+ ["VALIDATION_CONSTRAINT_VIOLATION" /* VALIDATION_CONSTRAINT_VIOLATION */]: "Constraint Violation",
205
259
  ["OAUTH2_INVALID_CLIENT" /* OAUTH2_INVALID_CLIENT */]: "Invalid Client",
206
260
  ["OAUTH2_INVALID_GRANT" /* OAUTH2_INVALID_GRANT */]: "Invalid Grant",
207
261
  ["OAUTH2_INVALID_SCOPE" /* OAUTH2_INVALID_SCOPE */]: "Invalid Scope",
208
262
  ["OAUTH2_INVALID_REDIRECT_URI" /* OAUTH2_INVALID_REDIRECT_URI */]: "Invalid Redirect URI",
209
- ["OAUTH2_UNSUPPORTED_GRANT_TYPE" /* OAUTH2_UNSUPPORTED_GRANT_TYPE */]: "Unsupported Grant Type"
263
+ ["OAUTH2_UNSUPPORTED_GRANT_TYPE" /* OAUTH2_UNSUPPORTED_GRANT_TYPE */]: "Unsupported Grant Type",
264
+ ["OAUTH2_ACCESS_DENIED" /* OAUTH2_ACCESS_DENIED */]: "Access Denied",
265
+ ["OAUTH2_SERVER_ERROR" /* OAUTH2_SERVER_ERROR */]: "OAuth2 Server Error",
266
+ ["DATABASE_CONNECTION_FAILED" /* DATABASE_CONNECTION_FAILED */]: "Database Connection Failed",
267
+ ["DATABASE_QUERY_FAILED" /* DATABASE_QUERY_FAILED */]: "Database Query Failed",
268
+ ["DATABASE_TRANSACTION_FAILED" /* DATABASE_TRANSACTION_FAILED */]: "Database Transaction Failed",
269
+ ["DATABASE_CONSTRAINT_VIOLATION" /* DATABASE_CONSTRAINT_VIOLATION */]: "Database Constraint Violation",
270
+ ["DATABASE_TIMEOUT" /* DATABASE_TIMEOUT */]: "Database Timeout",
271
+ ["DATABASE_POOL_EXHAUSTED" /* DATABASE_POOL_EXHAUSTED */]: "Database Connection Pool Exhausted",
272
+ ["DATABASE_MIGRATION_FAILED" /* DATABASE_MIGRATION_FAILED */]: "Database Migration Failed",
273
+ ["FILE_NOT_FOUND" /* FILE_NOT_FOUND */]: "File Not Found",
274
+ ["FILE_UPLOAD_FAILED" /* FILE_UPLOAD_FAILED */]: "File Upload Failed",
275
+ ["FILE_DOWNLOAD_FAILED" /* FILE_DOWNLOAD_FAILED */]: "File Download Failed",
276
+ ["FILE_SIZE_EXCEEDED" /* FILE_SIZE_EXCEEDED */]: "File Size Exceeded",
277
+ ["FILE_TYPE_NOT_ALLOWED" /* FILE_TYPE_NOT_ALLOWED */]: "File Type Not Allowed",
278
+ ["FILE_ACCESS_DENIED" /* FILE_ACCESS_DENIED */]: "File Access Denied",
279
+ ["FILE_PATH_TRAVERSAL" /* FILE_PATH_TRAVERSAL */]: "Path Traversal Detected",
280
+ ["MIDDLEWARE_EXECUTION_FAILED" /* MIDDLEWARE_EXECUTION_FAILED */]: "Middleware Execution Failed",
281
+ ["MIDDLEWARE_TIMEOUT" /* MIDDLEWARE_TIMEOUT */]: "Middleware Timeout",
282
+ ["CORS_NOT_ALLOWED" /* CORS_NOT_ALLOWED */]: "CORS Not Allowed",
283
+ ["CONFIG_INVALID" /* CONFIG_INVALID */]: "Invalid Configuration",
284
+ ["CONFIG_MISSING" /* CONFIG_MISSING */]: "Missing Configuration",
285
+ ["CONFIG_VALIDATION_FAILED" /* CONFIG_VALIDATION_FAILED */]: "Configuration Validation Failed"
210
286
  };
211
287
  });
212
288
 
@@ -218,42 +294,44 @@ var init_http_exception = __esm(() => {
218
294
  status;
219
295
  code;
220
296
  details;
221
- constructor(status, message, details, code) {
297
+ messageParams;
298
+ constructor(status, message, details, code, messageParams) {
222
299
  super(message);
223
300
  this.name = this.constructor.name;
224
301
  this.status = status;
225
302
  this.code = code;
226
303
  this.details = details;
304
+ this.messageParams = messageParams;
227
305
  }
228
- static withCode(code, message, details) {
306
+ static withCode(code, message, details, messageParams) {
229
307
  const status = ERROR_CODE_TO_STATUS[code] || 500;
230
308
  const finalMessage = message || ERROR_CODE_MESSAGES[code] || "Internal Server Error";
231
- return new HttpException(status, finalMessage, details, code);
309
+ return new HttpException(status, finalMessage, details, code, messageParams);
232
310
  }
233
311
  };
234
312
  BadRequestException = class BadRequestException extends HttpException {
235
- constructor(message = "Bad Request", details, code) {
236
- super(400, message, details, code);
313
+ constructor(message = "Bad Request", details, code, messageParams) {
314
+ super(400, message, details, code, messageParams);
237
315
  }
238
316
  };
239
317
  UnauthorizedException = class UnauthorizedException extends HttpException {
240
- constructor(message = "Unauthorized", details, code) {
241
- super(401, message, details, code);
318
+ constructor(message = "Unauthorized", details, code, messageParams) {
319
+ super(401, message, details, code, messageParams);
242
320
  }
243
321
  };
244
322
  ForbiddenException = class ForbiddenException extends HttpException {
245
- constructor(message = "Forbidden", details, code) {
246
- super(403, message, details, code);
323
+ constructor(message = "Forbidden", details, code, messageParams) {
324
+ super(403, message, details, code, messageParams);
247
325
  }
248
326
  };
249
327
  NotFoundException = class NotFoundException extends HttpException {
250
- constructor(message = "Not Found", details, code) {
251
- super(404, message, details, code);
328
+ constructor(message = "Not Found", details, code, messageParams) {
329
+ super(404, message, details, code, messageParams);
252
330
  }
253
331
  };
254
332
  InternalServerErrorException = class InternalServerErrorException extends HttpException {
255
- constructor(message = "Internal Server Error", details, code) {
256
- super(500, message, details, code);
333
+ constructor(message = "Internal Server Error", details, code, messageParams) {
334
+ super(500, message, details, code, messageParams);
257
335
  }
258
336
  };
259
337
  });
@@ -295,18 +373,35 @@ class ErrorMessageI18n {
295
373
  static getLanguage() {
296
374
  return this.currentLanguage;
297
375
  }
298
- static getMessage(code, language) {
376
+ static getMessage(code, language, params) {
299
377
  const lang = language || this.currentLanguage;
300
378
  const messages = ERROR_MESSAGES_I18N[lang];
301
- return messages?.[code] || ERROR_CODE_MESSAGES[code] || "Internal Server Error";
379
+ let message = messages?.[code] || ERROR_CODE_MESSAGES[code] || "Internal Server Error";
380
+ if (params) {
381
+ message = this.replaceTemplate(message, params);
382
+ }
383
+ return message;
384
+ }
385
+ static replaceTemplate(template, params) {
386
+ return template.replace(/\{(\w+)\}/g, (match, key) => {
387
+ const value = params[key];
388
+ return value !== undefined ? String(value) : match;
389
+ });
302
390
  }
303
391
  static parseLanguageFromHeader(acceptLanguage) {
304
392
  if (!acceptLanguage) {
305
393
  return "en";
306
394
  }
307
- if (acceptLanguage.includes("zh-CN") || acceptLanguage.includes("zh")) {
395
+ const lowerAcceptLanguage = acceptLanguage.toLowerCase();
396
+ if (lowerAcceptLanguage.includes("zh-cn") || lowerAcceptLanguage.includes("zh")) {
308
397
  return "zh-CN";
309
398
  }
399
+ if (lowerAcceptLanguage.includes("ja")) {
400
+ return "ja";
401
+ }
402
+ if (lowerAcceptLanguage.includes("ko")) {
403
+ return "ko";
404
+ }
310
405
  return "en";
311
406
  }
312
407
  }
@@ -322,19 +417,65 @@ var init_i18n = __esm(() => {
322
417
  ["INVALID_REQUEST" /* INVALID_REQUEST */]: "\u65E0\u6548\u7684\u8BF7\u6C42",
323
418
  ["RESOURCE_NOT_FOUND" /* RESOURCE_NOT_FOUND */]: "\u8D44\u6E90\u672A\u627E\u5230",
324
419
  ["METHOD_NOT_ALLOWED" /* METHOD_NOT_ALLOWED */]: "\u65B9\u6CD5\u4E0D\u5141\u8BB8",
420
+ ["RATE_LIMIT_EXCEEDED" /* RATE_LIMIT_EXCEEDED */]: "\u8BF7\u6C42\u9891\u7387\u8D85\u9650",
421
+ ["SERVICE_UNAVAILABLE" /* SERVICE_UNAVAILABLE */]: "\u670D\u52A1\u4E0D\u53EF\u7528",
422
+ ["TIMEOUT" /* TIMEOUT */]: "\u8BF7\u6C42\u8D85\u65F6",
325
423
  ["AUTH_REQUIRED" /* AUTH_REQUIRED */]: "\u9700\u8981\u8BA4\u8BC1",
326
424
  ["AUTH_INVALID_TOKEN" /* AUTH_INVALID_TOKEN */]: "\u65E0\u6548\u7684\u8BA4\u8BC1\u4EE4\u724C",
327
425
  ["AUTH_TOKEN_EXPIRED" /* AUTH_TOKEN_EXPIRED */]: "\u8BA4\u8BC1\u4EE4\u724C\u5DF2\u8FC7\u671F",
328
426
  ["AUTH_INSUFFICIENT_PERMISSIONS" /* AUTH_INSUFFICIENT_PERMISSIONS */]: "\u6743\u9650\u4E0D\u8DB3",
427
+ ["AUTH_INVALID_CREDENTIALS" /* AUTH_INVALID_CREDENTIALS */]: "\u65E0\u6548\u7684\u51ED\u636E",
428
+ ["AUTH_ACCOUNT_LOCKED" /* AUTH_ACCOUNT_LOCKED */]: "\u8D26\u6237\u5DF2\u9501\u5B9A",
429
+ ["AUTH_ACCOUNT_DISABLED" /* AUTH_ACCOUNT_DISABLED */]: "\u8D26\u6237\u5DF2\u7981\u7528",
329
430
  ["VALIDATION_FAILED" /* VALIDATION_FAILED */]: "\u9A8C\u8BC1\u5931\u8D25",
330
431
  ["VALIDATION_REQUIRED_FIELD" /* VALIDATION_REQUIRED_FIELD */]: "\u5FC5\u586B\u5B57\u6BB5\u7F3A\u5931",
331
432
  ["VALIDATION_INVALID_FORMAT" /* VALIDATION_INVALID_FORMAT */]: "\u683C\u5F0F\u65E0\u6548",
332
433
  ["VALIDATION_OUT_OF_RANGE" /* VALIDATION_OUT_OF_RANGE */]: "\u503C\u8D85\u51FA\u8303\u56F4",
434
+ ["VALIDATION_TYPE_MISMATCH" /* VALIDATION_TYPE_MISMATCH */]: "\u7C7B\u578B\u4E0D\u5339\u914D",
435
+ ["VALIDATION_CONSTRAINT_VIOLATION" /* VALIDATION_CONSTRAINT_VIOLATION */]: "\u7EA6\u675F\u8FDD\u53CD",
333
436
  ["OAUTH2_INVALID_CLIENT" /* OAUTH2_INVALID_CLIENT */]: "\u65E0\u6548\u7684\u5BA2\u6237\u7AEF",
334
437
  ["OAUTH2_INVALID_GRANT" /* OAUTH2_INVALID_GRANT */]: "\u65E0\u6548\u7684\u6388\u6743",
335
438
  ["OAUTH2_INVALID_SCOPE" /* OAUTH2_INVALID_SCOPE */]: "\u65E0\u6548\u7684\u4F5C\u7528\u57DF",
336
439
  ["OAUTH2_INVALID_REDIRECT_URI" /* OAUTH2_INVALID_REDIRECT_URI */]: "\u65E0\u6548\u7684\u91CD\u5B9A\u5411 URI",
337
- ["OAUTH2_UNSUPPORTED_GRANT_TYPE" /* OAUTH2_UNSUPPORTED_GRANT_TYPE */]: "\u4E0D\u652F\u6301\u7684\u6388\u6743\u7C7B\u578B"
440
+ ["OAUTH2_UNSUPPORTED_GRANT_TYPE" /* OAUTH2_UNSUPPORTED_GRANT_TYPE */]: "\u4E0D\u652F\u6301\u7684\u6388\u6743\u7C7B\u578B",
441
+ ["OAUTH2_ACCESS_DENIED" /* OAUTH2_ACCESS_DENIED */]: "\u8BBF\u95EE\u88AB\u62D2\u7EDD",
442
+ ["OAUTH2_SERVER_ERROR" /* OAUTH2_SERVER_ERROR */]: "OAuth2 \u670D\u52A1\u5668\u9519\u8BEF",
443
+ ["DATABASE_CONNECTION_FAILED" /* DATABASE_CONNECTION_FAILED */]: "\u6570\u636E\u5E93\u8FDE\u63A5\u5931\u8D25",
444
+ ["DATABASE_QUERY_FAILED" /* DATABASE_QUERY_FAILED */]: "\u6570\u636E\u5E93\u67E5\u8BE2\u5931\u8D25",
445
+ ["DATABASE_TRANSACTION_FAILED" /* DATABASE_TRANSACTION_FAILED */]: "\u6570\u636E\u5E93\u4E8B\u52A1\u5931\u8D25",
446
+ ["DATABASE_CONSTRAINT_VIOLATION" /* DATABASE_CONSTRAINT_VIOLATION */]: "\u6570\u636E\u5E93\u7EA6\u675F\u8FDD\u53CD",
447
+ ["DATABASE_TIMEOUT" /* DATABASE_TIMEOUT */]: "\u6570\u636E\u5E93\u8D85\u65F6",
448
+ ["DATABASE_POOL_EXHAUSTED" /* DATABASE_POOL_EXHAUSTED */]: "\u6570\u636E\u5E93\u8FDE\u63A5\u6C60\u8017\u5C3D",
449
+ ["DATABASE_MIGRATION_FAILED" /* DATABASE_MIGRATION_FAILED */]: "\u6570\u636E\u5E93\u8FC1\u79FB\u5931\u8D25",
450
+ ["FILE_NOT_FOUND" /* FILE_NOT_FOUND */]: "\u6587\u4EF6\u672A\u627E\u5230",
451
+ ["FILE_UPLOAD_FAILED" /* FILE_UPLOAD_FAILED */]: "\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25",
452
+ ["FILE_DOWNLOAD_FAILED" /* FILE_DOWNLOAD_FAILED */]: "\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25",
453
+ ["FILE_SIZE_EXCEEDED" /* FILE_SIZE_EXCEEDED */]: "\u6587\u4EF6\u5927\u5C0F\u8D85\u9650",
454
+ ["FILE_TYPE_NOT_ALLOWED" /* FILE_TYPE_NOT_ALLOWED */]: "\u4E0D\u5141\u8BB8\u7684\u6587\u4EF6\u7C7B\u578B",
455
+ ["FILE_ACCESS_DENIED" /* FILE_ACCESS_DENIED */]: "\u6587\u4EF6\u8BBF\u95EE\u88AB\u62D2\u7EDD",
456
+ ["FILE_PATH_TRAVERSAL" /* FILE_PATH_TRAVERSAL */]: "\u68C0\u6D4B\u5230\u8DEF\u5F84\u904D\u5386\u653B\u51FB",
457
+ ["MIDDLEWARE_EXECUTION_FAILED" /* MIDDLEWARE_EXECUTION_FAILED */]: "\u4E2D\u95F4\u4EF6\u6267\u884C\u5931\u8D25",
458
+ ["MIDDLEWARE_TIMEOUT" /* MIDDLEWARE_TIMEOUT */]: "\u4E2D\u95F4\u4EF6\u8D85\u65F6",
459
+ ["CORS_NOT_ALLOWED" /* CORS_NOT_ALLOWED */]: "CORS \u4E0D\u5141\u8BB8",
460
+ ["CONFIG_INVALID" /* CONFIG_INVALID */]: "\u65E0\u6548\u7684\u914D\u7F6E",
461
+ ["CONFIG_MISSING" /* CONFIG_MISSING */]: "\u7F3A\u5C11\u914D\u7F6E",
462
+ ["CONFIG_VALIDATION_FAILED" /* CONFIG_VALIDATION_FAILED */]: "\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25"
463
+ },
464
+ ja: {
465
+ ["INTERNAL_ERROR" /* INTERNAL_ERROR */]: "\u30B5\u30FC\u30D0\u30FC\u5185\u90E8\u30A8\u30E9\u30FC",
466
+ ["INVALID_REQUEST" /* INVALID_REQUEST */]: "\u7121\u52B9\u306A\u30EA\u30AF\u30A8\u30B9\u30C8",
467
+ ["RESOURCE_NOT_FOUND" /* RESOURCE_NOT_FOUND */]: "\u30EA\u30BD\u30FC\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093",
468
+ ["AUTH_REQUIRED" /* AUTH_REQUIRED */]: "\u8A8D\u8A3C\u304C\u5FC5\u8981\u3067\u3059",
469
+ ["AUTH_INVALID_TOKEN" /* AUTH_INVALID_TOKEN */]: "\u7121\u52B9\u306A\u8A8D\u8A3C\u30C8\u30FC\u30AF\u30F3",
470
+ ["VALIDATION_FAILED" /* VALIDATION_FAILED */]: "\u691C\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F"
471
+ },
472
+ ko: {
473
+ ["INTERNAL_ERROR" /* INTERNAL_ERROR */]: "\uC11C\uBC84 \uB0B4\uBD80 \uC624\uB958",
474
+ ["INVALID_REQUEST" /* INVALID_REQUEST */]: "\uC798\uBABB\uB41C \uC694\uCCAD",
475
+ ["RESOURCE_NOT_FOUND" /* RESOURCE_NOT_FOUND */]: "\uB9AC\uC18C\uC2A4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4",
476
+ ["AUTH_REQUIRED" /* AUTH_REQUIRED */]: "\uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4",
477
+ ["AUTH_INVALID_TOKEN" /* AUTH_INVALID_TOKEN */]: "\uC798\uBABB\uB41C \uC778\uC99D \uD1A0\uD070",
478
+ ["VALIDATION_FAILED" /* VALIDATION_FAILED */]: "\uC720\uD6A8\uC131 \uAC80\uC0AC \uC2E4\uD328"
338
479
  }
339
480
  };
340
481
  });
@@ -356,7 +497,7 @@ async function handleError(error, context) {
356
497
  if (error.code) {
357
498
  const acceptLanguage = context.getHeader("accept-language");
358
499
  const language = ErrorMessageI18n.parseLanguageFromHeader(acceptLanguage);
359
- errorMessage = ErrorMessageI18n.getMessage(error.code, language);
500
+ errorMessage = ErrorMessageI18n.getMessage(error.code, language, error.messageParams);
360
501
  }
361
502
  const responseBody = {
362
503
  error: errorMessage
@@ -390,6 +531,181 @@ var init_handler = __esm(() => {
390
531
  init_i18n();
391
532
  });
392
533
 
534
+ // src/database/orm/transaction-types.ts
535
+ var Propagation, IsolationLevel, TransactionStatus, TRANSACTION_SERVICE_TOKEN;
536
+ var init_transaction_types = __esm(() => {
537
+ ((Propagation2) => {
538
+ Propagation2["REQUIRED"] = "REQUIRED";
539
+ Propagation2["REQUIRES_NEW"] = "REQUIRES_NEW";
540
+ Propagation2["SUPPORTS"] = "SUPPORTS";
541
+ Propagation2["NOT_SUPPORTED"] = "NOT_SUPPORTED";
542
+ Propagation2["NEVER"] = "NEVER";
543
+ Propagation2["NESTED"] = "NESTED";
544
+ })(Propagation ||= {});
545
+ ((IsolationLevel2) => {
546
+ IsolationLevel2["READ_UNCOMMITTED"] = "READ_UNCOMMITTED";
547
+ IsolationLevel2["READ_COMMITTED"] = "READ_COMMITTED";
548
+ IsolationLevel2["REPEATABLE_READ"] = "REPEATABLE_READ";
549
+ IsolationLevel2["SERIALIZABLE"] = "SERIALIZABLE";
550
+ })(IsolationLevel ||= {});
551
+ ((TransactionStatus2) => {
552
+ TransactionStatus2["ACTIVE"] = "ACTIVE";
553
+ TransactionStatus2["COMMITTED"] = "COMMITTED";
554
+ TransactionStatus2["ROLLED_BACK"] = "ROLLED_BACK";
555
+ TransactionStatus2["SUSPENDED"] = "SUSPENDED";
556
+ })(TransactionStatus ||= {});
557
+ TRANSACTION_SERVICE_TOKEN = Symbol("@dangao/bun-server:orm:transaction:service");
558
+ });
559
+
560
+ // src/database/orm/transaction-decorator.ts
561
+ var exports_transaction_decorator = {};
562
+ __export(exports_transaction_decorator, {
563
+ getTransactionMetadata: () => getTransactionMetadata,
564
+ Transactional: () => Transactional,
565
+ TRANSACTION_METADATA_KEY: () => TRANSACTION_METADATA_KEY
566
+ });
567
+ import"reflect-metadata";
568
+ function Transactional(options) {
569
+ return (target, propertyKey, descriptor) => {
570
+ if (!descriptor || typeof descriptor.value !== "function") {
571
+ throw new Error("@Transactional() can only be applied to methods");
572
+ }
573
+ const metadata = {
574
+ propagation: options?.propagation ?? "REQUIRED" /* REQUIRED */,
575
+ isolationLevel: options?.isolationLevel,
576
+ timeout: options?.timeout,
577
+ readOnly: options?.readOnly ?? false,
578
+ rollbackFor: options?.rollbackFor ?? [],
579
+ noRollbackFor: options?.noRollbackFor ?? []
580
+ };
581
+ Reflect.defineMetadata(TRANSACTION_METADATA_KEY, metadata, target, propertyKey);
582
+ };
583
+ }
584
+ function getTransactionMetadata(target, propertyKey) {
585
+ if (typeof target === "object" && target !== null) {
586
+ return Reflect.getMetadata(TRANSACTION_METADATA_KEY, target, propertyKey);
587
+ }
588
+ return;
589
+ }
590
+ var TRANSACTION_METADATA_KEY;
591
+ var init_transaction_decorator = __esm(() => {
592
+ init_transaction_types();
593
+ TRANSACTION_METADATA_KEY = Symbol("@dangao/bun-server:orm:transaction");
594
+ });
595
+
596
+ // src/database/orm/transaction-interceptor.ts
597
+ var exports_transaction_interceptor = {};
598
+ __export(exports_transaction_interceptor, {
599
+ TransactionInterceptor: () => TransactionInterceptor
600
+ });
601
+
602
+ class TransactionInterceptor {
603
+ static async executeWithTransaction(target, propertyKey, originalMethod, args, container) {
604
+ const transactionMetadata = getTransactionMetadata(target, propertyKey);
605
+ if (!transactionMetadata) {
606
+ return await Promise.resolve(originalMethod.apply(target, args));
607
+ }
608
+ let transactionManager;
609
+ try {
610
+ transactionManager = container.resolve(TRANSACTION_SERVICE_TOKEN);
611
+ } catch (error) {
612
+ console.warn("TransactionManager not found, executing without transaction");
613
+ return await Promise.resolve(originalMethod.apply(target, args));
614
+ }
615
+ const propagation = transactionMetadata.propagation ?? "REQUIRED" /* REQUIRED */;
616
+ const currentTransaction = transactionManager.getCurrentTransaction();
617
+ switch (propagation) {
618
+ case "REQUIRED" /* REQUIRED */:
619
+ if (currentTransaction) {
620
+ return await this.executeInExistingTransaction(originalMethod, target, args, currentTransaction.id, transactionManager);
621
+ } else {
622
+ return await this.executeInNewTransaction(originalMethod, target, args, transactionMetadata, transactionManager);
623
+ }
624
+ case "REQUIRES_NEW" /* REQUIRES_NEW */:
625
+ return await this.executeInNewTransaction(originalMethod, target, args, transactionMetadata, transactionManager);
626
+ case "SUPPORTS" /* SUPPORTS */:
627
+ if (currentTransaction) {
628
+ return await this.executeInExistingTransaction(originalMethod, target, args, currentTransaction.id, transactionManager);
629
+ } else {
630
+ return await Promise.resolve(originalMethod.apply(target, args));
631
+ }
632
+ case "NOT_SUPPORTED" /* NOT_SUPPORTED */:
633
+ return await Promise.resolve(originalMethod.apply(target, args));
634
+ case "NEVER" /* NEVER */:
635
+ if (currentTransaction) {
636
+ throw new Error("Transaction propagation NEVER requires no existing transaction");
637
+ }
638
+ return await Promise.resolve(originalMethod.apply(target, args));
639
+ case "NESTED" /* NESTED */:
640
+ if (currentTransaction) {
641
+ return await this.executeInNestedTransaction(originalMethod, target, args, currentTransaction.id, transactionMetadata, transactionManager);
642
+ } else {
643
+ return await this.executeInNewTransaction(originalMethod, target, args, transactionMetadata, transactionManager);
644
+ }
645
+ default:
646
+ return await Promise.resolve(originalMethod.apply(target, args));
647
+ }
648
+ }
649
+ static async executeInNewTransaction(method, target, args, options, transactionManager) {
650
+ const context = await transactionManager.beginTransaction({
651
+ timeout: options.timeout
652
+ });
653
+ try {
654
+ const result = await Promise.resolve(method.apply(target, args));
655
+ await transactionManager.commitTransaction(context.id);
656
+ return result;
657
+ } catch (error) {
658
+ if (this.shouldRollback(error, options.rollbackFor, options.noRollbackFor)) {
659
+ await transactionManager.rollbackTransaction(context.id);
660
+ } else {
661
+ await transactionManager.commitTransaction(context.id);
662
+ }
663
+ throw error;
664
+ }
665
+ }
666
+ static async executeInExistingTransaction(method, target, args, transactionId, transactionManager) {
667
+ return await Promise.resolve(method.apply(target, args));
668
+ }
669
+ static async executeInNestedTransaction(method, target, args, parentTransactionId, options, transactionManager) {
670
+ const savepointName = await transactionManager.createSavepoint(parentTransactionId);
671
+ try {
672
+ const result = await Promise.resolve(method.apply(target, args));
673
+ return result;
674
+ } catch (error) {
675
+ if (this.shouldRollback(error, options.rollbackFor, options.noRollbackFor)) {
676
+ await transactionManager.rollbackToSavepoint(parentTransactionId, savepointName);
677
+ }
678
+ throw error;
679
+ }
680
+ }
681
+ static shouldRollback(error, rollbackFor, noRollbackFor) {
682
+ if (!error) {
683
+ return false;
684
+ }
685
+ if (noRollbackFor && noRollbackFor.length > 0) {
686
+ for (const ErrorClass of noRollbackFor) {
687
+ if (error instanceof ErrorClass) {
688
+ return false;
689
+ }
690
+ }
691
+ }
692
+ if (rollbackFor && rollbackFor.length > 0) {
693
+ for (const ErrorClass of rollbackFor) {
694
+ if (error instanceof ErrorClass) {
695
+ return true;
696
+ }
697
+ }
698
+ return false;
699
+ }
700
+ return true;
701
+ }
702
+ }
703
+ var init_transaction_interceptor = __esm(() => {
704
+ init_transaction_types();
705
+ init_transaction_decorator();
706
+ init_transaction_types();
707
+ });
708
+
393
709
  // src/request/body-parser.ts
394
710
  class BodyParser {
395
711
  static async parse(request) {
@@ -525,6 +841,17 @@ class Context {
525
841
  getHeader(key) {
526
842
  return this.headers.get(key);
527
843
  }
844
+ getClientIp() {
845
+ const forwardedFor = this.getHeader("X-Forwarded-For");
846
+ if (forwardedFor) {
847
+ return forwardedFor.split(",")[0].trim();
848
+ }
849
+ const realIp = this.getHeader("X-Real-IP");
850
+ if (realIp) {
851
+ return realIp.trim();
852
+ }
853
+ return "unknown";
854
+ }
528
855
  setHeader(key, value) {
529
856
  this.responseHeaders.set(key, value);
530
857
  }
@@ -1325,6 +1652,112 @@ function getRouteMetadata(target) {
1325
1652
  }
1326
1653
  // src/middleware/decorators.ts
1327
1654
  import"reflect-metadata";
1655
+
1656
+ // src/middleware/builtin/rate-limit.ts
1657
+ class MemoryRateLimitStore {
1658
+ store = new Map;
1659
+ async get(key) {
1660
+ const entry = this.store.get(key);
1661
+ if (!entry) {
1662
+ return 0;
1663
+ }
1664
+ if (Date.now() > entry.resetTime) {
1665
+ this.store.delete(key);
1666
+ return 0;
1667
+ }
1668
+ return entry.count;
1669
+ }
1670
+ async increment(key, windowMs) {
1671
+ const now = Date.now();
1672
+ const entry = this.store.get(key);
1673
+ if (!entry || now > entry.resetTime) {
1674
+ const resetTime = now + windowMs;
1675
+ this.store.set(key, { count: 1, resetTime });
1676
+ return 1;
1677
+ }
1678
+ entry.count++;
1679
+ return entry.count;
1680
+ }
1681
+ async reset(key) {
1682
+ this.store.delete(key);
1683
+ }
1684
+ cleanup() {
1685
+ const now = Date.now();
1686
+ for (const [key, entry] of this.store.entries()) {
1687
+ if (now > entry.resetTime) {
1688
+ this.store.delete(key);
1689
+ }
1690
+ }
1691
+ }
1692
+ }
1693
+ function defaultKeyGenerator(context) {
1694
+ return `rate-limit:${context.getClientIp()}`;
1695
+ }
1696
+ function createRateLimitMiddleware(options) {
1697
+ const {
1698
+ max,
1699
+ windowMs = 60000,
1700
+ store = new MemoryRateLimitStore,
1701
+ keyGenerator = defaultKeyGenerator,
1702
+ skipSuccessfulRequests = false,
1703
+ skipFailedRequests = false,
1704
+ message = "Too Many Requests",
1705
+ statusCode = 429,
1706
+ standardHeaders = true,
1707
+ legacyHeaders = true
1708
+ } = options;
1709
+ return async (context, next) => {
1710
+ const key = await keyGenerator(context);
1711
+ const currentCount = await store.increment(key, windowMs);
1712
+ const remaining = Math.max(0, max - currentCount);
1713
+ const resetTime = Date.now() + windowMs;
1714
+ if (standardHeaders) {
1715
+ context.setHeader("RateLimit-Limit", max.toString());
1716
+ context.setHeader("RateLimit-Remaining", remaining.toString());
1717
+ context.setHeader("RateLimit-Reset", Math.ceil(resetTime / 1000).toString());
1718
+ }
1719
+ if (legacyHeaders) {
1720
+ context.setHeader("X-RateLimit-Limit", max.toString());
1721
+ context.setHeader("X-RateLimit-Remaining", remaining.toString());
1722
+ context.setHeader("X-RateLimit-Reset", Math.ceil(resetTime / 1000).toString());
1723
+ }
1724
+ if (currentCount > max) {
1725
+ context.setStatus(statusCode);
1726
+ return context.createResponse({
1727
+ error: message,
1728
+ retryAfter: Math.ceil(windowMs / 1000)
1729
+ });
1730
+ }
1731
+ const response = await next();
1732
+ const shouldSkip = skipSuccessfulRequests && response.status >= 200 && response.status < 300 || skipFailedRequests && response.status >= 400;
1733
+ if (shouldSkip) {
1734
+ const current = await store.get(key);
1735
+ if (current > 0) {}
1736
+ }
1737
+ return response;
1738
+ };
1739
+ }
1740
+ function createTokenKeyGenerator(tokenHeader = "Authorization") {
1741
+ return (context) => {
1742
+ const token = context.getHeader(tokenHeader);
1743
+ if (token) {
1744
+ const tokenValue = token.startsWith("Bearer ") ? token.substring(7) : token;
1745
+ return `rate-limit:token:${tokenValue}`;
1746
+ }
1747
+ return defaultKeyGenerator(context);
1748
+ };
1749
+ }
1750
+ function createUserKeyGenerator(getUserId) {
1751
+ return (context) => {
1752
+ const userId = getUserId(context);
1753
+ if (userId) {
1754
+ return `rate-limit:user:${userId}`;
1755
+ }
1756
+ return defaultKeyGenerator(context);
1757
+ };
1758
+ }
1759
+
1760
+ // src/middleware/decorators.ts
1328
1761
  var CLASS_MIDDLEWARE_METADATA_KEY = Symbol("middleware:class");
1329
1762
  var METHOD_MIDDLEWARE_METADATA_KEY = Symbol("middleware:method");
1330
1763
  function appendMiddlewareMetadata(target, propertyKey, middlewares) {
@@ -1344,6 +1777,12 @@ function UseMiddleware(...middlewares) {
1344
1777
  appendMiddlewareMetadata(propertyKey === undefined ? target : target, propertyKey, middlewares);
1345
1778
  };
1346
1779
  }
1780
+ function RateLimit(options) {
1781
+ return function(target, propertyKey) {
1782
+ const middleware = createRateLimitMiddleware(options);
1783
+ appendMiddlewareMetadata(target, propertyKey, [middleware]);
1784
+ };
1785
+ }
1347
1786
  function getClassMiddlewares(constructor) {
1348
1787
  return Reflect.getMetadata(CLASS_MIDDLEWARE_METADATA_KEY, constructor) || [];
1349
1788
  }
@@ -1690,7 +2129,19 @@ class ControllerRegistry {
1690
2129
  if (!method || typeof method !== "function") {
1691
2130
  throw new Error(`Method ${propertyKey} not found on controller ${controllerClass.name}`);
1692
2131
  }
1693
- const result = method.apply(controllerInstance, params);
2132
+ let result;
2133
+ try {
2134
+ const { TransactionInterceptor: TransactionInterceptor2 } = await Promise.resolve().then(() => (init_transaction_interceptor(), exports_transaction_interceptor));
2135
+ const { getTransactionMetadata: getTransactionMetadata2 } = await Promise.resolve().then(() => (init_transaction_decorator(), exports_transaction_decorator));
2136
+ const hasTransaction = getTransactionMetadata2(prototype2, propertyKey);
2137
+ if (hasTransaction) {
2138
+ result = TransactionInterceptor2.executeWithTransaction(prototype2, propertyKey, method, params, controllerContainer);
2139
+ } else {
2140
+ result = method.apply(controllerInstance, params);
2141
+ }
2142
+ } catch (error) {
2143
+ result = method.apply(controllerInstance, params);
2144
+ }
1694
2145
  const responseData = await Promise.resolve(result);
1695
2146
  if (responseData instanceof Response) {
1696
2147
  return responseData;
@@ -2051,10 +2502,11 @@ class Application {
2051
2502
  use(middleware) {
2052
2503
  this.middlewarePipeline.use(middleware);
2053
2504
  }
2054
- listen(port, hostname) {
2505
+ async listen(port, hostname) {
2055
2506
  if (this.server?.isRunning()) {
2056
2507
  throw new Error("Application is already running");
2057
2508
  }
2509
+ await this.initializeExtensions();
2058
2510
  const serverOptions = {
2059
2511
  port: port ?? this.options.port ?? 3000,
2060
2512
  hostname: hostname ?? this.options.hostname,
@@ -2064,9 +2516,27 @@ class Application {
2064
2516
  this.server = new BunServer(serverOptions);
2065
2517
  this.server.start();
2066
2518
  }
2067
- stop() {
2519
+ async initializeExtensions() {
2520
+ const container = this.getContainer();
2521
+ for (const extension of this.extensions) {
2522
+ if (extension && typeof extension === "object" && "initialize" in extension && typeof extension.initialize === "function") {
2523
+ await extension.initialize(container);
2524
+ }
2525
+ }
2526
+ }
2527
+ async stop() {
2528
+ await this.closeExtensions();
2068
2529
  this.server?.stop();
2069
2530
  }
2531
+ async closeExtensions() {
2532
+ const container = this.getContainer();
2533
+ for (let i = this.extensions.length - 1;i >= 0; i--) {
2534
+ const extension = this.extensions[i];
2535
+ if (extension && typeof extension === "object" && "close" in extension && typeof extension.close === "function") {
2536
+ await extension.close(container);
2537
+ }
2538
+ }
2539
+ }
2070
2540
  async handleRequest(context) {
2071
2541
  if (["POST", "PUT", "PATCH"].includes(context.method)) {
2072
2542
  await context.getBody();
@@ -3122,19 +3592,19 @@ class OAuth2Controller {
3122
3592
  constructor(oauth2Service) {
3123
3593
  this.oauth2Service = oauth2Service;
3124
3594
  }
3125
- authorize(clientId, redirectUri, state, scope) {
3126
- const query = {
3127
- client_id: clientId,
3128
- redirect_uri: redirectUri,
3129
- ...state && { state },
3130
- ...scope && { scope }
3131
- };
3595
+ authorize(clientId, redirectUri, responseType, state, scope) {
3596
+ if (!clientId || !redirectUri) {
3597
+ throw new Error("Missing required parameters: client_id and redirect_uri are required");
3598
+ }
3599
+ if (responseType !== "code") {
3600
+ throw new Error(`Unsupported response_type: ${responseType}. Only 'code' is supported.`);
3601
+ }
3132
3602
  const request = {
3133
- clientId: query.client_id || "",
3134
- redirectUri: query.redirect_uri || "",
3603
+ clientId,
3604
+ redirectUri,
3135
3605
  responseType: "code",
3136
- scope: query.scope,
3137
- state: query.state
3606
+ scope: scope || undefined,
3607
+ state: state || undefined
3138
3608
  };
3139
3609
  const validation = this.oauth2Service.validateAuthorizationRequest(request);
3140
3610
  if (!validation.valid) {
@@ -3195,13 +3665,15 @@ __legacyDecorateClassTS([
3195
3665
  GET("/authorize"),
3196
3666
  __legacyDecorateParamTS(0, Query("client_id")),
3197
3667
  __legacyDecorateParamTS(1, Query("redirect_uri")),
3198
- __legacyDecorateParamTS(2, Query("state")),
3199
- __legacyDecorateParamTS(3, Query("scope")),
3668
+ __legacyDecorateParamTS(2, Query("response_type")),
3669
+ __legacyDecorateParamTS(3, Query("state")),
3670
+ __legacyDecorateParamTS(4, Query("scope")),
3200
3671
  __legacyMetadataTS("design:type", Function),
3201
3672
  __legacyMetadataTS("design:paramtypes", [
3202
3673
  String,
3203
3674
  String,
3204
3675
  String,
3676
+ String,
3205
3677
  String
3206
3678
  ]),
3207
3679
  __legacyMetadataTS("design:returntype", undefined)
@@ -3489,6 +3961,1166 @@ HealthModule = __legacyDecorateClassTS([
3489
3961
  providers: []
3490
3962
  })
3491
3963
  ], HealthModule);
3964
+ // src/metrics/collector.ts
3965
+ class MetricsCollector {
3966
+ counters = new Map;
3967
+ gauges = new Map;
3968
+ histograms = new Map;
3969
+ customMetrics = [];
3970
+ registerCustomMetric(metric) {
3971
+ this.customMetrics.push(metric);
3972
+ }
3973
+ incrementCounter(name, labels, value = 1) {
3974
+ const key = this.getKey(name, labels);
3975
+ const counterMap = this.counters.get(name) || new Map;
3976
+ const current = counterMap.get(key) || 0;
3977
+ counterMap.set(key, current + value);
3978
+ this.counters.set(name, counterMap);
3979
+ }
3980
+ setGauge(name, labels, value) {
3981
+ const key = this.getKey(name, labels);
3982
+ const gaugeMap = this.gauges.get(name) || new Map;
3983
+ gaugeMap.set(key, value);
3984
+ this.gauges.set(name, gaugeMap);
3985
+ }
3986
+ observeHistogram(name, labels, value) {
3987
+ const key = this.getKey(name, labels);
3988
+ const histogramMap = this.histograms.get(name) || new Map;
3989
+ const values = histogramMap.get(key) || [];
3990
+ values.push(value);
3991
+ histogramMap.set(key, values);
3992
+ this.histograms.set(name, histogramMap);
3993
+ }
3994
+ async getAllDataPoints() {
3995
+ const dataPoints = [];
3996
+ for (const [name, counterMap] of this.counters.entries()) {
3997
+ for (const [key, value] of counterMap.entries()) {
3998
+ const labels = this.parseKey(key);
3999
+ dataPoints.push({
4000
+ name,
4001
+ type: "counter",
4002
+ value,
4003
+ labels: labels && Object.keys(labels).length > 0 ? labels : undefined
4004
+ });
4005
+ }
4006
+ }
4007
+ for (const [name, gaugeMap] of this.gauges.entries()) {
4008
+ for (const [key, value] of gaugeMap.entries()) {
4009
+ const labels = this.parseKey(key);
4010
+ dataPoints.push({
4011
+ name,
4012
+ type: "gauge",
4013
+ value,
4014
+ labels: labels && Object.keys(labels).length > 0 ? labels : undefined
4015
+ });
4016
+ }
4017
+ }
4018
+ for (const [name, histogramMap] of this.histograms.entries()) {
4019
+ for (const [key, values] of histogramMap.entries()) {
4020
+ const labels = this.parseKey(key);
4021
+ const sum = values.reduce((a, b) => a + b, 0);
4022
+ const count = values.length;
4023
+ const buckets = this.calculateBuckets(values);
4024
+ dataPoints.push({
4025
+ name: `${name}_sum`,
4026
+ type: "histogram",
4027
+ value: sum,
4028
+ labels: labels && Object.keys(labels).length > 0 ? labels : undefined
4029
+ });
4030
+ dataPoints.push({
4031
+ name: `${name}_count`,
4032
+ type: "histogram",
4033
+ value: count,
4034
+ labels: labels && Object.keys(labels).length > 0 ? labels : undefined
4035
+ });
4036
+ for (const [bucket, bucketCount] of Object.entries(buckets)) {
4037
+ dataPoints.push({
4038
+ name: `${name}_bucket`,
4039
+ type: "histogram",
4040
+ value: bucketCount,
4041
+ labels: {
4042
+ ...labels,
4043
+ le: bucket
4044
+ }
4045
+ });
4046
+ }
4047
+ }
4048
+ }
4049
+ for (const metric of this.customMetrics) {
4050
+ try {
4051
+ const value = await metric.getValue();
4052
+ dataPoints.push({
4053
+ name: metric.name,
4054
+ type: metric.type,
4055
+ value,
4056
+ help: metric.help
4057
+ });
4058
+ } catch (error) {
4059
+ console.error(`Failed to collect custom metric ${metric.name}:`, error);
4060
+ }
4061
+ }
4062
+ return dataPoints;
4063
+ }
4064
+ reset() {
4065
+ this.counters.clear();
4066
+ this.gauges.clear();
4067
+ this.histograms.clear();
4068
+ }
4069
+ getKey(name, labels) {
4070
+ if (!labels || Object.keys(labels).length === 0) {
4071
+ return "";
4072
+ }
4073
+ const sortedLabels = Object.keys(labels).sort().map((key) => `${key}="${labels[key]}"`).join(",");
4074
+ return `{${sortedLabels}}`;
4075
+ }
4076
+ parseKey(key) {
4077
+ if (!key || key === "") {
4078
+ return;
4079
+ }
4080
+ const labels = {};
4081
+ const match = key.match(/\{([^}]+)\}/);
4082
+ if (match) {
4083
+ const labelPairs = match[1].split(",");
4084
+ for (const pair of labelPairs) {
4085
+ const [k, v] = pair.split("=");
4086
+ if (k && v) {
4087
+ labels[k.trim()] = v.trim().replace(/^"|"$/g, "");
4088
+ }
4089
+ }
4090
+ }
4091
+ return Object.keys(labels).length > 0 ? labels : undefined;
4092
+ }
4093
+ calculateBuckets(values) {
4094
+ const defaultBuckets = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10];
4095
+ const buckets = {};
4096
+ for (const bucket of defaultBuckets) {
4097
+ buckets[bucket.toString()] = values.filter((v) => v <= bucket).length;
4098
+ }
4099
+ buckets["+Inf"] = values.length;
4100
+ return buckets;
4101
+ }
4102
+ }
4103
+
4104
+ // src/metrics/prometheus.ts
4105
+ class PrometheusFormatter {
4106
+ format(dataPoints) {
4107
+ const lines = [];
4108
+ const metricGroups = this.groupByMetricName(dataPoints);
4109
+ for (const [metricName, points] of metricGroups.entries()) {
4110
+ const help = points[0]?.help;
4111
+ if (help) {
4112
+ lines.push(`# HELP ${metricName} ${help}`);
4113
+ }
4114
+ const type = points[0]?.type;
4115
+ if (type) {
4116
+ lines.push(`# TYPE ${metricName} ${type}`);
4117
+ }
4118
+ for (const point of points) {
4119
+ const labelString = this.formatLabels(point.labels);
4120
+ const line = labelString ? `${point.name}${labelString} ${point.value}` : `${point.name} ${point.value}`;
4121
+ lines.push(line);
4122
+ }
4123
+ lines.push("");
4124
+ }
4125
+ return lines.join(`
4126
+ `);
4127
+ }
4128
+ groupByMetricName(dataPoints) {
4129
+ const groups = new Map;
4130
+ for (const point of dataPoints) {
4131
+ const name = point.name;
4132
+ const existing = groups.get(name) || [];
4133
+ existing.push(point);
4134
+ groups.set(name, existing);
4135
+ }
4136
+ return groups;
4137
+ }
4138
+ formatLabels(labels) {
4139
+ if (!labels || Object.keys(labels).length === 0) {
4140
+ return "";
4141
+ }
4142
+ const labelPairs = Object.keys(labels).sort().map((key) => `${key}="${this.escapeLabelValue(labels[key])}"`).join(",");
4143
+ return `{${labelPairs}}`;
4144
+ }
4145
+ escapeLabelValue(value) {
4146
+ return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\n");
4147
+ }
4148
+ }
4149
+
4150
+ // src/metrics/types.ts
4151
+ var METRICS_SERVICE_TOKEN = Symbol("@dangao/bun-server:metrics:service");
4152
+ var METRICS_OPTIONS_TOKEN = Symbol("@dangao/bun-server:metrics:options");
4153
+
4154
+ // src/metrics/controller.ts
4155
+ class MetricsController {
4156
+ collector;
4157
+ options;
4158
+ formatter;
4159
+ constructor(collector, options) {
4160
+ this.collector = collector;
4161
+ this.options = options;
4162
+ this.formatter = new PrometheusFormatter;
4163
+ }
4164
+ async metrics() {
4165
+ const dataPoints = await this.collector.getAllDataPoints();
4166
+ const prometheusText = this.formatter.format(dataPoints);
4167
+ return new Response(prometheusText, {
4168
+ headers: {
4169
+ "Content-Type": "text/plain; version=0.0.4; charset=utf-8"
4170
+ }
4171
+ });
4172
+ }
4173
+ }
4174
+ __legacyDecorateClassTS([
4175
+ GET("/metrics"),
4176
+ __legacyMetadataTS("design:type", Function),
4177
+ __legacyMetadataTS("design:paramtypes", []),
4178
+ __legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
4179
+ ], MetricsController.prototype, "metrics", null);
4180
+ MetricsController = __legacyDecorateClassTS([
4181
+ Controller("/"),
4182
+ __legacyDecorateParamTS(0, Inject(METRICS_SERVICE_TOKEN)),
4183
+ __legacyDecorateParamTS(1, Inject(METRICS_OPTIONS_TOKEN)),
4184
+ __legacyMetadataTS("design:paramtypes", [
4185
+ typeof MetricsCollector === "undefined" ? Object : MetricsCollector,
4186
+ typeof MetricsModuleOptions === "undefined" ? Object : MetricsModuleOptions
4187
+ ])
4188
+ ], MetricsController);
4189
+
4190
+ // src/metrics/metrics-module.ts
4191
+ class MetricsModule {
4192
+ static forRoot(options = {}) {
4193
+ const providers2 = [];
4194
+ const collector = new MetricsCollector;
4195
+ if (options.customMetrics) {
4196
+ for (const metric of options.customMetrics) {
4197
+ collector.registerCustomMetric(metric);
4198
+ }
4199
+ }
4200
+ providers2.push({
4201
+ provide: METRICS_SERVICE_TOKEN,
4202
+ useValue: collector
4203
+ }, {
4204
+ provide: METRICS_OPTIONS_TOKEN,
4205
+ useValue: options
4206
+ }, MetricsCollector);
4207
+ const existingMetadata = Reflect.getMetadata(MODULE_METADATA_KEY, MetricsModule) || {};
4208
+ const metadata = {
4209
+ ...existingMetadata,
4210
+ controllers: [...existingMetadata.controllers || [], MetricsController],
4211
+ providers: [...existingMetadata.providers || [], ...providers2],
4212
+ exports: [
4213
+ ...existingMetadata.exports || [],
4214
+ METRICS_SERVICE_TOKEN,
4215
+ MetricsCollector
4216
+ ]
4217
+ };
4218
+ Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, MetricsModule);
4219
+ return MetricsModule;
4220
+ }
4221
+ }
4222
+ MetricsModule = __legacyDecorateClassTS([
4223
+ Module({
4224
+ controllers: [MetricsController],
4225
+ providers: []
4226
+ })
4227
+ ], MetricsModule);
4228
+ // src/metrics/middleware.ts
4229
+ function createHttpMetricsMiddleware(collector) {
4230
+ return async (context2, next) => {
4231
+ const startTime = Date.now();
4232
+ const response = await next();
4233
+ const duration = Date.now() - startTime;
4234
+ const durationSeconds = duration / 1000;
4235
+ const method = context2.method;
4236
+ const path = context2.path;
4237
+ const statusCode = response.status;
4238
+ collector.incrementCounter("http_requests_total", {
4239
+ method,
4240
+ path,
4241
+ status: statusCode.toString()
4242
+ });
4243
+ collector.observeHistogram("http_request_duration_seconds", {
4244
+ method,
4245
+ path,
4246
+ status: statusCode.toString()
4247
+ }, durationSeconds);
4248
+ collector.observeHistogram("http_request_duration_seconds_summary", {
4249
+ method,
4250
+ path
4251
+ }, durationSeconds);
4252
+ return response;
4253
+ };
4254
+ }
4255
+ // src/database/types.ts
4256
+ var DATABASE_SERVICE_TOKEN = Symbol("@dangao/bun-server:database:service");
4257
+ var DATABASE_OPTIONS_TOKEN = Symbol("@dangao/bun-server:database:options");
4258
+
4259
+ // src/database/database-extension.ts
4260
+ class DatabaseExtension {
4261
+ register(container) {}
4262
+ async initialize(container) {
4263
+ try {
4264
+ const databaseService = container.resolve(DATABASE_SERVICE_TOKEN);
4265
+ await databaseService.initialize();
4266
+ } catch (error) {
4267
+ if (error instanceof Error && error.message.includes("Provider not found")) {
4268
+ return;
4269
+ }
4270
+ throw error;
4271
+ }
4272
+ }
4273
+ async close(container) {
4274
+ try {
4275
+ const databaseService = container.resolve(DATABASE_SERVICE_TOKEN);
4276
+ await databaseService.closePool();
4277
+ } catch (error) {
4278
+ if (error instanceof Error && error.message.includes("Provider not found")) {
4279
+ return;
4280
+ }
4281
+ throw error;
4282
+ }
4283
+ }
4284
+ }
4285
+
4286
+ // src/database/health-indicator.ts
4287
+ class DatabaseHealthIndicator {
4288
+ databaseService;
4289
+ name = "database";
4290
+ constructor(databaseService) {
4291
+ this.databaseService = databaseService;
4292
+ }
4293
+ async check() {
4294
+ try {
4295
+ const isHealthy = await this.databaseService.healthCheck();
4296
+ const connectionInfo = this.databaseService.getConnectionInfo();
4297
+ if (isHealthy) {
4298
+ return {
4299
+ status: "up",
4300
+ details: {
4301
+ type: connectionInfo.type,
4302
+ status: connectionInfo.status
4303
+ }
4304
+ };
4305
+ }
4306
+ return {
4307
+ status: "down",
4308
+ details: {
4309
+ type: connectionInfo.type,
4310
+ status: connectionInfo.status,
4311
+ error: connectionInfo.error
4312
+ }
4313
+ };
4314
+ } catch (error) {
4315
+ return {
4316
+ status: "down",
4317
+ details: {
4318
+ error: error instanceof Error ? error.message : String(error)
4319
+ }
4320
+ };
4321
+ }
4322
+ }
4323
+ }
4324
+
4325
+ // src/database/orm/service.ts
4326
+ class OrmService {
4327
+ databaseService;
4328
+ options;
4329
+ drizzleInstance = null;
4330
+ constructor(databaseService, options = {}) {
4331
+ this.databaseService = databaseService;
4332
+ this.options = options;
4333
+ }
4334
+ getDrizzle() {
4335
+ if (this.options.drizzle) {
4336
+ return this.options.drizzle;
4337
+ }
4338
+ if (this.drizzleInstance) {
4339
+ return this.drizzleInstance;
4340
+ }
4341
+ return null;
4342
+ }
4343
+ setDrizzle(drizzle) {
4344
+ this.drizzleInstance = drizzle;
4345
+ }
4346
+ getDatabaseService() {
4347
+ return this.databaseService;
4348
+ }
4349
+ }
4350
+ OrmService = __legacyDecorateClassTS([
4351
+ Injectable(),
4352
+ __legacyMetadataTS("design:paramtypes", [
4353
+ typeof DatabaseService === "undefined" ? Object : DatabaseService,
4354
+ typeof OrmModuleOptions === "undefined" ? Object : OrmModuleOptions
4355
+ ])
4356
+ ], OrmService);
4357
+
4358
+ // src/database/orm/transaction-manager.ts
4359
+ init_transaction_types();
4360
+ class TransactionManager {
4361
+ databaseService;
4362
+ transactions = new Map;
4363
+ connectionTransactions = new Map;
4364
+ constructor(databaseService) {
4365
+ this.databaseService = databaseService;
4366
+ }
4367
+ async beginTransaction(options = {}) {
4368
+ const transactionId = this.generateTransactionId();
4369
+ const context2 = {
4370
+ id: transactionId,
4371
+ status: "ACTIVE" /* ACTIVE */,
4372
+ startTime: Date.now(),
4373
+ level: 0,
4374
+ savepoints: []
4375
+ };
4376
+ const connection = await this.databaseService.getConnection();
4377
+ this.connectionTransactions.set(connection, transactionId);
4378
+ this.transactions.set(transactionId, context2);
4379
+ await this.executeBegin(connection, options);
4380
+ return context2;
4381
+ }
4382
+ async commitTransaction(transactionId) {
4383
+ const context2 = this.transactions.get(transactionId);
4384
+ if (!context2) {
4385
+ throw new Error(`Transaction ${transactionId} not found`);
4386
+ }
4387
+ if (context2.status !== "ACTIVE" /* ACTIVE */) {
4388
+ throw new Error(`Transaction ${transactionId} is not active`);
4389
+ }
4390
+ const connection = this.findConnectionByTransactionId(transactionId);
4391
+ if (!connection) {
4392
+ throw new Error(`Connection not found for transaction ${transactionId}`);
4393
+ }
4394
+ await this.executeCommit(connection);
4395
+ context2.status = "COMMITTED" /* COMMITTED */;
4396
+ this.cleanupTransaction(transactionId);
4397
+ }
4398
+ async rollbackTransaction(transactionId) {
4399
+ const context2 = this.transactions.get(transactionId);
4400
+ if (!context2) {
4401
+ throw new Error(`Transaction ${transactionId} not found`);
4402
+ }
4403
+ const connection = this.findConnectionByTransactionId(transactionId);
4404
+ if (!connection) {
4405
+ throw new Error(`Connection not found for transaction ${transactionId}`);
4406
+ }
4407
+ await this.executeRollback(connection);
4408
+ context2.status = "ROLLED_BACK" /* ROLLED_BACK */;
4409
+ this.cleanupTransaction(transactionId);
4410
+ }
4411
+ async createSavepoint(transactionId) {
4412
+ const context2 = this.transactions.get(transactionId);
4413
+ if (!context2) {
4414
+ throw new Error(`Transaction ${transactionId} not found`);
4415
+ }
4416
+ const savepointName = `sp_${context2.level}_${Date.now()}`;
4417
+ context2.savepoints = context2.savepoints || [];
4418
+ context2.savepoints.push(savepointName);
4419
+ context2.level += 1;
4420
+ const connection = this.findConnectionByTransactionId(transactionId);
4421
+ if (connection) {
4422
+ await this.executeSavepoint(connection, savepointName);
4423
+ }
4424
+ return savepointName;
4425
+ }
4426
+ async rollbackToSavepoint(transactionId, savepointName) {
4427
+ const context2 = this.transactions.get(transactionId);
4428
+ if (!context2) {
4429
+ throw new Error(`Transaction ${transactionId} not found`);
4430
+ }
4431
+ const connection = this.findConnectionByTransactionId(transactionId);
4432
+ if (connection) {
4433
+ await this.executeRollbackToSavepoint(connection, savepointName);
4434
+ }
4435
+ const index = context2.savepoints?.indexOf(savepointName) ?? -1;
4436
+ if (index >= 0 && context2.savepoints) {
4437
+ context2.savepoints = context2.savepoints.slice(0, index);
4438
+ context2.level = index;
4439
+ }
4440
+ }
4441
+ getCurrentTransaction() {
4442
+ for (const context2 of this.transactions.values()) {
4443
+ if (context2.status === "ACTIVE" /* ACTIVE */) {
4444
+ return context2;
4445
+ }
4446
+ }
4447
+ return null;
4448
+ }
4449
+ hasActiveTransaction() {
4450
+ return this.getCurrentTransaction() !== null;
4451
+ }
4452
+ generateTransactionId() {
4453
+ return `tx_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
4454
+ }
4455
+ findConnectionByTransactionId(transactionId) {
4456
+ for (const [connection, txId] of this.connectionTransactions.entries()) {
4457
+ if (txId === transactionId) {
4458
+ return connection;
4459
+ }
4460
+ }
4461
+ return null;
4462
+ }
4463
+ cleanupTransaction(transactionId) {
4464
+ this.transactions.delete(transactionId);
4465
+ for (const [connection, txId] of this.connectionTransactions.entries()) {
4466
+ if (txId === transactionId) {
4467
+ this.connectionTransactions.delete(connection);
4468
+ break;
4469
+ }
4470
+ }
4471
+ }
4472
+ async executeBegin(connection, options) {
4473
+ const dbType = this.databaseService["config"].database.type;
4474
+ if (dbType === "sqlite") {
4475
+ await this.databaseService.query("BEGIN TRANSACTION");
4476
+ } else if (dbType === "postgres" || dbType === "mysql") {
4477
+ let sql = "START TRANSACTION";
4478
+ if (options.isolationLevel) {
4479
+ const isolation = this.getIsolationLevelSQL(options.isolationLevel);
4480
+ sql += ` ${isolation}`;
4481
+ }
4482
+ if (options.readOnly) {
4483
+ sql += " READ ONLY";
4484
+ }
4485
+ await this.databaseService.query(sql);
4486
+ }
4487
+ }
4488
+ async executeCommit(connection) {
4489
+ await this.databaseService.query("COMMIT");
4490
+ }
4491
+ async executeRollback(connection) {
4492
+ await this.databaseService.query("ROLLBACK");
4493
+ }
4494
+ async executeSavepoint(connection, savepointName) {
4495
+ await this.databaseService.query(`SAVEPOINT ${savepointName}`);
4496
+ }
4497
+ async executeRollbackToSavepoint(connection, savepointName) {
4498
+ await this.databaseService.query(`ROLLBACK TO SAVEPOINT ${savepointName}`);
4499
+ }
4500
+ getIsolationLevelSQL(level) {
4501
+ const dbType = this.databaseService["config"].database.type;
4502
+ const levelMap = {
4503
+ ["READ_UNCOMMITTED" /* READ_UNCOMMITTED */]: "READ UNCOMMITTED",
4504
+ ["READ_COMMITTED" /* READ_COMMITTED */]: "READ COMMITTED",
4505
+ ["REPEATABLE_READ" /* REPEATABLE_READ */]: "REPEATABLE READ",
4506
+ ["SERIALIZABLE" /* SERIALIZABLE */]: "SERIALIZABLE"
4507
+ };
4508
+ if (dbType === "postgres") {
4509
+ return `SET TRANSACTION ISOLATION LEVEL ${levelMap[level]}`;
4510
+ } else if (dbType === "mysql") {
4511
+ return `SET TRANSACTION ISOLATION LEVEL ${levelMap[level]}`;
4512
+ }
4513
+ return "";
4514
+ }
4515
+ }
4516
+ TransactionManager = __legacyDecorateClassTS([
4517
+ Injectable(),
4518
+ __legacyDecorateParamTS(0, Inject(DATABASE_SERVICE_TOKEN)),
4519
+ __legacyMetadataTS("design:paramtypes", [
4520
+ typeof DatabaseService === "undefined" ? Object : DatabaseService
4521
+ ])
4522
+ ], TransactionManager);
4523
+
4524
+ // src/database/connection-pool.ts
4525
+ class ConnectionPool {
4526
+ config;
4527
+ options;
4528
+ connections = [];
4529
+ pendingConnections = new Set;
4530
+ isClosing = false;
4531
+ constructor(config, options = {}) {
4532
+ this.config = config;
4533
+ this.options = {
4534
+ maxConnections: options.maxConnections ?? 10,
4535
+ connectionTimeout: options.connectionTimeout ?? 30000,
4536
+ retryCount: options.retryCount ?? 3,
4537
+ retryDelay: options.retryDelay ?? 1000
4538
+ };
4539
+ }
4540
+ async acquire() {
4541
+ if (this.isClosing) {
4542
+ throw new Error("Connection pool is closing");
4543
+ }
4544
+ const idleConnection = this.connections.find((conn) => !conn.inUse);
4545
+ if (idleConnection) {
4546
+ idleConnection.inUse = true;
4547
+ idleConnection.lastUsedAt = Date.now();
4548
+ return idleConnection.connection;
4549
+ }
4550
+ if (this.connections.length < this.options.maxConnections) {
4551
+ const connection = await this.createConnection();
4552
+ const poolConnection = {
4553
+ connection,
4554
+ inUse: true,
4555
+ createdAt: Date.now(),
4556
+ lastUsedAt: Date.now()
4557
+ };
4558
+ this.connections.push(poolConnection);
4559
+ return connection;
4560
+ }
4561
+ return await this.waitForConnection();
4562
+ }
4563
+ release(connection) {
4564
+ const poolConnection = this.connections.find((conn) => conn.connection === connection);
4565
+ if (poolConnection) {
4566
+ poolConnection.inUse = false;
4567
+ poolConnection.lastUsedAt = Date.now();
4568
+ }
4569
+ }
4570
+ async close() {
4571
+ this.isClosing = true;
4572
+ await Promise.all(Array.from(this.pendingConnections));
4573
+ const closePromises = this.connections.map((poolConnection) => this.closeConnection(poolConnection.connection));
4574
+ await Promise.all(closePromises);
4575
+ this.connections = [];
4576
+ this.isClosing = false;
4577
+ }
4578
+ getPoolStats() {
4579
+ const inUse = this.connections.filter((conn) => conn.inUse).length;
4580
+ return {
4581
+ total: this.connections.length,
4582
+ inUse,
4583
+ idle: this.connections.length - inUse,
4584
+ maxConnections: this.options.maxConnections
4585
+ };
4586
+ }
4587
+ async createConnection() {
4588
+ const createPromise = this.createConnectionWithRetry();
4589
+ this.pendingConnections.add(createPromise);
4590
+ try {
4591
+ const connection = await createPromise;
4592
+ return connection;
4593
+ } finally {
4594
+ this.pendingConnections.delete(createPromise);
4595
+ }
4596
+ }
4597
+ async createConnectionWithRetry() {
4598
+ let lastError;
4599
+ for (let i = 0;i <= this.options.retryCount; i++) {
4600
+ try {
4601
+ if (this.config.type === "sqlite") {
4602
+ return await this.createSqliteConnection(this.config.config);
4603
+ } else if (this.config.type === "postgres") {
4604
+ return await this.createPostgresConnection(this.config.config);
4605
+ } else if (this.config.type === "mysql") {
4606
+ return await this.createMysqlConnection(this.config.config);
4607
+ }
4608
+ } catch (error) {
4609
+ lastError = error instanceof Error ? error : new Error(String(error));
4610
+ if (i < this.options.retryCount) {
4611
+ await this.sleep(this.options.retryDelay);
4612
+ }
4613
+ }
4614
+ }
4615
+ throw lastError ?? new Error("Failed to create database connection");
4616
+ }
4617
+ async createSqliteConnection(config) {
4618
+ const { Database } = await import("bun:sqlite");
4619
+ const db = new Database(config.path);
4620
+ return db;
4621
+ }
4622
+ async createPostgresConnection(config) {
4623
+ const url = `postgres://${config.user}:${config.password}@${config.host}:${config.port}/${config.database}`;
4624
+ const { SQL } = await Promise.resolve(globalThis.Bun);
4625
+ return new SQL(url, {
4626
+ max: 1,
4627
+ tls: config.ssl ?? false
4628
+ });
4629
+ }
4630
+ async createMysqlConnection(config) {
4631
+ const url = `mysql://${config.user}:${config.password}@${config.host}:${config.port}/${config.database}`;
4632
+ const { SQL } = await Promise.resolve(globalThis.Bun);
4633
+ return new SQL(url, {
4634
+ max: 1
4635
+ });
4636
+ }
4637
+ async closeConnection(connection) {
4638
+ const dbType = this.config.type;
4639
+ if (dbType === "sqlite") {
4640
+ await this.closeSqliteConnection(connection);
4641
+ } else if (dbType === "postgres") {
4642
+ await this.closePostgresConnection(connection);
4643
+ } else if (dbType === "mysql") {
4644
+ await this.closeMysqlConnection(connection);
4645
+ }
4646
+ }
4647
+ async closeSqliteConnection(connection) {
4648
+ if (connection && typeof connection === "object" && "close" in connection && typeof connection.close === "function") {
4649
+ connection.close();
4650
+ }
4651
+ }
4652
+ async closePostgresConnection(_connection) {
4653
+ if (_connection && typeof _connection === "object" && "close" in _connection && typeof _connection.close === "function") {
4654
+ _connection.close();
4655
+ }
4656
+ }
4657
+ async closeMysqlConnection(_connection) {
4658
+ if (_connection && typeof _connection === "object" && "close" in _connection && typeof _connection.close === "function") {
4659
+ _connection.close();
4660
+ }
4661
+ }
4662
+ async waitForConnection() {
4663
+ const startTime = Date.now();
4664
+ const timeout = this.options.connectionTimeout;
4665
+ while (Date.now() - startTime < timeout) {
4666
+ const idleConnection = this.connections.find((conn) => !conn.inUse);
4667
+ if (idleConnection) {
4668
+ idleConnection.inUse = true;
4669
+ idleConnection.lastUsedAt = Date.now();
4670
+ return idleConnection.connection;
4671
+ }
4672
+ await this.sleep(100);
4673
+ }
4674
+ throw new Error(`Connection timeout: No available connection within ${timeout}ms`);
4675
+ }
4676
+ sleep(ms) {
4677
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
4678
+ }
4679
+ }
4680
+
4681
+ // src/database/connection-manager.ts
4682
+ class DatabaseConnectionManager {
4683
+ config;
4684
+ poolOptions;
4685
+ pool;
4686
+ currentConnection = null;
4687
+ status = "disconnected";
4688
+ error;
4689
+ constructor(config, poolOptions = {}) {
4690
+ this.config = config;
4691
+ this.poolOptions = {
4692
+ maxConnections: poolOptions.maxConnections ?? 10,
4693
+ connectionTimeout: poolOptions.connectionTimeout ?? 30000,
4694
+ retryCount: poolOptions.retryCount ?? 3,
4695
+ retryDelay: poolOptions.retryDelay ?? 1000
4696
+ };
4697
+ this.pool = new ConnectionPool(config, this.poolOptions);
4698
+ }
4699
+ async connect() {
4700
+ if (this.status === "connected") {
4701
+ return;
4702
+ }
4703
+ this.status = "connecting";
4704
+ try {
4705
+ this.currentConnection = await this.pool.acquire();
4706
+ this.status = "connected";
4707
+ this.error = undefined;
4708
+ } catch (error) {
4709
+ this.status = "error";
4710
+ this.error = error instanceof Error ? error.message : String(error);
4711
+ throw error;
4712
+ }
4713
+ }
4714
+ async disconnect() {
4715
+ if (this.status === "disconnected" || !this.currentConnection) {
4716
+ return;
4717
+ }
4718
+ try {
4719
+ this.pool.release(this.currentConnection);
4720
+ this.currentConnection = null;
4721
+ this.status = "disconnected";
4722
+ this.error = undefined;
4723
+ } catch (error) {
4724
+ this.status = "error";
4725
+ this.error = error instanceof Error ? error.message : String(error);
4726
+ throw error;
4727
+ }
4728
+ }
4729
+ async closePool() {
4730
+ await this.pool.close();
4731
+ this.currentConnection = null;
4732
+ this.status = "disconnected";
4733
+ this.error = undefined;
4734
+ }
4735
+ async healthCheck() {
4736
+ if (this.status !== "connected" || !this.currentConnection) {
4737
+ return false;
4738
+ }
4739
+ try {
4740
+ if (this.config.type === "sqlite") {
4741
+ return await this.healthCheckSqlite(this.currentConnection);
4742
+ } else if (this.config.type === "postgres") {
4743
+ return await this.healthCheckPostgres(this.currentConnection);
4744
+ } else if (this.config.type === "mysql") {
4745
+ return await this.healthCheckMysql(this.currentConnection);
4746
+ }
4747
+ return false;
4748
+ } catch {
4749
+ return false;
4750
+ }
4751
+ }
4752
+ getPoolStats() {
4753
+ return this.pool.getPoolStats();
4754
+ }
4755
+ getConnectionInfo() {
4756
+ return {
4757
+ status: this.status,
4758
+ type: this.config.type,
4759
+ error: this.error
4760
+ };
4761
+ }
4762
+ getConnection() {
4763
+ return this.currentConnection;
4764
+ }
4765
+ async acquireConnection() {
4766
+ return await this.pool.acquire();
4767
+ }
4768
+ releaseConnection(connection) {
4769
+ this.pool.release(connection);
4770
+ }
4771
+ getDatabaseType() {
4772
+ return this.config.type;
4773
+ }
4774
+ async healthCheckSqlite(connection) {
4775
+ try {
4776
+ if (connection && typeof connection === "object" && "query" in connection && typeof connection.query === "function") {
4777
+ const db = connection;
4778
+ db.query("SELECT 1").all();
4779
+ return true;
4780
+ }
4781
+ return false;
4782
+ } catch {
4783
+ return false;
4784
+ }
4785
+ }
4786
+ async healthCheckPostgres(connection) {
4787
+ try {
4788
+ if (connection && typeof connection === "function") {
4789
+ const result = await connection`SELECT 1`;
4790
+ return Array.isArray(result) && result.length > 0;
4791
+ }
4792
+ if (connection && typeof connection === "object" && "query" in connection && typeof connection.query === "function") {
4793
+ await connection.query("SELECT 1");
4794
+ return true;
4795
+ }
4796
+ return false;
4797
+ } catch {
4798
+ return false;
4799
+ }
4800
+ }
4801
+ async healthCheckMysql(connection) {
4802
+ try {
4803
+ if (connection && typeof connection === "function") {
4804
+ const result = await connection`SELECT 1`;
4805
+ return Array.isArray(result) && result.length > 0;
4806
+ }
4807
+ if (connection && typeof connection === "object" && "query" in connection && typeof connection.query === "function") {
4808
+ await connection.query("SELECT 1");
4809
+ return true;
4810
+ }
4811
+ return false;
4812
+ } catch {
4813
+ return false;
4814
+ }
4815
+ }
4816
+ }
4817
+
4818
+ // src/database/service.ts
4819
+ class DatabaseService2 {
4820
+ connectionManager;
4821
+ options;
4822
+ constructor(options) {
4823
+ this.options = options;
4824
+ this.connectionManager = new DatabaseConnectionManager(options.database, options.pool);
4825
+ }
4826
+ async initialize() {
4827
+ await this.connectionManager.connect();
4828
+ }
4829
+ async close() {
4830
+ await this.connectionManager.disconnect();
4831
+ }
4832
+ async closePool() {
4833
+ await this.connectionManager.closePool();
4834
+ }
4835
+ getPoolStats() {
4836
+ return this.connectionManager.getPoolStats();
4837
+ }
4838
+ getConnection() {
4839
+ return this.connectionManager.getConnection();
4840
+ }
4841
+ get config() {
4842
+ return this.options;
4843
+ }
4844
+ getDatabaseType() {
4845
+ return this.connectionManager.getDatabaseType();
4846
+ }
4847
+ async healthCheck() {
4848
+ if (!this.options.enableHealthCheck) {
4849
+ return true;
4850
+ }
4851
+ return await this.connectionManager.healthCheck();
4852
+ }
4853
+ getConnectionInfo() {
4854
+ return this.connectionManager.getConnectionInfo();
4855
+ }
4856
+ query(sql, params) {
4857
+ const connection = this.getConnection();
4858
+ if (!connection) {
4859
+ throw new Error("Database connection is not established");
4860
+ }
4861
+ const dbType = this.getDatabaseType();
4862
+ if (dbType === "sqlite") {
4863
+ return this.querySqlite(connection, sql, params);
4864
+ } else if (dbType === "postgres" || dbType === "mysql") {
4865
+ return this.queryBunSQL(connection, sql, params);
4866
+ }
4867
+ throw new Error(`Query not supported for database type: ${dbType}`);
4868
+ }
4869
+ querySqlite(connection, sql, params) {
4870
+ if (connection && typeof connection === "object" && "query" in connection && typeof connection.query === "function") {
4871
+ const db = connection;
4872
+ const statement = db.query(sql);
4873
+ const result = params && params.length > 0 ? statement.all(...params) : statement.all();
4874
+ return result;
4875
+ }
4876
+ throw new Error("Invalid SQLite connection");
4877
+ }
4878
+ async queryBunSQL(connection, sql, params) {
4879
+ if (connection && typeof connection === "function") {
4880
+ try {
4881
+ const sqlWithParams = this.interpolateParams(sql, params);
4882
+ const result = await connection`${sqlWithParams}`;
4883
+ return result;
4884
+ } catch {
4885
+ throw new Error("Bun.SQL parameterized queries are not fully supported. Consider using template string queries.");
4886
+ }
4887
+ }
4888
+ if (connection && typeof connection === "object" && "query" in connection && typeof connection.query === "function") {
4889
+ const db = connection;
4890
+ const result = await db.query(sql, ...params ?? []);
4891
+ return result;
4892
+ }
4893
+ throw new Error("Invalid Bun.SQL connection");
4894
+ }
4895
+ interpolateParams(sql, params) {
4896
+ if (!params || params.length === 0) {
4897
+ return sql;
4898
+ }
4899
+ let result = sql;
4900
+ for (let i = 0;i < params.length; i++) {
4901
+ const param = params[i];
4902
+ const value = typeof param === "string" ? `'${param.replace(/'/g, "''")}'` : String(param);
4903
+ result = result.replace("?", value);
4904
+ }
4905
+ return result;
4906
+ }
4907
+ }
4908
+ DatabaseService2 = __legacyDecorateClassTS([
4909
+ Injectable(),
4910
+ __legacyMetadataTS("design:paramtypes", [
4911
+ typeof DatabaseModuleOptions === "undefined" ? Object : DatabaseModuleOptions
4912
+ ])
4913
+ ], DatabaseService2);
4914
+
4915
+ // src/database/orm/types.ts
4916
+ var ORM_SERVICE_TOKEN = Symbol("@dangao/bun-server:orm:service");
4917
+
4918
+ // src/database/database-module.ts
4919
+ init_transaction_types();
4920
+ class DatabaseModule {
4921
+ static forRoot(options) {
4922
+ const providers2 = [];
4923
+ const service = new DatabaseService2(options);
4924
+ providers2.push({
4925
+ provide: DATABASE_SERVICE_TOKEN,
4926
+ useValue: service
4927
+ }, {
4928
+ provide: DATABASE_OPTIONS_TOKEN,
4929
+ useValue: options
4930
+ }, DatabaseService2);
4931
+ if (options.orm?.enabled) {
4932
+ const ormService = new OrmService(service, {
4933
+ enabled: true,
4934
+ drizzle: options.orm.drizzle,
4935
+ databaseService: service
4936
+ });
4937
+ providers2.push({
4938
+ provide: ORM_SERVICE_TOKEN,
4939
+ useValue: ormService
4940
+ }, OrmService);
4941
+ }
4942
+ const transactionManager = new TransactionManager(service);
4943
+ providers2.push({
4944
+ provide: TRANSACTION_SERVICE_TOKEN,
4945
+ useValue: transactionManager
4946
+ }, TransactionManager);
4947
+ const existingMetadata = Reflect.getMetadata(MODULE_METADATA_KEY, DatabaseModule) || {};
4948
+ const databaseExtension = new DatabaseExtension;
4949
+ const metadata = {
4950
+ ...existingMetadata,
4951
+ providers: [...existingMetadata.providers || [], ...providers2],
4952
+ exports: [
4953
+ ...existingMetadata.exports || [],
4954
+ DATABASE_SERVICE_TOKEN,
4955
+ DATABASE_OPTIONS_TOKEN,
4956
+ DatabaseService2,
4957
+ TRANSACTION_SERVICE_TOKEN,
4958
+ TransactionManager,
4959
+ ...options.orm?.enabled ? [ORM_SERVICE_TOKEN, OrmService] : []
4960
+ ],
4961
+ extensions: [
4962
+ ...existingMetadata.extensions || [],
4963
+ databaseExtension
4964
+ ]
4965
+ };
4966
+ Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, DatabaseModule);
4967
+ return DatabaseModule;
4968
+ }
4969
+ static createHealthIndicator(databaseService) {
4970
+ return new DatabaseHealthIndicator(databaseService);
4971
+ }
4972
+ }
4973
+ DatabaseModule = __legacyDecorateClassTS([
4974
+ Module({
4975
+ providers: []
4976
+ })
4977
+ ], DatabaseModule);
4978
+ // src/database/orm/decorators.ts
4979
+ import"reflect-metadata";
4980
+ var ENTITY_METADATA_KEY = Symbol("@dangao/bun-server:orm:entity");
4981
+ var COLUMN_METADATA_KEY = Symbol("@dangao/bun-server:orm:column");
4982
+ function Entity(tableName) {
4983
+ return (target) => {
4984
+ Reflect.defineMetadata(ENTITY_METADATA_KEY, { tableName }, target);
4985
+ };
4986
+ }
4987
+ function Column(options) {
4988
+ return (target, propertyKey) => {
4989
+ const existingColumns = Reflect.getMetadata(COLUMN_METADATA_KEY, target.constructor) || [];
4990
+ const existingIndex = existingColumns.findIndex((col) => col.propertyKey === String(propertyKey));
4991
+ const columnDef = {
4992
+ name: options?.name ?? String(propertyKey),
4993
+ type: options?.type ?? "TEXT",
4994
+ primaryKey: options?.primaryKey ?? false,
4995
+ autoIncrement: options?.autoIncrement ?? false,
4996
+ nullable: options?.nullable !== undefined ? options.nullable : true,
4997
+ defaultValue: options?.defaultValue,
4998
+ propertyKey: String(propertyKey)
4999
+ };
5000
+ if (existingIndex >= 0) {
5001
+ const existing = existingColumns[existingIndex];
5002
+ existingColumns[existingIndex] = {
5003
+ ...existing,
5004
+ name: options?.name ?? existing.name,
5005
+ type: options?.type ?? existing.type,
5006
+ primaryKey: options?.primaryKey !== undefined ? options.primaryKey : existing.primaryKey,
5007
+ nullable: options?.nullable !== undefined ? options.nullable : existing.nullable,
5008
+ autoIncrement: options?.autoIncrement !== undefined ? options.autoIncrement : existing.autoIncrement,
5009
+ defaultValue: options?.defaultValue !== undefined ? options.defaultValue : existing.defaultValue,
5010
+ propertyKey: String(propertyKey)
5011
+ };
5012
+ } else {
5013
+ existingColumns.push(columnDef);
5014
+ }
5015
+ Reflect.defineMetadata(COLUMN_METADATA_KEY, existingColumns, target.constructor);
5016
+ };
5017
+ }
5018
+ function PrimaryKey() {
5019
+ return Column({ primaryKey: true, nullable: false });
5020
+ }
5021
+ function getEntityMetadata(target) {
5022
+ if (typeof target === "function" || typeof target === "object" && target !== null) {
5023
+ return Reflect.getMetadata(ENTITY_METADATA_KEY, target);
5024
+ }
5025
+ return;
5026
+ }
5027
+ function getColumnMetadata(target) {
5028
+ if (typeof target === "function" || typeof target === "object" && target !== null) {
5029
+ return Reflect.getMetadata(COLUMN_METADATA_KEY, target) || [];
5030
+ }
5031
+ return [];
5032
+ }
5033
+ // src/database/orm/repository-decorator.ts
5034
+ import"reflect-metadata";
5035
+ var REPOSITORY_METADATA_KEY = Symbol("@dangao/bun-server:orm:repository");
5036
+ function Repository(tableName, primaryKey = "id") {
5037
+ return function(target) {
5038
+ Injectable()(target);
5039
+ Reflect.defineMetadata(REPOSITORY_METADATA_KEY, { tableName, primaryKey }, target);
5040
+ return target;
5041
+ };
5042
+ }
5043
+ function getRepositoryMetadata(target) {
5044
+ if (typeof target === "function" || typeof target === "object" && target !== null) {
5045
+ return Reflect.getMetadata(REPOSITORY_METADATA_KEY, target);
5046
+ }
5047
+ return;
5048
+ }
5049
+
5050
+ // src/database/orm/index.ts
5051
+ init_transaction_decorator();
5052
+
5053
+ // src/database/orm/repository.ts
5054
+ class BaseRepository {
5055
+ databaseService;
5056
+ constructor(databaseService) {
5057
+ this.databaseService = databaseService;
5058
+ }
5059
+ async findAll() {
5060
+ const sql = `SELECT * FROM ${this.tableName}`;
5061
+ const result = await this.executeQuery(sql);
5062
+ return Array.isArray(result) ? result : [];
5063
+ }
5064
+ async findById(id) {
5065
+ const sql = `SELECT * FROM ${this.tableName} WHERE ${this.primaryKey} = ?`;
5066
+ const result = await this.executeQuery(sql, [id]);
5067
+ if (Array.isArray(result) && result.length > 0) {
5068
+ return result[0];
5069
+ }
5070
+ return null;
5071
+ }
5072
+ async create(data) {
5073
+ const keys = Object.keys(data);
5074
+ const values = Object.values(data);
5075
+ const placeholders = keys.map(() => "?").join(", ");
5076
+ const sql = `INSERT INTO ${this.tableName} (${keys.join(", ")}) VALUES (${placeholders})`;
5077
+ await this.executeQuery(sql, values);
5078
+ const lastIdResult = await this.executeQuery("SELECT last_insert_rowid() as id");
5079
+ const lastId = Array.isArray(lastIdResult) && lastIdResult[0] ? lastIdResult[0].id : null;
5080
+ if (lastId !== null) {
5081
+ return await this.findById(lastId);
5082
+ }
5083
+ return data;
5084
+ }
5085
+ async update(id, data) {
5086
+ const keys = Object.keys(data);
5087
+ const values = Object.values(data);
5088
+ const setClause = keys.map((key) => `${key} = ?`).join(", ");
5089
+ const sql = `UPDATE ${this.tableName} SET ${setClause} WHERE ${this.primaryKey} = ?`;
5090
+ await this.executeQuery(sql, [...values, id]);
5091
+ return await this.findById(id);
5092
+ }
5093
+ async delete(id) {
5094
+ const sql = `DELETE FROM ${this.tableName} WHERE ${this.primaryKey} = ?`;
5095
+ await this.executeQuery(sql, [id]);
5096
+ return true;
5097
+ }
5098
+ async executeQuery(sql, params) {
5099
+ const result = this.databaseService.query(sql, params);
5100
+ if (result instanceof Promise) {
5101
+ const resolved = await result;
5102
+ return Array.isArray(resolved) ? resolved : [resolved];
5103
+ }
5104
+ return Array.isArray(result) ? result : [result];
5105
+ }
5106
+ }
5107
+ BaseRepository = __legacyDecorateClassTS([
5108
+ __legacyDecorateParamTS(0, Inject(DATABASE_SERVICE_TOKEN)),
5109
+ __legacyMetadataTS("design:paramtypes", [
5110
+ typeof DatabaseService === "undefined" ? Object : DatabaseService
5111
+ ])
5112
+ ], BaseRepository);
5113
+ // src/database/orm/drizzle-repository.ts
5114
+ class DrizzleBaseRepository {
5115
+ databaseService;
5116
+ constructor(databaseService) {
5117
+ this.databaseService = databaseService;
5118
+ }
5119
+ }
5120
+
5121
+ // src/database/orm/index.ts
5122
+ init_transaction_interceptor();
5123
+ init_transaction_types();
3492
5124
  // src/testing/harness.ts
3493
5125
  import { performance as performance2 } from "perf_hooks";
3494
5126
 
@@ -3551,12 +5183,20 @@ class StressTester {
3551
5183
  }
3552
5184
  export {
3553
5185
  requiresAuth,
5186
+ getTransactionMetadata,
5187
+ getRepositoryMetadata,
5188
+ getEntityMetadata,
5189
+ getColumnMetadata,
3554
5190
  getAuthMetadata,
5191
+ createUserKeyGenerator,
5192
+ createTokenKeyGenerator,
3555
5193
  createSwaggerUIMiddleware,
3556
5194
  createStaticFileMiddleware,
3557
5195
  createSecurityFilter,
3558
5196
  createRequestLoggingMiddleware,
5197
+ createRateLimitMiddleware,
3559
5198
  createLoggerMiddleware,
5199
+ createHttpMetricsMiddleware,
3560
5200
  createFileUploadMiddleware,
3561
5201
  createErrorHandlingMiddleware,
3562
5202
  createCorsMiddleware,
@@ -3567,6 +5207,11 @@ export {
3567
5207
  Validate,
3568
5208
  UseMiddleware,
3569
5209
  UnauthorizedException,
5210
+ Transactional,
5211
+ TransactionStatus,
5212
+ TransactionManager,
5213
+ TransactionInterceptor,
5214
+ TRANSACTION_SERVICE_TOKEN,
3570
5215
  SwaggerModule,
3571
5216
  SwaggerGenerator,
3572
5217
  SwaggerExtension,
@@ -3579,16 +5224,23 @@ export {
3579
5224
  RoleBasedAccessDecisionManager,
3580
5225
  ResponseBuilder,
3581
5226
  RequestWrapper,
5227
+ Repository,
5228
+ RateLimit,
3582
5229
  Query,
5230
+ Propagation,
5231
+ PrometheusFormatter,
5232
+ PrimaryKey,
3583
5233
  PerformanceHarness,
3584
5234
  ParamBinder,
3585
5235
  Param,
3586
5236
  PUT,
3587
5237
  POST,
3588
5238
  PATCH,
5239
+ OrmService,
3589
5240
  OnOpen,
3590
5241
  OnMessage,
3591
5242
  OnClose,
5243
+ ORM_SERVICE_TOKEN,
3592
5244
  OAuth2Service,
3593
5245
  OAuth2Controller,
3594
5246
  OAuth2AuthenticationProvider,
@@ -3598,6 +5250,10 @@ export {
3598
5250
  Module,
3599
5251
  MinLength,
3600
5252
  MiddlewarePipeline,
5253
+ MetricsModule,
5254
+ MetricsCollector,
5255
+ METRICS_SERVICE_TOKEN,
5256
+ METRICS_OPTIONS_TOKEN,
3601
5257
  LoggerModule,
3602
5258
  LoggerExtension,
3603
5259
  LogLevel2 as LogLevel,
@@ -3606,6 +5262,7 @@ export {
3606
5262
  JwtAuthenticationProvider,
3607
5263
  JWT_UTIL_TOKEN,
3608
5264
  JWTUtil,
5265
+ IsolationLevel,
3609
5266
  IsString,
3610
5267
  IsOptional,
3611
5268
  IsNumber,
@@ -3621,17 +5278,29 @@ export {
3621
5278
  GET,
3622
5279
  ForbiddenException,
3623
5280
  ExceptionFilterRegistry,
5281
+ Entity,
5282
+ DrizzleBaseRepository,
5283
+ DatabaseService2 as DatabaseService,
5284
+ DatabaseModule,
5285
+ DatabaseHealthIndicator,
5286
+ DatabaseExtension,
5287
+ DatabaseConnectionManager,
3624
5288
  DELETE,
5289
+ DATABASE_SERVICE_TOKEN,
5290
+ DATABASE_OPTIONS_TOKEN,
3625
5291
  ControllerRegistry,
3626
5292
  Controller,
3627
5293
  Context,
3628
5294
  Container,
5295
+ ConnectionPool,
3629
5296
  ConfigService,
3630
5297
  ConfigModule,
5298
+ Column,
3631
5299
  CONFIG_SERVICE_TOKEN,
3632
5300
  BunServer,
3633
5301
  BodyParser,
3634
5302
  Body,
5303
+ BaseRepository,
3635
5304
  BadRequestException,
3636
5305
  AuthenticationManager,
3637
5306
  Auth,