azurajs 3.0.1 → 3.0.2

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 (106) hide show
  1. package/dist/config/index.js +128 -6
  2. package/dist/config/index.js.map +1 -1
  3. package/dist/config/index.mjs +130 -1
  4. package/dist/config/index.mjs.map +1 -1
  5. package/dist/core/index.js +1100 -11
  6. package/dist/core/index.js.map +1 -1
  7. package/dist/core/index.mjs +1102 -3
  8. package/dist/core/index.mjs.map +1 -1
  9. package/dist/decorators/index.js +117 -87
  10. package/dist/decorators/index.js.map +1 -1
  11. package/dist/decorators/index.mjs +98 -1
  12. package/dist/decorators/index.mjs.map +1 -1
  13. package/dist/index.js +2592 -236
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.mjs +2537 -9
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/middleware/index.js +16 -7
  18. package/dist/middleware/index.js.map +1 -1
  19. package/dist/middleware/index.mjs +17 -1
  20. package/dist/middleware/index.mjs.map +1 -1
  21. package/dist/plugins/index.js +1056 -73
  22. package/dist/plugins/index.js.map +1 -1
  23. package/dist/plugins/index.mjs +1042 -1
  24. package/dist/plugins/index.mjs.map +1 -1
  25. package/dist/types/index.js +49 -12
  26. package/dist/types/index.js.map +1 -1
  27. package/dist/types/index.mjs +49 -2
  28. package/dist/types/index.mjs.map +1 -1
  29. package/dist/utils/index.js +551 -50
  30. package/dist/utils/index.js.map +1 -1
  31. package/dist/utils/index.mjs +541 -3
  32. package/dist/utils/index.mjs.map +1 -1
  33. package/package.json +35 -17
  34. package/{dist/chunk-DR254CWJ.mjs → src/config/ConfigModule.ts} +169 -132
  35. package/src/config/index.ts +1 -0
  36. package/src/core/index.ts +2 -0
  37. package/src/core/router.ts +284 -0
  38. package/{dist/chunk-EYAHUNC7.mjs → src/core/server.ts} +590 -699
  39. package/src/decorators/Route.ts +110 -0
  40. package/src/decorators/index.ts +23 -0
  41. package/src/index.ts +12 -0
  42. package/src/middleware/LoggingMiddleware.ts +20 -0
  43. package/src/middleware/index.ts +1 -0
  44. package/src/plugins/CORSPlugin.ts +56 -0
  45. package/src/plugins/CircuitBreakerPlugin.ts +84 -0
  46. package/src/plugins/CompressionPlugin.ts +80 -0
  47. package/src/plugins/ETagPlugin.ts +31 -0
  48. package/src/plugins/HealthCheckPlugin.ts +57 -0
  49. package/src/plugins/HelmetPlugin.ts +89 -0
  50. package/src/plugins/JWTPlugin.ts +132 -0
  51. package/src/plugins/MultipartPlugin.ts +168 -0
  52. package/src/plugins/ProxyPlugin.ts +89 -0
  53. package/src/plugins/RateLimitPlugin.ts +96 -0
  54. package/src/plugins/RequestIdPlugin.ts +21 -0
  55. package/src/plugins/SSEPlugin.ts +114 -0
  56. package/src/plugins/SessionPlugin.ts +98 -0
  57. package/src/plugins/StaticPlugin.ts +152 -0
  58. package/src/plugins/TimeoutPlugin.ts +33 -0
  59. package/src/plugins/index.ts +18 -0
  60. package/src/types/common.type.ts +82 -0
  61. package/src/types/config.type.ts +57 -0
  62. package/{dist/chunk-OWUGAI5V.mjs → src/types/http/status.ts} +49 -51
  63. package/src/types/index.ts +55 -0
  64. package/src/types/plugins/plugin.type.ts +170 -0
  65. package/src/types/reflect.d.ts +14 -0
  66. package/src/types/routes.type.ts +70 -0
  67. package/src/utils/HttpError.ts +62 -0
  68. package/src/utils/IpResolver.ts +30 -0
  69. package/src/utils/Logger.ts +144 -0
  70. package/src/utils/Parser.ts +182 -0
  71. package/src/utils/cookies/CookieManager.ts +48 -0
  72. package/src/utils/index.ts +9 -0
  73. package/{dist/chunk-UWIFSGSQ.mjs → src/utils/validators/DTOValidator.ts} +145 -141
  74. package/src/utils/validators/SchemaValidator.ts +45 -0
  75. package/dist/chunk-3UFAWS2V.js +0 -392
  76. package/dist/chunk-3UFAWS2V.js.map +0 -1
  77. package/dist/chunk-4LSFAAZW.js +0 -4
  78. package/dist/chunk-4LSFAAZW.js.map +0 -1
  79. package/dist/chunk-7NSRIVZM.js +0 -54
  80. package/dist/chunk-7NSRIVZM.js.map +0 -1
  81. package/dist/chunk-AOG6NYAM.js +0 -144
  82. package/dist/chunk-AOG6NYAM.js.map +0 -1
  83. package/dist/chunk-DR254CWJ.mjs.map +0 -1
  84. package/dist/chunk-EYAHUNC7.mjs.map +0 -1
  85. package/dist/chunk-HHDQPIJN.mjs +0 -19
  86. package/dist/chunk-HHDQPIJN.mjs.map +0 -1
  87. package/dist/chunk-HHZNAGGI.js +0 -702
  88. package/dist/chunk-HHZNAGGI.js.map +0 -1
  89. package/dist/chunk-KJM5XCAY.js +0 -21
  90. package/dist/chunk-KJM5XCAY.js.map +0 -1
  91. package/dist/chunk-NLSZKAPA.mjs +0 -1044
  92. package/dist/chunk-NLSZKAPA.mjs.map +0 -1
  93. package/dist/chunk-OWUGAI5V.mjs.map +0 -1
  94. package/dist/chunk-POPNQEOK.js +0 -1063
  95. package/dist/chunk-POPNQEOK.js.map +0 -1
  96. package/dist/chunk-QPRW4YU4.js +0 -134
  97. package/dist/chunk-QPRW4YU4.js.map +0 -1
  98. package/dist/chunk-REJDZUZ5.mjs +0 -382
  99. package/dist/chunk-REJDZUZ5.mjs.map +0 -1
  100. package/dist/chunk-TC6N6TJZ.mjs +0 -100
  101. package/dist/chunk-TC6N6TJZ.mjs.map +0 -1
  102. package/dist/chunk-TEUXKMXP.js +0 -122
  103. package/dist/chunk-TEUXKMXP.js.map +0 -1
  104. package/dist/chunk-UWIFSGSQ.mjs.map +0 -1
  105. package/dist/chunk-YPBKY4KY.mjs +0 -3
  106. package/dist/chunk-YPBKY4KY.mjs.map +0 -1
@@ -0,0 +1,284 @@
1
+ import type { HttpMethod, RouteHandler, MiddlewareHandler, RouteMatch } from "../types/common.type.js";
2
+
3
+ const PARAM_PREFIX = 58; // ':'
4
+
5
+ interface RadixNode {
6
+ segment: string;
7
+ children: Map<string, RadixNode>;
8
+ paramChild: RadixNode | null;
9
+ paramName: string;
10
+ handlers: Map<HttpMethod, StoredRoute>;
11
+ wildcardHandler: Map<HttpMethod, StoredRoute> | null;
12
+ }
13
+
14
+ interface StoredRoute {
15
+ handler: RouteHandler;
16
+ middlewares: MiddlewareHandler[];
17
+ meta?: Record<string, any>;
18
+ }
19
+
20
+ function createNode(segment: string = ""): RadixNode {
21
+ return {
22
+ segment,
23
+ children: new Map(),
24
+ paramChild: null,
25
+ paramName: "",
26
+ handlers: new Map(),
27
+ wildcardHandler: null,
28
+ };
29
+ }
30
+
31
+ /**
32
+ * LRU Cache with O(1) get/set via doubly linked list + hash map.
33
+ * Used for route lookup caching in hot paths.
34
+ */
35
+ class LRUCache<K, V> {
36
+ private capacity: number;
37
+ private map: Map<K, { value: V; key: K; prev: any; next: any }>;
38
+ private head: any;
39
+ private tail: any;
40
+
41
+ constructor(capacity: number) {
42
+ this.capacity = capacity;
43
+ this.map = new Map();
44
+ this.head = { prev: null, next: null };
45
+ this.tail = { prev: null, next: null };
46
+ this.head.next = this.tail;
47
+ this.tail.prev = this.head;
48
+ }
49
+
50
+ get(key: K): V | undefined {
51
+ const node = this.map.get(key);
52
+ if (!node) return undefined;
53
+ this.moveToHead(node);
54
+ return node.value;
55
+ }
56
+
57
+ set(key: K, value: V): void {
58
+ const existing = this.map.get(key);
59
+ if (existing) {
60
+ existing.value = value;
61
+ this.moveToHead(existing);
62
+ return;
63
+ }
64
+
65
+ const node = { value, key, prev: null as any, next: null as any };
66
+ this.map.set(key, node);
67
+ this.addToHead(node);
68
+
69
+ if (this.map.size > this.capacity) {
70
+ const removed = this.removeTail();
71
+ if (removed) this.map.delete(removed.key);
72
+ }
73
+ }
74
+
75
+ private addToHead(node: any): void {
76
+ node.prev = this.head;
77
+ node.next = this.head.next;
78
+ this.head.next.prev = node;
79
+ this.head.next = node;
80
+ }
81
+
82
+ private removeNode(node: any): void {
83
+ node.prev.next = node.next;
84
+ node.next.prev = node.prev;
85
+ }
86
+
87
+ private moveToHead(node: any): void {
88
+ this.removeNode(node);
89
+ this.addToHead(node);
90
+ }
91
+
92
+ private removeTail(): any {
93
+ const node = this.tail.prev;
94
+ if (node === this.head) return null;
95
+ this.removeNode(node);
96
+ return node;
97
+ }
98
+
99
+ clear(): void {
100
+ this.map.clear();
101
+ this.head.next = this.tail;
102
+ this.tail.prev = this.head;
103
+ }
104
+ }
105
+
106
+ export class Router {
107
+ private root: RadixNode = createNode();
108
+ private cache: LRUCache<string, RouteMatch | null>;
109
+ private staticRoutes: Map<string, StoredRoute> = new Map();
110
+
111
+ constructor(cacheSize: number = 1024) {
112
+ this.cache = new LRUCache(cacheSize);
113
+ }
114
+
115
+ add(
116
+ method: HttpMethod,
117
+ path: string,
118
+ handler: RouteHandler,
119
+ middlewares: MiddlewareHandler[] = [],
120
+ meta?: Record<string, any>,
121
+ ): void {
122
+ this.cache.clear();
123
+ const normalizedPath = this.normalizePath(path);
124
+ const stored: StoredRoute = { handler, middlewares, meta };
125
+
126
+ if (!normalizedPath.includes(":") && !normalizedPath.includes("*")) {
127
+ const key = `${method}:${normalizedPath}`;
128
+ this.staticRoutes.set(key, stored);
129
+ return;
130
+ }
131
+
132
+ const segments = normalizedPath.split("/").filter(Boolean);
133
+ let node = this.root;
134
+
135
+ for (let i = 0; i < segments.length; i++) {
136
+ const seg = segments[i];
137
+
138
+ if (seg === "*") {
139
+ if (!node.wildcardHandler) {
140
+ node.wildcardHandler = new Map();
141
+ }
142
+ node.wildcardHandler.set(method, stored);
143
+ return;
144
+ }
145
+
146
+ if (seg.charCodeAt(0) === PARAM_PREFIX) {
147
+ if (!node.paramChild) {
148
+ node.paramChild = createNode(seg);
149
+ node.paramChild.paramName = seg.slice(1);
150
+ }
151
+ node = node.paramChild;
152
+ continue;
153
+ }
154
+
155
+ let child = node.children.get(seg);
156
+ if (!child) {
157
+ child = createNode(seg);
158
+ node.children.set(seg, child);
159
+ }
160
+ node = child;
161
+ }
162
+
163
+ node.handlers.set(method, stored);
164
+ }
165
+
166
+ find(method: HttpMethod, path: string): RouteMatch | null {
167
+ const normalizedPath = this.normalizePath(path);
168
+
169
+ const staticKey = `${method}:${normalizedPath}`;
170
+ const staticRoute = this.staticRoutes.get(staticKey);
171
+ if (staticRoute) {
172
+ return {
173
+ handler: staticRoute.handler,
174
+ params: {},
175
+ middlewares: staticRoute.middlewares,
176
+ meta: staticRoute.meta,
177
+ };
178
+ }
179
+
180
+ const cacheKey = staticKey;
181
+ const cached = this.cache.get(cacheKey);
182
+ if (cached !== undefined) {
183
+ return cached ? { ...cached, params: { ...cached.params } } : null;
184
+ }
185
+
186
+ const segments = normalizedPath.split("/").filter(Boolean);
187
+ const params: Record<string, string> = {};
188
+ const result = this.matchNode(this.root, segments, 0, params, method);
189
+
190
+ if (result) {
191
+ const match: RouteMatch = {
192
+ handler: result.handler,
193
+ params,
194
+ middlewares: result.middlewares,
195
+ meta: result.meta,
196
+ };
197
+ this.cache.set(cacheKey, match);
198
+ return { ...match, params: { ...params } };
199
+ }
200
+
201
+ this.cache.set(cacheKey, null);
202
+ return null;
203
+ }
204
+
205
+ private matchNode(
206
+ node: RadixNode,
207
+ segments: string[],
208
+ idx: number,
209
+ params: Record<string, string>,
210
+ method: HttpMethod,
211
+ ): StoredRoute | null {
212
+ if (idx === segments.length) {
213
+ return node.handlers.get(method) ?? null;
214
+ }
215
+
216
+ const seg = segments[idx];
217
+
218
+ const child = node.children.get(seg);
219
+ if (child) {
220
+ const result = this.matchNode(child, segments, idx + 1, params, method);
221
+ if (result) return result;
222
+ }
223
+
224
+ if (node.paramChild) {
225
+ params[node.paramChild.paramName] = seg;
226
+ const result = this.matchNode(node.paramChild, segments, idx + 1, params, method);
227
+ if (result) return result;
228
+ delete params[node.paramChild.paramName];
229
+ }
230
+
231
+ if (node.wildcardHandler) {
232
+ const route = node.wildcardHandler.get(method);
233
+ if (route) return route;
234
+ }
235
+
236
+ return null;
237
+ }
238
+
239
+ private normalizePath(path: string): string {
240
+ if (path === "/") return "/";
241
+ if (path.endsWith("/") && path.length > 1) return path.slice(0, -1);
242
+ return path;
243
+ }
244
+
245
+ getAllRoutes(): Array<{ method: HttpMethod; path: string }> {
246
+ const routes: Array<{ method: HttpMethod; path: string }> = [];
247
+
248
+ for (const [key] of this.staticRoutes) {
249
+ const [method, path] = key.split(":", 2) as [HttpMethod, string];
250
+ routes.push({ method, path });
251
+ }
252
+
253
+ this.collectRoutes(this.root, "", routes);
254
+ return routes;
255
+ }
256
+
257
+ private collectRoutes(
258
+ node: RadixNode,
259
+ prefix: string,
260
+ routes: Array<{ method: HttpMethod; path: string }>,
261
+ ): void {
262
+ for (const [method] of node.handlers) {
263
+ routes.push({ method, path: prefix || "/" });
264
+ }
265
+
266
+ for (const [seg, child] of node.children) {
267
+ this.collectRoutes(child, `${prefix}/${seg}`, routes);
268
+ }
269
+
270
+ if (node.paramChild) {
271
+ this.collectRoutes(
272
+ node.paramChild,
273
+ `${prefix}/:${node.paramChild.paramName}`,
274
+ routes,
275
+ );
276
+ }
277
+
278
+ if (node.wildcardHandler) {
279
+ for (const [method] of node.wildcardHandler) {
280
+ routes.push({ method, path: `${prefix}/*` });
281
+ }
282
+ }
283
+ }
284
+ }