@nodefony/framework 10.0.0-beta.3 → 10.0.0-beta.4
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 +4 -0
- package/dist/_virtual/{_@oxc-project_runtime@0.153.0 → _@oxc-project_runtime@0.155.0}/helpers/esm/decorate.js +1 -2
- package/dist/index.js +9 -18
- package/dist/nodefony/config/config.js +1 -2
- package/dist/nodefony/config/defineModuleConfig.js +1 -2
- package/dist/nodefony/controller/AdminApiController.js +38 -7
- package/dist/nodefony/controller/ApiKeyController.js +16 -8
- package/dist/nodefony/controller/BenchController.js +1 -2
- package/dist/nodefony/controller/IssuerMetadataController.js +1 -2
- package/dist/nodefony/controller/LoginPageController.js +4 -11
- package/dist/nodefony/controller/OAuth2Controller.js +3 -4
- package/dist/nodefony/controller/ProtectedResourceMetadataController.js +1 -2
- package/dist/nodefony/controller/SessionAuthController.js +13 -4
- package/dist/nodefony/controller/TokenAuthController.js +3 -4
- package/dist/nodefony/controller/TotpController.js +2 -3
- package/dist/nodefony/controller/WebAuthnController.js +2 -3
- package/dist/nodefony/controller/oauthAuthority.js +1 -2
- package/dist/nodefony/decorators/routerDecorators.js +155 -53
- package/dist/nodefony/service/AdminBroker.js +4 -6
- package/dist/nodefony/service/Eta.js +1 -2
- package/dist/nodefony/service/IdempotencyStore.js +4 -6
- package/dist/nodefony/service/router.js +49 -15
- package/dist/nodefony/src/Controller.js +22 -39
- package/dist/nodefony/src/FrameworkAdminApi.js +31 -10
- package/dist/nodefony/src/KernelAdminApi.js +7 -9
- package/dist/nodefony/src/PlaygroundAdminApi.js +72 -3
- package/dist/nodefony/src/RedisIdempotencyStore.js +46 -4
- package/dist/nodefony/src/Resolver.js +66 -34
- package/dist/nodefony/src/ResourceController.js +2 -3
- package/dist/nodefony/src/Route.js +2 -3
- package/dist/nodefony/src/SecurityApiController.js +1 -2
- package/dist/nodefony/src/SyslogAdminApi.js +1 -2
- package/dist/nodefony/src/Template.js +1 -2
- package/dist/nodefony/src/configMutation.js +1 -2
- package/dist/nodefony/src/docsReader.js +1 -2
- package/dist/nodefony/src/idempotency.js +1 -2
- package/dist/nodefony/src/idempotencyGc.js +1 -2
- package/dist/nodefony/src/idempotencyStoreRegistry.js +1 -2
- package/dist/nodefony/src/loginPage.js +2 -3
- package/dist/nodefony/src/requireAuthentication.js +1 -2
- package/dist/nodefony/src/routeSchema.js +81 -0
- package/dist/nodefony/src/scopeCatalog.js +1 -2
- package/dist/nodefony/src/singletonGuard.js +1 -2
- package/dist/nodefony/src/syslogFilters.js +1 -2
- package/dist/types/index.d.ts +5 -10
- package/dist/types/nodefony/controller/AdminApiController.d.ts +12 -0
- package/dist/types/nodefony/controller/SessionAuthController.d.ts +7 -0
- package/dist/types/nodefony/decorators/routerDecorators.d.ts +133 -32
- package/dist/types/nodefony/interfaces/IController.d.ts +2 -3
- package/dist/types/nodefony/service/router.d.ts +27 -1
- package/dist/types/nodefony/src/Controller.d.ts +14 -16
- package/dist/types/nodefony/src/PlaygroundAdminApi.d.ts +12 -0
- package/dist/types/nodefony/src/Resolver.d.ts +25 -1
- package/dist/types/nodefony/src/ResourceController.d.ts +1 -1
- package/dist/types/nodefony/src/Route.d.ts +3 -0
- package/dist/types/nodefony/src/loginPage.d.ts +1 -1
- package/dist/types/nodefony/src/routeSchema.d.ts +112 -0
- package/docs/admin.md +80 -80
- package/docs/controller.md +108 -109
- package/docs/decorateurs.md +208 -161
- package/docs/idempotence.md +133 -133
- package/docs/routing.md +90 -89
- package/docs/templates.md +55 -55
- package/package.json +8 -11
- package/dist/_virtual/_@oxc-project_runtime@0.153.0/helpers/esm/decorateMetadata.js +0 -6
package/docs/templates.md
CHANGED
|
@@ -44,11 +44,11 @@ flowchart LR
|
|
|
44
44
|
Deux idées à retenir :
|
|
45
45
|
|
|
46
46
|
1. **Le contrôleur lit le fichier, le moteur ne fait que rendre une chaîne.** `renderView()` résout le
|
|
47
|
-
chemin, lit l'octet, puis passe la **source** à Eta (`Controller.renderView()`, `Controller.ts
|
|
47
|
+
chemin, lit l'octet, puis passe la **source** à Eta (`Controller.renderView()`, `Controller.ts#Controller.renderView`).
|
|
48
48
|
Il n'y a **pas** de dossier `views/` magique connu du moteur.
|
|
49
49
|
2. **L'échappement est automatique.** Une donnée interpolée par `<%= %>` est neutralisée (`<` devient
|
|
50
50
|
`<`) avant d'entrer dans le HTML — c'est la protection XSS, active par défaut
|
|
51
|
-
(`autoEscape`, `Eta.ts
|
|
51
|
+
(`autoEscape`, `Eta.ts#defaultOption`).
|
|
52
52
|
|
|
53
53
|
## 📖 Lexique
|
|
54
54
|
|
|
@@ -87,24 +87,24 @@ site. C'est une faille **XSS**. La parade est l'**échappement** : on remplace `
|
|
|
87
87
|
## La vision Nodefony
|
|
88
88
|
|
|
89
89
|
Nodefony a **un seul** moteur de vues : **Eta** (il remplace Twig et EJS, retirés). Le choix est
|
|
90
|
-
documenté au source (`Eta`, `Eta.ts
|
|
90
|
+
documenté au source (`Eta`, `Eta.ts#Eta`) : écrit en TypeScript (types fournis, pas de `@types/*`), ESM
|
|
91
91
|
natif, échappement natif, et surtout des délimiteurs `<% %>` qui **n'entrent pas en collision** avec la
|
|
92
92
|
syntaxe TS/JSON/JSX — décisif car le même moteur sert aussi à générer du code (le scaffold `create`).
|
|
93
93
|
|
|
94
94
|
Le branchement est **délibérément minimal** :
|
|
95
95
|
|
|
96
96
|
- Le service Eta est enregistré au boot sous le nom `template` (`@services([Router, Eta, …])`,
|
|
97
|
-
`nodefony/framework/index.ts
|
|
98
|
-
(`this.get<Eta>("template")`, `Controller.ts
|
|
97
|
+
`nodefony/framework/index.ts`) ; chaque contrôleur le récupère à sa construction
|
|
98
|
+
(`this.get<Eta>("template")`, `Controller.ts#Controller.route`).
|
|
99
99
|
- Le moteur ne connaît **que le rendu d'une chaîne** : `Eta.render(source, data)` appelle
|
|
100
|
-
`renderStringAsync` (`Eta.ts
|
|
100
|
+
`renderStringAsync` (`Eta.ts#Eta.render`). C'est le contrôleur qui lit le fichier — pas Eta.
|
|
101
101
|
- Deux options seulement sont posées, plus le cache : `autoEscape`, `useWith`, `cache`
|
|
102
|
-
(`defaultOption`, `Eta.ts
|
|
102
|
+
(`defaultOption`, `Eta.ts#defaultOption`). Il n'y a **pas** de racine `views/`, donc **pas** de résolution
|
|
103
103
|
d'`include`/layout par nom (voir Pièges).
|
|
104
104
|
|
|
105
105
|
> [!NOTE]
|
|
106
106
|
> Le rendu **d'erreurs** ne passe **pas** par les templates : une exception devient un corps **JSON
|
|
107
|
-
> structuré** (`ErrorRenderer.renderHttp()`, `error-renderer.ts
|
|
107
|
+
> structuré** (`ErrorRenderer.renderHttp()`, `error-renderer.ts#DefaultErrorRenderer.renderHttp`), jamais une page Eta. Le moteur
|
|
108
108
|
> de vues ne sert que le HTML **que tu rends explicitement**.
|
|
109
109
|
|
|
110
110
|
## 🚀 Démarrage rapide
|
|
@@ -187,17 +187,17 @@ curl -s 'http://localhost:5151/hello/%3Cb%3Ex%3C%2Fb%3E'
|
|
|
187
187
|
> [!TIP]
|
|
188
188
|
> Tu n'as écrit **aucun** appel d'envoi (`send`, `res.end`). `renderView()` produit le corps **et**
|
|
189
189
|
> l'envoie. Pour piloter l'envoi toi-même, retourne plutôt une chaîne via `render()`
|
|
190
|
-
> (`Controller.render()`, `Controller.ts
|
|
190
|
+
> (`Controller.render()`, `Controller.ts#Controller.render`).
|
|
191
191
|
|
|
192
192
|
## 🏗️ Architecture interne — le parcours d'un `renderView()`
|
|
193
193
|
|
|
194
194
|
Deux classes, une responsabilité chacune :
|
|
195
195
|
|
|
196
|
-
- **`Template`** (`Template.ts
|
|
196
|
+
- **`Template`** (`Template.ts#Template`) — la base : elle étend `Service` (donc container + logs), garde une
|
|
197
197
|
référence au `module` et **décide du cache** selon l'environnement (`this.cache` vrai en `prod`,
|
|
198
|
-
`Template.ts
|
|
199
|
-
- **`Eta`** (`Eta.ts
|
|
200
|
-
`Eta.ts
|
|
198
|
+
`Template.ts#Template.constructor`).
|
|
199
|
+
- **`Eta`** (`Eta.ts#Eta`) — l'implémentation : elle instancie le moteur `eta` (`new EtaEngine()`,
|
|
200
|
+
`Eta.ts#Eta.constructor`), applique le cache calculé par `Template` (`this.engine.configure()`, `Eta.ts#Eta.constructor`), et
|
|
201
201
|
expose deux méthodes de rendu.
|
|
202
202
|
|
|
203
203
|
Le trajet d'un appel, étape par étape :
|
|
@@ -216,17 +216,17 @@ sequenceDiagram
|
|
|
216
216
|
C->>Ctx: setContextHtml() puis renderResponse(html)
|
|
217
217
|
```
|
|
218
218
|
|
|
219
|
-
| # | Étape | Où
|
|
220
|
-
| --- | -------------------------------------------- |
|
|
221
|
-
| 1 | Résolution + lecture async du fichier | `FileClass` dans `renderView()` (`Controller.ts
|
|
222
|
-
| 2 | Ouverture de la phase mesurée `render` | `phaseStart("render")` (`Controller.ts
|
|
223
|
-
| 3 | Injection des aides frontend dans les locals | `withFrontendLocals()` (`Controller.ts
|
|
224
|
-
| 4 | Rendu de la source par le moteur | `Eta.render()` → `renderStringAsync` (`Eta.ts
|
|
225
|
-
| 5 | `Content-Type: text/html` puis envoi | `setContextHtml()` + `renderResponse()` (`Controller.ts
|
|
219
|
+
| # | Étape | Où |
|
|
220
|
+
| --- | -------------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
221
|
+
| 1 | Résolution + lecture async du fichier | `FileClass` dans `renderView()` (`Controller.ts#Controller.renderView`) |
|
|
222
|
+
| 2 | Ouverture de la phase mesurée `render` | `phaseStart("render")` (`Controller.ts#Controller.render`) |
|
|
223
|
+
| 3 | Injection des aides frontend dans les locals | `withFrontendLocals()` (`Controller.ts#Controller.withFrontendLocals`) |
|
|
224
|
+
| 4 | Rendu de la source par le moteur | `Eta.render()` → `renderStringAsync` (`Eta.ts#Eta.render`) |
|
|
225
|
+
| 5 | `Content-Type: text/html` puis envoi | `setContextHtml()` + `renderResponse()` (`Controller.ts#Controller.renderResponse`) |
|
|
226
226
|
|
|
227
227
|
Le point notable de l'étape 3 : `withFrontendLocals()` ajoute automatiquement `frontendTags`,
|
|
228
228
|
`frontendDocument` et `asset` aux locals **si** le service `frontend` est présent — et **tes** valeurs
|
|
229
|
-
priment (spread `param` en dernier, `Controller.ts
|
|
229
|
+
priment (spread `param` en dernier, `Controller.ts#Controller.renderView`). Si le module frontend n'est pas chargé, la
|
|
230
230
|
fonction retourne les locals inchangés : zéro couplage dur.
|
|
231
231
|
|
|
232
232
|
## 🔐 Sécurité — échappement HTML et XSS
|
|
@@ -239,7 +239,7 @@ La règle Eta se lit sur les délimiteurs. Trois formes, trois comportements :
|
|
|
239
239
|
| `<%~ v %>` | interpole `v` **brut** | non | du HTML de confiance que TU produis (fragments) |
|
|
240
240
|
| `<% … %>` | exécute du code (if/for…) | n/a | logique de template (pas de sortie directe) |
|
|
241
241
|
|
|
242
|
-
L'échappement par défaut vient de l'option `autoEscape: true` posée dans `defaultOption` (`Eta.ts
|
|
242
|
+
L'échappement par défaut vient de l'option `autoEscape: true` posée dans `defaultOption` (`Eta.ts#defaultOption`).
|
|
243
243
|
Concrètement, `<%= %>` passe la valeur dans la fonction d'échappement d'Eta, qui remplace `& < > " '`
|
|
244
244
|
par leurs entités HTML. Une chaîne d'attaque comme `<script>alert(1)</script>` ressort donc en texte
|
|
245
245
|
inerte `<script>alert(1)</script>`.
|
|
@@ -255,22 +255,22 @@ Deux niveaux : ce que le **service Eta** expose, et ce que le **contrôleur** t'
|
|
|
255
255
|
|
|
256
256
|
### Le service `Eta` (nom d'injection `template`)
|
|
257
257
|
|
|
258
|
-
| Méthode | Rôle | Ancre
|
|
259
|
-
| ------------------------- | ---------------------------------------------------------- |
|
|
260
|
-
| `render(source, data?)` | Rend un template depuis une **chaîne** (chemin chaud) | `Eta.ts
|
|
261
|
-
| `renderFile(path, data?)` | Lit un fichier `.eta` **puis** le rend (usages CLI/outils) | `Eta.ts
|
|
258
|
+
| Méthode | Rôle | Ancre |
|
|
259
|
+
| ------------------------- | ---------------------------------------------------------- | ----------------------- |
|
|
260
|
+
| `render(source, data?)` | Rend un template depuis une **chaîne** (chemin chaud) | `Eta.ts#Eta.render` |
|
|
261
|
+
| `renderFile(path, data?)` | Lit un fichier `.eta` **puis** le rend (usages CLI/outils) | `Eta.ts#Eta.renderFile` |
|
|
262
262
|
|
|
263
263
|
`render()` est ce qu'appelle le contrôleur ; `renderFile()` lit lui-même le fichier
|
|
264
|
-
(`readFile` + `renderStringAsync`, `Eta.ts
|
|
264
|
+
(`readFile` + `renderStringAsync`, `Eta.ts#Eta.renderFile`) pour les usages qui partent d'un chemin (générateurs,
|
|
265
265
|
scaffold). Les deux sont **asynchrones** (I/O non bloquante).
|
|
266
266
|
|
|
267
267
|
### Les helpers du contrôleur
|
|
268
268
|
|
|
269
|
-
| Helper | Pour… | Ancre
|
|
270
|
-
| ----------------------------------- | ------------------------------------------------------- |
|
|
271
|
-
| `renderView(path, locals, status?)` | Rendre une vue `.eta` (lit le fichier + aides frontend) | `Controller.ts
|
|
272
|
-
| `render(data, encoding?, status?)` | Envoyer un corps quelconque (ex. HTML déjà prêt) | `Controller.ts
|
|
273
|
-
| `renderJson(obj, status?)` | Réponse JSON explicite (pas un template) | `Controller.ts
|
|
269
|
+
| Helper | Pour… | Ancre |
|
|
270
|
+
| ----------------------------------- | ------------------------------------------------------- | ------------------------------------- |
|
|
271
|
+
| `renderView(path, locals, status?)` | Rendre une vue `.eta` (lit le fichier + aides frontend) | `Controller.ts#Controller.render` |
|
|
272
|
+
| `render(data, encoding?, status?)` | Envoyer un corps quelconque (ex. HTML déjà prêt) | `Controller.ts#Controller.render` |
|
|
273
|
+
| `renderJson(obj, status?)` | Réponse JSON explicite (pas un template) | `Controller.ts#Controller.renderJson` |
|
|
274
274
|
|
|
275
275
|
Les signatures exactes vivent dans le graphe symbolique `.ai/symbols.json` — jamais recopiées ici.
|
|
276
276
|
|
|
@@ -278,14 +278,14 @@ Les signatures exactes vivent dans le graphe symbolique `.ai/symbols.json` — j
|
|
|
278
278
|
|
|
279
279
|
Le moteur est configuré **en dur**, pas via un bloc Zod exposé à `use()`. Trois réglages seulement :
|
|
280
280
|
|
|
281
|
-
| Réglage | Valeur Nodefony | Effet | Ancre
|
|
282
|
-
| ------------ | ----------------------------- | ------------------------------------------------------------------- |
|
|
283
|
-
| `autoEscape` | `true` | `<%= %>` échappe le HTML par défaut (anti-XSS) | `Eta.ts
|
|
284
|
-
| `useWith` | `true` | locals exposés nus (`<%= name %>`) — DX façon EJS | `Eta.ts
|
|
285
|
-
| `cache` | `true` en prod, `false` sinon | compile-once des templates en production ; recompile à chaud en dev | `Template.ts
|
|
281
|
+
| Réglage | Valeur Nodefony | Effet | Ancre |
|
|
282
|
+
| ------------ | ----------------------------- | ------------------------------------------------------------------- | ---------------------------------- |
|
|
283
|
+
| `autoEscape` | `true` | `<%= %>` échappe le HTML par défaut (anti-XSS) | `Eta.ts#defaultOption` |
|
|
284
|
+
| `useWith` | `true` | locals exposés nus (`<%= name %>`) — DX façon EJS | `Eta.ts#defaultOption` |
|
|
285
|
+
| `cache` | `true` en prod, `false` sinon | compile-once des templates en production ; recompile à chaud en dev | `Template.ts#Template.constructor` |
|
|
286
286
|
|
|
287
287
|
Le cache n'est **pas** un booléen figé : `Template` le dérive de l'environnement du kernel
|
|
288
|
-
(`environment === "prod"`, `Template.ts
|
|
288
|
+
(`environment === "prod"`, `Template.ts#Template.constructor`) puis `Eta` l'applique au moteur (`Eta.ts#Eta`). En
|
|
289
289
|
développement, un template modifié est donc pris en compte sans redémarrer.
|
|
290
290
|
|
|
291
291
|
## 🔌 HTTP et WebSocket — le même rendu
|
|
@@ -306,11 +306,11 @@ c'est le différenciateur Nodefony : une classe, deux transports, le même moteu
|
|
|
306
306
|
|
|
307
307
|
## 📜 Normes appliquées
|
|
308
308
|
|
|
309
|
-
| Domaine | Norme / référence | Comment le code s'y conforme
|
|
310
|
-
| ------------------ | ----------------------- |
|
|
311
|
-
| Neutralisation XSS | OWASP — Output Encoding | échappement HTML par défaut (`autoEscape`, `Eta.ts
|
|
312
|
-
| Type de média HTML | `text/html` | posé par `setContextHtml()` dans `renderView()` (`Controller.ts
|
|
313
|
-
| I/O non bloquante | Node.js async fs | lecture async du fichier (`readFile`, `Eta.ts
|
|
309
|
+
| Domaine | Norme / référence | Comment le code s'y conforme |
|
|
310
|
+
| ------------------ | ----------------------- | --------------------------------------------------------------------------------------- |
|
|
311
|
+
| Neutralisation XSS | OWASP — Output Encoding | échappement HTML par défaut (`autoEscape`, `Eta.ts#defaultOption`) |
|
|
312
|
+
| Type de média HTML | `text/html` | posé par `setContextHtml()` dans `renderView()` (`Controller.ts#Controller.renderView`) |
|
|
313
|
+
| I/O non bloquante | Node.js async fs | lecture async du fichier (`readFile`, `Eta.ts#Eta.renderFile`) |
|
|
314
314
|
|
|
315
315
|
## ⚡ Performance et mémoire
|
|
316
316
|
|
|
@@ -318,13 +318,13 @@ Le rendu de vue est la partie **réellement coûteuse** d'une réponse (lecture
|
|
|
318
318
|
template), et le framework l'isole pour ça :
|
|
319
319
|
|
|
320
320
|
- **Phase dédiée** : `renderView()` chronomètre le rendu sous la phase `render`
|
|
321
|
-
(`phaseStart("render")`, `Controller.ts
|
|
321
|
+
(`phaseStart("render")`, `Controller.ts#Controller.render`) — distincte de `action` et de `send`. On voit ainsi si
|
|
322
322
|
le temps part dans le moteur ou dans l'écriture réseau.
|
|
323
323
|
- **Cache en prod** : les templates sont compilés une fois (`cache` vrai en production,
|
|
324
|
-
`Template.ts
|
|
324
|
+
`Template.ts#Template.cache`) ; le coût de parsing n'est payé qu'au premier rendu.
|
|
325
325
|
- **Lecture non bloquante** : le fichier est lu en async (`FileClass.readAsync()` côté `renderView`,
|
|
326
|
-
`readFile` côté `renderFile`, `Eta.ts
|
|
327
|
-
- **Aides frontend paresseuses** : `withFrontendLocals()` (`Controller.ts
|
|
326
|
+
`readFile` côté `renderFile`, `Eta.ts#Eta.renderFile`) — l'event loop n'est jamais gelé par un `readFileSync`.
|
|
327
|
+
- **Aides frontend paresseuses** : `withFrontendLocals()` (`Controller.ts#Controller.withFrontendLocals`) ne construit les
|
|
328
328
|
fonctions `frontendTags`/`asset` que si le service `frontend` répond — sinon il rend les locals tels
|
|
329
329
|
quels, zéro allocation superflue.
|
|
330
330
|
|
|
@@ -337,14 +337,14 @@ template), et le framework l'isole pour ça :
|
|
|
337
337
|
|
|
338
338
|
## ⚠️ Pièges (symptôme → cause → correction)
|
|
339
339
|
|
|
340
|
-
| Symptôme | Cause (dans le code)
|
|
341
|
-
| -------------------------------------------------------- |
|
|
342
|
-
| `<%~ include("partial") %>` ne trouve pas la vue | Aucune racine `views/` n'est configurée (`defaultOption`, `Eta.ts
|
|
343
|
-
| Un `<b>` d'utilisateur s'exécute dans la page | Sortie brute `<%~ %>` sur une donnée non fiable
|
|
344
|
-
| `<%= it.name %>` requis alors qu'on attend `<%= name %>` | `useWith` mal compris — Nodefony l'active (`Eta.ts
|
|
345
|
-
| Modif de template ignorée en prod | `cache: true` en production (`Template.ts
|
|
346
|
-
| La réponse d'erreur n'est pas ma vue Eta | Les erreurs rendent du JSON, pas un template (`error-renderer.ts
|
|
347
|
-
| `renderView()` rejette et logge une ERROR | Fichier introuvable ou template invalide (le `catch` re-lève, `Controller.ts
|
|
340
|
+
| Symptôme | Cause (dans le code) | Correction |
|
|
341
|
+
| -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
342
|
+
| `<%~ include("partial") %>` ne trouve pas la vue | Aucune racine `views/` n'est configurée (`defaultOption`, `Eta.ts#defaultOption`) | Compose côté contrôleur : rends chaque fragment, ou passe le HTML en local |
|
|
343
|
+
| Un `<b>` d'utilisateur s'exécute dans la page | Sortie brute `<%~ %>` sur une donnée non fiable | Utiliser `<%= %>` (échappé par défaut) |
|
|
344
|
+
| `<%= it.name %>` requis alors qu'on attend `<%= name %>` | `useWith` mal compris — Nodefony l'active (`Eta.ts#defaultOption`), les locals sont nus | Écrire `<%= name %>` directement |
|
|
345
|
+
| Modif de template ignorée en prod | `cache: true` en production (`Template.ts#Template.constructor`) | Redémarrer le pod ; en dev le cache est off, recompile à chaud |
|
|
346
|
+
| La réponse d'erreur n'est pas ma vue Eta | Les erreurs rendent du JSON, pas un template (`error-renderer.ts#IValidationField.message`) | Pour une page d'erreur HTML, rendre explicitement une vue dans un handler |
|
|
347
|
+
| `renderView()` rejette et logge une ERROR | Fichier introuvable ou template invalide (le `catch` re-lève, `Controller.ts#Controller.renderResponse`) | Vérifier le chemin résolu (`resolve(module.path, …)`) |
|
|
348
348
|
|
|
349
349
|
## 🧪 Tests et couverture
|
|
350
350
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodefony/framework",
|
|
3
|
-
"version": "10.0.0-beta.
|
|
3
|
+
"version": "10.0.0-beta.4",
|
|
4
4
|
"description": "Le modèle de programmation Nodefony : routeur, contrôleurs, décorateurs et vues — HTTP et WebSocket dans le même contexte",
|
|
5
5
|
"author": "Christophe CAMENSULI <ccamensuli@gmail.com>",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"private": false,
|
|
27
27
|
"engines": {
|
|
28
|
-
"node": ">=24.
|
|
28
|
+
"node": ">=24.14.0"
|
|
29
29
|
},
|
|
30
30
|
"keywords": [
|
|
31
31
|
"nodefony",
|
|
@@ -44,28 +44,25 @@
|
|
|
44
44
|
"directory": "src/packages/@nodefony/framework"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@graphql-tools/merge": "9.2.7",
|
|
48
|
-
"@graphql-tools/schema": "10.1.4",
|
|
49
47
|
"eta": "4.6.0",
|
|
50
|
-
"graphql": "17.0.2",
|
|
51
48
|
"reflect-metadata": "0.2.2",
|
|
52
49
|
"tslib": "2.8.1"
|
|
53
50
|
},
|
|
54
51
|
"devDependencies": {
|
|
55
|
-
"@nodefony/http": "^10.0.0-beta.
|
|
52
|
+
"@nodefony/http": "^10.0.0-beta.4",
|
|
56
53
|
"@types/chai": "5.2.3",
|
|
57
54
|
"@types/node": "26.6.5",
|
|
58
|
-
"@vitest/coverage-v8": "5.0.
|
|
59
|
-
"nodefony": "^10.0.0-beta.
|
|
55
|
+
"@vitest/coverage-v8": "5.0.5",
|
|
56
|
+
"nodefony": "^10.0.0-beta.4",
|
|
60
57
|
"tsx": "4.23.15",
|
|
61
|
-
"vitest": "5.0.
|
|
58
|
+
"vitest": "5.0.5"
|
|
62
59
|
},
|
|
63
60
|
"license": "Apache-2.0",
|
|
64
61
|
"readmeFilename": "README.md",
|
|
65
62
|
"contributors": [],
|
|
66
63
|
"peerDependencies": {
|
|
67
|
-
"@nodefony/http": "^10.0.0-beta.
|
|
68
|
-
"nodefony": "^10.0.0-beta.
|
|
64
|
+
"@nodefony/http": "^10.0.0-beta.4",
|
|
65
|
+
"nodefony": "^10.0.0-beta.4",
|
|
69
66
|
"zod": "^4.6.7"
|
|
70
67
|
},
|
|
71
68
|
"files": [
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
//#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorateMetadata.js
|
|
2
|
-
function __decorateMetadata(k, v) {
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4
|
-
}
|
|
5
|
-
//#endregion
|
|
6
|
-
export { __decorateMetadata as default };
|