@j3r3mcdev/oast-server 1.1.1 → 1.1.3

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 (191) hide show
  1. package/.github/workflows/ci.yml +29 -29
  2. package/.github/workflows/publish.yml +31 -31
  3. package/README.md +192 -192
  4. package/dist/api/controllers/__tests__/tasks.controller.test.d.ts +1 -0
  5. package/dist/api/controllers/events.controller.d.ts +6 -0
  6. package/dist/api/controllers/health.controller.d.ts +4 -0
  7. package/dist/api/controllers/index.d.ts +0 -0
  8. package/dist/api/controllers/tasks.controller.d.ts +40 -0
  9. package/dist/api/dto/__tests__/create-task.dto.test.d.ts +1 -0
  10. package/dist/api/dto/__tests__/filter-tasks.dto.test.d.ts +1 -0
  11. package/dist/api/dto/create-task.dto.d.ts +9 -0
  12. package/dist/api/dto/filter-tasks.dto.d.ts +8 -0
  13. package/dist/api/services/__tests__/events.service.test.d.ts +1 -0
  14. package/dist/api/services/__tests__/tasks.service.test.d.ts +1 -0
  15. package/dist/api/services/events.service.d.ts +8 -0
  16. package/dist/api/services/tasks.service.d.ts +22 -0
  17. package/dist/api/sse/events.stream.d.ts +25 -0
  18. package/dist/bootstrap.d.ts +1 -0
  19. package/dist/bootstrap.js +76 -0
  20. package/dist/config/constants.d.ts +0 -0
  21. package/dist/config/env.d.ts +0 -0
  22. package/dist/core/__tests__/core-router.test.d.ts +1 -0
  23. package/dist/core/__tests__/core-server.test.d.ts +1 -0
  24. package/dist/core/__tests__/event.normalizer.test.d.ts +1 -0
  25. package/dist/core/__tests__/event.router.test.d.ts +1 -0
  26. package/dist/core/__tests__/logger.test.d.ts +1 -0
  27. package/dist/core/__tests__/storage-manager.test.d.ts +1 -0
  28. package/dist/core/event.normalizer.d.ts +10 -0
  29. package/dist/core/event.router.d.ts +7 -0
  30. package/dist/core/http/__tests__/adapter-node.test.d.ts +1 -0
  31. package/dist/core/http/__tests__/body-parser-multipart.test.d.ts +1 -0
  32. package/dist/core/http/__tests__/body-parser-raw.test.d.ts +1 -0
  33. package/dist/core/http/__tests__/body-parser-text.test.d.ts +1 -0
  34. package/dist/core/http/__tests__/compile-path.test.d.ts +1 -0
  35. package/dist/core/http/__tests__/middleware-pipeline.test.d.ts +1 -0
  36. package/dist/core/http/__tests__/request.test.d.ts +1 -0
  37. package/dist/core/http/__tests__/response.test.d.ts +1 -0
  38. package/dist/core/http/__tests__/router-match.test.d.ts +1 -0
  39. package/dist/core/http/adapter-node.d.ts +8 -0
  40. package/dist/core/http/buildRequest.d.ts +2 -0
  41. package/dist/core/http/compile-path.d.ts +13 -0
  42. package/dist/core/http/errors.d.ts +9 -0
  43. package/dist/core/http/http-server.d.ts +7 -0
  44. package/dist/core/http/index.d.ts +0 -0
  45. package/dist/core/http/main.d.ts +0 -0
  46. package/dist/core/http/middleware.d.ts +12 -0
  47. package/dist/core/http/request.d.ts +35 -0
  48. package/dist/core/http/response.d.ts +17 -0
  49. package/dist/core/http/router.d.ts +28 -0
  50. package/dist/core/http/utils.d.ts +0 -0
  51. package/dist/core/id-generator.d.ts +3 -0
  52. package/dist/core/logger.d.ts +29 -0
  53. package/dist/core/router.d.ts +16 -0
  54. package/dist/core/server.d.ts +25 -0
  55. package/dist/core/storage.d.ts +24 -0
  56. package/dist/index.d.ts +9 -0
  57. package/dist/index.js +19 -74
  58. package/dist/listeners/api/__tests__/api.controller.test.d.ts +1 -0
  59. package/dist/listeners/api/__tests__/api.extractor.test.d.ts +1 -0
  60. package/dist/listeners/api/__tests__/api.listener.test.d.ts +1 -0
  61. package/dist/listeners/api/__tests__/api.routes.test.d.ts +1 -0
  62. package/dist/listeners/api/__tests__/api.sse.test.d.ts +1 -0
  63. package/dist/listeners/api/api.controllers.d.ts +9 -0
  64. package/dist/listeners/api/api.extractor.d.ts +5 -0
  65. package/dist/listeners/api/api.listener.d.ts +17 -0
  66. package/dist/listeners/api/api.routes.d.ts +5 -0
  67. package/dist/listeners/api/api.sse.d.ts +10 -0
  68. package/dist/listeners/dns/__tests__/dns.test.d.ts +1 -0
  69. package/dist/listeners/dns/dns.extractor.d.ts +8 -0
  70. package/dist/listeners/dns/dns.listener.d.ts +15 -0
  71. package/dist/listeners/http/__tests__/http.extractor.test.d.ts +1 -0
  72. package/dist/listeners/http/__tests__/http.listener.test.d.ts +1 -0
  73. package/dist/listeners/http/http.extractor.d.ts +11 -0
  74. package/dist/listeners/http/http.listener.d.ts +17 -0
  75. package/dist/listeners/listener.interface.d.ts +4 -0
  76. package/dist/listeners/smtp/__tests__/smtp.extractor.test.d.ts +1 -0
  77. package/dist/listeners/smtp/__tests__/smtp.listener.test.d.ts +1 -0
  78. package/dist/listeners/smtp/smtp.extractor.d.ts +12 -0
  79. package/dist/listeners/smtp/smtp.listener.d.ts +13 -0
  80. package/dist/listeners/ssrf/__tests__/ssrf.extractor.test.d.ts +1 -0
  81. package/dist/listeners/ssrf/__tests__/ssrf.listener.test.d.ts +1 -0
  82. package/dist/listeners/ssrf/__tests__/ssrf.listener.test.js +4 -16
  83. package/dist/listeners/ssrf/ssrf.extractor.d.ts +10 -0
  84. package/dist/listeners/ssrf/ssrf.listener.d.ts +8 -0
  85. package/dist/listeners/tcp/tcp.extractor.d.ts +4 -0
  86. package/dist/listeners/tcp/tcp.listener.d.ts +18 -0
  87. package/dist/listeners/webhook/__tests__/webhook.extractor.test.d.ts +1 -0
  88. package/dist/listeners/webhook/__tests__/webhook.listener.test.d.ts +1 -0
  89. package/dist/listeners/webhook/webhook.extractor.d.ts +8 -0
  90. package/dist/listeners/webhook/webhook.listener.d.ts +8 -0
  91. package/dist/listeners/websocket/__tests__/websocket.extractor.test.d.ts +1 -0
  92. package/dist/listeners/websocket/__tests__/websocket.listener.test.d.ts +1 -0
  93. package/dist/listeners/websocket/websocket.extractor.d.ts +10 -0
  94. package/dist/listeners/websocket/websocket.listener.d.ts +8 -0
  95. package/dist/storage-adapters/adapters/__tests__/memory.storage.test.d.ts +1 -0
  96. package/dist/storage-adapters/adapters/memory.storage.d.ts +21 -0
  97. package/dist/storage-adapters/adapters/redis.storage.d.ts +0 -0
  98. package/dist/storage-adapters/adapters/sqlite.storage.d.ts +0 -0
  99. package/dist/storage-adapters/storage.interface.d.ts +18 -0
  100. package/dist/types/event.types.d.ts +118 -0
  101. package/dist/utils/token.d.ts +0 -0
  102. package/jest.config.js +14 -14
  103. package/package.json +45 -45
  104. package/sadmin list shadows +9 -9
  105. package/src/api/controllers/__tests__/tasks.controller.test.ts +74 -74
  106. package/src/api/controllers/events.controller.ts +10 -10
  107. package/src/api/controllers/health.controller.ts +7 -7
  108. package/src/api/controllers/tasks.controller.ts +41 -41
  109. package/src/api/dto/__tests__/create-task.dto.test.ts +41 -41
  110. package/src/api/dto/__tests__/filter-tasks.dto.test.ts +35 -35
  111. package/src/api/dto/create-task.dto.ts +33 -33
  112. package/src/api/dto/filter-tasks.dto.ts +33 -33
  113. package/src/api/services/__tests__/events.service.test.ts +41 -41
  114. package/src/api/services/__tests__/tasks.service.test.ts +41 -41
  115. package/src/api/services/events.service.ts +17 -17
  116. package/src/api/services/tasks.service.ts +79 -79
  117. package/src/api/sse/events.stream.ts +90 -90
  118. package/src/bootstrap.ts +89 -0
  119. package/src/core/__tests__/core-router.test.ts +30 -30
  120. package/src/core/__tests__/core-server.test.ts +44 -44
  121. package/src/core/__tests__/event.normalizer.test.ts +56 -56
  122. package/src/core/__tests__/event.router.test.ts +89 -89
  123. package/src/core/__tests__/logger.test.ts +32 -32
  124. package/src/core/__tests__/storage-manager.test.ts +74 -74
  125. package/src/core/event.normalizer.ts +147 -147
  126. package/src/core/event.router.ts +13 -13
  127. package/src/core/http/__tests__/adapter-node.test.ts +52 -52
  128. package/src/core/http/__tests__/body-parser-multipart.test.ts +41 -41
  129. package/src/core/http/__tests__/body-parser-raw.test.ts +28 -28
  130. package/src/core/http/__tests__/body-parser-text.test.ts +28 -28
  131. package/src/core/http/__tests__/compile-path.test.ts +39 -39
  132. package/src/core/http/__tests__/middleware-pipeline.test.ts +51 -51
  133. package/src/core/http/__tests__/request.test.ts +34 -34
  134. package/src/core/http/__tests__/response.test.ts +35 -35
  135. package/src/core/http/__tests__/router-match.test.ts +171 -171
  136. package/src/core/http/adapter-node.ts +51 -51
  137. package/src/core/http/buildRequest.ts +18 -18
  138. package/src/core/http/compile-path.ts +32 -32
  139. package/src/core/http/errors.ts +37 -37
  140. package/src/core/http/http-server.ts +52 -52
  141. package/src/core/http/middleware.ts +160 -160
  142. package/src/core/http/request.ts +55 -55
  143. package/src/core/http/response.ts +93 -93
  144. package/src/core/http/router.ts +138 -138
  145. package/src/core/id-generator.ts +8 -8
  146. package/src/core/logger.ts +113 -113
  147. package/src/core/router.ts +44 -44
  148. package/src/core/server.ts +85 -85
  149. package/src/core/storage.ts +64 -64
  150. package/src/index.ts +10 -89
  151. package/src/listeners/api/__tests__/api.controller.test.ts +116 -116
  152. package/src/listeners/api/__tests__/api.extractor.test.ts +46 -46
  153. package/src/listeners/api/__tests__/api.listener.test.ts +82 -82
  154. package/src/listeners/api/__tests__/api.routes.test.ts +155 -155
  155. package/src/listeners/api/__tests__/api.sse.test.ts +105 -105
  156. package/src/listeners/api/api.controllers.ts +67 -67
  157. package/src/listeners/api/api.extractor.ts +43 -43
  158. package/src/listeners/api/api.listener.ts +50 -50
  159. package/src/listeners/api/api.routes.ts +76 -76
  160. package/src/listeners/api/api.sse.ts +38 -38
  161. package/src/listeners/dns/__tests__/dns.test.ts +118 -118
  162. package/src/listeners/dns/dns.extractor.ts +14 -14
  163. package/src/listeners/dns/dns.listener.ts +61 -61
  164. package/src/listeners/http/__tests__/http.extractor.test.ts +59 -59
  165. package/src/listeners/http/__tests__/http.listener.test.ts +133 -133
  166. package/src/listeners/http/http.extractor.ts +15 -15
  167. package/src/listeners/http/http.listener.ts +110 -110
  168. package/src/listeners/listener.interface.ts +4 -4
  169. package/src/listeners/smtp/__tests__/smtp.extractor.test.ts +69 -69
  170. package/src/listeners/smtp/__tests__/smtp.listener.test.ts +150 -150
  171. package/src/listeners/smtp/smtp.extractor.ts +18 -18
  172. package/src/listeners/smtp/smtp.listener.ts +60 -60
  173. package/src/listeners/ssrf/__tests__/ssrf.extractor.test.ts +41 -41
  174. package/src/listeners/ssrf/__tests__/ssrf.listener.test.ts +87 -87
  175. package/src/listeners/ssrf/ssrf.extractor.ts +14 -14
  176. package/src/listeners/ssrf/ssrf.listener.ts +37 -37
  177. package/src/listeners/tcp/tcp.extractor.ts +16 -16
  178. package/src/listeners/tcp/tcp.listener.ts +61 -61
  179. package/src/listeners/webhook/__tests__/webhook.extractor.test.ts +35 -35
  180. package/src/listeners/webhook/__tests__/webhook.listener.test.ts +122 -122
  181. package/src/listeners/webhook/webhook.extractor.ts +12 -12
  182. package/src/listeners/webhook/webhook.listener.ts +58 -58
  183. package/src/listeners/websocket/__tests__/websocket.extractor.test.ts +33 -33
  184. package/src/listeners/websocket/__tests__/websocket.listener.test.ts +90 -90
  185. package/src/listeners/websocket/websocket.extractor.ts +11 -11
  186. package/src/listeners/websocket/websocket.listener.ts +40 -40
  187. package/src/storage-adapters/adapters/__tests__/memory.storage.test.ts +75 -75
  188. package/src/storage-adapters/adapters/memory.storage.ts +64 -64
  189. package/src/storage-adapters/storage.interface.ts +26 -26
  190. package/src/types/event.types.ts +147 -147
  191. package/tsconfig.json +21 -21
@@ -1,138 +1,138 @@
1
- // src/http/router.ts
2
-
3
- import { compilePath } from "./compile-path";
4
- import { Middleware } from "./middleware";
5
-
6
- export class Router {
7
- private routes: Array<{
8
- method: string;
9
- path: string;
10
- compiled: any[];
11
- middlewares: Middleware[];
12
- handler: Function;
13
- }> = [];
14
-
15
- /**
16
- * Enregistre une route avec middlewares optionnels :
17
- * router.get("/x", mw1, mw2, handler)
18
- */
19
- register(method: string, path: string, ...middlewaresAndHandler: any[]) {
20
- const compiled = compilePath(path);
21
-
22
- const handler = middlewaresAndHandler.pop();
23
- const middlewares = middlewaresAndHandler as Middleware[];
24
-
25
- this.routes.push({
26
- method,
27
- path,
28
- compiled,
29
- middlewares,
30
- handler,
31
- });
32
- }
33
-
34
- /**
35
- * Trouve la route et extrait les params
36
- */
37
- match(method: string, urlPath: string) {
38
- const urlSegments = urlPath.replace(/^\//, "").split("/");
39
-
40
- for (const route of this.routes) {
41
- if (route.method !== method) continue;
42
-
43
- const params: Record<string, string> = {};
44
- const compiled = route.compiled;
45
-
46
- if (this.matchSegments(compiled, urlSegments, params)) {
47
- return {
48
- handler: route.handler,
49
- middlewares: route.middlewares,
50
- params,
51
- };
52
- }
53
- }
54
-
55
- return null;
56
- }
57
-
58
- /**
59
- * Ton moteur de matching existant — inchangé
60
- */
61
- private matchSegments(
62
- compiled: any[],
63
- urlSegments: string[],
64
- params: Record<string, string>,
65
- ) {
66
- let i = 0;
67
-
68
- for (let j = 0; j < compiled.length; j++) {
69
- const segment = compiled[j];
70
- const part = urlSegments[i];
71
-
72
- if (!part && segment.type !== "wildcard") {
73
- return false;
74
- }
75
-
76
- if (segment.type === "static") {
77
- if (segment.value !== part) return false;
78
- i++;
79
- continue;
80
- }
81
-
82
- if (segment.type === "param") {
83
- if (!part) return false;
84
- params[segment.name] = part;
85
- i++;
86
- continue;
87
- }
88
-
89
- if (segment.type === "wildcard") {
90
- if (!part) return false;
91
-
92
- const next = compiled[j + 1];
93
- if (!next) return true;
94
-
95
- while (i < urlSegments.length) {
96
- if (next.type === "static" && urlSegments[i] === next.value) {
97
- break;
98
- }
99
- i++;
100
- }
101
-
102
- if (i >= urlSegments.length) return false;
103
-
104
- continue;
105
- }
106
- }
107
-
108
- return i === urlSegments.length;
109
- }
110
-
111
- get(path: string, ...middlewaresAndHandler: any[]) {
112
- this.register("GET", path, ...middlewaresAndHandler);
113
- }
114
-
115
- post(path: string, ...middlewaresAndHandler: any[]) {
116
- this.register("POST", path, ...middlewaresAndHandler);
117
- }
118
-
119
- put(path: string, ...middlewaresAndHandler: any[]) {
120
- this.register("PUT", path, ...middlewaresAndHandler);
121
- }
122
-
123
- delete(path: string, ...middlewaresAndHandler: any[]) {
124
- this.register("DELETE", path, ...middlewaresAndHandler);
125
- }
126
-
127
- patch(path: string, ...middlewaresAndHandler: any[]) {
128
- this.register("PATCH", path, ...middlewaresAndHandler);
129
- }
130
-
131
- options(path: string, ...middlewaresAndHandler: any[]) {
132
- this.register("OPTIONS", path, ...middlewaresAndHandler);
133
- }
134
-
135
- head(path: string, ...middlewaresAndHandler: any[]) {
136
- this.register("HEAD", path, ...middlewaresAndHandler);
137
- }
138
- }
1
+ // src/http/router.ts
2
+
3
+ import { compilePath } from "./compile-path";
4
+ import { Middleware } from "./middleware";
5
+
6
+ export class Router {
7
+ private routes: Array<{
8
+ method: string;
9
+ path: string;
10
+ compiled: any[];
11
+ middlewares: Middleware[];
12
+ handler: Function;
13
+ }> = [];
14
+
15
+ /**
16
+ * Enregistre une route avec middlewares optionnels :
17
+ * router.get("/x", mw1, mw2, handler)
18
+ */
19
+ register(method: string, path: string, ...middlewaresAndHandler: any[]) {
20
+ const compiled = compilePath(path);
21
+
22
+ const handler = middlewaresAndHandler.pop();
23
+ const middlewares = middlewaresAndHandler as Middleware[];
24
+
25
+ this.routes.push({
26
+ method,
27
+ path,
28
+ compiled,
29
+ middlewares,
30
+ handler,
31
+ });
32
+ }
33
+
34
+ /**
35
+ * Trouve la route et extrait les params
36
+ */
37
+ match(method: string, urlPath: string) {
38
+ const urlSegments = urlPath.replace(/^\//, "").split("/");
39
+
40
+ for (const route of this.routes) {
41
+ if (route.method !== method) continue;
42
+
43
+ const params: Record<string, string> = {};
44
+ const compiled = route.compiled;
45
+
46
+ if (this.matchSegments(compiled, urlSegments, params)) {
47
+ return {
48
+ handler: route.handler,
49
+ middlewares: route.middlewares,
50
+ params,
51
+ };
52
+ }
53
+ }
54
+
55
+ return null;
56
+ }
57
+
58
+ /**
59
+ * Ton moteur de matching existant — inchangé
60
+ */
61
+ private matchSegments(
62
+ compiled: any[],
63
+ urlSegments: string[],
64
+ params: Record<string, string>,
65
+ ) {
66
+ let i = 0;
67
+
68
+ for (let j = 0; j < compiled.length; j++) {
69
+ const segment = compiled[j];
70
+ const part = urlSegments[i];
71
+
72
+ if (!part && segment.type !== "wildcard") {
73
+ return false;
74
+ }
75
+
76
+ if (segment.type === "static") {
77
+ if (segment.value !== part) return false;
78
+ i++;
79
+ continue;
80
+ }
81
+
82
+ if (segment.type === "param") {
83
+ if (!part) return false;
84
+ params[segment.name] = part;
85
+ i++;
86
+ continue;
87
+ }
88
+
89
+ if (segment.type === "wildcard") {
90
+ if (!part) return false;
91
+
92
+ const next = compiled[j + 1];
93
+ if (!next) return true;
94
+
95
+ while (i < urlSegments.length) {
96
+ if (next.type === "static" && urlSegments[i] === next.value) {
97
+ break;
98
+ }
99
+ i++;
100
+ }
101
+
102
+ if (i >= urlSegments.length) return false;
103
+
104
+ continue;
105
+ }
106
+ }
107
+
108
+ return i === urlSegments.length;
109
+ }
110
+
111
+ get(path: string, ...middlewaresAndHandler: any[]) {
112
+ this.register("GET", path, ...middlewaresAndHandler);
113
+ }
114
+
115
+ post(path: string, ...middlewaresAndHandler: any[]) {
116
+ this.register("POST", path, ...middlewaresAndHandler);
117
+ }
118
+
119
+ put(path: string, ...middlewaresAndHandler: any[]) {
120
+ this.register("PUT", path, ...middlewaresAndHandler);
121
+ }
122
+
123
+ delete(path: string, ...middlewaresAndHandler: any[]) {
124
+ this.register("DELETE", path, ...middlewaresAndHandler);
125
+ }
126
+
127
+ patch(path: string, ...middlewaresAndHandler: any[]) {
128
+ this.register("PATCH", path, ...middlewaresAndHandler);
129
+ }
130
+
131
+ options(path: string, ...middlewaresAndHandler: any[]) {
132
+ this.register("OPTIONS", path, ...middlewaresAndHandler);
133
+ }
134
+
135
+ head(path: string, ...middlewaresAndHandler: any[]) {
136
+ this.register("HEAD", path, ...middlewaresAndHandler);
137
+ }
138
+ }
@@ -1,8 +1,8 @@
1
- import crypto from "crypto";
2
-
3
- export class IdGenerator {
4
- static generate(): string {
5
- // Token long, alphanumérique, très difficile à deviner
6
- return crypto.randomBytes(16).toString("hex");
7
- }
8
- }
1
+ import crypto from "crypto";
2
+
3
+ export class IdGenerator {
4
+ static generate(): string {
5
+ // Token long, alphanumérique, très difficile à deviner
6
+ return crypto.randomBytes(16).toString("hex");
7
+ }
8
+ }
@@ -1,113 +1,113 @@
1
- export type LogLevel = "debug" | "info" | "warn" | "error" | "fatal";
2
-
3
- export interface LoggerOptions {
4
- level?: LogLevel;
5
- context?: string;
6
- enabled?: boolean;
7
- hooks?: Array<(entry: LogEntry) => void>;
8
- }
9
-
10
- export interface LogEntry {
11
- timestamp: string;
12
- level: LogLevel;
13
- message: string;
14
- context?: string;
15
- data?: any;
16
- }
17
-
18
- const COLORS = {
19
- reset: "\x1b[0m",
20
- gray: "\x1b[90m",
21
- blue: "\x1b[34m",
22
- yellow: "\x1b[33m",
23
- red: "\x1b[31m",
24
- magenta: "\x1b[35m",
25
- };
26
-
27
- const LEVEL_COLORS: Record<LogLevel, string> = {
28
- debug: COLORS.gray,
29
- info: COLORS.blue,
30
- warn: COLORS.yellow,
31
- error: COLORS.red,
32
- fatal: COLORS.magenta,
33
- };
34
-
35
- const LEVEL_ORDER: Record<LogLevel, number> = {
36
- debug: 10,
37
- info: 20,
38
- warn: 30,
39
- error: 40,
40
- fatal: 50,
41
- };
42
-
43
- export class Logger {
44
- private level: LogLevel;
45
- private context?: string;
46
- private enabled: boolean;
47
- private hooks: Array<(entry: LogEntry) => void>;
48
-
49
- constructor(options: LoggerOptions = {}) {
50
- this.level = options.level ?? "info";
51
- this.context = options.context;
52
- this.enabled = options.enabled ?? true;
53
- this.hooks = options.hooks ?? [];
54
- }
55
-
56
- private shouldLog(level: LogLevel): boolean {
57
- return this.enabled && LEVEL_ORDER[level] >= LEVEL_ORDER[this.level];
58
- }
59
-
60
- private emit(level: LogLevel, message: string, data?: any) {
61
- if (!this.shouldLog(level)) return;
62
-
63
- const entry: LogEntry = {
64
- timestamp: new Date().toISOString(),
65
- level,
66
- message,
67
- context: this.context,
68
- data,
69
- };
70
-
71
- // Console output
72
- const color = LEVEL_COLORS[level];
73
- const ctx = this.context ? `[${this.context}] ` : "";
74
- const formatted = `${color}${entry.timestamp} ${level.toUpperCase()} ${ctx}${message}${COLORS.reset}`;
75
-
76
- console.log(formatted);
77
-
78
- // Hooks (dashboard, file, webhook…)
79
- for (const hook of this.hooks) {
80
- hook(entry);
81
- }
82
- }
83
-
84
- debug(msg: string, data?: any) {
85
- this.emit("debug", msg, data);
86
- }
87
-
88
- info(msg: string, data?: any) {
89
- this.emit("info", msg, data);
90
- }
91
-
92
- warn(msg: string, data?: any) {
93
- this.emit("warn", msg, data);
94
- }
95
-
96
- error(msg: string, data?: any) {
97
- this.emit("error", msg, data);
98
- }
99
-
100
- fatal(msg: string, data?: any) {
101
- this.emit("fatal", msg, data);
102
- }
103
-
104
- // Créer un logger enfant avec un contexte différent
105
- withContext(context: string): Logger {
106
- return new Logger({
107
- level: this.level,
108
- enabled: this.enabled,
109
- hooks: this.hooks,
110
- context,
111
- });
112
- }
113
- }
1
+ export type LogLevel = "debug" | "info" | "warn" | "error" | "fatal";
2
+
3
+ export interface LoggerOptions {
4
+ level?: LogLevel;
5
+ context?: string;
6
+ enabled?: boolean;
7
+ hooks?: Array<(entry: LogEntry) => void>;
8
+ }
9
+
10
+ export interface LogEntry {
11
+ timestamp: string;
12
+ level: LogLevel;
13
+ message: string;
14
+ context?: string;
15
+ data?: any;
16
+ }
17
+
18
+ const COLORS = {
19
+ reset: "\x1b[0m",
20
+ gray: "\x1b[90m",
21
+ blue: "\x1b[34m",
22
+ yellow: "\x1b[33m",
23
+ red: "\x1b[31m",
24
+ magenta: "\x1b[35m",
25
+ };
26
+
27
+ const LEVEL_COLORS: Record<LogLevel, string> = {
28
+ debug: COLORS.gray,
29
+ info: COLORS.blue,
30
+ warn: COLORS.yellow,
31
+ error: COLORS.red,
32
+ fatal: COLORS.magenta,
33
+ };
34
+
35
+ const LEVEL_ORDER: Record<LogLevel, number> = {
36
+ debug: 10,
37
+ info: 20,
38
+ warn: 30,
39
+ error: 40,
40
+ fatal: 50,
41
+ };
42
+
43
+ export class Logger {
44
+ private level: LogLevel;
45
+ private context?: string;
46
+ private enabled: boolean;
47
+ private hooks: Array<(entry: LogEntry) => void>;
48
+
49
+ constructor(options: LoggerOptions = {}) {
50
+ this.level = options.level ?? "info";
51
+ this.context = options.context;
52
+ this.enabled = options.enabled ?? true;
53
+ this.hooks = options.hooks ?? [];
54
+ }
55
+
56
+ private shouldLog(level: LogLevel): boolean {
57
+ return this.enabled && LEVEL_ORDER[level] >= LEVEL_ORDER[this.level];
58
+ }
59
+
60
+ private emit(level: LogLevel, message: string, data?: any) {
61
+ if (!this.shouldLog(level)) return;
62
+
63
+ const entry: LogEntry = {
64
+ timestamp: new Date().toISOString(),
65
+ level,
66
+ message,
67
+ context: this.context,
68
+ data,
69
+ };
70
+
71
+ // Console output
72
+ const color = LEVEL_COLORS[level];
73
+ const ctx = this.context ? `[${this.context}] ` : "";
74
+ const formatted = `${color}${entry.timestamp} ${level.toUpperCase()} ${ctx}${message}${COLORS.reset}`;
75
+
76
+ console.log(formatted);
77
+
78
+ // Hooks (dashboard, file, webhook…)
79
+ for (const hook of this.hooks) {
80
+ hook(entry);
81
+ }
82
+ }
83
+
84
+ debug(msg: string, data?: any) {
85
+ this.emit("debug", msg, data);
86
+ }
87
+
88
+ info(msg: string, data?: any) {
89
+ this.emit("info", msg, data);
90
+ }
91
+
92
+ warn(msg: string, data?: any) {
93
+ this.emit("warn", msg, data);
94
+ }
95
+
96
+ error(msg: string, data?: any) {
97
+ this.emit("error", msg, data);
98
+ }
99
+
100
+ fatal(msg: string, data?: any) {
101
+ this.emit("fatal", msg, data);
102
+ }
103
+
104
+ // Créer un logger enfant avec un contexte différent
105
+ withContext(context: string): Logger {
106
+ return new Logger({
107
+ level: this.level,
108
+ enabled: this.enabled,
109
+ hooks: this.hooks,
110
+ context,
111
+ });
112
+ }
113
+ }
@@ -1,44 +1,44 @@
1
- import { Storage } from "../storage-adapters/storage.interface";
2
- import { Logger } from "./logger";
3
- import { AnyNormalizedEvent } from "../types/event.types";
4
-
5
- export type RouterHook = (event: AnyNormalizedEvent) => void | Promise<void>;
6
-
7
- export interface RouterOptions {
8
- logger?: Logger;
9
- hooks?: RouterHook[];
10
- }
11
-
12
- export class CoreRouter {
13
- private logger: Logger;
14
- private hooks: RouterHook[];
15
-
16
- constructor(
17
- private storage: Storage,
18
- options: RouterOptions = {},
19
- ) {
20
- this.logger = options.logger ?? new Logger({ context: "CoreRouter" });
21
- this.hooks = options.hooks ?? [];
22
- }
23
-
24
- async dispatch(event: AnyNormalizedEvent): Promise<void> {
25
- // 1. Log
26
- this.logger.info(`Event received (${event.type})`, { id: event.id });
27
-
28
- // 2. Save
29
- await this.storage.save(event);
30
-
31
- // 3. Hooks
32
- for (const hook of this.hooks) {
33
- try {
34
- await hook(event);
35
- } catch (err) {
36
- this.logger.error("Hook error", err);
37
- }
38
- }
39
- }
40
-
41
- addHook(hook: RouterHook) {
42
- this.hooks.push(hook);
43
- }
44
- }
1
+ import { Storage } from "../storage-adapters/storage.interface";
2
+ import { Logger } from "./logger";
3
+ import { AnyNormalizedEvent } from "../types/event.types";
4
+
5
+ export type RouterHook = (event: AnyNormalizedEvent) => void | Promise<void>;
6
+
7
+ export interface RouterOptions {
8
+ logger?: Logger;
9
+ hooks?: RouterHook[];
10
+ }
11
+
12
+ export class CoreRouter {
13
+ private logger: Logger;
14
+ private hooks: RouterHook[];
15
+
16
+ constructor(
17
+ private storage: Storage,
18
+ options: RouterOptions = {},
19
+ ) {
20
+ this.logger = options.logger ?? new Logger({ context: "CoreRouter" });
21
+ this.hooks = options.hooks ?? [];
22
+ }
23
+
24
+ async dispatch(event: AnyNormalizedEvent): Promise<void> {
25
+ // 1. Log
26
+ this.logger.info(`Event received (${event.type})`, { id: event.id });
27
+
28
+ // 2. Save
29
+ await this.storage.save(event);
30
+
31
+ // 3. Hooks
32
+ for (const hook of this.hooks) {
33
+ try {
34
+ await hook(event);
35
+ } catch (err) {
36
+ this.logger.error("Hook error", err);
37
+ }
38
+ }
39
+ }
40
+
41
+ addHook(hook: RouterHook) {
42
+ this.hooks.push(hook);
43
+ }
44
+ }