@dangao/bun-server 0.3.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 (56) 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/database/connection-manager.d.ts +72 -0
  7. package/dist/database/connection-manager.d.ts.map +1 -0
  8. package/dist/database/connection-pool.d.ts +79 -0
  9. package/dist/database/connection-pool.d.ts.map +1 -0
  10. package/dist/database/database-extension.d.ts +20 -0
  11. package/dist/database/database-extension.d.ts.map +1 -0
  12. package/dist/database/database-module.d.ts +18 -0
  13. package/dist/database/database-module.d.ts.map +1 -0
  14. package/dist/database/health-indicator.d.ts +15 -0
  15. package/dist/database/health-indicator.d.ts.map +1 -0
  16. package/dist/database/index.d.ts +9 -0
  17. package/dist/database/index.d.ts.map +1 -0
  18. package/dist/database/orm/decorators.d.ts +70 -0
  19. package/dist/database/orm/decorators.d.ts.map +1 -0
  20. package/dist/database/orm/drizzle-repository.d.ts +34 -0
  21. package/dist/database/orm/drizzle-repository.d.ts.map +1 -0
  22. package/dist/database/orm/index.d.ts +11 -0
  23. package/dist/database/orm/index.d.ts.map +1 -0
  24. package/dist/database/orm/repository-decorator.d.ts +21 -0
  25. package/dist/database/orm/repository-decorator.d.ts.map +1 -0
  26. package/dist/database/orm/repository.d.ts +36 -0
  27. package/dist/database/orm/repository.d.ts.map +1 -0
  28. package/dist/database/orm/service.d.ts +26 -0
  29. package/dist/database/orm/service.d.ts.map +1 -0
  30. package/dist/database/orm/transaction-decorator.d.ts +17 -0
  31. package/dist/database/orm/transaction-decorator.d.ts.map +1 -0
  32. package/dist/database/orm/transaction-interceptor.d.ts +28 -0
  33. package/dist/database/orm/transaction-interceptor.d.ts.map +1 -0
  34. package/dist/database/orm/transaction-manager.d.ts +77 -0
  35. package/dist/database/orm/transaction-manager.d.ts.map +1 -0
  36. package/dist/database/orm/transaction-types.d.ts +136 -0
  37. package/dist/database/orm/transaction-types.d.ts.map +1 -0
  38. package/dist/database/orm/types.d.ts +95 -0
  39. package/dist/database/orm/types.d.ts.map +1 -0
  40. package/dist/database/service.d.ts +71 -0
  41. package/dist/database/service.d.ts.map +1 -0
  42. package/dist/database/types.d.ts +168 -0
  43. package/dist/database/types.d.ts.map +1 -0
  44. package/dist/error/error-codes.d.ts +49 -3
  45. package/dist/error/error-codes.d.ts.map +1 -1
  46. package/dist/error/handler.d.ts.map +1 -1
  47. package/dist/error/http-exception.d.ts +26 -7
  48. package/dist/error/http-exception.d.ts.map +1 -1
  49. package/dist/error/i18n.d.ts +46 -2
  50. package/dist/error/i18n.d.ts.map +1 -1
  51. package/dist/error/index.d.ts +1 -1
  52. package/dist/error/index.d.ts.map +1 -1
  53. package/dist/index.d.ts +1 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +1281 -36
  56. package/package.json +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) {
@@ -1813,7 +2129,19 @@ class ControllerRegistry {
1813
2129
  if (!method || typeof method !== "function") {
1814
2130
  throw new Error(`Method ${propertyKey} not found on controller ${controllerClass.name}`);
1815
2131
  }
1816
- 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
+ }
1817
2145
  const responseData = await Promise.resolve(result);
1818
2146
  if (responseData instanceof Response) {
1819
2147
  return responseData;
@@ -2174,10 +2502,11 @@ class Application {
2174
2502
  use(middleware) {
2175
2503
  this.middlewarePipeline.use(middleware);
2176
2504
  }
2177
- listen(port, hostname) {
2505
+ async listen(port, hostname) {
2178
2506
  if (this.server?.isRunning()) {
2179
2507
  throw new Error("Application is already running");
2180
2508
  }
2509
+ await this.initializeExtensions();
2181
2510
  const serverOptions = {
2182
2511
  port: port ?? this.options.port ?? 3000,
2183
2512
  hostname: hostname ?? this.options.hostname,
@@ -2187,9 +2516,27 @@ class Application {
2187
2516
  this.server = new BunServer(serverOptions);
2188
2517
  this.server.start();
2189
2518
  }
2190
- 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();
2191
2529
  this.server?.stop();
2192
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
+ }
2193
2540
  async handleRequest(context) {
2194
2541
  if (["POST", "PUT", "PATCH"].includes(context.method)) {
2195
2542
  await context.getBody();
@@ -3245,19 +3592,19 @@ class OAuth2Controller {
3245
3592
  constructor(oauth2Service) {
3246
3593
  this.oauth2Service = oauth2Service;
3247
3594
  }
3248
- authorize(clientId, redirectUri, state, scope) {
3249
- const query = {
3250
- client_id: clientId,
3251
- redirect_uri: redirectUri,
3252
- ...state && { state },
3253
- ...scope && { scope }
3254
- };
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
+ }
3255
3602
  const request = {
3256
- clientId: query.client_id || "",
3257
- redirectUri: query.redirect_uri || "",
3603
+ clientId,
3604
+ redirectUri,
3258
3605
  responseType: "code",
3259
- scope: query.scope,
3260
- state: query.state
3606
+ scope: scope || undefined,
3607
+ state: state || undefined
3261
3608
  };
3262
3609
  const validation = this.oauth2Service.validateAuthorizationRequest(request);
3263
3610
  if (!validation.valid) {
@@ -3318,13 +3665,15 @@ __legacyDecorateClassTS([
3318
3665
  GET("/authorize"),
3319
3666
  __legacyDecorateParamTS(0, Query("client_id")),
3320
3667
  __legacyDecorateParamTS(1, Query("redirect_uri")),
3321
- __legacyDecorateParamTS(2, Query("state")),
3322
- __legacyDecorateParamTS(3, Query("scope")),
3668
+ __legacyDecorateParamTS(2, Query("response_type")),
3669
+ __legacyDecorateParamTS(3, Query("state")),
3670
+ __legacyDecorateParamTS(4, Query("scope")),
3323
3671
  __legacyMetadataTS("design:type", Function),
3324
3672
  __legacyMetadataTS("design:paramtypes", [
3325
3673
  String,
3326
3674
  String,
3327
3675
  String,
3676
+ String,
3328
3677
  String
3329
3678
  ]),
3330
3679
  __legacyMetadataTS("design:returntype", undefined)
@@ -3903,6 +4252,875 @@ function createHttpMetricsMiddleware(collector) {
3903
4252
  return response;
3904
4253
  };
3905
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();
3906
5124
  // src/testing/harness.ts
3907
5125
  import { performance as performance2 } from "perf_hooks";
3908
5126
 
@@ -3965,6 +5183,10 @@ class StressTester {
3965
5183
  }
3966
5184
  export {
3967
5185
  requiresAuth,
5186
+ getTransactionMetadata,
5187
+ getRepositoryMetadata,
5188
+ getEntityMetadata,
5189
+ getColumnMetadata,
3968
5190
  getAuthMetadata,
3969
5191
  createUserKeyGenerator,
3970
5192
  createTokenKeyGenerator,
@@ -3985,6 +5207,11 @@ export {
3985
5207
  Validate,
3986
5208
  UseMiddleware,
3987
5209
  UnauthorizedException,
5210
+ Transactional,
5211
+ TransactionStatus,
5212
+ TransactionManager,
5213
+ TransactionInterceptor,
5214
+ TRANSACTION_SERVICE_TOKEN,
3988
5215
  SwaggerModule,
3989
5216
  SwaggerGenerator,
3990
5217
  SwaggerExtension,
@@ -3997,18 +5224,23 @@ export {
3997
5224
  RoleBasedAccessDecisionManager,
3998
5225
  ResponseBuilder,
3999
5226
  RequestWrapper,
5227
+ Repository,
4000
5228
  RateLimit,
4001
5229
  Query,
5230
+ Propagation,
4002
5231
  PrometheusFormatter,
5232
+ PrimaryKey,
4003
5233
  PerformanceHarness,
4004
5234
  ParamBinder,
4005
5235
  Param,
4006
5236
  PUT,
4007
5237
  POST,
4008
5238
  PATCH,
5239
+ OrmService,
4009
5240
  OnOpen,
4010
5241
  OnMessage,
4011
5242
  OnClose,
5243
+ ORM_SERVICE_TOKEN,
4012
5244
  OAuth2Service,
4013
5245
  OAuth2Controller,
4014
5246
  OAuth2AuthenticationProvider,
@@ -4030,6 +5262,7 @@ export {
4030
5262
  JwtAuthenticationProvider,
4031
5263
  JWT_UTIL_TOKEN,
4032
5264
  JWTUtil,
5265
+ IsolationLevel,
4033
5266
  IsString,
4034
5267
  IsOptional,
4035
5268
  IsNumber,
@@ -4045,17 +5278,29 @@ export {
4045
5278
  GET,
4046
5279
  ForbiddenException,
4047
5280
  ExceptionFilterRegistry,
5281
+ Entity,
5282
+ DrizzleBaseRepository,
5283
+ DatabaseService2 as DatabaseService,
5284
+ DatabaseModule,
5285
+ DatabaseHealthIndicator,
5286
+ DatabaseExtension,
5287
+ DatabaseConnectionManager,
4048
5288
  DELETE,
5289
+ DATABASE_SERVICE_TOKEN,
5290
+ DATABASE_OPTIONS_TOKEN,
4049
5291
  ControllerRegistry,
4050
5292
  Controller,
4051
5293
  Context,
4052
5294
  Container,
5295
+ ConnectionPool,
4053
5296
  ConfigService,
4054
5297
  ConfigModule,
5298
+ Column,
4055
5299
  CONFIG_SERVICE_TOKEN,
4056
5300
  BunServer,
4057
5301
  BodyParser,
4058
5302
  Body,
5303
+ BaseRepository,
4059
5304
  BadRequestException,
4060
5305
  AuthenticationManager,
4061
5306
  Auth,