nodefony 7.0.2 → 10.0.0-alpha.2

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 (903) hide show
  1. package/.ai/symbols.json +36135 -0
  2. package/LICENSE +544 -0
  3. package/README.md +316 -694
  4. package/bin/nodefony +2183 -85
  5. package/dist/client/Container.js +367 -0
  6. package/dist/client/Event.js +198 -0
  7. package/dist/client/Service.js +344 -0
  8. package/dist/client/Tools.js +162 -0
  9. package/dist/client/client/ClientKernel.js +276 -0
  10. package/dist/client/client/angular/index.js +352 -0
  11. package/dist/client/client/announce.js +212 -0
  12. package/dist/client/client/debugbar/DebugBar.js +1624 -0
  13. package/dist/client/client/debugbar/format.js +103 -0
  14. package/dist/client/client/debugbar/hmr.js +37 -0
  15. package/dist/client/client/debugbar/index.js +29 -0
  16. package/dist/client/client/debugbar/model.js +133 -0
  17. package/dist/client/client/debugbar/network.js +173 -0
  18. package/dist/client/client/debugbar/profile.js +114 -0
  19. package/dist/client/client/index.js +34 -0
  20. package/dist/client/client/react/index.js +268 -0
  21. package/dist/client/client/realtime/AdaptiveRate.js +240 -0
  22. package/dist/client/client/realtime/BrowserWsTransport.js +57 -0
  23. package/dist/client/client/realtime/RealtimeClient.js +898 -0
  24. package/dist/client/client/realtime/localEvents.js +56 -0
  25. package/dist/client/client/realtime/notice.js +125 -0
  26. package/dist/client/client/realtime/observe.js +280 -0
  27. package/dist/client/client/roles/index.js +3 -0
  28. package/dist/client/client/roles/registry.js +97 -0
  29. package/dist/client/client/roles/roles.js +91 -0
  30. package/dist/client/client/shim/events.js +88 -0
  31. package/dist/client/client/shim/util.js +20 -0
  32. package/dist/client/client/svelte/index.js +319 -0
  33. package/dist/client/client/syslog/context.js +122 -0
  34. package/dist/client/client/syslog/errors.js +49 -0
  35. package/dist/client/client/syslog/uplink.js +106 -0
  36. package/dist/client/client/vue/index.js +321 -0
  37. package/dist/client/colors.js +63 -0
  38. package/dist/client/debugbar.standalone.js +4274 -0
  39. package/dist/client/realtime/IRealtimeTransport.js +32 -0
  40. package/dist/client/realtime/JsonRpcPeer.js +251 -0
  41. package/dist/client/realtime/channelRate.js +39 -0
  42. package/dist/client/realtime/platformChannels.js +155 -0
  43. package/dist/client/syslog/Pdu.js +224 -0
  44. package/dist/client/syslog/Syslog.js +1159 -0
  45. package/dist/client/syslog/drivers/pduFlow.js +106 -0
  46. package/dist/client/syslog/drivers/pduProtocol.js +28 -0
  47. package/dist/client/syslog/logColor.js +80 -0
  48. package/dist/client/types/src/Container.d.ts +221 -0
  49. package/dist/client/types/src/Event.d.ts +171 -0
  50. package/dist/client/types/src/FileClass.d.ts +184 -0
  51. package/dist/client/types/src/Service.d.ts +165 -0
  52. package/dist/client/types/src/Tools.d.ts +116 -0
  53. package/dist/client/types/src/client/ClientKernel.d.ts +90 -0
  54. package/dist/client/types/src/client/IClientKernel.d.ts +195 -0
  55. package/dist/client/types/src/client/angular/index.d.ts +273 -0
  56. package/dist/client/types/src/client/announce.d.ts +74 -0
  57. package/dist/client/types/src/client/debugbar/DebugBar.d.ts +279 -0
  58. package/dist/client/types/src/client/debugbar/format.d.ts +48 -0
  59. package/dist/client/types/src/client/debugbar/hmr.d.ts +16 -0
  60. package/dist/client/types/src/client/debugbar/index.d.ts +30 -0
  61. package/dist/client/types/src/client/debugbar/model.d.ts +158 -0
  62. package/dist/client/types/src/client/debugbar/network.d.ts +55 -0
  63. package/dist/client/types/src/client/debugbar/profile.d.ts +99 -0
  64. package/dist/client/types/src/client/index.d.ts +47 -0
  65. package/dist/client/types/src/client/react/index.d.ts +207 -0
  66. package/dist/client/types/src/client/realtime/AdaptiveRate.d.ts +138 -0
  67. package/dist/client/types/src/client/realtime/BrowserWsTransport.d.ts +27 -0
  68. package/dist/client/types/src/client/realtime/RealtimeClient.d.ts +573 -0
  69. package/dist/client/types/src/client/realtime/localEvents.d.ts +53 -0
  70. package/dist/client/types/src/client/realtime/notice.d.ts +70 -0
  71. package/dist/client/types/src/client/realtime/observe.d.ts +284 -0
  72. package/dist/client/types/src/client/roles/index.d.ts +15 -0
  73. package/dist/client/types/src/client/roles/registry.d.ts +72 -0
  74. package/dist/client/types/src/client/roles/roles.d.ts +68 -0
  75. package/dist/client/types/src/client/shim/cli-color.d.ts +2 -0
  76. package/dist/client/types/src/client/shim/events.d.ts +39 -0
  77. package/dist/client/types/src/client/shim/util.d.ts +14 -0
  78. package/dist/client/types/src/client/svelte/index.d.ts +216 -0
  79. package/dist/client/types/src/client/syslog/context.d.ts +76 -0
  80. package/dist/client/types/src/client/syslog/errors.d.ts +46 -0
  81. package/dist/client/types/src/client/syslog/uplink.d.ts +89 -0
  82. package/dist/client/types/src/client/transport/websocket.d.ts +5 -0
  83. package/dist/client/types/src/client/vue/index.d.ts +234 -0
  84. package/dist/client/types/src/colors.d.ts +32 -0
  85. package/dist/client/types/src/config/infra.d.ts +171 -0
  86. package/dist/client/types/src/kernel/bootReport.d.ts +112 -0
  87. package/dist/client/types/src/kernel/readinessRegistry.d.ts +104 -0
  88. package/dist/client/types/src/realtime/IRealtimeSocket.d.ts +142 -0
  89. package/dist/client/types/src/realtime/IRealtimeTransport.d.ts +50 -0
  90. package/dist/client/types/src/realtime/JsonRpcPeer.d.ts +251 -0
  91. package/dist/client/types/src/realtime/RealtimeEventMap.d.ts +269 -0
  92. package/dist/client/types/src/realtime/channelRate.d.ts +55 -0
  93. package/dist/client/types/src/realtime/platformChannels.d.ts +147 -0
  94. package/dist/client/types/src/syslog/Pdu.d.ts +134 -0
  95. package/dist/client/types/src/syslog/Syslog.d.ts +482 -0
  96. package/dist/client/types/src/syslog/drivers/ILogDriver.d.ts +177 -0
  97. package/dist/client/types/src/syslog/drivers/pduFlow.d.ts +53 -0
  98. package/dist/client/types/src/syslog/drivers/pduProtocol.d.ts +20 -0
  99. package/dist/client/types/src/syslog/logColor.d.ts +59 -0
  100. package/dist/client/types/src/types/ICliKernel.d.ts +28 -0
  101. package/dist/client/types/src/types/ICommand.d.ts +14 -0
  102. package/dist/client/types/src/types/IContainer.d.ts +35 -0
  103. package/dist/client/types/src/types/IKernel.d.ts +138 -0
  104. package/dist/client/types/src/types/IMcpTool.d.ts +157 -0
  105. package/dist/client/types/src/types/IModule.d.ts +73 -0
  106. package/dist/client/types/src/types/IPage.d.ts +119 -0
  107. package/dist/client/types/src/types/IService.d.ts +62 -0
  108. package/dist/client/types/src/types/ISyslog.d.ts +58 -0
  109. package/dist/client/types/src/types/ITransport.d.ts +5 -0
  110. package/dist/client/types/src/types/globals.d.ts +47 -0
  111. package/dist/node/Cli.js +750 -0
  112. package/dist/node/Container.js +367 -0
  113. package/dist/node/Error.js +309 -0
  114. package/dist/node/Event.js +198 -0
  115. package/dist/node/FileClass.js +308 -0
  116. package/dist/node/Nodefony.js +78 -0
  117. package/dist/node/Service.js +344 -0
  118. package/dist/node/Tools.js +205 -0
  119. package/dist/node/bin/resolveLocalCli.js +10 -0
  120. package/dist/node/bundler/index.js +103 -0
  121. package/dist/node/cli/agentTargets.js +461 -0
  122. package/dist/node/cli/aiMcp.js +553 -0
  123. package/dist/node/cli/aiMcpReport.js +129 -0
  124. package/dist/node/cli/aiSync.js +323 -0
  125. package/dist/node/cli/aiSyncReport.js +142 -0
  126. package/dist/node/cli/card.js +186 -0
  127. package/dist/node/cli/cardReport.js +110 -0
  128. package/dist/node/cli/completion.js +415 -0
  129. package/dist/node/cli/create.js +805 -0
  130. package/dist/node/cli/env.js +332 -0
  131. package/dist/node/cli/envReport.js +159 -0
  132. package/dist/node/cli/execPortable.js +60 -0
  133. package/dist/node/cli/gitHooks.js +191 -0
  134. package/dist/node/cli/gitHooksReport.js +119 -0
  135. package/dist/node/cli/globalFlags.js +67 -0
  136. package/dist/node/cli/helpReport.js +288 -0
  137. package/dist/node/cli/manPage.js +165 -0
  138. package/dist/node/cli/nodefonyBin.js +61 -0
  139. package/dist/node/cli/outdated.js +144 -0
  140. package/dist/node/cli/progress.js +555 -0
  141. package/dist/node/cli/projectRoot.js +32 -0
  142. package/dist/node/cli/promptPassword.js +44 -0
  143. package/dist/node/cli/prompts.js +86 -0
  144. package/dist/node/cli/scaffold/destination.js +92 -0
  145. package/dist/node/cli/scaffold/engine.js +2156 -0
  146. package/dist/node/cli/scaffold/entityFields.js +589 -0
  147. package/dist/node/cli/scaffold/format.js +243 -0
  148. package/dist/node/cli/scaffold/interactive.js +124 -0
  149. package/dist/node/cli/scaffold/moduleLayout.js +38 -0
  150. package/dist/node/cli/scaffold/reservedEntities.js +74 -0
  151. package/dist/node/cli/scaffold/spec.js +704 -0
  152. package/dist/node/cli/scaffold/steps.js +40 -0
  153. package/dist/node/cli/scaffold/userContractSource.js +133 -0
  154. package/dist/node/cli/scaffold/versions.js +57 -0
  155. package/dist/node/cli/scaffold/writer.js +172 -0
  156. package/dist/node/cli/startMenu.js +496 -0
  157. package/dist/node/cli/symbols.js +205 -0
  158. package/dist/node/cli/sysexits.js +34 -0
  159. package/dist/node/cli/tableReport.js +184 -0
  160. package/dist/node/cli/usageReport.js +144 -0
  161. package/dist/node/colors.js +63 -0
  162. package/dist/node/command/Builder.js +153 -0
  163. package/dist/node/command/Command.js +348 -0
  164. package/dist/node/config/configProvenance.js +101 -0
  165. package/dist/node/config/defaults.js +39 -0
  166. package/dist/node/config/defineConfig.js +129 -0
  167. package/dist/node/config/defineEnv.js +264 -0
  168. package/dist/node/config/envExample.js +41 -0
  169. package/dist/node/config/envOverride.js +423 -0
  170. package/dist/node/config/infra.js +163 -0
  171. package/dist/node/config/reactivity.js +23 -0
  172. package/dist/node/config/reservedEnv.js +118 -0
  173. package/dist/node/config/schema.js +134 -0
  174. package/dist/node/config/use.js +24 -0
  175. package/dist/node/finder/File.js +49 -0
  176. package/dist/node/finder/FileResult.js +86 -0
  177. package/dist/node/finder/Finder.js +201 -0
  178. package/dist/node/finder/Result.js +45 -0
  179. package/dist/node/index.js +121 -0
  180. package/dist/node/kernel/BootConfigurationError.js +54 -0
  181. package/dist/node/kernel/CliKernel.js +630 -0
  182. package/dist/node/kernel/Kernel.js +2198 -0
  183. package/dist/node/kernel/Module.js +453 -0
  184. package/dist/node/kernel/adminPlane/adminCaller.js +98 -0
  185. package/dist/node/kernel/adminPlane/adminRbac.js +51 -0
  186. package/dist/node/kernel/adminPlane/catalog.js +158 -0
  187. package/dist/node/kernel/adminPlane/executeAdmin.js +78 -0
  188. package/dist/node/kernel/checks/deep.js +335 -0
  189. package/dist/node/kernel/checks/freshness.js +139 -0
  190. package/dist/node/kernel/checks/gating.js +231 -0
  191. package/dist/node/kernel/checks/guards.js +232 -0
  192. package/dist/node/kernel/checks/lastBoot.js +136 -0
  193. package/dist/node/kernel/checks/live.js +330 -0
  194. package/dist/node/kernel/checks/packageDeps.js +292 -0
  195. package/dist/node/kernel/checks/readiness.js +153 -0
  196. package/dist/node/kernel/checks/renderReport.js +780 -0
  197. package/dist/node/kernel/checks/report.js +421 -0
  198. package/dist/node/kernel/checks/runDoctor.js +731 -0
  199. package/dist/node/kernel/checks/surface.js +364 -0
  200. package/dist/node/kernel/checks/walk.js +100 -0
  201. package/dist/node/kernel/checks/wiring.js +450 -0
  202. package/dist/node/kernel/commands/AiMcpCommand.js +65 -0
  203. package/dist/node/kernel/commands/AiSyncCommand.js +48 -0
  204. package/dist/node/kernel/commands/BuildCommand.js +49 -0
  205. package/dist/node/kernel/commands/CardCommand.js +50 -0
  206. package/dist/node/kernel/commands/ClusterCommand.js +58 -0
  207. package/dist/node/kernel/commands/CompletionCommand.js +31 -0
  208. package/dist/node/kernel/commands/CreateCommand.js +45 -0
  209. package/dist/node/kernel/commands/DevCommand.js +99 -0
  210. package/dist/node/kernel/commands/DoctorCommand.js +115 -0
  211. package/dist/node/kernel/commands/EnvCommand.js +52 -0
  212. package/dist/node/kernel/commands/GitHooksCommand.js +47 -0
  213. package/dist/node/kernel/commands/InspectCommand.js +153 -0
  214. package/dist/node/kernel/commands/InstallCommand.js +20 -0
  215. package/dist/node/kernel/commands/MenuCommand.js +261 -0
  216. package/dist/node/kernel/commands/OutdatedCommand.js +164 -0
  217. package/dist/node/kernel/commands/ProdCommand.js +60 -0
  218. package/dist/node/kernel/commands/StatusCommand.js +30 -0
  219. package/dist/node/kernel/commands/StopCommand.js +35 -0
  220. package/dist/node/kernel/commands/SymbolsCommand.js +45 -0
  221. package/dist/node/kernel/commands/runtimeLauncher.js +95 -0
  222. package/dist/node/kernel/decorators/kernelDecorator.js +110 -0
  223. package/dist/node/kernel/injector/injector.js +137 -0
  224. package/dist/node/kernel/injector/serviceOrder.js +106 -0
  225. package/dist/node/kernel/inspect/adminSubjects.js +194 -0
  226. package/dist/node/kernel/inspect/docOutline.js +86 -0
  227. package/dist/node/kernel/lifecycleTags.js +76 -0
  228. package/dist/node/kernel/moduleConfig.js +75 -0
  229. package/dist/node/kernel/moduleGating.js +68 -0
  230. package/dist/node/kernel/readinessRegistry.js +98 -0
  231. package/dist/node/kernel/resolveModuleEntry.js +61 -0
  232. package/dist/node/mcp/caller.js +40 -0
  233. package/dist/node/mcp/guard.js +51 -0
  234. package/dist/node/mcp/protocol.js +157 -0
  235. package/dist/node/mcp/server.js +216 -0
  236. package/dist/node/mcp/tools.js +861 -0
  237. package/dist/node/oauth/authorizationServer.js +221 -0
  238. package/dist/node/oauth/protectedResource.js +293 -0
  239. package/dist/node/package.js +4 -0
  240. package/dist/node/realtime/IRealtimeTransport.js +32 -0
  241. package/dist/node/realtime/JsonRpcPeer.js +251 -0
  242. package/dist/node/realtime/RealtimeEventMap.js +15 -0
  243. package/dist/node/realtime/channelRate.js +39 -0
  244. package/dist/node/realtime/platformChannels.js +155 -0
  245. package/dist/node/runtime/GcScheduler.js +92 -0
  246. package/dist/node/runtime/RequestContext.js +76 -0
  247. package/dist/node/runtime/bearer.js +84 -0
  248. package/dist/node/runtime/engineEnvironment.js +79 -0
  249. package/dist/node/runtime/loadEnv.js +105 -0
  250. package/dist/node/runtime/pageFacets.js +85 -0
  251. package/dist/node/runtime/pageFilters.js +103 -0
  252. package/dist/node/runtime/pageGuard.js +84 -0
  253. package/dist/node/runtime/pageQuery.js +160 -0
  254. package/dist/node/runtime/pageSort.js +114 -0
  255. package/dist/node/runtime/redact.js +43 -0
  256. package/dist/node/runtime/withTimeout.js +71 -0
  257. package/dist/node/service/cluster/ClusterManager.js +202 -0
  258. package/dist/node/service/cluster/ClusterProbeAggregator.js +120 -0
  259. package/dist/node/service/cluster/ClusterRelay.js +74 -0
  260. package/dist/node/service/cluster/clusterMaster.js +65 -0
  261. package/dist/node/service/cluster/clusterMessage.js +70 -0
  262. package/dist/node/service/cluster/cpuQuota.js +59 -0
  263. package/dist/node/service/cluster/instanceProbe.js +52 -0
  264. package/dist/node/service/cluster/podEnvironment.js +48 -0
  265. package/dist/node/service/cluster/processProbe.js +70 -0
  266. package/dist/node/service/cluster/richProcessProbe.js +115 -0
  267. package/dist/node/service/cluster/topology.js +71 -0
  268. package/dist/node/service/dev/BootReporter.js +490 -0
  269. package/dist/node/service/dev/DevSupervisor.js +1004 -0
  270. package/dist/node/service/dev/bootVerdict.js +158 -0
  271. package/dist/node/service/dev/detachedStart.js +372 -0
  272. package/dist/node/service/dev/devProcess.js +1137 -0
  273. package/dist/node/service/dev/devProjects.js +138 -0
  274. package/dist/node/service/dev/devStatusReport.js +395 -0
  275. package/dist/node/service/dev/devStop.js +263 -0
  276. package/dist/node/service/fetchService.js +35 -0
  277. package/dist/node/service/gitService.js +62 -0
  278. package/dist/node/syslog/Pdu.js +224 -0
  279. package/dist/node/syslog/Syslog.js +1159 -0
  280. package/dist/node/syslog/drivers/ClusterFileLogDriver.js +114 -0
  281. package/dist/node/syslog/drivers/FileLogDriver.js +127 -0
  282. package/dist/node/syslog/drivers/ILogDriver.js +26 -0
  283. package/dist/node/syslog/drivers/LokiLogDriver.js +144 -0
  284. package/dist/node/syslog/drivers/MemoryLogDriver.js +33 -0
  285. package/dist/node/syslog/drivers/OpenSearchLogDriver.js +159 -0
  286. package/dist/node/syslog/drivers/builtinLogDrivers.js +114 -0
  287. package/dist/node/syslog/drivers/filterPdus.js +71 -0
  288. package/dist/node/syslog/drivers/logDriverRegistry.js +83 -0
  289. package/dist/node/syslog/drivers/opensearchShared.js +17 -0
  290. package/dist/node/syslog/drivers/pduFlow.js +106 -0
  291. package/dist/node/syslog/drivers/pduProtocol.js +28 -0
  292. package/dist/node/syslog/httpFetch.js +43 -0
  293. package/dist/node/syslog/logColor.js +80 -0
  294. package/dist/node/syslog/sinks/FileSink.js +142 -0
  295. package/dist/node/syslog/transports/BatchingHttpTransport.js +98 -0
  296. package/dist/node/syslog/transports/ConsoleTransport.js +14 -0
  297. package/dist/node/syslog/transports/FileTransport.js +17 -0
  298. package/dist/node/syslog/transports/HttpTransport.js +44 -0
  299. package/dist/node/syslog/transports/LokiTransport.js +80 -0
  300. package/dist/node/syslog/transports/OpenSearchTransport.js +53 -0
  301. package/dist/node/syslog/transports/SyslogTransport.js +13 -0
  302. package/dist/node/syslog/transports/index.js +8 -0
  303. package/dist/node/testing/index.js +190 -0
  304. package/dist/types/Cli.d.ts +177 -0
  305. package/dist/types/Container.d.ts +221 -0
  306. package/dist/types/Error.d.ts +162 -0
  307. package/dist/types/Event.d.ts +171 -0
  308. package/dist/types/FileClass.d.ts +184 -0
  309. package/dist/types/Nodefony.d.ts +66 -0
  310. package/dist/types/Service.d.ts +165 -0
  311. package/dist/types/Tools.d.ts +116 -0
  312. package/dist/types/bin/resolveLocalCli.d.ts +49 -0
  313. package/dist/types/bundler/index.d.ts +66 -0
  314. package/dist/types/cli/agentTargets.d.ts +378 -0
  315. package/dist/types/cli/aiMcp.d.ts +239 -0
  316. package/dist/types/cli/aiMcpReport.d.ts +113 -0
  317. package/dist/types/cli/aiSync.d.ts +68 -0
  318. package/dist/types/cli/aiSyncReport.d.ts +149 -0
  319. package/dist/types/cli/card.d.ts +49 -0
  320. package/dist/types/cli/cardReport.d.ts +127 -0
  321. package/dist/types/cli/completion.d.ts +154 -0
  322. package/dist/types/cli/create.d.ts +177 -0
  323. package/dist/types/cli/env.d.ts +103 -0
  324. package/dist/types/cli/envReport.d.ts +153 -0
  325. package/dist/types/cli/execPortable.d.ts +54 -0
  326. package/dist/types/cli/gitHooks.d.ts +48 -0
  327. package/dist/types/cli/gitHooksReport.d.ts +101 -0
  328. package/dist/types/cli/globalFlags.d.ts +48 -0
  329. package/dist/types/cli/helpReport.d.ts +110 -0
  330. package/dist/types/cli/manPage.d.ts +21 -0
  331. package/dist/types/cli/nodefonyBin.d.ts +45 -0
  332. package/dist/types/cli/outdated.d.ts +119 -0
  333. package/dist/types/cli/progress.d.ts +349 -0
  334. package/dist/types/cli/projectRoot.d.ts +19 -0
  335. package/dist/types/cli/promptPassword.d.ts +22 -0
  336. package/dist/types/cli/prompts.d.ts +102 -0
  337. package/dist/types/cli/scaffold/destination.d.ts +70 -0
  338. package/dist/types/cli/scaffold/engine.d.ts +545 -0
  339. package/dist/types/cli/scaffold/entityFields.d.ts +238 -0
  340. package/dist/types/cli/scaffold/format.d.ts +78 -0
  341. package/dist/types/cli/scaffold/interactive.d.ts +11 -0
  342. package/dist/types/cli/scaffold/moduleLayout.d.ts +69 -0
  343. package/dist/types/cli/scaffold/reservedEntities.d.ts +49 -0
  344. package/dist/types/cli/scaffold/spec.d.ts +159 -0
  345. package/dist/types/cli/scaffold/steps.d.ts +24 -0
  346. package/dist/types/cli/scaffold/userContractSource.d.ts +86 -0
  347. package/dist/types/cli/scaffold/versions.d.ts +14 -0
  348. package/dist/types/cli/scaffold/writer.d.ts +100 -0
  349. package/dist/types/cli/startMenu.d.ts +195 -0
  350. package/dist/types/cli/symbols.d.ts +84 -0
  351. package/dist/types/cli/sysexits.d.ts +31 -0
  352. package/dist/types/cli/tableReport.d.ts +44 -0
  353. package/dist/types/cli/usageReport.d.ts +108 -0
  354. package/dist/types/client/ClientKernel.d.ts +90 -0
  355. package/dist/types/client/IClientKernel.d.ts +195 -0
  356. package/dist/types/client/angular/index.d.ts +273 -0
  357. package/dist/types/client/announce.d.ts +74 -0
  358. package/dist/types/client/debugbar/DebugBar.d.ts +279 -0
  359. package/dist/types/client/debugbar/format.d.ts +48 -0
  360. package/dist/types/client/debugbar/hmr.d.ts +16 -0
  361. package/dist/types/client/debugbar/index.d.ts +30 -0
  362. package/dist/types/client/debugbar/model.d.ts +158 -0
  363. package/dist/types/client/debugbar/network.d.ts +55 -0
  364. package/dist/types/client/debugbar/profile.d.ts +99 -0
  365. package/dist/types/client/index.d.ts +47 -0
  366. package/dist/types/client/react/index.d.ts +207 -0
  367. package/dist/types/client/realtime/AdaptiveRate.d.ts +138 -0
  368. package/dist/types/client/realtime/BrowserWsTransport.d.ts +27 -0
  369. package/dist/types/client/realtime/RealtimeClient.d.ts +573 -0
  370. package/dist/types/client/realtime/localEvents.d.ts +53 -0
  371. package/dist/types/client/realtime/notice.d.ts +70 -0
  372. package/dist/types/client/realtime/observe.d.ts +284 -0
  373. package/dist/types/client/roles/index.d.ts +15 -0
  374. package/dist/types/client/roles/registry.d.ts +72 -0
  375. package/dist/types/client/roles/roles.d.ts +68 -0
  376. package/dist/types/client/shim/cli-color.d.ts +2 -0
  377. package/dist/types/client/shim/events.d.ts +39 -0
  378. package/dist/types/client/shim/util.d.ts +14 -0
  379. package/dist/types/client/svelte/index.d.ts +216 -0
  380. package/dist/types/client/syslog/context.d.ts +76 -0
  381. package/dist/types/client/syslog/errors.d.ts +46 -0
  382. package/dist/types/client/syslog/uplink.d.ts +89 -0
  383. package/dist/types/client/transport/websocket.d.ts +5 -0
  384. package/dist/types/client/vue/index.d.ts +234 -0
  385. package/dist/types/colors.d.ts +32 -0
  386. package/dist/types/command/Builder.d.ts +47 -0
  387. package/dist/types/command/Command.d.ts +268 -0
  388. package/dist/types/config/configMeta.d.ts +53 -0
  389. package/dist/types/config/configProvenance.d.ts +58 -0
  390. package/dist/types/config/defaults.d.ts +33 -0
  391. package/dist/types/config/defineConfig.d.ts +70 -0
  392. package/dist/types/config/defineEnv.d.ts +170 -0
  393. package/dist/types/config/envExample.d.ts +23 -0
  394. package/dist/types/config/envOverride.d.ts +236 -0
  395. package/dist/types/config/index.d.ts +23 -0
  396. package/dist/types/config/infra.d.ts +171 -0
  397. package/dist/types/config/reactivity.d.ts +36 -0
  398. package/dist/types/config/reservedEnv.d.ts +145 -0
  399. package/dist/types/config/schema.d.ts +113 -0
  400. package/dist/types/config/types.d.ts +374 -0
  401. package/dist/types/config/use.d.ts +80 -0
  402. package/dist/types/finder/File.d.ts +26 -0
  403. package/dist/types/finder/FileResult.d.ts +14 -0
  404. package/dist/types/finder/Finder.d.ts +51 -0
  405. package/dist/types/finder/Result.d.ts +10 -0
  406. package/dist/types/index.d.ts +205 -0
  407. package/dist/types/kernel/BootConfigurationError.d.ts +50 -0
  408. package/dist/types/kernel/CliKernel.d.ts +289 -0
  409. package/dist/types/kernel/Kernel.d.ts +1255 -0
  410. package/dist/types/kernel/Module.d.ts +326 -0
  411. package/dist/types/kernel/adminPlane/adminCaller.d.ts +105 -0
  412. package/dist/types/kernel/adminPlane/adminRbac.d.ts +44 -0
  413. package/dist/types/kernel/adminPlane/catalog.d.ts +122 -0
  414. package/dist/types/kernel/adminPlane/executeAdmin.d.ts +99 -0
  415. package/dist/types/kernel/bootReport.d.ts +112 -0
  416. package/dist/types/kernel/checks/deep.d.ts +122 -0
  417. package/dist/types/kernel/checks/freshness.d.ts +49 -0
  418. package/dist/types/kernel/checks/gating.d.ts +134 -0
  419. package/dist/types/kernel/checks/guards.d.ts +57 -0
  420. package/dist/types/kernel/checks/lastBoot.d.ts +189 -0
  421. package/dist/types/kernel/checks/live.d.ts +110 -0
  422. package/dist/types/kernel/checks/packageDeps.d.ts +44 -0
  423. package/dist/types/kernel/checks/readiness.d.ts +97 -0
  424. package/dist/types/kernel/checks/renderReport.d.ts +107 -0
  425. package/dist/types/kernel/checks/report.d.ts +414 -0
  426. package/dist/types/kernel/checks/runDoctor.d.ts +361 -0
  427. package/dist/types/kernel/checks/surface.d.ts +148 -0
  428. package/dist/types/kernel/checks/walk.d.ts +45 -0
  429. package/dist/types/kernel/checks/wiring.d.ts +54 -0
  430. package/dist/types/kernel/commands/AiMcpCommand.d.ts +39 -0
  431. package/dist/types/kernel/commands/AiSyncCommand.d.ts +28 -0
  432. package/dist/types/kernel/commands/BuildCommand.d.ts +13 -0
  433. package/dist/types/kernel/commands/CardCommand.d.ts +34 -0
  434. package/dist/types/kernel/commands/ClusterCommand.d.ts +29 -0
  435. package/dist/types/kernel/commands/CompletionCommand.d.ts +17 -0
  436. package/dist/types/kernel/commands/CreateCommand.d.ts +16 -0
  437. package/dist/types/kernel/commands/DevCommand.d.ts +40 -0
  438. package/dist/types/kernel/commands/DoctorCommand.d.ts +55 -0
  439. package/dist/types/kernel/commands/EnvCommand.d.ts +35 -0
  440. package/dist/types/kernel/commands/GitHooksCommand.d.ts +27 -0
  441. package/dist/types/kernel/commands/InspectCommand.d.ts +59 -0
  442. package/dist/types/kernel/commands/InstallCommand.d.ts +7 -0
  443. package/dist/types/kernel/commands/MenuCommand.d.ts +58 -0
  444. package/dist/types/kernel/commands/OutdatedCommand.d.ts +47 -0
  445. package/dist/types/kernel/commands/ProdCommand.d.ts +29 -0
  446. package/dist/types/kernel/commands/StatusCommand.d.ts +17 -0
  447. package/dist/types/kernel/commands/StopCommand.d.ts +17 -0
  448. package/dist/types/kernel/commands/SymbolsCommand.d.ts +29 -0
  449. package/dist/types/kernel/commands/runtimeLauncher.d.ts +76 -0
  450. package/dist/types/kernel/decorators/kernelDecorator.d.ts +76 -0
  451. package/dist/types/kernel/injector/injector.d.ts +47 -0
  452. package/dist/types/kernel/injector/serviceOrder.d.ts +29 -0
  453. package/dist/types/kernel/inspect/adminSubjects.d.ts +169 -0
  454. package/dist/types/kernel/inspect/docOutline.d.ts +53 -0
  455. package/dist/types/kernel/lifecycleTags.d.ts +79 -0
  456. package/dist/types/kernel/moduleConfig.d.ts +35 -0
  457. package/dist/types/kernel/moduleGating.d.ts +78 -0
  458. package/dist/types/kernel/readinessRegistry.d.ts +104 -0
  459. package/dist/types/kernel/resolveModuleEntry.d.ts +46 -0
  460. package/dist/types/mcp/caller.d.ts +55 -0
  461. package/dist/types/mcp/guard.d.ts +66 -0
  462. package/dist/types/mcp/protocol.d.ts +163 -0
  463. package/dist/types/mcp/server.d.ts +70 -0
  464. package/dist/types/mcp/tools.d.ts +209 -0
  465. package/dist/types/oauth/authorizationServer.d.ts +204 -0
  466. package/dist/types/oauth/protectedResource.d.ts +339 -0
  467. package/dist/types/realtime/IRealtimeSocket.d.ts +142 -0
  468. package/dist/types/realtime/IRealtimeTransport.d.ts +50 -0
  469. package/dist/types/realtime/JsonRpcPeer.d.ts +251 -0
  470. package/dist/types/realtime/RealtimeEventMap.d.ts +269 -0
  471. package/dist/types/realtime/channelRate.d.ts +55 -0
  472. package/dist/types/realtime/platformChannels.d.ts +147 -0
  473. package/dist/types/runtime/GcScheduler.d.ts +96 -0
  474. package/dist/types/runtime/RequestContext.d.ts +152 -0
  475. package/dist/types/runtime/bearer.d.ts +88 -0
  476. package/dist/types/runtime/engineEnvironment.d.ts +115 -0
  477. package/dist/types/runtime/loadEnv.d.ts +86 -0
  478. package/dist/types/runtime/pageFacets.d.ts +104 -0
  479. package/dist/types/runtime/pageFilters.d.ts +139 -0
  480. package/dist/types/runtime/pageGuard.d.ts +78 -0
  481. package/dist/types/runtime/pageQuery.d.ts +138 -0
  482. package/dist/types/runtime/pageSort.d.ts +86 -0
  483. package/dist/types/runtime/redact.d.ts +27 -0
  484. package/dist/types/runtime/withTimeout.d.ts +51 -0
  485. package/dist/types/service/cluster/ClusterManager.d.ts +112 -0
  486. package/dist/types/service/cluster/ClusterProbeAggregator.d.ts +68 -0
  487. package/dist/types/service/cluster/ClusterRelay.d.ts +57 -0
  488. package/dist/types/service/cluster/clusterMaster.d.ts +40 -0
  489. package/dist/types/service/cluster/clusterMessage.d.ts +94 -0
  490. package/dist/types/service/cluster/cpuQuota.d.ts +37 -0
  491. package/dist/types/service/cluster/instanceProbe.d.ts +82 -0
  492. package/dist/types/service/cluster/podEnvironment.d.ts +35 -0
  493. package/dist/types/service/cluster/processProbe.d.ts +53 -0
  494. package/dist/types/service/cluster/richProcessProbe.d.ts +77 -0
  495. package/dist/types/service/cluster/topology.d.ts +64 -0
  496. package/dist/types/service/dev/BootReporter.d.ts +67 -0
  497. package/dist/types/service/dev/DevSupervisor.d.ts +117 -0
  498. package/dist/types/service/dev/bootVerdict.d.ts +99 -0
  499. package/dist/types/service/dev/detachedStart.d.ts +164 -0
  500. package/dist/types/service/dev/devProcess.d.ts +638 -0
  501. package/dist/types/service/dev/devProjects.d.ts +121 -0
  502. package/dist/types/service/dev/devStatusReport.d.ts +141 -0
  503. package/dist/types/service/dev/devStop.d.ts +57 -0
  504. package/dist/types/service/fetchService.d.ts +29 -0
  505. package/dist/types/service/gitService.d.ts +24 -0
  506. package/dist/types/syslog/Pdu.d.ts +134 -0
  507. package/dist/types/syslog/Syslog.d.ts +482 -0
  508. package/dist/types/syslog/drivers/ClusterFileLogDriver.d.ts +40 -0
  509. package/dist/types/syslog/drivers/FileLogDriver.d.ts +55 -0
  510. package/dist/types/syslog/drivers/ILogDriver.d.ts +177 -0
  511. package/dist/types/syslog/drivers/LokiLogDriver.d.ts +44 -0
  512. package/dist/types/syslog/drivers/MemoryLogDriver.d.ts +20 -0
  513. package/dist/types/syslog/drivers/OpenSearchLogDriver.d.ts +40 -0
  514. package/dist/types/syslog/drivers/builtinLogDrivers.d.ts +43 -0
  515. package/dist/types/syslog/drivers/filterPdus.d.ts +21 -0
  516. package/dist/types/syslog/drivers/logDriverRegistry.d.ts +100 -0
  517. package/dist/types/syslog/drivers/opensearchShared.d.ts +11 -0
  518. package/dist/types/syslog/drivers/pduFlow.d.ts +53 -0
  519. package/dist/types/syslog/drivers/pduProtocol.d.ts +20 -0
  520. package/dist/types/syslog/httpFetch.d.ts +48 -0
  521. package/dist/types/syslog/logColor.d.ts +59 -0
  522. package/dist/types/syslog/sinks/FileSink.d.ts +78 -0
  523. package/dist/types/syslog/transports/BatchingHttpTransport.d.ts +59 -0
  524. package/dist/types/syslog/transports/ConsoleTransport.d.ts +8 -0
  525. package/dist/types/syslog/transports/FileTransport.d.ts +13 -0
  526. package/dist/types/syslog/transports/HttpTransport.d.ts +15 -0
  527. package/dist/types/syslog/transports/LokiTransport.d.ts +45 -0
  528. package/dist/types/syslog/transports/OpenSearchTransport.d.ts +40 -0
  529. package/dist/types/syslog/transports/SyslogTransport.d.ts +9 -0
  530. package/dist/types/syslog/transports/index.d.ts +12 -0
  531. package/dist/types/testing/index.d.ts +197 -0
  532. package/dist/types/types/IAdminApi.d.ts +246 -0
  533. package/dist/types/types/ICliKernel.d.ts +28 -0
  534. package/dist/types/types/ICommand.d.ts +14 -0
  535. package/dist/types/types/IContainer.d.ts +35 -0
  536. package/dist/types/types/IIdempotencyStore.d.ts +159 -0
  537. package/dist/types/types/IKernel.d.ts +138 -0
  538. package/dist/types/types/IMcpTool.d.ts +157 -0
  539. package/dist/types/types/IModule.d.ts +73 -0
  540. package/dist/types/types/IModuleManifest.d.ts +49 -0
  541. package/dist/types/types/IPage.d.ts +119 -0
  542. package/dist/types/types/IService.d.ts +62 -0
  543. package/dist/types/types/ISyslog.d.ts +58 -0
  544. package/dist/types/types/ITransport.d.ts +5 -0
  545. package/dist/types/types/globals.d.ts +47 -0
  546. package/docs/angular-services.md +318 -0
  547. package/docs/catalogue.md +184 -0
  548. package/docs/cli.md +369 -0
  549. package/docs/client.md +616 -0
  550. package/docs/debugbar.md +218 -0
  551. package/docs/environnement.md +308 -0
  552. package/docs/index.md +388 -0
  553. package/docs/kernel.md +670 -0
  554. package/docs/progression.md +228 -0
  555. package/docs/react-hooks.md +686 -0
  556. package/docs/request-context.md +507 -0
  557. package/docs/service.md +590 -0
  558. package/docs/svelte-reactivite.md +293 -0
  559. package/docs/syslog.md +848 -0
  560. package/docs/testing.md +203 -0
  561. package/docs/vue-composables.md +255 -0
  562. package/man/nodefony.1 +152 -0
  563. package/package.json +163 -83
  564. package/templates/app/agents/AGENTS.md.tpl +967 -0
  565. package/templates/app/agents/POINTEUR.md.tpl +12 -0
  566. package/templates/app/base/Dockerfile.tpl +104 -0
  567. package/templates/app/base/README.md.tpl +314 -0
  568. package/templates/app/base/dockerignore.tpl +28 -0
  569. package/templates/app/base/env.ts.tpl +130 -0
  570. package/templates/app/base/gitattributes.tpl +28 -0
  571. package/templates/app/base/github/workflows/ci.yml.tpl +91 -0
  572. package/templates/app/base/gitignore.tpl +46 -0
  573. package/templates/app/base/gitlab-ci.yml.tpl +42 -0
  574. package/templates/app/base/index.ts.tpl +69 -0
  575. package/templates/app/base/nodefony.config.ts.tpl +342 -0
  576. package/templates/app/base/oxlintrc.json.tpl +127 -0
  577. package/templates/app/base/package.json.tpl +75 -0
  578. package/templates/app/base/prettierignore.tpl +24 -0
  579. package/templates/app/base/prettierrc.json.tpl +12 -0
  580. package/templates/app/base/rolldown.config.ts.tpl +8 -0
  581. package/templates/app/base/tests/config.test.ts.tpl +29 -0
  582. package/templates/app/base/tests/e2e.setup.ts.tpl +181 -0
  583. package/templates/app/base/tests/e2e.test.ts.tpl +105 -0
  584. package/templates/app/base/tests/migrations.e2e.test.ts.tpl +579 -0
  585. package/templates/app/base/tsconfig.json.tpl +47 -0
  586. package/templates/app/base/vitest.config.ts.tpl +88 -0
  587. package/templates/app/base/vitest.e2e.config.ts.tpl +39 -0
  588. package/templates/app/complete/compose.yaml.tpl +328 -0
  589. package/templates/app/complete/deploy/migrate-job.yaml.tpl +100 -0
  590. package/templates/app/complete/docker/db/init-nodefony-e2e.sql.tpl +30 -0
  591. package/templates/app/complete/docker/grafana/provisioning/datasources/loki.yaml.tpl +15 -0
  592. package/templates/app/complete/env.local.tpl +11 -0
  593. package/templates/app/complete/env.tpl +53 -0
  594. package/templates/app/complete/nodefony/entity/User.ts.tpl +69 -0
  595. package/templates/app/complete/nodefony/security/provisionUsers.ts.tpl +124 -0
  596. package/templates/app/complete/nodefony/service/AppBannerService.ts.tpl +98 -0
  597. package/templates/app/complete/nodefony/service/AppInfoService.ts.tpl +85 -0
  598. package/templates/app/frontend/angular/frontend/src/accent.css.tpl +34 -0
  599. package/templates/app/frontend/angular/frontend/src/app/app.component.ts.tpl +400 -0
  600. package/templates/app/frontend/react/frontend/src/App.tsx.tpl +421 -0
  601. package/templates/app/frontend/react/frontend/src/accent.css.tpl +30 -0
  602. package/templates/app/frontend/shared/frontend/src/brand.ts.tpl +3 -0
  603. package/templates/app/frontend/shared/frontend/src/showcase.css.tpl +224 -0
  604. package/templates/app/frontend/shared/nodefony/controllers/AppController.ts.tpl +45 -0
  605. package/templates/app/frontend/svelte/frontend/src/App.svelte.tpl +371 -0
  606. package/templates/app/frontend/svelte/frontend/src/accent.css.tpl +34 -0
  607. package/templates/app/frontend/vue/frontend/src/App.vue.tpl +367 -0
  608. package/templates/app/frontend/vue/frontend/src/accent.css.tpl +34 -0
  609. package/templates/app/home/nodefony/controllers/HomeController.ts.tpl +38 -0
  610. package/templates/command/nodefony/command/__NAME__.ts.tpl +132 -0
  611. package/templates/controller/duplex/nodefony/controllers/__NAME__.ts.tpl +188 -0
  612. package/templates/controller/example/nodefony/controllers/__NAME__.ts.tpl +348 -0
  613. package/templates/controller/hello/nodefony/controllers/__NAME__.ts.tpl +143 -0
  614. package/templates/controller/realtime/nodefony/controllers/__NAME__.ts.tpl +153 -0
  615. package/templates/controller/realtime/tests/__KEBAB__-realtime.test.ts.tpl +79 -0
  616. package/templates/controller/rest/nodefony/controllers/__NAME__.ts.tpl +159 -0
  617. package/templates/entity/base/nodefony/entity/__PASCAL__.schema.ts.tpl +31 -0
  618. package/templates/entity/base/nodefony/entity/__PASCAL__.ts.tpl +68 -0
  619. package/templates/entity/controller/nodefony/controllers/__PASCAL__Controller.ts.tpl +335 -0
  620. package/templates/entity/service/nodefony/service/__PASCAL__Service.ts.tpl +126 -0
  621. package/templates/entity/tests/tests/__KEBAB__.e2e.test.ts.tpl +358 -0
  622. package/templates/entity/tests/tests/__KEBAB__.test.ts.tpl +87 -0
  623. package/templates/front/angular/frontend/src/app/app.component.ts.tpl +30 -0
  624. package/templates/front/base/nodefony/controllers/__NAME__.ts.tpl +60 -0
  625. package/templates/front/react/frontend/src/App.tsx.tpl +26 -0
  626. package/templates/front/svelte/frontend/src/App.svelte.tpl +19 -0
  627. package/templates/front/vue/frontend/src/App.vue.tpl +23 -0
  628. package/templates/module/ai/AGENTS.md.tpl +71 -0
  629. package/templates/module/base/README.md.tpl +62 -0
  630. package/templates/module/base/docs/index.md.tpl +55 -0
  631. package/templates/module/base/index.ts.tpl +50 -0
  632. package/templates/module/base/nodefony/config/config.ts.tpl +60 -0
  633. package/templates/module/base/nodefony/config/defineModuleConfig.ts.tpl +55 -0
  634. package/templates/module/base/nodefony/src/errors/__PASCAL__Error.ts.tpl +20 -0
  635. package/templates/module/base/package.json.tpl +53 -0
  636. package/templates/module/base/rolldown.config.ts.tpl +14 -0
  637. package/templates/module/base/tests/__KEBAB__.test.ts.tpl +39 -0
  638. package/templates/module/base/tsconfig.json.tpl +42 -0
  639. package/templates/module/base/vitest.config.ts.tpl +27 -0
  640. package/templates/module/packages/CLAUDE.md.tpl +51 -0
  641. package/templates/module/packages/MEMORY.md.tpl +39 -0
  642. package/templates/module/packages/tsconfig.declarations.json.tpl +19 -0
  643. package/templates/module/packages/tsconfig.tests.json.tpl +11 -0
  644. package/templates/module/service/nodefony/interfaces/I__PASCAL__Service.ts.tpl +14 -0
  645. package/templates/module/service/nodefony/interfaces/index.ts.tpl +1 -0
  646. package/templates/module/service/nodefony/service/__PASCAL__Service.ts.tpl +116 -0
  647. package/templates/service/nodefony/interfaces/I__PASCAL__Service.ts.tpl +19 -0
  648. package/templates/service/nodefony/service/__PASCAL__Service.ts.tpl +136 -0
  649. package/templates/service/tests/__PASCAL__Service.test.ts.tpl +53 -0
  650. package/templates/shared/front-entry/angular/frontend/src/main.ts.tpl +17 -0
  651. package/templates/shared/front-entry/react/frontend/src/main.tsx.tpl +11 -0
  652. package/templates/shared/front-entry/svelte/frontend/src/main.ts.tpl +13 -0
  653. package/templates/shared/front-entry/vue/frontend/src/main.ts.tpl +12 -0
  654. package/templates/shared/front-registrar/nodefony/frontend/register__PASCAL__Entry.ts.tpl +40 -0
  655. package/templates/shared/front-shell/frontend/index.html.tpl +39 -0
  656. package/templates/shared/ng-app-tsconfig/frontend/tsconfig.app.json.tpl +18 -0
  657. package/templates/shared/svelte-shim/frontend/src/env.d.ts.tpl +12 -0
  658. package/templates/shared/vue-shim/frontend/src/env.d.ts.tpl +15 -0
  659. package/.yarnclean +0 -45
  660. package/CHANGELOG.md +0 -406
  661. package/autoloader.es6 +0 -253
  662. package/builder.es6 +0 -366
  663. package/cli/builder/bundles/bundle.js +0 -328
  664. package/cli/builder/bundles/controller.js +0 -73
  665. package/cli/builder/bundles/users-bundle/.yarnclean +0 -45
  666. package/cli/builder/bundles/users-bundle/Command/fixtureTask.js +0 -47
  667. package/cli/builder/bundles/users-bundle/Command/usersCommand.js +0 -105
  668. package/cli/builder/bundles/users-bundle/Entity/mongoose/userEntity.js +0 -168
  669. package/cli/builder/bundles/users-bundle/Entity/sequelize/userEntity.js +0 -231
  670. package/cli/builder/bundles/users-bundle/Fixtures/users.js +0 -117
  671. package/cli/builder/bundles/users-bundle/Fixtures/usersFixtures.js +0 -114
  672. package/cli/builder/bundles/users-bundle/Resources/config/config.js +0 -90
  673. package/cli/builder/bundles/users-bundle/Resources/config/routing.js +0 -17
  674. package/cli/builder/bundles/users-bundle/Resources/config/security.js +0 -96
  675. package/cli/builder/bundles/users-bundle/Resources/config/services.js +0 -7
  676. package/cli/builder/bundles/users-bundle/Resources/config/webpack/webpack.dev.config.js +0 -13
  677. package/cli/builder/bundles/users-bundle/Resources/config/webpack/webpack.prod.config.js +0 -31
  678. package/cli/builder/bundles/users-bundle/Resources/config/webpack.config.js +0 -146
  679. package/cli/builder/bundles/users-bundle/Resources/js/users.js +0 -153
  680. package/cli/builder/bundles/users-bundle/Resources/public/favicon.ico +0 -0
  681. package/cli/builder/bundles/users-bundle/Resources/public/images/users-logo.png +0 -0
  682. package/cli/builder/bundles/users-bundle/Resources/scss/awesome/font-awesome.config.js +0 -11
  683. package/cli/builder/bundles/users-bundle/Resources/scss/custom.scss +0 -23
  684. package/cli/builder/bundles/users-bundle/Resources/scss/users.scss +0 -59
  685. package/cli/builder/bundles/users-bundle/Resources/swagger/openapi/login.js +0 -235
  686. package/cli/builder/bundles/users-bundle/Resources/swagger/openapi/users.js +0 -232
  687. package/cli/builder/bundles/users-bundle/Resources/translations/login.en_en.yml +0 -14
  688. package/cli/builder/bundles/users-bundle/Resources/translations/login.fr_fr.yml +0 -14
  689. package/cli/builder/bundles/users-bundle/Resources/translations/users.en_en.yml +0 -35
  690. package/cli/builder/bundles/users-bundle/Resources/translations/users.fr_fr.yml +0 -36
  691. package/cli/builder/bundles/users-bundle/Resources/views/base.html.twig +0 -32
  692. package/cli/builder/bundles/users-bundle/Resources/views/footer.html.twig +0 -7
  693. package/cli/builder/bundles/users-bundle/Resources/views/header.html.twig +0 -90
  694. package/cli/builder/bundles/users-bundle/Resources/views/login/login.html.twig +0 -43
  695. package/cli/builder/bundles/users-bundle/Resources/views/users/createUser.html.twig +0 -296
  696. package/cli/builder/bundles/users-bundle/Resources/views/users/readUsers.html.twig +0 -94
  697. package/cli/builder/bundles/users-bundle/controller/api/graphql/graphqlController.js +0 -56
  698. package/cli/builder/bundles/users-bundle/controller/api/graphql/userResolver.js +0 -121
  699. package/cli/builder/bundles/users-bundle/controller/api/graphql/usertype.js +0 -58
  700. package/cli/builder/bundles/users-bundle/controller/api/openapi/loginApiController.js +0 -210
  701. package/cli/builder/bundles/users-bundle/controller/api/openapi/restUserController.js +0 -244
  702. package/cli/builder/bundles/users-bundle/controller/loginController.js +0 -91
  703. package/cli/builder/bundles/users-bundle/controller/usersController.js +0 -332
  704. package/cli/builder/bundles/users-bundle/package.json +0 -58
  705. package/cli/builder/bundles/users-bundle/readme.md +0 -360
  706. package/cli/builder/bundles/users-bundle/services/usersService.js +0 -411
  707. package/cli/builder/bundles/users-bundle/src/providers/mongoose/userProvider.js +0 -47
  708. package/cli/builder/bundles/users-bundle/src/providers/sequelize/userProvider.js +0 -48
  709. package/cli/builder/bundles/users-bundle/tests/loginTest.js +0 -182
  710. package/cli/builder/bundles/users-bundle/usersBundle.js +0 -26
  711. package/cli/builder/microService/microService.js +0 -261
  712. package/cli/builder/microService/skeletons/.editorconfig +0 -18
  713. package/cli/builder/microService/skeletons/.env-cmdrc.js +0 -32
  714. package/cli/builder/microService/skeletons/.jshintrc +0 -37
  715. package/cli/builder/microService/skeletons/README.md +0 -117
  716. package/cli/builder/microService/skeletons/bin/bash/hello.sh +0 -5
  717. package/cli/builder/microService/skeletons/bin/cli +0 -13
  718. package/cli/builder/microService/skeletons/bin/python/hello.py +0 -20
  719. package/cli/builder/microService/skeletons/config/config.js +0 -29
  720. package/cli/builder/microService/skeletons/config/pm2.config.js +0 -72
  721. package/cli/builder/microService/skeletons/config/webpack/webpack.config.dev.js +0 -8
  722. package/cli/builder/microService/skeletons/config/webpack/webpack.config.prod.js +0 -25
  723. package/cli/builder/microService/skeletons/config/webpack.config.js +0 -114
  724. package/cli/builder/microService/skeletons/package.json +0 -76
  725. package/cli/builder/microService/skeletons/src/browser/index.css +0 -3
  726. package/cli/builder/microService/skeletons/src/browser/index.js +0 -16
  727. package/cli/builder/microService/skeletons/src/browser/socketio.js +0 -46
  728. package/cli/builder/microService/skeletons/src/cli/cli.js +0 -224
  729. package/cli/builder/microService/skeletons/src/cli/menu.js +0 -28
  730. package/cli/builder/microService/skeletons/src/n-api/README.md +0 -1
  731. package/cli/builder/microService/skeletons/src/n-api/binding.gyp +0 -14
  732. package/cli/builder/microService/skeletons/src/n-api/hello.cc +0 -14
  733. package/cli/builder/microService/skeletons/src/n-api/hello.js +0 -23
  734. package/cli/builder/microService/skeletons/src/n-api/package.json +0 -15
  735. package/cli/builder/microService/skeletons/src/node/examples/index.js +0 -120
  736. package/cli/builder/microService/skeletons/src/node/index.js +0 -102
  737. package/cli/builder/microService/skeletons/src/node/services/markdown/markdown.js +0 -27
  738. package/cli/builder/microService/skeletons/src/node/services/servers/http.js +0 -45
  739. package/cli/builder/microService/skeletons/src/node/services/servers/https.js +0 -44
  740. package/cli/builder/microService/skeletons/src/node/services/socketio/socketio.js +0 -46
  741. package/cli/builder/microService/skeletons/src/node/services/syscall/syscall.js +0 -111
  742. package/cli/builder/microService/skeletons/src/node/services/worker/thread.js +0 -59
  743. package/cli/builder/microService/skeletons/src/node/services/worker/worker.js +0 -60
  744. package/cli/builder/microService/skeletons/src/templates/base.html +0 -12
  745. package/cli/builder/microService/skeletons/src/templates/socket.html +0 -23
  746. package/cli/builder/microService/skeletons/tests/unit/serviceTest.js +0 -30
  747. package/cli/builder/project/project.js +0 -474
  748. package/cli/builder/project/skeletons/README.md +0 -778
  749. package/cli/builder/project/skeletons/bin/dev-deploy.sh +0 -5
  750. package/cli/builder/project/skeletons/bin/generateCertificates.sh.skeleton +0 -180
  751. package/cli/builder/project/skeletons/bin/prod-deploy.sh +0 -3
  752. package/cli/builder/project/skeletons/config/config.js.skeleton +0 -178
  753. package/cli/builder/project/skeletons/config/openssl/ca/openssl.cnf.skeleton +0 -150
  754. package/cli/builder/project/skeletons/config/openssl/ca_intermediate/openssl.cnf.skeleton +0 -152
  755. package/cli/builder/project/skeletons/config/pm2.config.js.skeleton +0 -62
  756. package/cli/builder/project/skeletons/documentation.html.twig +0 -24
  757. package/cli/builder/project/skeletons/editorconfig.skeleton +0 -18
  758. package/cli/builder/project/skeletons/eslintignore.skeleton +0 -15
  759. package/cli/builder/project/skeletons/eslintrc.js.skeleton +0 -97
  760. package/cli/builder/project/skeletons/gitignore.skeleton +0 -32
  761. package/cli/builder/project/skeletons/migrations/2022.12.25T17.37.37.entity-user.js +0 -137
  762. package/cli/builder/project/skeletons/migrations/2022.12.25T17.37.38.entity-session.js +0 -97
  763. package/cli/builder/project/skeletons/migrations/2022.12.25T17.37.39.entity-requests.js +0 -115
  764. package/cli/builder/project/skeletons/migrations/2022.12.25T17.37.40.entity-jwts.js +0 -97
  765. package/cli/builder/project/skeletons/migrations/migrations.skeleton.js +0 -101
  766. package/cli/builder/project/skeletons/package.json.twig +0 -71
  767. package/cli/builder/react/reactBuilder.js +0 -224
  768. package/cli/builder/react/skeletons/app/Resources/databases/nodefony.db +0 -0
  769. package/cli/builder/react/skeletons/app/Resources/translations/messages.en_en.yml +0 -5
  770. package/cli/builder/react/skeletons/app/Resources/translations/messages.fr_fr.yml +0 -5
  771. package/cli/builder/react/skeletons/app/Resources/views/base.html.twig +0 -33
  772. package/cli/builder/react/skeletons/app/config/config.js +0 -392
  773. package/cli/builder/react/skeletons/app/config/routing.js +0 -10
  774. package/cli/builder/react/skeletons/app/config/security.js +0 -74
  775. package/cli/builder/react/skeletons/app/controller/appController.js +0 -22
  776. package/cli/builder/sandbox/sandBoxBuilder.js +0 -610
  777. package/cli/builder/sandbox/skeletons/Resources/css/entry.css +0 -48
  778. package/cli/builder/sandbox/skeletons/Resources/js/entry.js +0 -60
  779. package/cli/builder/sandbox/skeletons/Resources/public/manifest.json +0 -32
  780. package/cli/builder/sandbox/skeletons/Resources/translations/messages.en_en.yml +0 -5
  781. package/cli/builder/sandbox/skeletons/Resources/translations/messages.fr_fr.yml +0 -5
  782. package/cli/builder/sandbox/skeletons/Resources/views/base.html.twig +0 -46
  783. package/cli/builder/sandbox/skeletons/Resources/views/index.html.twig +0 -34
  784. package/cli/builder/sandbox/skeletons/bootstrap/custom.scss +0 -27
  785. package/cli/builder/sandbox/skeletons/bootstrap/entry.scss +0 -60
  786. package/cli/builder/sandbox/skeletons/workbox/templates/index.html.twig +0 -32
  787. package/cli/builder/sandbox/skeletons/workbox/workers/service-worker.js +0 -196
  788. package/cli/builder/skeletons/Resources/public/favicon.ico +0 -0
  789. package/cli/builder/skeletons/Resources/public/images/app-logo.png +0 -0
  790. package/cli/builder/skeletons/Resources/views/framework-bundle/views/401.html.twig +0 -1
  791. package/cli/builder/skeletons/Resources/views/framework-bundle/views/401.json.twig +0 -24
  792. package/cli/builder/skeletons/Resources/views/framework-bundle/views/403.html.twig +0 -1
  793. package/cli/builder/skeletons/Resources/views/framework-bundle/views/403.json.twig +0 -20
  794. package/cli/builder/skeletons/Resources/views/framework-bundle/views/404.html.twig +0 -1
  795. package/cli/builder/skeletons/Resources/views/framework-bundle/views/404.json.twig +0 -20
  796. package/cli/builder/skeletons/Resources/views/framework-bundle/views/500.html.twig +0 -1
  797. package/cli/builder/skeletons/Resources/views/framework-bundle/views/base.html.twig +0 -30
  798. package/cli/builder/skeletons/Resources/views/framework-bundle/views/exception.html.twig +0 -1
  799. package/cli/builder/skeletons/Resources/views/framework-bundle/views/exception.json.twig +0 -24
  800. package/cli/builder/skeletons/Resources/views/framework-bundle/views/footer.html.twig +0 -33
  801. package/cli/builder/skeletons/Resources/views/framework-bundle/views/header.html.twig +0 -6
  802. package/cli/builder/skeletons/Resources/views/framework-bundle/views/index.html.twig +0 -6
  803. package/cli/builder/skeletons/Resources/views/framework-bundle/views/index.json.twig +0 -1
  804. package/cli/builder/skeletons/Resources/views/framework-bundle/views/layout.html.twig +0 -125
  805. package/cli/builder/skeletons/Resources/views/framework-bundle/views/layout.json.twig +0 -5
  806. package/cli/builder/skeletons/Resources/views/framework-bundle/views/timeout.html.twig +0 -1
  807. package/cli/builder/skeletons/Resources/views/framework-bundle/views/timeout.json.twig +0 -24
  808. package/cli/builder/skeletons/app/appKernel.js +0 -133
  809. package/cli/builder/skeletons/binding/binding.cc +0 -26
  810. package/cli/builder/skeletons/binding/binding.skeleton +0 -8
  811. package/cli/builder/skeletons/bundle/bundleClass.js +0 -37
  812. package/cli/builder/skeletons/command/commandClass.js +0 -11
  813. package/cli/builder/skeletons/command/taskClass.js +0 -20
  814. package/cli/builder/skeletons/config/config.js +0 -138
  815. package/cli/builder/skeletons/config/nodefony/elastic-bundle.js +0 -37
  816. package/cli/builder/skeletons/config/nodefony/framework-bundle.js +0 -22
  817. package/cli/builder/skeletons/config/nodefony/http-bundle.js +0 -104
  818. package/cli/builder/skeletons/config/nodefony/mail-bundle.js +0 -44
  819. package/cli/builder/skeletons/config/nodefony/mongoose-bundle.js +0 -51
  820. package/cli/builder/skeletons/config/nodefony/monitoring-bundle.js +0 -34
  821. package/cli/builder/skeletons/config/nodefony/realtime-bundle.js +0 -15
  822. package/cli/builder/skeletons/config/nodefony/redis-bundle.js +0 -44
  823. package/cli/builder/skeletons/config/nodefony/security-bundle.js +0 -25
  824. package/cli/builder/skeletons/config/nodefony/sequelize-bundle.js +0 -156
  825. package/cli/builder/skeletons/config/routing.js +0 -55
  826. package/cli/builder/skeletons/config/security.js +0 -102
  827. package/cli/builder/skeletons/config/services.js +0 -1
  828. package/cli/builder/skeletons/config/webpack/webpack.dev.config.js +0 -13
  829. package/cli/builder/skeletons/config/webpack/webpack.prod.config.js +0 -20
  830. package/cli/builder/skeletons/config/webpack.config.js +0 -148
  831. package/cli/builder/skeletons/controller/controllerClass.js +0 -75
  832. package/cli/builder/skeletons/package.json.twig +0 -57
  833. package/cli/builder/skeletons/unittest/testFile.js +0 -46
  834. package/cli/builder/vue/skeletons/Resources/public/images/app-logo.png +0 -0
  835. package/cli/builder/vue/skeletons/Resources/translations/messages.en_en.yml +0 -5
  836. package/cli/builder/vue/skeletons/Resources/translations/messages.fr_fr.yml +0 -5
  837. package/cli/builder/vue/skeletons/vue.config.js +0 -129
  838. package/cli/builder/vue/vueBuilder.js +0 -410
  839. package/cli/generate/generate.es6 +0 -103
  840. package/cli/install/install.js +0 -190
  841. package/cli/sequelize/sequelize.js +0 -94
  842. package/cli/start.js +0 -702
  843. package/cli/tools/pm2.es6 +0 -112
  844. package/cli/tools/tools.es6 +0 -97
  845. package/cli.es6 +0 -925
  846. package/container.es6 +0 -272
  847. package/error.es6 +0 -293
  848. package/fileClass.es6 +0 -242
  849. package/finder/file.es6 +0 -33
  850. package/finder/fileResult.es6 +0 -138
  851. package/finder/finder2.es6 +0 -275
  852. package/finder.es6 +0 -427
  853. package/kernel/annotations/annotations.es6 +0 -286
  854. package/kernel/api/api.es6 +0 -61
  855. package/kernel/api/graphqlApi.es6 +0 -107
  856. package/kernel/api/jsonApi.es6 +0 -177
  857. package/kernel/api/openApi.es6 +0 -139
  858. package/kernel/api/schemas/openApiSchema.js +0 -394
  859. package/kernel/babylon.es6 +0 -162
  860. package/kernel/bundle.es6 +0 -1200
  861. package/kernel/cliKernel.es6 +0 -869
  862. package/kernel/command.es6 +0 -78
  863. package/kernel/commands/nodefonyCommand.es6 +0 -247
  864. package/kernel/commands/tasks/bundlesTask.es6 +0 -59
  865. package/kernel/controllers/controller.es6 +0 -791
  866. package/kernel/fixture.es6 +0 -19
  867. package/kernel/injections/injections.es6 +0 -424
  868. package/kernel/kernel.es6 +0 -1960
  869. package/kernel/kernelWatcher.es6 +0 -387
  870. package/kernel/orm/entity.es6 +0 -59
  871. package/kernel/orm/orm.es6 +0 -139
  872. package/kernel/reader.es6 +0 -290
  873. package/kernel/security/encoder.es6 +0 -17
  874. package/kernel/security/factories/factory.es6 +0 -111
  875. package/kernel/security/factories/passeportFactory.es6 +0 -61
  876. package/kernel/security/provider.es6 +0 -58
  877. package/kernel/security/providers/chainProvider.es6 +0 -99
  878. package/kernel/security/providers/memoryProvider.es6 +0 -55
  879. package/kernel/security/providers/providerManager.es6 +0 -67
  880. package/kernel/security/providers/userEntityProvider.es6 +0 -50
  881. package/kernel/security/role.es6 +0 -12
  882. package/kernel/security/secureArea.es6 +0 -431
  883. package/kernel/security/tokens/token.es6 +0 -171
  884. package/kernel/security/user.es6 +0 -106
  885. package/kernel/serviceRealTime.es6 +0 -21
  886. package/kernel/services/connectionsService.es6 +0 -93
  887. package/kernel/services/cron/cronService.es6 +0 -123
  888. package/kernel/task.es6 +0 -80
  889. package/kernel/templates.es6 +0 -22
  890. package/kernel/templating/twig.es6 +0 -218
  891. package/kernel/tests/cliTest.js +0 -59
  892. package/kernel/tests/containerTest.js +0 -232
  893. package/kernel/tests/kernelTest.js +0 -39
  894. package/nodefony.es6 +0 -1084
  895. package/notificationsCenter.es6 +0 -118
  896. package/protocol.es6 +0 -86
  897. package/protocols/bayeux.es6 +0 -174
  898. package/protocols/jsonRpc/jsonrpc.es6 +0 -56
  899. package/result.es6 +0 -99
  900. package/service.es6 +0 -288
  901. package/syslog/pdu.es6 +0 -141
  902. package/syslog/syslog.es6 +0 -754
  903. package/watcher.es6 +0 -113
@@ -0,0 +1,967 @@
1
+ # AGENTS.md — <%= it.appName %>
2
+
3
+ > **N'invente jamais du code Nodefony : génère-le, imite-le, vérifie-le.**
4
+ > Trois actes pour toute tâche : **LIRE** (ce fichier, puis la doc pointée) →
5
+ > **GÉNÉRER** (`npx nodefony create …` produit du vrai code, à imiter) →
6
+ > **VÉRIFIER** (`npm run verify` — UNE commande : types + lint + tests + câblage).
7
+ >
8
+ > **Le réflexe, avant d'écrire le MOINDRE fichier** : un générateur le
9
+ > produit-il ? Écrire à la main un CRUD, un controller, une entité ou un
10
+ > squelette de module, c'est le signal que tu as raté une commande de la
11
+ > table ci-dessous — arrête-toi et lance-la.
12
+ >
13
+ > **Tu RENDS une réponse ?** `return this.renderJson(obj)` pour du JSON ;
14
+ > `this.setContextHtml()` puis `return this.render(html)` pour une PAGE — le nonce
15
+ > CSP de la requête s'écrit **`this.context?.cspNonce`** (le `?.` n'est pas
16
+ > optionnel : `context` est `ContextType | undefined`, sans lui le code ne
17
+ > compile pas), à recopier dans tout `<script>` en ligne. Ne touche JAMAIS
18
+ > `this.response` à la main : poser `Content-Type` toi-même court-circuite la
19
+ > négociation, et un `this.response as any` est le signal que tu as raté la façade.
20
+ >
21
+ > **Tu LIS une liste ?** Elle se BORNE, toujours. Le service d'une entité hérite
22
+ > `findPage({ limit: 25 })` — il ne charge que `limit + 1` lignes et rend
23
+ > `{ items, hasNext }` ; sinon `find(criteria, { limit })`. Un `find` sans borne
24
+ > matérialise la table ENTIÈRE : indolore sur les quelques lignes du poste de
25
+ > développement, fatal sur les dizaines de milliers de la production. Il te faut
26
+ > une projection de colonnes, une CTE, une agrégation ? Descends au natif **avec
27
+ > son type** — `import type { DrizzleDb } from "@nodefony/drizzle"` puis
28
+ > `orm.getNativeConnection<DrizzleDb>()`. Sans le paramètre de type tu reçois
29
+ > `unknown`, et il ne te reste qu'un `as any` que le contrôle refuse.
30
+ >
31
+ > **Tu SERS un fichier ?** Trois façades, jamais `createReadStream` à la main :
32
+ > `this.renderMediaStream(f)` pour un média qu'on parcourt (`Range` → 206),
33
+ > `this.streamFile(f)` pour le fichier entier, `this.renderFileDownload(f)` pour
34
+ > forcer le téléchargement. Le faire soi-même rend une réponse que le client ne
35
+ > peut pas lire — le détail, plus bas, est MESURÉ.
36
+
37
+ ## Générateurs — appelle-les, ne recompose jamais leur sortie de mémoire
38
+
39
+ | Besoin | Commande |
40
+ | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
41
+ | Module applicatif (workspace npm) | `npx nodefony create module <nom>` |
42
+ | Controller HTTP **et** WebSocket (même classe) | `npx nodefony create controller <nom> --kind hello\|rest\|realtime\|duplex\|example` |
43
+ | Controller **réservé à une habilitation** — garde de classe + rôle déclaré dans la hiérarchie | `npx nodefony create controller <nom> --role ROLE_X` |
44
+ | Ressource REST **complète** — entité + service + controller CRUD + tests (ne JAMAIS l'écrire à la main) | `npx nodefony create entity <Nom> --fields "sku:string! price:float"` |
45
+ | Service métier seul — la logique réutilisable, hors de tout controller | `npx nodefony create service <Nom> [--inject <AutreService>] [--module <m>]` |
46
+ | Frontend Vite (React/Vue/Angular) | `npx nodefony create front <nom> [--module <m>]` |
47
+ | Commande CLI `nodefony <module>:<action>` | `npx nodefony create command <action> [--module <m>] [--phase onReady\|onRegister\|onPostReady]` |
48
+
49
+ **Ces dossiers ne s'écrivent JAMAIS à la main** — y déposer un fichier signifie
50
+ que tu as raté une commande de la table ci-dessus :
51
+
52
+ | Tu t'apprêtes à écrire dans… | Lance plutôt |
53
+ | -------------------------------- | ------------------------------------------------------------------------ |
54
+ | `nodefony/entity/` | `npx nodefony create entity <Nom> --fields "…"` |
55
+ | `nodefony/controllers/` | `npx nodefony create controller <nom> --kind …` |
56
+ | `nodefony/service/` | `npx nodefony create service <Nom>` (ou `create entity`, qui en pose un) |
57
+ | `nodefony/command/` | `npx nodefony create command <action> [--module <m>]` |
58
+ | `modules/<nom>/` (module entier) | `npx nodefony create module <nom>` |
59
+
60
+ Le code écrit à la main compile souvent — c'est tout le piège. Il diverge du
61
+ gabarit courant, et cette divergence ne se voit qu'à la première montée de
62
+ version. `npx nodefony create --help` liste les générateurs de CETTE version : la
63
+ liste s'allonge, ne te fie pas à ta mémoire.
64
+
65
+ Chaque commande se décrit à une machine : `--describe-json` (questions + options
66
+ en JSON), `--answers-json <fichier|->` (réponses en JSON), `--dry-run` (plan et
67
+ diffs, zéro écriture). Un refus n'écrit jamais rien (transaction).
68
+
69
+ Les champs d'une entité se déclarent en positionnels :
70
+ `npx nodefony create entity Post title:string! views:int=0 status:enum(draft,published) slug:string:index author:ref:User`.
71
+ Le `!` interdit le nul, le `?` l'autorise, `:index` pose l'index, `=<valeur>` fixe
72
+ la valeur par défaut, `enum(a,b)` borne les valeurs admises, et
73
+ `ref:<Entité>` crée la colonne de jointure **avec** son index. Les types portent
74
+ leur taille (`string(120)`, `char(2)`, `decimal(10,2)`). Un index de TABLE couvre
75
+ plusieurs colonnes et se répète : `--index "siteId,createdAt"`, `--unique "a,b"`.
76
+ Un `enum` rend la MÊME colonne sur les trois moteurs (pas de type SQL nommé, qui
77
+ exigerait une migration) : c'est le type TypeScript et le schéma Zod qui la
78
+ bornent — donc sur TOUS les transports, REST comme socket.
79
+
80
+ Si la table EXISTE DÉJÀ en base, trois options lui font épouser ses noms sans
81
+ rien renommer à la main : `--table <nom_sql>` (au lieu du pluriel),
82
+ `--column-case snake` (colonne `site_id`, propriété toujours `siteId`) et
83
+ `--id-name <colonne>` (clé primaire `website_id`, propriété toujours `id`). Le
84
+ code TypeScript ne change dans aucun des trois cas — seul le SQL suit.
85
+ `npx nodefony create entity --help` porte la grammaire de CETTE version — elle
86
+ s'enrichit, ta mémoire non.
87
+
88
+ ## Où lire AVANT de coder (tâche → doc installée)
89
+
90
+ La référence est INSTALLÉE avec les paquets — lis CIBLÉ, jamais tout le dossier.
91
+
92
+ > 🔎 **Une recherche ORDINAIRE ne voit pas cette documentation.** `rg "terme"`
93
+ > lancé à la racine ne descend pas dans `node_modules` (git l'ignore, `rg` le
94
+ > suit) : le sujet paraît absent alors qu'il occupe quinze pages. Trois gestes
95
+ > justes, du plus utile au plus brut :
96
+ >
97
+ > - **chercher partout, avec le sens** — si le serveur tourne et que l'outil MCP
98
+ > est câblé (`npx nodefony ai:mcp`), `nodefony_docs` avec `query` balaie TOUTE
99
+ > la documentation chargée et rend des extraits ; `nodefony_symbols` rend la
100
+ > SIGNATURE réelle d'un symbole, que le graphe seul ne porte pas ;
101
+ > - **désigner le dossier** — `rg "terme" node_modules/@nodefony/*/docs/` :
102
+ > l'exclusion ne vaut que pour le PARCOURS, un chemin donné en argument est
103
+ > toujours lu ;
104
+ > - **forcer l'inclusion** — `rg --no-ignore "terme"` pour un balayage large.
105
+ >
106
+ > ⚠️ **Si `node_modules/` n'existe pas, la documentation n'est pas là** — et
107
+ > aucun de ces gestes ne répondra. Ce n'est pas « le sujet n'est pas documenté » :
108
+ > c'est `npm install` qui n'a pas été lancé. DIS-LE plutôt que de conclure de son
109
+ > silence, et ne réécris jamais à la main ce que tu n'as pas pu lire.
110
+
111
+ - **Quel module installer pour tel besoin** (et lequel NE PAS installer) — `node_modules/nodefony/docs/catalogue.md`
112
+ - **Variables d'environnement** : cascade des `.env`, précédence, `NF__`, **et dans quel MODE tourne une commande** — `node_modules/nodefony/docs/environnement.md`
113
+ - **Kernel, cycle de vie, CLI** — `node_modules/nodefony/docs/kernel.md` + `cli.md`
114
+ - **Service, DI, container, scopes** — `node_modules/nodefony/docs/service.md`
115
+ - **Client isomorphe (navigateur), hooks React** — `node_modules/nodefony/docs/client.md` + `react-hooks.md`
116
+ - **Serveurs, sessions, cookies, upload, rate-limit** — `node_modules/@nodefony/http/docs/`
117
+ - **Recevoir un FICHIER** (formulaire multipart, `@UploadedFile`, où le ranger sans laisser le client choisir) — `node_modules/@nodefony/http/docs/upload.md`
118
+ - **Journaliser, corréler, tracer une requête** (identifiant de requête, trace) — `node_modules/@nodefony/http/docs/observabilite.md`
119
+ - **Routing, controllers, décorateurs, idempotence** — `node_modules/@nodefony/framework/docs/`
120
+ <% if (it.hasSecurity) { %>- **Firewall, authenticators, CSRF, CORS, clés d'API** — `node_modules/@nodefony/security/docs/firewall.md`
121
+ - **Protéger une action par un RÔLE** (`@IsGranted`), voters, hiérarchie — `node_modules/@nodefony/security/docs/authorization.md`
122
+ - **Le navigateur REFUSE d'exécuter ton script ou de charger une image** (politique de contenu, nonce, `Context.cspNonce`, HSTS, clickjacking) — `node_modules/@nodefony/security/docs/headers.md`
123
+ - **Utilisateurs** : contrat `IUser`, `UserService`, mot de passe — `node_modules/@nodefony/user/docs/index.md`
124
+ - **Notifier un système tiers** (webhook signé, rejeu, endpoints) — `node_modules/@nodefony/security/docs/webhooks.md`
125
+ <% } %><% if (it.hasOrm) { %>- **Entités, repositories, requêtes (ORM)** — `node_modules/@nodefony/orm-core/docs/`
126
+ - **Migrations de schéma** (générer, appliquer, ÉPROUVER sans risque, déployer, réparer) — charge d'abord le skill `nodefony-migrate-schema` ; le détail des verdicts vit dans `node_modules/@nodefony/drizzle/docs/migrations.md`
127
+ <% } %><% if (it.hasRealtime) { %>- **Canaux temps réel, actions, protocole WS** — `node_modules/@nodefony/realtime/docs/`
128
+ <% } %><% if (it.front) { %>- **Builder Vite, entries, HMR** — `node_modules/@nodefony/frontend/docs/`
129
+ <% } %><% if (it.hasStudio) { %>- **Console d'admin Studio (dev)** — `node_modules/@nodefony/studio/docs/` + http://127.0.0.1:5151/nodefony
130
+ <% } %>
131
+ La config de l'app vit dans `nodefony.config.ts` (modules chargés) et `env.ts`
132
+ (variables d'environnement, seul lecteur de `process.env`) — pointe-les, ne les
133
+ recopie pas.
134
+
135
+ **Des skills d'agent sont posés dans `.agents/skills/`** — la marche à suivre
136
+ complète pour les tâches courantes (`ls .agents/skills/` les liste ; leur
137
+ description dit quand chacun s'applique). Ce sont des **pointeurs** vers le
138
+ contenu installé dans `node_modules` : ils suivent la version du framework de CE
139
+ projet, et les éditer ne servirait à rien. Si ton outil ne charge que son propre
140
+ dossier de découverte, lis-les à la main — c'est le chemin le plus court vers la
141
+ bonne façade. `npx nodefony ai:sync` les remet à jour après un `npm update`
142
+ (`--dry-run` dit ce qui changerait).
143
+
144
+ **Les instructions que tu lis vivent dans `AGENTS.md`** — standard porté par
145
+ l'Agentic AI Foundation (Linux Foundation), précédence « le plus proche gagne ».
146
+ Les fichiers au nom d'un outil (`CLAUDE.md`, `GEMINI.md`) n'en sont que des
147
+ POINTEURS : ce qu'on y recopierait divergerait en silence. Deux agents lisent
148
+ `AGENTS.md` d'office (Codex, Vibe), deux ouvrent leur propre fichier.
149
+
150
+ **La porte d'introspection de cette application** (protocole MCP) se câble par
151
+ `npx nodefony ai:mcp` : elle écrit `.mcp.json` à la racine et, si tu le
152
+ demandes, déclare la porte chez tes agents **par leur propre CLI**. En mode
153
+ authentifié (`--auth`), l'en-tête porte `${NF_MCP_TOKEN}` — jamais le jeton
154
+ lui-même, que `npx nodefony security:token --write` émet à part. ⚠️ La porte est
155
+ une ROUTE : elle n'existe que serveur démarré, et un client MCP qui la trouve
156
+ éteinte la marque en échec pour toute sa session.
157
+
158
+ ## Les commandes de l'app — demande la liste, ne la devine pas
159
+
160
+ ```bash
161
+ npx nodefony --help # TOUTES les commandes, celles des modules installés comprises
162
+ npx nodefony <commande> --help # les options exactes de l'une d'elles
163
+ ```
164
+
165
+ La liste **dépend des modules installés** : elle n'est pas la même d'une app à
166
+ l'autre, et elle s'allonge dès que tu en ajoutes un. C'est pour ça qu'elle se
167
+ demande au lieu de se retenir.
168
+
169
+ **Toujours `npx`, jamais `nodefony` nu.** Le binaire vit dans les `node_modules`
170
+ de CETTE app, pas dans ton PATH : la forme nue rend un code 127 tant que rien
171
+ n'est installé globalement. Une installation globale existe bien
172
+ (`npm i -g nodefony`) — elle sert à créer une app HORS projet — et, dans un
173
+ projet, elle passe la main au binaire local (le projet gagne, comme `gradlew`).
174
+ Mais elle peut être plus ANCIENNE que celle de l'app : `npx` prend directement la
175
+ version que cette application a choisie, sans dépendre de ce qui traîne sur la
176
+ machine.
177
+
178
+ Celles qu'on n'invente pas — faute de savoir qu'elles existent :
179
+
180
+ - Mettre l'app derrière **nginx ou haproxy** — `npx nodefony proxy:generate <nginx|haproxy> [-o <fichier>] [-b <hôte>] [-l <port>] [--reencrypt]`
181
+ - **Servir les fichiers statiques depuis un CDN** — `npx nodefony assets:publish [-o <dossier>] [--clean] [--json]`
182
+ - **Certificat TLS de développement** — `npx nodefony http:certificates [-f] [-j]`
183
+ <% if (it.front) { %>- **Construire le front pour la production** — `npx nodefony frontend:build [-f]`
184
+ - **Où en est le serveur Vite** — `npx nodefony frontend:status [-j]`
185
+ <% } %><% if (it.hasSecurity) { %>- **Clés de chiffrement du firewall** — `npx nodefony security:secrets [-j] [-w]`
186
+ - Créer un compte **administrateur** — `npx nodefony security:user:add <identifiant> --admin`
187
+ <% } %><% if (it.hasOrm) { %>- **Écrire les migrations** des entités modifiées — `npx nodefony orm:generate [--name <nom>] [--custom]`
188
+ - **Appliquer les migrations** (verrou + historique) — `npx nodefony orm:migrate [-n|--dry-run] [--json]`
189
+ - **La base est-elle à jour ?** — `npx nodefony orm:migrate:status [--json]` — **0** = à jour, **1** = en retard : ta barrière de déploiement
190
+ - **Éprouver une migration SANS toucher à ta base** — `NF_MIGRATE_DATABASE_URL="sqlite:/tmp/essai.sqlite" npx nodefony orm:migrate` — migre AILLEURS ; c'est ainsi qu'on prouve qu'une migration s'applique, jamais en refaisant la base
191
+ - **Repartir d'une base vierge EN DÉVELOPPEMENT** — `npx nodefony orm:reset [-c <connecteur>] [-y]` — refusée partout ailleurs, et **elle DÉTRUIT les données** : ce n'est jamais la façon d'éprouver une migration, ni la réponse à une migration qui refuse
192
+ <% } %>- **Dépendances en retard (agrégées, pas le brut de npm)** — `npx nodefony outdated [-j] [-a]`
193
+ - **Cohérence du projet (classe non câblée, route qui répondra 404)** — `npx nodefony doctor [--json]` — depuis n'importe quel sous-dossier
194
+ - **Plusieurs processus, un cœur chacun** — `npx nodefony production -w <n>` · `npx nodefony cluster -w <n>`
195
+ - **Construire l'image de container** — `docker build -t <%= it.appName %> .` — le `Dockerfile` est DÉJÀ là, ne le réécris pas
196
+ <% if (it.hasMigrateRecipe) { %>- **Migrer le schéma avant un déploiement** — `deploy/migrate-job.yaml` est DÉJÀ rendu au nom de cette app (travail Kubernetes, même image, secret DDL séparé) — son mode d'emploi est en tête du fichier, ne le réécris pas
197
+ <% } %>
198
+ - **Complétion au TAB** — `source <(nodefony completion zsh)`
199
+
200
+ Ce tableau ne remplace pas `--help` : lui seul connaît les modules de CETTE app,
201
+ et il fait foi le jour où les deux divergent.
202
+
203
+ ## Vérités du framework (anti-préjugés — ce que tu crois savoir est faux ici)
204
+ <% if (it.hasSecurity) { %>
205
+ - **La PROVENANCE d'une requête n'est pas une PREUVE D'INTENTION — une mutation
206
+ exige `@CsrfProtect`.** Le raisonnement qui vient, et qui est faux : « le
207
+ firewall vérifie déjà `Sec-Fetch-Site`, donc une écriture est protégée ». Ces
208
+ en-têtes sont posés par un NAVIGATEUR ; un programme qui parle en HTTP n'en
209
+ envoie aucun, et la défense de provenance le laisse alors passer — c'est son
210
+ rôle, elle distingue les sites, pas les intentions. Résultat mesuré : un
211
+ `POST /api/cart/items` sans jeton rend `201`, et l'application croit avoir une
212
+ défense. Toute action qui ÉCRIT porte donc `@CsrfProtect` explicitement. Le
213
+ jeton ne se demande à AUCUN endpoint : une requête sûre (`GET`) vers la route
214
+ protégée sème le cookie lisible `csrf-token`, et la mutation le rejoue dans
215
+ l'en-tête `x-csrf-token` — c'est le double-submit, sinon `403`. La provenance
216
+ et le jeton se cumulent ; l'une ne remplace jamais l'autre.
217
+
218
+ - **Une origine tierce refusée en 403 se DÉCLARE — elle ne s'exempte pas.** Quand
219
+ les envois d'un partenaire sont rejetés alors que les tiens aboutissent, la
220
+ cause est la défense CSRF, et le réflexe qui vient (`@CsrfExempt` sur la route,
221
+ `checkOrigin: false`, `csrf.enabled: false`) fait passer le partenaire **et
222
+ n'importe quel autre site** : la route cesse de distinguer qui que ce soit,
223
+ c'est-à-dire exactement l'attaque que la défense arrêtait. La réponse est une
224
+ ligne de configuration — ajoute l'origine au bloc `csrf` déjà présent dans
225
+ `use("@nodefony/security", …)`, `nodefony.config.ts` :
226
+
227
+ ```ts
228
+ csrf: {
229
+ secret: ctx.env.NF_CSRF_SECRET,
230
+ trustedOrigins: ["https://partenaire.example"],
231
+ },
232
+ ```
233
+
234
+ La comparaison porte sur la chaîne d'origine ENTIÈRE (`scheme://host[:port]`) :
235
+ ni joker, ni sous-domaine implicite — une origine par entrée. À ne pas
236
+ confondre avec `cors.origins`, qui autorise EN PLUS le JS du tiers à **lire**
237
+ tes réponses : un partenaire qui POSTE n'en a pas besoin, et les deux
238
+ traversent la défense. Détail :
239
+ `node_modules/@nodefony/security/docs/csrf.md` ; geste complet et pièges :
240
+ skill **`nodefony-protect-route`**.
241
+ <% } %>
242
+ - **Un adaptateur de données ne remplace pas l'autre : ils se COMPLÈTENT.** Chacun
243
+ déclare les _stores_ qu'il sait tenir (`nodefony.stores` de son `package.json`) —
244
+ `drizzle` les huit (session, user, tokens, passkeys, totp, audit, webhooks,
245
+ idempotency), `mongoose` cinq (ni `totp`, ni `audit`, ni `idempotency`), `redis`
246
+ quatre. Ce n'est pas un retard de développement mais un CHOIX : un journal
247
+ d'audit n'a rien à faire dans un moteur documentaire. Ne promets donc jamais une
248
+ parité qui n'existe pas, et vérifie où atterrit chaque donnée :
249
+ `npx nodefony inspect stores`. Le détail par brique :
250
+ `node_modules/nodefony/docs/catalogue.md`.
251
+
252
+ - **Le cœur `nodefony` est ISOMORPHE** : le même paquet se charge côté Node
253
+ ET navigateur. La porte client EXPLICITE est le subpath `nodefony/client`
254
+ (`RealtimeClient`, notices, rôles — résolu à l'identique par Vite, Node et
255
+ le typecheck) ; les hooks React vivent dans `nodefony/react`. Ne réécris
256
+ JAMAIS un client WebSocket/JSON-RPC, ne duplique JAMAIS un type entre front
257
+ et back : un seul contrat, vérifié par le compilateur des deux bouts.
258
+
259
+ - **Une commande ne tourne PAS dans le mode du serveur que tu as lancé — DEMANDE-le.**
260
+ Chaque commande démarre son propre noyau. Sans `NODE_ENV` dans ton shell, elle
261
+ part en `development` ; avec `NODE_ENV=production`, elle lit une AUTRE
262
+ configuration et une AUTRE base de données — sans rien dire de plus. Ne le
263
+ suppose jamais avant d'écrire ou de migrer quoi que ce soit :
264
+
265
+ ```bash
266
+ npx nodefony env # le mode, et d'où vient chaque variable
267
+ npx nodefony inspect config # la configuration EFFECTIVE, et sa provenance
268
+ ```
269
+
270
+ Pour forcer : `NODE_ENV=production npx nodefony <commande>`. La règle complète
271
+ (absent, posé, valeur non-moteur) est dans
272
+ `node_modules/nodefony/docs/environnement.md`.
273
+
274
+ - **Une initialisation s'ACCROCHE à une phase du démarrage — il n'y a pas de
275
+ `app.use()`.** Nodefony n'est pas un framework à middlewares chaînés : du code
276
+ posé au chargement d'un fichier s'exécute AVANT que la configuration existe, et
277
+ il n'y a rien à quoi « ajouter » un traitement global. Ce qui doit tourner au
278
+ démarrage se déclare depuis un module ou un service :
279
+ `this.module?.hookKernel("onBoot", async () => { … })` — l'étiquette porte alors
280
+ le nom et la criticité du module, ce qu'un `kernel.once(…)` posé à la main
281
+ perdrait. Les phases, dans l'ordre : `onRegister` (les modules se déclarent),
282
+ `onBoot` (tout est chargé, les connexions s'ouvrent), `onReady` (juste AVANT que
283
+ les serveurs se mettent à écouter), `onPostReady` (ils écoutent), `onTerminate`
284
+ (fermeture). Une commande CLI se pose sur la
285
+ même échelle : `npx nodefony create command <action> --phase onReady`.
286
+ ⚠️ Si tu t'apprêtes à écrire `as any` sur le kernel pour atteindre une méthode,
287
+ arrête-toi : c'est le signe que tu cherches une API d'un AUTRE framework. Les
288
+ phases, le conteneur et les connecteurs sont typés — la référence est dans
289
+ `node_modules/nodefony/docs/kernel.md`, et `npx nodefony inspect services`
290
+ montre ce qui existe RÉELLEMENT dans cette application.
291
+
292
+ - **Un service n'est pas une classe utilitaire.** Une classe à méthodes `static`,
293
+ ou un objet exporté, COMPILE et marche — et reste invisible au framework. Un
294
+ service Nodefony est une classe `@injectable()` qui `extends Service` : c'est
295
+ de là que lui viennent sa config fusionnée, son journal (`this.log`), les
296
+ événements, et sa place dans le conteneur. Il porte DEUX noms sans que ce soit
297
+ une redondance : le décorateur nomme la CLASSE (ce qu'on écrit dans
298
+ `@inject("…")`), le `super("nom", …)` nomme l'INSTANCE (sa clé pour
299
+ `container.get("…")`). Ne l'écris pas de mémoire :
300
+ `npx nodefony create service <Nom>` en pose un complet, commenté, à imiter ;
301
+ la référence est dans
302
+ `node_modules/nodefony/docs/service.md`.
303
+ **Un service qui en appelle un autre le déclare au CONSTRUCTEUR** :
304
+ `npx nodefony create service <Nom> --inject <AutreService>` écrit le
305
+ `@inject("AutreService")` et l'appel qui va avec. La dépendance est alors
306
+ ordonnée par le conteneur et visible dans la signature — là où
307
+ `container.get("…")` cherche à l'exécution et rend `undefined` en silence si
308
+ le service n'est pas enregistré.
309
+
310
+ - **Les violations de contrainte sont DÉJÀ traduites en HTTP — ne les rattrape pas.**
311
+ Un doublon sur une colonne unique ressort en **409**, une donnée qui viole le
312
+ schéma Zod en **422**, chacun avec son corps JSON : le rendu d'erreur lit le code
313
+ du pilote (`23505` PostgreSQL, `ER_DUP_ENTRY` MySQL, `SQLITE_CONSTRAINT_UNIQUE`,
314
+ `11000` MongoDB) et le mappe, quel que soit le moteur. N'écris donc JAMAIS un
315
+ `throw … 409` dans un service pour un `sku` déjà pris. Le vérifier toi-même
316
+ d'abord (« existe-t-il ? » puis insertion) est plus lent ET **faux sous
317
+ concurrence** : deux requêtes simultanées passent toutes les deux le test avant
318
+ que l'une n'écrive. La contrainte de la base est le seul arbitre exact — laisse-la
319
+ lever, le pipeline traduit.
320
+
321
+ - **Un fichier ne se sert pas à la main.** Trois façades, et le choix se fait sur
322
+ l'usage : `this.renderMediaStream(file)` implémente les **requêtes par plage**
323
+ (`Range` → 206 + `Content-Range`, 416 hors plage) — c'est ce qu'exige un lecteur
324
+ vidéo ou audio pour se déplacer ; `this.streamFile(file)` envoie le fichier
325
+ ENTIER en flux, sans plage ; `this.renderFileDownload(file)` force le
326
+ téléchargement. Recomposer ça avec `createReadStream` et `response.write`
327
+ compile, passe les tests — et rend une réponse **incohérente** : un statut posé
328
+ à la main n'atteint jamais la socket (le pipeline écrit statut et en-têtes à
329
+ SON tour), donc le client reçoit **200 avec un corps partiel** et croit tenir le
330
+ fichier complet. Mesuré au banc, pas supposé.
331
+
332
+ - **Le container DI est PROTOTYPAL** : les services vivent sur une chaîne de
333
+ prototypes — un scope de requête VOIT tous les services du kernel sans
334
+ aucune copie (coût d'un scope ≈ un `Object.create`), et ce qu'on `set()`
335
+ dans un scope MEURT avec la requête. Ne fabrique donc ni cache de services
336
+ par requête, ni singleton maison : `container.get("<nom>")` remonte la
337
+ chaîne, c'est le mécanisme.
338
+
339
+ - **Le WS métier passe par la socket Nodefony** (`--kind realtime` : canaux
340
+ pub/sub + actions RPC + policies). L'echo WS brut des exemples est une démo
341
+ du pipeline partagé, pas un modèle à imiter.
342
+
343
+ <% if (it.hasSecurity) { %>- **Utilisateurs et droits : tout existe, n'improvise RIEN.** Ces gestes
344
+ couvrent l'essentiel, et chacun a sa doc installée (cf. la table « Où lire
345
+ AVANT de coder », plus haut) ; le geste détaillé et ses pièges vivent dans le
346
+ skill **`nodefony-protect-route`** :
347
+ - **protéger un ESPACE de routes** (tout ce qui commence par un préfixe) :
348
+ une zone de firewall dans `nodefony.config.ts`, dont le `pattern` est le
349
+ PRÉFIXE lui-même — `pattern: "^/api/account"`, **jamais** la liste des
350
+ routes du jour (`"^/api/account/(profile|invoices)"`). Énumérer marche à
351
+ l'essai, passe la revue, et laisse la route sœur ajoutée ensuite NAÎTRE
352
+ PUBLIQUE — rien ne le signale, la zone a l'air de couvrir l'espace. Quand
353
+ des routes partagent un préfixe, ne les protège pas une par une ;
354
+ - **protéger une action** : le décorateur `@IsGranted("ROLE_ADMIN")` sur la
355
+ méthode — il vaut pour TOUS les transports (HTTP et socket), et se pose
356
+ **en plus** de la zone de firewall (le firewall AUTHENTIFIE, `@IsGranted`
357
+ AUTORISE) ;
358
+ - **réserver TOUT un controller à une habilitation** : ne l'écris pas,
359
+ demande-le — `npx nodefony create controller <nom> --role ROLE_X` pose la
360
+ garde sur la CLASSE (donc sur les actions à venir) **et** déclare le rôle
361
+ sous `ROLE_ADMIN` dans `roleHierarchy`. Les deux gestes vont ensemble, et
362
+ c'est le second qu'on oublie en les faisant à la main ;
363
+ - **lire l'utilisateur courant** : le paramètre décoré `@CurrentUser()`
364
+ (typé `IUser` de `@nodefony/user`) — l'identité est ré-résolue à chaque
365
+ requête, donc les rôles sont frais et une révocation prend effet tout de
366
+ suite. N'écris pas ton propre lecteur de session ;
367
+ - **déclarer qu'un rôle en implique un autre** : la clé `roleHierarchy` de
368
+ la config du module de sécurité (`ROLE_ADMIN` hérite `ROLE_USER`) — que
369
+ `create controller --role` remplit pour toi quand le rôle naît avec son
370
+ controller. Elle
371
+ est aplatie au boot ; n'écris pas de test d'appartenance à la main — et
372
+ n'énumère pas non plus les rôles du jour sur l'action.
373
+ `@IsGranted(["ROLE_BILLING", "ROLE_ADMIN"])` accorde bien l'accès (un
374
+ attribut suffit), mais la relation entre ces deux rôles n'existe alors
375
+ NULLE PART : la route sœur ajoutée demain devra répéter la liste, et
376
+ l'oubli ne se voit sur aucune route. C'est le piège de la puce
377
+ précédente, un cran plus haut — énumérer ce qu'on a sous les yeux au
378
+ lieu de déclarer la règle ;
379
+ - **créer un compte** : la commande `npx nodefony security:user:add <identifiant>`.
380
+ Ne fabrique pas d'utilisateur en insérant directement dans la base — le mot
381
+ de passe passe par l'encodeur du framework.
382
+ - **ouvrir une API à un PROGRAMME** (service partenaire, script, agent — pas
383
+ un navigateur) : cette zone est **déjà posée** dans `nodefony.config.ts` —
384
+
385
+ ```ts
386
+ machine: {
387
+ pattern: "^/api/machine",
388
+ authenticators: ["apikey"], // PAS "session" — ce client n'a pas de cookie
389
+ stateless: true, // false ⇒ un registre de sessions pour un client qui ne le relit pas
390
+ },
391
+ ```
392
+
393
+ Pour une route **NEUVE**, fais-la **tomber sous `/api/machine`** plutôt que
394
+ d'ajouter une zone : celle-ci est déjà réglée, et une seconde zone au
395
+ pattern plus court la coifferait sans prévenir (le firewall trie par
396
+ longueur de pattern).
397
+
398
+ 🔴 **Mais une URL DÉJÀ PUBLIÉE ne se déplace pas — c'est un contrat.** Quand
399
+ on te demande de protéger une adresse existante (`/api/partenaire/depot`),
400
+ la déménager sous `/api/machine` la fait répondre `404` à celui-là même
401
+ qu'on voulait servir : le partenaire appelle l'ancienne, personne ne l'a
402
+ prévenu, et rien dans l'application ne signale la rupture. Vécu, et le
403
+ contrôle l'a vu — clé d'API valide, `404`. **On adapte la ZONE à l'URL,
404
+ jamais l'URL à la zone** : étends le `pattern` de la zone `machine` pour
405
+ qu'il couvre aussi l'adresse en place —
406
+
407
+ ```ts
408
+ machine: {
409
+ pattern: "^/api/(machine|partenaire)",
410
+ authenticators: ["apikey"],
411
+ stateless: true,
412
+ },
413
+ ```
414
+
415
+ Une URL ne se déplace que si l'énoncé le demande, et alors l'ancienne
416
+ redirige.
417
+
418
+ ⚠️ `stateless: false` (le défaut) **ne fait pas échouer l'essai**, et c'est
419
+ tout le piège : depuis un navigateur ou un `curl -c`, le cookie posé revient
420
+ aux requêtes suivantes et tout semble marcher. Ce que ça coûte n'est pas un
421
+ refus mais un **registre** — chaque appel portant un cookie inconnu fait
422
+ reprendre puis réécrire une session serveur, et renvoyer un `Set-Cookie`,
423
+ pour un appelant qui ne la relira jamais. `stateless: true` ferme cela : la
424
+ zone n'ouvre ni ne reprend de session, et le cookie entrant est ignoré.
425
+ Lister `"session"` dans une zone stateless est une contradiction, et
426
+ l'application **refuse de démarrer** en nommant la zone. Règle : un appelant
427
+ qui ne stocke pas de cookie ne doit rien recevoir qu'il faille stocker.
428
+ Les clés s'émettent par `POST /nodefony/security/api/keys`.
429
+
430
+ - Un droit **métier** qui ne se réduit pas à un rôle (« l'auteur peut éditer
431
+ SON document ») s'écrit en **voter** et s'enregistre par
432
+ `registerVoterFactory` ; `@IsGranted("doc.edit", { subject: "id" })` l'appelle.
433
+ C'est le point d'extension prévu — il n'y a pas de table de permissions à
434
+ inventer.
435
+
436
+ <% } %>## Environnement : ne devine JAMAIS, demande
437
+
438
+ ```bash
439
+ npx nodefony env # cascade des .env, valeur EFFECTIVE de chaque variable, sa PROVENANCE
440
+ npx nodefony env --json # même rapport, pour un script
441
+ ```
442
+
443
+ **Encadre toute modification de configuration par cette commande** : une fois
444
+ AVANT, pour savoir ce qui s'applique aujourd'hui et d'où ça vient ; une fois
445
+ APRÈS, pour prouver que ta valeur est bien celle qui gagne. Ce n'est pas un
446
+ outil de dépannage qu'on sort quand ça casse — c'est le geste qui remplace la
447
+ déduction.
448
+
449
+ Elle répond aux quatre questions dont dépend toute configuration, et qu'aucune
450
+ lecture de fichier ne tranche : quels fichiers sont lus **et dans quel ordre**,
451
+ quelles variables l'app **déclare**, quelle valeur est **effective et d'où elle
452
+ vient**, et **ce qui est ignoré**. Lire les `.env` toi-même te donne des
453
+ contenus ; la précédence, elle, est un mécanisme — tu ne peux que la supposer,
454
+ et une supposition fausse ne se voit qu'en production. La commande ne boote
455
+ rien, donc elle répond aussi quand l'app ne démarre plus.
456
+
457
+ **Précédence, du plus FORT au plus faible** — le premier qui pose une valeur
458
+ gagne, les suivants sont ignorés en silence :
459
+
460
+ ```
461
+ process.env > .env.<déploiement>.local > .env.<mode>.local > .env.local
462
+ > .env.<déploiement> > .env.<mode> > .env
463
+ ```
464
+
465
+ `<mode>` = `NODE_ENV` (`development`/`production`). `<déploiement>` = `APP_ENV`
466
+ (`staging`, `canary`… — plus spécifique, donc plus fort). Les `*.local` ne sont
467
+ jamais committés : les secrets y vont, et nulle part ailleurs.
468
+
469
+ **Deux mécanismes à ne pas confondre** :
470
+
471
+ | Forme | Ce que c'est | Où c'est déclaré |
472
+ | ------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------ |
473
+ | `NF_PORT=5151` | variable de l'APP, typée et validée | `env.ts` (`defineEnv`) — non déclarée = **sans effet** |
474
+ | `NF__HTTP__SERVERS__HTTPS__PORT=8443` | surcharge DIRECTE d'une clé de config d'un module | rien à déclarer — double `__` = séparateur |
475
+ | `NF_TOTP_KEY_FILE=/run/secrets/x` | la même variable, lue depuis un fichier (secret Docker/K8s) | idem `NF_TOTP_KEY` |
476
+
477
+ Une variable `NF_` mal orthographiée n'échoue pas : elle est **ignorée**, et le
478
+ défaut s'applique en silence. `npx nodefony env` est le seul endroit qui la montre
479
+ (avec la correction probable).
480
+
481
+ **Les clés de configuration d'un module, avec leurs défauts, sont LISIBLES :**
482
+ `node_modules/@nodefony/<module>/dist/nodefony/config/config.js` porte le schéma
483
+ Zod du module — chaque clé, son `.default(…)` et sa `.describe(…)`. C'est la
484
+ source, pas une copie : la lire évite d'inventer une option qui n'existe pas
485
+ (une clé inconnue est retirée en silence à la validation). Ne recopie jamais ces
486
+ valeurs dans la doc du projet ; elles bougeront sans toi.
487
+
488
+ Pour ce que le PROJET offre comme choix (connecteurs déclarés, entités déjà
489
+ créées, types de colonnes de ton moteur) :
490
+ `npx nodefony create entity --describe-json` — c'est la même source que le
491
+ formulaire de Studio, à jour par construction.
492
+
493
+ ## Pièges qui coûtent cher — vécus, pas théoriques
494
+
495
+ Chacun a déjà fait perdre une heure et beaucoup d'allers-retours. Le symptôme ne
496
+ désigne jamais la cause : c'est ce qui les rend chers.
497
+
498
+ - **Un test rouge en suite, VERT rejoué seul** — une ressource PARTAGÉE entre fichiers (serveur, table, état global) — pas une régression de ton diff → rejoue-le seul : l'isolation dit la vérité ; puis donne à chaque fichier sa propre ressource
499
+ - **Le serveur lancé en arrière-plan a disparu** — `… &` reçoit SIGHUP et meurt ; et tuer le PID du port ne tue pas le superviseur, qui respawne → `npx nodefony production --detach --wait` pour démarrer, `npx nodefony stop` pour arrêter — jamais `&`, jamais un kill par le port
500
+ - **Des dizaines de tests d'intégration rouges d'un coup** — ils FRAPPENT un serveur, ils ne le lancent pas : il est éteint (`ECONNREFUSED`) → `npx nodefony status` d'abord ; en e2e, laisse la commande gérer le cycle
501
+ - **La route existe dans le code et répond 404** — le runtime charge `dist/`, pas tes sources → `npm run build` — et en cas de doute vérifie le `dist/` par son CONTENU (`grep` du symbole), jamais par sa date
502
+ - **Ta route NEUVE répond 404, et le `dist/` est à jour** — elle n'est pas montée où tu crois : le chemin réel est le PRÉFIXE de son controller suivi du `path` de la route — une action `path: "/widget"` posée dans un controller `@controller("/api")` répond sur `/api/widget` → `npx nodefony inspect routes --json` donne le chemin MONTÉ ; si l'URL demandée ne doit pas porter le préfixe, la route va dans un controller qui n'en a pas
503
+ - **TOUT répond 404, même les routes du gabarit** — un AUTRE serveur tient les ports — ou LE TIEN a glissé sur d'autres ports, le port voulu étant pris → `npx nodefony status` : il montre les ports RÉELS, pas ceux que tu as configurés, et NOMME le projet voisin qui tient un port ; `npx nodefony stop <nom>` l'arrête sans te déplacer
504
+ - **L'app démarre, et pourtant une brique manque** (base injoignable, module absent) — une brique peut tomber en fail-soft, ou être écartée par sa `policy` : le boot CONTINUE, et le journal ne le dit qu'une fois, dans le terminal de celui qui a lancé → `npm run doctor` — il lit `var/last-boot.json` et nomme chaque brique absente AVEC sa raison
505
+ - **L'app ne démarre plus et tu n'as pas la sortie** (démarrage détaché, conteneur, CI) — le journal est parti avec le terminal → `npm run doctor` n'exécute rien : il rapporte la phase atteinte et la cause du dernier démarrage
506
+ - **Ça marche en dev, c'est mort en production** — les modules `policy: dev` sont RETIRÉS en production — ce qu'ils portaient disparaît avec eux → avant de livrer, UN boot `npx nodefony production --detach --wait` et rejoue tes vérifications
507
+ - **Un réglage de `nodefony.config.ts` ne change rien** — clé inconnue ou mal placée : retirée EN SILENCE à la validation → `npx nodefony inspect config --json` — la config effective et la provenance de chaque valeur
508
+ - **Une variable d'environnement « ne prend pas »** — mal orthographiée (ignorée en silence) ou masquée par un rang supérieur → `npx nodefony env` — il montre la valeur EFFECTIVE et sa provenance
509
+ - **Après un échec au milieu d'une chaîne `&&`, tout ment** — rien d'aval n'a tourné : tu mesures l'état d'AVANT → après tout échec, considère que la suite n'a pas eu lieu — revérifie que l'artefact mesuré a été régénéré
510
+ - **Les tests passent, `npm run typecheck` échoue** — le runner efface les types : un test vert ne typecheck rien → lance les DEUX avant de conclure
511
+ - **Suite verte, et le câblage est mort** — un test qui ne quitte pas la brique ne prouve que la brique → débranche le point de câblage : si rien ne tombe, il n'est pas testé
512
+ - **Un test vert « prouve » une garantie de sécurité** — elle est vraie dans la fonction, fausse sur le trajet réel → frappe la route en anonyme et regarde si le code a tourné
513
+ - **Un test qui n'a jamais échoué** — il ne garde rien — un test neuf est complaisant par défaut → casse-le exprès une fois, vérifie qu'il rougit
514
+ - **« Tout est vert » alors qu'une suite ne s'est pas exécutée** — un test sauté compte comme réussi — et un fichier jamais COLLECTÉ (erreur de syntaxe, hors du glob) ne compte pas du tout → lis le NOMBRE de tests, pas la couleur
515
+ - **`localhost` et `127.0.0.1` te jouent des tours** — ce sont deux ORIGINES distinctes : cookies, cache et passkeys ne les partagent pas → une seule origine en développement, partout — URL ouverte comme callbacks
516
+ <% if (it.hasSecurity) { %>- **Ta page répond 200 et son script ne s'exécute pas** — la politique de contenu exige un `nonce` sur les scripts, et le navigateur refuse un `<script>` en ligne qui n'en porte pas (« Refused to execute inline script ») : un `curl` ne le voit JAMAIS, il ne lit que le corps → signe le script (`<script nonce="…">`, valeur `this.context?.cspNonce` de ton controller) ou sors-le dans un fichier servi ; ne desserre PAS la politique (`'unsafe-inline'`), et le journal du serveur te le dit en développement — détail : `node_modules/@nodefony/security/docs/headers.md`
517
+ <% } %><% if (it.hasOrm) { %>- **La modif d'une entité « ne prend pas »** (erreur SQL au runtime) — en développement, un champ AJOUTÉ qui accepte le vide est posé au boot suivant, un champ OBLIGATOIRE ne l'est jamais, et aucune colonne n'est jamais retirée → écris la migration (`npx nodefony orm:generate` puis `npx nodefony orm:migrate`), qui vaut en dev comme en production ; `npx nodefony orm:reset` refait la base à neuf et **perd les données** — à ne taper que sur une base dont le contenu ne compte pour personne
518
+ - **Un déploiement où « rien ne répond »** alors que les pods tournent — un exemplaire dont la base est en retard répond 503 sur `/readyz` (jamais sur `/livez`) et reste hors du répartiteur : c'est voulu, ce n'est pas une panne → `npx nodefony orm:migrate:status` dit qui est en retard ; applique les migrations, les pods se mettent en service SEULS
519
+ <% } %><% if (it.hasSecurity) { %>- **Les routes authentifiées plafonnent** quand le reste tient la charge — le stockage de session par défaut est SYNCHRONE : chaque reprise bloque la boucle d'événements → compare une route anonyme et une route authentifiée AVANT d'accuser TLS ou le pare-feu ; passe le stockage sur redis pour la charge
520
+ <% } %><% if (it.front) { %>- **En production, la modif front n'apparaît jamais** — hors développement il n'y a PAS de rechargement à chaud, et le manifeste est lu AU BOOT → `npm run build` → **redémarre le serveur** → rechargement forcé
521
+ - **Ta modif front n'apparaît pas (en dev)** — le navigateur sert son cache — et le rechargement à chaud ne remplace ni un singleton ni un composant qui gagne des hooks : le code neuf tourne sur du vieil état → rechargement forcé, et vérifie que Vite a bien recompilé
522
+ - **Une route d'API répond du HTML** — un repli SPA générique avale les routes voisines — le premier motif qui correspond gagne → repli en préfixe LITTÉRAL ; `npx nodefony inspect routes --json` montre l'ordre réel
523
+ - **Des utilisateurs « déconnectés au hasard »** — le traitement global « 401 = session expirée » frappe aussi les sondes d'authentification, où 401 est NORMAL — et détruit une session valide → exempte les sondes du traitement global
524
+ <% } %>
525
+ **Ce qui coûte le plus de tokens** : enchaîner arrêt → construction → démarrage
526
+ après chaque petite modification. Regroupe TOUTES tes modifications serveur, puis
527
+ UN seul cycle. Le serveur de développement reconstruit tout seul<% if (it.front) { %>, et le front
528
+ passe en rechargement à chaud — zéro redémarrage<% } %>. Et ne lance **jamais** une
529
+ construction pendant qu'une suite de tests interroge le serveur : il redémarre au
530
+ milieu, et tu passes l'heure suivante sur des 404 fantômes.
531
+
532
+ ## Modules du projet
533
+
534
+ <% if (it.modules.length === 0) { %>Aucun — `npx nodefony create module <nom>` en pose un (workspace npm sous `modules/`).
535
+ <% } else { %><% it.modules.forEach(function (m) { %>- `<%= m.dir %>/` — `<%= m.name %>` (son `AGENTS.md` local prime quand tu travailles dedans)
536
+ <% }) %><% } %>
537
+ ## Gates — vérifier avant de dire « fait »
538
+
539
+ ```bash
540
+ npm run verify # ⬅ LA commande. typecheck + lint + tests + doctor, dans cet ordre
541
+ ```
542
+
543
+ **Une seule à retenir, et c'est délibéré.** Les quatre gates ci-dessous existent
544
+ séparément pour qu'on puisse en relancer un ; mais tant qu'ils n'étaient QUE
545
+ séparés, il fallait penser à les enchaîner — et le premier oublié était toujours
546
+ le même, `typecheck`, celui que rien d'autre ne remplace : **le bundler ne
547
+ type-check pas**, ton code peut être bâti, servi, et ne pas compiler.
548
+
549
+ `verify` s'arrête au premier rouge, et ce rouge est ta tâche suivante.
550
+
551
+ ```bash
552
+ npm run typecheck # types — le seul gate que le build ne fait PAS à ta place
553
+ npm run lint # style et pièges
554
+ npm test # unitaires, rapides, zéro serveur
555
+ npm run doctor # diagnostic : câblage, install, + BILAN du dernier démarrage
556
+ npm run test:e2e # boot RÉEL + HTTP/WS (build inclus) — HORS `verify` : c'est le gate LENT
557
+ ```
558
+
559
+ ### `doctor` — le premier réflexe quand quelque chose ne va pas
560
+
561
+ **Avant de chercher, demande.** `npx nodefony doctor` (ou `npm run doctor`) est
562
+ la commande de diagnostic : elle répond depuis n'importe quel sous-dossier, elle
563
+ n'exécute RIEN de ton application, et `--json` la rend exploitable par un script.
564
+ `check` en est un alias historique — le nom à retenir est `doctor`.
565
+
566
+ Ce qu'elle t'épargne : une demi-heure à chercher pourquoi une route répond 404,
567
+ pourquoi un service est introuvable, ou pourquoi l'app « marche » sans faire ce
568
+ qu'on lui demande. Elle ne devine pas — elle LIT, et elle nomme le geste.
569
+
570
+ ```bash
571
+ npx nodefony doctor # sortie lisible ; sort en erreur s'il manque quelque chose
572
+ npx nodefony doctor --json # même chose, pour un script ou un agent
573
+ ```
574
+
575
+ **`doctor` nomme d'abord ce qui empêche de DÉMARRER**, et il le fait sans rien
576
+ exécuter — donc il répond sur une app qui ne se lance plus :
577
+
578
+ - une **variable REQUISE** sans valeur ;
579
+ - un module que le manifeste charge mais qui n'est **pas installé** ;
580
+ - une dépendance déclarée **absente de `node_modules`** ;
581
+ - un **port déjà tenu** par un autre programme (le tien ne compte pas).
582
+
583
+ Il nomme aussi une **classe écrite que rien ne déclare** — une entité hors de
584
+ `@entities([…])`, un controller hors de `@controllers([…])`. Elle compile, les
585
+ tests qui l'importent passent, et la panne n'arrive qu'au démarrage suivant :
586
+ une table jamais créée, une route qui répond 404 sans que rien ne l'explique.
587
+ C'est le mode d'échec de la COPIE, celui qu'on fait en recopiant le voisin au
588
+ lieu d'appeler le générateur.
589
+
590
+ **`doctor` te dit aussi ce qui s'est passé au dernier démarrage**, et c'est la
591
+ seule façon de l'apprendre après coup : l'app écrit son bilan dans
592
+ `var/last-boot.json` à chaque boot. Deux cas que tu ne peux pas voir autrement :
593
+
594
+ - **elle ne démarre plus** — `doctor` n'exécute rien, donc il répond quand même,
595
+ et il nomme la phase atteinte et la cause ;
596
+ - **elle démarre mais AMPUTÉE** — c'est le cas piégeux : tout a l'air sain, et
597
+ une brique manque (base injoignable, module écarté par sa `policy`). Le
598
+ journal l'a dit une fois, au terminal de celui qui a lancé. `doctor` te le
599
+ redit, avec la RAISON de chaque brique absente.
600
+
601
+ Sur une app saine il n'en parle pas. S'il en parle, lis avant de coder.
602
+
603
+ ## Piloter le serveur — et l'ARRÊTER
604
+
605
+ ```bash
606
+ npm run dev # développement : rechargement auto, Ctrl+C pour arrêter
607
+ npx nodefony development --no-watch # développement SANS rechargement : un seul process, stable
608
+ npx nodefony status # que tourne-t-il ? ports, PID — ne boote rien
609
+ npx nodefony stop # arrêt PROPRE de tout runtime de cette app
610
+ npx nodefony stop <nom|chemin> # arrêter un AUTRE projet, sans changer de dossier
611
+ npx nodefony production --detach --wait # boot réel en arrière-plan ; rend la main ports OUVERTS
612
+ ```
613
+
614
+ **Arrête ce que tu démarres.** Un serveur laissé derrière garde les ports : le run
615
+ suivant échoue sur une erreur qui ne parle jamais de lui (`EADDRINUSE`, ou pire, un
616
+ test qui interroge l'ANCIENNE version du code). `npx nodefony stop` est la sortie
617
+ propre, `npx nodefony status` dit ce qui reste.
618
+
619
+ **Ces deux commandes ne voient QUE cette application.** Plusieurs projets Nodefony
620
+ peuvent tourner sur la même machine ; `status` ne compte jamais les process du
621
+ voisin comme les tiens, il les NOMME dans une table à part (nom, ports tenus,
622
+ racine) — et ce nom est ce que `stop` accepte. Deux conséquences pour toi :
623
+ « aucune instance » veut dire « aucune À MOI », pas « rien ne tourne » ; et une
624
+ cible que `stop` ne peut pas désigner sans ambiguïté est REFUSÉE, avec un code de
625
+ sortie non nul et rien d'arrêté — **lis ce code**, un refus ressemble sinon à un
626
+ succès. Ne prends `--all` que pour faire table rase du poste entier : il emporte
627
+ les serveurs des autres projets, y compris ceux que tu n'as pas lancés.
628
+
629
+ **Pour faire tourner une suite contre un serveur, prends `--no-watch`.** Le mode
630
+ développement surveille les sources et relance le serveur dès qu'un fichier bouge —
631
+ ce qui est exactement ce qu'on veut en codant, et exactement ce qu'on ne veut pas
632
+ pendant un run : le redémarrage coupe les connexions sous les tests, et le rouge qui
633
+ en sort accuse le code alors que le fautif est le décor. `--no-watch` garde tout le
634
+ mode développement (mêmes modules, mêmes erreurs détaillées) et retire le seul
635
+ rechargement automatique.
636
+
637
+ ⚠️ **Une suite lancée contre un serveur de PRODUCTION reçoit `404` sur tout.** Les
638
+ modules déclarés `policy: "dev"` n'y sont pas chargés — les routes que la suite
639
+ interroge n'existent tout simplement pas. C'est le rôle de cette politique, pas un
640
+ défaut à contourner. Si c'est bien le mode production que tu veux éprouver :
641
+
642
+ ```bash
643
+ NF_WITH_DEV_MODULES=1 nodefony production --detach --wait # dérogation explicite
644
+ NF_WITH_DEV_MODULES_TTL_MIN=120 … # campagne longue (charge)
645
+ ```
646
+
647
+ Ce runtime **s'arrête tout seul** (30 min par défaut, réglable jusqu'à 4 h, jamais
648
+ désarmable), après un préavis. Ce n'est pas une gêne : c'est ce qui empêche une
649
+ variable oubliée dans une image ou un manifeste de laisser des routes de banc
650
+ ouvertes en production pendant des mois. Règle le délai AVANT une mesure longue — un
651
+ serveur qui tombe au milieu ne rend pas une mesure fausse, il en rend une qu'on
652
+ croira vraie.
653
+
654
+ ## Voir un écran toi-même — un navigateur, pas un `curl`
655
+
656
+ Un `curl` prouve qu'une route répond ; il ne dit pas si l'écran **se monte**. Le
657
+ devkit porte des sondes prêtes à l'emploi, qui s'exécutent de deux façons.
658
+
659
+ **Sur cette machine** — le plus court :
660
+
661
+ ```bash
662
+ npm run see:setup
663
+ node node_modules/@nodefony/devkit/skills/nodefony-browser/scripts/inspect.mjs /
664
+ ```
665
+
666
+ `see:setup` n'installe **rien de lourd par défaut** : le pilote pèse quelques
667
+ mégaoctets, et il essaie d'abord les navigateurs **déjà présents** sur la machine —
668
+ Chrome, puis Edge, qui est préinstallé sur tout Windows. Le navigateur complet
669
+ n'est téléchargé que si aucun ne répond, une seule fois par machine (cache
670
+ utilisateur partagé par tous tes projets, jamais dans `node_modules`) :
671
+
672
+ ```bash
673
+ npx playwright install chromium
674
+ ```
675
+
676
+ Le champ `navigateur` de la sortie dit lequel a servi — deux mesures faites avec
677
+ des navigateurs différents ne se comparent pas.
678
+
679
+ **En conteneur** — quand tu veux une mesure **comparable** dans le temps (image
680
+ épinglée, donc version figée), de l'**isolation** (le navigateur ne voit ni ton
681
+ disque ni ton réseau), ou que tu ne veux **rien** installer :
682
+
683
+ ```bash
684
+ docker compose --profile browser up -d
685
+ docker cp node_modules/@nodefony/devkit/skills/nodefony-browser/scripts/. <%= it.appName %>-browser:/app/see-screen
686
+ docker exec <%= it.appName %>-browser node /app/see-screen/inspect.mjs /
687
+ ```
688
+
689
+ Le **`/.`** de la copie n'est pas décoratif : sans lui, une seconde copie imbrique
690
+ un dossier de plus au lieu de remplacer, et tu relances une version périmée des
691
+ sondes sans le moindre message.
692
+
693
+ Tu obtiens un JSON : le titre, la langue, le thème, les **scripts réellement
694
+ servis**, les erreurs de console, une capture horodatée — et surtout des **mesures**
695
+ que ni une capture ni un `curl` ne donnent : la couleur, le fond effectif, le
696
+ **contraste calculé** (luminances WCAG) et la taille de chaque élément que tu
697
+ sondes (`-e "NF_BROWSER_PROBES=libellé=sélecteur,…"`). C'est la différence entre
698
+ « ça me paraît lisible » et « 7,39:1, donc AAA ».
699
+
700
+ `watch.mjs`, à côté, regarde le temps qui coule plutôt qu'un instant : frames
701
+ WebSocket horodatées dans les deux sens, réponses ≥ 400, erreurs de console. C'est
702
+ la seule façon de voir une frame qui n'arrive pas ou une reconnexion en boucle.
703
+ Il s'arrête sur une **condition applicative** (`NF_BROWSER_UNTIL`) plutôt que sur
704
+ une durée — mais **éprouve toute condition d'arrêt avec une condition IMPOSSIBLE**
705
+ avant de lui faire confiance : tant qu'elle n'a pas échoué une fois, rien ne dit
706
+ qu'elle discrimine.
707
+
708
+ ### Auditer, pas seulement regarder
709
+
710
+ ```bash
711
+ npm run audit:setup
712
+ npm run audit:web -- /tableau-de-bord
713
+ ```
714
+
715
+ Lighthouse complet **sur une page authentifiée** — ce que l'extension du navigateur
716
+ ne sait pas faire. Cinq catégories, dont **`agentic-browsing`** : ce qu'un agent
717
+ d'intelligence artificielle trouve en arrivant sur ta page (arbre d'accessibilité,
718
+ stabilité visuelle, annotations WebMCP de tes formulaires, `llms.txt`).
719
+
720
+ `audit:setup` est **séparé** de `see:setup` parce que Lighthouse pèse une
721
+ vingtaine de mégaoctets : tu ne le paies que si tu audites.
722
+
723
+ ⚠️ **Ne juge pas la note de performance sur le serveur de développement** :
724
+ modules servis un par un, sources non minifiées, rechargement à chaud. Elle
725
+ s'effondre pour des raisons qui n'existent pas en production. Cette catégorie
726
+ ne se mesure que sur une version bâtie.
727
+
728
+ Le mode d'emploi complet est le skill **`nodefony-browser`** du devkit (`ai:sync` en pose
729
+ le pointeur dans `.agents/skills/`).
730
+
731
+ **Quatre règles, sinon tu diagnostiqueras le vide** :
732
+
733
+ | Règle | Pourquoi |
734
+ | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
735
+ | Joins l'app par **`host.docker.internal`** | `localhost` désigne le conteneur, pas ta machine. Si tu as activé `domainCheck`, ajoute ce nom aux `trustedHosts` en développement, sinon la barrière répond `421`. |
736
+ | Passe par **HTTPS** | Le cookie de session est `secure` : sur une origine `http://` non-`localhost` le navigateur le **jette**, et tout revient en `401` — on croit alors que le login rate. |
737
+ | **Rien à poser** pour rendre Vite joignable | L'origine des assets se dérive du `Host` de ta requête : arriver par `host.docker.internal` suffit, l'allowlist Vite et le WebSocket du HMR suivent le même nom, et le poste reste servi sur `127.0.0.1` en même temps. Si la page annonce quand même `127.0.0.1:5173` depuis le conteneur, c'est que le nom ne franchit pas `trustedHosts`, ou qu'une `publicOrigin` explicite est configurée (elle gagne toujours). |
738
+ | **Attends un texte propre à l'écran visé** avant de lire ou capturer | Le SPA se monte APRÈS la navigation. Et attendre un texte présent aussi sur la page de connexion (le nom de l'app…) aboutit dans les deux cas : ça ne prouve rien. |
739
+
740
+ Une capture **n'écrase pas** un fichier existant : réutiliser un nom te fait relire
741
+ une image périmée pendant que l'appel répond « OK ». Nom neuf, ou vérifie la date.
742
+
743
+ **🔴 AVANT d'accuser ton code : le bundle SERVI est-il celui que tu as bâti ?** En
744
+ front pré-bâti, trois mécanismes indépendants te font observer du code que la source
745
+ ne contient plus — un build partiel qui ne purge pas la sortie (deux générations de
746
+ chunks, l'`index.html` pouvant désigner l'ancienne), un cache de build qui RESTAURE
747
+ un ancien `dist` par-dessus le tien, et le service d'assets qui lit l'`index.html`
748
+ au démarrage seulement. Le symptôme est traître : l'écran montre un composant que tu
749
+ as remplacé.
750
+
751
+ Le champ **`scripts`** rendu par `inspect.mjs` liste les fichiers servis à la page :
752
+ compare-les à ceux que désigne l'`index.html` produit dans `<module>/dist/frontend/`.
753
+ Deux valeurs différentes ⇒ le défaut n'est pas dans ton code. Rebâtis en forçant
754
+ (cache invalidé), redémarre le serveur, PUIS redémarre le conteneur navigateur —
755
+ son cache HTTP survit à un simple rechargement. Aucun de ces trois pas n'est
756
+ facultatif.
757
+
758
+ **L'autre voie — le serveur MCP.** Le même conteneur expose un serveur MCP
759
+ (`claude mcp add --transport http browser http://127.0.0.1:3001/mcp`) : prends-le
760
+ pour **explorer** une page interactivement, et les sondes ci-dessus pour tout le
761
+ reste. Le protocole intermédiaire coûte plusieurs fois le temps d'un appel direct,
762
+ ne rend rien qu'un script puisse exploiter, et sa session peut tomber sous toi.
763
+
764
+ Ce que ce navigateur ne remplace pas : le rechargement à chaud, l'animation et le
765
+ rendu fin — ça se juge dans un vrai navigateur. Lui répond à « l'écran se monte-t-il,
766
+ s'alimente-t-il, et crie-t-il dans la console ? ».
767
+
768
+ ## Demander à l'app, plutôt que déduire du code
769
+
770
+ **Perdu ? Commence par ici** — la carte de visite dit qui répond, ce qui est
771
+ chargé, où lire et quoi lancer :
772
+
773
+ ```bash
774
+ npx nodefony card # ajoute -j pour du JSON (| jq)
775
+ ```
776
+
777
+ Elle répond **toujours** : sur une application pas encore construite, et depuis
778
+ un terminal qui n'a posé aucune variable d'environnement — elle ne lit que des
779
+ fichiers. Dans ce cas elle le DIT (« modules installés », pas « chargés ») et
780
+ renvoie à `npx nodefony inspect modules` pour ce qui est vraiment monté.
781
+ `devkit:card` reste accepté : c'est son ancien nom.
782
+
783
+ ```bash
784
+ npx nodefony inspect routes --json # toutes les routes réelles (chemin, méthodes, controller)
785
+ npx nodefony inspect services --json # services enregistrés, et le module qui les porte
786
+ npx nodefony inspect config --json # config EFFECTIVE de chaque module (+ d'où vient chaque valeur)
787
+ npx nodefony inspect modules --json # modules CHARGÉS — pas ceux que le manifeste déclare
788
+ npx nodefony inspect module http # un module en détail
789
+ npx nodefony inspect entities --json # entités déclarées à l'ORM
790
+ npx nodefony inspect stores --json # où sont RÉELLEMENT écrites les données (sessions, cache…)
791
+ npx nodefony inspect graph --json # graphe des entités et de leurs relations
792
+ ```
793
+
794
+ Ces commandes bootent l'app **sans ouvrir un seul port** et rendent exactement ce
795
+ que sert la console d'administration — même code, deux portes. Préfère-les à la
796
+ lecture des sources : une route dépend de décorateurs, d'un manifeste et d'un
797
+ ordre de chargement ; la déduire, c'est se tromper un jour sur deux. `--json` est
798
+ un flux pur, `| jq` fonctionne.
799
+
800
+ **« Que fait cette classe, où est-elle définie, qu'étend-elle ? » → une commande,
801
+ pas une fouille :**
802
+
803
+ ```bash
804
+ npx nodefony symbols AbstractCrudService # définition, TSDoc, parenté — en O(1)
805
+ npx nodefony symbols --module @nodefony/http # toute la surface exportée d'un paquet
806
+ npx nodefony symbols # ce que le graphe couvre, et d'où il vient
807
+ ```
808
+
809
+ Le graphe symbolique de TOUT le framework est livré avec le paquet `nodefony` :
810
+ la réponse ne dépend ni d'un serveur, ni d'un build, ni de ta connexion. Va y
811
+ chercher un symbole AVANT d'ouvrir un `.d.ts` ou de parcourir `node_modules` —
812
+ et avant, surtout, d'inventer une signature.
813
+
814
+ **Tu préfères des OUTILS à des commandes ? Cette app en expose, par MCP.** Les
815
+ mêmes réponses (`inspect`, `check`, `symbols`, `card`), servies en Model Context
816
+ Protocol — utile si ton client sait appeler des outils mais pas lancer un
817
+ terminal :
818
+
819
+ ```bash
820
+ npx nodefony ai:mcp # écrit .mcp.json ; --dry-run pour voir sans écrire
821
+ ```
822
+
823
+ Ce n'est **pas un process de plus** : le serveur MCP est une route de cette
824
+ application (`POST /nodefony/mcp`), donc il n'existe **que pendant que l'app
825
+ tourne**, et il suit chaque rechargement du serveur de développement sans rien à
826
+ resynchroniser. Après avoir écrit le fichier, **redémarre ton client** : aucun ne
827
+ relit sa configuration en cours de route.
828
+
829
+ ⚠️ **L'ordre compte, et il se paie en silence** : ton client se connecte aux
830
+ serveurs MCP **au démarrage de TA session, une seule fois** — si l'application
831
+ ne tournait pas à cet instant, le serveur reste marqué `failed` et ses outils
832
+ n'apparaîtront **jamais** dans cette session, même après un
833
+ `npx nodefony development --detach --wait`. Démarre l'application D'ABORD, ta
834
+ session ENSUITE. Application éteinte ou session déjà ouverte : les commandes
835
+ CLI (`inspect`, `check`, `symbols`, `card`) rendent les mêmes réponses, sans
836
+ rien exiger.
837
+
838
+ Deux choses à savoir avant de t'étonner : la porte est **refusée à toute adresse
839
+ non locale** et à toute origine de navigateur non déclarée (`403`) — c'est une
840
+ protection contre une page web qui viserait ton `localhost`, pas un bogue ; et
841
+ elle **n'existe pas en production**, le module qui la sert étant `policy: "dev"`.
842
+ Réglages : `use("@nodefony/devkit", { mcp: { … } })`.
843
+
844
+ **Ces quatre outils décrivent le FRAMEWORK. Ceux du métier, c'est toi qui les
845
+ ajoutes** — n'importe quel module de cette application publie les siens en
846
+ implémentant `getMcpTools()`. C'est le seul moyen qu'un agent extérieur
847
+ interroge le domaine plutôt que la plomberie :
848
+
849
+ ```ts
850
+ import { Module, mcpText, type IMcpTool } from "nodefony";
851
+
852
+ class Shop extends Module {
853
+ getMcpTools(): IMcpTool[] {
854
+ return [
855
+ {
856
+ name: "shop_stock",
857
+ // La description est ce qui DÉCLENCHE l'outil : dire ce qu'il rend ET
858
+ // quand s'en servir. Un modèle n'appelle pas ce qu'il ne comprend pas.
859
+ description:
860
+ "Stock réel d'une référence produit. À utiliser avant de proposer " +
861
+ "une commande — la réponse vient de la base, pas d'un cache.",
862
+ inputSchema: {
863
+ type: "object",
864
+ properties: { sku: { type: "string", description: "Référence" } },
865
+ required: ["sku"],
866
+ },
867
+ handler: async (args) => mcpText(await this.stock(String(args.sku))),
868
+ },
869
+ ];
870
+ }
871
+ }
872
+ ```
873
+
874
+ Rien ne s'enregistre au démarrage : la liste est relue à chaque requête, donc un
875
+ module ajouté apparaît sans rien redémarrer. `mcp.tools` ne filtre que les
876
+ outils **intégrés** — le tien est publié dès qu'il est déclaré. Un outil écarté
877
+ (nom hors `[a-zA-Z0-9_-]{1,64}`, nom déjà pris, handler absent) le dit en
878
+ `WARNING` dans les journaux du serveur : s'il manque à l'appel, la raison y est
879
+ déjà, ne la cherche pas dans ton handler — il n'a pas été appelé.
880
+
881
+ **Un outil qui touche à des données réservées se DÉCLARE tel** — `scopes` (tous
882
+ exigés) et/ou `requiresAuth`, et son handler reçoit l'appelant en second
883
+ paramètre pour borner ce qu'il rend :
884
+
885
+ ```ts
886
+ {
887
+ name: "shop_invoice",
888
+ description: "Facture d'une commande.",
889
+ inputSchema: { type: "object", properties: { id: { type: "string" } } },
890
+ scopes: ["shop:read", "shop:billing"],
891
+ handler: async (args, caller) => mcpText(await this.invoice(args.id, caller.subject)),
892
+ }
893
+ ```
894
+
895
+ Un outil ainsi déclaré est **retenu** tant que l'appelant ne présente pas ce
896
+ qu'il exige : absent de `tools/list`, **et** inappelable en le nommant — un
897
+ catalogue filtré dont les outils cachés répondent quand même ne serait qu'un
898
+ rideau. Le refus dit « outil inconnu », jamais « interdit » : son existence même
899
+ n'est pas révélée.
900
+
901
+ ⚠️ **Aujourd'hui cette porte n'authentifie PERSONNE** — elle ne valide aucun
902
+ jeton. Un outil qui exige des scopes est donc, ici et maintenant, **invisible
903
+ pour toujours**. C'est voulu (fermé par défaut), mais retiens-en la conséquence
904
+ pratique : tant que l'authentification n'est pas branchée, n'attends pas d'un
905
+ outil protégé qu'il réponde — c'est le comportement normal, pas une panne.
906
+
907
+ ⚠️ Et pour les outils publics : avant d'exposer une donnée, demande-toi si elle
908
+ supporterait d'être lue **sans identification** par qui a accès à la machine.
909
+
910
+ **Ce que rend `inspect` ENGLOBE tes sources, et les dépasse de loin.** Les modules
911
+ installés — ceux du framework compris — montent leurs propres routes, services et
912
+ entités : une app qui ne définit qu'une poignée de routes en expose couramment plus
913
+ d'une centaine. Un écart d'un ordre de grandeur entre ce que tu lis dans tes
914
+ fichiers et `npx nodefony inspect routes --json | jq 'length'` n'est donc PAS une
915
+ anomalie de l'outil : c'est la différence entre ce que TU as écrit et ce que l'app
916
+ MONTE. Dès que la question porte sur l'app, le chiffre juste est celui d'`inspect` —
917
+ compter dans les sources répond à une autre question que celle posée.
918
+
919
+ **Si la commande te résiste, répare l'APPEL — ne te rabats pas sur les sources.**
920
+ C'est le réflexe qui coûte le plus cher, parce qu'il produit une réponse d'allure
921
+ normale : un shell qui manque un outil (`timeout` n'existe pas sur macOS), un `jq`
922
+ mal formé, et l'on se replie sur ce qu'on sait lire. Les fichiers répondront
923
+ toujours quelque chose — mais pas à la question posée. Relance sans le tube pour
924
+ voir la sortie brute, puis remets ton filtre.
925
+
926
+ N'invente pas d'attente : `--wait` ne rend la main qu'une fois les ports en écoute
927
+ — un `sleep` arbitraire est soit trop court (test rouge sans raison), soit du temps
928
+ perdu à chaque exécution. `npm run test:e2e` gère déjà ce cycle tout seul.
929
+
930
+ ## Méthode de travail
931
+
932
+ 1. **Budget tokens = une règle de conception** : lire ciblé via les tables
933
+ ci-dessus ; ne jamais scanner le projet entier.
934
+ 2. **Le poids du modèle est un CHOIX, et il est mesuré ici** (si ton outil sait
935
+ déléguer à des sous-agents). Une tâche couverte par un **générateur** ne
936
+ demande pas un gros modèle : c'est le générateur qui porte le savoir, pas le
937
+ modèle. Mesuré sur ce framework, « ajoute une ressource REST » rend le MÊME
938
+ résultat en modèle léger et en modèle fort — mêmes contrôles verts, écart
939
+ d'étapes dans le bruit — pour **~3× moins cher**. À l'inverse, le socle SANS
940
+ générateur (flux, session, cycle de vie) fait échouer le modèle léger environ
941
+ une fois sur deux. Donc : **léger** pour appeler un générateur, inventorier,
942
+ lire, vérifier un fait, appliquer un patron ; **fort** pour écrire du socle
943
+ sans générateur et pour arbitrer une architecture. Le test qui tranche en une
944
+ seconde : _la tâche a-t-elle une bonne réponse vérifiable ?_ Aucun nom de
945
+ modèle ici — ils changent tous les trimestres ; raisonne en poids.
946
+ 3. **Une règle = une source** : ce fichier POINTE la doc, il ne la recopie
947
+ pas ; n'y recopie rien non plus.
948
+ 4. **Batcher les modifs serveur** puis UN SEUL cycle build/restart ; le
949
+ frontend passe en HMR, zéro restart.
950
+ 5. **Vérifier avant de dire « fait »** : `npm run verify`, jamais `npm test`
951
+ seul — vitest n'inspecte AUCUN type, une app peut être verte et ne pas
952
+ compiler ; un vert ne couvre que le diff qui l'a produit ; suspecte ton
953
+ propre diff.
954
+ 6. **La mémoire de l'app est ci-dessous** : accumule les leçons DURABLES dans
955
+ la zone Notes — pas dans des commentaires éparpillés.
956
+
957
+ ## Notes de cette app (zone préservée à la régénération)
958
+
959
+ Fichier 100 % généré (nodefony <%= it.nodefonyVersion %>) — régénéré par les
960
+ commandes `create`, il ne peut pas mentir. Tes leçons propres à CETTE app vont
961
+ dans la zone ci-dessous : elle survit à la régénération.
962
+
963
+ <!-- app-notes:start -->
964
+
965
+ _(vide — leçons, gotchas et conventions propres à cette app, au fil des sessions)_
966
+
967
+ <!-- app-notes:end -->