@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,160 +1,160 @@
1
- // src/http/middleware.ts
2
-
3
- import { Request } from "./request";
4
- import { Response } from "./response";
5
-
6
- export type Middleware = (
7
- req: Request,
8
- res: Response,
9
- next: () => Promise<void>,
10
- ) => Promise<void> | void;
11
-
12
- export class MiddlewarePipeline {
13
- private middlewares: Middleware[] = [];
14
-
15
- use(mw: Middleware): this {
16
- this.middlewares.push(mw);
17
- return this;
18
- }
19
-
20
- async run(req: Request, res: Response): Promise<void> {
21
- let index = -1;
22
-
23
- const next = async (): Promise<void> => {
24
- index++;
25
-
26
- if (index >= this.middlewares.length) return;
27
-
28
- const mw = this.middlewares[index];
29
-
30
- await Promise.resolve(mw(req, res, next));
31
- };
32
-
33
- await next();
34
- }
35
- }
36
-
37
- /* ---------------------------------------------------------
38
- JSON PARSER
39
- --------------------------------------------------------- */
40
- export async function bodyParserJson(req: Request, res: Response) {
41
- const raw = req.raw;
42
- const contentType = raw.headers["content-type"] ?? "";
43
-
44
- if (!contentType.includes("application/json")) {
45
- return;
46
- }
47
-
48
- const chunks: Buffer[] = [];
49
- for await (const chunk of raw) chunks.push(chunk);
50
-
51
- const text = Buffer.concat(chunks).toString("utf8");
52
-
53
- try {
54
- req.body = text.length > 0 ? JSON.parse(text) : {};
55
- } catch {
56
- res.status(400).json({ error: "Invalid JSON" });
57
- }
58
- }
59
-
60
- /* ---------------------------------------------------------
61
- RAW PARSER
62
- --------------------------------------------------------- */
63
- export async function bodyParserRaw(req: Request, res: Response) {
64
- const raw = req.raw;
65
- const contentType = raw.headers["content-type"] ?? "";
66
-
67
- if (contentType.includes("application/json")) return;
68
-
69
- const chunks: Buffer[] = [];
70
- for await (const chunk of raw) chunks.push(chunk);
71
-
72
- req.bodyRaw = Buffer.concat(chunks);
73
- }
74
-
75
- /* ---------------------------------------------------------
76
- TEXT PARSER
77
- --------------------------------------------------------- */
78
- export async function bodyParserText(req: Request, res: Response) {
79
- const raw = req.raw;
80
- const contentType = raw.headers["content-type"] ?? "";
81
-
82
- const isText =
83
- contentType.startsWith("text/") ||
84
- contentType.includes("application/xml") ||
85
- contentType.includes("application/xhtml+xml");
86
-
87
- if (!isText) return;
88
-
89
- const chunks: Buffer[] = [];
90
- for await (const chunk of raw) chunks.push(chunk);
91
-
92
- req.bodyText = Buffer.concat(chunks).toString("utf8");
93
- }
94
-
95
- /* ---------------------------------------------------------
96
- MULTIPART PARSER
97
- --------------------------------------------------------- */
98
- export async function bodyParserMultipart(req: Request, res: Response) {
99
- const raw = req.raw;
100
- const contentType = raw.headers["content-type"] ?? "";
101
-
102
- if (!contentType.startsWith("multipart/form-data")) return;
103
-
104
- const boundaryMatch = contentType.match(/boundary=(.+)$/);
105
- if (!boundaryMatch) {
106
- res.status(400).json({ error: "Missing multipart boundary" });
107
- return;
108
- }
109
-
110
- const boundary = "--" + boundaryMatch[1];
111
-
112
- const chunks: Buffer[] = [];
113
- for await (const chunk of raw) chunks.push(chunk);
114
-
115
- const buffer = Buffer.concat(chunks);
116
- const parts = buffer.toString("binary").split(boundary);
117
-
118
- req.files = [];
119
- req.form = {};
120
-
121
- for (const part of parts) {
122
- if (part === "--\r\n" || part === "" || part === "\r\n") continue;
123
-
124
- const [rawHeaders, rawBody] = part.split("\r\n\r\n");
125
- if (!rawBody) continue;
126
-
127
- // Nettoyage du body brut
128
- const cleaned = rawBody.replace(/\r\n--$/, "");
129
- const body = Buffer.from(cleaned, "binary");
130
-
131
- const disposition = rawHeaders.match(/name="([^"]+)"/);
132
- if (!disposition) continue;
133
-
134
- const fieldname = disposition[1];
135
- const filenameMatch = rawHeaders.match(/filename="([^"]+)"/);
136
-
137
- if (filenameMatch) {
138
- // ----------- FICHIER -----------
139
- const filename = filenameMatch[1];
140
- const contentTypeMatch = rawHeaders.match(/Content-Type: (.+)/);
141
-
142
- req.files.push({
143
- fieldname,
144
- filename,
145
- contentType: contentTypeMatch
146
- ? contentTypeMatch[1]
147
- : "application/octet-stream",
148
-
149
- // 🔥 Correction : retirer le \r\n final
150
- data: Buffer.from(
151
- body.toString("binary").replace(/\r\n$/, ""),
152
- "binary",
153
- ),
154
- });
155
- } else {
156
- // ----------- CHAMP TEXTE -----------
157
- req.form[fieldname] = body.toString("utf8").replace(/\r\n$/, ""); // 🔥 Correction champ texte
158
- }
159
- }
160
- }
1
+ // src/http/middleware.ts
2
+
3
+ import { Request } from "./request";
4
+ import { Response } from "./response";
5
+
6
+ export type Middleware = (
7
+ req: Request,
8
+ res: Response,
9
+ next: () => Promise<void>,
10
+ ) => Promise<void> | void;
11
+
12
+ export class MiddlewarePipeline {
13
+ private middlewares: Middleware[] = [];
14
+
15
+ use(mw: Middleware): this {
16
+ this.middlewares.push(mw);
17
+ return this;
18
+ }
19
+
20
+ async run(req: Request, res: Response): Promise<void> {
21
+ let index = -1;
22
+
23
+ const next = async (): Promise<void> => {
24
+ index++;
25
+
26
+ if (index >= this.middlewares.length) return;
27
+
28
+ const mw = this.middlewares[index];
29
+
30
+ await Promise.resolve(mw(req, res, next));
31
+ };
32
+
33
+ await next();
34
+ }
35
+ }
36
+
37
+ /* ---------------------------------------------------------
38
+ JSON PARSER
39
+ --------------------------------------------------------- */
40
+ export async function bodyParserJson(req: Request, res: Response) {
41
+ const raw = req.raw;
42
+ const contentType = raw.headers["content-type"] ?? "";
43
+
44
+ if (!contentType.includes("application/json")) {
45
+ return;
46
+ }
47
+
48
+ const chunks: Buffer[] = [];
49
+ for await (const chunk of raw) chunks.push(chunk);
50
+
51
+ const text = Buffer.concat(chunks).toString("utf8");
52
+
53
+ try {
54
+ req.body = text.length > 0 ? JSON.parse(text) : {};
55
+ } catch {
56
+ res.status(400).json({ error: "Invalid JSON" });
57
+ }
58
+ }
59
+
60
+ /* ---------------------------------------------------------
61
+ RAW PARSER
62
+ --------------------------------------------------------- */
63
+ export async function bodyParserRaw(req: Request, res: Response) {
64
+ const raw = req.raw;
65
+ const contentType = raw.headers["content-type"] ?? "";
66
+
67
+ if (contentType.includes("application/json")) return;
68
+
69
+ const chunks: Buffer[] = [];
70
+ for await (const chunk of raw) chunks.push(chunk);
71
+
72
+ req.bodyRaw = Buffer.concat(chunks);
73
+ }
74
+
75
+ /* ---------------------------------------------------------
76
+ TEXT PARSER
77
+ --------------------------------------------------------- */
78
+ export async function bodyParserText(req: Request, res: Response) {
79
+ const raw = req.raw;
80
+ const contentType = raw.headers["content-type"] ?? "";
81
+
82
+ const isText =
83
+ contentType.startsWith("text/") ||
84
+ contentType.includes("application/xml") ||
85
+ contentType.includes("application/xhtml+xml");
86
+
87
+ if (!isText) return;
88
+
89
+ const chunks: Buffer[] = [];
90
+ for await (const chunk of raw) chunks.push(chunk);
91
+
92
+ req.bodyText = Buffer.concat(chunks).toString("utf8");
93
+ }
94
+
95
+ /* ---------------------------------------------------------
96
+ MULTIPART PARSER
97
+ --------------------------------------------------------- */
98
+ export async function bodyParserMultipart(req: Request, res: Response) {
99
+ const raw = req.raw;
100
+ const contentType = raw.headers["content-type"] ?? "";
101
+
102
+ if (!contentType.startsWith("multipart/form-data")) return;
103
+
104
+ const boundaryMatch = contentType.match(/boundary=(.+)$/);
105
+ if (!boundaryMatch) {
106
+ res.status(400).json({ error: "Missing multipart boundary" });
107
+ return;
108
+ }
109
+
110
+ const boundary = "--" + boundaryMatch[1];
111
+
112
+ const chunks: Buffer[] = [];
113
+ for await (const chunk of raw) chunks.push(chunk);
114
+
115
+ const buffer = Buffer.concat(chunks);
116
+ const parts = buffer.toString("binary").split(boundary);
117
+
118
+ req.files = [];
119
+ req.form = {};
120
+
121
+ for (const part of parts) {
122
+ if (part === "--\r\n" || part === "" || part === "\r\n") continue;
123
+
124
+ const [rawHeaders, rawBody] = part.split("\r\n\r\n");
125
+ if (!rawBody) continue;
126
+
127
+ // Nettoyage du body brut
128
+ const cleaned = rawBody.replace(/\r\n--$/, "");
129
+ const body = Buffer.from(cleaned, "binary");
130
+
131
+ const disposition = rawHeaders.match(/name="([^"]+)"/);
132
+ if (!disposition) continue;
133
+
134
+ const fieldname = disposition[1];
135
+ const filenameMatch = rawHeaders.match(/filename="([^"]+)"/);
136
+
137
+ if (filenameMatch) {
138
+ // ----------- FICHIER -----------
139
+ const filename = filenameMatch[1];
140
+ const contentTypeMatch = rawHeaders.match(/Content-Type: (.+)/);
141
+
142
+ req.files.push({
143
+ fieldname,
144
+ filename,
145
+ contentType: contentTypeMatch
146
+ ? contentTypeMatch[1]
147
+ : "application/octet-stream",
148
+
149
+ // 🔥 Correction : retirer le \r\n final
150
+ data: Buffer.from(
151
+ body.toString("binary").replace(/\r\n$/, ""),
152
+ "binary",
153
+ ),
154
+ });
155
+ } else {
156
+ // ----------- CHAMP TEXTE -----------
157
+ req.form[fieldname] = body.toString("utf8").replace(/\r\n$/, ""); // 🔥 Correction champ texte
158
+ }
159
+ }
160
+ }
@@ -1,55 +1,55 @@
1
- // src/http/request.ts
2
-
3
- export interface RequestContext {
4
- // espace réservé pour les middlewares
5
- [key: string]: any;
6
- }
7
-
8
- export class Request {
9
- readonly method: string;
10
- readonly path: string;
11
- readonly headers: Record<string, string>;
12
- readonly query: Record<string, string | string[]>;
13
- readonly params: Record<string, string>;
14
- body: any;
15
- bodyRaw?: Buffer;
16
- bodyText?: string;
17
- files?: Array<{
18
- fieldname: string;
19
- filename: string;
20
- contentType: string;
21
- data: Buffer;
22
- }>;
23
- form?: Record<string, string>;
24
-
25
- readonly ip: string;
26
- readonly raw: any; // Node IncomingMessage ou autre selon l'adaptateur
27
- readonly context: RequestContext;
28
-
29
- constructor(options: {
30
- method: string;
31
- path: string;
32
- headers: Record<string, string>;
33
- query?: Record<string, string | string[]>;
34
- params?: Record<string, string>;
35
- body?: any;
36
- ip?: string;
37
- raw?: any;
38
- context?: RequestContext;
39
- }) {
40
- this.method = options.method;
41
- this.path = options.path;
42
- this.headers = options.headers;
43
- this.query = options.query ?? {};
44
- this.params = options.params ?? {};
45
- this.body = options.body ?? null;
46
- this.ip = options.ip ?? "";
47
- this.raw = options.raw ?? null;
48
- this.context = options.context ?? {};
49
- }
50
-
51
- // Exemple d'utilitaire PRO
52
- header(name: string): string | undefined {
53
- return this.headers[name.toLowerCase()];
54
- }
55
- }
1
+ // src/http/request.ts
2
+
3
+ export interface RequestContext {
4
+ // espace réservé pour les middlewares
5
+ [key: string]: any;
6
+ }
7
+
8
+ export class Request {
9
+ readonly method: string;
10
+ readonly path: string;
11
+ readonly headers: Record<string, string>;
12
+ readonly query: Record<string, string | string[]>;
13
+ readonly params: Record<string, string>;
14
+ body: any;
15
+ bodyRaw?: Buffer;
16
+ bodyText?: string;
17
+ files?: Array<{
18
+ fieldname: string;
19
+ filename: string;
20
+ contentType: string;
21
+ data: Buffer;
22
+ }>;
23
+ form?: Record<string, string>;
24
+
25
+ readonly ip: string;
26
+ readonly raw: any; // Node IncomingMessage ou autre selon l'adaptateur
27
+ readonly context: RequestContext;
28
+
29
+ constructor(options: {
30
+ method: string;
31
+ path: string;
32
+ headers: Record<string, string>;
33
+ query?: Record<string, string | string[]>;
34
+ params?: Record<string, string>;
35
+ body?: any;
36
+ ip?: string;
37
+ raw?: any;
38
+ context?: RequestContext;
39
+ }) {
40
+ this.method = options.method;
41
+ this.path = options.path;
42
+ this.headers = options.headers;
43
+ this.query = options.query ?? {};
44
+ this.params = options.params ?? {};
45
+ this.body = options.body ?? null;
46
+ this.ip = options.ip ?? "";
47
+ this.raw = options.raw ?? null;
48
+ this.context = options.context ?? {};
49
+ }
50
+
51
+ // Exemple d'utilitaire PRO
52
+ header(name: string): string | undefined {
53
+ return this.headers[name.toLowerCase()];
54
+ }
55
+ }
@@ -1,93 +1,93 @@
1
- // src/http/response.ts
2
-
3
- export class Response {
4
- private _status = 200;
5
- private _headers: Record<string, string> = {};
6
- private _sent = false;
7
- private _raw: any; // Node ServerResponse ou autre selon l'adaptateur
8
-
9
- constructor(raw: any) {
10
- this._raw = raw;
11
- }
12
-
13
- status(code: number): this {
14
- this._status = code;
15
- return this;
16
- }
17
-
18
- header(name: string, value: string): this {
19
- this._headers[name.toLowerCase()] = value;
20
- return this;
21
- }
22
-
23
- json(data: any): void {
24
- this.ensureNotSent();
25
- this.header("content-type", "application/json");
26
- this.send(JSON.stringify(data));
27
- }
28
-
29
- text(data: string): void {
30
- this.ensureNotSent();
31
- this.header("content-type", "text/plain");
32
- this.send(data);
33
- }
34
-
35
- send(data: any): void {
36
- this.ensureNotSent();
37
-
38
- for (const [name, value] of Object.entries(this._headers)) {
39
- this._raw.setHeader(name, value);
40
- }
41
-
42
- this._raw.statusCode = this._status;
43
- this._raw.end(data);
44
-
45
- this._sent = true;
46
- }
47
-
48
- stream(readable: NodeJS.ReadableStream): void {
49
- this.ensureNotSent();
50
-
51
- for (const [name, value] of Object.entries(this._headers)) {
52
- this._raw.setHeader(name, value);
53
- }
54
-
55
- this._raw.statusCode = this._status;
56
- readable.pipe(this._raw);
57
-
58
- this._sent = true;
59
- }
60
-
61
- sse(): void {
62
- this.ensureNotSent();
63
-
64
- this.header("content-type", "text/event-stream");
65
- this.header("cache-control", "no-cache");
66
- this.header("connection", "keep-alive");
67
-
68
- for (const [name, value] of Object.entries(this._headers)) {
69
- this._raw.setHeader(name, value);
70
- }
71
-
72
- this._raw.flushHeaders?.();
73
-
74
- this._sent = false; // SSE reste ouvert
75
- }
76
-
77
- write(data: string): void {
78
- this._raw.write(data);
79
- }
80
-
81
- end(): void {
82
- if (!this._sent) {
83
- this._raw.end();
84
- this._sent = true;
85
- }
86
- }
87
-
88
- private ensureNotSent() {
89
- if (this._sent) {
90
- throw new Error("Response already sent");
91
- }
92
- }
93
- }
1
+ // src/http/response.ts
2
+
3
+ export class Response {
4
+ private _status = 200;
5
+ private _headers: Record<string, string> = {};
6
+ private _sent = false;
7
+ private _raw: any; // Node ServerResponse ou autre selon l'adaptateur
8
+
9
+ constructor(raw: any) {
10
+ this._raw = raw;
11
+ }
12
+
13
+ status(code: number): this {
14
+ this._status = code;
15
+ return this;
16
+ }
17
+
18
+ header(name: string, value: string): this {
19
+ this._headers[name.toLowerCase()] = value;
20
+ return this;
21
+ }
22
+
23
+ json(data: any): void {
24
+ this.ensureNotSent();
25
+ this.header("content-type", "application/json");
26
+ this.send(JSON.stringify(data));
27
+ }
28
+
29
+ text(data: string): void {
30
+ this.ensureNotSent();
31
+ this.header("content-type", "text/plain");
32
+ this.send(data);
33
+ }
34
+
35
+ send(data: any): void {
36
+ this.ensureNotSent();
37
+
38
+ for (const [name, value] of Object.entries(this._headers)) {
39
+ this._raw.setHeader(name, value);
40
+ }
41
+
42
+ this._raw.statusCode = this._status;
43
+ this._raw.end(data);
44
+
45
+ this._sent = true;
46
+ }
47
+
48
+ stream(readable: NodeJS.ReadableStream): void {
49
+ this.ensureNotSent();
50
+
51
+ for (const [name, value] of Object.entries(this._headers)) {
52
+ this._raw.setHeader(name, value);
53
+ }
54
+
55
+ this._raw.statusCode = this._status;
56
+ readable.pipe(this._raw);
57
+
58
+ this._sent = true;
59
+ }
60
+
61
+ sse(): void {
62
+ this.ensureNotSent();
63
+
64
+ this.header("content-type", "text/event-stream");
65
+ this.header("cache-control", "no-cache");
66
+ this.header("connection", "keep-alive");
67
+
68
+ for (const [name, value] of Object.entries(this._headers)) {
69
+ this._raw.setHeader(name, value);
70
+ }
71
+
72
+ this._raw.flushHeaders?.();
73
+
74
+ this._sent = false; // SSE reste ouvert
75
+ }
76
+
77
+ write(data: string): void {
78
+ this._raw.write(data);
79
+ }
80
+
81
+ end(): void {
82
+ if (!this._sent) {
83
+ this._raw.end();
84
+ this._sent = true;
85
+ }
86
+ }
87
+
88
+ private ensureNotSent() {
89
+ if (this._sent) {
90
+ throw new Error("Response already sent");
91
+ }
92
+ }
93
+ }