@dangao/bun-server 0.4.0 → 1.0.1

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 (44) hide show
  1. package/dist/cache/cache-module.d.ts +9 -0
  2. package/dist/cache/cache-module.d.ts.map +1 -0
  3. package/dist/cache/decorators.d.ts +110 -0
  4. package/dist/cache/decorators.d.ts.map +1 -0
  5. package/dist/cache/index.d.ts +6 -0
  6. package/dist/cache/index.d.ts.map +1 -0
  7. package/dist/cache/service.d.ts +76 -0
  8. package/dist/cache/service.d.ts.map +1 -0
  9. package/dist/cache/types.d.ts +160 -0
  10. package/dist/cache/types.d.ts.map +1 -0
  11. package/dist/controller/decorators.d.ts +9 -1
  12. package/dist/controller/decorators.d.ts.map +1 -1
  13. package/dist/controller/param-binder.d.ts +4 -1
  14. package/dist/controller/param-binder.d.ts.map +1 -1
  15. package/dist/index.d.ts +6 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1123 -25
  18. package/dist/middleware/pipeline.d.ts.map +1 -1
  19. package/dist/queue/decorators.d.ts +63 -0
  20. package/dist/queue/decorators.d.ts.map +1 -0
  21. package/dist/queue/index.d.ts +6 -0
  22. package/dist/queue/index.d.ts.map +1 -0
  23. package/dist/queue/queue-module.d.ts +9 -0
  24. package/dist/queue/queue-module.d.ts.map +1 -0
  25. package/dist/queue/service.d.ts +93 -0
  26. package/dist/queue/service.d.ts.map +1 -0
  27. package/dist/queue/types.d.ts +204 -0
  28. package/dist/queue/types.d.ts.map +1 -0
  29. package/dist/router/router.d.ts +16 -1
  30. package/dist/router/router.d.ts.map +1 -1
  31. package/dist/session/decorators.d.ts +16 -0
  32. package/dist/session/decorators.d.ts.map +1 -0
  33. package/dist/session/index.d.ts +8 -0
  34. package/dist/session/index.d.ts.map +1 -0
  35. package/dist/session/middleware.d.ts +8 -0
  36. package/dist/session/middleware.d.ts.map +1 -0
  37. package/dist/session/service.d.ts +86 -0
  38. package/dist/session/service.d.ts.map +1 -0
  39. package/dist/session/session-module.d.ts +9 -0
  40. package/dist/session/session-module.d.ts.map +1 -0
  41. package/dist/session/types.d.ts +193 -0
  42. package/dist/session/types.d.ts.map +1 -0
  43. package/package.json +1 -1
  44. package/readme.md +98 -117
package/dist/index.js CHANGED
@@ -969,21 +969,23 @@ class MiddlewarePipeline {
969
969
  if (length === 0) {
970
970
  return await finalHandler();
971
971
  }
972
+ let currentIndex = 0;
972
973
  const called = new Array(length).fill(false);
973
- const chain = new Array(length + 1);
974
- chain[length] = finalHandler;
975
- for (let i = length - 1;i >= 0; i--) {
976
- const middleware = this.middlewares[i];
977
- const downstream = chain[i + 1];
978
- chain[i] = async () => {
979
- if (called[i]) {
974
+ const createNext = (index) => {
975
+ if (index >= length) {
976
+ return finalHandler;
977
+ }
978
+ return async () => {
979
+ if (called[index]) {
980
980
  throw new Error("next() called multiple times");
981
981
  }
982
- called[i] = true;
983
- return await middleware(context, downstream);
982
+ called[index] = true;
983
+ currentIndex = index + 1;
984
+ const middleware = this.middlewares[index];
985
+ return await middleware(context, createNext(index + 1));
984
986
  };
985
- }
986
- return await chain[0]();
987
+ };
988
+ return await createNext(0)();
987
989
  }
988
990
  }
989
991
 
@@ -1053,6 +1055,7 @@ class Router {
1053
1055
  routes = [];
1054
1056
  staticRoutes = new Map;
1055
1057
  dynamicRoutes = [];
1058
+ matchCache = new Map;
1056
1059
  normalizePath(path) {
1057
1060
  if (path.length > 1 && path.endsWith("/")) {
1058
1061
  return path.slice(0, -1);
@@ -1069,6 +1072,7 @@ class Router {
1069
1072
  } else {
1070
1073
  this.dynamicRoutes.push(route);
1071
1074
  }
1075
+ this.matchCache.clear();
1072
1076
  }
1073
1077
  get(path, handler, middlewares = []) {
1074
1078
  this.register("GET", path, handler, middlewares);
@@ -1086,14 +1090,29 @@ class Router {
1086
1090
  this.register("PATCH", path, handler, middlewares);
1087
1091
  }
1088
1092
  findRoute(method, path) {
1089
- const staticRoute = this.staticRoutes.get(`${method}:${path}`);
1093
+ const result = this.findRouteWithMatch(method, path);
1094
+ return result?.route;
1095
+ }
1096
+ findRouteWithMatch(method, path) {
1097
+ const normalizedPath = this.normalizePath(path);
1098
+ const cacheKey = `${method}:${normalizedPath}`;
1099
+ const cached = this.matchCache.get(cacheKey);
1100
+ if (cached && cached.match.matched) {
1101
+ return cached;
1102
+ }
1103
+ const staticRoute = this.staticRoutes.get(cacheKey);
1090
1104
  if (staticRoute) {
1091
- return staticRoute;
1105
+ const match = { matched: true, params: {} };
1106
+ const result = { route: staticRoute, match };
1107
+ this.matchCache.set(cacheKey, result);
1108
+ return result;
1092
1109
  }
1093
1110
  for (const route of this.dynamicRoutes) {
1094
- const match = route.match(method, path);
1111
+ const match = route.match(method, normalizedPath);
1095
1112
  if (match.matched) {
1096
- return route;
1113
+ const result = { route, match };
1114
+ this.matchCache.set(cacheKey, result);
1115
+ return result;
1097
1116
  }
1098
1117
  }
1099
1118
  return;
@@ -1101,11 +1120,11 @@ class Router {
1101
1120
  async preHandle(context) {
1102
1121
  const method = context.method;
1103
1122
  const path = this.normalizePath(context.path);
1104
- const route = this.findRoute(method, path);
1105
- if (!route) {
1123
+ const result = this.findRouteWithMatch(method, path);
1124
+ if (!result) {
1106
1125
  return;
1107
1126
  }
1108
- const match = route.match(method, path);
1127
+ const { route, match } = result;
1109
1128
  if (match.matched) {
1110
1129
  context.params = match.params;
1111
1130
  }
@@ -1117,13 +1136,22 @@ class Router {
1117
1136
  }
1118
1137
  }
1119
1138
  async handle(context) {
1120
- await this.preHandle(context);
1121
1139
  const method = context.method;
1122
1140
  const path = this.normalizePath(context.path);
1123
- const route = this.findRoute(method, path);
1124
- if (!route) {
1141
+ const result = this.findRouteWithMatch(method, path);
1142
+ if (!result) {
1125
1143
  return;
1126
1144
  }
1145
+ const { route, match } = result;
1146
+ if (match.matched) {
1147
+ context.params = match.params;
1148
+ }
1149
+ if (route.controllerClass && route.methodName) {
1150
+ context.routeHandler = {
1151
+ controller: route.controllerClass,
1152
+ method: route.methodName
1153
+ };
1154
+ }
1127
1155
  return await route.execute(context);
1128
1156
  }
1129
1157
  getRoutes() {
@@ -1133,6 +1161,7 @@ class Router {
1133
1161
  this.routes.length = 0;
1134
1162
  this.dynamicRoutes.length = 0;
1135
1163
  this.staticRoutes.clear();
1164
+ this.matchCache.clear();
1136
1165
  }
1137
1166
  }
1138
1167
 
@@ -1521,14 +1550,162 @@ function getParamMetadata(target, propertyKey) {
1521
1550
  return Reflect.getMetadata(PARAM_METADATA_KEY, target, propertyKey) || [];
1522
1551
  }
1523
1552
 
1553
+ // src/session/types.ts
1554
+ class MemorySessionStore {
1555
+ store = new Map;
1556
+ cleanupInterval;
1557
+ constructor(options) {
1558
+ if (options?.cleanupInterval !== undefined) {
1559
+ this.cleanupInterval = setInterval(() => {
1560
+ this.cleanup();
1561
+ }, options.cleanupInterval);
1562
+ }
1563
+ }
1564
+ async get(sessionId) {
1565
+ const session = this.store.get(sessionId);
1566
+ if (!session) {
1567
+ return;
1568
+ }
1569
+ if (Date.now() > session.expiresAt) {
1570
+ this.store.delete(sessionId);
1571
+ return;
1572
+ }
1573
+ return session;
1574
+ }
1575
+ async set(session, maxAge) {
1576
+ const now = Date.now();
1577
+ session.expiresAt = now + maxAge;
1578
+ session.lastAccessedAt = now;
1579
+ this.store.set(session.id, session);
1580
+ return true;
1581
+ }
1582
+ async delete(sessionId) {
1583
+ return this.store.delete(sessionId);
1584
+ }
1585
+ async has(sessionId) {
1586
+ const session = this.store.get(sessionId);
1587
+ if (!session) {
1588
+ return false;
1589
+ }
1590
+ if (Date.now() > session.expiresAt) {
1591
+ this.store.delete(sessionId);
1592
+ return false;
1593
+ }
1594
+ return true;
1595
+ }
1596
+ async touch(sessionId) {
1597
+ const session = this.store.get(sessionId);
1598
+ if (!session) {
1599
+ return false;
1600
+ }
1601
+ if (Date.now() > session.expiresAt) {
1602
+ this.store.delete(sessionId);
1603
+ return false;
1604
+ }
1605
+ session.lastAccessedAt = Date.now();
1606
+ return true;
1607
+ }
1608
+ async clear() {
1609
+ this.store.clear();
1610
+ return true;
1611
+ }
1612
+ cleanup() {
1613
+ const now = Date.now();
1614
+ for (const [sessionId, session] of this.store.entries()) {
1615
+ if (now > session.expiresAt) {
1616
+ this.store.delete(sessionId);
1617
+ }
1618
+ }
1619
+ }
1620
+ destroy() {
1621
+ if (this.cleanupInterval) {
1622
+ clearInterval(this.cleanupInterval);
1623
+ this.cleanupInterval = undefined;
1624
+ }
1625
+ this.store.clear();
1626
+ }
1627
+ }
1628
+
1629
+ class RedisSessionStore {
1630
+ client;
1631
+ keyPrefix;
1632
+ constructor(options) {
1633
+ this.client = options.client;
1634
+ this.keyPrefix = options.keyPrefix ?? "session:";
1635
+ }
1636
+ getKey(sessionId) {
1637
+ return `${this.keyPrefix}${sessionId}`;
1638
+ }
1639
+ async get(sessionId) {
1640
+ try {
1641
+ const value = await this.client.get(this.getKey(sessionId));
1642
+ if (value === null) {
1643
+ return;
1644
+ }
1645
+ return JSON.parse(value);
1646
+ } catch {
1647
+ return;
1648
+ }
1649
+ }
1650
+ async set(session, maxAge) {
1651
+ try {
1652
+ const serialized = JSON.stringify(session);
1653
+ await this.client.set(this.getKey(session.id), serialized, {
1654
+ PX: maxAge
1655
+ });
1656
+ return true;
1657
+ } catch {
1658
+ return false;
1659
+ }
1660
+ }
1661
+ async delete(sessionId) {
1662
+ try {
1663
+ await this.client.del(this.getKey(sessionId));
1664
+ return true;
1665
+ } catch {
1666
+ return false;
1667
+ }
1668
+ }
1669
+ async has(sessionId) {
1670
+ try {
1671
+ const result = await this.client.exists(this.getKey(sessionId));
1672
+ return result === 1;
1673
+ } catch {
1674
+ return false;
1675
+ }
1676
+ }
1677
+ async touch(sessionId) {
1678
+ try {
1679
+ const session = await this.get(sessionId);
1680
+ if (!session) {
1681
+ return false;
1682
+ }
1683
+ session.lastAccessedAt = Date.now();
1684
+ const remainingTime = session.expiresAt - Date.now();
1685
+ if (remainingTime > 0) {
1686
+ await this.client.expire(this.getKey(sessionId), Math.floor(remainingTime / 1000));
1687
+ return true;
1688
+ }
1689
+ return false;
1690
+ } catch {
1691
+ return false;
1692
+ }
1693
+ }
1694
+ async clear() {
1695
+ return false;
1696
+ }
1697
+ }
1698
+ var SESSION_SERVICE_TOKEN = Symbol("@dangao/bun-server:session:service");
1699
+ var SESSION_OPTIONS_TOKEN = Symbol("@dangao/bun-server:session:options");
1700
+
1524
1701
  // src/controller/param-binder.ts
1525
1702
  class ParamBinder {
1526
- static async bind(target, propertyKey, context) {
1703
+ static async bind(target, propertyKey, context, container) {
1527
1704
  const metadata = getParamMetadata(target, propertyKey);
1528
1705
  const params = [];
1529
1706
  metadata.sort((a, b) => a.index - b.index);
1530
1707
  for (const meta of metadata) {
1531
- const value = await this.getValue(meta, context);
1708
+ const value = await this.getValue(meta, context, container);
1532
1709
  params[meta.index] = value;
1533
1710
  }
1534
1711
  const maxIndex = metadata.length > 0 ? Math.max(...metadata.map((m) => m.index)) : -1;
@@ -1539,7 +1716,7 @@ class ParamBinder {
1539
1716
  }
1540
1717
  return params;
1541
1718
  }
1542
- static async getValue(meta, context) {
1719
+ static async getValue(meta, context, container) {
1543
1720
  switch (meta.type) {
1544
1721
  case "body" /* BODY */:
1545
1722
  return await this.getBodyValue(meta.key, context);
@@ -1558,6 +1735,24 @@ class ParamBinder {
1558
1735
  throw new Error("@Header() decorator requires a key parameter");
1559
1736
  }
1560
1737
  return this.getHeaderValue(meta.key, context);
1738
+ case "session" /* SESSION */:
1739
+ if (!container) {
1740
+ throw new Error("@Session() decorator requires a Container instance");
1741
+ }
1742
+ const session = context.session;
1743
+ if (session) {
1744
+ return session;
1745
+ }
1746
+ try {
1747
+ const sessionService = container.resolve(SESSION_SERVICE_TOKEN);
1748
+ if (sessionService) {
1749
+ const newSession = await sessionService.create();
1750
+ context.session = newSession;
1751
+ context.sessionId = newSession.id;
1752
+ return newSession;
1753
+ }
1754
+ } catch {}
1755
+ return;
1561
1756
  default:
1562
1757
  return;
1563
1758
  }
@@ -2116,7 +2311,7 @@ class ControllerRegistry {
2116
2311
  const controllerContainer = this.controllerContainers.get(controllerClass) ?? this.container;
2117
2312
  const controllerInstance = controllerContainer.resolve(controllerClass);
2118
2313
  const prototype2 = controllerClass.prototype;
2119
- const params = await ParamBinder.bind(prototype2, propertyKey, context);
2314
+ const params = await ParamBinder.bind(prototype2, propertyKey, context, controllerContainer);
2120
2315
  const validationMetadata = getValidationMetadata(prototype2, propertyKey);
2121
2316
  if (validationMetadata.length > 0) {
2122
2317
  validateParameters(params, validationMetadata);
@@ -5181,6 +5376,885 @@ class StressTester {
5181
5376
  };
5182
5377
  }
5183
5378
  }
5379
+ // src/cache/types.ts
5380
+ class MemoryCacheStore {
5381
+ store = new Map;
5382
+ cleanupInterval;
5383
+ constructor(options) {
5384
+ if (options?.cleanupInterval !== undefined) {
5385
+ this.cleanupInterval = setInterval(() => {
5386
+ this.cleanup();
5387
+ }, options.cleanupInterval);
5388
+ }
5389
+ }
5390
+ async get(key) {
5391
+ const entry = this.store.get(key);
5392
+ if (!entry) {
5393
+ return;
5394
+ }
5395
+ if (entry.expiresAt && Date.now() > entry.expiresAt) {
5396
+ this.store.delete(key);
5397
+ return;
5398
+ }
5399
+ return entry.value;
5400
+ }
5401
+ async set(key, value, ttl) {
5402
+ const expiresAt = ttl && ttl > 0 ? Date.now() + ttl : undefined;
5403
+ this.store.set(key, { value, expiresAt });
5404
+ return true;
5405
+ }
5406
+ async delete(key) {
5407
+ return this.store.delete(key);
5408
+ }
5409
+ async has(key) {
5410
+ const entry = this.store.get(key);
5411
+ if (!entry) {
5412
+ return false;
5413
+ }
5414
+ if (entry.expiresAt && Date.now() > entry.expiresAt) {
5415
+ this.store.delete(key);
5416
+ return false;
5417
+ }
5418
+ return true;
5419
+ }
5420
+ async clear() {
5421
+ this.store.clear();
5422
+ return true;
5423
+ }
5424
+ async getMany(keys) {
5425
+ const result = new Map;
5426
+ const now = Date.now();
5427
+ for (const key of keys) {
5428
+ const entry = this.store.get(key);
5429
+ if (entry) {
5430
+ if (entry.expiresAt && now > entry.expiresAt) {
5431
+ this.store.delete(key);
5432
+ continue;
5433
+ }
5434
+ result.set(key, entry.value);
5435
+ }
5436
+ }
5437
+ return result;
5438
+ }
5439
+ async setMany(entries, ttl) {
5440
+ const expiresAt = ttl && ttl > 0 ? Date.now() + ttl : undefined;
5441
+ for (const { key, value } of entries) {
5442
+ this.store.set(key, { value, expiresAt });
5443
+ }
5444
+ return true;
5445
+ }
5446
+ async deleteMany(keys) {
5447
+ const deleted = [];
5448
+ for (const key of keys) {
5449
+ if (this.store.delete(key)) {
5450
+ deleted.push(key);
5451
+ }
5452
+ }
5453
+ return deleted;
5454
+ }
5455
+ cleanup() {
5456
+ const now = Date.now();
5457
+ for (const [key, entry] of this.store.entries()) {
5458
+ if (entry.expiresAt && now > entry.expiresAt) {
5459
+ this.store.delete(key);
5460
+ }
5461
+ }
5462
+ }
5463
+ destroy() {
5464
+ if (this.cleanupInterval) {
5465
+ clearInterval(this.cleanupInterval);
5466
+ this.cleanupInterval = undefined;
5467
+ }
5468
+ this.store.clear();
5469
+ }
5470
+ }
5471
+
5472
+ class RedisCacheStore {
5473
+ client;
5474
+ keyPrefix;
5475
+ constructor(options) {
5476
+ this.client = options.client;
5477
+ this.keyPrefix = options.keyPrefix ?? "cache:";
5478
+ }
5479
+ getKey(key) {
5480
+ return `${this.keyPrefix}${key}`;
5481
+ }
5482
+ async get(key) {
5483
+ const value = await this.client.get(this.getKey(key));
5484
+ if (value === null) {
5485
+ return;
5486
+ }
5487
+ try {
5488
+ return JSON.parse(value);
5489
+ } catch {
5490
+ return;
5491
+ }
5492
+ }
5493
+ async set(key, value, ttl) {
5494
+ try {
5495
+ const serialized = JSON.stringify(value);
5496
+ if (ttl && ttl > 0) {
5497
+ await this.client.set(this.getKey(key), serialized, { PX: ttl });
5498
+ } else {
5499
+ await this.client.set(this.getKey(key), serialized);
5500
+ }
5501
+ return true;
5502
+ } catch {
5503
+ return false;
5504
+ }
5505
+ }
5506
+ async delete(key) {
5507
+ try {
5508
+ await this.client.del(this.getKey(key));
5509
+ return true;
5510
+ } catch {
5511
+ return false;
5512
+ }
5513
+ }
5514
+ async has(key) {
5515
+ try {
5516
+ const result = await this.client.exists(this.getKey(key));
5517
+ return result === 1;
5518
+ } catch {
5519
+ return false;
5520
+ }
5521
+ }
5522
+ async clear() {
5523
+ try {
5524
+ await this.client.flushdb();
5525
+ return true;
5526
+ } catch {
5527
+ return false;
5528
+ }
5529
+ }
5530
+ async getMany(keys) {
5531
+ const result = new Map;
5532
+ if (keys.length === 0) {
5533
+ return result;
5534
+ }
5535
+ try {
5536
+ const prefixedKeys = keys.map((k) => this.getKey(k));
5537
+ const values = await this.client.mget(prefixedKeys);
5538
+ for (let i = 0;i < keys.length; i++) {
5539
+ const value = values[i];
5540
+ if (value !== null) {
5541
+ try {
5542
+ result.set(keys[i], JSON.parse(value));
5543
+ } catch {}
5544
+ }
5545
+ }
5546
+ } catch {}
5547
+ return result;
5548
+ }
5549
+ async setMany(entries, ttl) {
5550
+ if (entries.length === 0) {
5551
+ return true;
5552
+ }
5553
+ try {
5554
+ const redisEntries = entries.map(({ key, value }) => ({
5555
+ key: this.getKey(key),
5556
+ value: JSON.stringify(value)
5557
+ }));
5558
+ await this.client.mset(redisEntries);
5559
+ if (ttl && ttl > 0) {
5560
+ for (const entry of redisEntries) {
5561
+ await this.client.set(entry.key, entry.value, { PX: ttl });
5562
+ }
5563
+ }
5564
+ return true;
5565
+ } catch {
5566
+ return false;
5567
+ }
5568
+ }
5569
+ async deleteMany(keys) {
5570
+ if (keys.length === 0) {
5571
+ return [];
5572
+ }
5573
+ try {
5574
+ const prefixedKeys = keys.map((k) => this.getKey(k));
5575
+ const deleted = [];
5576
+ for (const key of prefixedKeys) {
5577
+ try {
5578
+ await this.client.del(key);
5579
+ deleted.push(key.replace(this.keyPrefix, ""));
5580
+ } catch {}
5581
+ }
5582
+ return deleted;
5583
+ } catch {
5584
+ return [];
5585
+ }
5586
+ }
5587
+ }
5588
+ var CACHE_SERVICE_TOKEN = Symbol("@dangao/bun-server:cache:service");
5589
+ var CACHE_OPTIONS_TOKEN = Symbol("@dangao/bun-server:cache:options");
5590
+
5591
+ // src/cache/service.ts
5592
+ class CacheService {
5593
+ store;
5594
+ defaultTtl;
5595
+ keyPrefix;
5596
+ constructor(options) {
5597
+ this.store = options.store;
5598
+ this.defaultTtl = options.defaultTtl ?? 3600000;
5599
+ this.keyPrefix = options.keyPrefix ?? "";
5600
+ }
5601
+ async get(key) {
5602
+ return this.store.get(this.getKey(key));
5603
+ }
5604
+ async set(key, value, ttl) {
5605
+ const finalTtl = ttl !== undefined ? ttl : this.defaultTtl;
5606
+ return this.store.set(this.getKey(key), value, finalTtl);
5607
+ }
5608
+ async delete(key) {
5609
+ return this.store.delete(this.getKey(key));
5610
+ }
5611
+ async has(key) {
5612
+ return this.store.has(this.getKey(key));
5613
+ }
5614
+ async clear() {
5615
+ return this.store.clear();
5616
+ }
5617
+ async getMany(keys) {
5618
+ const prefixedKeys = keys.map((k) => this.getKey(k));
5619
+ const result = await this.store.getMany(prefixedKeys);
5620
+ const map = new Map;
5621
+ for (const [key, value] of result.entries()) {
5622
+ map.set(key.replace(this.keyPrefix, ""), value);
5623
+ }
5624
+ return map;
5625
+ }
5626
+ async setMany(entries, ttl) {
5627
+ const finalTtl = ttl !== undefined ? ttl : this.defaultTtl;
5628
+ const prefixedEntries = entries.map(({ key, value }) => ({
5629
+ key: this.getKey(key),
5630
+ value
5631
+ }));
5632
+ return this.store.setMany(prefixedEntries, finalTtl);
5633
+ }
5634
+ async deleteMany(keys) {
5635
+ const prefixedKeys = keys.map((k) => this.getKey(k));
5636
+ const deleted = await this.store.deleteMany(prefixedKeys);
5637
+ return deleted.map((k) => k.replace(this.keyPrefix, ""));
5638
+ }
5639
+ async getOrSet(key, factory, ttl) {
5640
+ const cached = await this.get(key);
5641
+ if (cached !== undefined) {
5642
+ return cached;
5643
+ }
5644
+ const value = await factory();
5645
+ await this.set(key, value, ttl);
5646
+ return value;
5647
+ }
5648
+ getKey(key) {
5649
+ return this.keyPrefix ? `${this.keyPrefix}${key}` : key;
5650
+ }
5651
+ }
5652
+ CacheService = __legacyDecorateClassTS([
5653
+ Injectable(),
5654
+ __legacyDecorateParamTS(0, Inject(CACHE_OPTIONS_TOKEN)),
5655
+ __legacyMetadataTS("design:paramtypes", [
5656
+ typeof CacheModuleOptions === "undefined" ? Object : CacheModuleOptions
5657
+ ])
5658
+ ], CacheService);
5659
+
5660
+ // src/cache/cache-module.ts
5661
+ class CacheModule {
5662
+ static forRoot(options = {}) {
5663
+ const providers2 = [];
5664
+ const store = options.store ?? new MemoryCacheStore({
5665
+ cleanupInterval: 60000
5666
+ });
5667
+ const service = new CacheService({
5668
+ store,
5669
+ defaultTtl: options.defaultTtl,
5670
+ keyPrefix: options.keyPrefix
5671
+ });
5672
+ providers2.push({
5673
+ provide: CACHE_SERVICE_TOKEN,
5674
+ useValue: service
5675
+ }, {
5676
+ provide: CACHE_OPTIONS_TOKEN,
5677
+ useValue: options
5678
+ }, CacheService);
5679
+ const existingMetadata = Reflect.getMetadata(MODULE_METADATA_KEY, CacheModule) || {};
5680
+ const metadata = {
5681
+ ...existingMetadata,
5682
+ providers: [...existingMetadata.providers || [], ...providers2],
5683
+ exports: [
5684
+ ...existingMetadata.exports || [],
5685
+ CACHE_SERVICE_TOKEN,
5686
+ CACHE_OPTIONS_TOKEN,
5687
+ CacheService
5688
+ ]
5689
+ };
5690
+ Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, CacheModule);
5691
+ return CacheModule;
5692
+ }
5693
+ }
5694
+ CacheModule = __legacyDecorateClassTS([
5695
+ Module({
5696
+ providers: []
5697
+ })
5698
+ ], CacheModule);
5699
+ // src/cache/decorators.ts
5700
+ import"reflect-metadata";
5701
+ var CACHEABLE_METADATA_KEY = Symbol("@dangao/bun-server:cache:cacheable");
5702
+ var CACHE_EVICT_METADATA_KEY = Symbol("@dangao/bun-server:cache:cache-evict");
5703
+ var CACHE_PUT_METADATA_KEY = Symbol("@dangao/bun-server:cache:cache-put");
5704
+ function Cacheable(options = {}) {
5705
+ return function(target, propertyKey, descriptor) {
5706
+ const metadata = {
5707
+ key: options.key,
5708
+ keyPrefix: options.keyPrefix,
5709
+ ttl: options.ttl,
5710
+ condition: options.condition
5711
+ };
5712
+ Reflect.defineMetadata(CACHEABLE_METADATA_KEY, metadata, descriptor.value);
5713
+ };
5714
+ }
5715
+ function CacheEvict(options = {}) {
5716
+ return function(target, propertyKey, descriptor) {
5717
+ const metadata = {
5718
+ key: options.key,
5719
+ keyPrefix: options.keyPrefix,
5720
+ beforeInvocation: options.beforeInvocation ?? false,
5721
+ allEntries: options.allEntries ?? false
5722
+ };
5723
+ Reflect.defineMetadata(CACHE_EVICT_METADATA_KEY, metadata, descriptor.value);
5724
+ };
5725
+ }
5726
+ function CachePut(options = {}) {
5727
+ return function(target, propertyKey, descriptor) {
5728
+ const metadata = {
5729
+ key: options.key,
5730
+ keyPrefix: options.keyPrefix,
5731
+ ttl: options.ttl,
5732
+ condition: options.condition
5733
+ };
5734
+ Reflect.defineMetadata(CACHE_PUT_METADATA_KEY, metadata, descriptor.value);
5735
+ };
5736
+ }
5737
+ // src/queue/types.ts
5738
+ class MemoryQueueStore {
5739
+ queues = new Map;
5740
+ jobCounter = 0;
5741
+ async add(queueName, job) {
5742
+ const queue = this.getQueue(queueName);
5743
+ const jobId = job.options?.jobId ?? `job_${++this.jobCounter}_${Date.now()}`;
5744
+ const now = Date.now();
5745
+ const fullJob = {
5746
+ id: jobId,
5747
+ name: job.name,
5748
+ data: job.data,
5749
+ options: job.options,
5750
+ status: job.options?.delay ? "delayed" : "waiting",
5751
+ createdAt: now,
5752
+ updatedAt: now
5753
+ };
5754
+ queue.set(jobId, fullJob);
5755
+ return jobId;
5756
+ }
5757
+ async get(queueName, jobId) {
5758
+ const queue = this.getQueue(queueName);
5759
+ return queue.get(jobId);
5760
+ }
5761
+ async getNext(queueName) {
5762
+ const queue = this.getQueue(queueName);
5763
+ const now = Date.now();
5764
+ let nextJob;
5765
+ let highestPriority = -Infinity;
5766
+ for (const job of queue.values()) {
5767
+ if (job.status === "delayed" && job.options?.delay) {
5768
+ const delayEndTime = job.createdAt + job.options.delay;
5769
+ if (now >= delayEndTime) {
5770
+ if ((job.options.priority ?? 0) > highestPriority || !nextJob) {
5771
+ nextJob = job;
5772
+ highestPriority = job.options?.priority ?? 0;
5773
+ }
5774
+ }
5775
+ } else if (job.status === "waiting") {
5776
+ if ((job.options?.priority ?? 0) > highestPriority || !nextJob) {
5777
+ nextJob = job;
5778
+ highestPriority = job.options?.priority ?? 0;
5779
+ }
5780
+ }
5781
+ }
5782
+ return nextJob;
5783
+ }
5784
+ async updateStatus(queueName, jobId, status) {
5785
+ const queue = this.getQueue(queueName);
5786
+ const job = queue.get(jobId);
5787
+ if (!job) {
5788
+ return false;
5789
+ }
5790
+ job.status = status;
5791
+ job.updatedAt = Date.now();
5792
+ return true;
5793
+ }
5794
+ async delete(queueName, jobId) {
5795
+ const queue = this.getQueue(queueName);
5796
+ return queue.delete(jobId);
5797
+ }
5798
+ async clear(queueName) {
5799
+ const queue = this.getQueue(queueName);
5800
+ queue.clear();
5801
+ return true;
5802
+ }
5803
+ async count(queueName) {
5804
+ const queue = this.getQueue(queueName);
5805
+ return queue.size;
5806
+ }
5807
+ getQueue(queueName) {
5808
+ if (!this.queues.has(queueName)) {
5809
+ this.queues.set(queueName, new Map);
5810
+ }
5811
+ return this.queues.get(queueName);
5812
+ }
5813
+ }
5814
+ var QUEUE_SERVICE_TOKEN = Symbol("@dangao/bun-server:queue:service");
5815
+ var QUEUE_OPTIONS_TOKEN = Symbol("@dangao/bun-server:queue:options");
5816
+
5817
+ // src/queue/service.ts
5818
+ class QueueService {
5819
+ store;
5820
+ defaultQueue;
5821
+ enableWorker;
5822
+ concurrency;
5823
+ workers = new Map;
5824
+ cronJobs = new Map;
5825
+ cronTimers = new Map;
5826
+ constructor(options) {
5827
+ this.store = options.store;
5828
+ this.defaultQueue = options.defaultQueue ?? "default";
5829
+ this.enableWorker = options.enableWorker ?? true;
5830
+ this.concurrency = options.concurrency ?? 1;
5831
+ if (this.enableWorker) {
5832
+ this.startWorker(this.defaultQueue);
5833
+ }
5834
+ }
5835
+ async add(jobName, data, options, queueName) {
5836
+ const queue = queueName ?? this.defaultQueue;
5837
+ const jobId = await this.store.add(queue, {
5838
+ name: jobName,
5839
+ data,
5840
+ options
5841
+ });
5842
+ if (this.enableWorker && !this.workers.has(queue)) {
5843
+ this.startWorker(queue);
5844
+ }
5845
+ return jobId;
5846
+ }
5847
+ async get(jobId, queueName) {
5848
+ const queue = queueName ?? this.defaultQueue;
5849
+ return this.store.get(queue, jobId);
5850
+ }
5851
+ async delete(jobId, queueName) {
5852
+ const queue = queueName ?? this.defaultQueue;
5853
+ return this.store.delete(queue, jobId);
5854
+ }
5855
+ async clear(queueName) {
5856
+ const queue = queueName ?? this.defaultQueue;
5857
+ return this.store.clear(queue);
5858
+ }
5859
+ async count(queueName) {
5860
+ const queue = queueName ?? this.defaultQueue;
5861
+ return this.store.count(queue);
5862
+ }
5863
+ async registerHandler(jobName, handler, queueName) {
5864
+ const queue = queueName ?? this.defaultQueue;
5865
+ const key = `${queue}:${jobName}`;
5866
+ this.handlers = this.handlers ?? new Map;
5867
+ this.handlers.set(key, handler);
5868
+ }
5869
+ async registerCron(jobName, handler, options, queueName) {
5870
+ const queue = queueName ?? this.defaultQueue;
5871
+ const key = `${queue}:${jobName}`;
5872
+ this.cronJobs.set(key, { handler, options });
5873
+ if (options.runOnInit) {
5874
+ await this.add(jobName, {}, undefined, queue);
5875
+ }
5876
+ const interval = this.parseCronInterval(options.pattern);
5877
+ if (interval > 0) {
5878
+ const timer = setInterval(async () => {
5879
+ await this.add(jobName, {}, undefined, queue);
5880
+ }, interval);
5881
+ this.cronTimers.set(key, timer);
5882
+ }
5883
+ }
5884
+ startWorker(queueName) {
5885
+ if (this.workers.has(queueName)) {
5886
+ return;
5887
+ }
5888
+ const workerSet = new Set;
5889
+ this.workers.set(queueName, workerSet);
5890
+ for (let i = 0;i < this.concurrency; i++) {
5891
+ const worker = this.processQueue(queueName);
5892
+ workerSet.add(worker);
5893
+ }
5894
+ }
5895
+ async processQueue(queueName) {
5896
+ while (true) {
5897
+ try {
5898
+ const job = await this.store.getNext(queueName);
5899
+ if (!job) {
5900
+ await new Promise((resolve2) => setTimeout(resolve2, 1000));
5901
+ continue;
5902
+ }
5903
+ await this.store.updateStatus(queueName, job.id, "active");
5904
+ try {
5905
+ const handler = this.getHandler(job.name, queueName);
5906
+ if (handler) {
5907
+ await handler(job);
5908
+ await this.store.updateStatus(queueName, job.id, "completed");
5909
+ } else {
5910
+ await this.store.updateStatus(queueName, job.id, "failed");
5911
+ }
5912
+ } catch (error) {
5913
+ await this.store.updateStatus(queueName, job.id, "failed");
5914
+ console.error(`Job ${job.id} failed:`, error);
5915
+ }
5916
+ } catch (error) {
5917
+ console.error(`Error processing queue ${queueName}:`, error);
5918
+ await new Promise((resolve2) => setTimeout(resolve2, 1000));
5919
+ }
5920
+ }
5921
+ }
5922
+ getHandler(jobName, queueName) {
5923
+ const key = `${queueName}:${jobName}`;
5924
+ return this.handlers?.get(key);
5925
+ }
5926
+ parseCronInterval(pattern) {
5927
+ const parts = pattern.trim().split(/\s+/);
5928
+ if (parts.length !== 5) {
5929
+ return -1;
5930
+ }
5931
+ const [minute, hour, day, month, weekday] = parts;
5932
+ if (minute === "*" && hour === "*" && day === "*" && month === "*" && weekday === "*") {
5933
+ return 60000;
5934
+ }
5935
+ if (/^\d+$/.test(minute) && hour === "*" && day === "*" && month === "*" && weekday === "*") {
5936
+ return parseInt(minute, 10) * 60000;
5937
+ }
5938
+ return -1;
5939
+ }
5940
+ destroy() {
5941
+ for (const timer of this.cronTimers.values()) {
5942
+ clearInterval(timer);
5943
+ }
5944
+ this.cronTimers.clear();
5945
+ this.cronJobs.clear();
5946
+ this.workers.clear();
5947
+ }
5948
+ }
5949
+ QueueService = __legacyDecorateClassTS([
5950
+ Injectable(),
5951
+ __legacyDecorateParamTS(0, Inject(QUEUE_OPTIONS_TOKEN)),
5952
+ __legacyMetadataTS("design:paramtypes", [
5953
+ typeof QueueModuleOptions === "undefined" ? Object : QueueModuleOptions
5954
+ ])
5955
+ ], QueueService);
5956
+
5957
+ // src/queue/queue-module.ts
5958
+ class QueueModule {
5959
+ static forRoot(options = {}) {
5960
+ const providers2 = [];
5961
+ const store = options.store ?? new MemoryQueueStore;
5962
+ const service = new QueueService({
5963
+ store,
5964
+ defaultQueue: options.defaultQueue,
5965
+ enableWorker: options.enableWorker,
5966
+ concurrency: options.concurrency
5967
+ });
5968
+ providers2.push({
5969
+ provide: QUEUE_SERVICE_TOKEN,
5970
+ useValue: service
5971
+ }, {
5972
+ provide: QUEUE_OPTIONS_TOKEN,
5973
+ useValue: options
5974
+ }, QueueService);
5975
+ const existingMetadata = Reflect.getMetadata(MODULE_METADATA_KEY, QueueModule) || {};
5976
+ const metadata = {
5977
+ ...existingMetadata,
5978
+ providers: [...existingMetadata.providers || [], ...providers2],
5979
+ exports: [
5980
+ ...existingMetadata.exports || [],
5981
+ QUEUE_SERVICE_TOKEN,
5982
+ QUEUE_OPTIONS_TOKEN,
5983
+ QueueService
5984
+ ]
5985
+ };
5986
+ Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, QueueModule);
5987
+ return QueueModule;
5988
+ }
5989
+ }
5990
+ QueueModule = __legacyDecorateClassTS([
5991
+ Module({
5992
+ providers: []
5993
+ })
5994
+ ], QueueModule);
5995
+ // src/queue/decorators.ts
5996
+ import"reflect-metadata";
5997
+ var QUEUE_METADATA_KEY = Symbol("@dangao/bun-server:queue:queue");
5998
+ var CRON_METADATA_KEY = Symbol("@dangao/bun-server:queue:cron");
5999
+ function Queue(options = {}) {
6000
+ return function(target, propertyKey, descriptor) {
6001
+ const metadata = {
6002
+ name: options.name
6003
+ };
6004
+ Reflect.defineMetadata(QUEUE_METADATA_KEY, metadata, descriptor.value);
6005
+ };
6006
+ }
6007
+ function Cron(options) {
6008
+ return function(target, propertyKey, descriptor) {
6009
+ const metadata = {
6010
+ pattern: options.pattern,
6011
+ timezone: options.timezone,
6012
+ runOnInit: options.runOnInit ?? false,
6013
+ queueName: options.queueName
6014
+ };
6015
+ Reflect.defineMetadata(CRON_METADATA_KEY, metadata, descriptor.value);
6016
+ };
6017
+ }
6018
+ // src/session/service.ts
6019
+ import { randomBytes } from "crypto";
6020
+ class SessionService {
6021
+ store;
6022
+ name;
6023
+ maxAge;
6024
+ rolling;
6025
+ cookieOptions;
6026
+ constructor(options) {
6027
+ this.store = options.store;
6028
+ this.name = options.name ?? "sessionId";
6029
+ this.maxAge = options.maxAge ?? 86400000;
6030
+ this.rolling = options.rolling ?? true;
6031
+ this.cookieOptions = {
6032
+ secure: options.cookie?.secure ?? false,
6033
+ httpOnly: options.cookie?.httpOnly ?? true,
6034
+ path: options.cookie?.path ?? "/",
6035
+ domain: options.cookie?.domain,
6036
+ sameSite: options.cookie?.sameSite ?? "lax"
6037
+ };
6038
+ }
6039
+ generateSessionId() {
6040
+ return randomBytes(32).toString("hex");
6041
+ }
6042
+ async create(initialData = {}) {
6043
+ const now = Date.now();
6044
+ const session = {
6045
+ id: this.generateSessionId(),
6046
+ data: initialData,
6047
+ createdAt: now,
6048
+ lastAccessedAt: now,
6049
+ expiresAt: now + this.maxAge
6050
+ };
6051
+ await this.store.set(session, this.maxAge);
6052
+ return session;
6053
+ }
6054
+ async get(sessionId) {
6055
+ const session = await this.store.get(sessionId);
6056
+ if (!session) {
6057
+ return;
6058
+ }
6059
+ if (this.rolling) {
6060
+ await this.touch(sessionId);
6061
+ }
6062
+ return session;
6063
+ }
6064
+ async set(sessionId, data) {
6065
+ const session = await this.store.get(sessionId);
6066
+ if (!session) {
6067
+ return false;
6068
+ }
6069
+ session.data = { ...session.data, ...data };
6070
+ session.lastAccessedAt = Date.now();
6071
+ if (this.rolling) {
6072
+ session.expiresAt = Date.now() + this.maxAge;
6073
+ }
6074
+ return this.store.set(session, this.maxAge);
6075
+ }
6076
+ async getValue(sessionId, key) {
6077
+ const session = await this.store.get(sessionId);
6078
+ if (!session) {
6079
+ return;
6080
+ }
6081
+ return session.data[key];
6082
+ }
6083
+ async setValue(sessionId, key, value) {
6084
+ const session = await this.store.get(sessionId);
6085
+ if (!session) {
6086
+ return false;
6087
+ }
6088
+ session.data[key] = value;
6089
+ session.lastAccessedAt = Date.now();
6090
+ if (this.rolling) {
6091
+ session.expiresAt = Date.now() + this.maxAge;
6092
+ }
6093
+ return this.store.set(session, this.maxAge);
6094
+ }
6095
+ async deleteValue(sessionId, key) {
6096
+ const session = await this.store.get(sessionId);
6097
+ if (!session) {
6098
+ return false;
6099
+ }
6100
+ delete session.data[key];
6101
+ session.lastAccessedAt = Date.now();
6102
+ if (this.rolling) {
6103
+ session.expiresAt = Date.now() + this.maxAge;
6104
+ }
6105
+ return this.store.set(session, this.maxAge);
6106
+ }
6107
+ async delete(sessionId) {
6108
+ return this.store.delete(sessionId);
6109
+ }
6110
+ async touch(sessionId) {
6111
+ return this.store.touch(sessionId);
6112
+ }
6113
+ getCookieName() {
6114
+ return this.name;
6115
+ }
6116
+ getCookieOptions() {
6117
+ return this.cookieOptions;
6118
+ }
6119
+ getMaxAge() {
6120
+ return this.maxAge;
6121
+ }
6122
+ }
6123
+ SessionService = __legacyDecorateClassTS([
6124
+ Injectable(),
6125
+ __legacyDecorateParamTS(0, Inject(SESSION_OPTIONS_TOKEN)),
6126
+ __legacyMetadataTS("design:paramtypes", [
6127
+ typeof SessionModuleOptions === "undefined" ? Object : SessionModuleOptions
6128
+ ])
6129
+ ], SessionService);
6130
+
6131
+ // src/session/session-module.ts
6132
+ class SessionModule {
6133
+ static forRoot(options = {}) {
6134
+ const providers2 = [];
6135
+ const store = options.store ?? new MemorySessionStore({
6136
+ cleanupInterval: 60000
6137
+ });
6138
+ const service = new SessionService({
6139
+ store,
6140
+ name: options.name,
6141
+ maxAge: options.maxAge,
6142
+ rolling: options.rolling,
6143
+ cookie: options.cookie
6144
+ });
6145
+ providers2.push({
6146
+ provide: SESSION_SERVICE_TOKEN,
6147
+ useValue: service
6148
+ }, {
6149
+ provide: SESSION_OPTIONS_TOKEN,
6150
+ useValue: options
6151
+ }, SessionService);
6152
+ const existingMetadata = Reflect.getMetadata(MODULE_METADATA_KEY, SessionModule) || {};
6153
+ const metadata = {
6154
+ ...existingMetadata,
6155
+ providers: [...existingMetadata.providers || [], ...providers2],
6156
+ exports: [
6157
+ ...existingMetadata.exports || [],
6158
+ SESSION_SERVICE_TOKEN,
6159
+ SESSION_OPTIONS_TOKEN,
6160
+ SessionService
6161
+ ]
6162
+ };
6163
+ Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, SessionModule);
6164
+ return SessionModule;
6165
+ }
6166
+ }
6167
+ SessionModule = __legacyDecorateClassTS([
6168
+ Module({
6169
+ providers: []
6170
+ })
6171
+ ], SessionModule);
6172
+ // src/session/middleware.ts
6173
+ function createSessionMiddleware(container) {
6174
+ return async (context2, next) => {
6175
+ let sessionService;
6176
+ try {
6177
+ sessionService = container.resolve(SESSION_SERVICE_TOKEN);
6178
+ } catch {
6179
+ return await next();
6180
+ }
6181
+ if (!sessionService) {
6182
+ return await next();
6183
+ }
6184
+ const cookieName = sessionService.getCookieName();
6185
+ const cookieHeader = context2.request.headers.get("cookie");
6186
+ let sessionId;
6187
+ if (cookieHeader) {
6188
+ const cookies = cookieHeader.split(";").map((c) => c.trim());
6189
+ for (const cookie of cookies) {
6190
+ if (cookie.startsWith(`${cookieName}=`)) {
6191
+ sessionId = cookie.substring(cookieName.length + 1).trim();
6192
+ break;
6193
+ }
6194
+ }
6195
+ }
6196
+ if (sessionId) {
6197
+ const session = await sessionService.get(sessionId);
6198
+ if (session) {
6199
+ context2.session = session;
6200
+ context2.sessionId = sessionId;
6201
+ } else {
6202
+ sessionId = undefined;
6203
+ }
6204
+ }
6205
+ if (!sessionId) {
6206
+ const newSession = await sessionService.create();
6207
+ context2.session = newSession;
6208
+ context2.sessionId = newSession.id;
6209
+ sessionId = newSession.id;
6210
+ }
6211
+ const response = await next();
6212
+ const currentSessionId = context2.sessionId;
6213
+ if (currentSessionId) {
6214
+ const cookieOptions = sessionService.getCookieOptions();
6215
+ const maxAge = sessionService.getMaxAge();
6216
+ const cookieValue = buildCookie(cookieName, currentSessionId, {
6217
+ ...cookieOptions,
6218
+ maxAge
6219
+ });
6220
+ const newHeaders = new Headers(response.headers);
6221
+ newHeaders.set("Set-Cookie", cookieValue);
6222
+ return new Response(response.body, {
6223
+ status: response.status,
6224
+ statusText: response.statusText,
6225
+ headers: newHeaders
6226
+ });
6227
+ }
6228
+ return response;
6229
+ };
6230
+ }
6231
+ function buildCookie(name, value, options) {
6232
+ let cookie = `${name}=${value}`;
6233
+ if (options.path) {
6234
+ cookie += `; Path=${options.path}`;
6235
+ }
6236
+ if (options.domain) {
6237
+ cookie += `; Domain=${options.domain}`;
6238
+ }
6239
+ if (options.maxAge) {
6240
+ cookie += `; Max-Age=${Math.floor(options.maxAge / 1000)}`;
6241
+ }
6242
+ if (options.secure) {
6243
+ cookie += "; Secure";
6244
+ }
6245
+ if (options.httpOnly) {
6246
+ cookie += "; HttpOnly";
6247
+ }
6248
+ if (options.sameSite) {
6249
+ cookie += `; SameSite=${options.sameSite}`;
6250
+ }
6251
+ return cookie;
6252
+ }
6253
+ // src/session/decorators.ts
6254
+ import"reflect-metadata";
6255
+ function Session() {
6256
+ return createParamDecorator("session" /* SESSION */);
6257
+ }
5184
6258
  export {
5185
6259
  requiresAuth,
5186
6260
  getTransactionMetadata,
@@ -5192,6 +6266,7 @@ export {
5192
6266
  createTokenKeyGenerator,
5193
6267
  createSwaggerUIMiddleware,
5194
6268
  createStaticFileMiddleware,
6269
+ createSessionMiddleware,
5195
6270
  createSecurityFilter,
5196
6271
  createRequestLoggingMiddleware,
5197
6272
  createRateLimitMiddleware,
@@ -5216,8 +6291,13 @@ export {
5216
6291
  SwaggerGenerator,
5217
6292
  SwaggerExtension,
5218
6293
  StressTester,
6294
+ SessionService,
6295
+ SessionModule,
6296
+ Session,
5219
6297
  SecurityModule,
5220
6298
  SecurityContextHolder,
6299
+ SESSION_SERVICE_TOKEN,
6300
+ SESSION_OPTIONS_TOKEN,
5221
6301
  Router,
5222
6302
  RouteRegistry,
5223
6303
  Route,
@@ -5225,8 +6305,15 @@ export {
5225
6305
  ResponseBuilder,
5226
6306
  RequestWrapper,
5227
6307
  Repository,
6308
+ RedisSessionStore,
6309
+ RedisCacheStore,
5228
6310
  RateLimit,
6311
+ QueueService,
6312
+ QueueModule,
6313
+ Queue,
5229
6314
  Query,
6315
+ QUEUE_SERVICE_TOKEN,
6316
+ QUEUE_OPTIONS_TOKEN,
5230
6317
  Propagation,
5231
6318
  PrometheusFormatter,
5232
6319
  PrimaryKey,
@@ -5252,6 +6339,9 @@ export {
5252
6339
  MiddlewarePipeline,
5253
6340
  MetricsModule,
5254
6341
  MetricsCollector,
6342
+ MemorySessionStore,
6343
+ MemoryQueueStore,
6344
+ MemoryCacheStore,
5255
6345
  METRICS_SERVICE_TOKEN,
5256
6346
  METRICS_OPTIONS_TOKEN,
5257
6347
  LoggerModule,
@@ -5288,6 +6378,7 @@ export {
5288
6378
  DELETE,
5289
6379
  DATABASE_SERVICE_TOKEN,
5290
6380
  DATABASE_OPTIONS_TOKEN,
6381
+ Cron,
5291
6382
  ControllerRegistry,
5292
6383
  Controller,
5293
6384
  Context,
@@ -5296,7 +6387,14 @@ export {
5296
6387
  ConfigService,
5297
6388
  ConfigModule,
5298
6389
  Column,
6390
+ Cacheable,
6391
+ CacheService,
6392
+ CachePut,
6393
+ CacheModule,
6394
+ CacheEvict,
5299
6395
  CONFIG_SERVICE_TOKEN,
6396
+ CACHE_SERVICE_TOKEN,
6397
+ CACHE_OPTIONS_TOKEN,
5300
6398
  BunServer,
5301
6399
  BodyParser,
5302
6400
  Body,