@fougere/cli 0.12.5-alpha.0 → 0.13.0-alpha.0

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 (350) hide show
  1. package/dist/.fougere/scan.generated.d.ts +3 -0
  2. package/dist/.fougere/scan.generated.d.ts.map +1 -0
  3. package/dist/.fougere/scan.generated.js +140 -0
  4. package/dist/.fougere/scan.generated.js.map +1 -0
  5. package/dist/app/commands/BuildCommand.d.ts +18 -0
  6. package/dist/app/commands/BuildCommand.d.ts.map +1 -0
  7. package/dist/app/commands/BuildCommand.js +35 -0
  8. package/dist/app/commands/BuildCommand.js.map +1 -0
  9. package/dist/app/commands/CallCommand.d.ts +16 -0
  10. package/dist/app/commands/CallCommand.d.ts.map +1 -0
  11. package/dist/app/commands/CallCommand.js +73 -0
  12. package/dist/app/commands/CallCommand.js.map +1 -0
  13. package/dist/app/commands/CheckCommand.d.ts +11 -0
  14. package/dist/app/commands/CheckCommand.d.ts.map +1 -0
  15. package/dist/app/commands/CheckCommand.js +59 -0
  16. package/dist/app/commands/CheckCommand.js.map +1 -0
  17. package/dist/app/commands/CompletionCommand.d.ts +7 -0
  18. package/dist/app/commands/CompletionCommand.d.ts.map +1 -0
  19. package/dist/app/commands/CompletionCommand.js +23 -0
  20. package/dist/app/commands/CompletionCommand.js.map +1 -0
  21. package/dist/app/commands/DevtoolsCommand.d.ts +20 -0
  22. package/dist/app/commands/DevtoolsCommand.d.ts.map +1 -0
  23. package/dist/app/commands/DevtoolsCommand.js +79 -0
  24. package/dist/app/commands/DevtoolsCommand.js.map +1 -0
  25. package/dist/app/commands/ExplainCommand.d.ts +18 -0
  26. package/dist/app/commands/ExplainCommand.d.ts.map +1 -0
  27. package/dist/app/commands/ExplainCommand.js +111 -0
  28. package/dist/app/commands/ExplainCommand.js.map +1 -0
  29. package/dist/app/commands/FreezeCommand.d.ts +21 -0
  30. package/dist/app/commands/FreezeCommand.d.ts.map +1 -0
  31. package/dist/app/commands/FreezeCommand.js +102 -0
  32. package/dist/app/commands/FreezeCommand.js.map +1 -0
  33. package/dist/app/commands/GrantCommand.d.ts +18 -0
  34. package/dist/app/commands/GrantCommand.d.ts.map +1 -0
  35. package/dist/app/commands/GrantCommand.js +39 -0
  36. package/dist/app/commands/GrantCommand.js.map +1 -0
  37. package/dist/app/commands/GraphCommand.d.ts +11 -0
  38. package/dist/app/commands/GraphCommand.d.ts.map +1 -0
  39. package/dist/app/commands/GraphCommand.js +72 -0
  40. package/dist/app/commands/GraphCommand.js.map +1 -0
  41. package/dist/app/commands/KeysCommand.d.ts +22 -0
  42. package/dist/app/commands/KeysCommand.d.ts.map +1 -0
  43. package/dist/app/commands/KeysCommand.js +50 -0
  44. package/dist/app/commands/KeysCommand.js.map +1 -0
  45. package/dist/app/commands/LoadCommand.d.ts +19 -0
  46. package/dist/app/commands/LoadCommand.d.ts.map +1 -0
  47. package/dist/app/commands/LoadCommand.js +37 -0
  48. package/dist/app/commands/LoadCommand.js.map +1 -0
  49. package/dist/app/commands/MigrateCommand.d.ts +17 -0
  50. package/dist/app/commands/MigrateCommand.d.ts.map +1 -0
  51. package/dist/app/commands/MigrateCommand.js +47 -0
  52. package/dist/app/commands/MigrateCommand.js.map +1 -0
  53. package/dist/app/commands/NewCommand.d.ts +24 -0
  54. package/dist/app/commands/NewCommand.d.ts.map +1 -0
  55. package/dist/app/commands/NewCommand.js +108 -0
  56. package/dist/app/commands/NewCommand.js.map +1 -0
  57. package/dist/app/commands/ServeCommand.d.ts +17 -0
  58. package/dist/app/commands/ServeCommand.d.ts.map +1 -0
  59. package/dist/app/commands/ServeCommand.js +92 -0
  60. package/dist/app/commands/ServeCommand.js.map +1 -0
  61. package/dist/app/commands/grant-material.d.ts +5 -0
  62. package/dist/app/commands/grant-material.d.ts.map +1 -0
  63. package/{app/commands/grant-material.ts → dist/app/commands/grant-material.js} +2 -2
  64. package/dist/app/commands/grant-material.js.map +1 -0
  65. package/dist/fronds/analysis/entities/Build.d.ts +10 -0
  66. package/dist/fronds/analysis/entities/Build.d.ts.map +1 -0
  67. package/dist/fronds/analysis/entities/Build.js +9 -0
  68. package/dist/fronds/analysis/entities/Build.js.map +1 -0
  69. package/dist/fronds/analysis/entities/Check.d.ts +8 -0
  70. package/dist/fronds/analysis/entities/Check.d.ts.map +1 -0
  71. package/dist/fronds/analysis/entities/Check.js +7 -0
  72. package/dist/fronds/analysis/entities/Check.js.map +1 -0
  73. package/dist/fronds/analysis/entities/Devtools.d.ts +10 -0
  74. package/dist/fronds/analysis/entities/Devtools.d.ts.map +1 -0
  75. package/dist/fronds/analysis/entities/Devtools.js +9 -0
  76. package/dist/fronds/analysis/entities/Devtools.js.map +1 -0
  77. package/dist/fronds/analysis/entities/Explain.d.ts +11 -0
  78. package/dist/fronds/analysis/entities/Explain.d.ts.map +1 -0
  79. package/dist/fronds/analysis/entities/Explain.js +10 -0
  80. package/dist/fronds/analysis/entities/Explain.js.map +1 -0
  81. package/dist/fronds/analysis/entities/Freeze.d.ts +10 -0
  82. package/dist/fronds/analysis/entities/Freeze.d.ts.map +1 -0
  83. package/dist/fronds/analysis/entities/Freeze.js +9 -0
  84. package/dist/fronds/analysis/entities/Freeze.js.map +1 -0
  85. package/dist/fronds/analysis/entities/Graph.d.ts +9 -0
  86. package/dist/fronds/analysis/entities/Graph.d.ts.map +1 -0
  87. package/dist/fronds/analysis/entities/Graph.js +8 -0
  88. package/dist/fronds/analysis/entities/Graph.js.map +1 -0
  89. package/dist/fronds/analysis/entities/Load.d.ts +10 -0
  90. package/dist/fronds/analysis/entities/Load.d.ts.map +1 -0
  91. package/dist/fronds/analysis/entities/Load.js +9 -0
  92. package/dist/fronds/analysis/entities/Load.js.map +1 -0
  93. package/dist/fronds/analysis/entities/Migrate.d.ts +10 -0
  94. package/dist/fronds/analysis/entities/Migrate.d.ts.map +1 -0
  95. package/dist/fronds/analysis/entities/Migrate.js +9 -0
  96. package/dist/fronds/analysis/entities/Migrate.js.map +1 -0
  97. package/dist/fronds/analysis/handlers/BuildHandler.d.ts +50 -0
  98. package/dist/fronds/analysis/handlers/BuildHandler.d.ts.map +1 -0
  99. package/dist/fronds/analysis/handlers/BuildHandler.js +63 -0
  100. package/dist/fronds/analysis/handlers/BuildHandler.js.map +1 -0
  101. package/dist/fronds/analysis/handlers/CheckHandler.d.ts +30 -0
  102. package/dist/fronds/analysis/handlers/CheckHandler.d.ts.map +1 -0
  103. package/dist/fronds/analysis/handlers/CheckHandler.js +196 -0
  104. package/dist/fronds/analysis/handlers/CheckHandler.js.map +1 -0
  105. package/dist/fronds/analysis/handlers/DevtoolsHandler.d.ts +45 -0
  106. package/dist/fronds/analysis/handlers/DevtoolsHandler.d.ts.map +1 -0
  107. package/dist/fronds/analysis/handlers/DevtoolsHandler.js +61 -0
  108. package/dist/fronds/analysis/handlers/DevtoolsHandler.js.map +1 -0
  109. package/dist/fronds/analysis/handlers/ExplainHandler.d.ts +99 -0
  110. package/dist/fronds/analysis/handlers/ExplainHandler.d.ts.map +1 -0
  111. package/dist/fronds/analysis/handlers/ExplainHandler.js +157 -0
  112. package/dist/fronds/analysis/handlers/ExplainHandler.js.map +1 -0
  113. package/dist/fronds/analysis/handlers/FreezeHandler.d.ts +55 -0
  114. package/dist/fronds/analysis/handlers/FreezeHandler.d.ts.map +1 -0
  115. package/dist/fronds/analysis/handlers/FreezeHandler.js +145 -0
  116. package/dist/fronds/analysis/handlers/FreezeHandler.js.map +1 -0
  117. package/dist/fronds/analysis/handlers/GraphHandler.d.ts +23 -0
  118. package/dist/fronds/analysis/handlers/GraphHandler.d.ts.map +1 -0
  119. package/dist/fronds/analysis/handlers/GraphHandler.js +23 -0
  120. package/dist/fronds/analysis/handlers/GraphHandler.js.map +1 -0
  121. package/dist/fronds/analysis/handlers/LoadHandler.d.ts +26 -0
  122. package/dist/fronds/analysis/handlers/LoadHandler.d.ts.map +1 -0
  123. package/dist/fronds/analysis/handlers/LoadHandler.js +35 -0
  124. package/dist/fronds/analysis/handlers/LoadHandler.js.map +1 -0
  125. package/dist/fronds/analysis/handlers/MigrateHandler.d.ts +34 -0
  126. package/dist/fronds/analysis/handlers/MigrateHandler.d.ts.map +1 -0
  127. package/dist/fronds/analysis/handlers/MigrateHandler.js +92 -0
  128. package/dist/fronds/analysis/handlers/MigrateHandler.js.map +1 -0
  129. package/dist/fronds/analysis/services/ProjectScan.d.ts +22 -0
  130. package/dist/fronds/analysis/services/ProjectScan.d.ts.map +1 -0
  131. package/dist/fronds/analysis/services/ProjectScan.js +48 -0
  132. package/dist/fronds/analysis/services/ProjectScan.js.map +1 -0
  133. package/dist/fronds/analysis/versions.d.ts +21 -0
  134. package/dist/fronds/analysis/versions.d.ts.map +1 -0
  135. package/dist/fronds/analysis/versions.js +48 -0
  136. package/dist/fronds/analysis/versions.js.map +1 -0
  137. package/dist/fronds/scaffold/entities/BuildFrond.d.ts +7 -0
  138. package/dist/fronds/scaffold/entities/BuildFrond.d.ts.map +1 -0
  139. package/dist/fronds/scaffold/entities/BuildFrond.js +6 -0
  140. package/dist/fronds/scaffold/entities/BuildFrond.js.map +1 -0
  141. package/dist/fronds/scaffold/entities/Call.d.ts +8 -0
  142. package/dist/fronds/scaffold/entities/Call.d.ts.map +1 -0
  143. package/{fronds/scaffold/entities/Call.ts → dist/fronds/scaffold/entities/Call.js} +4 -3
  144. package/dist/fronds/scaffold/entities/Call.js.map +1 -0
  145. package/dist/fronds/scaffold/entities/Completion.d.ts +7 -0
  146. package/dist/fronds/scaffold/entities/Completion.d.ts.map +1 -0
  147. package/dist/fronds/scaffold/entities/Completion.js +6 -0
  148. package/dist/fronds/scaffold/entities/Completion.js.map +1 -0
  149. package/dist/fronds/scaffold/entities/Grant.d.ts +8 -0
  150. package/dist/fronds/scaffold/entities/Grant.d.ts.map +1 -0
  151. package/{fronds/scaffold/entities/Grant.ts → dist/fronds/scaffold/entities/Grant.js} +4 -3
  152. package/dist/fronds/scaffold/entities/Grant.js.map +1 -0
  153. package/dist/fronds/scaffold/entities/Keys.d.ts +6 -0
  154. package/dist/fronds/scaffold/entities/Keys.d.ts.map +1 -0
  155. package/{fronds/scaffold/entities/Keys.ts → dist/fronds/scaffold/entities/Keys.js} +3 -2
  156. package/dist/fronds/scaffold/entities/Keys.js.map +1 -0
  157. package/dist/fronds/scaffold/entities/New.d.ts +19 -0
  158. package/dist/fronds/scaffold/entities/New.d.ts.map +1 -0
  159. package/dist/fronds/scaffold/entities/New.js +18 -0
  160. package/dist/fronds/scaffold/entities/New.js.map +1 -0
  161. package/dist/fronds/scaffold/entities/Serve.d.ts +10 -0
  162. package/dist/fronds/scaffold/entities/Serve.d.ts.map +1 -0
  163. package/dist/fronds/scaffold/entities/Serve.js +9 -0
  164. package/dist/fronds/scaffold/entities/Serve.js.map +1 -0
  165. package/dist/fronds/scaffold/entities/Sync.d.ts +8 -0
  166. package/dist/fronds/scaffold/entities/Sync.d.ts.map +1 -0
  167. package/dist/fronds/scaffold/entities/Sync.js +7 -0
  168. package/dist/fronds/scaffold/entities/Sync.js.map +1 -0
  169. package/dist/fronds/scaffold/handlers/BuildFrondHandler.d.ts +11 -0
  170. package/dist/fronds/scaffold/handlers/BuildFrondHandler.d.ts.map +1 -0
  171. package/dist/fronds/scaffold/handlers/BuildFrondHandler.js +82 -0
  172. package/dist/fronds/scaffold/handlers/BuildFrondHandler.js.map +1 -0
  173. package/dist/fronds/scaffold/handlers/CallHandler.d.ts +10 -0
  174. package/dist/fronds/scaffold/handlers/CallHandler.d.ts.map +1 -0
  175. package/{fronds/scaffold/handlers/CallHandler.ts → dist/fronds/scaffold/handlers/CallHandler.js} +3 -2
  176. package/dist/fronds/scaffold/handlers/CallHandler.js.map +1 -0
  177. package/dist/fronds/scaffold/handlers/CompletionHandler.d.ts +9 -0
  178. package/dist/fronds/scaffold/handlers/CompletionHandler.d.ts.map +1 -0
  179. package/{fronds/scaffold/handlers/CompletionHandler.ts → dist/fronds/scaffold/handlers/CompletionHandler.js} +3 -2
  180. package/dist/fronds/scaffold/handlers/CompletionHandler.js.map +1 -0
  181. package/dist/fronds/scaffold/handlers/GrantHandler.d.ts +9 -0
  182. package/dist/fronds/scaffold/handlers/GrantHandler.d.ts.map +1 -0
  183. package/{fronds/scaffold/handlers/GrantHandler.ts → dist/fronds/scaffold/handlers/GrantHandler.js} +3 -2
  184. package/dist/fronds/scaffold/handlers/GrantHandler.js.map +1 -0
  185. package/dist/fronds/scaffold/handlers/KeysHandler.d.ts +9 -0
  186. package/dist/fronds/scaffold/handlers/KeysHandler.d.ts.map +1 -0
  187. package/{fronds/scaffold/handlers/KeysHandler.ts → dist/fronds/scaffold/handlers/KeysHandler.js} +3 -2
  188. package/dist/fronds/scaffold/handlers/KeysHandler.js.map +1 -0
  189. package/dist/fronds/scaffold/handlers/NewHandler.d.ts +9 -0
  190. package/dist/fronds/scaffold/handlers/NewHandler.d.ts.map +1 -0
  191. package/{fronds/scaffold/handlers/NewHandler.ts → dist/fronds/scaffold/handlers/NewHandler.js} +3 -2
  192. package/dist/fronds/scaffold/handlers/NewHandler.js.map +1 -0
  193. package/dist/fronds/scaffold/handlers/ServeHandler.d.ts +10 -0
  194. package/dist/fronds/scaffold/handlers/ServeHandler.d.ts.map +1 -0
  195. package/{fronds/scaffold/handlers/ServeHandler.ts → dist/fronds/scaffold/handlers/ServeHandler.js} +3 -2
  196. package/dist/fronds/scaffold/handlers/ServeHandler.js.map +1 -0
  197. package/dist/fronds/scaffold/handlers/SyncHandler.d.ts +18 -0
  198. package/dist/fronds/scaffold/handlers/SyncHandler.d.ts.map +1 -0
  199. package/dist/fronds/scaffold/handlers/SyncHandler.js +327 -0
  200. package/dist/fronds/scaffold/handlers/SyncHandler.js.map +1 -0
  201. package/dist/fronds/scaffold/services/ProjectWriter.d.ts +54 -0
  202. package/dist/fronds/scaffold/services/ProjectWriter.d.ts.map +1 -0
  203. package/dist/fronds/scaffold/services/ProjectWriter.js +315 -0
  204. package/dist/fronds/scaffold/services/ProjectWriter.js.map +1 -0
  205. package/dist/src/bin.d.ts.map +1 -0
  206. package/dist/src/bin.js +11 -0
  207. package/dist/src/bin.js.map +1 -0
  208. package/dist/src/bridge.d.ts.map +1 -0
  209. package/dist/src/bridge.js.map +1 -0
  210. package/dist/src/completion.d.ts.map +1 -0
  211. package/dist/src/completion.js.map +1 -0
  212. package/dist/src/index.d.ts.map +1 -0
  213. package/dist/src/index.js.map +1 -0
  214. package/dist/src/loader.d.ts.map +1 -0
  215. package/dist/src/loader.js.map +1 -0
  216. package/dist/src/machine.d.ts.map +1 -0
  217. package/dist/src/machine.js.map +1 -0
  218. package/dist/src/main.d.ts +2 -0
  219. package/dist/src/main.d.ts.map +1 -0
  220. package/dist/src/main.js +19 -0
  221. package/dist/src/main.js.map +1 -0
  222. package/dist/src/runner.d.ts.map +1 -0
  223. package/dist/{runner.js → src/runner.js} +22 -22
  224. package/dist/src/runner.js.map +1 -0
  225. package/dist/src/theme.d.ts.map +1 -0
  226. package/dist/src/theme.js.map +1 -0
  227. package/dist/src/typescript/EntityTypes.d.ts.map +1 -0
  228. package/dist/src/typescript/EntityTypes.js.map +1 -0
  229. package/dist/src/typescript/FacadeTypes.d.ts.map +1 -0
  230. package/dist/src/typescript/FacadeTypes.js.map +1 -0
  231. package/dist/src/typescript/syntax.d.ts.map +1 -0
  232. package/dist/src/typescript/syntax.js.map +1 -0
  233. package/dist/{ui.d.ts → src/ui.d.ts} +0 -1
  234. package/dist/src/ui.d.ts.map +1 -0
  235. package/dist/{ui.js → src/ui.js} +24 -22
  236. package/dist/src/ui.js.map +1 -0
  237. package/package.json +25 -29
  238. package/templates/frond/fronds/tsconfig.json +17 -0
  239. package/templates/workspace/fronds/tsconfig.json +2 -4
  240. package/templates/workspace/package.json +1 -1
  241. package/templates/workspace/pnpm-workspace.yaml +5 -3
  242. package/app/commands/BuildCommand.ts +0 -43
  243. package/app/commands/CallCommand.ts +0 -70
  244. package/app/commands/CheckCommand.ts +0 -70
  245. package/app/commands/CompletionCommand.ts +0 -24
  246. package/app/commands/DevtoolsCommand.ts +0 -92
  247. package/app/commands/ExplainCommand.ts +0 -136
  248. package/app/commands/FreezeCommand.ts +0 -119
  249. package/app/commands/GrantCommand.ts +0 -46
  250. package/app/commands/GraphCommand.ts +0 -91
  251. package/app/commands/KeysCommand.ts +0 -57
  252. package/app/commands/LoadCommand.ts +0 -46
  253. package/app/commands/MigrateCommand.ts +0 -61
  254. package/app/commands/NewCommand.ts +0 -137
  255. package/app/commands/ServeCommand.ts +0 -108
  256. package/dist/bin.d.ts.map +0 -1
  257. package/dist/bin.js +0 -64
  258. package/dist/bin.js.map +0 -1
  259. package/dist/bridge.d.ts.map +0 -1
  260. package/dist/bridge.js.map +0 -1
  261. package/dist/completion.d.ts.map +0 -1
  262. package/dist/completion.js.map +0 -1
  263. package/dist/index.d.ts.map +0 -1
  264. package/dist/index.js.map +0 -1
  265. package/dist/loader.d.ts.map +0 -1
  266. package/dist/loader.js.map +0 -1
  267. package/dist/machine.d.ts.map +0 -1
  268. package/dist/machine.js.map +0 -1
  269. package/dist/runner.d.ts.map +0 -1
  270. package/dist/runner.js.map +0 -1
  271. package/dist/theme.d.ts.map +0 -1
  272. package/dist/theme.js.map +0 -1
  273. package/dist/typescript/EntityTypes.d.ts.map +0 -1
  274. package/dist/typescript/EntityTypes.js.map +0 -1
  275. package/dist/typescript/FacadeTypes.d.ts.map +0 -1
  276. package/dist/typescript/FacadeTypes.js.map +0 -1
  277. package/dist/typescript/syntax.d.ts.map +0 -1
  278. package/dist/typescript/syntax.js.map +0 -1
  279. package/dist/ui.d.ts.map +0 -1
  280. package/dist/ui.js.map +0 -1
  281. package/fronds/analysis/entities/Build.ts +0 -8
  282. package/fronds/analysis/entities/Check.ts +0 -6
  283. package/fronds/analysis/entities/Devtools.ts +0 -8
  284. package/fronds/analysis/entities/Explain.ts +0 -9
  285. package/fronds/analysis/entities/Freeze.ts +0 -8
  286. package/fronds/analysis/entities/Graph.ts +0 -7
  287. package/fronds/analysis/entities/Load.ts +0 -8
  288. package/fronds/analysis/entities/Migrate.ts +0 -8
  289. package/fronds/analysis/handlers/BuildHandler.ts +0 -87
  290. package/fronds/analysis/handlers/CheckHandler.ts +0 -217
  291. package/fronds/analysis/handlers/DevtoolsHandler.ts +0 -97
  292. package/fronds/analysis/handlers/ExplainHandler.ts +0 -263
  293. package/fronds/analysis/handlers/FreezeHandler.ts +0 -183
  294. package/fronds/analysis/handlers/GraphHandler.ts +0 -38
  295. package/fronds/analysis/handlers/LoadHandler.ts +0 -44
  296. package/fronds/analysis/handlers/MigrateHandler.ts +0 -110
  297. package/fronds/analysis/services/ProjectScan.ts +0 -55
  298. package/fronds/analysis/versions.ts +0 -59
  299. package/fronds/scaffold/entities/BuildFrond.ts +0 -5
  300. package/fronds/scaffold/entities/Completion.ts +0 -5
  301. package/fronds/scaffold/entities/New.ts +0 -19
  302. package/fronds/scaffold/entities/Serve.ts +0 -8
  303. package/fronds/scaffold/entities/Sync.ts +0 -6
  304. package/fronds/scaffold/handlers/BuildFrondHandler.ts +0 -96
  305. package/fronds/scaffold/handlers/SyncHandler.ts +0 -376
  306. package/fronds/scaffold/services/ProjectWriter.ts +0 -339
  307. package/fronds/shims.d.ts +0 -9
  308. package/src/bin.ts +0 -77
  309. package/src/bridge.ts +0 -118
  310. package/src/completion.ts +0 -145
  311. package/src/index.ts +0 -1
  312. package/src/loader.ts +0 -28
  313. package/src/machine.ts +0 -17
  314. package/src/runner.ts +0 -152
  315. package/src/theme.ts +0 -19
  316. package/src/typescript/EntityTypes.ts +0 -92
  317. package/src/typescript/FacadeTypes.ts +0 -50
  318. package/src/typescript/syntax.ts +0 -11
  319. package/src/ui.ts +0 -142
  320. package/templates/flat/AGENTS.md +0 -14
  321. package/templates/flat/CLAUDE.md +0 -87
  322. package/templates/flat/_gitignore +0 -6
  323. package/templates/flat/app/app.vue +0 -25
  324. package/templates/flat/app/pages/index.vue +0 -7
  325. package/templates/flat/fougere.config.ts +0 -7
  326. package/templates/flat/nuxt.config.ts +0 -4
  327. package/templates/flat/package.json +0 -24
  328. package/templates/flat/pnpm-workspace.yaml +0 -6
  329. package/templates/flat/tsconfig.frond.json +0 -25
  330. package/templates/flat/tsconfig.json +0 -3
  331. /package/dist/{bin.d.ts → src/bin.d.ts} +0 -0
  332. /package/dist/{bridge.d.ts → src/bridge.d.ts} +0 -0
  333. /package/dist/{bridge.js → src/bridge.js} +0 -0
  334. /package/dist/{completion.d.ts → src/completion.d.ts} +0 -0
  335. /package/dist/{completion.js → src/completion.js} +0 -0
  336. /package/dist/{index.d.ts → src/index.d.ts} +0 -0
  337. /package/dist/{index.js → src/index.js} +0 -0
  338. /package/dist/{loader.d.ts → src/loader.d.ts} +0 -0
  339. /package/dist/{loader.js → src/loader.js} +0 -0
  340. /package/dist/{machine.d.ts → src/machine.d.ts} +0 -0
  341. /package/dist/{machine.js → src/machine.js} +0 -0
  342. /package/dist/{runner.d.ts → src/runner.d.ts} +0 -0
  343. /package/dist/{theme.d.ts → src/theme.d.ts} +0 -0
  344. /package/dist/{theme.js → src/theme.js} +0 -0
  345. /package/dist/{typescript → src/typescript}/EntityTypes.d.ts +0 -0
  346. /package/dist/{typescript → src/typescript}/EntityTypes.js +0 -0
  347. /package/dist/{typescript → src/typescript}/FacadeTypes.d.ts +0 -0
  348. /package/dist/{typescript → src/typescript}/FacadeTypes.js +0 -0
  349. /package/dist/{typescript → src/typescript}/syntax.d.ts +0 -0
  350. /package/dist/{typescript → src/typescript}/syntax.js +0 -0
@@ -0,0 +1,157 @@
1
+ import { addressOf, resolveEffectiveOperations, } from '@fougere/core';
2
+ import { relative } from 'node:path';
3
+ import { ANONYMOUS_SCHEMA_NAME } from '@fougere/schema';
4
+ import { remotesOf } from '@fougere/core/node';
5
+ /** Read one operation directly from the model boot and check also consume. */
6
+ export default class ExplainHandler {
7
+ projectScan;
8
+ constructor(projectScan) {
9
+ this.projectScan = projectScan;
10
+ }
11
+ /** The names this project serves — the list `explain` used to spell in a refusal only. */
12
+ async list(input) {
13
+ const { scan, model } = await this.modelOf(input.root);
14
+ const remotes = remotesOf(scan.config);
15
+ const counted = new Map();
16
+ for (const operation of model.operations) {
17
+ const frond = operation.placement.frond;
18
+ counted.set(frond, (counted.get(frond) ?? 0) + 1);
19
+ }
20
+ return {
21
+ fronds: scan.fronds.map((frond) => ({
22
+ name: frond.name,
23
+ runtime: remotes[frond.name] ? 'remote' : 'local',
24
+ remote: remotes[frond.name] ?? null,
25
+ operations: counted.get(frond.name) ?? 0,
26
+ })).sort((a, b) => a.name.localeCompare(b.name)),
27
+ operations: model.operations.map((operation) => operation.id).sort(),
28
+ };
29
+ }
30
+ async modelOf(root) {
31
+ const scan = await this.projectScan.at(root);
32
+ return {
33
+ scan,
34
+ model: resolveEffectiveOperations(scan.fronds, {
35
+ diagnostics: scan.diagnostics,
36
+ remotes: remotesOf(scan.config),
37
+ adapters: scan.config.adapters,
38
+ }),
39
+ };
40
+ }
41
+ /** Print the contract one operation will be served under. */
42
+ async execute(input) {
43
+ const requested = input.operation?.trim();
44
+ if (!requested)
45
+ throw new Error('Usage: fougere explain <Operation> [--json] [--root <directory>]');
46
+ const selector = parseSelector(requested);
47
+ const { scan, model } = await this.modelOf(input.root);
48
+ const candidates = model.operations.filter((operation) => matches(operation, selector));
49
+ if (candidates.length === 0) {
50
+ const failed = model.resolutionDiagnostics.find((diagnostic) => diagnostic.subject?.toLowerCase().includes(`.${selector.op.toLowerCase()}`)
51
+ && diagnostic.subject.toLowerCase().includes(selector.address.toLowerCase()));
52
+ if (failed)
53
+ throw new Error(`[${failed.code}] ${failed.message}`);
54
+ const available = model.operations.map((operation) => operation.id).sort();
55
+ throw new Error(`Unknown operation '${requested}'. `
56
+ + (available.length > 0
57
+ ? `Available operations: ${available.join(', ')}.`
58
+ : 'This project exposes no resolved operation.'));
59
+ }
60
+ if (candidates.length > 1) {
61
+ throw new Error(`Ambiguous operation '${requested}'. Matches: `
62
+ + `${candidates.map((operation) => operation.id).sort().join(', ')}. `
63
+ + 'Use one of these qualified names.');
64
+ }
65
+ const selected = candidates[0];
66
+ const invalid = model.resolutionDiagnostics.find((diagnostic) => diagnostic.subject?.startsWith(`${selected.handler.className}.${selected.name}`));
67
+ if (invalid)
68
+ throw new Error(`[${invalid.code}] ${invalid.message}`);
69
+ return project(selected, scan.root);
70
+ }
71
+ }
72
+ function project(operation, root) {
73
+ return {
74
+ operation: operation.operation,
75
+ handler: {
76
+ class: operation.implementation.className,
77
+ address: operation.handler.address,
78
+ method: operation.implementation.method,
79
+ file: operation.implementation.filePath
80
+ ? relative(root, operation.implementation.filePath)
81
+ : null,
82
+ },
83
+ kind: operation.kind,
84
+ description: operation.description ?? null,
85
+ input: inputTypeOf(operation),
86
+ output: outputOf(operation),
87
+ parameters: operation.parameters.map((parameter) => ({
88
+ name: parameter.name,
89
+ type: parameter.type,
90
+ optional: parameter.optional,
91
+ nullable: parameter.nullable,
92
+ undefinable: parameter.undefinable,
93
+ binding: bindingOf(parameter.binding),
94
+ })),
95
+ collectors: operation.collectors.map((collector) => ({
96
+ typeName: collector.typeName,
97
+ class: collector.className,
98
+ file: relative(root, collector.filePath),
99
+ })),
100
+ contexts: operation.contexts,
101
+ semantics: operation.semantics,
102
+ exposure: operation.exposure,
103
+ placement: {
104
+ frond: operation.placement.frond,
105
+ runtime: operation.placement.runtime,
106
+ remote: operation.placement.remote ?? null,
107
+ },
108
+ reach: operation.reach,
109
+ };
110
+ }
111
+ function parseSelector(value) {
112
+ const dot = value.lastIndexOf('.');
113
+ if (dot <= 0 || dot === value.length - 1) {
114
+ throw new Error(`Invalid operation '${value}'. Expected '<Handler>.<method>', for example 'Post.publish'.`);
115
+ }
116
+ const path = value.slice(0, dot).split('/').filter(Boolean);
117
+ if (path.length === 0 || path.length > 3) {
118
+ throw new Error(`Invalid operation '${value}'. Expected 'Post.publish', 'blog/Post.publish', or 'blog/public/Post.publish'.`);
119
+ }
120
+ const qualifiers = path.slice(0, -1);
121
+ return {
122
+ ...(qualifiers[0] ? { frond: qualifiers[0] } : {}),
123
+ ...(qualifiers[1] ? { surface: qualifiers[1] } : {}),
124
+ address: addressOf(path.at(-1)),
125
+ op: value.slice(dot + 1),
126
+ };
127
+ }
128
+ function matches(operation, selector) {
129
+ return operation.handler.address.toLowerCase() === selector.address.toLowerCase()
130
+ && operation.name === selector.op
131
+ && (!selector.frond || operation.placement.frond === selector.frond)
132
+ && (!selector.surface || operation.exposure.surfaces.includes(selector.surface));
133
+ }
134
+ function inputTypeOf(operation) {
135
+ const body = operation.parameters.find((parameter) => parameter.binding.source.kind === 'input');
136
+ return body?.type ?? schemaName(operation.input) ?? null;
137
+ }
138
+ function outputOf(operation) {
139
+ const type = schemaName(operation.output) ?? parsedOutput(operation.signature?.returnType?.raw);
140
+ return type ? { type, cardinality: operation.cardinality ?? null } : null;
141
+ }
142
+ function schemaName(schema) {
143
+ if (!schema)
144
+ return undefined;
145
+ if (schema.name && schema.name !== ANONYMOUS_SCHEMA_NAME)
146
+ return schema.name;
147
+ return schema.derivation?.sourceName;
148
+ }
149
+ function parsedOutput(raw) {
150
+ if (!raw)
151
+ return undefined;
152
+ return raw.startsWith('Promise<') && raw.endsWith('>') ? raw.slice(8, -1) : raw;
153
+ }
154
+ function bindingOf(binding) {
155
+ return { ...binding.source };
156
+ }
157
+ //# sourceMappingURL=ExplainHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExplainHandler.js","sourceRoot":"","sources":["../../../../fronds/analysis/handlers/ExplainHandler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { type SetDiff } from '@fougere/schema';
2
+ import ProjectScan from '../services/ProjectScan.js';
3
+ import type Freeze from '../entities/Freeze.js';
4
+ export interface FreezeInspection {
5
+ version: string;
6
+ /** The version this one follows, or absent when it is the first. */
7
+ previous?: string;
8
+ entities: string[];
9
+ /** What the step contains — absent when there is nothing before to step from. */
10
+ step?: SetDiff;
11
+ /** Per entity, the pairs the calculation refuses to decide. Empty means it was written. */
12
+ ambiguous: Record<string, {
13
+ removed: string;
14
+ added: string;
15
+ }[]>;
16
+ /** Whether anything reached the disk — false while a question stands. */
17
+ written: boolean;
18
+ }
19
+ /**
20
+ * Freezing a version — the artefact three readers share.
21
+ *
22
+ * A snapshot alone loses the INTENT (a field gone plus a field appeared cannot be told
23
+ * from a rename), and a step alone corrupts in silence. Both are written, and replaying
24
+ * the step over the previous snapshot must reproduce this one — which is what catches a
25
+ * missing step or a hand-edited file.
26
+ *
27
+ * Nothing is written while an ambiguity stands: the only information the code does not
28
+ * hold is what the person who made the change meant, and this is the one place asking
29
+ * for it is justified.
30
+ */
31
+ export default class FreezeHandler {
32
+ private projectScan;
33
+ constructor(projectScan: ProjectScan);
34
+ /**
35
+ * Record this version — or report what stops it, having written nothing.
36
+ *
37
+ * One op and not two: it is idempotent while it refuses, so a caller settles the
38
+ * ambiguities and calls again with `renamed`. Splitting it would let a caller write
39
+ * a version it never inspected.
40
+ *
41
+ * `json` is the presentation's, so it is not part of what this operation receives.
42
+ */
43
+ execute(input: Omit<Freeze, 'json'> & {
44
+ renamed?: Record<string, Record<string, string>>;
45
+ }): Promise<FreezeInspection>;
46
+ private record;
47
+ /**
48
+ * Today's shapes and the version before them, one entry per frond.
49
+ *
50
+ * `Fronds.schemas()` is deliberately flat — a fact heard in one frond is declared in
51
+ * another — so the per-frond map is built here, where the question IS per frond.
52
+ */
53
+ private read;
54
+ }
55
+ //# sourceMappingURL=FreezeHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FreezeHandler.d.ts","sourceRoot":"","sources":["../../../../fronds/analysis/handlers/FreezeHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0D,KAAK,OAAO,EAAE,MAAM,iBAAiB,CAAC;AACvG,OAAO,WAAW,MAAM,4BAA4B,CAAC;AAErD,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,iFAAiF;IACjF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2FAA2F;IAC3F,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC;IAChE,yEAAyE;IACzE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;IACpB,OAAO,CAAC,WAAW;IAA/B,YAAoB,WAAW,EAAE,WAAW,EAAI;IAEhD;;;;;;;;OAQG;IACG,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA2C3H;YAEa,MAAM;IAMpB;;;;;OAKG;YACW,IAAI;CAgBnB"}
@@ -0,0 +1,145 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { Bundle, lowerFirst } from '@fougere/schema';
4
+ import { VERSIONS, chainOf } from '../versions.js';
5
+ /**
6
+ * Freezing a version — the artefact three readers share.
7
+ *
8
+ * A snapshot alone loses the INTENT (a field gone plus a field appeared cannot be told
9
+ * from a rename), and a step alone corrupts in silence. Both are written, and replaying
10
+ * the step over the previous snapshot must reproduce this one — which is what catches a
11
+ * missing step or a hand-edited file.
12
+ *
13
+ * Nothing is written while an ambiguity stands: the only information the code does not
14
+ * hold is what the person who made the change meant, and this is the one place asking
15
+ * for it is justified.
16
+ */
17
+ export default class FreezeHandler {
18
+ projectScan;
19
+ constructor(projectScan) {
20
+ this.projectScan = projectScan;
21
+ }
22
+ /**
23
+ * Record this version — or report what stops it, having written nothing.
24
+ *
25
+ * One op and not two: it is idempotent while it refuses, so a caller settles the
26
+ * ambiguities and calls again with `renamed`. Splitting it would let a caller write
27
+ * a version it never inspected.
28
+ *
29
+ * `json` is the presentation's, so it is not part of what this operation receives.
30
+ */
31
+ async execute(input) {
32
+ const fronds = await this.read(input);
33
+ const version = input.version;
34
+ const entities = fronds.flatMap(({ bundle }) => Object.keys(bundle.$defs ?? {}));
35
+ // Two entrances, one map: what the entities declare, and what a caller answered.
36
+ // The answer wins — it is the later word on a question the declaration left open.
37
+ const renamed = settled(fronds.map(({ declared }) => declared), input.renamed ?? {});
38
+ // Every frond is inspected before ANY of them writes: a question standing in one
39
+ // frond must not leave the others recorded, or a second run cuts half a version.
40
+ const inspected = fronds.map(({ path, bundle, previous }) => ({
41
+ path,
42
+ bundle,
43
+ previous,
44
+ step: previous
45
+ ? Bundle.fromDescriptor(previous.bundle).diff(Bundle.fromDescriptor(bundle), { renamed })
46
+ : undefined,
47
+ }));
48
+ const ambiguous = {};
49
+ for (const { step } of inspected) {
50
+ for (const [name, answer] of Object.entries(step?.entities ?? {})) {
51
+ if (answer.ambiguous.length > 0)
52
+ ambiguous[name] = answer.ambiguous;
53
+ }
54
+ }
55
+ // Nothing on disk while a question stands. The only information the code does not
56
+ // hold is what the person who made the change meant.
57
+ if (Object.keys(ambiguous).length > 0) {
58
+ return { version, previous: previousName(inspected), entities, step: merge(inspected), ambiguous, written: false };
59
+ }
60
+ for (const { path, bundle, previous, step } of inspected) {
61
+ await this.record(path, version, bundle);
62
+ if (!previous || !step)
63
+ continue;
64
+ // `previous` is recorded rather than re-derived: the chain is a fact of the moment
65
+ // this version was cut, and a later sort of directory names is not that fact.
66
+ await writeFile(join(path, VERSIONS, version, 'from.json'), `${JSON.stringify({ previous: previous.name, renamed, ...step }, null, 2)}\n`);
67
+ }
68
+ return { version, previous: previousName(inspected), entities, step: merge(inspected), ambiguous: {}, written: true };
69
+ }
70
+ async record(root, version, bundle) {
71
+ const directory = join(root, VERSIONS, version);
72
+ await mkdir(directory, { recursive: true });
73
+ await writeFile(join(directory, 'shape.json'), `${JSON.stringify(bundle, null, 2)}\n`);
74
+ }
75
+ /**
76
+ * Today's shapes and the version before them, one entry per frond.
77
+ *
78
+ * `Fronds.schemas()` is deliberately flat — a fact heard in one frond is declared in
79
+ * another — so the per-frond map is built here, where the question IS per frond.
80
+ */
81
+ async read(input) {
82
+ const scan = await this.projectScan.at(input.root ?? undefined);
83
+ return Promise.all(scan.fronds
84
+ .filter((frond) => frond.entities.length > 0)
85
+ .map(async (frond) => ({
86
+ path: frond.source.path,
87
+ bundle: Bundle.fromSchemas(Object.fromEntries(frond.entities.map((e) => [e.name, e.entityClass]))).descriptor,
88
+ declared: declaredRenames(frond.entities),
89
+ previous: await previousOf(frond.source.path, input.version),
90
+ })));
91
+ }
92
+ }
93
+ /**
94
+ * What the entities state about themselves — `previous` says what a field WAS, while
95
+ * `Bundle.diff` reads old to new, so the pair is turned around here and nowhere else.
96
+ */
97
+ function declaredRenames(entities) {
98
+ const out = {};
99
+ for (const { name, entityClass } of entities) {
100
+ const previous = entityClass.previous;
101
+ // Keyed as `Bundle.fromSchemas` keys `$defs`, which is what `Bundle.diff` reads. Spelling the
102
+ // convention a second way here is the defect this repo has already recorded twice.
103
+ const key = lowerFirst(name);
104
+ if (previous)
105
+ out[key] = Object.fromEntries(Object.entries(previous).map(([now, was]) => [was, now]));
106
+ }
107
+ return out;
108
+ }
109
+ /** Every source of an answer, folded per entity — later sources win field by field. */
110
+ function settled(sources, answers) {
111
+ const out = {};
112
+ for (const source of [...sources, answers]) {
113
+ for (const [entity, pairs] of Object.entries(source))
114
+ out[entity] = { ...out[entity], ...pairs };
115
+ }
116
+ return out;
117
+ }
118
+ /** The version every frond steps from. They are cut together, so they agree. */
119
+ function previousName(inspected) {
120
+ return inspected.find(({ previous }) => previous)?.previous?.name;
121
+ }
122
+ /**
123
+ * One report out of several fronds — entity names are unique across a scan, so the
124
+ * union loses nothing. Writing stays per frond; only the telling is gathered.
125
+ */
126
+ function merge(inspected) {
127
+ const steps = inspected.map(({ step }) => step).filter((step) => Boolean(step));
128
+ if (steps.length === 0)
129
+ return undefined;
130
+ return {
131
+ entities: Object.assign({}, ...steps.map((step) => step.entities)),
132
+ entitiesAdded: steps.flatMap((step) => step.entitiesAdded),
133
+ entitiesRemoved: steps.flatMap((step) => step.entitiesRemoved),
134
+ };
135
+ }
136
+ /** The version this one steps from: the tip of the chain, the links read rather than sorted. */
137
+ async function previousOf(root, version) {
138
+ const chain = (await chainOf(root)).filter((cut) => cut.name !== version);
139
+ const last = chain.at(-1)?.name;
140
+ if (!last)
141
+ return undefined;
142
+ const raw = await readFile(join(root, VERSIONS, last, 'shape.json'), 'utf8').catch(() => undefined);
143
+ return raw ? { name: last, bundle: JSON.parse(raw) } : undefined;
144
+ }
145
+ //# sourceMappingURL=FreezeHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FreezeHandler.js","sourceRoot":"","sources":["../../../../fronds/analysis/handlers/FreezeHandler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type DeclaredTopology, type EntityNode, type DomainCluster } from '@fougere/core';
2
+ import ProjectScan from '../services/ProjectScan.js';
3
+ export interface GraphResult {
4
+ /** How many fronds the scan found — the descriptors themselves hold classes, which no
5
+ * operation answers: a reader outside this process would receive the husk JSON makes of them. */
6
+ totalFronds: number;
7
+ /** Where the fronds run and which reaches which — the same picture, one altitude up. */
8
+ declared: DeclaredTopology;
9
+ nodes: Record<string, EntityNode>;
10
+ clusters: DomainCluster[];
11
+ totalEntities: number;
12
+ totalRefs: number;
13
+ }
14
+ export default class GraphHandler {
15
+ private projectScan;
16
+ constructor(projectScan: ProjectScan);
17
+ /** Report how a workspace's fronds and entities reference each other. */
18
+ execute(input: {
19
+ root?: string;
20
+ minEntities?: number;
21
+ }): Promise<GraphResult>;
22
+ }
23
+ //# sourceMappingURL=GraphHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphHandler.d.ts","sourceRoot":"","sources":["../../../../fronds/analysis/handlers/GraphHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAC3D,MAAM,eAAe,CAAC;AACvB,OAAO,WAAW,MAAM,4BAA4B,CAAC;AAGrD,MAAM,WAAW,WAAW;IAC1B;qGACiG;IACjG,WAAW,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,CAAC,OAAO,OAAO,YAAY;IACnB,OAAO,CAAC,WAAW;IAA/B,YAAoB,WAAW,EAAE,WAAW,EAAI;IAEhD,yEAAyE;IACnE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAalF;CACF"}
@@ -0,0 +1,23 @@
1
+ import { buildGraph, declaredTopologyOf, suggestSplit, } from '@fougere/core';
2
+ import { remotesOf } from '@fougere/core/node';
3
+ export default class GraphHandler {
4
+ projectScan;
5
+ constructor(projectScan) {
6
+ this.projectScan = projectScan;
7
+ }
8
+ /** Report how a workspace's fronds and entities reference each other. */
9
+ async execute(input) {
10
+ const { fronds, config } = await this.projectScan.at(input.root);
11
+ const nodes = buildGraph(fronds);
12
+ const clusters = suggestSplit(nodes);
13
+ return {
14
+ totalFronds: fronds.length,
15
+ declared: declaredTopologyOf({ fronds, remotes: remotesOf(config) }),
16
+ nodes: Object.fromEntries(nodes),
17
+ clusters,
18
+ totalEntities: nodes.size,
19
+ totalRefs: [...nodes.values()].reduce((sum, n) => sum + n.refs.length, 0),
20
+ };
21
+ }
22
+ }
23
+ //# sourceMappingURL=GraphHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphHandler.js","sourceRoot":"","sources":["../../../../fronds/analysis/handlers/GraphHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAAE,kBAAkB,EAAE,YAAY,GAE7C,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAc/C,MAAM,CAAC,OAAO,OAAO,YAAY;IACX,WAAW;IAA/B,YAAoB,WAAwB;2BAAxB,WAAW;IAAgB,CAAC;IAEhD,yEAAyE;IACzE,KAAK,CAAC,OAAO,CAAC,KAA8C;QAC1D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QAErC,OAAO;YACL,WAAW,EAAE,MAAM,CAAC,MAAM;YAC1B,QAAQ,EAAE,kBAAkB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YACpE,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC;YAChC,QAAQ;YACR,aAAa,EAAE,KAAK,CAAC,IAAI;YACzB,SAAS,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;SAC1E,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ import ProjectScan from '../services/ProjectScan.js';
2
+ export interface LoadScenario {
3
+ /** Where it was written, or `null` when it was only printed. */
4
+ file: string | null;
5
+ facade: string;
6
+ /** Every operation the scenario calls, in the order it lists them. */
7
+ operations: string[];
8
+ script: string;
9
+ }
10
+ /**
11
+ * A load scenario, written from what the project serves.
12
+ *
13
+ * Read from the SCAN rather than a boot: an app that boots runs its migrations and plants its
14
+ * seeds, and a command that describes a project has no business writing to its database.
15
+ */
16
+ export default class LoadHandler {
17
+ private projectScan;
18
+ constructor(projectScan: ProjectScan);
19
+ /** Generate a k6 scenario covering every operation the default facade answers. */
20
+ execute(input: {
21
+ root?: string;
22
+ facade?: string;
23
+ out?: string;
24
+ }): Promise<LoadScenario>;
25
+ }
26
+ //# sourceMappingURL=LoadHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadHandler.d.ts","sourceRoot":"","sources":["../../../../fronds/analysis/handlers/LoadHandler.ts"],"names":[],"mappings":"AAGA,OAAO,WAAW,MAAM,4BAA4B,CAAC;AAGrD,MAAM,WAAW,YAAY;IAC3B,gEAAgE;IAChE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAClB,OAAO,CAAC,WAAW;IAA/B,YAAoB,WAAW,EAAE,WAAW,EAAI;IAEhD,kFAAkF;IAC5E,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAiB5F;CACF"}
@@ -0,0 +1,35 @@
1
+ import { loadScript, reachableOps } from '@fougere/testing/load';
2
+ import { writeFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { remotesOf } from '@fougere/core/node';
5
+ /**
6
+ * A load scenario, written from what the project serves.
7
+ *
8
+ * Read from the SCAN rather than a boot: an app that boots runs its migrations and plants its
9
+ * seeds, and a command that describes a project has no business writing to its database.
10
+ */
11
+ export default class LoadHandler {
12
+ projectScan;
13
+ constructor(projectScan) {
14
+ this.projectScan = projectScan;
15
+ }
16
+ /** Generate a k6 scenario covering every operation the default facade answers. */
17
+ async execute(input) {
18
+ const { root, fronds, config } = await this.projectScan.at(input.root);
19
+ const facade = input.facade?.trim() || undefined;
20
+ // The topology statement travels with it: an op that crosses a process is not held to the
21
+ // same figure as one that never leaves, and `remotes:` is what says which is which.
22
+ const remotes = remotesOf(config);
23
+ const script = loadScript({ fronds }, { ...(facade ? { facade } : {}), remotes });
24
+ const file = input.out === undefined ? join(root, 'load.js') : input.out || null;
25
+ if (file)
26
+ await writeFile(file, script, 'utf8');
27
+ return {
28
+ file,
29
+ facade: facade ?? 'http://127.0.0.1:3000/_fougere/call',
30
+ operations: reachableOps({ fronds }, {}, remotes).map((one) => one.method),
31
+ script,
32
+ };
33
+ }
34
+ }
35
+ //# sourceMappingURL=LoadHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadHandler.js","sourceRoot":"","sources":["../../../../fronds/analysis/handlers/LoadHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAW/C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IACV,WAAW;IAA/B,YAAoB,WAAwB;2BAAxB,WAAW;IAAgB,CAAC;IAEhD,kFAAkF;IAClF,KAAK,CAAC,OAAO,CAAC,KAAuD;QACnE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;QACjD,0FAA0F;QAC1F,oFAAoF;QACpF,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAElF,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC;QACjF,IAAI,IAAI;YAAE,MAAM,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAEhD,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,MAAM,IAAI,qCAAqC;YACvD,UAAU,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;YAC1E,MAAM;SACP,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,34 @@
1
+ import type { Plan, StepChange } from '@fougere/adapter-sql';
2
+ import ProjectScan from '../services/ProjectScan.js';
3
+ import type Migrate from '../entities/Migrate.js';
4
+ export interface MigrationPlan {
5
+ /** Versions whose step was read, oldest first. */
6
+ chain: string[];
7
+ changes: StepChange[];
8
+ refusals: Plan['refusals'];
9
+ /** The statements actually run — empty unless `apply` was asked for. */
10
+ ran: string[];
11
+ }
12
+ /**
13
+ * Catching the database up with the frozen chain.
14
+ *
15
+ * Every step is replayed in order and what has already happened is SKIPPED, read off the
16
+ * columns themselves rather than a ledger of applied migrations. That is what makes the
17
+ * chain safe to replay whole: nothing here has to know which version the database sits
18
+ * at, and a column renamed by hand is seen rather than contradicted.
19
+ *
20
+ * The additive pass is not repeated here — a boot already creates missing tables and
21
+ * columns. What this adds is the half that touches live data, and only what a human
22
+ * declared at `fougere freeze`.
23
+ */
24
+ export default class MigrateHandler {
25
+ private projectScan;
26
+ constructor(projectScan: ProjectScan);
27
+ /**
28
+ * Realise the frozen steps this database has not caught up with.
29
+ *
30
+ * `json` is the presentation's, so it is not part of what this operation receives.
31
+ */
32
+ execute(input: Omit<Migrate, 'json'>): Promise<MigrationPlan>;
33
+ }
34
+ //# sourceMappingURL=MigrateHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrateHandler.d.ts","sourceRoot":"","sources":["../../../../fronds/analysis/handlers/MigrateHandler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,WAAW,MAAM,4BAA4B,CAAC;AAErD,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAElD,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3B,wEAAwE;IACxE,GAAG,EAAE,MAAM,EAAE,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;IACrB,OAAO,CAAC,WAAW;IAA/B,YAAoB,WAAW,EAAE,WAAW,EAAI;IAEhD;;;;OAIG;IACG,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAmDlE;CACF"}