@j3r3mcdev/oast-server 1.0.0 → 1.1.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 (187) 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/config/constants.d.ts +0 -0
  19. package/dist/config/env.d.ts +0 -0
  20. package/dist/core/__tests__/core-router.test.d.ts +1 -0
  21. package/dist/core/__tests__/core-server.test.d.ts +1 -0
  22. package/dist/core/__tests__/event.normalizer.test.d.ts +1 -0
  23. package/dist/core/__tests__/event.router.test.d.ts +1 -0
  24. package/dist/core/__tests__/logger.test.d.ts +1 -0
  25. package/dist/core/__tests__/storage-manager.test.d.ts +1 -0
  26. package/dist/core/event.normalizer.d.ts +10 -0
  27. package/dist/core/event.router.d.ts +7 -0
  28. package/dist/core/http/__tests__/adapter-node.test.d.ts +1 -0
  29. package/dist/core/http/__tests__/body-parser-multipart.test.d.ts +1 -0
  30. package/dist/core/http/__tests__/body-parser-raw.test.d.ts +1 -0
  31. package/dist/core/http/__tests__/body-parser-text.test.d.ts +1 -0
  32. package/dist/core/http/__tests__/compile-path.test.d.ts +1 -0
  33. package/dist/core/http/__tests__/middleware-pipeline.test.d.ts +1 -0
  34. package/dist/core/http/__tests__/request.test.d.ts +1 -0
  35. package/dist/core/http/__tests__/response.test.d.ts +1 -0
  36. package/dist/core/http/__tests__/router-match.test.d.ts +1 -0
  37. package/dist/core/http/adapter-node.d.ts +8 -0
  38. package/dist/core/http/buildRequest.d.ts +2 -0
  39. package/dist/core/http/compile-path.d.ts +13 -0
  40. package/dist/core/http/errors.d.ts +9 -0
  41. package/dist/core/http/http-server.d.ts +7 -0
  42. package/dist/core/http/index.d.ts +0 -0
  43. package/dist/core/http/main.d.ts +0 -0
  44. package/dist/core/http/middleware.d.ts +12 -0
  45. package/dist/core/http/request.d.ts +35 -0
  46. package/dist/core/http/response.d.ts +17 -0
  47. package/dist/core/http/router.d.ts +28 -0
  48. package/dist/core/http/utils.d.ts +0 -0
  49. package/dist/core/id-generator.d.ts +3 -0
  50. package/dist/core/logger.d.ts +29 -0
  51. package/dist/core/router.d.ts +16 -0
  52. package/dist/core/server.d.ts +25 -0
  53. package/dist/core/storage.d.ts +24 -0
  54. package/dist/index.d.ts +1 -0
  55. package/dist/listeners/api/__tests__/api.controller.test.d.ts +1 -0
  56. package/dist/listeners/api/__tests__/api.extractor.test.d.ts +1 -0
  57. package/dist/listeners/api/__tests__/api.listener.test.d.ts +1 -0
  58. package/dist/listeners/api/__tests__/api.routes.test.d.ts +1 -0
  59. package/dist/listeners/api/__tests__/api.sse.test.d.ts +1 -0
  60. package/dist/listeners/api/api.controllers.d.ts +9 -0
  61. package/dist/listeners/api/api.extractor.d.ts +5 -0
  62. package/dist/listeners/api/api.listener.d.ts +17 -0
  63. package/dist/listeners/api/api.routes.d.ts +5 -0
  64. package/dist/listeners/api/api.sse.d.ts +10 -0
  65. package/dist/listeners/dns/__tests__/dns.test.d.ts +1 -0
  66. package/dist/listeners/dns/dns.extractor.d.ts +8 -0
  67. package/dist/listeners/dns/dns.listener.d.ts +15 -0
  68. package/dist/listeners/http/__tests__/http.extractor.test.d.ts +1 -0
  69. package/dist/listeners/http/__tests__/http.listener.test.d.ts +1 -0
  70. package/dist/listeners/http/http.extractor.d.ts +11 -0
  71. package/dist/listeners/http/http.listener.d.ts +17 -0
  72. package/dist/listeners/listener.interface.d.ts +4 -0
  73. package/dist/listeners/smtp/__tests__/smtp.extractor.test.d.ts +1 -0
  74. package/dist/listeners/smtp/__tests__/smtp.listener.test.d.ts +1 -0
  75. package/dist/listeners/smtp/smtp.extractor.d.ts +12 -0
  76. package/dist/listeners/smtp/smtp.listener.d.ts +13 -0
  77. package/dist/listeners/ssrf/__tests__/ssrf.extractor.test.d.ts +1 -0
  78. package/dist/listeners/ssrf/__tests__/ssrf.listener.test.d.ts +1 -0
  79. package/dist/listeners/ssrf/__tests__/ssrf.listener.test.js +4 -16
  80. package/dist/listeners/ssrf/ssrf.extractor.d.ts +10 -0
  81. package/dist/listeners/ssrf/ssrf.listener.d.ts +8 -0
  82. package/dist/listeners/tcp/tcp.extractor.d.ts +4 -0
  83. package/dist/listeners/tcp/tcp.listener.d.ts +18 -0
  84. package/dist/listeners/webhook/__tests__/webhook.extractor.test.d.ts +1 -0
  85. package/dist/listeners/webhook/__tests__/webhook.listener.test.d.ts +1 -0
  86. package/dist/listeners/webhook/webhook.extractor.d.ts +8 -0
  87. package/dist/listeners/webhook/webhook.listener.d.ts +8 -0
  88. package/dist/listeners/websocket/__tests__/websocket.extractor.test.d.ts +1 -0
  89. package/dist/listeners/websocket/__tests__/websocket.listener.test.d.ts +1 -0
  90. package/dist/listeners/websocket/websocket.extractor.d.ts +10 -0
  91. package/dist/listeners/websocket/websocket.listener.d.ts +8 -0
  92. package/dist/storage-adapters/adapters/__tests__/memory.storage.test.d.ts +1 -0
  93. package/dist/storage-adapters/adapters/memory.storage.d.ts +21 -0
  94. package/dist/storage-adapters/adapters/redis.storage.d.ts +0 -0
  95. package/dist/storage-adapters/adapters/sqlite.storage.d.ts +0 -0
  96. package/dist/storage-adapters/storage.interface.d.ts +18 -0
  97. package/dist/types/event.types.d.ts +118 -0
  98. package/dist/utils/token.d.ts +0 -0
  99. package/jest.config.js +14 -11
  100. package/package.json +45 -45
  101. package/sadmin list shadows +9 -9
  102. package/src/api/controllers/__tests__/tasks.controller.test.ts +74 -74
  103. package/src/api/controllers/events.controller.ts +10 -10
  104. package/src/api/controllers/health.controller.ts +7 -7
  105. package/src/api/controllers/tasks.controller.ts +41 -41
  106. package/src/api/dto/__tests__/create-task.dto.test.ts +41 -41
  107. package/src/api/dto/__tests__/filter-tasks.dto.test.ts +35 -35
  108. package/src/api/dto/create-task.dto.ts +33 -33
  109. package/src/api/dto/filter-tasks.dto.ts +33 -33
  110. package/src/api/services/__tests__/events.service.test.ts +41 -41
  111. package/src/api/services/__tests__/tasks.service.test.ts +41 -41
  112. package/src/api/services/events.service.ts +17 -17
  113. package/src/api/services/tasks.service.ts +79 -79
  114. package/src/api/sse/events.stream.ts +90 -90
  115. package/src/core/__tests__/core-router.test.ts +30 -30
  116. package/src/core/__tests__/core-server.test.ts +44 -44
  117. package/src/core/__tests__/event.normalizer.test.ts +56 -56
  118. package/src/core/__tests__/event.router.test.ts +89 -89
  119. package/src/core/__tests__/logger.test.ts +32 -32
  120. package/src/core/__tests__/storage-manager.test.ts +74 -74
  121. package/src/core/event.normalizer.ts +147 -147
  122. package/src/core/event.router.ts +13 -13
  123. package/src/core/http/__tests__/adapter-node.test.ts +52 -52
  124. package/src/core/http/__tests__/body-parser-multipart.test.ts +41 -41
  125. package/src/core/http/__tests__/body-parser-raw.test.ts +28 -28
  126. package/src/core/http/__tests__/body-parser-text.test.ts +28 -28
  127. package/src/core/http/__tests__/compile-path.test.ts +39 -39
  128. package/src/core/http/__tests__/middleware-pipeline.test.ts +51 -51
  129. package/src/core/http/__tests__/request.test.ts +34 -34
  130. package/src/core/http/__tests__/response.test.ts +35 -35
  131. package/src/core/http/__tests__/router-match.test.ts +171 -171
  132. package/src/core/http/adapter-node.ts +51 -51
  133. package/src/core/http/buildRequest.ts +18 -18
  134. package/src/core/http/compile-path.ts +32 -32
  135. package/src/core/http/errors.ts +37 -37
  136. package/src/core/http/http-server.ts +52 -52
  137. package/src/core/http/middleware.ts +160 -160
  138. package/src/core/http/request.ts +55 -55
  139. package/src/core/http/response.ts +93 -93
  140. package/src/core/http/router.ts +138 -138
  141. package/src/core/id-generator.ts +8 -8
  142. package/src/core/logger.ts +113 -113
  143. package/src/core/router.ts +44 -44
  144. package/src/core/server.ts +85 -85
  145. package/src/core/storage.ts +64 -64
  146. package/src/index.ts +89 -89
  147. package/src/listeners/api/__tests__/api.controller.test.ts +116 -116
  148. package/src/listeners/api/__tests__/api.extractor.test.ts +46 -46
  149. package/src/listeners/api/__tests__/api.listener.test.ts +82 -82
  150. package/src/listeners/api/__tests__/api.routes.test.ts +155 -155
  151. package/src/listeners/api/__tests__/api.sse.test.ts +105 -105
  152. package/src/listeners/api/api.controllers.ts +67 -67
  153. package/src/listeners/api/api.extractor.ts +43 -43
  154. package/src/listeners/api/api.listener.ts +50 -50
  155. package/src/listeners/api/api.routes.ts +76 -76
  156. package/src/listeners/api/api.sse.ts +38 -38
  157. package/src/listeners/dns/__tests__/dns.test.ts +118 -118
  158. package/src/listeners/dns/dns.extractor.ts +14 -14
  159. package/src/listeners/dns/dns.listener.ts +61 -61
  160. package/src/listeners/http/__tests__/http.extractor.test.ts +59 -59
  161. package/src/listeners/http/__tests__/http.listener.test.ts +133 -133
  162. package/src/listeners/http/http.extractor.ts +15 -15
  163. package/src/listeners/http/http.listener.ts +110 -110
  164. package/src/listeners/listener.interface.ts +4 -4
  165. package/src/listeners/smtp/__tests__/smtp.extractor.test.ts +69 -69
  166. package/src/listeners/smtp/__tests__/smtp.listener.test.ts +150 -150
  167. package/src/listeners/smtp/smtp.extractor.ts +18 -18
  168. package/src/listeners/smtp/smtp.listener.ts +60 -60
  169. package/src/listeners/ssrf/__tests__/ssrf.extractor.test.ts +41 -41
  170. package/src/listeners/ssrf/__tests__/ssrf.listener.test.ts +87 -98
  171. package/src/listeners/ssrf/ssrf.extractor.ts +14 -14
  172. package/src/listeners/ssrf/ssrf.listener.ts +37 -37
  173. package/src/listeners/tcp/tcp.extractor.ts +16 -16
  174. package/src/listeners/tcp/tcp.listener.ts +61 -61
  175. package/src/listeners/webhook/__tests__/webhook.extractor.test.ts +35 -35
  176. package/src/listeners/webhook/__tests__/webhook.listener.test.ts +122 -122
  177. package/src/listeners/webhook/webhook.extractor.ts +12 -12
  178. package/src/listeners/webhook/webhook.listener.ts +58 -58
  179. package/src/listeners/websocket/__tests__/websocket.extractor.test.ts +33 -33
  180. package/src/listeners/websocket/__tests__/websocket.listener.test.ts +90 -90
  181. package/src/listeners/websocket/websocket.extractor.ts +11 -11
  182. package/src/listeners/websocket/websocket.listener.ts +40 -40
  183. package/src/storage-adapters/adapters/__tests__/memory.storage.test.ts +75 -75
  184. package/src/storage-adapters/adapters/memory.storage.ts +64 -64
  185. package/src/storage-adapters/storage.interface.ts +26 -26
  186. package/src/types/event.types.ts +147 -147
  187. package/tsconfig.json +21 -15
@@ -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
+ }
@@ -1,85 +1,85 @@
1
- import { Logger } from "./logger";
2
- import { CoreRouter } from "./router";
3
- import { StorageManager } from "./storage";
4
- import { Listener } from "../listeners/listener.interface";
5
- export interface CoreServerOptions {
6
- logger?: Logger;
7
- storage?: StorageManager;
8
- listeners?: Listener[];
9
- }
10
-
11
- export class CoreServer {
12
- private logger: Logger;
13
- private storage: StorageManager;
14
- private router: CoreRouter;
15
- private listeners: Listener[];
16
-
17
- constructor(options: CoreServerOptions = {}) {
18
- this.logger = options.logger ?? new Logger({ context: "CoreServer" });
19
- this.storage =
20
- options.storage ?? new StorageManager({ logger: this.logger });
21
- this.router = new CoreRouter(this.storage, { logger: this.logger });
22
- this.listeners = options.listeners ?? [];
23
- }
24
-
25
- getRouter() {
26
- return this.router;
27
- }
28
-
29
- getStorage() {
30
- return this.storage;
31
- }
32
-
33
- async start(): Promise<void> {
34
- this.logger.info("Starting OAST server...");
35
-
36
- // Démarrage des listeners
37
- for (const listener of this.listeners) {
38
- try {
39
- await listener.start();
40
- this.logger.info(`Listener started`, {
41
- listener: listener.constructor.name,
42
- });
43
- } catch (err: any) {
44
- this.logger.error("Listener failed to start", {
45
- listener: listener.constructor.name,
46
- error: err.message,
47
- });
48
- }
49
- }
50
-
51
- this.logger.info("OAST server started");
52
- }
53
-
54
- async stop(): Promise<void> {
55
- this.logger.info("Stopping OAST server...");
56
-
57
- for (const listener of this.listeners) {
58
- try {
59
- await listener.stop();
60
- this.logger.info(`Listener stopped`, {
61
- listener: listener.constructor.name,
62
- });
63
- } catch (err: any) {
64
- this.logger.error("Listener failed to stop", {
65
- listener: listener.constructor.name,
66
- error: err.message,
67
- });
68
- }
69
- }
70
-
71
- this.logger.info("OAST server stopped");
72
- }
73
-
74
- /**
75
- * Méthode appelée par CoreRouter après chaque event normalisé.
76
- * Permet de diffuser l’event aux listeners SSE (ApiListener).
77
- */
78
- broadcast(event: any) {
79
- for (const listener of this.listeners) {
80
- if (typeof (listener as any).broadcastEvent === "function") {
81
- (listener as any).broadcastEvent(event);
82
- }
83
- }
84
- }
85
- }
1
+ import { Logger } from "./logger";
2
+ import { CoreRouter } from "./router";
3
+ import { StorageManager } from "./storage";
4
+ import { Listener } from "../listeners/listener.interface";
5
+ export interface CoreServerOptions {
6
+ logger?: Logger;
7
+ storage?: StorageManager;
8
+ listeners?: Listener[];
9
+ }
10
+
11
+ export class CoreServer {
12
+ private logger: Logger;
13
+ private storage: StorageManager;
14
+ private router: CoreRouter;
15
+ private listeners: Listener[];
16
+
17
+ constructor(options: CoreServerOptions = {}) {
18
+ this.logger = options.logger ?? new Logger({ context: "CoreServer" });
19
+ this.storage =
20
+ options.storage ?? new StorageManager({ logger: this.logger });
21
+ this.router = new CoreRouter(this.storage, { logger: this.logger });
22
+ this.listeners = options.listeners ?? [];
23
+ }
24
+
25
+ getRouter() {
26
+ return this.router;
27
+ }
28
+
29
+ getStorage() {
30
+ return this.storage;
31
+ }
32
+
33
+ async start(): Promise<void> {
34
+ this.logger.info("Starting OAST server...");
35
+
36
+ // Démarrage des listeners
37
+ for (const listener of this.listeners) {
38
+ try {
39
+ await listener.start();
40
+ this.logger.info(`Listener started`, {
41
+ listener: listener.constructor.name,
42
+ });
43
+ } catch (err: any) {
44
+ this.logger.error("Listener failed to start", {
45
+ listener: listener.constructor.name,
46
+ error: err.message,
47
+ });
48
+ }
49
+ }
50
+
51
+ this.logger.info("OAST server started");
52
+ }
53
+
54
+ async stop(): Promise<void> {
55
+ this.logger.info("Stopping OAST server...");
56
+
57
+ for (const listener of this.listeners) {
58
+ try {
59
+ await listener.stop();
60
+ this.logger.info(`Listener stopped`, {
61
+ listener: listener.constructor.name,
62
+ });
63
+ } catch (err: any) {
64
+ this.logger.error("Listener failed to stop", {
65
+ listener: listener.constructor.name,
66
+ error: err.message,
67
+ });
68
+ }
69
+ }
70
+
71
+ this.logger.info("OAST server stopped");
72
+ }
73
+
74
+ /**
75
+ * Méthode appelée par CoreRouter après chaque event normalisé.
76
+ * Permet de diffuser l’event aux listeners SSE (ApiListener).
77
+ */
78
+ broadcast(event: any) {
79
+ for (const listener of this.listeners) {
80
+ if (typeof (listener as any).broadcastEvent === "function") {
81
+ (listener as any).broadcastEvent(event);
82
+ }
83
+ }
84
+ }
85
+ }
@@ -1,64 +1,64 @@
1
- import { Storage } from "../storage-adapters/storage.interface";
2
- import { AnyNormalizedEvent } from "../types/event.types";
3
- import { Logger } from "./logger";
4
-
5
- export class StorageManager implements Storage {
6
- private events: AnyNormalizedEvent[] = [];
7
- private logger: Logger;
8
-
9
- constructor(options: { logger?: Logger } = {}) {
10
- this.logger = options.logger ?? new Logger({ context: "StorageManager" });
11
- }
12
-
13
- async save(event: AnyNormalizedEvent): Promise<void> {
14
- this.events.push(event);
15
- }
16
-
17
- async getEvent(id: string): Promise<AnyNormalizedEvent | null> {
18
- return this.events.find((e) => e.id === id) ?? null;
19
- }
20
-
21
- async listEvents(params: {
22
- type?: string;
23
- page?: number;
24
- limit?: number;
25
- }): Promise<AnyNormalizedEvent[]> {
26
- const { type, page = 1, limit = 50 } = params;
27
-
28
- let filtered = this.events;
29
- if (type) filtered = filtered.filter((e) => e.type === type);
30
-
31
- const start = (page - 1) * limit;
32
- return filtered.slice(start, start + limit);
33
- }
34
-
35
- async getAll(): Promise<AnyNormalizedEvent[]> {
36
- return this.events;
37
- }
38
-
39
- async deleteEvent(id: string): Promise<boolean> {
40
- const before = this.events.length;
41
- this.events = this.events.filter((e) => e.id !== id);
42
- return this.events.length !== before;
43
- }
44
-
45
- async clearEvents(): Promise<void> {
46
- this.events = [];
47
- }
48
-
49
- async getStats(): Promise<{
50
- total: number;
51
- byType: Record<string, number>;
52
- }> {
53
- const byType: Record<string, number> = {};
54
-
55
- for (const e of this.events) {
56
- byType[e.type] = (byType[e.type] ?? 0) + 1;
57
- }
58
-
59
- return {
60
- total: this.events.length,
61
- byType,
62
- };
63
- }
64
- }
1
+ import { Storage } from "../storage-adapters/storage.interface";
2
+ import { AnyNormalizedEvent } from "../types/event.types";
3
+ import { Logger } from "./logger";
4
+
5
+ export class StorageManager implements Storage {
6
+ private events: AnyNormalizedEvent[] = [];
7
+ private logger: Logger;
8
+
9
+ constructor(options: { logger?: Logger } = {}) {
10
+ this.logger = options.logger ?? new Logger({ context: "StorageManager" });
11
+ }
12
+
13
+ async save(event: AnyNormalizedEvent): Promise<void> {
14
+ this.events.push(event);
15
+ }
16
+
17
+ async getEvent(id: string): Promise<AnyNormalizedEvent | null> {
18
+ return this.events.find((e) => e.id === id) ?? null;
19
+ }
20
+
21
+ async listEvents(params: {
22
+ type?: string;
23
+ page?: number;
24
+ limit?: number;
25
+ }): Promise<AnyNormalizedEvent[]> {
26
+ const { type, page = 1, limit = 50 } = params;
27
+
28
+ let filtered = this.events;
29
+ if (type) filtered = filtered.filter((e) => e.type === type);
30
+
31
+ const start = (page - 1) * limit;
32
+ return filtered.slice(start, start + limit);
33
+ }
34
+
35
+ async getAll(): Promise<AnyNormalizedEvent[]> {
36
+ return this.events;
37
+ }
38
+
39
+ async deleteEvent(id: string): Promise<boolean> {
40
+ const before = this.events.length;
41
+ this.events = this.events.filter((e) => e.id !== id);
42
+ return this.events.length !== before;
43
+ }
44
+
45
+ async clearEvents(): Promise<void> {
46
+ this.events = [];
47
+ }
48
+
49
+ async getStats(): Promise<{
50
+ total: number;
51
+ byType: Record<string, number>;
52
+ }> {
53
+ const byType: Record<string, number> = {};
54
+
55
+ for (const e of this.events) {
56
+ byType[e.type] = (byType[e.type] ?? 0) + 1;
57
+ }
58
+
59
+ return {
60
+ total: this.events.length,
61
+ byType,
62
+ };
63
+ }
64
+ }