@dangao/bun-server 3.1.0 → 3.3.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 (161) hide show
  1. package/dist/ai/types.d.ts +4 -0
  2. package/dist/ai/types.d.ts.map +1 -1
  3. package/dist/auth/types.d.ts +4 -0
  4. package/dist/auth/types.d.ts.map +1 -1
  5. package/dist/cache/interceptors.d.ts +3 -3
  6. package/dist/cache/interceptors.d.ts.map +1 -1
  7. package/dist/cache/service.d.ts +6 -6
  8. package/dist/cache/service.d.ts.map +1 -1
  9. package/dist/cache/types.d.ts +12 -12
  10. package/dist/cache/types.d.ts.map +1 -1
  11. package/dist/config/service.d.ts +6 -4
  12. package/dist/config/service.d.ts.map +1 -1
  13. package/dist/core/application.d.ts +4 -0
  14. package/dist/core/application.d.ts.map +1 -1
  15. package/dist/core/context.d.ts +4 -2
  16. package/dist/core/context.d.ts.map +1 -1
  17. package/dist/database/connection-manager.d.ts +2 -2
  18. package/dist/database/connection-manager.d.ts.map +1 -1
  19. package/dist/database/connection-pool.d.ts +4 -4
  20. package/dist/database/connection-pool.d.ts.map +1 -1
  21. package/dist/database/database-module.d.ts.map +1 -1
  22. package/dist/database/db-proxy.d.ts.map +1 -1
  23. package/dist/database/driver.d.ts +83 -0
  24. package/dist/database/driver.d.ts.map +1 -0
  25. package/dist/database/index.d.ts +2 -1
  26. package/dist/database/index.d.ts.map +1 -1
  27. package/dist/database/service.d.ts +0 -10
  28. package/dist/database/service.d.ts.map +1 -1
  29. package/dist/database/sql-manager.d.ts.map +1 -1
  30. package/dist/database/sqlite-adapter.d.ts +4 -2
  31. package/dist/database/sqlite-adapter.d.ts.map +1 -1
  32. package/dist/database/types.d.ts +26 -0
  33. package/dist/database/types.d.ts.map +1 -1
  34. package/dist/di/container.d.ts +2 -0
  35. package/dist/di/container.d.ts.map +1 -1
  36. package/dist/di/module-registry.d.ts.map +1 -1
  37. package/dist/di/module.d.ts +11 -1
  38. package/dist/di/module.d.ts.map +1 -1
  39. package/dist/di/types.d.ts +1 -1
  40. package/dist/di/types.d.ts.map +1 -1
  41. package/dist/error/handler.d.ts.map +1 -1
  42. package/dist/error/http-exception.d.ts +8 -8
  43. package/dist/error/http-exception.d.ts.map +1 -1
  44. package/dist/error/index.d.ts +1 -0
  45. package/dist/error/index.d.ts.map +1 -1
  46. package/dist/events/service.d.ts +2 -2
  47. package/dist/events/service.d.ts.map +1 -1
  48. package/dist/events/types.d.ts +12 -3
  49. package/dist/events/types.d.ts.map +1 -1
  50. package/dist/index.js +5951 -5820
  51. package/dist/index.node.mjs +310 -139
  52. package/dist/interceptor/base-interceptor.d.ts +3 -3
  53. package/dist/interceptor/base-interceptor.d.ts.map +1 -1
  54. package/dist/interceptor/builtin/log-interceptor.d.ts +1 -1
  55. package/dist/interceptor/builtin/log-interceptor.d.ts.map +1 -1
  56. package/dist/interceptor/builtin/permission-interceptor.d.ts +1 -1
  57. package/dist/interceptor/builtin/permission-interceptor.d.ts.map +1 -1
  58. package/dist/interceptor/interceptor-chain.d.ts +1 -1
  59. package/dist/interceptor/interceptor-chain.d.ts.map +1 -1
  60. package/dist/interceptor/interceptor-registry.d.ts +3 -1
  61. package/dist/interceptor/interceptor-registry.d.ts.map +1 -1
  62. package/dist/interceptor/types.d.ts +6 -1
  63. package/dist/interceptor/types.d.ts.map +1 -1
  64. package/dist/microservice/service-client/types.d.ts +1 -0
  65. package/dist/microservice/service-client/types.d.ts.map +1 -1
  66. package/dist/microservice/tracing/tracer.d.ts +1 -0
  67. package/dist/microservice/tracing/tracer.d.ts.map +1 -1
  68. package/dist/middleware/builtin/file-upload.d.ts +2 -0
  69. package/dist/middleware/builtin/file-upload.d.ts.map +1 -1
  70. package/dist/middleware/builtin/rate-limit.d.ts +9 -1
  71. package/dist/middleware/builtin/rate-limit.d.ts.map +1 -1
  72. package/dist/queue/service.d.ts +2 -2
  73. package/dist/queue/service.d.ts.map +1 -1
  74. package/dist/queue/types.d.ts +25 -1
  75. package/dist/queue/types.d.ts.map +1 -1
  76. package/dist/router/decorators.d.ts +1 -2
  77. package/dist/router/decorators.d.ts.map +1 -1
  78. package/dist/security/guards/types.d.ts +1 -0
  79. package/dist/security/guards/types.d.ts.map +1 -1
  80. package/dist/security/types.d.ts +1 -1
  81. package/dist/security/types.d.ts.map +1 -1
  82. package/dist/session/types.d.ts +8 -0
  83. package/dist/session/types.d.ts.map +1 -1
  84. package/dist/swagger/decorators.d.ts +1 -1
  85. package/dist/swagger/decorators.d.ts.map +1 -1
  86. package/dist/swagger/types.d.ts +1 -1
  87. package/dist/swagger/types.d.ts.map +1 -1
  88. package/dist/testing/harness.d.ts +1 -1
  89. package/dist/testing/harness.d.ts.map +1 -1
  90. package/dist/testing/test-client.d.ts +1 -1
  91. package/dist/testing/test-client.d.ts.map +1 -1
  92. package/dist/testing/testing-module.d.ts +2 -2
  93. package/dist/testing/testing-module.d.ts.map +1 -1
  94. package/dist/validation/errors.d.ts +5 -1
  95. package/dist/validation/errors.d.ts.map +1 -1
  96. package/docs/database.md +44 -0
  97. package/docs/zh/database.md +44 -0
  98. package/package.json +3 -3
  99. package/src/ai/types.ts +5 -0
  100. package/src/auth/types.ts +4 -1
  101. package/src/cache/interceptors.ts +6 -6
  102. package/src/cache/service-proxy.ts +2 -2
  103. package/src/cache/service.ts +17 -8
  104. package/src/cache/types.ts +12 -12
  105. package/src/config/service.ts +8 -6
  106. package/src/core/application.ts +7 -1
  107. package/src/core/context.ts +6 -3
  108. package/src/database/connection-manager.ts +5 -46
  109. package/src/database/connection-pool.ts +26 -49
  110. package/src/database/database-module.ts +6 -0
  111. package/src/database/db-proxy.ts +3 -2
  112. package/src/database/driver.ts +368 -0
  113. package/src/database/index.ts +8 -0
  114. package/src/database/service.ts +3 -74
  115. package/src/database/sql-manager.ts +38 -24
  116. package/src/database/sqlite-adapter.ts +4 -3
  117. package/src/database/types.ts +27 -2
  118. package/src/di/container.ts +13 -0
  119. package/src/di/module-registry.ts +2 -3
  120. package/src/di/module.ts +21 -2
  121. package/src/di/types.ts +1 -2
  122. package/src/error/handler.ts +3 -4
  123. package/src/error/http-exception.ts +11 -11
  124. package/src/error/index.ts +1 -1
  125. package/src/events/service.ts +4 -2
  126. package/src/events/types.ts +14 -3
  127. package/src/interceptor/base-interceptor.ts +5 -6
  128. package/src/interceptor/builtin/log-interceptor.ts +2 -3
  129. package/src/interceptor/builtin/permission-interceptor.ts +2 -3
  130. package/src/interceptor/interceptor-chain.ts +6 -7
  131. package/src/interceptor/interceptor-registry.ts +5 -3
  132. package/src/interceptor/types.ts +9 -4
  133. package/src/microservice/service-client/types.ts +1 -1
  134. package/src/microservice/tracing/tracer.ts +15 -3
  135. package/src/middleware/builtin/file-upload.ts +3 -2
  136. package/src/middleware/builtin/rate-limit.ts +22 -5
  137. package/src/queue/service.ts +1 -1
  138. package/src/queue/types.ts +40 -1
  139. package/src/router/decorators.ts +2 -3
  140. package/src/security/guards/types.ts +2 -1
  141. package/src/security/types.ts +1 -2
  142. package/src/session/service.ts +1 -1
  143. package/src/session/types.ts +10 -0
  144. package/src/swagger/decorators.ts +15 -4
  145. package/src/swagger/generator.ts +2 -3
  146. package/src/swagger/types.ts +1 -2
  147. package/src/testing/harness.ts +1 -2
  148. package/src/testing/test-client.ts +2 -2
  149. package/src/testing/testing-module.ts +5 -5
  150. package/src/validation/errors.ts +6 -2
  151. package/tests/bun-test-shim.d.ts +11 -0
  152. package/tests/controller/context-decorator.test.ts +1 -2
  153. package/tests/database/database-module.test.ts +4 -0
  154. package/tests/database/driver-mysql2.test.ts +95 -0
  155. package/tests/database/driver.test.ts +234 -0
  156. package/tests/database/orm.test.ts +4 -0
  157. package/tests/di/module.test.ts +199 -1
  158. package/tests/events/event-emitter.test.ts +2 -2
  159. package/tests/global.d.ts +30 -0
  160. package/tests/queue/queue-service.test.ts +14 -0
  161. package/tests/testing/testing-module.test.ts +20 -0
@@ -1125,8 +1125,9 @@ var init_http_exception = __esm(() => {
1125
1125
  this.messageParams = messageParams;
1126
1126
  }
1127
1127
  static withCode(code, message, details, messageParams) {
1128
- const status = ERROR_CODE_TO_STATUS[code] || 500;
1129
- const finalMessage = message || ERROR_CODE_MESSAGES[code] || "Internal Server Error";
1128
+ const knownCode = code;
1129
+ const status = ERROR_CODE_TO_STATUS[knownCode] || 500;
1130
+ const finalMessage = message || ERROR_CODE_MESSAGES[knownCode] || "Internal Server Error";
1130
1131
  return new HttpException(status, finalMessage, details, code, messageParams);
1131
1132
  }
1132
1133
  };
@@ -2150,7 +2151,7 @@ async function handleError(error, context) {
2150
2151
  });
2151
2152
  }
2152
2153
  let errorMessage = error.message;
2153
- if (error.code) {
2154
+ if (error.code && error.code in ERROR_CODE_MESSAGES) {
2154
2155
  const acceptLanguage = context.getHeader("accept-language");
2155
2156
  const language = ErrorMessageI18n.parseLanguageFromHeader(acceptLanguage);
2156
2157
  errorMessage = ErrorMessageI18n.getMessage(error.code, language, error.messageParams);
@@ -2192,6 +2193,7 @@ var init_handler = __esm(() => {
2192
2193
  init_http_exception();
2193
2194
  init_validation();
2194
2195
  init_i18n();
2196
+ init_error_codes();
2195
2197
  });
2196
2198
 
2197
2199
  // src/error/index.ts
@@ -2572,7 +2574,8 @@ class Container {
2572
2574
  typeToToken = new Map;
2573
2575
  dependencyPlans = new Map;
2574
2576
  postProcessors = [];
2575
- register(token, config) {
2577
+ register(token, configOrImplementation) {
2578
+ const config = typeof configOrImplementation === "function" ? { implementation: configOrImplementation } : configOrImplementation;
2576
2579
  const tokenKey = this.getTokenKey(token);
2577
2580
  let lifecycle = config?.lifecycle;
2578
2581
  if (!lifecycle && typeof token === "function") {
@@ -3318,9 +3321,11 @@ function defaultKeyGenerator(context) {
3318
3321
  function createRateLimitMiddleware(options) {
3319
3322
  const {
3320
3323
  max,
3324
+ limit,
3321
3325
  windowMs = 60000,
3322
3326
  store = new MemoryRateLimitStore,
3323
3327
  keyGenerator = defaultKeyGenerator,
3328
+ skip,
3324
3329
  skipSuccessfulRequests = false,
3325
3330
  skipFailedRequests = false,
3326
3331
  message = "Too Many Requests",
@@ -3328,22 +3333,26 @@ function createRateLimitMiddleware(options) {
3328
3333
  standardHeaders = true,
3329
3334
  legacyHeaders = true
3330
3335
  } = options;
3336
+ const requestLimit = limit ?? max ?? 100;
3331
3337
  return async (context, next) => {
3338
+ if (skip && await skip(context)) {
3339
+ return await next();
3340
+ }
3332
3341
  const key = await keyGenerator(context);
3333
3342
  const currentCount = await store.increment(key, windowMs);
3334
- const remaining = Math.max(0, max - currentCount);
3343
+ const remaining = Math.max(0, requestLimit - currentCount);
3335
3344
  const resetTime = Date.now() + windowMs;
3336
3345
  if (standardHeaders) {
3337
- context.setHeader("RateLimit-Limit", max.toString());
3346
+ context.setHeader("RateLimit-Limit", requestLimit.toString());
3338
3347
  context.setHeader("RateLimit-Remaining", remaining.toString());
3339
3348
  context.setHeader("RateLimit-Reset", Math.ceil(resetTime / 1000).toString());
3340
3349
  }
3341
3350
  if (legacyHeaders) {
3342
- context.setHeader("X-RateLimit-Limit", max.toString());
3351
+ context.setHeader("X-RateLimit-Limit", requestLimit.toString());
3343
3352
  context.setHeader("X-RateLimit-Remaining", remaining.toString());
3344
3353
  context.setHeader("X-RateLimit-Reset", Math.ceil(resetTime / 1000).toString());
3345
3354
  }
3346
- if (currentCount > max) {
3355
+ if (currentCount > requestLimit) {
3347
3356
  context.setStatus(statusCode);
3348
3357
  return context.createErrorResponse({
3349
3358
  error: message,
@@ -3621,7 +3630,7 @@ var init_file_handler = __esm(() => {
3621
3630
 
3622
3631
  // src/middleware/builtin/file-upload.ts
3623
3632
  function createFileUploadMiddleware(options = {}) {
3624
- const maxSize = options.maxSize ?? 10 * 1024 * 1024;
3633
+ const maxSize = options.maxSize ?? options.maxFileSize ?? 10 * 1024 * 1024;
3625
3634
  return async (context, next) => {
3626
3635
  const contentType = context.getHeader("Content-Type");
3627
3636
  if (!contentType || !contentType.includes("multipart/form-data")) {
@@ -3737,6 +3746,7 @@ var init_types3 = __esm(() => {
3737
3746
  class InterceptorRegistry {
3738
3747
  interceptors = new Map;
3739
3748
  register(metadataKey, interceptor, priority = 100) {
3749
+ const resolvedPriority = typeof priority === "number" ? priority : priority.priority ?? 100;
3740
3750
  if (!this.interceptors.has(metadataKey)) {
3741
3751
  this.interceptors.set(metadataKey, []);
3742
3752
  }
@@ -3746,7 +3756,7 @@ class InterceptorRegistry {
3746
3756
  metadataList.push({
3747
3757
  metadataKey,
3748
3758
  interceptor,
3749
- priority
3759
+ priority: resolvedPriority
3750
3760
  });
3751
3761
  metadataList.sort((a, b) => a.priority - b.priority);
3752
3762
  }
@@ -4044,6 +4054,13 @@ var init_logger_extension = __esm(() => {
4044
4054
 
4045
4055
  // src/di/module.ts
4046
4056
  import"reflect-metadata";
4057
+ function invokeFactoryProvider(provider, container) {
4058
+ const inject = provider.inject ?? [];
4059
+ if (inject.length > 0) {
4060
+ return provider.useFactory(...inject.map((token) => container.resolve(token)));
4061
+ }
4062
+ return provider.useFactory(container);
4063
+ }
4047
4064
  function Module(metadata) {
4048
4065
  return (target) => {
4049
4066
  Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, target);
@@ -4863,8 +4880,10 @@ class Context {
4863
4880
  _body;
4864
4881
  _bodyParsed = false;
4865
4882
  signal;
4866
- constructor(request) {
4883
+ container;
4884
+ constructor(request, container) {
4867
4885
  this.request = request;
4886
+ this.container = container;
4868
4887
  this.url = new URL2(request.url);
4869
4888
  this.method = request.method;
4870
4889
  this.path = this.url.pathname;
@@ -5577,7 +5596,7 @@ class ModuleRegistry {
5577
5596
  if ("useFactory" in provider) {
5578
5597
  container.register(provider.provide, {
5579
5598
  lifecycle: provider.lifecycle ?? "singleton" /* Singleton */,
5580
- factory: () => provider.useFactory(container)
5599
+ factory: () => invokeFactoryProvider(provider, container)
5581
5600
  });
5582
5601
  continue;
5583
5602
  }
@@ -5884,7 +5903,7 @@ class ConfigService {
5884
5903
  this.config = newConfig;
5885
5904
  for (const listener of this.configUpdateListeners) {
5886
5905
  try {
5887
- listener(newConfig);
5906
+ listener(this.config);
5888
5907
  } catch (error) {
5889
5908
  console.error("[ConfigService] Error in config update listener:", error);
5890
5909
  }
@@ -6392,9 +6411,10 @@ class CacheService {
6392
6411
  defaultTtl;
6393
6412
  keyPrefix;
6394
6413
  constructor(options) {
6395
- this.store = options.store;
6396
- this.defaultTtl = options.defaultTtl ?? 3600000;
6397
- this.keyPrefix = options.keyPrefix ?? "";
6414
+ const resolvedOptions = isCacheStore(options) ? { store: options } : options;
6415
+ this.store = resolvedOptions.store;
6416
+ this.defaultTtl = resolvedOptions.defaultTtl ?? 3600000;
6417
+ this.keyPrefix = resolvedOptions.keyPrefix ?? "";
6398
6418
  }
6399
6419
  async get(key) {
6400
6420
  return this.store.get(this.getKey(key));
@@ -6451,9 +6471,12 @@ CacheService = __legacyDecorateClassTS([
6451
6471
  Injectable(),
6452
6472
  __legacyDecorateParamTS(0, Inject(CACHE_OPTIONS_TOKEN)),
6453
6473
  __legacyMetadataTS("design:paramtypes", [
6454
- typeof CacheModuleOptions === "undefined" ? Object : CacheModuleOptions
6474
+ Object
6455
6475
  ])
6456
6476
  ], CacheService);
6477
+ function isCacheStore(value) {
6478
+ return typeof value.get === "function" && typeof value.set === "function" && typeof value.delete === "function";
6479
+ }
6457
6480
 
6458
6481
  // src/cache/service-proxy.ts
6459
6482
  import"reflect-metadata";
@@ -6997,6 +7020,8 @@ class EventEmitterService {
6997
7020
  handleError(error, event, payload) {
6998
7021
  if (this.options.onError) {
6999
7022
  this.options.onError(error, event, payload);
7023
+ } else if (this.options.errorHandler) {
7024
+ this.options.errorHandler(String(event), error, payload);
7000
7025
  } else {
7001
7026
  console.error(`[EventEmitter] Error in listener for event "${String(event)}":`, error);
7002
7027
  }
@@ -7641,6 +7666,9 @@ class Application {
7641
7666
  getServer() {
7642
7667
  return this.server;
7643
7668
  }
7669
+ getNativeServer() {
7670
+ return this.server?.getNativeServer();
7671
+ }
7644
7672
  async registerServices(port, hostname) {
7645
7673
  if (ServiceRegistryModule.autoRegister === false) {
7646
7674
  return;
@@ -8141,11 +8169,17 @@ function ApiOperation(metadata) {
8141
8169
  };
8142
8170
  }
8143
8171
  function ApiParam(metadata) {
8144
- return function(target, propertyKey, parameterIndex) {
8172
+ const decorator = (target, propertyKey, descriptorOrParameterIndex) => {
8173
+ const paramMetadata = {
8174
+ in: "path",
8175
+ ...metadata
8176
+ };
8145
8177
  const existingParams = Reflect.getMetadata(API_PARAM_METADATA_KEY, target, propertyKey) || [];
8146
- existingParams.push({ index: parameterIndex, metadata });
8178
+ const index = typeof descriptorOrParameterIndex === "number" ? descriptorOrParameterIndex : -1;
8179
+ existingParams.push({ index, metadata: paramMetadata });
8147
8180
  Reflect.defineMetadata(API_PARAM_METADATA_KEY, existingParams, target, propertyKey);
8148
8181
  };
8182
+ return decorator;
8149
8183
  }
8150
8184
  function ApiBody(metadata) {
8151
8185
  return function(target, propertyKey) {
@@ -8262,7 +8296,7 @@ class SwaggerGenerator {
8262
8296
  const pathParamMatches = fullPath.matchAll(/\{([^}]+)\}/g);
8263
8297
  for (const match of pathParamMatches) {
8264
8298
  const paramName = match[1];
8265
- const existingParam = params.find((p) => p.metadata.name === paramName && p.metadata.in === "path");
8299
+ const existingParam = params.find((p) => p.metadata.name === paramName && (p.metadata.in ?? "path") === "path");
8266
8300
  if (!existingParam) {
8267
8301
  pathParams.push({
8268
8302
  name: paramName,
@@ -8275,7 +8309,7 @@ class SwaggerGenerator {
8275
8309
  for (const param of params) {
8276
8310
  pathParams.push({
8277
8311
  name: param.metadata.name,
8278
- in: param.metadata.in,
8312
+ in: param.metadata.in ?? "path",
8279
8313
  description: param.metadata.description,
8280
8314
  required: param.metadata.required,
8281
8315
  schema: param.metadata.schema
@@ -10865,6 +10899,197 @@ init_decorators();
10865
10899
  // src/database/connection-pool.ts
10866
10900
  init_runtime();
10867
10901
 
10902
+ // src/database/driver.ts
10903
+ var DRIVER_TAG = Symbol.for("@dangao/bun-server:database:driver");
10904
+ function resolveDriver(dbType, option, engine) {
10905
+ const driver = option ?? "auto";
10906
+ switch (driver) {
10907
+ case "auto":
10908
+ if (engine === "bun") {
10909
+ return "bun-sql";
10910
+ }
10911
+ return dbType === "mysql" ? "mysql2" : "postgres";
10912
+ case "bun-sql":
10913
+ if (engine !== "bun") {
10914
+ throw new Error(`[bun-server] driver 'bun-sql' requires the Bun runtime, but the current platform engine is '${engine}'. ` + `Use driver 'auto' / 'mysql2' / 'postgres', or run on Bun.`);
10915
+ }
10916
+ return "bun-sql";
10917
+ case "mysql2":
10918
+ if (dbType !== "mysql") {
10919
+ throw new Error(`[bun-server] driver 'mysql2' is only valid for type 'mysql', but got type '${dbType}'.`);
10920
+ }
10921
+ return "mysql2";
10922
+ case "postgres":
10923
+ if (dbType !== "postgres") {
10924
+ throw new Error(`[bun-server] driver 'postgres' is only valid for type 'postgres', but got type '${dbType}'.`);
10925
+ }
10926
+ return "postgres";
10927
+ default:
10928
+ throw new Error(`[bun-server] unknown driver '${String(driver)}'.`);
10929
+ }
10930
+ }
10931
+ function tagConnection(connection, driver) {
10932
+ if (connection && (typeof connection === "object" || typeof connection === "function")) {
10933
+ try {
10934
+ Object.defineProperty(connection, DRIVER_TAG, {
10935
+ value: driver,
10936
+ enumerable: false,
10937
+ configurable: true,
10938
+ writable: true
10939
+ });
10940
+ } catch {}
10941
+ }
10942
+ return connection;
10943
+ }
10944
+ function getConnectionDriver(connection) {
10945
+ if (!connection) {
10946
+ return;
10947
+ }
10948
+ if (typeof connection === "object" || typeof connection === "function") {
10949
+ const tagged = connection[DRIVER_TAG];
10950
+ if (tagged === "bun-sql" || tagged === "mysql2" || tagged === "postgres") {
10951
+ return tagged;
10952
+ }
10953
+ }
10954
+ if (typeof connection === "function") {
10955
+ return "bun-sql";
10956
+ }
10957
+ return;
10958
+ }
10959
+ async function createPostgresConnection(config, driver) {
10960
+ const url = `postgres://${config.user}:${config.password}@${config.host}:${config.port}/${config.database}`;
10961
+ if (driver === "bun-sql") {
10962
+ const { SQL } = await import("bun");
10963
+ return tagConnection(new SQL({
10964
+ adapter: "postgres",
10965
+ hostname: config.host,
10966
+ port: config.port,
10967
+ username: config.user,
10968
+ password: config.password,
10969
+ database: config.database,
10970
+ max: 1,
10971
+ tls: config.ssl ?? false
10972
+ }), "bun-sql");
10973
+ }
10974
+ if (driver === "postgres") {
10975
+ const postgres = loadPostgres();
10976
+ return tagConnection(postgres(url, { max: 1, ssl: config.ssl ? "require" : false }), "postgres");
10977
+ }
10978
+ throw new Error(`[bun-server] driver '${driver}' cannot create a postgres connection.`);
10979
+ }
10980
+ async function createMysqlConnection(config, driver) {
10981
+ if (driver === "bun-sql") {
10982
+ const { SQL } = await import("bun");
10983
+ return tagConnection(new SQL({
10984
+ adapter: "mysql",
10985
+ hostname: config.host,
10986
+ port: config.port,
10987
+ username: config.user,
10988
+ password: config.password,
10989
+ database: config.database,
10990
+ max: 1,
10991
+ ssl: config.ssl ?? false
10992
+ }), "bun-sql");
10993
+ }
10994
+ if (driver === "mysql2") {
10995
+ const mysql2 = loadMysql2();
10996
+ const conn = await mysql2.createConnection({
10997
+ host: config.host,
10998
+ port: config.port,
10999
+ database: config.database,
11000
+ user: config.user,
11001
+ password: config.password
11002
+ });
11003
+ return tagConnection(conn, "mysql2");
11004
+ }
11005
+ throw new Error(`[bun-server] driver '${driver}' cannot create a mysql connection.`);
11006
+ }
11007
+ async function queryViaDriver(connection, sql, params) {
11008
+ const driver = getConnectionDriver(connection);
11009
+ if (driver === "mysql2") {
11010
+ const conn = connection;
11011
+ const [rows] = await conn.query(sql, params ?? []);
11012
+ return rows ?? [];
11013
+ }
11014
+ if (driver === "postgres") {
11015
+ const conn = connection;
11016
+ const rows = await conn.unsafe(sql, params ?? []);
11017
+ return rows ?? [];
11018
+ }
11019
+ if (typeof connection === "function") {
11020
+ const { strings, values } = buildTemplateFromSql(sql, params);
11021
+ const template = Object.assign(strings.slice(), {
11022
+ raw: strings.slice()
11023
+ });
11024
+ const result = await connection(template, ...values);
11025
+ return result;
11026
+ }
11027
+ if (connection && typeof connection === "object" && "query" in connection && typeof connection.query === "function") {
11028
+ const result = await connection.query(sql, params ?? []);
11029
+ return Array.isArray(result) ? result[0] : result;
11030
+ }
11031
+ throw new Error("[bun-server] invalid SQL connection for query.");
11032
+ }
11033
+ async function templateQueryViaDriver(connection, strings, values) {
11034
+ const driver = getConnectionDriver(connection);
11035
+ if (driver === "mysql2") {
11036
+ const sql = strings.join("?");
11037
+ const conn = connection;
11038
+ const [rows] = await conn.query(sql, values);
11039
+ return rows;
11040
+ }
11041
+ return await connection(strings, ...values);
11042
+ }
11043
+ async function healthCheckViaDriver(connection) {
11044
+ try {
11045
+ const rows = await queryViaDriver(connection, "SELECT 1");
11046
+ return Array.isArray(rows);
11047
+ } catch {
11048
+ return false;
11049
+ }
11050
+ }
11051
+ async function closeViaDriver(connection) {
11052
+ if (!connection || typeof connection !== "object" && typeof connection !== "function") {
11053
+ return;
11054
+ }
11055
+ const driver = getConnectionDriver(connection);
11056
+ const conn = connection;
11057
+ if (driver === "mysql2" || driver === "postgres") {
11058
+ if (typeof conn.end === "function") {
11059
+ await conn.end();
11060
+ return;
11061
+ }
11062
+ }
11063
+ if (driver === "bun-sql") {
11064
+ if (typeof conn.close === "function") {
11065
+ await conn.close();
11066
+ return;
11067
+ }
11068
+ }
11069
+ if (typeof conn.close === "function") {
11070
+ await conn.close();
11071
+ } else if (typeof conn.end === "function") {
11072
+ await conn.end();
11073
+ }
11074
+ }
11075
+ function buildTemplateFromSql(sql, params) {
11076
+ if (!params || params.length === 0) {
11077
+ return { strings: [sql], values: [] };
11078
+ }
11079
+ const strings = sql.split("?");
11080
+ if (strings.length !== params.length + 1) {
11081
+ throw new Error("SQL placeholders count does not match parameters count");
11082
+ }
11083
+ return { strings, values: params };
11084
+ }
11085
+ function loadMysql2() {
11086
+ return __require("mysql2/promise");
11087
+ }
11088
+ function loadPostgres() {
11089
+ return __require("postgres");
11090
+ }
11091
+
11092
+ // src/database/connection-pool.ts
10868
11093
  class ConnectionPool {
10869
11094
  config;
10870
11095
  options;
@@ -10979,29 +11204,12 @@ Install it with: bun add @vscode/sqlite3@5.1.12-vscode`);
10979
11204
  return new sqlite3.Database(config.path);
10980
11205
  }
10981
11206
  async createPostgresConnection(config) {
10982
- const url = `postgres://${config.user}:${config.password}@${config.host}:${config.port}/${config.database}`;
10983
- if (getRuntime().engine === "bun") {
10984
- const { SQL } = await import("bun");
10985
- return new SQL(url, { max: 1, tls: config.ssl ?? false });
10986
- }
10987
- const postgres = __require("postgres");
10988
- return postgres(url, { max: 1, ssl: config.ssl ? "require" : false });
11207
+ const driver = resolveDriver("postgres", this.config.type === "postgres" ? this.config.driver : undefined, getRuntime().engine);
11208
+ return await createPostgresConnection(config, driver);
10989
11209
  }
10990
11210
  async createMysqlConnection(config) {
10991
- if (getRuntime().engine === "bun") {
10992
- const url = `mysql://${config.user}:${config.password}@${config.host}:${config.port}/${config.database}`;
10993
- const { SQL } = await import("bun");
10994
- return new SQL(url, { max: 1 });
10995
- }
10996
- const mysql2 = __require("mysql2/promise");
10997
- const conn = await mysql2.createConnection({
10998
- host: config.host,
10999
- port: config.port,
11000
- database: config.database,
11001
- user: config.user,
11002
- password: config.password
11003
- });
11004
- return conn;
11211
+ const driver = resolveDriver("mysql", this.config.type === "mysql" ? this.config.driver : undefined, getRuntime().engine);
11212
+ return await createMysqlConnection(config, driver);
11005
11213
  }
11006
11214
  async closeConnection(connection) {
11007
11215
  const dbType = this.config.type;
@@ -11018,15 +11226,11 @@ Install it with: bun add @vscode/sqlite3@5.1.12-vscode`);
11018
11226
  connection.close();
11019
11227
  }
11020
11228
  }
11021
- async closePostgresConnection(_connection) {
11022
- if (_connection && typeof _connection === "object" && "close" in _connection && typeof _connection.close === "function") {
11023
- _connection.close();
11024
- }
11229
+ async closePostgresConnection(connection) {
11230
+ await closeViaDriver(connection);
11025
11231
  }
11026
- async closeMysqlConnection(_connection) {
11027
- if (_connection && typeof _connection === "object" && "close" in _connection && typeof _connection.close === "function") {
11028
- _connection.close();
11029
- }
11232
+ async closeMysqlConnection(connection) {
11233
+ await closeViaDriver(connection);
11030
11234
  }
11031
11235
  async waitForConnection() {
11032
11236
  const startTime = Date.now();
@@ -11167,34 +11371,10 @@ class DatabaseConnectionManager {
11167
11371
  }
11168
11372
  }
11169
11373
  async healthCheckPostgres(connection) {
11170
- try {
11171
- if (connection && typeof connection === "function") {
11172
- const result = await connection`SELECT 1`;
11173
- return Array.isArray(result) && result.length > 0;
11174
- }
11175
- if (connection && typeof connection === "object" && "query" in connection && typeof connection.query === "function") {
11176
- await connection.query("SELECT 1");
11177
- return true;
11178
- }
11179
- return false;
11180
- } catch (_error) {
11181
- return false;
11182
- }
11374
+ return await healthCheckViaDriver(connection);
11183
11375
  }
11184
11376
  async healthCheckMysql(connection) {
11185
- try {
11186
- if (connection && typeof connection === "function") {
11187
- const result = await connection`SELECT 1`;
11188
- return Array.isArray(result) && result.length > 0;
11189
- }
11190
- if (connection && typeof connection === "object" && "query" in connection && typeof connection.query === "function") {
11191
- await connection.query("SELECT 1");
11192
- return true;
11193
- }
11194
- return false;
11195
- } catch (_error) {
11196
- return false;
11197
- }
11377
+ return await healthCheckViaDriver(connection);
11198
11378
  }
11199
11379
  }
11200
11380
 
@@ -11265,7 +11445,7 @@ class DatabaseService2 {
11265
11445
  if (dbType === "sqlite") {
11266
11446
  return this.querySqlite(connection, sql, params);
11267
11447
  } else if (dbType === "postgres" || dbType === "mysql") {
11268
- return this.queryBunSQL(connection, sql, params);
11448
+ return queryViaDriver(connection, sql, params);
11269
11449
  }
11270
11450
  throw new Error(`Query not supported for database type: ${dbType}`);
11271
11451
  }
@@ -11288,37 +11468,6 @@ class DatabaseService2 {
11288
11468
  }
11289
11469
  throw new Error("Invalid SQLite connection");
11290
11470
  }
11291
- async queryBunSQL(connection, sql, params) {
11292
- if (connection && typeof connection === "function") {
11293
- try {
11294
- const { strings, values } = this.buildTemplateFromSql(sql, params);
11295
- const template = Object.assign(strings, {
11296
- raw: strings
11297
- });
11298
- const result = await connection(template, ...values);
11299
- return result;
11300
- } catch (error) {
11301
- const errorMessage = error instanceof Error ? error.message : String(error);
11302
- throw new Error(`Bun.SQL parameterized queries are not fully supported. Consider using template string queries. Original error: ${errorMessage}`);
11303
- }
11304
- }
11305
- if (connection && typeof connection === "object" && "query" in connection && typeof connection.query === "function") {
11306
- const db = connection;
11307
- const result = await db.query(sql, ...params ?? []);
11308
- return result;
11309
- }
11310
- throw new Error("Invalid Bun.SQL connection");
11311
- }
11312
- buildTemplateFromSql(sql, params) {
11313
- if (!params || params.length === 0) {
11314
- return { strings: [sql], values: [] };
11315
- }
11316
- const strings = sql.split("?");
11317
- if (strings.length !== params.length + 1) {
11318
- throw new Error("SQL placeholders count does not match parameters count");
11319
- }
11320
- return { strings, values: params };
11321
- }
11322
11471
  }
11323
11472
  DatabaseService2 = __legacyDecorateClassTS([
11324
11473
  Injectable(),
@@ -11332,7 +11481,6 @@ var ORM_SERVICE_TOKEN = Symbol("@dangao/bun-server:orm:service");
11332
11481
 
11333
11482
  // src/database/sql-manager.ts
11334
11483
  init_runtime();
11335
-
11336
11484
  class BunSQLManager2 {
11337
11485
  instances = new Map;
11338
11486
  defaultTenantId = "default";
@@ -11342,34 +11490,49 @@ class BunSQLManager2 {
11342
11490
  return existing;
11343
11491
  }
11344
11492
  const pool = config.pool ?? {};
11493
+ const driver = resolveDriver(config.type, config.driver, getRuntime().engine);
11345
11494
  let sql;
11346
- if (getRuntime().engine === "bun") {
11495
+ if (driver === "bun-sql") {
11347
11496
  const { SQL } = __require("bun");
11348
- sql = new SQL(config.url, {
11349
- max: pool.max ?? 10,
11350
- idleTimeout: pool.idleTimeout ?? 30,
11351
- maxLifetime: pool.maxLifetime ?? 0,
11352
- connectionTimeout: pool.connectionTimeout ?? 30000
11353
- });
11354
- } else {
11355
- const url = config.url.toLowerCase();
11356
- if (url.startsWith("mysql://") || url.startsWith("mysql2://")) {
11357
- const mysql2 = __require("mysql2/promise");
11358
- sql = mysql2.createPool({
11359
- uri: config.url,
11360
- connectionLimit: pool.max ?? 10,
11361
- waitForConnections: true
11497
+ if (config.type === "mysql") {
11498
+ const parsed = new URL(config.url);
11499
+ sql = new SQL({
11500
+ adapter: "mysql",
11501
+ hostname: parsed.hostname,
11502
+ port: parsed.port ? Number(parsed.port) : 3306,
11503
+ username: decodeURIComponent(parsed.username),
11504
+ password: decodeURIComponent(parsed.password),
11505
+ database: parsed.pathname.replace(/^\//, ""),
11506
+ max: pool.max ?? 10,
11507
+ idleTimeout: pool.idleTimeout ?? 30,
11508
+ maxLifetime: pool.maxLifetime ?? 0,
11509
+ connectionTimeout: pool.connectionTimeout ?? 30000
11362
11510
  });
11363
11511
  } else {
11364
- const postgres = __require("postgres");
11365
- sql = postgres(config.url, {
11512
+ sql = new SQL(config.url, {
11366
11513
  max: pool.max ?? 10,
11367
- idle_timeout: pool.idleTimeout ?? 30,
11368
- max_lifetime: pool.maxLifetime ?? 0,
11369
- connect_timeout: (pool.connectionTimeout ?? 30000) / 1000
11514
+ idleTimeout: pool.idleTimeout ?? 30,
11515
+ maxLifetime: pool.maxLifetime ?? 0,
11516
+ connectionTimeout: pool.connectionTimeout ?? 30000
11370
11517
  });
11371
11518
  }
11519
+ } else if (driver === "mysql2") {
11520
+ const mysql2 = __require("mysql2/promise");
11521
+ sql = mysql2.createPool({
11522
+ uri: config.url,
11523
+ connectionLimit: pool.max ?? 10,
11524
+ waitForConnections: true
11525
+ });
11526
+ } else {
11527
+ const postgres = __require("postgres");
11528
+ sql = postgres(config.url, {
11529
+ max: pool.max ?? 10,
11530
+ idle_timeout: pool.idleTimeout ?? 30,
11531
+ max_lifetime: pool.maxLifetime ?? 0,
11532
+ connect_timeout: (pool.connectionTimeout ?? 30000) / 1000
11533
+ });
11372
11534
  }
11535
+ tagConnection(sql, driver);
11373
11536
  this.instances.set(tenantId, sql);
11374
11537
  return sql;
11375
11538
  }
@@ -11580,10 +11743,10 @@ var baseDb = async (tenantId, strings, ...values) => {
11580
11743
  if (tenantId) {
11581
11744
  const tenantSql = sqlManager.get(tenantId);
11582
11745
  if (tenantSql) {
11583
- return await tenantSql(strings, ...values);
11746
+ return await templateQueryViaDriver(tenantSql, strings, values);
11584
11747
  }
11585
11748
  }
11586
- return await sqlManager.getDefault()(strings, ...values);
11749
+ return await templateQueryViaDriver(sqlManager.getDefault(), strings, values);
11587
11750
  };
11588
11751
  function createDb(tenantId) {
11589
11752
  const fn = async (strings, ...values) => baseDb(tenantId, strings, ...values);
@@ -11657,7 +11820,8 @@ class DatabaseModule {
11657
11820
  config: {
11658
11821
  type: db2.type,
11659
11822
  url,
11660
- pool: options.bunSqlPool
11823
+ pool: options.bunSqlPool,
11824
+ driver: db2.driver ?? options.driver
11661
11825
  }
11662
11826
  }
11663
11827
  ];
@@ -11682,7 +11846,8 @@ class DatabaseModule {
11682
11846
  config: {
11683
11847
  type: options.type,
11684
11848
  url: options.url,
11685
- pool: options.bunSqlPool
11849
+ pool: options.bunSqlPool,
11850
+ driver: options.driver
11686
11851
  }
11687
11852
  }
11688
11853
  ];
@@ -11696,7 +11861,8 @@ class DatabaseModule {
11696
11861
  config: {
11697
11862
  type: options.type,
11698
11863
  url,
11699
- pool: options.bunSqlPool
11864
+ pool: options.bunSqlPool,
11865
+ driver: options.driver
11700
11866
  }
11701
11867
  }
11702
11868
  ];
@@ -11780,7 +11946,8 @@ class DatabaseModule {
11780
11946
  database: options.databasePath ?? "default",
11781
11947
  user: options.username ?? "root",
11782
11948
  password: options.password ?? ""
11783
- }
11949
+ },
11950
+ driver: normalized[0]?.config?.driver ?? options.driver
11784
11951
  }
11785
11952
  };
11786
11953
  const service = new DatabaseService2(legacyOptions);
@@ -12770,6 +12937,7 @@ class StressTester {
12770
12937
  }
12771
12938
  // src/testing/testing-module.ts
12772
12939
  import"reflect-metadata";
12940
+ init_module();
12773
12941
 
12774
12942
  // src/testing/test-client.ts
12775
12943
  class TestHttpClient {
@@ -12933,7 +13101,7 @@ class TestingModule {
12933
13101
  container.registerInstance(provider.provide, provider.useValue);
12934
13102
  } else if ("useFactory" in provider && provider.provide) {
12935
13103
  container.register(provider.provide, {
12936
- factory: () => provider.useFactory(container)
13104
+ factory: () => invokeFactoryProvider(provider, container)
12937
13105
  });
12938
13106
  } else if ("useClass" in provider) {
12939
13107
  const token = provider.provide ?? provider.useClass;
@@ -13375,7 +13543,7 @@ class SessionService {
13375
13543
  constructor(options) {
13376
13544
  this.store = options.store;
13377
13545
  this.name = options.name ?? "sessionId";
13378
- this.maxAge = options.maxAge ?? 86400000;
13546
+ this.maxAge = options.maxAge ?? options.ttl ?? 86400000;
13379
13547
  this.rolling = options.rolling ?? true;
13380
13548
  this.cookieOptions = {
13381
13549
  secure: options.cookie?.secure ?? false,
@@ -14085,14 +14253,15 @@ class Tracer {
14085
14253
  Object.assign(span.tags, tags);
14086
14254
  }
14087
14255
  }
14088
- addSpanEvent(spanId, event) {
14256
+ addSpanEvent(spanId, event, attributes) {
14089
14257
  const span = this.activeSpans.get(spanId);
14090
14258
  if (span) {
14091
14259
  if (!span.events) {
14092
14260
  span.events = [];
14093
14261
  }
14262
+ const spanEvent = typeof event === "string" ? { name: event, attributes } : event;
14094
14263
  span.events.push({
14095
- ...event,
14264
+ ...spanEvent,
14096
14265
  timestamp: Date.now()
14097
14266
  });
14098
14267
  }
@@ -14795,6 +14964,7 @@ class ServiceMetricsCollector {
14795
14964
  var AI_SERVICE_TOKEN = Symbol("@dangao/bun-server:ai:service");
14796
14965
  var AI_MODULE_OPTIONS_TOKEN = Symbol("@dangao/bun-server:ai:options");
14797
14966
  var AI_TOOL_REGISTRY_TOKEN = Symbol("@dangao/bun-server:ai:tool-registry");
14967
+ var MODULE_METADATA_KEY3 = "@dangao/bun-server:ai:module";
14798
14968
  var AI_TOOL_METADATA_KEY = "@dangao/bun-server:ai:tool";
14799
14969
  // src/ai/errors.ts
14800
14970
  init_http_exception();
@@ -17578,6 +17748,7 @@ export {
17578
17748
  Max,
17579
17749
  Matches,
17580
17750
  MarkdownChunker,
17751
+ MODULE_METADATA_KEY3 as MODULE_METADATA_KEY,
17581
17752
  METRICS_SERVICE_TOKEN,
17582
17753
  METRICS_OPTIONS_TOKEN,
17583
17754
  MCP_TOOL_METADATA_KEY,