@fougere/core 0.2.0-alpha.2 → 0.3.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 (414) hide show
  1. package/README.md +2 -1
  2. package/dist/boot/AppLifecycle.d.ts +18 -0
  3. package/dist/boot/AppLifecycle.d.ts.map +1 -0
  4. package/dist/boot/AppLifecycle.js +42 -0
  5. package/dist/boot/AppLifecycle.js.map +1 -0
  6. package/dist/boot/Emissions.d.ts +126 -0
  7. package/dist/boot/Emissions.d.ts.map +1 -0
  8. package/dist/boot/Emissions.js +233 -0
  9. package/dist/boot/Emissions.js.map +1 -0
  10. package/dist/boot/HandlerFacade.d.ts +72 -0
  11. package/dist/boot/HandlerFacade.d.ts.map +1 -0
  12. package/dist/boot/HandlerFacade.js +174 -0
  13. package/dist/boot/HandlerFacade.js.map +1 -0
  14. package/dist/boot/Lifecycle.d.ts +4 -0
  15. package/dist/boot/Lifecycle.d.ts.map +1 -0
  16. package/dist/boot/Lifecycle.js +3 -0
  17. package/dist/boot/Lifecycle.js.map +1 -0
  18. package/dist/boot/ambient-port.d.ts +38 -0
  19. package/dist/boot/ambient-port.d.ts.map +1 -0
  20. package/dist/boot/ambient-port.js +2 -0
  21. package/dist/boot/ambient-port.js.map +1 -0
  22. package/dist/boot/ambient.als.d.ts +3 -0
  23. package/dist/boot/ambient.als.d.ts.map +1 -0
  24. package/dist/boot/ambient.als.js +34 -0
  25. package/dist/boot/ambient.als.js.map +1 -0
  26. package/dist/boot/ambient.queue.d.ts +10 -0
  27. package/dist/boot/ambient.queue.d.ts.map +1 -0
  28. package/dist/boot/ambient.queue.js +60 -0
  29. package/dist/boot/ambient.queue.js.map +1 -0
  30. package/dist/boot/apply.d.ts +22 -0
  31. package/dist/boot/apply.d.ts.map +1 -0
  32. package/dist/boot/apply.js +48 -0
  33. package/dist/boot/apply.js.map +1 -0
  34. package/dist/boot/auth.d.ts +53 -0
  35. package/dist/boot/auth.d.ts.map +1 -0
  36. package/dist/boot/auth.js +2 -0
  37. package/dist/boot/auth.js.map +1 -0
  38. package/dist/{binding.d.ts → boot/binding.d.ts} +14 -17
  39. package/dist/boot/binding.d.ts.map +1 -0
  40. package/dist/{binding.js → boot/binding.js} +19 -10
  41. package/dist/boot/binding.js.map +1 -0
  42. package/dist/{boot.d.ts → boot/boot.d.ts} +25 -5
  43. package/dist/boot/boot.d.ts.map +1 -0
  44. package/dist/boot/boot.js +70 -0
  45. package/dist/boot/boot.js.map +1 -0
  46. package/dist/boot/bootstrap.d.ts.map +1 -0
  47. package/dist/boot/bootstrap.js +721 -0
  48. package/dist/boot/bootstrap.js.map +1 -0
  49. package/dist/boot/egress.d.ts +8 -0
  50. package/dist/boot/egress.d.ts.map +1 -0
  51. package/dist/boot/egress.js +11 -0
  52. package/dist/boot/egress.js.map +1 -0
  53. package/dist/boot/frame.d.ts +44 -0
  54. package/dist/boot/frame.d.ts.map +1 -0
  55. package/dist/boot/frame.js +181 -0
  56. package/dist/boot/frame.js.map +1 -0
  57. package/dist/boot/ownership.d.ts +42 -0
  58. package/dist/boot/ownership.d.ts.map +1 -0
  59. package/dist/boot/ownership.js +127 -0
  60. package/dist/boot/ownership.js.map +1 -0
  61. package/dist/boot/ports.d.ts +17 -0
  62. package/dist/boot/ports.d.ts.map +1 -0
  63. package/dist/boot/ports.js +57 -0
  64. package/dist/boot/ports.js.map +1 -0
  65. package/dist/{remote.d.ts → boot/remote.d.ts} +11 -3
  66. package/dist/boot/remote.d.ts.map +1 -0
  67. package/dist/{remote.js → boot/remote.js} +24 -26
  68. package/dist/boot/remote.js.map +1 -0
  69. package/dist/{seed.d.ts → boot/seed.d.ts} +13 -1
  70. package/dist/boot/seed.d.ts.map +1 -0
  71. package/dist/{seed.js → boot/seed.js} +24 -3
  72. package/dist/boot/seed.js.map +1 -0
  73. package/dist/boot/together.d.ts +26 -0
  74. package/dist/boot/together.d.ts.map +1 -0
  75. package/dist/boot/together.js +163 -0
  76. package/dist/boot/together.js.map +1 -0
  77. package/dist/boot/types.d.ts +260 -0
  78. package/dist/boot/types.d.ts.map +1 -0
  79. package/dist/boot/types.js.map +1 -0
  80. package/dist/builtins/config.d.ts +9 -0
  81. package/dist/builtins/config.d.ts.map +1 -1
  82. package/dist/builtins/config.js +16 -1
  83. package/dist/builtins/config.js.map +1 -1
  84. package/dist/builtins/logger.d.ts +37 -4
  85. package/dist/builtins/logger.d.ts.map +1 -1
  86. package/dist/builtins/logger.js +66 -7
  87. package/dist/builtins/logger.js.map +1 -1
  88. package/dist/config-loader.d.ts +39 -35
  89. package/dist/config-loader.d.ts.map +1 -1
  90. package/dist/config-loader.js +15 -54
  91. package/dist/config-loader.js.map +1 -1
  92. package/dist/contract/Call.d.ts +10 -0
  93. package/dist/contract/Call.d.ts.map +1 -0
  94. package/dist/contract/Call.js +15 -0
  95. package/dist/contract/Call.js.map +1 -0
  96. package/dist/contract/Invocation.d.ts +27 -0
  97. package/dist/contract/Invocation.d.ts.map +1 -0
  98. package/dist/contract/Invocation.js +59 -0
  99. package/dist/contract/Invocation.js.map +1 -0
  100. package/dist/contract/RouteAddress.d.ts +17 -0
  101. package/dist/contract/RouteAddress.d.ts.map +1 -0
  102. package/dist/contract/RouteAddress.js +38 -0
  103. package/dist/contract/RouteAddress.js.map +1 -0
  104. package/dist/contract.d.ts +25 -19
  105. package/dist/contract.d.ts.map +1 -1
  106. package/dist/contract.js +25 -10
  107. package/dist/contract.js.map +1 -1
  108. package/dist/crypto/encoding.d.ts +25 -0
  109. package/dist/crypto/encoding.d.ts.map +1 -0
  110. package/dist/crypto/encoding.js +58 -0
  111. package/dist/crypto/encoding.js.map +1 -0
  112. package/dist/crypto/node.d.ts +4 -0
  113. package/dist/crypto/node.d.ts.map +1 -0
  114. package/dist/crypto/node.js +25 -0
  115. package/dist/crypto/node.js.map +1 -0
  116. package/dist/crypto/port.d.ts +42 -0
  117. package/dist/crypto/port.d.ts.map +1 -0
  118. package/dist/crypto/port.js +19 -0
  119. package/dist/crypto/port.js.map +1 -0
  120. package/dist/crypto/webcrypto.d.ts +4 -0
  121. package/dist/crypto/webcrypto.d.ts.map +1 -0
  122. package/dist/crypto/webcrypto.js +34 -0
  123. package/dist/crypto/webcrypto.js.map +1 -0
  124. package/dist/dispatch/ArgumentResolver.d.ts +10 -0
  125. package/dist/dispatch/ArgumentResolver.d.ts.map +1 -0
  126. package/dist/dispatch/ArgumentResolver.js +12 -0
  127. package/dist/dispatch/ArgumentResolver.js.map +1 -0
  128. package/dist/dispatch/ArrayResult.d.ts +3 -0
  129. package/dist/dispatch/ArrayResult.d.ts.map +1 -0
  130. package/dist/dispatch/ArrayResult.js +11 -0
  131. package/dist/dispatch/ArrayResult.js.map +1 -0
  132. package/dist/dispatch/DispatchEvent.d.ts +18 -0
  133. package/dist/dispatch/DispatchEvent.d.ts.map +1 -0
  134. package/dist/dispatch/DispatchEvent.js +30 -0
  135. package/dist/dispatch/DispatchEvent.js.map +1 -0
  136. package/dist/dispatch/DispatchLifecycle.d.ts +9 -0
  137. package/dist/dispatch/DispatchLifecycle.d.ts.map +1 -0
  138. package/dist/dispatch/DispatchLifecycle.js +25 -0
  139. package/dist/dispatch/DispatchLifecycle.js.map +1 -0
  140. package/dist/dispatch/DispatchPort.d.ts +6 -0
  141. package/dist/dispatch/DispatchPort.d.ts.map +1 -0
  142. package/dist/dispatch/DispatchPort.js +2 -0
  143. package/dist/dispatch/DispatchPort.js.map +1 -0
  144. package/dist/dispatch/Dispatcher.d.ts +16 -0
  145. package/dist/dispatch/Dispatcher.d.ts.map +1 -0
  146. package/dist/dispatch/Dispatcher.js +44 -0
  147. package/dist/dispatch/Dispatcher.js.map +1 -0
  148. package/dist/dispatch/InFlight.d.ts +12 -0
  149. package/dist/dispatch/InFlight.d.ts.map +1 -0
  150. package/dist/dispatch/InFlight.js +46 -0
  151. package/dist/dispatch/InFlight.js.map +1 -0
  152. package/dist/dispatch/InputValidator.d.ts +7 -0
  153. package/dist/dispatch/InputValidator.d.ts.map +1 -0
  154. package/dist/dispatch/InputValidator.js +21 -0
  155. package/dist/dispatch/InputValidator.js.map +1 -0
  156. package/dist/dispatch/LocalRoutePolicy.d.ts +11 -0
  157. package/dist/dispatch/LocalRoutePolicy.d.ts.map +1 -0
  158. package/dist/dispatch/LocalRoutePolicy.js +32 -0
  159. package/dist/dispatch/LocalRoutePolicy.js.map +1 -0
  160. package/dist/dispatch/OperationExecutor.d.ts +25 -0
  161. package/dist/dispatch/OperationExecutor.d.ts.map +1 -0
  162. package/dist/dispatch/OperationExecutor.js +32 -0
  163. package/dist/dispatch/OperationExecutor.js.map +1 -0
  164. package/dist/dispatch/OperationRoute.d.ts +13 -0
  165. package/dist/dispatch/OperationRoute.d.ts.map +1 -0
  166. package/dist/dispatch/OperationRoute.js +15 -0
  167. package/dist/dispatch/OperationRoute.js.map +1 -0
  168. package/dist/dispatch/OutputProjector.d.ts +12 -0
  169. package/dist/dispatch/OutputProjector.d.ts.map +1 -0
  170. package/dist/dispatch/OutputProjector.js +30 -0
  171. package/dist/dispatch/OutputProjector.js.map +1 -0
  172. package/dist/dispatch/OutputView.d.ts +8 -0
  173. package/dist/dispatch/OutputView.d.ts.map +1 -0
  174. package/dist/dispatch/OutputView.js +10 -0
  175. package/dist/dispatch/OutputView.js.map +1 -0
  176. package/dist/dispatch/PresenterArgumentResolver.d.ts +12 -0
  177. package/dist/dispatch/PresenterArgumentResolver.d.ts.map +1 -0
  178. package/dist/dispatch/PresenterArgumentResolver.js +20 -0
  179. package/dist/dispatch/PresenterArgumentResolver.js.map +1 -0
  180. package/dist/dispatch/PresenterExecutor.d.ts +11 -0
  181. package/dist/dispatch/PresenterExecutor.d.ts.map +1 -0
  182. package/dist/dispatch/PresenterExecutor.js +56 -0
  183. package/dist/dispatch/PresenterExecutor.js.map +1 -0
  184. package/dist/dispatch/RemoteRouteResolver.d.ts +13 -0
  185. package/dist/dispatch/RemoteRouteResolver.d.ts.map +1 -0
  186. package/dist/dispatch/RemoteRouteResolver.js +18 -0
  187. package/dist/dispatch/RemoteRouteResolver.js.map +1 -0
  188. package/dist/dispatch/Route.d.ts +10 -0
  189. package/dist/dispatch/Route.d.ts.map +1 -0
  190. package/dist/dispatch/Route.js +2 -0
  191. package/dist/dispatch/Route.js.map +1 -0
  192. package/dist/dispatch/RouteNotFoundError.d.ts +10 -0
  193. package/dist/dispatch/RouteNotFoundError.d.ts.map +1 -0
  194. package/dist/dispatch/RouteNotFoundError.js +24 -0
  195. package/dist/dispatch/RouteNotFoundError.js.map +1 -0
  196. package/dist/dispatch/RoutePolicy.d.ts +8 -0
  197. package/dist/dispatch/RoutePolicy.d.ts.map +1 -0
  198. package/dist/dispatch/RoutePolicy.js +2 -0
  199. package/dist/dispatch/RoutePolicy.js.map +1 -0
  200. package/dist/dispatch/RouteRegistry.d.ts +18 -0
  201. package/dist/dispatch/RouteRegistry.d.ts.map +1 -0
  202. package/dist/dispatch/RouteRegistry.js +62 -0
  203. package/dist/dispatch/RouteRegistry.js.map +1 -0
  204. package/dist/dispatch/RouteResolver.d.ts +7 -0
  205. package/dist/dispatch/RouteResolver.d.ts.map +1 -0
  206. package/dist/dispatch/RouteResolver.js +2 -0
  207. package/dist/dispatch/RouteResolver.js.map +1 -0
  208. package/dist/dispatch/StorageGuard.d.ts +15 -0
  209. package/dist/dispatch/StorageGuard.d.ts.map +1 -0
  210. package/dist/dispatch/StorageGuard.js +63 -0
  211. package/dist/dispatch/StorageGuard.js.map +1 -0
  212. package/dist/effective-operation.d.ts +90 -0
  213. package/dist/effective-operation.d.ts.map +1 -0
  214. package/dist/effective-operation.js +450 -0
  215. package/dist/effective-operation.js.map +1 -0
  216. package/dist/emit.js +2 -2
  217. package/dist/emit.js.map +1 -1
  218. package/dist/entry/DynamicFacade.d.ts +10 -0
  219. package/dist/entry/DynamicFacade.d.ts.map +1 -0
  220. package/dist/entry/DynamicFacade.js +27 -0
  221. package/dist/entry/DynamicFacade.js.map +1 -0
  222. package/dist/entry/FacadeEntry.d.ts +11 -0
  223. package/dist/entry/FacadeEntry.d.ts.map +1 -0
  224. package/dist/entry/FacadeEntry.js +26 -0
  225. package/dist/entry/FacadeEntry.js.map +1 -0
  226. package/dist/entry/TransportEntry.d.ts +13 -0
  227. package/dist/entry/TransportEntry.d.ts.map +1 -0
  228. package/dist/entry/TransportEntry.js +24 -0
  229. package/dist/entry/TransportEntry.js.map +1 -0
  230. package/dist/frond-config.d.ts +24 -7
  231. package/dist/frond-config.d.ts.map +1 -1
  232. package/dist/frond-config.js.map +1 -1
  233. package/dist/graph.d.ts +1 -1
  234. package/dist/graph.d.ts.map +1 -1
  235. package/dist/graph.js +3 -2
  236. package/dist/graph.js.map +1 -1
  237. package/dist/identity-keys.d.ts +14 -0
  238. package/dist/identity-keys.d.ts.map +1 -0
  239. package/dist/identity-keys.js +37 -0
  240. package/dist/identity-keys.js.map +1 -0
  241. package/dist/identity.d.ts +58 -0
  242. package/dist/identity.d.ts.map +1 -0
  243. package/dist/identity.js +182 -0
  244. package/dist/identity.js.map +1 -0
  245. package/dist/imports.d.ts +1 -1
  246. package/dist/imports.d.ts.map +1 -1
  247. package/dist/imports.js +7 -3
  248. package/dist/imports.js.map +1 -1
  249. package/dist/index.d.ts +57 -38
  250. package/dist/index.d.ts.map +1 -1
  251. package/dist/index.js +38 -32
  252. package/dist/index.js.map +1 -1
  253. package/dist/loader.d.ts +16 -0
  254. package/dist/loader.d.ts.map +1 -0
  255. package/dist/loader.js +25 -0
  256. package/dist/loader.js.map +1 -0
  257. package/dist/node.d.ts +21 -0
  258. package/dist/node.d.ts.map +1 -0
  259. package/dist/node.js +24 -0
  260. package/dist/node.js.map +1 -0
  261. package/dist/orm.d.ts +69 -8
  262. package/dist/orm.d.ts.map +1 -1
  263. package/dist/orm.js +35 -2
  264. package/dist/orm.js.map +1 -1
  265. package/dist/prefab/collector.d.ts +29 -0
  266. package/dist/prefab/collector.d.ts.map +1 -0
  267. package/dist/prefab/collector.js +34 -0
  268. package/dist/prefab/collector.js.map +1 -0
  269. package/dist/{crud.d.ts → prefab/crud.d.ts} +7 -8
  270. package/dist/prefab/crud.d.ts.map +1 -0
  271. package/dist/{crud.js → prefab/crud.js} +39 -5
  272. package/dist/prefab/crud.js.map +1 -0
  273. package/dist/prefab/mirror.d.ts +52 -0
  274. package/dist/prefab/mirror.d.ts.map +1 -0
  275. package/dist/prefab/mirror.js +66 -0
  276. package/dist/prefab/mirror.js.map +1 -0
  277. package/dist/prefab/prefab.d.ts +15 -0
  278. package/dist/prefab/prefab.d.ts.map +1 -0
  279. package/dist/prefab/prefab.js +19 -0
  280. package/dist/prefab/prefab.js.map +1 -0
  281. package/dist/{presenter.d.ts → prefab/presenter.d.ts} +6 -17
  282. package/dist/prefab/presenter.d.ts.map +1 -0
  283. package/dist/{presenter.js → prefab/presenter.js} +5 -23
  284. package/dist/prefab/presenter.js.map +1 -0
  285. package/dist/prefab/repository.d.ts +104 -0
  286. package/dist/prefab/repository.d.ts.map +1 -0
  287. package/dist/prefab/repository.js +62 -0
  288. package/dist/prefab/repository.js.map +1 -0
  289. package/dist/scan/Fronds.d.ts +45 -0
  290. package/dist/scan/Fronds.d.ts.map +1 -0
  291. package/dist/scan/Fronds.js +66 -0
  292. package/dist/scan/Fronds.js.map +1 -0
  293. package/dist/scan/conventions.d.ts +74 -0
  294. package/dist/scan/conventions.d.ts.map +1 -0
  295. package/dist/scan/conventions.js +82 -0
  296. package/dist/scan/conventions.js.map +1 -0
  297. package/dist/scan/emit.d.ts +14 -0
  298. package/dist/scan/emit.d.ts.map +1 -0
  299. package/dist/scan/emit.js +211 -0
  300. package/dist/scan/emit.js.map +1 -0
  301. package/dist/scan/frond.d.ts +224 -0
  302. package/dist/scan/frond.d.ts.map +1 -0
  303. package/dist/scan/frond.js +2 -0
  304. package/dist/scan/frond.js.map +1 -0
  305. package/dist/{handler-parser.d.ts → scan/handler-parser.d.ts} +18 -9
  306. package/dist/scan/handler-parser.d.ts.map +1 -0
  307. package/dist/scan/handler-parser.js +625 -0
  308. package/dist/scan/handler-parser.js.map +1 -0
  309. package/dist/scan/scan-cache.d.ts +16 -0
  310. package/dist/scan/scan-cache.d.ts.map +1 -0
  311. package/dist/{scan-cache.js → scan/scan-cache.js} +27 -20
  312. package/dist/scan/scan-cache.js.map +1 -0
  313. package/dist/scan/scanner.d.ts +20 -0
  314. package/dist/scan/scanner.d.ts.map +1 -0
  315. package/dist/{scanner.js → scan/scanner.js} +185 -167
  316. package/dist/scan/scanner.js.map +1 -0
  317. package/dist/verify.d.ts +16 -3
  318. package/dist/verify.d.ts.map +1 -1
  319. package/dist/verify.js +21 -18
  320. package/dist/verify.js.map +1 -1
  321. package/dist/{call.d.ts → wire/call.d.ts} +70 -1
  322. package/dist/wire/call.d.ts.map +1 -0
  323. package/dist/{call.js → wire/call.js} +48 -75
  324. package/dist/wire/call.js.map +1 -0
  325. package/dist/{middleware.d.ts → wire/errors.d.ts} +18 -19
  326. package/dist/wire/errors.d.ts.map +1 -0
  327. package/dist/{middleware.js → wire/errors.js} +26 -14
  328. package/dist/wire/errors.js.map +1 -0
  329. package/dist/{errors.d.ts → wire/http-error.d.ts} +5 -6
  330. package/dist/wire/http-error.d.ts.map +1 -0
  331. package/dist/{errors.js → wire/http-error.js} +7 -6
  332. package/dist/wire/http-error.js.map +1 -0
  333. package/dist/wire/invocation.d.ts +4 -0
  334. package/dist/wire/invocation.d.ts.map +1 -0
  335. package/dist/wire/invocation.js +3 -0
  336. package/dist/wire/invocation.js.map +1 -0
  337. package/dist/{middleware/logger.d.ts → wire/loggerMiddleware.d.ts} +3 -3
  338. package/dist/wire/loggerMiddleware.d.ts.map +1 -0
  339. package/dist/{middleware/logger.js → wire/loggerMiddleware.js} +2 -2
  340. package/dist/wire/loggerMiddleware.js.map +1 -0
  341. package/dist/wire/middleware.d.ts +29 -0
  342. package/dist/wire/middleware.d.ts.map +1 -0
  343. package/dist/wire/middleware.js +20 -0
  344. package/dist/wire/middleware.js.map +1 -0
  345. package/dist/{operation.d.ts → wire/operation.d.ts} +39 -10
  346. package/dist/wire/operation.d.ts.map +1 -0
  347. package/dist/wire/operation.js +167 -0
  348. package/dist/wire/operation.js.map +1 -0
  349. package/package.json +24 -7
  350. package/dist/binding.d.ts.map +0 -1
  351. package/dist/binding.js.map +0 -1
  352. package/dist/boot.d.ts.map +0 -1
  353. package/dist/boot.js +0 -53
  354. package/dist/boot.js.map +0 -1
  355. package/dist/bootstrap.d.ts.map +0 -1
  356. package/dist/bootstrap.js +0 -879
  357. package/dist/bootstrap.js.map +0 -1
  358. package/dist/call.d.ts.map +0 -1
  359. package/dist/call.js.map +0 -1
  360. package/dist/collector.d.ts +0 -28
  361. package/dist/collector.d.ts.map +0 -1
  362. package/dist/collector.js +0 -32
  363. package/dist/collector.js.map +0 -1
  364. package/dist/crud.d.ts.map +0 -1
  365. package/dist/crud.js.map +0 -1
  366. package/dist/egress.d.ts +0 -52
  367. package/dist/egress.d.ts.map +0 -1
  368. package/dist/egress.js +0 -186
  369. package/dist/egress.js.map +0 -1
  370. package/dist/errors.d.ts.map +0 -1
  371. package/dist/errors.js.map +0 -1
  372. package/dist/handler-parser.d.ts.map +0 -1
  373. package/dist/handler-parser.js +0 -505
  374. package/dist/handler-parser.js.map +0 -1
  375. package/dist/invocation.d.ts +0 -20
  376. package/dist/invocation.d.ts.map +0 -1
  377. package/dist/invocation.js +0 -15
  378. package/dist/invocation.js.map +0 -1
  379. package/dist/middleware/error-handler.d.ts +0 -15
  380. package/dist/middleware/error-handler.d.ts.map +0 -1
  381. package/dist/middleware/error-handler.js +0 -29
  382. package/dist/middleware/error-handler.js.map +0 -1
  383. package/dist/middleware/logger.d.ts.map +0 -1
  384. package/dist/middleware/logger.js.map +0 -1
  385. package/dist/middleware.d.ts.map +0 -1
  386. package/dist/middleware.js.map +0 -1
  387. package/dist/mirror.d.ts +0 -93
  388. package/dist/mirror.d.ts.map +0 -1
  389. package/dist/mirror.js +0 -96
  390. package/dist/mirror.js.map +0 -1
  391. package/dist/operation.d.ts.map +0 -1
  392. package/dist/operation.js +0 -95
  393. package/dist/operation.js.map +0 -1
  394. package/dist/presenter.d.ts.map +0 -1
  395. package/dist/presenter.js.map +0 -1
  396. package/dist/remote.d.ts.map +0 -1
  397. package/dist/remote.js.map +0 -1
  398. package/dist/repository.d.ts +0 -55
  399. package/dist/repository.d.ts.map +0 -1
  400. package/dist/repository.js +0 -26
  401. package/dist/repository.js.map +0 -1
  402. package/dist/scan-cache.d.ts +0 -10
  403. package/dist/scan-cache.d.ts.map +0 -1
  404. package/dist/scan-cache.js.map +0 -1
  405. package/dist/scanner.d.ts +0 -34
  406. package/dist/scanner.d.ts.map +0 -1
  407. package/dist/scanner.js.map +0 -1
  408. package/dist/seed.d.ts.map +0 -1
  409. package/dist/seed.js.map +0 -1
  410. package/dist/types.d.ts +0 -421
  411. package/dist/types.d.ts.map +0 -1
  412. package/dist/types.js.map +0 -1
  413. /package/dist/{bootstrap.d.ts → boot/bootstrap.d.ts} +0 -0
  414. /package/dist/{types.js → boot/types.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DynamicFacade.js","sourceRoot":"","sources":["../../src/entry/DynamicFacade.ts"],"names":[],"mappings":"AAEA,yFAAyF;AACzF,MAAM,OAAO,aAAa;IAGK;IAFpB,UAAU,CAA4B;IAE/C,YAA6B,SAAsC;QAAtC,cAAS,GAAT,SAAS,CAA6B;QACjE,IAAI,CAAC,UAAU,GAAG,IAAI,KAAK,CAAC,EAAE,EAAE;YAC9B,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;YACrF,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;YAClD,wBAAwB,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;gBACrE,CAAC,CAAC;oBACE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;oBAC3B,QAAQ,EAAE,KAAK;oBACf,UAAU,EAAE,IAAI;oBAChB,YAAY,EAAE,IAAI;iBACnB;gBACH,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;IACL,CAAC;IAEO,eAAe,CAAC,IAAqB;QAC3C,OAAO,OAAO,IAAI,KAAK,QAAQ;eAC1B,IAAI,KAAK,MAAM;eACf,IAAI,KAAK,QAAQ;eACjB,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import type { DispatchPort } from '../dispatch/DispatchPort.js';
2
+ /** Object-shaped entry that turns facade method calls into canonical dispatches. */
3
+ export declare class FacadeEntry {
4
+ private readonly dispatcher;
5
+ private readonly entity;
6
+ private readonly surface?;
7
+ readonly operations: Record<string, Function>;
8
+ constructor(dispatcher: DispatchPort, entity: string, operationNames?: Iterable<string>, surface?: string | undefined);
9
+ private operation;
10
+ }
11
+ //# sourceMappingURL=FacadeEntry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FacadeEntry.d.ts","sourceRoot":"","sources":["../../src/entry/FacadeEntry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,oFAAoF;AACpF,qBAAa,WAAW;IAIpB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAN3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBAG3B,UAAU,EAAE,YAAY,EACxB,MAAM,EAAE,MAAM,EAC/B,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,EAChB,OAAO,CAAC,EAAE,MAAM,YAAA;IAOnC,OAAO,CAAC,SAAS;CAUlB"}
@@ -0,0 +1,26 @@
1
+ import { Call } from '../contract/Call.js';
2
+ import { RouteAddress } from '../contract/RouteAddress.js';
3
+ import { DynamicFacade } from './DynamicFacade.js';
4
+ /** Object-shaped entry that turns facade method calls into canonical dispatches. */
5
+ export class FacadeEntry {
6
+ dispatcher;
7
+ entity;
8
+ surface;
9
+ operations;
10
+ constructor(dispatcher, entity, operationNames, surface) {
11
+ this.dispatcher = dispatcher;
12
+ this.entity = entity;
13
+ this.surface = surface;
14
+ this.operations = operationNames
15
+ ? Object.fromEntries([...operationNames].map((name) => [name, this.operation(name)]))
16
+ : new DynamicFacade((name) => this.operation(name)).operations;
17
+ }
18
+ operation(name) {
19
+ return (invocation) => this.dispatcher.dispatch(new Call(new RouteAddress({
20
+ entity: this.entity,
21
+ operation: name,
22
+ ...(this.surface !== undefined ? { surface: this.surface } : {}),
23
+ }), invocation));
24
+ }
25
+ }
26
+ //# sourceMappingURL=FacadeEntry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FacadeEntry.js","sourceRoot":"","sources":["../../src/entry/FacadeEntry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,oFAAoF;AACpF,MAAM,OAAO,WAAW;IAIH;IACA;IAEA;IANV,UAAU,CAA2B;IAE9C,YACmB,UAAwB,EACxB,MAAc,EAC/B,cAAiC,EAChB,OAAgB;QAHhB,eAAU,GAAV,UAAU,CAAc;QACxB,WAAM,GAAN,MAAM,CAAQ;QAEd,YAAO,GAAP,OAAO,CAAS;QAEjC,IAAI,CAAC,UAAU,GAAG,cAAc;YAC9B,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACrF,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC;IACnE,CAAC;IAEO,SAAS,CAAC,IAAY;QAC5B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CACtD,IAAI,YAAY,CAAC;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,SAAS,EAAE,IAAI;YACf,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC,EACF,UAAU,CACX,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import type { DispatchPort } from '../dispatch/DispatchPort.js';
2
+ import type { FrondCall, Transport } from '../wire/call.js';
3
+ import type { InvocationContext } from '../contract/Invocation.js';
4
+ /** Object entry for the historical transport contract. */
5
+ export declare class TransportEntry {
6
+ private readonly dispatcher;
7
+ private readonly surface?;
8
+ constructor(dispatcher: DispatchPort, surface?: string | undefined);
9
+ receive(legacy: FrondCall, invocation: InvocationContext): Promise<unknown>;
10
+ }
11
+ /** Adapt the historical transport signature to the canonical dispatch port. */
12
+ export declare function createTransportEntry(dispatcher: DispatchPort, surface?: string): Transport;
13
+ //# sourceMappingURL=TransportEntry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransportEntry.d.ts","sourceRoot":"","sources":["../../src/entry/TransportEntry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,0DAA0D;AAC1D,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBADR,UAAU,EAAE,YAAY,EACxB,OAAO,CAAC,EAAE,MAAM,YAAA;IAGnC,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;CAU5E;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAG1F"}
@@ -0,0 +1,24 @@
1
+ import { Call } from '../contract/Call.js';
2
+ import { RouteAddress } from '../contract/RouteAddress.js';
3
+ /** Object entry for the historical transport contract. */
4
+ export class TransportEntry {
5
+ dispatcher;
6
+ surface;
7
+ constructor(dispatcher, surface) {
8
+ this.dispatcher = dispatcher;
9
+ this.surface = surface;
10
+ }
11
+ receive(legacy, invocation) {
12
+ return this.dispatcher.dispatch(new Call(new RouteAddress({
13
+ entity: legacy.entity,
14
+ operation: legacy.op,
15
+ ...(this.surface !== undefined ? { surface: this.surface } : {}),
16
+ }), invocation));
17
+ }
18
+ }
19
+ /** Adapt the historical transport signature to the canonical dispatch port. */
20
+ export function createTransportEntry(dispatcher, surface) {
21
+ const entry = new TransportEntry(dispatcher, surface);
22
+ return entry.receive.bind(entry);
23
+ }
24
+ //# sourceMappingURL=TransportEntry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransportEntry.js","sourceRoot":"","sources":["../../src/entry/TransportEntry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAK3D,0DAA0D;AAC1D,MAAM,OAAO,cAAc;IAEN;IACA;IAFnB,YACmB,UAAwB,EACxB,OAAgB;QADhB,eAAU,GAAV,UAAU,CAAc;QACxB,YAAO,GAAP,OAAO,CAAS;IAChC,CAAC;IAEJ,OAAO,CAAC,MAAiB,EAAE,UAA6B;QACtD,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CACtC,IAAI,YAAY,CAAC;YACf,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,EAAE;YACpB,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC,EACF,UAAU,CACX,CAAC,CAAC;IACL,CAAC;CACF;AAED,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAAC,UAAwB,EAAE,OAAgB;IAC7E,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACtD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC"}
@@ -1,12 +1,13 @@
1
- import type { SchemaView } from '@fougere/schema';
2
- import type { BindingPlan } from './binding.js';
1
+ import type { EntityConstructor, SchemaView } from '@fougere/schema';
2
+ import type { BindingPlan } from './boot/binding.js';
3
3
  /**
4
4
  * Per-operation override. Config takes precedence over conventions (isReadOp, facade lookup).
5
5
  *
6
6
  * Two families of keys, and they act at different depths:
7
7
  *
8
- * - **Surface** (`kind`, `handler`, `method`, `policy`) — how the op is EXPOSED. Read by
9
- * the transport adapters: `kind` decides query vs mutation and GET vs POST.
8
+ * - **Resolution** (`kind`, `handler`, `method`) — intent and implementation, resolved
9
+ * once into core's `EffectiveOperation`; every local or remote door consumes it.
10
+ * - **Projection** (`graphql`) — protocol vocabulary, read only by that adapter.
10
11
  * - **Contract** (`input`, `output`, `binding`) — what the op IS. Read by the façade,
11
12
  * and this is the third producer of an {@link OperationContract}: a prefab DECLARES its
12
13
  * ops (`Crud.__ops`), the scan DERIVES them from source, config STATES them outright.
@@ -16,20 +17,34 @@ import type { BindingPlan } from './binding.js';
16
17
  * answers that nothing else does:
17
18
  * - a method inherited from an **installed** base class — the scan resolves nothing there
18
19
  * (workspace-only heritage) and says nothing, so the op silently misses the façade;
19
- * - a signature the AST parser cannot read (a type alias, `type CurrentUser = User | null`).
20
+ * - an operation inherited from a declaration unavailable to the project's type checker.
20
21
  *
21
22
  * Config wins over both other producers — it is the most explicit statement, made by
22
23
  * whoever assembles the app. Precedence: CLI > frond config > fougere config > scan >
23
24
  * conventions.
24
25
  */
25
26
  export interface OperationOverride {
26
- /** Force operation kind (overrides isReadOp-based default). */
27
+ /**
28
+ * Force operation kind, over the naming convention (`isReadOp`).
29
+ *
30
+ * The convention reads the NAME, which is a weak signal — an app naming its reads in
31
+ * domain terms (`ofBook`, `roots`, `bySlug`) matches no prefix and every one of them is
32
+ * published as a mutation and a POST. This is the only place that fixes it.
33
+ */
27
34
  kind?: 'query' | 'command';
35
+ /**
36
+ * The GraphQL root field this op answers to. Defaults to the method name.
37
+ *
38
+ * A GraphQL root is flat, so two handlers naming a method `ofBook` claim one field and
39
+ * the build is refused, naming both. Nothing is renamed for you: the root vocabulary is
40
+ * the app's, and a derived name would move the day a distant frond gained an entity.
41
+ */
42
+ graphql?: string;
28
43
  /**
29
44
  * Handler class to delegate to (overrides the default `{Entity}Handler` lookup).
30
45
  * Class name is used to resolve from DI. E.g. `ArchiveHandler` → `app.resolve('ArchiveHandler')`.
31
46
  */
32
- handler?: abstract new (...args: any[]) => any;
47
+ handler?: EntityConstructor;
33
48
  /** Method name on `handler` (defaults to the operation name). */
34
49
  method?: string;
35
50
  /**
@@ -51,6 +66,8 @@ export interface OperationOverride {
51
66
  * from the method signature. An empty array is meaningful: "this op takes nothing".
52
67
  */
53
68
  binding?: BindingPlan;
69
+ /** Per-operation output view, below prefab declarations and above handler/entity defaults. */
70
+ output?: SchemaView;
54
71
  }
55
72
  export interface FrondConfig {
56
73
  /** Class names exposed as the frond's public contract (all surfaces). */
@@ -1 +1 @@
1
- {"version":3,"file":"frond-config.d.ts","sourceRoot":"","sources":["../src/frond-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAIhD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IAC/C,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAIhB,kFAAkF;IAClF,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;CAOvB;AAED,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpC,wFAAwF;IACxF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAChD;AAID;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAE5D;AAMD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CASzF"}
1
+ {"version":3,"file":"frond-config.d.ts","sourceRoot":"","sources":["../src/frond-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAIhB,kFAAkF;IAClF,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpC,wFAAwF;IACxF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAChD;AAID;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAE5D;AAMD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CASzF"}
@@ -1 +1 @@
1
- {"version":3,"file":"frond-config.js","sourceRoot":"","sources":["../src/frond-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AA4FrC,oDAAoD;AAEpD;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,MAAmB;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,oDAAoD;AAEpD,MAAM,kBAAkB,GAAG,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;AAEtF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACtC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"frond-config.js","sourceRoot":"","sources":["../src/frond-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAwGrC,oDAAoD;AAEpD;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,MAAmB;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,oDAAoD;AAEpD,MAAM,kBAAkB,GAAG,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;AAEtF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACtC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
package/dist/graph.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Entity dependency graph — analyzes ref() links between entities
3
3
  * to suggest domain boundaries for splitting fronds.
4
4
  */
5
- import type { FrondDescriptor } from './types.js';
5
+ import type { FrondDescriptor } from './scan/frond.js';
6
6
  export interface EntityNode {
7
7
  name: string;
8
8
  frond: string;
@@ -1 +1 @@
1
- {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,eAAe,EAAe,MAAM,YAAY,CAAC;AAE/D,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAClE;AAED,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CA6B7E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,aAAa,EAAE,CAwC/E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAC9B,cAAc,SAAI,GACjB,aAAa,EAAE,CAmDjB"}
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AACA;;;GAGG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAClE;AAED,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CA6B7E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,aAAa,EAAE,CAwC/E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAC9B,cAAc,SAAI,GACjB,aAAa,EAAE,CAmDjB"}
package/dist/graph.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { Role } from '@fougere/schema';
1
2
  /** Build the full entity dependency graph from scanned fronds. */
2
3
  export function buildGraph(fronds) {
3
4
  const nodes = new Map();
@@ -6,8 +7,8 @@ export function buildGraph(fronds) {
6
7
  for (const entity of frond.entities) {
7
8
  const refs = [];
8
9
  for (const [, field] of Object.entries(entity.entityClass.getFields())) {
9
- if (field.role?.relation?.kind === 'one') {
10
- const resolved = field.role.relation.to();
10
+ if (Role.of(field).isReference) {
11
+ const resolved = Role.of(field).target;
11
12
  const targetName = typeof resolved === 'function' && 'name' in resolved
12
13
  ? resolved.name.toLowerCase()
13
14
  : undefined;
package/dist/graph.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /** A fresh Ed25519 pair, PEM both ways. The root's and a frond's are the same kind. */
2
+ export declare function generateKeyPair(): {
3
+ privateKey: string;
4
+ publicKey: string;
5
+ };
6
+ /**
7
+ * Bind a name to a public key, signed by the root — the whole of what a receiver
8
+ * needs to recognize a frond it has never seen.
9
+ *
10
+ * `ttlDays` bounds the damage of a leaked frond key without a revocation list:
11
+ * re-issuing is a deployment, which is the same gesture that leaked it.
12
+ */
13
+ export declare function issueGrant(rootPrivateKey: string, name: string, frondPublicKey: string, ttlDays?: number): string;
14
+ //# sourceMappingURL=identity-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-keys.d.ts","sourceRoot":"","sources":["../src/identity-keys.ts"],"names":[],"mappings":"AAcA,uFAAuF;AACvF,wBAAgB,eAAe,IAAI;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAM3E;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,EACtB,OAAO,SAAK,GACX,MAAM,CAOR"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Making keys and issuing grants — the half of identity that runs at a DEPLOYMENT.
3
+ *
4
+ * It sits on the Node entry because it is the CLI speaking: `fougere keys` generates a
5
+ * pair, `fougere grant` binds a name to one, and both happen once, on a machine with a
6
+ * filesystem. Neither is reachable from a request path, so nothing here is on any hot
7
+ * path and `generateKeyPairSync` — the one gesture WebCrypto could not replace without
8
+ * changing what a key IS — never has to leave `node:crypto`.
9
+ *
10
+ * The verifying half is elsewhere (`identity.ts`) because it runs per call, everywhere.
11
+ */
12
+ import { createPrivateKey, createPublicKey, generateKeyPairSync, sign } from 'node:crypto';
13
+ import { b64url } from './crypto/encoding.js';
14
+ /** A fresh Ed25519 pair, PEM both ways. The root's and a frond's are the same kind. */
15
+ export function generateKeyPair() {
16
+ const { privateKey, publicKey } = generateKeyPairSync('ed25519');
17
+ return {
18
+ privateKey: privateKey.export({ type: 'pkcs8', format: 'pem' }).toString(),
19
+ publicKey: publicKey.export({ type: 'spki', format: 'pem' }).toString(),
20
+ };
21
+ }
22
+ /**
23
+ * Bind a name to a public key, signed by the root — the whole of what a receiver
24
+ * needs to recognize a frond it has never seen.
25
+ *
26
+ * `ttlDays` bounds the damage of a leaked frond key without a revocation list:
27
+ * re-issuing is a deployment, which is the same gesture that leaked it.
28
+ */
29
+ export function issueGrant(rootPrivateKey, name, frondPublicKey, ttlDays = 90) {
30
+ const jwk = createPublicKey(frondPublicKey).export({ format: 'jwk' });
31
+ const now = Date.now();
32
+ const header = b64url(JSON.stringify({ alg: 'EdDSA', typ: 'fougere-grant' }));
33
+ const payload = b64url(JSON.stringify({ sub: name, jwk, iat: now, exp: now + ttlDays * 86_400_000 }));
34
+ const signingInput = `${header}.${payload}`;
35
+ return `${signingInput}.${b64url(new Uint8Array(sign(null, Buffer.from(signingInput), createPrivateKey(rootPrivateKey))))}`;
36
+ }
37
+ //# sourceMappingURL=identity-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-keys.js","sourceRoot":"","sources":["../src/identity-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,uFAAuF;AACvF,MAAM,UAAU,eAAe;IAC7B,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACjE,OAAO;QACL,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE;QAC1E,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE;KACxE,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,cAAsB,EACtB,IAAY,EACZ,cAAsB,EACtB,OAAO,GAAG,EAAE;IAEZ,MAAM,GAAG,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;IACtG,MAAM,YAAY,GAAG,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC;IAC5C,OAAO,GAAG,YAAY,IAAI,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9H,CAAC"}
@@ -0,0 +1,58 @@
1
+ import type { SignedCall } from './wire/call.js';
2
+ export type { SignedCall } from './wire/call.js';
3
+ /** What a deployment hands a frond that CALLS: its own key, and the root's word for it. */
4
+ export interface FrondIdentity {
5
+ /** The frond's private key, PEM (PKCS#8). */
6
+ privateKey: string;
7
+ /** The root's statement binding this frond's name to its public key. */
8
+ grant: string;
9
+ }
10
+ /** What `verifyEnvelope` establishes — never what the caller asked for. */
11
+ export interface VerifiedCall {
12
+ /** The frond that signed, as the root named it. */
13
+ caller: string;
14
+ /** The state it asserted, now proven to come from `caller`. */
15
+ state: Record<string, unknown>;
16
+ }
17
+ /**
18
+ * Sign one call, whole: who is asking, what is asked, and on whose behalf.
19
+ *
20
+ * The private key is parsed on every call here, which is the convenience form. A process
21
+ * that signs in a request path builds its signer once — `identityFromEnv` does exactly
22
+ * that, and `sign` on the value it returns holds the parsed key.
23
+ */
24
+ export declare function signEnvelope(identity: FrondIdentity, call: SignedCall): Promise<string>;
25
+ /**
26
+ * Establish the caller, or throw. Order matters: the grant is checked against the ROOT
27
+ * first, and only the key it carries verifies the envelope — reading the envelope's own
28
+ * claim of who it is before that would be believing the thing under examination.
29
+ */
30
+ export declare function verifyEnvelope(token: string, rootPublicKey: string, presented: SignedCall): Promise<VerifiedCall>;
31
+ /** The two halves a boot needs, and the environment they come from. */
32
+ export interface CallIdentity {
33
+ /**
34
+ * Signs an outgoing call, whole. Absent when this process holds no key — it only answers.
35
+ *
36
+ * A promise because WebCrypto has no synchronous form. On Node the work stays
37
+ * synchronous inside and only the answer is wrapped: measured at 14.28 µs awaited
38
+ * against 14.30 µs called directly, while WebCrypto on the same curve costs 22.72.
39
+ */
40
+ sign?: (call: SignedCall) => Promise<string>;
41
+ /** Establishes an incoming caller, against the call that actually arrived. */
42
+ verify?: (identity: string, presented: SignedCall) => Promise<VerifiedCall>;
43
+ /** Refuse an unsigned call. True exactly when a root is trusted. */
44
+ requireIdentity: boolean;
45
+ }
46
+ /**
47
+ * What the deployment injected, read once at boot.
48
+ *
49
+ * Three variables, no config key: a private key never belongs in a committed file, and
50
+ * `fougere keys` prints exactly these. A process may hold either half or both — a frond
51
+ * that only answers has no key, one that only calls trusts no root, one in the middle
52
+ * does both.
53
+ *
54
+ * Trusting a root IS asking to refuse: there is no separate flag, because a deployment
55
+ * that names an authority and then accepts unsigned calls has said two things at once.
56
+ */
57
+ export declare function identityFromEnv(env?: Record<string, string | undefined>): Promise<CallIdentity>;
58
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAOjD,2FAA2F;AAC3F,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;CACf;AAuBD,2EAA2E;AAC3E,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAkCD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7F;AAaD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAEvH;AA+BD,uEAAuE;AACvE,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,8EAA8E;IAC9E,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5E,oEAAoE;IACpE,eAAe,EAAE,OAAO,CAAC;CAC1B;AAcD;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAgBrH"}
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Who is calling — the proof, not the claim.
3
+ *
4
+ * `InvocationContext.state` is what a caller SAYS about itself, and a split receiver
5
+ * used to believe it: identity read straight off the wire, so a reader could post
6
+ * `{ state: { user: { role: 'admin' } } }` and be one. This module is what turns that
7
+ * sack into something a receiver establishes instead of accepts.
8
+ *
9
+ * Two signatures, one public key to distribute:
10
+ *
11
+ * GRANT the root says "this key is `blog`" — issued once, at deployment
12
+ * ENVELOPE `blog` says "here is my whole call" — signed per call
13
+ *
14
+ * The envelope binds the CALL and not only its state: address, params, query, a digest
15
+ * of the body. Signing the state alone proved WHO without proving WHAT, so anyone on the
16
+ * wire could replay a captured envelope against another operation for as long as it
17
+ * stayed valid — `post.list` re-sent as `post.delete`, same signature, still good.
18
+ *
19
+ * A receiver holds the root's public key and nothing else: it validates any frond it
20
+ * has never seen, which is what a per-caller list could not do. The private root key
21
+ * signs grants and never leaves the machine that issued them.
22
+ *
23
+ * Ed25519 and a JWS-shaped grant rather than X.509: node can PARSE a certificate but
24
+ * not ISSUE one, so a real chain would mean openssl or a library. The grant says the
25
+ * same thing — a name bound to a public key, signed by the root — with no dependency.
26
+ *
27
+ * The Ed25519 itself comes through `#crypto`, which has two realizations: `node:crypto`
28
+ * everywhere, WebCrypto under `workerd`. Everything here is therefore async — WebCrypto
29
+ * has no synchronous form — and a key is parsed ONCE, into a `Signer` or a `Verifier`,
30
+ * never per call. Making the keys and issuing grants happen at a deployment and live in
31
+ * `identity-keys.ts`, on the Node entry.
32
+ */
33
+ import { crypto } from '#crypto';
34
+ import { b64url, unb64url, bytesOf, textOf, unb64 } from './crypto/encoding.js';
35
+ /** How long a call envelope stays valid. A signed call is not a session. */
36
+ const ENVELOPE_TTL_MS = 60_000;
37
+ /** Clock skew tolerated on both sides of a validity window. */
38
+ const SKEW_MS = 30_000;
39
+ /** The body's fingerprint. Absence and explicit null are different signed calls. */
40
+ async function digestOf(body) {
41
+ // The tag is outside the caller value, so no user object can collide with it. JSON's
42
+ // own omission rule still applies inside `value`, matching what crosses the wire.
43
+ const canonical = body === undefined
44
+ ? { kind: 'undefined' }
45
+ : { kind: 'value', value: body };
46
+ return b64url(await crypto.sha256(bytesOf(JSON.stringify(canonical))));
47
+ }
48
+ /** What the envelope pins, as one comparable value. */
49
+ async function boundTo(call) {
50
+ return {
51
+ entity: call.entity,
52
+ op: call.op,
53
+ params: call.params ?? {},
54
+ query: call.query ?? {},
55
+ body: await digestOf(call.body),
56
+ };
57
+ }
58
+ /** A JWS compact serialization, signed with Ed25519. */
59
+ async function signJws(header, payload, signer) {
60
+ const signingInput = `${b64url(JSON.stringify(header))}.${b64url(JSON.stringify(payload))}`;
61
+ return `${signingInput}.${b64url(await signer.sign(bytesOf(signingInput)))}`;
62
+ }
63
+ /**
64
+ * The payload, once the signature holds. Throws rather than returning a falsy value:
65
+ * every caller here is deciding whether to admit a call, and an unverified payload
66
+ * must never be reachable by forgetting a check.
67
+ */
68
+ async function verifyJws(token, verifier, what) {
69
+ const parts = token.split('.');
70
+ if (parts.length !== 3)
71
+ throw new Error(`Malformed ${what}`);
72
+ const [encodedHeader, encodedPayload, encodedSignature] = parts;
73
+ if (!await verifier.verify(bytesOf(`${encodedHeader}.${encodedPayload}`), unb64url(encodedSignature))) {
74
+ throw new Error(`Bad ${what} signature`);
75
+ }
76
+ const payload = JSON.parse(textOf(unb64url(encodedPayload)));
77
+ const now = Date.now();
78
+ if (typeof payload.exp === 'number' && now > payload.exp + SKEW_MS)
79
+ throw new Error(`Expired ${what}`);
80
+ if (typeof payload.nbf === 'number' && now < payload.nbf - SKEW_MS)
81
+ throw new Error(`${what} not yet valid`);
82
+ return payload;
83
+ }
84
+ /** Read a JWS header without verifying anything — only to find which key to verify WITH. */
85
+ function headerOf(token) {
86
+ const encodedHeader = token.split('.')[0];
87
+ if (!encodedHeader)
88
+ throw new Error('Malformed envelope');
89
+ return JSON.parse(textOf(unb64url(encodedHeader)));
90
+ }
91
+ /**
92
+ * Sign one call, whole: who is asking, what is asked, and on whose behalf.
93
+ *
94
+ * The private key is parsed on every call here, which is the convenience form. A process
95
+ * that signs in a request path builds its signer once — `identityFromEnv` does exactly
96
+ * that, and `sign` on the value it returns holds the parsed key.
97
+ */
98
+ export async function signEnvelope(identity, call) {
99
+ return sealWith(await crypto.signerOf(identity.privateKey), identity.grant, call);
100
+ }
101
+ /** The same envelope, against a key someone already parsed. */
102
+ async function sealWith(signer, grant, call) {
103
+ const now = Date.now();
104
+ const { sub } = JSON.parse(textOf(unb64url(grant.split('.')[1])));
105
+ return signJws({ alg: 'EdDSA', typ: 'fougere-call', grant }, { iss: sub, state: call.state ?? {}, bound: await boundTo(call), iat: now, exp: now + ENVELOPE_TTL_MS }, signer);
106
+ }
107
+ /**
108
+ * Establish the caller, or throw. Order matters: the grant is checked against the ROOT
109
+ * first, and only the key it carries verifies the envelope — reading the envelope's own
110
+ * claim of who it is before that would be believing the thing under examination.
111
+ */
112
+ export async function verifyEnvelope(token, rootPublicKey, presented) {
113
+ return openWith(await crypto.verifierOf(rootPublicKey), token, presented);
114
+ }
115
+ /** The same check, against a root key someone already parsed. */
116
+ async function openWith(root, token, presented) {
117
+ const { grant } = headerOf(token);
118
+ if (typeof grant !== 'string')
119
+ throw new Error('Envelope carries no grant');
120
+ const granted = await verifyJws(grant, root, 'grant');
121
+ if (typeof granted.sub !== 'string' || typeof granted.jwk !== 'object' || granted.jwk === null) {
122
+ throw new Error('Grant names no frond');
123
+ }
124
+ const payload = await verifyJws(token, await crypto.verifierOf(granted.jwk), 'envelope');
125
+ // The grant is the authority on the name; the envelope only repeats it. They disagree
126
+ // when a frond signs under someone else's name with its own key.
127
+ if (payload.iss !== granted.sub)
128
+ throw new Error(`Envelope signed by '${granted.sub}' claims to be '${String(payload.iss)}'`);
129
+ // The signature says this envelope was made by `blog`; this says it was made for THIS
130
+ // call. Without it a captured envelope is a blank cheque until it expires.
131
+ const bound = JSON.stringify(payload.bound);
132
+ if (bound !== JSON.stringify(await boundTo(presented))) {
133
+ throw new Error(`Envelope was signed for a different call than ${presented.entity}.${presented.op}`);
134
+ }
135
+ return {
136
+ caller: granted.sub,
137
+ state: payload.state ?? {},
138
+ };
139
+ }
140
+ /**
141
+ * A PEM, however the deployment chose to carry it.
142
+ *
143
+ * A PEM is multi-line and an environment variable that spans lines survives poorly —
144
+ * docker-compose, systemd and CI secret stores each mangle it differently — so
145
+ * `fougere keys` prints base64. Both forms are read here rather than one being decreed:
146
+ * a human pasting a real PEM is not making a mistake.
147
+ */
148
+ function pemOf(value) {
149
+ return value.trimStart().startsWith('-----') ? value : textOf(unb64(value));
150
+ }
151
+ /**
152
+ * What the deployment injected, read once at boot.
153
+ *
154
+ * Three variables, no config key: a private key never belongs in a committed file, and
155
+ * `fougere keys` prints exactly these. A process may hold either half or both — a frond
156
+ * that only answers has no key, one that only calls trusts no root, one in the middle
157
+ * does both.
158
+ *
159
+ * Trusting a root IS asking to refuse: there is no separate flag, because a deployment
160
+ * that names an authority and then accepts unsigned calls has said two things at once.
161
+ */
162
+ export async function identityFromEnv(env = envOfProcess()) {
163
+ const root = env.FOUGERE_ROOT ? pemOf(env.FOUGERE_ROOT) : undefined;
164
+ const privateKey = env.FOUGERE_KEY ? pemOf(env.FOUGERE_KEY) : undefined;
165
+ const grant = env.FOUGERE_GRANT;
166
+ // Async because the keys are parsed HERE, once, and both closures below capture the
167
+ // result: importing a key is per-key work, and a per-call import would put it inside
168
+ // every request. This is the one gesture a boot pays for.
169
+ const signer = privateKey ? await crypto.signerOf(privateKey) : undefined;
170
+ const rootKey = root ? await crypto.verifierOf(root) : undefined;
171
+ return {
172
+ ...(signer && grant ? { sign: (call) => sealWith(signer, grant, call) } : {}),
173
+ ...(rootKey ? { verify: (identity, presented) => openWith(rootKey, identity, presented) } : {}),
174
+ requireIdentity: Boolean(root),
175
+ };
176
+ }
177
+ /** A Worker has no `process`. Reading the global is what makes an absent one an empty env. */
178
+ function envOfProcess() {
179
+ const proc = globalThis.process;
180
+ return proc?.env ?? {};
181
+ }
182
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"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"}
package/dist/imports.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { FrondDescriptor } from './types.js';
1
+ import type { FrondDescriptor } from './scan/frond.js';
2
2
  export interface CrossFrondImport {
3
3
  /** Stable rule name — the same vocabulary `verify()` uses. */
4
4
  rule: 'cross-frond-import';
@@ -1 +1 @@
1
- {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../src/imports.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAQlD,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,IAAI,EAAE,oBAAoB,CAAC;IAC3B,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AA2BD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,GAC9D,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAoC7B"}
1
+ {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../src/imports.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAQvD,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,IAAI,EAAE,oBAAoB,CAAC;IAC3B,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AA2BD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,GAC9D,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAwC7B"}
package/dist/imports.js CHANGED
@@ -3,7 +3,7 @@ import { join, resolve, dirname, relative, isAbsolute } from 'node:path';
3
3
  let _ts;
4
4
  async function loadTs() {
5
5
  if (!_ts)
6
- _ts = (await import('typescript')).default;
6
+ _ts = (await import('@typescript/typescript6')).default;
7
7
  return _ts;
8
8
  }
9
9
  /** Is `child` inside `parent`? Path-based, so it says nothing about either existing. */
@@ -42,7 +42,11 @@ async function sourcesUnder(dir) {
42
42
  */
43
43
  export async function crossFrondImports(fronds) {
44
44
  const typescript = await loadTs();
45
- const roots = fronds.map((frond) => ({ name: frond.name, path: resolve(frond.source.path) }));
45
+ // `source.package` is the scoped name the scan already resolved — the remedy this rule
46
+ // prints must be the name that actually resolves, not one rebuilt from a prefix here.
47
+ const roots = fronds.map((frond) => ({
48
+ name: frond.name, path: resolve(frond.source.path), package: frond.source.package,
49
+ }));
46
50
  const found = [];
47
51
  for (const root of roots) {
48
52
  for (const filePath of await sourcesUnder(root.path)) {
@@ -65,7 +69,7 @@ export async function crossFrondImports(fronds) {
65
69
  message: target
66
70
  ? `'${specifier}' resolves into frond '${target.name}'. A relative path states that `
67
71
  + `these two fronds share a directory tree — a constraint nothing declares, and one `
68
- + `that nothing here can see. Write '@frond/${target.name}/…' instead: it says the `
72
+ + `that nothing here can see. Write '${target.package}/…' instead: it says the `
69
73
  + `same dependency in terms the model reads, and it is the form \`fougere sync\` writes, `
70
74
  + `so it survives '${target.name}' moving out.`
71
75
  : `'${specifier}' resolves outside frond '${root.name}', into no frond at all. `