@nodefony/http 10.0.0-alpha.9 → 10.0.0-beta.1
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.
- package/README.md +7 -0
- package/dist/index.js +4 -2
- package/dist/nodefony/command/assetsPublishCommand.js +1 -1
- package/dist/nodefony/command/certificatesCommand.js +1 -1
- package/dist/nodefony/command/networkCommand.js +1 -1
- package/dist/nodefony/command/proxyGenerateCommand.js +1 -1
- package/dist/nodefony/config/config.js +22 -1
- package/dist/nodefony/interfaces/IRouting.js +1 -0
- package/dist/nodefony/interfaces/ISecurity.js +1 -0
- package/dist/nodefony/service/ProfilerAdminApi.js +2 -1
- package/dist/nodefony/service/audit-logger.js +16 -13
- package/dist/nodefony/service/certificates.js +25 -13
- package/dist/nodefony/service/error-renderer.js +11 -8
- package/dist/nodefony/service/http-kernel.js +340 -163
- package/dist/nodefony/service/pretty-request-logger.js +3 -10
- package/dist/nodefony/service/servers/clientError.js +2 -2
- package/dist/nodefony/service/servers/server-http.js +20 -20
- package/dist/nodefony/service/servers/server-https.js +38 -39
- package/dist/nodefony/service/servers/server-static.js +13 -17
- package/dist/nodefony/service/servers/server-websocket-secure.js +8 -7
- package/dist/nodefony/service/servers/server-websocket.js +8 -7
- package/dist/nodefony/service/servers/wsHeartbeat.js +2 -2
- package/dist/nodefony/service/sessions/sessions-service.js +19 -12
- package/dist/nodefony/service/trace.js +1 -1
- package/dist/nodefony/service/upload/upload-service.js +8 -7
- package/dist/nodefony/src/assets/prebuiltUi.js +1 -1
- package/dist/nodefony/src/context/Context.js +34 -19
- package/dist/nodefony/src/context/forwarded.js +4 -4
- package/dist/nodefony/src/context/http/HttpContext.js +133 -88
- package/dist/nodefony/src/context/http/Request.js +93 -44
- package/dist/nodefony/src/context/http/Response.js +107 -51
- package/dist/nodefony/src/context/http/parser.js +9 -10
- package/dist/nodefony/src/context/http/urlFastPath.js +1 -2
- package/dist/nodefony/src/context/http2/Response.js +53 -25
- package/dist/nodefony/src/context/metaData.js +1 -1
- package/dist/nodefony/src/context/trustProxy.js +4 -3
- package/dist/nodefony/src/context/websocket/Response.js +13 -6
- package/dist/nodefony/src/context/websocket/WebsocketContext.js +59 -26
- package/dist/nodefony/src/context/websocket/wsCloseReason.js +41 -0
- package/dist/nodefony/src/cookies/cookie.js +3 -3
- package/dist/nodefony/src/errors/httpError.js +6 -6
- package/dist/nodefony/src/errors/thrownMessage.js +27 -0
- package/dist/nodefony/src/profiler/FrameProfile.js +4 -3
- package/dist/nodefony/src/profiler/Profiler.js +4 -4
- package/dist/nodefony/src/servers/kernelServers.js +29 -0
- package/dist/nodefony/src/servers/portBinder.js +8 -21
- package/dist/nodefony/src/session/session.js +18 -10
- package/dist/nodefony/src/session/sessionStoreFailure.js +2 -1
- package/dist/nodefony/src/session/storage/RevocationGuardStorage.js +24 -9
- package/dist/types/index.d.ts +16 -0
- package/dist/types/nodefony/config/config.d.ts +22 -0
- package/dist/types/nodefony/interfaces/IContext.d.ts +24 -7
- package/dist/types/nodefony/interfaces/ICookie.d.ts +18 -18
- package/dist/types/nodefony/interfaces/IHttpKernel.d.ts +10 -4
- package/dist/types/nodefony/interfaces/IResponse.d.ts +1 -1
- package/dist/types/nodefony/interfaces/IRouting.d.ts +87 -0
- package/dist/types/nodefony/interfaces/ISecurity.d.ts +45 -0
- package/dist/types/nodefony/interfaces/ISession.d.ts +8 -8
- package/dist/types/nodefony/interfaces/IUpload.d.ts +9 -9
- package/dist/types/nodefony/interfaces/index.d.ts +2 -0
- package/dist/types/nodefony/service/audit-logger.d.ts +14 -10
- package/dist/types/nodefony/service/certificates.d.ts +10 -10
- package/dist/types/nodefony/service/http-kernel.d.ts +192 -42
- package/dist/types/nodefony/service/servers/server-http.d.ts +4 -1
- package/dist/types/nodefony/service/servers/server-https.d.ts +4 -1
- package/dist/types/nodefony/service/servers/server-websocket-secure.d.ts +4 -1
- package/dist/types/nodefony/service/servers/server-websocket.d.ts +4 -1
- package/dist/types/nodefony/service/sessions/sessions-service.d.ts +6 -2
- package/dist/types/nodefony/service/upload/upload-service.d.ts +1 -1
- package/dist/types/nodefony/src/context/Context.d.ts +21 -10
- package/dist/types/nodefony/src/context/forwarded.d.ts +3 -3
- package/dist/types/nodefony/src/context/http/HttpContext.d.ts +75 -18
- package/dist/types/nodefony/src/context/http/Request.d.ts +39 -2
- package/dist/types/nodefony/src/context/http/Response.d.ts +47 -7
- package/dist/types/nodefony/src/context/http/parser.d.ts +1 -1
- package/dist/types/nodefony/src/context/http2/Response.d.ts +32 -2
- package/dist/types/nodefony/src/context/websocket/Response.d.ts +4 -4
- package/dist/types/nodefony/src/context/websocket/WebsocketContext.d.ts +11 -2
- package/dist/types/nodefony/src/context/websocket/wsCloseReason.d.ts +21 -0
- package/dist/types/nodefony/src/cookies/cookie.d.ts +9 -9
- package/dist/types/nodefony/src/errors/httpError.d.ts +7 -7
- package/dist/types/nodefony/src/errors/thrownMessage.d.ts +12 -0
- package/dist/types/nodefony/src/profiler/Profiler.d.ts +28 -28
- package/dist/types/nodefony/src/servers/kernelServers.d.ts +20 -0
- package/dist/types/nodefony/src/servers/portBinder.d.ts +6 -19
- package/dist/types/nodefony/src/session/session.d.ts +12 -12
- package/dist/types/nodefony/src/session/storage/RevocationGuardStorage.d.ts +1 -1
- package/docs/cookies.md +20 -20
- package/docs/observabilite.md +25 -25
- package/docs/rate-limit.md +18 -18
- package/docs/servers.md +52 -52
- package/docs/session.md +65 -60
- package/docs/upload.md +36 -30
- package/package.json +7 -7
package/docs/upload.md
CHANGED
|
@@ -62,10 +62,10 @@ flowchart TD
|
|
|
62
62
|
|
|
63
63
|
Trois idées portent tout le reste :
|
|
64
64
|
|
|
65
|
-
1. **Le `Content-Type` décide, pas la méthode.** `parseRequest()` (`context/http/Request.ts:
|
|
65
|
+
1. **Le `Content-Type` décide, pas la méthode.** `parseRequest()` (`context/http/Request.ts:451`)
|
|
66
66
|
aiguille vers `ParserJson` / `ParserQs` / `ParserXml` / **busboy** / parser brut selon l'en-tête.
|
|
67
67
|
2. **Seul le multipart écrit sur disque.** Les fichiers sont **streamés** au fil de l'eau vers un
|
|
68
|
-
fichier temporaire (`parseMultipart()`, `context/http/Request.ts:
|
|
68
|
+
fichier temporaire (`parseMultipart()`, `context/http/Request.ts:523`) — jamais bufferisés en RAM.
|
|
69
69
|
JSON / urlencoded / XML restent en mémoire (petits corps).
|
|
70
70
|
3. **Deux budgets distincts, jamais confondus.** Le corps **non-multipart** est borné par `maxBodySize`
|
|
71
71
|
(défaut **1 MiB**) ; le multipart a **ses propres** limites busboy (`maxFileSize`, `maxTotalFileSize`,
|
|
@@ -117,11 +117,11 @@ Trois choix structurent l'implémentation, et chacun a une raison de sécurité
|
|
|
117
117
|
|
|
118
118
|
**Le multipart ne touche jamais la RAM.** Là où l'ancien chemin bufferisait le corps entier, busboy lit
|
|
119
119
|
le flux et écrit chaque fichier au fil de l'eau dans le dossier temporaire (`streamMultipart()`,
|
|
120
|
-
`context/http/Request.ts:
|
|
120
|
+
`context/http/Request.ts:564`). Un upload de 1 Go ne coûte donc pas 1 Go de heap — seuls les petits
|
|
121
121
|
champs texte restent en mémoire. C'est ce qui rend un endpoint d'upload public tenable.
|
|
122
122
|
|
|
123
123
|
**Le nom du fichier temporaire n'est jamais celui du client.** Chaque fichier reçu est écrit sous un nom
|
|
124
|
-
`randomUUID()` + extension d'origine (`context/http/Request.ts:
|
|
124
|
+
`randomUUID()` + extension d'origine (`context/http/Request.ts:627`) : un nom malveillant
|
|
125
125
|
(`../../etc/passwd`) ne peut pas influencer le **chemin** d'écriture. Le nom d'origine est conservé en
|
|
126
126
|
**métadonnée** (`filename`), pas dans le chemin.
|
|
127
127
|
|
|
@@ -257,14 +257,14 @@ sequenceDiagram
|
|
|
257
257
|
Les points d'implémentation qui expliquent des comportements surprenants :
|
|
258
258
|
|
|
259
259
|
1. **L'aiguillage lit le `Content-Type`, pas la méthode** — `parseRequest()`
|
|
260
|
-
(`context/http/Request.ts:
|
|
261
|
-
des méthodes parsées (`context/http/Request.ts:
|
|
260
|
+
(`context/http/Request.ts:451`). `PATCH` porte un corps comme `POST`/`PUT` : il figure dans la table
|
|
261
|
+
des méthodes parsées (`context/http/Request.ts:94`) — l'oubli laissait tout `PATCH` avec un corps vide.
|
|
262
262
|
2. **Le multipart draine sur un `finish`, après flush de tous les writes** — `streamMultipart()`
|
|
263
|
-
(`context/http/Request.ts:
|
|
264
|
-
qu'une fois tous les fichiers fermés (`context/http/Request.ts:
|
|
263
|
+
(`context/http/Request.ts:564`) accumule les `Promise` d'écriture disque et ne résout `{ fields, files }`
|
|
264
|
+
qu'une fois tous les fichiers fermés (`bb.on("finish")`, `context/http/Request.ts:707`).
|
|
265
265
|
3. **Une limite dépassée nettoie les temporaires déjà posés** — `abort()`
|
|
266
|
-
(`context/http/Request.ts:
|
|
267
|
-
déjà écrits (`context/http/Request.ts:
|
|
266
|
+
(`context/http/Request.ts:584`) délie le flux, détruit les write-streams ouverts et `unlink` les temp
|
|
267
|
+
déjà écrits (`context/http/Request.ts:601`) avant de rejeter en `413` : pas d'orphelins sur le disque.
|
|
268
268
|
4. **Les autres formats drainent AVANT de concaténer** — la base `Parser.parse()` attend `end`
|
|
269
269
|
(`context/http/parser.ts:111`) avant `Buffer.concat` : sans ce drain, `ParserQs`/`ParserXml`
|
|
270
270
|
lisaient un corps partiel → `queryPost` vide (bug de régression, cf tests).
|
|
@@ -283,11 +283,17 @@ non-multipart n'écoute pas `upload.*`.
|
|
|
283
283
|
| `maxBodySize` | octets | `1_048_576` (1 MiB) | Plafond d'un corps **JSON / urlencoded / XML / brut** → `413`. `0` = illimité. |
|
|
284
284
|
|
|
285
285
|
Deux rideaux, tous deux `runtimeMutable` (éditable à chaud) : un **pré-check** sur `Content-Length`
|
|
286
|
-
qui rejette **avant** de lire (`enforceBodyLimit()`, `context/http/Request.ts:
|
|
286
|
+
qui rejette **avant** de lire (`enforceBodyLimit()`, `context/http/Request.ts:428`), puis un **compteur
|
|
287
287
|
en streaming** qui coupe le socket si le corps déborde sans `Content-Length` honnête — chunked ou
|
|
288
288
|
menteur (`Parser.write()`, `context/http/parser.ts:33`, dépassement `context/http/parser.ts:33`).
|
|
289
289
|
Champ `maxBodySize` du schéma : `config/config.ts:1026`.
|
|
290
290
|
|
|
291
|
+
**Par requête** : `maxBodySize` et les limites `upload.*` (hors `uploadDir`) sont sur la liste blanche
|
|
292
|
+
du calque de configuration — une application peut les changer pour une requête
|
|
293
|
+
(`overlayConfig("@nodefony/http", { maxBodySize: … })`, posé dans un écouteur `onRequestScope`). Ils
|
|
294
|
+
sont lus au moment de lire le corps (`Request.readBodyLimits()`), donc un calque posé après ce moment
|
|
295
|
+
(au pare-feu, dans un contrôleur) n'agit pas. Détail : [configuration](../../../../../docs/guides/configuration.md).
|
|
296
|
+
|
|
291
297
|
### Fichiers multipart — `upload.*`
|
|
292
298
|
|
|
293
299
|
Table dérivée de `uploadSchema` (`config/config.ts:159`). Toutes les bornes sont `runtimeMutable`.
|
|
@@ -316,16 +322,16 @@ recommandé) et les **getters** de `Controller` (impératif). Les signatures exa
|
|
|
316
322
|
|
|
317
323
|
| Accès | Source lue | Ancrage |
|
|
318
324
|
| -------------------------------------------------- | ------------------------------------ | ------------------------------------------------------------------- |
|
|
319
|
-
| `@UploadedFiles() f: IUploadedFile[]` | tous les fichiers (`queryFile`) | `resolveParamArg` `"files"` (`routerDecorators.ts:
|
|
320
|
-
| `@UploadedFile() f: IUploadedFile` | le **premier** fichier | `resolveParamArg` `"file"` (`routerDecorators.ts:
|
|
321
|
-
| `@Body() body` | tous les champs parsés (`queryPost`) | `resolveParamArg` `"body"` (`routerDecorators.ts:
|
|
325
|
+
| `@UploadedFiles() f: IUploadedFile[]` | tous les fichiers (`queryFile`) | `resolveParamArg` `"files"` (`routerDecorators.ts:1283`) |
|
|
326
|
+
| `@UploadedFile() f: IUploadedFile` | le **premier** fichier | `resolveParamArg` `"file"` (`routerDecorators.ts:1282`) |
|
|
327
|
+
| `@Body() body` | tous les champs parsés (`queryPost`) | `resolveParamArg` `"body"` (`routerDecorators.ts:1232`) |
|
|
322
328
|
| `@Body("label") v` | un seul champ du body | même source, clé (`routerDecorators.ts:1223`) |
|
|
323
|
-
| `@Body({ stream: true }) s: NodeJS.ReadableStream` | le **flux brut**, parse **sauté** | `resolveParamArg` stream (`routerDecorators.ts:
|
|
324
|
-
| `this.queryFile` | équivalent getter des fichiers | `Controller.queryFile` (`framework/nodefony/src/Controller.ts:
|
|
325
|
-
| `this.queryPost` | équivalent getter des champs | `Controller.queryPost` (`framework/nodefony/src/Controller.ts:
|
|
329
|
+
| `@Body({ stream: true }) s: NodeJS.ReadableStream` | le **flux brut**, parse **sauté** | `resolveParamArg` stream (`routerDecorators.ts:1326`) |
|
|
330
|
+
| `this.queryFile` | équivalent getter des fichiers | `Controller.queryFile` (`framework/nodefony/src/Controller.ts:341`) |
|
|
331
|
+
| `this.queryPost` | équivalent getter des champs | `Controller.queryPost` (`framework/nodefony/src/Controller.ts:351`) |
|
|
326
332
|
|
|
327
333
|
Les décorateurs `@UploadedFile` / `@UploadedFiles` sont des fabriques de paramètre
|
|
328
|
-
(`routerDecorators.ts:
|
|
334
|
+
(`routerDecorators.ts:1287`), exportées par `@nodefony/framework` ; leurs interfaces `IUploadedFile` /
|
|
329
335
|
`IParsedUploadFile` viennent de `@nodefony/http` (`interfaces/IUpload.ts:49`, `interfaces/IUpload.ts:7`).
|
|
330
336
|
|
|
331
337
|
### Un fichier uploadé — `UploadedFile`
|
|
@@ -340,8 +346,8 @@ sur disque. Ses membres utiles :
|
|
|
340
346
|
| `prettySize` | Taille lisible (`« 1.2 MB »`). | `getPrettySize()` (`service/upload/upload-service.ts:143`) |
|
|
341
347
|
| `mimeType` | Type MIME déclaré (`image/png`…), sinon deviné de l'extension. | `getMimeType()` (`service/upload/upload-service.ts:153`) |
|
|
342
348
|
| `hash` / `hashAlgorithm` | Empreinte d'intégrité si `upload.hashAlgorithm` est réglé. | `interfaces/IUpload.ts:55` |
|
|
343
|
-
| `moveAsync(target)` | Déplace le temp — **non bloquant, recommandé** dans le pipeline. | `moveAsync()` (`service/upload/upload-service.ts:
|
|
344
|
-
| `move(target)` | Variante **synchrone** (compat) — bloque l'event-loop. | `move()` (`service/upload/upload-service.ts:
|
|
349
|
+
| `moveAsync(target)` | Déplace le temp — **non bloquant, recommandé** dans le pipeline. | `moveAsync()` (`service/upload/upload-service.ts:218`) |
|
|
350
|
+
| `move(target)` | Variante **synchrone** (compat) — bloque l'event-loop. | `move()` (`service/upload/upload-service.ts:186`) |
|
|
345
351
|
|
|
346
352
|
`move`/`moveAsync` acceptent un **fichier cible** ou un **dossier existant** : sur un dossier, la
|
|
347
353
|
destination est bâtie avec `filename` — d'où l'avertissement de sécurité ci-dessous.
|
|
@@ -351,7 +357,7 @@ destination est bâtie avec `filename` — d'où l'avertissement de sécurité c
|
|
|
351
357
|
Pour piper directement un très gros corps (vidéo, backup) vers le disque ou S3 sans passer par busboy ni
|
|
352
358
|
par la RAM, `@Body({ stream: true })` court-circuite le parse et injecte l'`IncomingMessage` brut (un
|
|
353
359
|
`Readable`). Le pipeline sait le sauter en amont via `routeExpectsBodyStream()`
|
|
354
|
-
(`routerDecorators.ts:
|
|
360
|
+
(`routerDecorators.ts:1408`), mémoïsé sur la route.
|
|
355
361
|
|
|
356
362
|
```ts
|
|
357
363
|
// fragment — le contrôleur pipe le flux lui-même (0 parse, 0 pic RAM)
|
|
@@ -370,10 +376,10 @@ piégé. Les défenses en place, et **ce qui reste à ta charge**.
|
|
|
370
376
|
<!-- prettier-ignore -->
|
|
371
377
|
| Menace | Défense côté framework | À ta charge |
|
|
372
378
|
| --- | --- | --- |
|
|
373
|
-
| **Path traversal** (chemin d'écriture) | Le temp est nommé `randomUUID()` + extension — jamais le nom client (`context/http/Request.ts:
|
|
379
|
+
| **Path traversal** (chemin d'écriture) | Le temp est nommé `randomUUID()` + extension — jamais le nom client (`context/http/Request.ts:627`). | La **destination** de `move()` (voir avertissement). |
|
|
374
380
|
| **Saturation RAM** | Multipart streamé (jamais bufferisé) ; corps non-multipart borné (`maxBodySize`). | Resserrer `maxBodySize` selon l'endpoint. |
|
|
375
|
-
| **Saturation disque** | `maxFileSize` + `maxTotalFileSize` + `maxFiles` ; `abort()` nettoie les temp à l'abandon (`context/http/Request.ts:
|
|
376
|
-
| **DoS par quantité** | `maxFields` / `maxFiles` / `parts` → `413` (`context/http/Request.ts:
|
|
381
|
+
| **Saturation disque** | `maxFileSize` + `maxTotalFileSize` + `maxFiles` ; `abort()` nettoie les temp à l'abandon (`context/http/Request.ts:584`). | Purger les temp non déplacés (TTL / cron). |
|
|
382
|
+
| **DoS par quantité** | `maxFields` / `maxFiles` / `parts` → `413` (`context/http/Request.ts:754`). | — |
|
|
377
383
|
| **Type de fichier hostile** | `mimeType` **déclaré** est exposé tel quel. | Valider le type/contenu réel (le MIME client est déclaratif). |
|
|
378
384
|
|
|
379
385
|
> [!WARNING]
|
|
@@ -406,12 +412,12 @@ pipeline : `npm run test:memory` (skill `nodefony-check-memory-health`).
|
|
|
406
412
|
|
|
407
413
|
| Domaine | Norme | Ancrage |
|
|
408
414
|
| ---------------------------------- | -------------------------------- | ------------------------------------------------------------- |
|
|
409
|
-
| Formulaire avec fichiers | RFC 7578 (`multipart/form-data`) | `parseMultipart()` via busboy (`context/http/Request.ts:
|
|
410
|
-
| Corps trop gros → 413 | RFC 9110 §15.5.14 | `enforceBodyLimit()` (`context/http/Request.ts:
|
|
415
|
+
| Formulaire avec fichiers | RFC 7578 (`multipart/form-data`) | `parseMultipart()` via busboy (`context/http/Request.ts:523`) |
|
|
416
|
+
| Corps trop gros → 413 | RFC 9110 §15.5.14 | `enforceBodyLimit()` (`context/http/Request.ts:428`) |
|
|
411
417
|
| 413 en streaming (chunked/menteur) | RFC 9110 §15.5.14 | `Parser.write()` (`context/http/parser.ts:33`) |
|
|
412
418
|
| Bornes multipart → 413 | RFC 9110 §15.5.14 | `stream.on("limit")` (`context/http/Request.ts:481`) |
|
|
413
|
-
| Défense path traversal (nom temp) | OWASP — File Upload | `randomUUID()` (`context/http/Request.ts:
|
|
414
|
-
| Charset du corps honoré | RFC 9110 (Content-Type) | `getCharset()` (`context/http/Request.ts:
|
|
419
|
+
| Défense path traversal (nom temp) | OWASP — File Upload | `randomUUID()` (`context/http/Request.ts:627`) |
|
|
420
|
+
| Charset du corps honoré | RFC 9110 (Content-Type) | `getCharset()` (`context/http/Request.ts:824`) |
|
|
415
421
|
|
|
416
422
|
## ⚠️ Pièges
|
|
417
423
|
|
|
@@ -423,8 +429,8 @@ pipeline : `npm run test:memory` (skill `nodefony-check-memory-health`).
|
|
|
423
429
|
| `413` sur upload sans message clair | Une borne busboy atteinte en streaming (fichier, cumul, nombre) | Vérifier les bornes `upload.*` — 413 émis sur `stream.on("limit")` (`context/http/Request.ts:481`) |
|
|
424
430
|
| Un fichier écrit `../../etc/…` après un `move` | `move(dossier)` utilise le nom **client** (`upload-service.ts:197`) | Passer une cible complète, ou `path.basename(file.filename)` |
|
|
425
431
|
| Des fichiers temporaires s'accumulent dans `uploadDir` | Le contrôleur ne déplace jamais le temp | Appeler `moveAsync()` (ou purger l'ancien temp par TTL) |
|
|
426
|
-
| `queryPost` vide sur `PATCH` | Déjà géré : `PATCH` est dans la table des méthodes parsées | Aucune — corps `PATCH` parsé comme `POST` (`context/http/Request.ts:
|
|
427
|
-
| Corps `latin1` mal décodé | Déjà géré : le `charset=` du `Content-Type` est honoré | Aucune — `getCharset()` normalise (`context/http/Request.ts:
|
|
432
|
+
| `queryPost` vide sur `PATCH` | Déjà géré : `PATCH` est dans la table des méthodes parsées | Aucune — corps `PATCH` parsé comme `POST` (`context/http/Request.ts:93`) |
|
|
433
|
+
| Corps `latin1` mal décodé | Déjà géré : le `charset=` du `Content-Type` est honoré | Aucune — `getCharset()` normalise (`context/http/Request.ts:824`) |
|
|
428
434
|
| `multipart` sans boundary fait planter | `new Busboy()` throw synchrone | Déjà géré : bascule sur le parser brut (`context/http/Request.ts:502`) |
|
|
429
435
|
|
|
430
436
|
## 🧪 Tests & couverture
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodefony/http",
|
|
3
|
-
"version": "10.0.0-
|
|
3
|
+
"version": "10.0.0-beta.1",
|
|
4
4
|
"description": "Serveurs HTTP, HTTPS, HTTP/2 et WebSocket natifs pour Nodefony : sessions, contextes de requête, certificats TLS",
|
|
5
5
|
"author": "Christophe CAMENSULI <ccamensuli@gmail.com>",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -60,31 +60,31 @@
|
|
|
60
60
|
"qs": "^6.15.3",
|
|
61
61
|
"serve-static": "2.2.1",
|
|
62
62
|
"tslib": "2.8.1",
|
|
63
|
-
"ws": "8.
|
|
63
|
+
"ws": "8.22.0",
|
|
64
64
|
"xml2js": "0.6.2"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"@types/chai": "5.2.3",
|
|
68
68
|
"@types/mime-types": "3.0.1",
|
|
69
69
|
"@types/ms": "2.1.0",
|
|
70
|
-
"@types/node": "26.6.
|
|
70
|
+
"@types/node": "26.6.3",
|
|
71
71
|
"@types/node-forge": "1.3.14",
|
|
72
72
|
"@types/qs": "6.15.1",
|
|
73
73
|
"@types/serve-static": "2.2.0",
|
|
74
74
|
"@types/websocket": "1.0.10",
|
|
75
75
|
"@types/ws": "8.18.1",
|
|
76
76
|
"@types/xml2js": "0.4.14",
|
|
77
|
-
"@vitest/coverage-v8": "5.0.
|
|
77
|
+
"@vitest/coverage-v8": "5.0.2",
|
|
78
78
|
"chai": "6.2.2",
|
|
79
|
-
"nodefony": "^10.0.0-
|
|
79
|
+
"nodefony": "^10.0.0-beta.1",
|
|
80
80
|
"tsx": "4.23.15",
|
|
81
|
-
"vitest": "5.0.
|
|
81
|
+
"vitest": "5.0.2"
|
|
82
82
|
},
|
|
83
83
|
"license": "Apache-2.0",
|
|
84
84
|
"readmeFilename": "README.md",
|
|
85
85
|
"contributors": [],
|
|
86
86
|
"peerDependencies": {
|
|
87
|
-
"nodefony": "^10.0.0-
|
|
87
|
+
"nodefony": "^10.0.0-beta.1",
|
|
88
88
|
"zod": "^4.6.5"
|
|
89
89
|
},
|
|
90
90
|
"files": [
|