@nodefony/framework 10.0.0-alpha.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.
Files changed (96) hide show
  1. package/LICENSE +544 -0
  2. package/README.md +50 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorate.js +9 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateMetadata.js +6 -0
  5. package/dist/index.js +211 -0
  6. package/dist/nodefony/config/config.js +61 -0
  7. package/dist/nodefony/config/defineModuleConfig.js +36 -0
  8. package/dist/nodefony/controller/AdminApiController.js +163 -0
  9. package/dist/nodefony/controller/ApiKeyController.js +151 -0
  10. package/dist/nodefony/controller/BenchController.js +132 -0
  11. package/dist/nodefony/controller/IssuerMetadataController.js +148 -0
  12. package/dist/nodefony/controller/OAuth2Controller.js +133 -0
  13. package/dist/nodefony/controller/ProtectedResourceMetadataController.js +221 -0
  14. package/dist/nodefony/controller/SessionAuthController.js +141 -0
  15. package/dist/nodefony/controller/TokenAuthController.js +113 -0
  16. package/dist/nodefony/controller/TotpController.js +129 -0
  17. package/dist/nodefony/controller/WebAuthnController.js +242 -0
  18. package/dist/nodefony/controller/oauthAuthority.js +74 -0
  19. package/dist/nodefony/decorators/routerDecorators.js +967 -0
  20. package/dist/nodefony/interfaces/IAdminBroker.js +1 -0
  21. package/dist/nodefony/interfaces/IController.js +1 -0
  22. package/dist/nodefony/interfaces/IIdempotencyStore.js +1 -0
  23. package/dist/nodefony/interfaces/IResolver.js +1 -0
  24. package/dist/nodefony/interfaces/IRoute.js +1 -0
  25. package/dist/nodefony/interfaces/index.js +1 -0
  26. package/dist/nodefony/service/AdminBroker.js +106 -0
  27. package/dist/nodefony/service/Eta.js +68 -0
  28. package/dist/nodefony/service/IdempotencyStore.js +136 -0
  29. package/dist/nodefony/service/router.js +243 -0
  30. package/dist/nodefony/src/Controller.js +515 -0
  31. package/dist/nodefony/src/FrameworkAdminApi.js +268 -0
  32. package/dist/nodefony/src/KernelAdminApi.js +1243 -0
  33. package/dist/nodefony/src/PlaygroundAdminApi.js +97 -0
  34. package/dist/nodefony/src/RedisIdempotencyStore.js +254 -0
  35. package/dist/nodefony/src/Resolver.js +416 -0
  36. package/dist/nodefony/src/ResourceController.js +148 -0
  37. package/dist/nodefony/src/Route.js +476 -0
  38. package/dist/nodefony/src/SyslogAdminApi.js +466 -0
  39. package/dist/nodefony/src/Template.js +15 -0
  40. package/dist/nodefony/src/configMutation.js +186 -0
  41. package/dist/nodefony/src/docsReader.js +929 -0
  42. package/dist/nodefony/src/idempotency.js +137 -0
  43. package/dist/nodefony/src/idempotencyGc.js +32 -0
  44. package/dist/nodefony/src/idempotencyStoreRegistry.js +36 -0
  45. package/dist/nodefony/src/scopeCatalog.js +40 -0
  46. package/dist/nodefony/src/syslogFilters.js +51 -0
  47. package/dist/types/index.d.ts +96 -0
  48. package/dist/types/nodefony/config/config.d.ts +41 -0
  49. package/dist/types/nodefony/config/defineModuleConfig.d.ts +27 -0
  50. package/dist/types/nodefony/controller/AdminApiController.d.ts +70 -0
  51. package/dist/types/nodefony/controller/ApiKeyController.d.ts +49 -0
  52. package/dist/types/nodefony/controller/BenchController.d.ts +45 -0
  53. package/dist/types/nodefony/controller/IssuerMetadataController.d.ts +86 -0
  54. package/dist/types/nodefony/controller/OAuth2Controller.d.ts +81 -0
  55. package/dist/types/nodefony/controller/ProtectedResourceMetadataController.d.ts +147 -0
  56. package/dist/types/nodefony/controller/SessionAuthController.d.ts +74 -0
  57. package/dist/types/nodefony/controller/TokenAuthController.d.ts +56 -0
  58. package/dist/types/nodefony/controller/TotpController.d.ts +42 -0
  59. package/dist/types/nodefony/controller/WebAuthnController.d.ts +123 -0
  60. package/dist/types/nodefony/controller/oauthAuthority.d.ts +54 -0
  61. package/dist/types/nodefony/decorators/routerDecorators.d.ts +632 -0
  62. package/dist/types/nodefony/interfaces/IAdminBroker.d.ts +79 -0
  63. package/dist/types/nodefony/interfaces/IController.d.ts +38 -0
  64. package/dist/types/nodefony/interfaces/IIdempotencyStore.d.ts +1 -0
  65. package/dist/types/nodefony/interfaces/IResolver.d.ts +25 -0
  66. package/dist/types/nodefony/interfaces/IRoute.d.ts +31 -0
  67. package/dist/types/nodefony/interfaces/index.d.ts +5 -0
  68. package/dist/types/nodefony/service/AdminBroker.d.ts +37 -0
  69. package/dist/types/nodefony/service/Eta.d.ts +25 -0
  70. package/dist/types/nodefony/service/IdempotencyStore.d.ts +45 -0
  71. package/dist/types/nodefony/service/router.d.ts +53 -0
  72. package/dist/types/nodefony/src/Controller.d.ts +193 -0
  73. package/dist/types/nodefony/src/FrameworkAdminApi.d.ts +35 -0
  74. package/dist/types/nodefony/src/KernelAdminApi.d.ts +71 -0
  75. package/dist/types/nodefony/src/PlaygroundAdminApi.d.ts +98 -0
  76. package/dist/types/nodefony/src/RedisIdempotencyStore.d.ts +104 -0
  77. package/dist/types/nodefony/src/Resolver.d.ts +165 -0
  78. package/dist/types/nodefony/src/ResourceController.d.ts +171 -0
  79. package/dist/types/nodefony/src/Route.d.ts +192 -0
  80. package/dist/types/nodefony/src/SyslogAdminApi.d.ts +38 -0
  81. package/dist/types/nodefony/src/Template.d.ts +8 -0
  82. package/dist/types/nodefony/src/configMutation.d.ts +109 -0
  83. package/dist/types/nodefony/src/docsReader.d.ts +369 -0
  84. package/dist/types/nodefony/src/idempotency.d.ts +96 -0
  85. package/dist/types/nodefony/src/idempotencyGc.d.ts +30 -0
  86. package/dist/types/nodefony/src/idempotencyStoreRegistry.d.ts +59 -0
  87. package/dist/types/nodefony/src/scopeCatalog.d.ts +26 -0
  88. package/dist/types/nodefony/src/syslogFilters.d.ts +52 -0
  89. package/docs/admin.md +451 -0
  90. package/docs/controller.md +645 -0
  91. package/docs/decorateurs.md +845 -0
  92. package/docs/idempotence.md +741 -0
  93. package/docs/index.md +151 -0
  94. package/docs/routing.md +648 -0
  95. package/docs/templates.md +380 -0
  96. package/package.json +83 -0
package/docs/index.md ADDED
@@ -0,0 +1,151 @@
1
+ ---
2
+ title: "@nodefony/framework — routes, contrôleurs, décorateurs"
3
+ navTitle: "@nodefony/framework"
4
+ lang: fr
5
+ module: "@nodefony/framework"
6
+ topic: framework
7
+ section: "Cœur runtime"
8
+ audience: [developer]
9
+ tags: [router, controller, decorateurs, resolver, routing, idempotence, admin]
10
+ version: "doc"
11
+ status: stable
12
+ updated: 2026-07-19
13
+ source: "src/packages/@nodefony/framework/docs/index.md"
14
+ coverageModule: framework
15
+ ---
16
+
17
+ # @nodefony/framework — routes, contrôleurs, décorateurs
18
+
19
+ > C'est ici qu'on écrit son application. `@nodefony/http` construit le contexte d'une requête ; ce
20
+ > module décide **quoi en faire** : quelle route, quel contrôleur, quelle action, avec quels droits.
21
+ > Il porte la DX du framework — les décorateurs — et ses invariants — résolution ordonnée, idempotence,
22
+ > data plane d'administration. Un contrôleur y déclare ses actions **HTTP et WebSocket avec les mêmes
23
+ > décorateurs**.
24
+
25
+ 📍 [Documentation](../../../../../docs/index.md) › **@nodefony/framework**
26
+
27
+ ## 🧭 Par où commencer
28
+
29
+ Trois parcours selon ce que tu viens faire. L'ordre compte : chaque étape suppose la précédente.
30
+
31
+ **J'écris ma première route** — le chemin le plus court vers une application qui répond.
32
+
33
+ 1. [Décorateurs](decorateurs.md) — la surface que tu tapes : `@controller`, `@Get`, `@Body`, `@Param`.
34
+ **Commence ici**, c'est la table de référence.
35
+ 2. [Contrôleurs](controller.md) — ce dont tu hérites, comment répondre, comment échouer proprement.
36
+ 3. [Routage](routing.md) — pourquoi telle route gagne sur telle autre, et comment lire un `405`.
37
+
38
+ **Je débugge une route qui ne répond pas comme prévu.**
39
+
40
+ 1. [Routage](routing.md) — l'ordre de déclaration **est** la priorité ; la passe 405 ; les vhosts.
41
+ 2. [Contrôleurs](controller.md) — l'ordre réel du cycle de vie, et ce que `initialize()` peut ou non
42
+ supposer.
43
+ 3. [Pipeline de requête](../../../../../docs/architecture/pipeline-requete.md) — ce qui s'est passé
44
+ avant que ta route soit même consultée.
45
+
46
+ **Je fiabilise des mutations** — paiements, commandes, tout ce qu'on ne veut pas jouer deux fois.
47
+
48
+ 1. [Idempotence](idempotence.md) — `@Idempotent`, la clé, les stores, ce qui se passe au rejeu.
49
+ 2. [Contrôleurs](controller.md) — codes de retour et réponses vides (204) sans piège.
50
+ 3. [Sécurité](../../security/docs/index.md) — l'autorisation qui va avec.
51
+
52
+ ## 🗂️ Les briques du module
53
+
54
+ Le tableau pour choisir vite ; les cards en dessous pour savoir ce qu'on y trouve.
55
+
56
+ | Brique | Ce qu'elle résout | Tu en as besoin quand… |
57
+ | ------------------------------- | -------------------------------------------------- | --------------------------------------------------------- |
58
+ | [Décorateurs](decorateurs.md) | déclarer routes, paramètres, réponses, gardes | toujours — c'est la surface d'écriture |
59
+ | [Contrôleurs](controller.md) | recevoir la requête, répondre, gérer l'erreur | toujours |
60
+ | [Routage](routing.md) | apparier une URL à une action, arbitrer, expliquer | deux routes se disputent, ou un 404/405 surprend |
61
+ | [Idempotence](idempotence.md) | empêcher le double effet d'une mutation rejouée | paiement, commande, tout effet non rejouable |
62
+ | [Admin (data plane)](admin.md) | monter les API d'admin `/nodefony/<ns>/api/*` | ton module expose des stats ou actions à Studio et au CLI |
63
+ | [Templates (Eta)](templates.md) | rendre des vues HTML côté serveur | tu renvoies des pages HTML plutôt que du JSON |
64
+
65
+ ```nodefony-cards
66
+ [
67
+ { "icon": "🏷️", "title": "decorateurs", "href": "decorateurs.md",
68
+ "desc": "La table de référence complète — classe, méthode HTTP, paramètre, réponse, sécurité, WebSocket — chacun avec son effet et un exemple court.",
69
+ "meta": "la page qu'on garde ouverte en écrivant un contrôleur" },
70
+ { "icon": "🎛️", "title": "controller", "href": "controller.md",
71
+ "desc": "Ce dont hérite un contrôleur, d'où viennent request / response / session, comment répondre (auto-JSON, codes, flux de fichiers), comment les erreurs remontent, et l'ordre réel du cycle de vie.",
72
+ "meta": "toujours — c'est ce dont tu hérites" },
73
+ { "icon": "🚦", "title": "routing", "href": "routing.md",
74
+ "desc": "Une table ordonnée où le premier motif qui correspond gagne : l'arbitrage sans score de spécificité, la partition littéral/dynamique qui accélère sans changer la sémantique, le 405 et son en-tête Allow, les vhosts, le duplex HTTP+WebSocket sur un même chemin.",
75
+ "meta": "deux routes se disputent, ou un 404/405 surprend" },
76
+ { "icon": "🔁", "title": "idempotence", "href": "idempotence.md",
77
+ "desc": "@Idempotent, la clé d'idempotence, les trois stores et leurs capacités réelles, le GC des entrées expirées, et ce que le client observe quand il rejoue la même clé.",
78
+ "meta": "paiement, commande, tout effet non rejouable" },
79
+ { "icon": "🛡️", "title": "admin", "href": "admin.md",
80
+ "desc": "Le data plane d'administration : comment un module déclare son API d'admin via AdminBroker, la convention de route /nodefony/<ns>/api/*, le RBAC fail-closed (ROLE_NODEFONY_ADMIN), le duplex HTTP/WebSocket, le catalogue et le Playground.",
81
+ "meta": "exposer une API d'admin cohérente CLI ↔ Web" },
82
+ { "icon": "📄", "title": "templates", "href": "templates.md",
83
+ "desc": "Le moteur de vues Eta : rendre une vue depuis un contrôleur (renderView, render), résolution des chemins de vues, passage de variables, échappement HTML par défaut contre le XSS, rendu d'erreurs.",
84
+ "meta": "produire du HTML côté serveur plutôt que du JSON" }
85
+ ]
86
+ ```
87
+
88
+ ## 🏛️ Place dans le framework
89
+
90
+ ```mermaid
91
+ flowchart LR
92
+ DEC["décorateurs<br/>@controller · @Get · @Param"] --> RT["Router<br/>table ordonnée de routes"]
93
+ RT --> RS["Resolver<br/>par requête : match → action"]
94
+ RS --> C["Controller<br/>ton code"]
95
+ C --> AB["AdminBroker<br/>/nodefony/&lt;ns&gt;/api/*"]
96
+ ```
97
+
98
+ Le module s'appuie sur `@nodefony/http` (contexte, serveurs) et se fait garder par
99
+ `@nodefony/security` (firewall, CSRF). L'inverse n'est pas vrai : `@nodefony/http` ne peut pas
100
+ importer ce module — ce serait un cycle.
101
+
102
+ ## 🧰 Surface publique
103
+
104
+ Depuis une application : `Controller`, `Router`, `Resolver`, `Route`, `controllers()`, les décorateurs
105
+ de route, de paramètre et de garde, `IdempotencyStore`, `AdminBroker`. Les signatures exactes vivent
106
+ dans `.ai/symbols.json` et les types générés — jamais recopiées ici, où elles se périmeraient.
107
+
108
+ ## ⚙️ Configuration
109
+
110
+ Bloc Zod (`nodefony/config/config.ts`), déclaré depuis l'application via
111
+ `use("@nodefony/framework", { … })` : `router`, `adminBroker`, et `idempotency` (choix du store et
112
+ réglages du GC — détaillé dans la page [Idempotence](idempotence.md)).
113
+
114
+ ## 📜 Normes appliquées
115
+
116
+ RFC 9110 (méthodes, `405` et en-tête `Allow`, redirections), RFC 6455 §7.4 (codes de fermeture
117
+ WebSocket, dont le `1002` d'erreur de sous-protocole), et le brouillon IETF `Idempotency-Key`.
118
+
119
+ ## 📡 Observabilité — Studio
120
+
121
+ L'écran **Routes** liste la table telle qu'elle est réellement montée, et le **Playground** permet de
122
+ jouer une route en voyant ses badges `@IsGranted` / `@Idempotent`. Chaque module publie son data plane
123
+ via `AdminBroker`.
124
+
125
+ ## 🧪 Tests & couverture
126
+
127
+ Les chiffres exacts vivent dans la carte de l'aperçu, régénérée depuis vitest — jamais figés ici.
128
+
129
+ | Type | Où | Ce qui est prouvé |
130
+ | ----------- | ------------------------ | ------------------------------------------------------- |
131
+ | Unitaire | `nodefony/tests/unit/**` | routeur, resolver, contrôleur, décorateurs, idempotence |
132
+ | Intégration | via `@nodefony/http` | la route réelle répond sur un serveur vivant |
133
+ | E2E | via `@nodefony/drizzle` | idempotence rejouée contre une vraie base |
134
+
135
+ ## ⚠️ Pièges (symptôme → cause → correction)
136
+
137
+ | Symptôme | Cause | Correction |
138
+ | --------------------------------------------- | ------------------------------------------------------------ | --------------------------------------------- |
139
+ | `404` sur une route qui « existe » | Contrôleur jamais importé — les routes naissent à l'import | L'ajouter à `@controllers([…])` du module |
140
+ | Une route paramétrée mange un chemin littéral | L'ordre de déclaration **est** la priorité | Déclarer le littéral avant le paramétré |
141
+ | Action WebSocket jamais atteinte | Transport `WEBSOCKET` non déclaré sur la route | L'ajouter aux méthodes de la route |
142
+ | `ce nom est RÉSERVÉ` sur une action `remove` | Le nom entre en collision avec un membre hérité de `Service` | Renommer l'action — l'URL vient du décorateur |
143
+ | Double effet d'une mutation rejouée | Route sensible sans clé d'idempotence | Voir [idempotence](idempotence.md) |
144
+
145
+ ## 🔗 Pour aller plus loin
146
+
147
+ - Le trajet complet d'une requête → [pipeline-requete](../../../../../docs/architecture/pipeline-requete.md)
148
+ - La couche transport en dessous → [@nodefony/http](../../http/docs/index.md)
149
+ - Le pare-feu qui garde les actions → [@nodefony/security](../../security/docs/index.md)
150
+ - Portées d'injection des contrôleurs → [injection-portees](../../../../../docs/architecture/injection-portees.md)
151
+ - Vue d'ensemble du framework → [vue-ensemble](../../../../../docs/architecture/vue-ensemble.md)