@dangao/bun-server 1.7.1 → 1.8.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 (116) hide show
  1. package/README.md +129 -21
  2. package/dist/di/decorators.d.ts +37 -0
  3. package/dist/di/decorators.d.ts.map +1 -1
  4. package/dist/di/index.d.ts +1 -1
  5. package/dist/di/index.d.ts.map +1 -1
  6. package/dist/di/module-registry.d.ts +17 -0
  7. package/dist/di/module-registry.d.ts.map +1 -1
  8. package/dist/events/decorators.d.ts +52 -0
  9. package/dist/events/decorators.d.ts.map +1 -0
  10. package/dist/events/event-module.d.ts +97 -0
  11. package/dist/events/event-module.d.ts.map +1 -0
  12. package/dist/events/index.d.ts +5 -0
  13. package/dist/events/index.d.ts.map +1 -0
  14. package/dist/events/service.d.ts +76 -0
  15. package/dist/events/service.d.ts.map +1 -0
  16. package/dist/events/types.d.ts +184 -0
  17. package/dist/events/types.d.ts.map +1 -0
  18. package/dist/index.d.ts +5 -3
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1511 -11
  21. package/dist/security/filter.d.ts +23 -0
  22. package/dist/security/filter.d.ts.map +1 -1
  23. package/dist/security/guards/builtin/auth-guard.d.ts +44 -0
  24. package/dist/security/guards/builtin/auth-guard.d.ts.map +1 -0
  25. package/dist/security/guards/builtin/index.d.ts +3 -0
  26. package/dist/security/guards/builtin/index.d.ts.map +1 -0
  27. package/dist/security/guards/builtin/roles-guard.d.ts +66 -0
  28. package/dist/security/guards/builtin/roles-guard.d.ts.map +1 -0
  29. package/dist/security/guards/decorators.d.ts +50 -0
  30. package/dist/security/guards/decorators.d.ts.map +1 -0
  31. package/dist/security/guards/execution-context.d.ts +56 -0
  32. package/dist/security/guards/execution-context.d.ts.map +1 -0
  33. package/dist/security/guards/guard-registry.d.ts +67 -0
  34. package/dist/security/guards/guard-registry.d.ts.map +1 -0
  35. package/dist/security/guards/index.d.ts +7 -0
  36. package/dist/security/guards/index.d.ts.map +1 -0
  37. package/dist/security/guards/reflector.d.ts +57 -0
  38. package/dist/security/guards/reflector.d.ts.map +1 -0
  39. package/dist/security/guards/types.d.ts +126 -0
  40. package/dist/security/guards/types.d.ts.map +1 -0
  41. package/dist/security/index.d.ts +1 -0
  42. package/dist/security/index.d.ts.map +1 -1
  43. package/dist/security/security-module.d.ts +20 -0
  44. package/dist/security/security-module.d.ts.map +1 -1
  45. package/dist/validation/class-validator.d.ts +108 -0
  46. package/dist/validation/class-validator.d.ts.map +1 -0
  47. package/dist/validation/custom-validator.d.ts +130 -0
  48. package/dist/validation/custom-validator.d.ts.map +1 -0
  49. package/dist/validation/errors.d.ts +22 -2
  50. package/dist/validation/errors.d.ts.map +1 -1
  51. package/dist/validation/index.d.ts +7 -1
  52. package/dist/validation/index.d.ts.map +1 -1
  53. package/dist/validation/rules/array.d.ts +33 -0
  54. package/dist/validation/rules/array.d.ts.map +1 -0
  55. package/dist/validation/rules/common.d.ts +90 -0
  56. package/dist/validation/rules/common.d.ts.map +1 -0
  57. package/dist/validation/rules/conditional.d.ts +30 -0
  58. package/dist/validation/rules/conditional.d.ts.map +1 -0
  59. package/dist/validation/rules/index.d.ts +5 -0
  60. package/dist/validation/rules/index.d.ts.map +1 -0
  61. package/dist/validation/rules/object.d.ts +30 -0
  62. package/dist/validation/rules/object.d.ts.map +1 -0
  63. package/dist/validation/types.d.ts +52 -1
  64. package/dist/validation/types.d.ts.map +1 -1
  65. package/docs/events.md +494 -0
  66. package/docs/guards.md +376 -0
  67. package/docs/guide.md +309 -1
  68. package/docs/request-lifecycle.md +444 -0
  69. package/docs/validation.md +407 -0
  70. package/docs/zh/events.md +494 -0
  71. package/docs/zh/guards.md +376 -0
  72. package/docs/zh/guide.md +309 -1
  73. package/docs/zh/request-lifecycle.md +444 -0
  74. package/docs/zh/validation.md +407 -0
  75. package/package.json +1 -1
  76. package/src/di/decorators.ts +46 -0
  77. package/src/di/index.ts +10 -1
  78. package/src/di/module-registry.ts +39 -0
  79. package/src/events/decorators.ts +103 -0
  80. package/src/events/event-module.ts +272 -0
  81. package/src/events/index.ts +32 -0
  82. package/src/events/service.ts +352 -0
  83. package/src/events/types.ts +223 -0
  84. package/src/index.ts +133 -1
  85. package/src/security/filter.ts +88 -8
  86. package/src/security/guards/builtin/auth-guard.ts +68 -0
  87. package/src/security/guards/builtin/index.ts +3 -0
  88. package/src/security/guards/builtin/roles-guard.ts +165 -0
  89. package/src/security/guards/decorators.ts +124 -0
  90. package/src/security/guards/execution-context.ts +152 -0
  91. package/src/security/guards/guard-registry.ts +164 -0
  92. package/src/security/guards/index.ts +7 -0
  93. package/src/security/guards/reflector.ts +99 -0
  94. package/src/security/guards/types.ts +144 -0
  95. package/src/security/index.ts +1 -0
  96. package/src/security/security-module.ts +72 -2
  97. package/src/validation/class-validator.ts +322 -0
  98. package/src/validation/custom-validator.ts +289 -0
  99. package/src/validation/errors.ts +50 -2
  100. package/src/validation/index.ts +103 -1
  101. package/src/validation/rules/array.ts +118 -0
  102. package/src/validation/rules/common.ts +286 -0
  103. package/src/validation/rules/conditional.ts +52 -0
  104. package/src/validation/rules/index.ts +51 -0
  105. package/src/validation/rules/object.ts +86 -0
  106. package/src/validation/types.ts +61 -1
  107. package/tests/di/global-module.test.ts +487 -0
  108. package/tests/events/event-decorators.test.ts +173 -0
  109. package/tests/events/event-emitter.test.ts +373 -0
  110. package/tests/events/event-module.test.ts +373 -0
  111. package/tests/security/guards/guards-integration.test.ts +371 -0
  112. package/tests/security/guards/guards.test.ts +775 -0
  113. package/tests/security/security-module.test.ts +2 -2
  114. package/tests/validation/class-validator.test.ts +349 -0
  115. package/tests/validation/custom-validator.test.ts +335 -0
  116. package/tests/validation/rules.test.ts +543 -0
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ var __create = Object.create;
3
3
  var __getProtoOf = Object.getPrototypeOf;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
8
  var __toESM = (mod, isNodeMode, target) => {
8
9
  target = mod != null ? __create(__getProtoOf(mod)) : {};
@@ -15,6 +16,20 @@ var __toESM = (mod, isNodeMode, target) => {
15
16
  });
16
17
  return to;
17
18
  };
19
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
20
+ var __toCommonJS = (from) => {
21
+ var entry = __moduleCache.get(from), desc;
22
+ if (entry)
23
+ return entry;
24
+ entry = __defProp({}, "__esModule", { value: true });
25
+ if (from && typeof from === "object" || typeof from === "function")
26
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
27
+ get: () => from[key],
28
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
29
+ }));
30
+ __moduleCache.set(from, entry);
31
+ return entry;
32
+ };
18
33
  var __export = (target, all) => {
19
34
  for (var name in all)
20
35
  __defProp(target, name, {
@@ -136,10 +151,19 @@ function getTypeReference(constructor, parameterIndex) {
136
151
  }
137
152
  return;
138
153
  }
139
- var DEPENDENCY_METADATA_KEY, INJECTABLE_METADATA_KEY, typeReferenceMap;
154
+ function Global() {
155
+ return (target) => {
156
+ Reflect.defineMetadata(GLOBAL_MODULE_METADATA_KEY, true, target);
157
+ };
158
+ }
159
+ function isGlobalModule(target) {
160
+ return Reflect.getMetadata(GLOBAL_MODULE_METADATA_KEY, target) === true;
161
+ }
162
+ var DEPENDENCY_METADATA_KEY, INJECTABLE_METADATA_KEY, GLOBAL_MODULE_METADATA_KEY, typeReferenceMap;
140
163
  var init_decorators = __esm(() => {
141
164
  DEPENDENCY_METADATA_KEY = Symbol("dependency:metadata");
142
165
  INJECTABLE_METADATA_KEY = Symbol("injectable");
166
+ GLOBAL_MODULE_METADATA_KEY = Symbol("@dangao/bun-server:global-module");
143
167
  typeReferenceMap = new WeakMap;
144
168
  });
145
169
 
@@ -1437,6 +1461,31 @@ var init_errors = __esm(() => {
1437
1461
  this.name = "ValidationError";
1438
1462
  this.issues = issues;
1439
1463
  }
1464
+ getFlattened() {
1465
+ const flatten = (issues, prefix = "") => {
1466
+ const result = [];
1467
+ for (const issue of issues) {
1468
+ const propertyPath = prefix ? `${prefix}.${issue.property ?? ""}` : issue.property ?? "";
1469
+ if (issue.children && issue.children.length > 0) {
1470
+ result.push(...flatten(issue.children, propertyPath));
1471
+ } else {
1472
+ result.push({
1473
+ ...issue,
1474
+ property: propertyPath || undefined
1475
+ });
1476
+ }
1477
+ }
1478
+ return result;
1479
+ };
1480
+ return flatten(this.issues);
1481
+ }
1482
+ toJSON() {
1483
+ return {
1484
+ name: this.name,
1485
+ message: this.message,
1486
+ issues: this.issues
1487
+ };
1488
+ }
1440
1489
  };
1441
1490
  });
1442
1491
 
@@ -1488,11 +1537,614 @@ var init_validator = __esm(() => {
1488
1537
  init_errors();
1489
1538
  });
1490
1539
 
1540
+ // src/validation/rules/object.ts
1541
+ function IsObject(options = {}) {
1542
+ return {
1543
+ name: "isObject",
1544
+ message: options.message ?? "\u5FC5\u987B\u662F\u5BF9\u8C61",
1545
+ validate: (value) => typeof value === "object" && value !== null && !Array.isArray(value)
1546
+ };
1547
+ }
1548
+ function IsNotEmpty(options = {}) {
1549
+ return {
1550
+ name: "isNotEmpty",
1551
+ message: options.message ?? "\u4E0D\u80FD\u4E3A\u7A7A",
1552
+ validate: (value) => {
1553
+ if (value === null || value === undefined) {
1554
+ return false;
1555
+ }
1556
+ if (typeof value === "string") {
1557
+ return value.trim().length > 0;
1558
+ }
1559
+ if (Array.isArray(value)) {
1560
+ return value.length > 0;
1561
+ }
1562
+ if (typeof value === "object") {
1563
+ return Object.keys(value).length > 0;
1564
+ }
1565
+ return true;
1566
+ }
1567
+ };
1568
+ }
1569
+ function IsNotEmptyObject(options = {}) {
1570
+ return {
1571
+ name: "isNotEmptyObject",
1572
+ message: options.message ?? "\u5FC5\u987B\u662F\u975E\u7A7A\u5BF9\u8C61",
1573
+ validate: (value) => {
1574
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
1575
+ return false;
1576
+ }
1577
+ return Object.keys(value).length > 0;
1578
+ }
1579
+ };
1580
+ }
1581
+ function ValidateNested(options = {}) {
1582
+ return {
1583
+ name: "validateNested",
1584
+ message: options.message ?? "\u5D4C\u5957\u5BF9\u8C61\u9A8C\u8BC1\u5931\u8D25",
1585
+ nested: true,
1586
+ each: options.each ?? false,
1587
+ validate: (value) => {
1588
+ if (options.each) {
1589
+ return Array.isArray(value);
1590
+ }
1591
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1592
+ }
1593
+ };
1594
+ }
1595
+
1596
+ // src/validation/rules/array.ts
1597
+ function IsArray(options = {}) {
1598
+ return {
1599
+ name: "isArray",
1600
+ message: options.message ?? "\u5FC5\u987B\u662F\u6570\u7EC4",
1601
+ validate: (value) => Array.isArray(value)
1602
+ };
1603
+ }
1604
+ function ArrayMinSize(min, options = {}) {
1605
+ return {
1606
+ name: "arrayMinSize",
1607
+ message: options.message ?? `\u6570\u7EC4\u957F\u5EA6\u4E0D\u80FD\u5C0F\u4E8E ${min}`,
1608
+ validate: (value) => Array.isArray(value) && value.length >= min
1609
+ };
1610
+ }
1611
+ function ArrayMaxSize(max, options = {}) {
1612
+ return {
1613
+ name: "arrayMaxSize",
1614
+ message: options.message ?? `\u6570\u7EC4\u957F\u5EA6\u4E0D\u80FD\u5927\u4E8E ${max}`,
1615
+ validate: (value) => Array.isArray(value) && value.length <= max
1616
+ };
1617
+ }
1618
+ function ArrayUnique(options = {}) {
1619
+ return {
1620
+ name: "arrayUnique",
1621
+ message: options.message ?? "\u6570\u7EC4\u5143\u7D20\u5FC5\u987B\u552F\u4E00",
1622
+ validate: (value) => {
1623
+ if (!Array.isArray(value)) {
1624
+ return false;
1625
+ }
1626
+ const seen = new Set;
1627
+ for (const item of value) {
1628
+ const key = typeof item === "object" ? JSON.stringify(item) : item;
1629
+ if (seen.has(key)) {
1630
+ return false;
1631
+ }
1632
+ seen.add(key);
1633
+ }
1634
+ return true;
1635
+ }
1636
+ };
1637
+ }
1638
+ function ArrayContains(values, options = {}) {
1639
+ return {
1640
+ name: "arrayContains",
1641
+ message: options.message ?? `\u6570\u7EC4\u5FC5\u987B\u5305\u542B ${values.join(", ")}`,
1642
+ validate: (value) => {
1643
+ if (!Array.isArray(value)) {
1644
+ return false;
1645
+ }
1646
+ return values.every((v) => {
1647
+ if (typeof v === "object") {
1648
+ const vStr = JSON.stringify(v);
1649
+ return value.some((item) => JSON.stringify(item) === vStr);
1650
+ }
1651
+ return value.includes(v);
1652
+ });
1653
+ }
1654
+ };
1655
+ }
1656
+ function ArrayNotContains(values, options = {}) {
1657
+ return {
1658
+ name: "arrayNotContains",
1659
+ message: options.message ?? `\u6570\u7EC4\u4E0D\u80FD\u5305\u542B ${values.join(", ")}`,
1660
+ validate: (value) => {
1661
+ if (!Array.isArray(value)) {
1662
+ return false;
1663
+ }
1664
+ return values.every((v) => {
1665
+ if (typeof v === "object") {
1666
+ const vStr = JSON.stringify(v);
1667
+ return !value.some((item) => JSON.stringify(item) === vStr);
1668
+ }
1669
+ return !value.includes(v);
1670
+ });
1671
+ }
1672
+ };
1673
+ }
1674
+ function ArrayNotEmpty(options = {}) {
1675
+ return {
1676
+ name: "arrayNotEmpty",
1677
+ message: options.message ?? "\u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A",
1678
+ validate: (value) => Array.isArray(value) && value.length > 0
1679
+ };
1680
+ }
1681
+
1682
+ // src/validation/rules/common.ts
1683
+ function IsBoolean(options = {}) {
1684
+ return {
1685
+ name: "isBoolean",
1686
+ message: options.message ?? "\u5FC5\u987B\u662F\u5E03\u5C14\u503C",
1687
+ validate: (value) => typeof value === "boolean"
1688
+ };
1689
+ }
1690
+ function IsInt(options = {}) {
1691
+ return {
1692
+ name: "isInt",
1693
+ message: options.message ?? "\u5FC5\u987B\u662F\u6574\u6570",
1694
+ validate: (value) => typeof value === "number" && Number.isInteger(value)
1695
+ };
1696
+ }
1697
+ function IsPositive(options = {}) {
1698
+ return {
1699
+ name: "isPositive",
1700
+ message: options.message ?? "\u5FC5\u987B\u662F\u6B63\u6570",
1701
+ validate: (value) => typeof value === "number" && value > 0
1702
+ };
1703
+ }
1704
+ function IsNegative(options = {}) {
1705
+ return {
1706
+ name: "isNegative",
1707
+ message: options.message ?? "\u5FC5\u987B\u662F\u8D1F\u6570",
1708
+ validate: (value) => typeof value === "number" && value < 0
1709
+ };
1710
+ }
1711
+ function Min(min, options = {}) {
1712
+ return {
1713
+ name: "min",
1714
+ message: options.message ?? `\u4E0D\u80FD\u5C0F\u4E8E ${min}`,
1715
+ validate: (value) => typeof value === "number" && value >= min
1716
+ };
1717
+ }
1718
+ function Max(max, options = {}) {
1719
+ return {
1720
+ name: "max",
1721
+ message: options.message ?? `\u4E0D\u80FD\u5927\u4E8E ${max}`,
1722
+ validate: (value) => typeof value === "number" && value <= max
1723
+ };
1724
+ }
1725
+ function IsDate(options = {}) {
1726
+ return {
1727
+ name: "isDate",
1728
+ message: options.message ?? "\u5FC5\u987B\u662F\u6709\u6548\u7684\u65E5\u671F",
1729
+ validate: (value) => {
1730
+ if (value instanceof Date) {
1731
+ return !Number.isNaN(value.getTime());
1732
+ }
1733
+ if (typeof value === "string" || typeof value === "number") {
1734
+ const date = new Date(value);
1735
+ return !Number.isNaN(date.getTime());
1736
+ }
1737
+ return false;
1738
+ }
1739
+ };
1740
+ }
1741
+ function IsUUID(version = "all", options = {}) {
1742
+ return {
1743
+ name: "isUUID",
1744
+ message: options.message ?? `\u5FC5\u987B\u662F\u6709\u6548\u7684 UUID${version !== "all" ? ` (v${version})` : ""}`,
1745
+ validate: (value) => typeof value === "string" && UUID_PATTERNS[version].test(value)
1746
+ };
1747
+ }
1748
+ function Length(min, max, options = {}) {
1749
+ const maxMsg = max !== undefined ? ` \u4E14\u4E0D\u80FD\u5927\u4E8E ${max}` : "";
1750
+ return {
1751
+ name: "length",
1752
+ message: options.message ?? `\u957F\u5EA6\u4E0D\u80FD\u5C0F\u4E8E ${min}${maxMsg}`,
1753
+ validate: (value) => {
1754
+ if (typeof value !== "string") {
1755
+ return false;
1756
+ }
1757
+ if (value.length < min) {
1758
+ return false;
1759
+ }
1760
+ if (max !== undefined && value.length > max) {
1761
+ return false;
1762
+ }
1763
+ return true;
1764
+ }
1765
+ };
1766
+ }
1767
+ function MaxLength(max, options = {}) {
1768
+ return {
1769
+ name: "maxLength",
1770
+ message: options.message ?? `\u957F\u5EA6\u4E0D\u80FD\u5927\u4E8E ${max}`,
1771
+ validate: (value) => typeof value === "string" && value.length <= max
1772
+ };
1773
+ }
1774
+ function Matches(pattern, options = {}) {
1775
+ return {
1776
+ name: "matches",
1777
+ message: options.message ?? `\u5FC5\u987B\u5339\u914D\u683C\u5F0F ${pattern.toString()}`,
1778
+ validate: (value) => typeof value === "string" && pattern.test(value)
1779
+ };
1780
+ }
1781
+ function IsIn(values, options = {}) {
1782
+ return {
1783
+ name: "isIn",
1784
+ message: options.message ?? `\u5FC5\u987B\u662F\u4EE5\u4E0B\u503C\u4E4B\u4E00: ${values.join(", ")}`,
1785
+ validate: (value) => values.includes(value)
1786
+ };
1787
+ }
1788
+ function IsNotIn(values, options = {}) {
1789
+ return {
1790
+ name: "isNotIn",
1791
+ message: options.message ?? `\u4E0D\u80FD\u662F\u4EE5\u4E0B\u503C\u4E4B\u4E00: ${values.join(", ")}`,
1792
+ validate: (value) => !values.includes(value)
1793
+ };
1794
+ }
1795
+ function IsUrl(options = {}) {
1796
+ return {
1797
+ name: "isUrl",
1798
+ message: options.message ?? "\u5FC5\u987B\u662F\u6709\u6548\u7684 URL",
1799
+ validate: (value) => {
1800
+ if (typeof value !== "string") {
1801
+ return false;
1802
+ }
1803
+ try {
1804
+ new URL(value);
1805
+ return true;
1806
+ } catch {
1807
+ return false;
1808
+ }
1809
+ }
1810
+ };
1811
+ }
1812
+ function IsJSON(options = {}) {
1813
+ return {
1814
+ name: "isJSON",
1815
+ message: options.message ?? "\u5FC5\u987B\u662F\u6709\u6548\u7684 JSON \u5B57\u7B26\u4E32",
1816
+ validate: (value) => {
1817
+ if (typeof value !== "string") {
1818
+ return false;
1819
+ }
1820
+ try {
1821
+ JSON.parse(value);
1822
+ return true;
1823
+ } catch {
1824
+ return false;
1825
+ }
1826
+ }
1827
+ };
1828
+ }
1829
+ function Equals(comparison, options = {}) {
1830
+ return {
1831
+ name: "equals",
1832
+ message: options.message ?? `\u5FC5\u987B\u7B49\u4E8E ${comparison}`,
1833
+ validate: (value) => value === comparison
1834
+ };
1835
+ }
1836
+ function NotEquals(comparison, options = {}) {
1837
+ return {
1838
+ name: "notEquals",
1839
+ message: options.message ?? `\u4E0D\u80FD\u7B49\u4E8E ${comparison}`,
1840
+ validate: (value) => value !== comparison
1841
+ };
1842
+ }
1843
+ function IsDefined(options = {}) {
1844
+ return {
1845
+ name: "isDefined",
1846
+ message: options.message ?? "\u5FC5\u987B\u5B9A\u4E49",
1847
+ validate: (value) => value !== null && value !== undefined
1848
+ };
1849
+ }
1850
+ function IsAlphanumeric(options = {}) {
1851
+ return {
1852
+ name: "isAlphanumeric",
1853
+ message: options.message ?? "\u53EA\u80FD\u5305\u542B\u5B57\u6BCD\u548C\u6570\u5B57",
1854
+ validate: (value) => typeof value === "string" && /^[a-zA-Z0-9]+$/.test(value)
1855
+ };
1856
+ }
1857
+ function IsAlpha(options = {}) {
1858
+ return {
1859
+ name: "isAlpha",
1860
+ message: options.message ?? "\u53EA\u80FD\u5305\u542B\u5B57\u6BCD",
1861
+ validate: (value) => typeof value === "string" && /^[a-zA-Z]+$/.test(value)
1862
+ };
1863
+ }
1864
+ function IsNumberString(options = {}) {
1865
+ return {
1866
+ name: "isNumberString",
1867
+ message: options.message ?? "\u53EA\u80FD\u5305\u542B\u6570\u5B57",
1868
+ validate: (value) => typeof value === "string" && /^[0-9]+$/.test(value)
1869
+ };
1870
+ }
1871
+ var UUID_PATTERNS;
1872
+ var init_common = __esm(() => {
1873
+ UUID_PATTERNS = {
1874
+ "3": /^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
1875
+ "4": /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
1876
+ "5": /^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
1877
+ all: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
1878
+ };
1879
+ });
1880
+
1881
+ // src/validation/rules/conditional.ts
1882
+ function ValidateIf(condition, options = {}) {
1883
+ return {
1884
+ name: "validateIf",
1885
+ message: options.message ?? "",
1886
+ condition,
1887
+ validate: () => true
1888
+ };
1889
+ }
1890
+ function Transform(transformFn, options = {}) {
1891
+ return {
1892
+ name: "transform",
1893
+ message: options.message ?? "",
1894
+ transform: transformFn,
1895
+ validate: () => true
1896
+ };
1897
+ }
1898
+
1899
+ // src/validation/custom-validator.ts
1900
+ function createCustomValidator(name, validate, defaultMessage) {
1901
+ return (...args) => (options = {}) => {
1902
+ const message = options.message ?? (typeof defaultMessage === "function" ? defaultMessage(...args) : defaultMessage);
1903
+ return {
1904
+ name,
1905
+ message,
1906
+ validate: (value) => validate(value, ...args)
1907
+ };
1908
+ };
1909
+ }
1910
+ function createSimpleValidator(name, validate, defaultMessage) {
1911
+ return (options = {}) => ({
1912
+ name,
1913
+ message: options.message ?? defaultMessage,
1914
+ validate
1915
+ });
1916
+ }
1917
+ function createRegexValidator(name, pattern, defaultMessage) {
1918
+ return createSimpleValidator(name, (value) => typeof value === "string" && pattern.test(value), defaultMessage);
1919
+ }
1920
+ var IsPhoneNumber, IsIdCard, IsIPv4, IsPort, IsPostalCode, IsCreditCard, IsHexColor, IsMacAddress, IsSemVer, IsDivisibleBy, IsBetween, Contains, NotContains;
1921
+ var init_custom_validator = __esm(() => {
1922
+ IsPhoneNumber = createSimpleValidator("isPhoneNumber", (value) => typeof value === "string" && /^1[3-9]\d{9}$/.test(value), "\u5FC5\u987B\u662F\u6709\u6548\u7684\u624B\u673A\u53F7\u7801");
1923
+ IsIdCard = createSimpleValidator("isIdCard", (value) => {
1924
+ if (typeof value !== "string")
1925
+ return false;
1926
+ const pattern15 = /^[1-9]\d{5}\d{2}((0[1-9])|(1[0-2]))(([0-2]\d)|30|31)\d{3}$/;
1927
+ const pattern18 = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2]\d)|30|31)\d{3}[0-9Xx]$/;
1928
+ return pattern15.test(value) || pattern18.test(value);
1929
+ }, "\u5FC5\u987B\u662F\u6709\u6548\u7684\u8EAB\u4EFD\u8BC1\u53F7\u7801");
1930
+ IsIPv4 = createSimpleValidator("isIPv4", (value) => {
1931
+ if (typeof value !== "string")
1932
+ return false;
1933
+ const parts = value.split(".");
1934
+ if (parts.length !== 4)
1935
+ return false;
1936
+ return parts.every((part) => {
1937
+ const num = parseInt(part, 10);
1938
+ return !Number.isNaN(num) && num >= 0 && num <= 255 && String(num) === part;
1939
+ });
1940
+ }, "\u5FC5\u987B\u662F\u6709\u6548\u7684 IPv4 \u5730\u5740");
1941
+ IsPort = createSimpleValidator("isPort", (value) => {
1942
+ if (typeof value === "string") {
1943
+ const num = parseInt(value, 10);
1944
+ return !Number.isNaN(num) && num >= 0 && num <= 65535;
1945
+ }
1946
+ if (typeof value === "number") {
1947
+ return Number.isInteger(value) && value >= 0 && value <= 65535;
1948
+ }
1949
+ return false;
1950
+ }, "\u5FC5\u987B\u662F\u6709\u6548\u7684\u7AEF\u53E3\u53F7 (0-65535)");
1951
+ IsPostalCode = createSimpleValidator("isPostalCode", (value) => typeof value === "string" && /^[1-9]\d{5}$/.test(value), "\u5FC5\u987B\u662F\u6709\u6548\u7684\u90AE\u653F\u7F16\u7801");
1952
+ IsCreditCard = createSimpleValidator("isCreditCard", (value) => {
1953
+ if (typeof value !== "string")
1954
+ return false;
1955
+ const sanitized = value.replace(/[\s-]/g, "");
1956
+ if (!/^\d{13,19}$/.test(sanitized))
1957
+ return false;
1958
+ let sum = 0;
1959
+ let isEven = false;
1960
+ for (let i = sanitized.length - 1;i >= 0; i--) {
1961
+ let digit = parseInt(sanitized[i], 10);
1962
+ if (isEven) {
1963
+ digit *= 2;
1964
+ if (digit > 9)
1965
+ digit -= 9;
1966
+ }
1967
+ sum += digit;
1968
+ isEven = !isEven;
1969
+ }
1970
+ return sum % 10 === 0;
1971
+ }, "\u5FC5\u987B\u662F\u6709\u6548\u7684\u4FE1\u7528\u5361\u53F7");
1972
+ IsHexColor = createSimpleValidator("isHexColor", (value) => typeof value === "string" && /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(value), "\u5FC5\u987B\u662F\u6709\u6548\u7684\u5341\u516D\u8FDB\u5236\u989C\u8272\u503C");
1973
+ IsMacAddress = createSimpleValidator("isMacAddress", (value) => typeof value === "string" && /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/.test(value), "\u5FC5\u987B\u662F\u6709\u6548\u7684 MAC \u5730\u5740");
1974
+ IsSemVer = createSimpleValidator("isSemVer", (value) => typeof value === "string" && /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(value), "\u5FC5\u987B\u662F\u6709\u6548\u7684\u8BED\u4E49\u5316\u7248\u672C\u53F7");
1975
+ IsDivisibleBy = createCustomValidator("isDivisibleBy", (value, divisor) => typeof value === "number" && !Number.isNaN(value) && value % divisor === 0, (divisor) => `\u5FC5\u987B\u80FD\u88AB ${divisor} \u6574\u9664`);
1976
+ IsBetween = createCustomValidator("isBetween", (value, min, max) => typeof value === "number" && value >= min && value <= max, (min, max) => `\u5FC5\u987B\u5728 ${min} \u548C ${max} \u4E4B\u95F4`);
1977
+ Contains = createCustomValidator("contains", (value, substring) => typeof value === "string" && value.includes(substring), (substring) => `\u5FC5\u987B\u5305\u542B "${substring}"`);
1978
+ NotContains = createCustomValidator("notContains", (value, substring) => typeof value === "string" && !value.includes(substring), (substring) => `\u4E0D\u80FD\u5305\u542B "${substring}"`);
1979
+ });
1980
+
1981
+ // src/validation/class-validator.ts
1982
+ import"reflect-metadata";
1983
+ function ValidateClass() {
1984
+ return (target) => {
1985
+ Reflect.defineMetadata(VALIDATE_CLASS_METADATA_KEY, true, target);
1986
+ };
1987
+ }
1988
+ function Property(...rules) {
1989
+ return (target, propertyKey) => {
1990
+ if (typeof propertyKey === "symbol") {
1991
+ throw new Error("@Property decorator does not support symbol property keys");
1992
+ }
1993
+ const existingMetadata = Reflect.getMetadata(CLASS_VALIDATION_METADATA_KEY, target.constructor) ?? [];
1994
+ let propertyMetadata = existingMetadata.find((m) => m.property === propertyKey);
1995
+ if (!propertyMetadata) {
1996
+ propertyMetadata = { property: propertyKey, rules: [] };
1997
+ existingMetadata.push(propertyMetadata);
1998
+ }
1999
+ propertyMetadata.rules.push(...rules);
2000
+ Reflect.defineMetadata(CLASS_VALIDATION_METADATA_KEY, existingMetadata, target.constructor);
2001
+ };
2002
+ }
2003
+ function getClassValidationMetadata(target) {
2004
+ return Reflect.getMetadata(CLASS_VALIDATION_METADATA_KEY, target) ?? [];
2005
+ }
2006
+ function isValidateClass(target) {
2007
+ return Reflect.getMetadata(VALIDATE_CLASS_METADATA_KEY, target) === true;
2008
+ }
2009
+ function validateValue(value, rules, property, fullObject) {
2010
+ const issues = [];
2011
+ let currentValue = value;
2012
+ let shouldSkip2 = false;
2013
+ for (const rule of rules) {
2014
+ if (rule.condition && !rule.condition(currentValue, fullObject)) {
2015
+ shouldSkip2 = true;
2016
+ break;
2017
+ }
2018
+ if (rule.optional && (currentValue === undefined || currentValue === null)) {
2019
+ shouldSkip2 = true;
2020
+ break;
2021
+ }
2022
+ if (rule.transform) {
2023
+ currentValue = rule.transform(currentValue);
2024
+ }
2025
+ if (rule.nested) {
2026
+ if (rule.each && Array.isArray(currentValue)) {
2027
+ for (let i = 0;i < currentValue.length; i++) {
2028
+ const item = currentValue[i];
2029
+ if (typeof item === "object" && item !== null && rule.nestedType) {
2030
+ const nestedIssues = validateObjectInternal(item, rule.nestedType, `${property}[${i}]`);
2031
+ issues.push(...nestedIssues);
2032
+ }
2033
+ }
2034
+ } else if (typeof currentValue === "object" && currentValue !== null && rule.nestedType) {
2035
+ const nestedIssues = validateObjectInternal(currentValue, rule.nestedType, property);
2036
+ issues.push(...nestedIssues);
2037
+ }
2038
+ continue;
2039
+ }
2040
+ const passed = rule.validate(currentValue, fullObject);
2041
+ if (!passed) {
2042
+ issues.push({
2043
+ property,
2044
+ rule: rule.name,
2045
+ message: rule.message,
2046
+ value: currentValue
2047
+ });
2048
+ }
2049
+ }
2050
+ return shouldSkip2 ? [] : issues;
2051
+ }
2052
+ function validateObjectInternal(obj, targetClass, prefix = "") {
2053
+ const metadata = getClassValidationMetadata(targetClass);
2054
+ const issues = [];
2055
+ if (typeof obj !== "object" || obj === null) {
2056
+ issues.push({
2057
+ property: prefix || "root",
2058
+ rule: "isObject",
2059
+ message: "\u5FC5\u987B\u662F\u5BF9\u8C61",
2060
+ value: obj
2061
+ });
2062
+ return issues;
2063
+ }
2064
+ const objRecord = obj;
2065
+ for (const meta of metadata) {
2066
+ const propertyPath = prefix ? `${prefix}.${meta.property}` : meta.property;
2067
+ const value = objRecord[meta.property];
2068
+ const propertyIssues = validateValue(value, meta.rules, propertyPath, obj);
2069
+ issues.push(...propertyIssues);
2070
+ }
2071
+ return issues;
2072
+ }
2073
+ function validateObject(obj, targetClass, options = {}) {
2074
+ const issues = validateObjectInternal(obj, targetClass);
2075
+ if (options.stopAtFirstError && issues.length > 0) {
2076
+ throw new ValidationError("Validation failed", [issues[0]]);
2077
+ }
2078
+ if (issues.length > 0) {
2079
+ throw new ValidationError("Validation failed", issues);
2080
+ }
2081
+ }
2082
+ function validateObjectSync(obj, targetClass, options = {}) {
2083
+ const issues = validateObjectInternal(obj, targetClass);
2084
+ if (options.stopAtFirstError && issues.length > 0) {
2085
+ return { valid: false, issues: [issues[0]] };
2086
+ }
2087
+ return { valid: issues.length === 0, issues };
2088
+ }
2089
+ function NestedProperty(nestedClass) {
2090
+ return (target, propertyKey) => {
2091
+ if (typeof propertyKey === "symbol") {
2092
+ throw new Error("@NestedProperty decorator does not support symbol property keys");
2093
+ }
2094
+ const existingMetadata = Reflect.getMetadata(CLASS_VALIDATION_METADATA_KEY, target.constructor) ?? [];
2095
+ let propertyMetadata = existingMetadata.find((m) => m.property === propertyKey);
2096
+ if (!propertyMetadata) {
2097
+ propertyMetadata = { property: propertyKey, rules: [] };
2098
+ existingMetadata.push(propertyMetadata);
2099
+ }
2100
+ propertyMetadata.rules.push({
2101
+ name: "validateNested",
2102
+ message: "\u5D4C\u5957\u5BF9\u8C61\u9A8C\u8BC1\u5931\u8D25",
2103
+ nested: true,
2104
+ nestedType: nestedClass,
2105
+ validate: (value) => typeof value === "object" && value !== null && !Array.isArray(value)
2106
+ });
2107
+ Reflect.defineMetadata(CLASS_VALIDATION_METADATA_KEY, existingMetadata, target.constructor);
2108
+ };
2109
+ }
2110
+ function ArrayNestedProperty(nestedClass) {
2111
+ return (target, propertyKey) => {
2112
+ if (typeof propertyKey === "symbol") {
2113
+ throw new Error("@ArrayNestedProperty decorator does not support symbol property keys");
2114
+ }
2115
+ const existingMetadata = Reflect.getMetadata(CLASS_VALIDATION_METADATA_KEY, target.constructor) ?? [];
2116
+ let propertyMetadata = existingMetadata.find((m) => m.property === propertyKey);
2117
+ if (!propertyMetadata) {
2118
+ propertyMetadata = { property: propertyKey, rules: [] };
2119
+ existingMetadata.push(propertyMetadata);
2120
+ }
2121
+ propertyMetadata.rules.push({
2122
+ name: "validateNestedArray",
2123
+ message: "\u6570\u7EC4\u5143\u7D20\u9A8C\u8BC1\u5931\u8D25",
2124
+ nested: true,
2125
+ nestedType: nestedClass,
2126
+ each: true,
2127
+ validate: (value) => Array.isArray(value)
2128
+ });
2129
+ Reflect.defineMetadata(CLASS_VALIDATION_METADATA_KEY, existingMetadata, target.constructor);
2130
+ };
2131
+ }
2132
+ var CLASS_VALIDATION_METADATA_KEY, PROPERTY_VALIDATION_METADATA_KEY, VALIDATE_CLASS_METADATA_KEY;
2133
+ var init_class_validator = __esm(() => {
2134
+ init_errors();
2135
+ CLASS_VALIDATION_METADATA_KEY = Symbol("validation:class");
2136
+ PROPERTY_VALIDATION_METADATA_KEY = Symbol("validation:property");
2137
+ VALIDATE_CLASS_METADATA_KEY = Symbol("validation:validateClass");
2138
+ });
2139
+
1491
2140
  // src/validation/index.ts
1492
2141
  var init_validation = __esm(() => {
1493
2142
  init_decorators5();
1494
2143
  init_validator();
1495
2144
  init_errors();
2145
+ init_common();
2146
+ init_custom_validator();
2147
+ init_class_validator();
1496
2148
  });
1497
2149
 
1498
2150
  // src/error/error-codes.ts
@@ -2571,6 +3223,12 @@ var init_interceptor = __esm(() => {
2571
3223
  });
2572
3224
 
2573
3225
  // src/controller/controller.ts
3226
+ var exports_controller = {};
3227
+ __export(exports_controller, {
3228
+ ControllerRegistry: () => ControllerRegistry,
3229
+ Controller: () => Controller,
3230
+ CONTROLLER_METADATA_KEY: () => CONTROLLER_METADATA_KEY
3231
+ });
2574
3232
  import"reflect-metadata";
2575
3233
  function Controller(path = "") {
2576
3234
  return function(target) {
@@ -3632,12 +4290,14 @@ init_controller();
3632
4290
  init_container();
3633
4291
  init_types();
3634
4292
  init_module();
4293
+ init_decorators();
3635
4294
 
3636
4295
  class ModuleRegistry {
3637
4296
  static instance;
3638
4297
  moduleRefs = new Map;
3639
4298
  processing = new Set;
3640
4299
  rootContainer;
4300
+ globalModules = new Set;
3641
4301
  static getInstance() {
3642
4302
  if (!ModuleRegistry.instance) {
3643
4303
  ModuleRegistry.instance = new ModuleRegistry;
@@ -3656,8 +4316,12 @@ class ModuleRegistry {
3656
4316
  clear() {
3657
4317
  this.moduleRefs.clear();
3658
4318
  this.processing.clear();
4319
+ this.globalModules.clear();
3659
4320
  this.rootContainer = undefined;
3660
4321
  }
4322
+ getGlobalModules() {
4323
+ return Array.from(this.globalModules);
4324
+ }
3661
4325
  processModule(moduleClass, parentContainer) {
3662
4326
  if (this.processing.has(moduleClass)) {
3663
4327
  throw new Error(`Circular module dependency detected for ${moduleClass.name}`);
@@ -3680,6 +4344,7 @@ class ModuleRegistry {
3680
4344
  throw new Error("ModuleRegistry is not initialized with a root container");
3681
4345
  }
3682
4346
  const metadata = getModuleMetadata(moduleClass);
4347
+ const isGlobal = isGlobalModule(moduleClass);
3683
4348
  const container = new Container({ parent: this.rootContainer });
3684
4349
  this.registerProviders(container, metadata.providers);
3685
4350
  ref = {
@@ -3689,12 +4354,25 @@ class ModuleRegistry {
3689
4354
  controllersRegistered: false,
3690
4355
  attachedParents: new Set,
3691
4356
  extensions: metadata.extensions ?? [],
3692
- middlewares: metadata.middlewares ?? []
4357
+ middlewares: metadata.middlewares ?? [],
4358
+ isGlobal
3693
4359
  };
3694
4360
  this.registerControllers(ref);
3695
4361
  this.moduleRefs.set(moduleClass, ref);
4362
+ if (isGlobal) {
4363
+ this.globalModules.add(moduleClass);
4364
+ this.registerGlobalExports(ref);
4365
+ }
3696
4366
  return ref;
3697
4367
  }
4368
+ registerGlobalExports(moduleRef) {
4369
+ if (!this.rootContainer) {
4370
+ return;
4371
+ }
4372
+ for (const exportedToken of moduleRef.metadata.exports) {
4373
+ this.registerExport(this.rootContainer, moduleRef, exportedToken);
4374
+ }
4375
+ }
3698
4376
  registerProviders(container, providers) {
3699
4377
  for (const provider of providers) {
3700
4378
  if (typeof provider === "function") {
@@ -5476,6 +6154,232 @@ function checkRoles(target, propertyKey, userRoles = []) {
5476
6154
  return config.roles.some((role) => userRoles.includes(role));
5477
6155
  }
5478
6156
 
6157
+ // src/security/guards/decorators.ts
6158
+ import"reflect-metadata";
6159
+
6160
+ // src/security/guards/types.ts
6161
+ var GUARDS_METADATA_KEY = Symbol("@dangao/bun-server:guards");
6162
+ var GUARD_REGISTRY_TOKEN = Symbol("@dangao/bun-server:guard-registry");
6163
+ var ROLES_METADATA_KEY = Symbol("@dangao/bun-server:roles");
6164
+
6165
+ // src/security/guards/decorators.ts
6166
+ function UseGuards(...guards) {
6167
+ return (target, propertyKey, descriptor) => {
6168
+ if (propertyKey !== undefined) {
6169
+ const existingGuards = Reflect.getMetadata(GUARDS_METADATA_KEY, target, propertyKey) || [];
6170
+ Reflect.defineMetadata(GUARDS_METADATA_KEY, [...existingGuards, ...guards], target, propertyKey);
6171
+ } else {
6172
+ const existingGuards = Reflect.getMetadata(GUARDS_METADATA_KEY, target) || [];
6173
+ Reflect.defineMetadata(GUARDS_METADATA_KEY, [...existingGuards, ...guards], target);
6174
+ }
6175
+ };
6176
+ }
6177
+ function Roles(...roles) {
6178
+ return (target, propertyKey, descriptor) => {
6179
+ if (propertyKey !== undefined) {
6180
+ Reflect.defineMetadata(ROLES_METADATA_KEY, roles, target, propertyKey);
6181
+ } else {
6182
+ Reflect.defineMetadata(ROLES_METADATA_KEY, roles, target);
6183
+ }
6184
+ };
6185
+ }
6186
+ function getGuardsMetadata(target, propertyKey) {
6187
+ if (target === null || target === undefined) {
6188
+ return [];
6189
+ }
6190
+ if (typeof target !== "object" && typeof target !== "function") {
6191
+ return [];
6192
+ }
6193
+ if (propertyKey !== undefined) {
6194
+ return Reflect.getMetadata(GUARDS_METADATA_KEY, target, propertyKey) || [];
6195
+ }
6196
+ return Reflect.getMetadata(GUARDS_METADATA_KEY, target) || [];
6197
+ }
6198
+ function getRolesMetadata(target, propertyKey) {
6199
+ if (propertyKey !== undefined) {
6200
+ return Reflect.getMetadata(ROLES_METADATA_KEY, target, propertyKey) || [];
6201
+ }
6202
+ return Reflect.getMetadata(ROLES_METADATA_KEY, target) || [];
6203
+ }
6204
+
6205
+ // src/security/guards/guard-registry.ts
6206
+ init_http_exception();
6207
+ init_error_codes();
6208
+
6209
+ class GuardRegistry {
6210
+ globalGuards = [];
6211
+ guardInstances = new Map;
6212
+ addGlobalGuards(...guards) {
6213
+ this.globalGuards.push(...guards);
6214
+ }
6215
+ getGlobalGuards() {
6216
+ return [...this.globalGuards];
6217
+ }
6218
+ clearGlobalGuards() {
6219
+ this.globalGuards = [];
6220
+ this.guardInstances.clear();
6221
+ }
6222
+ resolveGuard(guard, container) {
6223
+ if (typeof guard !== "function") {
6224
+ return guard;
6225
+ }
6226
+ const cached = this.guardInstances.get(guard);
6227
+ if (cached) {
6228
+ return cached;
6229
+ }
6230
+ try {
6231
+ if (container.isRegistered(guard)) {
6232
+ const instance2 = container.resolve(guard);
6233
+ this.guardInstances.set(guard, instance2);
6234
+ return instance2;
6235
+ }
6236
+ } catch {}
6237
+ const GuardClass = guard;
6238
+ const instance = new GuardClass;
6239
+ this.guardInstances.set(guard, instance);
6240
+ return instance;
6241
+ }
6242
+ getControllerGuards(controllerClass) {
6243
+ return getGuardsMetadata(controllerClass);
6244
+ }
6245
+ getMethodGuards(controllerClass, methodName) {
6246
+ return getGuardsMetadata(controllerClass.prototype, methodName);
6247
+ }
6248
+ collectGuards(controllerClass, methodName) {
6249
+ const globalGuards = this.getGlobalGuards();
6250
+ const controllerGuards = this.getControllerGuards(controllerClass);
6251
+ const methodGuards = this.getMethodGuards(controllerClass, methodName);
6252
+ return [...globalGuards, ...controllerGuards, ...methodGuards];
6253
+ }
6254
+ async executeGuards(context, container) {
6255
+ const controllerClass = context.getClass();
6256
+ const methodName = context.getMethodName();
6257
+ const guards = this.collectGuards(controllerClass, methodName);
6258
+ if (guards.length === 0) {
6259
+ return true;
6260
+ }
6261
+ for (const guard of guards) {
6262
+ const guardInstance = this.resolveGuard(guard, container);
6263
+ const result = await guardInstance.canActivate(context);
6264
+ if (!result) {
6265
+ const guardName = typeof guard === "function" ? guard.name : guard.constructor.name;
6266
+ throw new ForbiddenException(`Access denied by guard: ${guardName}`, { guard: guardName }, "AUTH_INSUFFICIENT_PERMISSIONS" /* AUTH_INSUFFICIENT_PERMISSIONS */);
6267
+ }
6268
+ }
6269
+ return true;
6270
+ }
6271
+ }
6272
+
6273
+ // src/security/guards/execution-context.ts
6274
+ import"reflect-metadata";
6275
+
6276
+ class HttpArgumentsHostImpl {
6277
+ ctx;
6278
+ responseBuilder;
6279
+ constructor(ctx, responseBuilder) {
6280
+ this.ctx = ctx;
6281
+ this.responseBuilder = responseBuilder;
6282
+ }
6283
+ getRequest() {
6284
+ return this.ctx;
6285
+ }
6286
+ getResponse() {
6287
+ return this.responseBuilder;
6288
+ }
6289
+ }
6290
+
6291
+ class WsArgumentsHostImpl {
6292
+ client;
6293
+ data;
6294
+ constructor(client, data) {
6295
+ this.client = client;
6296
+ this.data = data;
6297
+ }
6298
+ getClient() {
6299
+ return this.client;
6300
+ }
6301
+ getData() {
6302
+ return this.data;
6303
+ }
6304
+ }
6305
+
6306
+ class ExecutionContextImpl {
6307
+ ctx;
6308
+ controllerClass;
6309
+ methodName;
6310
+ handler;
6311
+ args;
6312
+ httpHost;
6313
+ wsHost;
6314
+ constructor(ctx, controllerClass, methodName, handler, args = [], responseBuilder) {
6315
+ this.ctx = ctx;
6316
+ this.controllerClass = controllerClass;
6317
+ this.methodName = methodName;
6318
+ this.handler = handler;
6319
+ this.args = args;
6320
+ this.httpHost = new HttpArgumentsHostImpl(ctx, responseBuilder);
6321
+ }
6322
+ setWsContext(client, data) {
6323
+ this.wsHost = new WsArgumentsHostImpl(client, data);
6324
+ }
6325
+ switchToHttp() {
6326
+ return this.httpHost;
6327
+ }
6328
+ switchToWs() {
6329
+ if (!this.wsHost) {
6330
+ throw new Error("WebSocket context is not available");
6331
+ }
6332
+ return this.wsHost;
6333
+ }
6334
+ getClass() {
6335
+ return this.controllerClass;
6336
+ }
6337
+ getHandler() {
6338
+ return this.handler;
6339
+ }
6340
+ getMethodName() {
6341
+ return this.methodName;
6342
+ }
6343
+ getMetadata(key) {
6344
+ const methodMetadata = Reflect.getMetadata(key, this.controllerClass.prototype, this.methodName);
6345
+ if (methodMetadata !== undefined) {
6346
+ return methodMetadata;
6347
+ }
6348
+ return Reflect.getMetadata(key, this.controllerClass);
6349
+ }
6350
+ getArgs() {
6351
+ return this.args;
6352
+ }
6353
+ }
6354
+
6355
+ // src/security/guards/reflector.ts
6356
+ import"reflect-metadata";
6357
+
6358
+ class Reflector {
6359
+ get(metadataKey, target) {
6360
+ return Reflect.getMetadata(metadataKey, target);
6361
+ }
6362
+ getFromClass(metadataKey, target) {
6363
+ return Reflect.getMetadata(metadataKey, target);
6364
+ }
6365
+ getFromMethod(metadataKey, target, propertyKey) {
6366
+ return Reflect.getMetadata(metadataKey, target, propertyKey);
6367
+ }
6368
+ getAllAndMerge(metadataKey, target, propertyKey) {
6369
+ const classMetadata = this.getFromClass(metadataKey, target) || [];
6370
+ const methodMetadata = this.getFromMethod(metadataKey, target.prototype, propertyKey) || [];
6371
+ return [...classMetadata, ...methodMetadata];
6372
+ }
6373
+ getAllAndOverride(metadataKey, target, propertyKey) {
6374
+ const methodMetadata = this.getFromMethod(metadataKey, target.prototype, propertyKey);
6375
+ if (methodMetadata !== undefined) {
6376
+ return methodMetadata;
6377
+ }
6378
+ return this.getFromClass(metadataKey, target);
6379
+ }
6380
+ }
6381
+ var REFLECTOR_TOKEN = Symbol("@dangao/bun-server:reflector");
6382
+
5479
6383
  // src/security/filter.ts
5480
6384
  function createSecurityFilter(config) {
5481
6385
  const {
@@ -5483,8 +6387,24 @@ function createSecurityFilter(config) {
5483
6387
  accessDecisionManager = new RoleBasedAccessDecisionManager,
5484
6388
  excludePaths = [],
5485
6389
  defaultAuthRequired = true,
5486
- extractToken
6390
+ extractToken,
6391
+ container: initialContainer,
6392
+ guardRegistry
5487
6393
  } = config;
6394
+ const registry = guardRegistry || new GuardRegistry;
6395
+ let cachedContainer = initialContainer || null;
6396
+ const getContainer = () => {
6397
+ if (cachedContainer) {
6398
+ return cachedContainer;
6399
+ }
6400
+ try {
6401
+ const { ControllerRegistry: ControllerRegistry2 } = (init_controller(), __toCommonJS(exports_controller));
6402
+ cachedContainer = ControllerRegistry2.getInstance().getContainer();
6403
+ return cachedContainer;
6404
+ } catch {
6405
+ return null;
6406
+ }
6407
+ };
5488
6408
  return async (ctx, next) => {
5489
6409
  return SecurityContextHolder.runWithContext(async () => {
5490
6410
  const path = ctx.path || ctx.request.url.split("?")[0].replace(/^https?:\/\/[^/]+/, "");
@@ -5505,11 +6425,23 @@ function createSecurityFilter(config) {
5505
6425
  securityContext.setAuthentication(authentication);
5506
6426
  }
5507
6427
  }
6428
+ ctx.security = securityContext;
6429
+ ctx.auth = {
6430
+ isAuthenticated: securityContext.isAuthenticated(),
6431
+ user: securityContext.getPrincipal(),
6432
+ payload: securityContext.authentication?.details
6433
+ };
5508
6434
  const handler = ctx.routeHandler;
5509
6435
  if (handler) {
5510
6436
  const controllerClass = handler.controller;
5511
6437
  const controllerTarget = controllerClass && controllerClass.prototype || controllerClass;
5512
6438
  const method = handler.method;
6439
+ const container = getContainer();
6440
+ if (container && typeof controllerClass === "function") {
6441
+ const methodHandler = controllerTarget[method];
6442
+ const executionContext = new ExecutionContextImpl(ctx, controllerClass, method, methodHandler || (() => {}));
6443
+ await registry.executeGuards(executionContext, container);
6444
+ }
5513
6445
  if (requiresAuth(controllerTarget, method)) {
5514
6446
  const authentication = securityContext.authentication;
5515
6447
  if (!authentication || !authentication.authenticated) {
@@ -5527,12 +6459,6 @@ function createSecurityFilter(config) {
5527
6459
  } else if (defaultAuthRequired && !securityContext.isAuthenticated()) {
5528
6460
  throw new UnauthorizedException("Authentication required", undefined, "AUTH_REQUIRED" /* AUTH_REQUIRED */);
5529
6461
  }
5530
- ctx.security = securityContext;
5531
- ctx.auth = {
5532
- isAuthenticated: securityContext.isAuthenticated(),
5533
- user: securityContext.getPrincipal(),
5534
- payload: securityContext.authentication?.details
5535
- };
5536
6462
  return await next();
5537
6463
  } finally {
5538
6464
  SecurityContextHolder.clearContext();
@@ -5540,6 +6466,22 @@ function createSecurityFilter(config) {
5540
6466
  });
5541
6467
  };
5542
6468
  }
6469
+ function getGuardRegistry(container) {
6470
+ if (container.isRegistered(GUARD_REGISTRY_TOKEN)) {
6471
+ return container.resolve(GUARD_REGISTRY_TOKEN);
6472
+ }
6473
+ const registry = new GuardRegistry;
6474
+ container.registerInstance(GUARD_REGISTRY_TOKEN, registry);
6475
+ return registry;
6476
+ }
6477
+ function registerReflector(container) {
6478
+ if (container.isRegistered(REFLECTOR_TOKEN)) {
6479
+ return container.resolve(REFLECTOR_TOKEN);
6480
+ }
6481
+ const reflector = new Reflector;
6482
+ container.registerInstance(REFLECTOR_TOKEN, reflector);
6483
+ return reflector;
6484
+ }
5543
6485
  function extractTokenFromHeader(ctx) {
5544
6486
  const authHeader = ctx.getHeader("authorization");
5545
6487
  if (!authHeader) {
@@ -6008,6 +6950,8 @@ OAuth2Controller = __legacyDecorateClassTS([
6008
6950
  ], OAuth2Controller);
6009
6951
 
6010
6952
  // src/security/security-module.ts
6953
+ var _guardRegistry = null;
6954
+
6011
6955
  class SecurityModule {
6012
6956
  static forRoot(config) {
6013
6957
  const jwtUtil = new JWTUtil(config.jwt);
@@ -6016,13 +6960,23 @@ class SecurityModule {
6016
6960
  const authenticationManager = new AuthenticationManager;
6017
6961
  authenticationManager.registerProvider(new JwtAuthenticationProvider(jwtUtil));
6018
6962
  authenticationManager.registerProvider(new OAuth2AuthenticationProvider(oauth2Service, jwtUtil));
6963
+ const guardRegistry = new GuardRegistry;
6964
+ if (_guardRegistry) {
6965
+ _guardRegistry.clearGlobalGuards();
6966
+ }
6967
+ _guardRegistry = guardRegistry;
6968
+ if (config.globalGuards && config.globalGuards.length > 0) {
6969
+ guardRegistry.addGlobalGuards(...config.globalGuards);
6970
+ }
6971
+ const reflector = new Reflector;
6019
6972
  const securityFilter = createSecurityFilter({
6020
6973
  authenticationManager,
6021
6974
  excludePaths: [
6022
6975
  ...config.excludePaths || [],
6023
6976
  ...config.enableOAuth2Endpoints !== false ? [config.oauth2Prefix || "/oauth2"] : []
6024
6977
  ],
6025
- defaultAuthRequired: config.defaultAuthRequired ?? false
6978
+ defaultAuthRequired: config.defaultAuthRequired ?? false,
6979
+ guardRegistry
6026
6980
  });
6027
6981
  const controllers = [];
6028
6982
  const providers = [];
@@ -6039,6 +6993,12 @@ class SecurityModule {
6039
6993
  }, {
6040
6994
  provide: AuthenticationManager,
6041
6995
  useValue: authenticationManager
6996
+ }, {
6997
+ provide: GUARD_REGISTRY_TOKEN,
6998
+ useValue: guardRegistry
6999
+ }, {
7000
+ provide: REFLECTOR_TOKEN,
7001
+ useValue: reflector
6042
7002
  });
6043
7003
  middlewares.push(securityFilter);
6044
7004
  const existingMetadata = Reflect.getMetadata(MODULE_METADATA_KEY, SecurityModule) || {};
@@ -6051,12 +7011,29 @@ class SecurityModule {
6051
7011
  ...existingMetadata.exports || [],
6052
7012
  JWT_UTIL_TOKEN,
6053
7013
  OAUTH2_SERVICE_TOKEN,
6054
- AuthenticationManager
7014
+ AuthenticationManager,
7015
+ GUARD_REGISTRY_TOKEN,
7016
+ REFLECTOR_TOKEN
6055
7017
  ]
6056
7018
  };
6057
7019
  Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, SecurityModule);
6058
7020
  return SecurityModule;
6059
7021
  }
7022
+ static getGuardRegistry() {
7023
+ return _guardRegistry;
7024
+ }
7025
+ static addGlobalGuards(...guards) {
7026
+ if (_guardRegistry) {
7027
+ _guardRegistry.addGlobalGuards(...guards);
7028
+ }
7029
+ }
7030
+ static reset() {
7031
+ if (_guardRegistry) {
7032
+ _guardRegistry.clearGlobalGuards();
7033
+ }
7034
+ _guardRegistry = null;
7035
+ Reflect.deleteMetadata(MODULE_METADATA_KEY, SecurityModule);
7036
+ }
6060
7037
  }
6061
7038
  SecurityModule = __legacyDecorateClassTS([
6062
7039
  Module({
@@ -6065,6 +7042,94 @@ SecurityModule = __legacyDecorateClassTS([
6065
7042
  middlewares: []
6066
7043
  })
6067
7044
  ], SecurityModule);
7045
+ // src/security/guards/builtin/auth-guard.ts
7046
+ init_decorators();
7047
+ init_http_exception();
7048
+ init_error_codes();
7049
+ class AuthGuard {
7050
+ canActivate(context) {
7051
+ const securityContext = SecurityContextHolder.getContext();
7052
+ if (!securityContext.isAuthenticated()) {
7053
+ throw new UnauthorizedException("Authentication required", undefined, "AUTH_REQUIRED" /* AUTH_REQUIRED */);
7054
+ }
7055
+ return true;
7056
+ }
7057
+ }
7058
+ AuthGuard = __legacyDecorateClassTS([
7059
+ Injectable()
7060
+ ], AuthGuard);
7061
+
7062
+ class OptionalAuthGuard {
7063
+ canActivate(context) {
7064
+ return true;
7065
+ }
7066
+ }
7067
+ OptionalAuthGuard = __legacyDecorateClassTS([
7068
+ Injectable()
7069
+ ], OptionalAuthGuard);
7070
+ // src/security/guards/builtin/roles-guard.ts
7071
+ init_decorators();
7072
+ init_http_exception();
7073
+ init_error_codes();
7074
+ class RolesGuard {
7075
+ reflector;
7076
+ constructor(reflector) {
7077
+ this.reflector = reflector || new Reflector;
7078
+ }
7079
+ canActivate(context) {
7080
+ const requiredRoles = this.reflector.getAllAndMerge(ROLES_METADATA_KEY, context.getClass(), context.getMethodName());
7081
+ if (!requiredRoles || requiredRoles.length === 0) {
7082
+ return true;
7083
+ }
7084
+ const securityContext = SecurityContextHolder.getContext();
7085
+ const authentication = securityContext.authentication;
7086
+ if (!authentication || !authentication.authenticated) {
7087
+ throw new ForbiddenException("Access denied: authentication required for role check", { requiredRoles }, "AUTH_INSUFFICIENT_PERMISSIONS" /* AUTH_INSUFFICIENT_PERMISSIONS */);
7088
+ }
7089
+ const userRoles = authentication.authorities || [];
7090
+ const hasRole = requiredRoles.some((role) => userRoles.includes(role));
7091
+ if (!hasRole) {
7092
+ throw new ForbiddenException(`Access denied: required roles [${requiredRoles.join(", ")}], but user has [${userRoles.join(", ")}]`, { requiredRoles, userRoles }, "AUTH_INSUFFICIENT_PERMISSIONS" /* AUTH_INSUFFICIENT_PERMISSIONS */);
7093
+ }
7094
+ return true;
7095
+ }
7096
+ }
7097
+ RolesGuard = __legacyDecorateClassTS([
7098
+ Injectable(),
7099
+ __legacyDecorateParamTS(0, Inject(REFLECTOR_TOKEN)),
7100
+ __legacyMetadataTS("design:paramtypes", [
7101
+ typeof Reflector === "undefined" ? Object : Reflector
7102
+ ])
7103
+ ], RolesGuard);
7104
+ function createRolesGuard(options = {}) {
7105
+ const { matchAll = false, getRoles } = options;
7106
+
7107
+ class CustomRolesGuard {
7108
+ reflector = new Reflector;
7109
+ canActivate(context) {
7110
+ const requiredRoles = this.reflector.getAllAndMerge(ROLES_METADATA_KEY, context.getClass(), context.getMethodName());
7111
+ if (!requiredRoles || requiredRoles.length === 0) {
7112
+ return true;
7113
+ }
7114
+ let userRoles;
7115
+ if (getRoles) {
7116
+ userRoles = getRoles(context);
7117
+ } else {
7118
+ const securityContext = SecurityContextHolder.getContext();
7119
+ userRoles = securityContext.authentication?.authorities || [];
7120
+ }
7121
+ const hasRole = matchAll ? requiredRoles.every((role) => userRoles.includes(role)) : requiredRoles.some((role) => userRoles.includes(role));
7122
+ if (!hasRole) {
7123
+ throw new ForbiddenException(`Access denied: required roles [${requiredRoles.join(", ")}], user has [${userRoles.join(", ")}]`, { requiredRoles, userRoles, matchAll }, "AUTH_INSUFFICIENT_PERMISSIONS" /* AUTH_INSUFFICIENT_PERMISSIONS */);
7124
+ }
7125
+ return true;
7126
+ }
7127
+ }
7128
+ CustomRolesGuard = __legacyDecorateClassTS([
7129
+ Injectable()
7130
+ ], CustomRolesGuard);
7131
+ return CustomRolesGuard;
7132
+ }
6068
7133
  // src/health/health-module.ts
6069
7134
  init_module();
6070
7135
 
@@ -9511,26 +10576,387 @@ class ServiceMetricsCollector {
9511
10576
  this.metricsIntegration?.stop();
9512
10577
  }
9513
10578
  }
10579
+ // src/events/types.ts
10580
+ var EVENT_EMITTER_TOKEN = Symbol("@dangao/bun-server:events:emitter");
10581
+ var EVENT_OPTIONS_TOKEN = Symbol("@dangao/bun-server:events:options");
10582
+ var ON_EVENT_METADATA_KEY = Symbol("@dangao/bun-server:events:on-event");
10583
+ var EVENT_LISTENER_CLASS_METADATA_KEY = Symbol("@dangao/bun-server:events:listener-class");
10584
+ // src/events/service.ts
10585
+ class EventEmitterService {
10586
+ listeners = new Map;
10587
+ options;
10588
+ constructor(options = {}) {
10589
+ this.options = {
10590
+ wildcard: false,
10591
+ delimiter: ".",
10592
+ maxListeners: 10,
10593
+ ...options
10594
+ };
10595
+ }
10596
+ emit(event, payload) {
10597
+ const eventName = this.resolveEventName(event);
10598
+ const matchedListeners = this.getMatchedListeners(eventName);
10599
+ if (matchedListeners.length === 0) {
10600
+ return;
10601
+ }
10602
+ const sortedListeners = this.sortListenersByPriority(matchedListeners);
10603
+ for (const { listener, once, async: isAsync } of sortedListeners) {
10604
+ try {
10605
+ const result = listener(payload);
10606
+ if (isAsync && result instanceof Promise) {
10607
+ result.catch((error) => {
10608
+ this.handleError(error, eventName, payload);
10609
+ });
10610
+ }
10611
+ } catch (error) {
10612
+ this.handleError(error, eventName, payload);
10613
+ }
10614
+ if (once) {
10615
+ this.off(eventName, listener);
10616
+ }
10617
+ }
10618
+ }
10619
+ async emitAsync(event, payload) {
10620
+ const eventName = this.resolveEventName(event);
10621
+ const matchedListeners = this.getMatchedListeners(eventName);
10622
+ if (matchedListeners.length === 0) {
10623
+ return;
10624
+ }
10625
+ const sortedListeners = this.sortListenersByPriority(matchedListeners);
10626
+ const promises = [];
10627
+ const toRemove = [];
10628
+ for (const { listener, once } of sortedListeners) {
10629
+ try {
10630
+ const result = listener(payload);
10631
+ if (result instanceof Promise) {
10632
+ promises.push(result.catch((error) => {
10633
+ this.handleError(error, eventName, payload);
10634
+ }));
10635
+ }
10636
+ } catch (error) {
10637
+ this.handleError(error, eventName, payload);
10638
+ }
10639
+ if (once) {
10640
+ toRemove.push(listener);
10641
+ }
10642
+ }
10643
+ if (promises.length > 0) {
10644
+ await Promise.all(promises);
10645
+ }
10646
+ for (const listener of toRemove) {
10647
+ this.off(eventName, listener);
10648
+ }
10649
+ }
10650
+ on(event, listener, options = {}) {
10651
+ const eventName = this.resolveEventName(event);
10652
+ return this.addListener(eventName, listener, false, options);
10653
+ }
10654
+ once(event, listener, options = {}) {
10655
+ const eventName = this.resolveEventName(event);
10656
+ return this.addListener(eventName, listener, true, options);
10657
+ }
10658
+ off(event, listener) {
10659
+ const eventName = this.resolveEventName(event);
10660
+ const eventListeners = this.listeners.get(eventName);
10661
+ if (!eventListeners) {
10662
+ return;
10663
+ }
10664
+ const index = eventListeners.findIndex((l) => l.listener === listener);
10665
+ if (index !== -1) {
10666
+ eventListeners.splice(index, 1);
10667
+ }
10668
+ if (eventListeners.length === 0) {
10669
+ this.listeners.delete(eventName);
10670
+ }
10671
+ }
10672
+ removeAllListeners(event) {
10673
+ if (event !== undefined) {
10674
+ const eventName = this.resolveEventName(event);
10675
+ this.listeners.delete(eventName);
10676
+ } else {
10677
+ this.listeners.clear();
10678
+ }
10679
+ }
10680
+ listenerCount(event) {
10681
+ const eventName = this.resolveEventName(event);
10682
+ const matchedListeners = this.getMatchedListeners(eventName);
10683
+ return matchedListeners.length;
10684
+ }
10685
+ eventNames() {
10686
+ return Array.from(this.listeners.keys());
10687
+ }
10688
+ addListener(event, listener, once, options) {
10689
+ let eventListeners = this.listeners.get(event);
10690
+ if (!eventListeners) {
10691
+ eventListeners = [];
10692
+ this.listeners.set(event, eventListeners);
10693
+ }
10694
+ if (this.options.maxListeners && eventListeners.length >= this.options.maxListeners) {
10695
+ console.warn(`[EventEmitter] Max listeners (${this.options.maxListeners}) exceeded for event: ${String(event)}. ` + "This may indicate a memory leak.");
10696
+ }
10697
+ const registeredListener = {
10698
+ listener,
10699
+ once,
10700
+ priority: options.priority ?? 0,
10701
+ async: options.async ?? false
10702
+ };
10703
+ eventListeners.push(registeredListener);
10704
+ return () => {
10705
+ this.off(event, listener);
10706
+ };
10707
+ }
10708
+ resolveEventName(event) {
10709
+ if (typeof event === "symbol") {
10710
+ return event;
10711
+ }
10712
+ if (this.options.globalPrefix) {
10713
+ return `${this.options.globalPrefix}${this.options.delimiter}${event}`;
10714
+ }
10715
+ return event;
10716
+ }
10717
+ getMatchedListeners(event) {
10718
+ const result = [];
10719
+ const exactListeners = this.listeners.get(event);
10720
+ if (exactListeners) {
10721
+ result.push(...exactListeners);
10722
+ }
10723
+ if (this.options.wildcard && typeof event === "string") {
10724
+ const delimiter = this.options.delimiter ?? ".";
10725
+ const eventParts = event.split(delimiter);
10726
+ for (const [key, listeners] of this.listeners.entries()) {
10727
+ if (typeof key !== "string" || key === event) {
10728
+ continue;
10729
+ }
10730
+ if (this.matchWildcard(eventParts, key.split(delimiter))) {
10731
+ result.push(...listeners);
10732
+ }
10733
+ }
10734
+ }
10735
+ return result;
10736
+ }
10737
+ matchWildcard(eventParts, patternParts) {
10738
+ let eventIndex = 0;
10739
+ let patternIndex = 0;
10740
+ while (patternIndex < patternParts.length) {
10741
+ const pattern = patternParts[patternIndex];
10742
+ if (pattern === "**") {
10743
+ if (patternIndex === patternParts.length - 1) {
10744
+ return true;
10745
+ }
10746
+ for (let i = eventIndex;i <= eventParts.length; i++) {
10747
+ if (this.matchWildcard(eventParts.slice(i), patternParts.slice(patternIndex + 1))) {
10748
+ return true;
10749
+ }
10750
+ }
10751
+ return false;
10752
+ } else if (pattern === "*") {
10753
+ if (eventIndex >= eventParts.length) {
10754
+ return false;
10755
+ }
10756
+ eventIndex++;
10757
+ patternIndex++;
10758
+ } else {
10759
+ if (eventIndex >= eventParts.length || eventParts[eventIndex] !== pattern) {
10760
+ return false;
10761
+ }
10762
+ eventIndex++;
10763
+ patternIndex++;
10764
+ }
10765
+ }
10766
+ return eventIndex === eventParts.length;
10767
+ }
10768
+ sortListenersByPriority(listeners) {
10769
+ return [...listeners].sort((a, b) => b.priority - a.priority);
10770
+ }
10771
+ handleError(error, event, payload) {
10772
+ if (this.options.onError) {
10773
+ this.options.onError(error, event, payload);
10774
+ } else {
10775
+ console.error(`[EventEmitter] Error in listener for event "${String(event)}":`, error);
10776
+ }
10777
+ }
10778
+ }
10779
+ // src/events/decorators.ts
10780
+ import"reflect-metadata";
10781
+ function OnEvent(event, options = {}) {
10782
+ return (target, propertyKey, descriptor) => {
10783
+ const methodName = String(propertyKey);
10784
+ const constructor = target.constructor;
10785
+ const existingMetadata = Reflect.getMetadata(ON_EVENT_METADATA_KEY, constructor) || [];
10786
+ const metadata = {
10787
+ methodName,
10788
+ event,
10789
+ async: options.async ?? false,
10790
+ priority: options.priority ?? 0
10791
+ };
10792
+ Reflect.defineMetadata(ON_EVENT_METADATA_KEY, [...existingMetadata, metadata], constructor);
10793
+ Reflect.defineMetadata(EVENT_LISTENER_CLASS_METADATA_KEY, true, constructor);
10794
+ return descriptor;
10795
+ };
10796
+ }
10797
+ function getOnEventMetadata(target) {
10798
+ return Reflect.getMetadata(ON_EVENT_METADATA_KEY, target);
10799
+ }
10800
+ function isEventListenerClass(target) {
10801
+ return Reflect.getMetadata(EVENT_LISTENER_CLASS_METADATA_KEY, target) === true;
10802
+ }
10803
+ // src/events/event-module.ts
10804
+ init_module();
10805
+ import"reflect-metadata";
10806
+ class EventListenerScanner {
10807
+ eventEmitter;
10808
+ container;
10809
+ constructor(eventEmitter, container) {
10810
+ this.eventEmitter = eventEmitter;
10811
+ this.container = container;
10812
+ }
10813
+ scanAndRegister(listenerClasses) {
10814
+ for (const listenerClass of listenerClasses) {
10815
+ this.registerListenerClass(listenerClass);
10816
+ }
10817
+ }
10818
+ registerListenerClass(listenerClass) {
10819
+ if (!isEventListenerClass(listenerClass)) {
10820
+ return;
10821
+ }
10822
+ const metadata = getOnEventMetadata(listenerClass);
10823
+ if (!metadata || metadata.length === 0) {
10824
+ return;
10825
+ }
10826
+ const instance = this.container.resolve(listenerClass);
10827
+ if (!instance) {
10828
+ console.warn(`[EventModule] Failed to resolve listener class: ${listenerClass.name}. ` + "Make sure it is registered as a provider.");
10829
+ return;
10830
+ }
10831
+ for (const listenerMetadata of metadata) {
10832
+ const method = instance[listenerMetadata.methodName];
10833
+ if (typeof method !== "function") {
10834
+ console.warn(`[EventModule] Method "${listenerMetadata.methodName}" not found on ${listenerClass.name}`);
10835
+ continue;
10836
+ }
10837
+ const boundMethod = method.bind(instance);
10838
+ this.eventEmitter.on(listenerMetadata.event, boundMethod, {
10839
+ async: listenerMetadata.async,
10840
+ priority: listenerMetadata.priority
10841
+ });
10842
+ }
10843
+ }
10844
+ }
10845
+ var EVENT_LISTENER_SCANNER_TOKEN = Symbol("@dangao/bun-server:events:scanner");
10846
+
10847
+ class EventModule {
10848
+ static listenerClasses = [];
10849
+ static forRoot(options = {}) {
10850
+ const providers2 = [];
10851
+ const eventEmitter = new EventEmitterService(options);
10852
+ providers2.push({
10853
+ provide: EVENT_OPTIONS_TOKEN,
10854
+ useValue: options
10855
+ });
10856
+ providers2.push({
10857
+ provide: EVENT_EMITTER_TOKEN,
10858
+ useValue: eventEmitter
10859
+ });
10860
+ const existingMetadata = Reflect.getMetadata(MODULE_METADATA_KEY, EventModule) || {};
10861
+ const metadata = {
10862
+ ...existingMetadata,
10863
+ providers: [...existingMetadata.providers || [], ...providers2],
10864
+ exports: [
10865
+ ...existingMetadata.exports || [],
10866
+ EVENT_EMITTER_TOKEN,
10867
+ EVENT_OPTIONS_TOKEN
10868
+ ]
10869
+ };
10870
+ Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, EventModule);
10871
+ EventModule.listenerClasses = [];
10872
+ return EventModule;
10873
+ }
10874
+ static registerListeners(listenerClasses) {
10875
+ EventModule.listenerClasses.push(...listenerClasses);
10876
+ }
10877
+ static initializeListeners(listenerContainer, additionalListeners = []) {
10878
+ const registry = ModuleRegistry.getInstance();
10879
+ const eventModuleRef = registry.getModuleRef(EventModule);
10880
+ let eventEmitter;
10881
+ if (eventModuleRef) {
10882
+ try {
10883
+ eventEmitter = eventModuleRef.container.resolve(EVENT_EMITTER_TOKEN);
10884
+ } catch {}
10885
+ }
10886
+ if (!eventEmitter) {
10887
+ console.warn("[EventModule] EventEmitter not found. Make sure EventModule.forRoot() is called and the module is registered.");
10888
+ return;
10889
+ }
10890
+ const resolveContainer = listenerContainer ?? eventModuleRef?.container;
10891
+ if (!resolveContainer) {
10892
+ console.warn("[EventModule] No container available to resolve listeners.");
10893
+ return;
10894
+ }
10895
+ const scanner = new EventListenerScanner(eventEmitter, resolveContainer);
10896
+ const allListeners = [
10897
+ ...EventModule.listenerClasses,
10898
+ ...additionalListeners
10899
+ ];
10900
+ scanner.scanAndRegister(allListeners);
10901
+ }
10902
+ static getEventEmitter(container) {
10903
+ const registry = ModuleRegistry.getInstance();
10904
+ const moduleRef = registry.getModuleRef(EventModule);
10905
+ if (moduleRef) {
10906
+ try {
10907
+ return moduleRef.container.resolve(EVENT_EMITTER_TOKEN);
10908
+ } catch {}
10909
+ }
10910
+ if (container) {
10911
+ try {
10912
+ return container.resolve(EVENT_EMITTER_TOKEN);
10913
+ } catch {}
10914
+ }
10915
+ return;
10916
+ }
10917
+ }
10918
+ EventModule = __legacyDecorateClassTS([
10919
+ Module({
10920
+ providers: []
10921
+ })
10922
+ ], EventModule);
9514
10923
  export {
10924
+ validateParameters,
10925
+ validateObjectSync,
10926
+ validateObject,
9515
10927
  scanInterceptorMetadata,
9516
10928
  requiresAuth,
10929
+ registerReflector,
10930
+ isValidateClass,
10931
+ isGlobalModule,
10932
+ isEventListenerClass,
10933
+ getValidationMetadata,
9517
10934
  getTransactionMetadata,
10935
+ getRolesMetadata,
9518
10936
  getRepositoryMetadata,
10937
+ getOnEventMetadata,
10938
+ getGuardsMetadata,
10939
+ getGuardRegistry,
9519
10940
  getEntityMetadata,
9520
10941
  getColumnMetadata,
10942
+ getClassValidationMetadata,
9521
10943
  getAuthMetadata,
9522
10944
  createUserKeyGenerator,
9523
10945
  createTokenKeyGenerator,
9524
10946
  createSwaggerUIMiddleware,
9525
10947
  createStaticFileMiddleware,
10948
+ createSimpleValidator,
9526
10949
  createSessionMiddleware,
9527
10950
  createSecurityFilter,
10951
+ createRolesGuard,
9528
10952
  createRequestLoggingMiddleware,
10953
+ createRegexValidator,
9529
10954
  createRateLimitMiddleware,
9530
10955
  createLoggerMiddleware,
9531
10956
  createHttpMetricsMiddleware,
9532
10957
  createFileUploadMiddleware,
9533
10958
  createErrorHandlingMiddleware,
10959
+ createCustomValidator,
9534
10960
  createCorsMiddleware,
9535
10961
  contextStore,
9536
10962
  checkRoles,
@@ -9538,10 +10964,15 @@ export {
9538
10964
  WebSocketGatewayRegistry,
9539
10965
  WebSocketGateway,
9540
10966
  ValidationError,
10967
+ ValidateNested,
10968
+ ValidateIf,
10969
+ ValidateClass,
9541
10970
  Validate,
9542
10971
  UserInfoRequestInterceptor,
9543
10972
  UseMiddleware,
10973
+ UseGuards,
9544
10974
  UnauthorizedException,
10975
+ Transform,
9545
10976
  Transactional,
9546
10977
  TransactionStatus,
9547
10978
  TransactionManager,
@@ -9570,6 +11001,8 @@ export {
9570
11001
  RouteRegistry,
9571
11002
  Route,
9572
11003
  RoundRobinLoadBalancer,
11004
+ RolesGuard,
11005
+ Roles,
9573
11006
  RoleBasedAccessDecisionManager,
9574
11007
  RetryStrategyImpl,
9575
11008
  ResponseTransformInterceptor,
@@ -9578,11 +11011,14 @@ export {
9578
11011
  RequestWrapper,
9579
11012
  RequestLogInterceptor,
9580
11013
  Repository,
11014
+ Reflector,
9581
11015
  RedisSessionStore,
9582
11016
  RedisCacheStore,
9583
11017
  RateLimiter,
9584
11018
  RateLimit,
9585
11019
  RandomLoadBalancer,
11020
+ ROLES_METADATA_KEY,
11021
+ REFLECTOR_TOKEN,
9586
11022
  QueueService,
9587
11023
  QueueModule,
9588
11024
  Queue,
@@ -9590,6 +11026,7 @@ export {
9590
11026
  Query,
9591
11027
  QUEUE_SERVICE_TOKEN,
9592
11028
  QUEUE_OPTIONS_TOKEN,
11029
+ Property,
9593
11030
  Propagation,
9594
11031
  PrometheusFormatter,
9595
11032
  PrimaryKey,
@@ -9603,20 +11040,27 @@ export {
9603
11040
  PERMISSION_METADATA_KEY,
9604
11041
  PATCH,
9605
11042
  OrmService,
11043
+ OptionalAuthGuard,
9606
11044
  OnOpen,
9607
11045
  OnMessage,
11046
+ OnEvent,
9608
11047
  OnClose,
9609
11048
  ORM_SERVICE_TOKEN,
11049
+ ON_EVENT_METADATA_KEY,
9610
11050
  OAuth2Service,
9611
11051
  OAuth2Controller,
9612
11052
  OAuth2AuthenticationProvider,
9613
11053
  OAUTH2_SERVICE_TOKEN,
9614
11054
  NotFoundException,
11055
+ NotEquals,
11056
+ NotContains,
11057
+ NestedProperty,
9615
11058
  NacosServiceRegistry,
9616
11059
  NacosConfigCenter,
9617
11060
  ModuleRegistry,
9618
11061
  Module,
9619
11062
  MinLength,
11063
+ Min,
9620
11064
  MiddlewarePipeline,
9621
11065
  MetricsModule,
9622
11066
  MetricsCollector,
@@ -9624,6 +11068,9 @@ export {
9624
11068
  MemorySessionStore,
9625
11069
  MemoryQueueStore,
9626
11070
  MemoryCacheStore,
11071
+ MaxLength,
11072
+ Max,
11073
+ Matches,
9627
11074
  METRICS_SERVICE_TOKEN,
9628
11075
  METRICS_OPTIONS_TOKEN,
9629
11076
  LoggerModule,
@@ -9633,6 +11080,7 @@ export {
9633
11080
  Log,
9634
11081
  LoadBalancerFactory,
9635
11082
  Lifecycle,
11083
+ Length,
9636
11084
  LeastActiveLoadBalancer,
9637
11085
  LOG_METADATA_KEY,
9638
11086
  LOGGER_TOKEN,
@@ -9640,10 +11088,39 @@ export {
9640
11088
  JWT_UTIL_TOKEN,
9641
11089
  JWTUtil,
9642
11090
  IsolationLevel,
11091
+ IsUrl,
11092
+ IsUUID,
9643
11093
  IsString,
11094
+ IsSemVer,
11095
+ IsPostalCode,
11096
+ IsPositive,
11097
+ IsPort,
11098
+ IsPhoneNumber,
9644
11099
  IsOptional,
11100
+ IsObject,
11101
+ IsNumberString,
9645
11102
  IsNumber,
11103
+ IsNotIn,
11104
+ IsNotEmptyObject,
11105
+ IsNotEmpty,
11106
+ IsNegative,
11107
+ IsMacAddress,
11108
+ IsJSON,
11109
+ IsInt,
11110
+ IsIn,
11111
+ IsIdCard,
11112
+ IsIPv4,
11113
+ IsHexColor,
9646
11114
  IsEmail,
11115
+ IsDivisibleBy,
11116
+ IsDefined,
11117
+ IsDate,
11118
+ IsCreditCard,
11119
+ IsBoolean,
11120
+ IsBetween,
11121
+ IsArray,
11122
+ IsAlphanumeric,
11123
+ IsAlpha,
9647
11124
  InternalServerErrorException,
9648
11125
  InterceptorRegistry,
9649
11126
  InterceptorChain,
@@ -9656,12 +11133,26 @@ export {
9656
11133
  Header,
9657
11134
  HEALTH_OPTIONS_TOKEN,
9658
11135
  HEALTH_INDICATORS_TOKEN,
11136
+ GuardRegistry,
11137
+ Global,
11138
+ GUARD_REGISTRY_TOKEN,
11139
+ GUARDS_METADATA_KEY,
11140
+ GLOBAL_MODULE_METADATA_KEY,
9659
11141
  GET,
9660
11142
  ForbiddenException,
11143
+ ExecutionContextImpl,
9661
11144
  ExceptionFilterRegistry,
11145
+ EventModule,
11146
+ EventListenerScanner,
11147
+ EventEmitterService,
9662
11148
  ErrorHandlerInterceptor,
11149
+ Equals,
9663
11150
  Entity,
9664
11151
  EnableCacheProxy,
11152
+ EVENT_OPTIONS_TOKEN,
11153
+ EVENT_LISTENER_SCANNER_TOKEN,
11154
+ EVENT_LISTENER_CLASS_METADATA_KEY,
11155
+ EVENT_EMITTER_TOKEN,
9665
11156
  DrizzleBaseRepository,
9666
11157
  DatabaseService2 as DatabaseService,
9667
11158
  DatabaseModule,
@@ -9677,6 +11168,7 @@ export {
9677
11168
  ContextService,
9678
11169
  Context2 as ContextParam,
9679
11170
  Context,
11171
+ Contains,
9680
11172
  Container,
9681
11173
  ConsoleTraceCollector,
9682
11174
  ConsistentHashLoadBalancer,
@@ -9713,7 +11205,15 @@ export {
9713
11205
  BaseInterceptor,
9714
11206
  BadRequestException,
9715
11207
  AuthenticationManager,
11208
+ AuthGuard,
9716
11209
  Auth,
11210
+ ArrayUnique,
11211
+ ArrayNotEmpty,
11212
+ ArrayNotContains,
11213
+ ArrayNestedProperty,
11214
+ ArrayMinSize,
11215
+ ArrayMaxSize,
11216
+ ArrayContains,
9717
11217
  Application,
9718
11218
  ApiTags,
9719
11219
  ApiResponse,