@storyshelf/core 0.6.2 → 0.8.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 (727) hide show
  1. package/README.md +49 -32
  2. package/dist/adapter/capture-queue.d.mts +44 -4
  3. package/dist/adapter/capture-runner.d.mts +134 -12
  4. package/dist/adapter/capture-runner.mjs +9 -12
  5. package/dist/adapter/database.d.mts +89 -10
  6. package/dist/adapter/database.mjs +4 -3
  7. package/dist/adapter/database.mjs.map +1 -1
  8. package/dist/adapter/design.d.mts +83 -0
  9. package/dist/adapter/design.mjs +27 -0
  10. package/dist/adapter/design.mjs.map +1 -0
  11. package/dist/adapter/email-sender.d.mts +0 -2
  12. package/dist/adapter/metadata.d.mts +3 -12
  13. package/dist/adapter/notifier.d.mts +6 -3
  14. package/dist/adapter/notifier.mjs +5 -1
  15. package/dist/adapter/oauth.d.mts +50 -0
  16. package/dist/adapter/setup.d.mts +4 -7
  17. package/dist/adapter/setup.mjs +3 -3
  18. package/dist/adapter/setup.mjs.map +1 -1
  19. package/dist/adapter/storage.d.mts +1 -3
  20. package/dist/adapter/webhook-events.d.mts +0 -2
  21. package/dist/adapter/webhook-events.mjs +13 -14
  22. package/dist/adapter/webhook-events.mjs.map +1 -1
  23. package/dist/adapters/capture-target-offers.d.mts +26 -0
  24. package/dist/adapters/capture-target-offers.mjs +57 -0
  25. package/dist/adapters/capture-target-offers.mjs.map +1 -0
  26. package/dist/adapters/capture-target.d.mts +69 -0
  27. package/dist/adapters/capture-target.mjs +75 -0
  28. package/dist/adapters/capture-target.mjs.map +1 -0
  29. package/dist/adapters/notifier/build-comment.d.mts +22 -0
  30. package/dist/adapters/notifier/build-comment.mjs +23 -0
  31. package/dist/adapters/notifier/build-comment.mjs.map +1 -0
  32. package/dist/adapters/notifier/build-state.d.mts +97 -0
  33. package/dist/adapters/notifier/build-state.mjs +217 -0
  34. package/dist/adapters/notifier/build-state.mjs.map +1 -0
  35. package/dist/adapters/notifier/events.d.mts +4 -4
  36. package/dist/adapters/notifier/events.mjs +32 -20
  37. package/dist/adapters/notifier/events.mjs.map +1 -1
  38. package/dist/adapters/notifier/format.d.mts +0 -2
  39. package/dist/adapters/notifier/format.mjs +1 -2
  40. package/dist/adapters/notifier/provider.d.mts +53 -9
  41. package/dist/adapters/notifier/provider.mjs +11 -0
  42. package/dist/adapters/notifier/provider.mjs.map +1 -0
  43. package/dist/adapters/notifier/state.d.mts +22 -0
  44. package/dist/adapters/notifier/state.mjs +65 -0
  45. package/dist/adapters/notifier/state.mjs.map +1 -0
  46. package/dist/adapters/notifier/types.d.mts +51 -4
  47. package/dist/adapters/remote-browser.d.mts +168 -0
  48. package/dist/adapters/remote-browser.mjs +201 -0
  49. package/dist/adapters/remote-browser.mjs.map +1 -0
  50. package/dist/adapters/remote-lease-attempt.mjs +39 -0
  51. package/dist/adapters/remote-lease-attempt.mjs.map +1 -0
  52. package/dist/adapters/remote-lease-error.d.mts +25 -0
  53. package/dist/adapters/remote-lease-error.mjs +54 -0
  54. package/dist/adapters/remote-lease-error.mjs.map +1 -0
  55. package/dist/adapters/remote-lease-held.d.mts +15 -0
  56. package/dist/adapters/remote-lease-held.mjs +86 -0
  57. package/dist/adapters/remote-lease-held.mjs.map +1 -0
  58. package/dist/adapters/remote-lease-shutdown.d.mts +12 -0
  59. package/dist/adapters/remote-lease-shutdown.mjs +32 -0
  60. package/dist/adapters/remote-lease-shutdown.mjs.map +1 -0
  61. package/dist/adapters/remote-lease.d.mts +39 -0
  62. package/dist/adapters/remote-lease.mjs +175 -0
  63. package/dist/adapters/remote-lease.mjs.map +1 -0
  64. package/dist/adapters/remote-limiter.mjs +121 -0
  65. package/dist/adapters/remote-limiter.mjs.map +1 -0
  66. package/dist/adapters/remote-pool.d.mts +56 -0
  67. package/dist/adapters/remote-pool.mjs +195 -0
  68. package/dist/adapters/remote-pool.mjs.map +1 -0
  69. package/dist/adapters/render-runs.d.mts +23 -0
  70. package/dist/adapters/render-runs.mjs +40 -0
  71. package/dist/adapters/render-runs.mjs.map +1 -0
  72. package/dist/adapters/setup-runner.d.mts +0 -2
  73. package/dist/adapters/setup-runner.mjs +3 -6
  74. package/dist/adapters/setup-runner.mjs.map +1 -1
  75. package/dist/adapters/sources.d.mts +10 -0
  76. package/dist/adapters/sources.mjs +19 -0
  77. package/dist/adapters/sources.mjs.map +1 -0
  78. package/dist/adapters/validate.d.mts +0 -2
  79. package/dist/adapters/validate.mjs +27 -20
  80. package/dist/adapters/validate.mjs.map +1 -1
  81. package/dist/ai.d.mts +103 -0
  82. package/dist/ai.mjs +18 -0
  83. package/dist/ai.mjs.map +1 -0
  84. package/dist/auth.d.mts +0 -2
  85. package/dist/auth.mjs +1 -2
  86. package/dist/brand-packs.d.mts +0 -2
  87. package/dist/brand-packs.mjs +0 -1
  88. package/dist/capture/a11y/axe-source.d.mts +16 -0
  89. package/dist/capture/a11y/axe-source.mjs +36 -0
  90. package/dist/capture/a11y/axe-source.mjs.map +1 -0
  91. package/dist/capture/a11y/in-page.d.mts +25 -0
  92. package/dist/capture/a11y/in-page.mjs +59 -0
  93. package/dist/capture/a11y/in-page.mjs.map +1 -0
  94. package/dist/capture/a11y/map.d.mts +22 -0
  95. package/dist/capture/a11y/map.mjs +47 -0
  96. package/dist/capture/a11y/map.mjs.map +1 -0
  97. package/dist/capture/a11y/options.d.mts +21 -0
  98. package/dist/capture/a11y/options.mjs +74 -0
  99. package/dist/capture/a11y/options.mjs.map +1 -0
  100. package/dist/capture/adapter.d.mts +46 -5
  101. package/dist/capture/adapter.mjs +1 -2
  102. package/dist/capture/adapter.mjs.map +1 -1
  103. package/dist/capture/affected.d.mts +2 -2
  104. package/dist/capture/affected.mjs +14 -6
  105. package/dist/capture/affected.mjs.map +1 -1
  106. package/dist/capture/attempt-logger.mjs +83 -0
  107. package/dist/capture/attempt-logger.mjs.map +1 -0
  108. package/dist/capture/browsers.d.mts +33 -0
  109. package/dist/capture/browsers.mjs +66 -0
  110. package/dist/capture/browsers.mjs.map +1 -0
  111. package/dist/capture/build-state/deliver.d.mts +30 -0
  112. package/dist/capture/build-state/deliver.mjs +117 -0
  113. package/dist/capture/build-state/deliver.mjs.map +1 -0
  114. package/dist/capture/build-state/index.d.mts +8 -0
  115. package/dist/capture/build-state/notify-job.d.mts +54 -0
  116. package/dist/capture/build-state/notify-job.mjs +132 -0
  117. package/dist/capture/build-state/notify-job.mjs.map +1 -0
  118. package/dist/capture/build-state/publisher.d.mts +21 -0
  119. package/dist/capture/build-state/publisher.mjs +106 -0
  120. package/dist/capture/build-state/publisher.mjs.map +1 -0
  121. package/dist/capture/build-state/resume.d.mts +7 -0
  122. package/dist/capture/build-state/resume.mjs +46 -0
  123. package/dist/capture/build-state/resume.mjs.map +1 -0
  124. package/dist/capture/build-state/types.d.mts +47 -0
  125. package/dist/capture/catalog/catalogue.d.mts +20 -0
  126. package/dist/capture/catalog/catalogue.mjs +52 -0
  127. package/dist/capture/catalog/catalogue.mjs.map +1 -0
  128. package/dist/capture/catalog/components.d.mts +21 -0
  129. package/dist/capture/catalog/components.mjs +54 -0
  130. package/dist/capture/catalog/components.mjs.map +1 -0
  131. package/dist/capture/catalog/history.d.mts +28 -0
  132. package/dist/capture/catalog/history.mjs +50 -0
  133. package/dist/capture/catalog/history.mjs.map +1 -0
  134. package/dist/capture/catalog/hook.d.mts +12 -0
  135. package/dist/capture/catalog/hook.mjs +18 -0
  136. package/dist/capture/catalog/hook.mjs.map +1 -0
  137. package/dist/capture/catalog/index.d.mts +11 -0
  138. package/dist/capture/catalog/load.d.mts +24 -0
  139. package/dist/capture/catalog/load.mjs +48 -0
  140. package/dist/capture/catalog/load.mjs.map +1 -0
  141. package/dist/capture/catalog/parse.d.mts +13 -0
  142. package/dist/capture/catalog/parse.mjs +55 -0
  143. package/dist/capture/catalog/parse.mjs.map +1 -0
  144. package/dist/capture/catalog/read.d.mts +15 -0
  145. package/dist/capture/catalog/read.mjs +39 -0
  146. package/dist/capture/catalog/read.mjs.map +1 -0
  147. package/dist/capture/catalog/types.d.mts +31 -0
  148. package/dist/capture/comparison-reference.d.mts +27 -0
  149. package/dist/capture/comparison-reference.mjs +75 -0
  150. package/dist/capture/comparison-reference.mjs.map +1 -0
  151. package/dist/capture/consumer/capture-handler.d.mts +56 -0
  152. package/dist/capture/consumer/capture-handler.mjs +117 -0
  153. package/dist/capture/consumer/capture-handler.mjs.map +1 -0
  154. package/dist/capture/consumer/idle.d.mts +15 -0
  155. package/dist/capture/consumer/idle.mjs +24 -0
  156. package/dist/capture/consumer/idle.mjs.map +1 -0
  157. package/dist/capture/consumer/index.d.mts +11 -0
  158. package/dist/capture/consumer/index.mjs +138 -0
  159. package/dist/capture/consumer/index.mjs.map +1 -0
  160. package/dist/capture/consumer/loop.mjs +109 -0
  161. package/dist/capture/consumer/loop.mjs.map +1 -0
  162. package/dist/capture/consumer/metrics.d.mts +39 -0
  163. package/dist/capture/consumer/metrics.mjs +37 -0
  164. package/dist/capture/consumer/metrics.mjs.map +1 -0
  165. package/dist/capture/consumer/retry.d.mts +31 -0
  166. package/dist/capture/consumer/retry.mjs +33 -0
  167. package/dist/capture/consumer/retry.mjs.map +1 -0
  168. package/dist/capture/consumer/run-job.mjs +194 -0
  169. package/dist/capture/consumer/run-job.mjs.map +1 -0
  170. package/dist/capture/consumer/startup.mjs +37 -0
  171. package/dist/capture/consumer/startup.mjs.map +1 -0
  172. package/dist/capture/consumer/types.d.mts +95 -0
  173. package/dist/capture/crash-failure.d.mts +23 -0
  174. package/dist/capture/crash-failure.mjs +69 -0
  175. package/dist/capture/crash-failure.mjs.map +1 -0
  176. package/dist/capture/db-queue/cadence.d.mts +30 -0
  177. package/dist/capture/db-queue/cadence.mjs +37 -0
  178. package/dist/capture/db-queue/cadence.mjs.map +1 -0
  179. package/dist/capture/db-queue/claim.d.mts +7 -0
  180. package/dist/capture/db-queue/claim.mjs +148 -0
  181. package/dist/capture/db-queue/claim.mjs.map +1 -0
  182. package/dist/capture/db-queue/clock.mjs +11 -0
  183. package/dist/capture/db-queue/clock.mjs.map +1 -0
  184. package/dist/capture/db-queue/codec.mjs +75 -0
  185. package/dist/capture/db-queue/codec.mjs.map +1 -0
  186. package/dist/capture/db-queue/index.d.mts +18 -0
  187. package/dist/capture/db-queue/index.mjs +89 -0
  188. package/dist/capture/db-queue/index.mjs.map +1 -0
  189. package/dist/capture/db-queue/keeper.d.mts +34 -0
  190. package/dist/capture/db-queue/keeper.mjs +91 -0
  191. package/dist/capture/db-queue/keeper.mjs.map +1 -0
  192. package/dist/capture/db-queue/lease.mjs +45 -0
  193. package/dist/capture/db-queue/lease.mjs.map +1 -0
  194. package/dist/capture/db-queue/lifecycle.mjs +35 -0
  195. package/dist/capture/db-queue/lifecycle.mjs.map +1 -0
  196. package/dist/capture/db-queue/operations.mjs +93 -0
  197. package/dist/capture/db-queue/operations.mjs.map +1 -0
  198. package/dist/capture/db-queue/poll-loop.d.mts +28 -0
  199. package/dist/capture/db-queue/poll-loop.mjs +88 -0
  200. package/dist/capture/db-queue/poll-loop.mjs.map +1 -0
  201. package/dist/capture/db-queue/poll.d.mts +8 -0
  202. package/dist/capture/db-queue/poll.mjs +68 -0
  203. package/dist/capture/db-queue/poll.mjs.map +1 -0
  204. package/dist/capture/db-queue/timers.d.mts +10 -0
  205. package/dist/capture/db-queue/timers.mjs +36 -0
  206. package/dist/capture/db-queue/timers.mjs.map +1 -0
  207. package/dist/capture/db-queue/types.d.mts +81 -0
  208. package/dist/capture/db-queue/types.mjs +11 -0
  209. package/dist/capture/db-queue/types.mjs.map +1 -0
  210. package/dist/capture/db-queue/wake.mjs +47 -0
  211. package/dist/capture/db-queue/wake.mjs.map +1 -0
  212. package/dist/capture/design.mjs +38 -0
  213. package/dist/capture/design.mjs.map +1 -0
  214. package/dist/capture/diff-record.mjs +24 -5
  215. package/dist/capture/diff-record.mjs.map +1 -1
  216. package/dist/capture/dispatch.d.mts +13 -10
  217. package/dist/capture/dispatch.mjs +102 -111
  218. package/dist/capture/dispatch.mjs.map +1 -1
  219. package/dist/capture/enrich.mjs +59 -0
  220. package/dist/capture/enrich.mjs.map +1 -0
  221. package/dist/capture/failure-sets.mjs +21 -0
  222. package/dist/capture/failure-sets.mjs.map +1 -0
  223. package/dist/capture/fingerprint.d.mts +40 -0
  224. package/dist/capture/fingerprint.mjs +82 -0
  225. package/dist/capture/fingerprint.mjs.map +1 -0
  226. package/dist/capture/forked/channel.d.mts +23 -0
  227. package/dist/capture/forked/child.d.mts +32 -0
  228. package/dist/capture/forked/child.mjs +201 -0
  229. package/dist/capture/forked/child.mjs.map +1 -0
  230. package/dist/capture/forked/crash-tracker.mjs +22 -0
  231. package/dist/capture/forked/crash-tracker.mjs.map +1 -0
  232. package/dist/capture/forked/decision.d.mts +24 -0
  233. package/dist/capture/forked/decision.mjs +26 -0
  234. package/dist/capture/forked/decision.mjs.map +1 -0
  235. package/dist/capture/forked/exit.mjs +11 -0
  236. package/dist/capture/forked/exit.mjs.map +1 -0
  237. package/dist/capture/forked/fork.d.mts +29 -0
  238. package/dist/capture/forked/fork.mjs +92 -0
  239. package/dist/capture/forked/fork.mjs.map +1 -0
  240. package/dist/capture/forked/forked-capture.d.mts +38 -0
  241. package/dist/capture/forked/forked-capture.mjs +239 -0
  242. package/dist/capture/forked/forked-capture.mjs.map +1 -0
  243. package/dist/capture/forked/lease-book.mjs +45 -0
  244. package/dist/capture/forked/lease-book.mjs.map +1 -0
  245. package/dist/capture/forked/protocol.d.mts +36 -0
  246. package/dist/capture/forked/protocol.mjs +24 -0
  247. package/dist/capture/forked/protocol.mjs.map +1 -0
  248. package/dist/capture/forked/runs.mjs +74 -0
  249. package/dist/capture/forked/runs.mjs.map +1 -0
  250. package/dist/capture/guards.mjs +1 -2
  251. package/dist/capture/ignore-regions.d.mts +36 -0
  252. package/dist/capture/ignore-regions.mjs +65 -0
  253. package/dist/capture/ignore-regions.mjs.map +1 -0
  254. package/dist/capture/isolate.mjs +140 -0
  255. package/dist/capture/isolate.mjs.map +1 -0
  256. package/dist/capture/job-lease.d.mts +26 -0
  257. package/dist/capture/job-lease.mjs +56 -0
  258. package/dist/capture/job-lease.mjs.map +1 -0
  259. package/dist/capture/matrix.mjs +298 -0
  260. package/dist/capture/matrix.mjs.map +1 -0
  261. package/dist/capture/modes.d.mts +23 -0
  262. package/dist/capture/modes.mjs +106 -0
  263. package/dist/capture/modes.mjs.map +1 -0
  264. package/dist/capture/orchestrator.d.mts +37 -7
  265. package/dist/capture/orchestrator.mjs +120 -110
  266. package/dist/capture/orchestrator.mjs.map +1 -1
  267. package/dist/capture/pipeline.d.mts +9 -4
  268. package/dist/capture/pipeline.mjs +284 -48
  269. package/dist/capture/pipeline.mjs.map +1 -1
  270. package/dist/capture/progress.d.mts +9 -0
  271. package/dist/capture/progress.mjs +27 -0
  272. package/dist/capture/progress.mjs.map +1 -0
  273. package/dist/capture/publish/accept.d.mts +37 -0
  274. package/dist/capture/publish/accept.mjs +27 -0
  275. package/dist/capture/publish/accept.mjs.map +1 -0
  276. package/dist/capture/publish/complete.d.mts +44 -0
  277. package/dist/capture/publish/complete.mjs +63 -0
  278. package/dist/capture/publish/complete.mjs.map +1 -0
  279. package/dist/capture/publish/extract.d.mts +18 -0
  280. package/dist/capture/publish/extract.mjs +120 -0
  281. package/dist/capture/publish/extract.mjs.map +1 -0
  282. package/dist/capture/publish/handler.d.mts +26 -0
  283. package/dist/capture/publish/handler.mjs +61 -0
  284. package/dist/capture/publish/handler.mjs.map +1 -0
  285. package/dist/capture/publish/index.d.mts +11 -0
  286. package/dist/capture/publish/invalid-zip.d.mts +8 -0
  287. package/dist/capture/publish/invalid-zip.mjs +11 -0
  288. package/dist/capture/publish/invalid-zip.mjs.map +1 -0
  289. package/dist/capture/publish/limits.d.mts +35 -0
  290. package/dist/capture/publish/limits.mjs +38 -0
  291. package/dist/capture/publish/limits.mjs.map +1 -0
  292. package/dist/capture/publish/published.d.mts +13 -0
  293. package/dist/capture/publish/published.mjs +17 -0
  294. package/dist/capture/publish/published.mjs.map +1 -0
  295. package/dist/capture/publish/run.d.mts +31 -0
  296. package/dist/capture/publish/run.mjs +29 -0
  297. package/dist/capture/publish/run.mjs.map +1 -0
  298. package/dist/capture/rediff.d.mts +1 -3
  299. package/dist/capture/rediff.mjs +23 -9
  300. package/dist/capture/rediff.mjs.map +1 -1
  301. package/dist/capture/render.mjs +52 -0
  302. package/dist/capture/render.mjs.map +1 -0
  303. package/dist/capture/scratch.d.mts +42 -0
  304. package/dist/capture/scratch.mjs +136 -0
  305. package/dist/capture/scratch.mjs.map +1 -0
  306. package/dist/capture/shard-plan.mjs +127 -0
  307. package/dist/capture/shard-plan.mjs.map +1 -0
  308. package/dist/capture/shards/context.mjs +51 -0
  309. package/dist/capture/shards/context.mjs.map +1 -0
  310. package/dist/capture/shards/execute.mjs +175 -0
  311. package/dist/capture/shards/execute.mjs.map +1 -0
  312. package/dist/capture/shards/fan-out.mjs +125 -0
  313. package/dist/capture/shards/fan-out.mjs.map +1 -0
  314. package/dist/capture/shards/history.mjs +34 -0
  315. package/dist/capture/shards/history.mjs.map +1 -0
  316. package/dist/capture/shards/reduce.mjs +96 -0
  317. package/dist/capture/shards/reduce.mjs.map +1 -0
  318. package/dist/capture/sizing.d.mts +0 -2
  319. package/dist/capture/sizing.mjs +2 -13
  320. package/dist/capture/sizing.mjs.map +1 -1
  321. package/dist/capture/skip-checks.mjs +3 -67
  322. package/dist/capture/skip-checks.mjs.map +1 -1
  323. package/dist/capture/statics.d.mts +7 -10
  324. package/dist/capture/statics.mjs +26 -74
  325. package/dist/capture/statics.mjs.map +1 -1
  326. package/dist/capture/storybook-urls.d.mts +38 -0
  327. package/dist/capture/storybook-urls.mjs +41 -0
  328. package/dist/capture/storybook-urls.mjs.map +1 -0
  329. package/dist/capture/storybook.d.mts +12 -6
  330. package/dist/capture/storybook.mjs +63 -19
  331. package/dist/capture/storybook.mjs.map +1 -1
  332. package/dist/capture/target.mjs +20 -0
  333. package/dist/capture/target.mjs.map +1 -0
  334. package/dist/capture/targets.d.mts +23 -0
  335. package/dist/capture/targets.mjs +31 -0
  336. package/dist/capture/targets.mjs.map +1 -0
  337. package/dist/capture/tests.d.mts +35 -0
  338. package/dist/capture/tests.mjs +136 -0
  339. package/dist/capture/tests.mjs.map +1 -0
  340. package/dist/capture/token-chunks.mjs +91 -0
  341. package/dist/capture/token-chunks.mjs.map +1 -0
  342. package/dist/capture.d.mts +63 -7
  343. package/dist/capture.mjs +51 -3
  344. package/dist/config.d.mts +136 -14
  345. package/dist/config.mjs +14 -8
  346. package/dist/config.mjs.map +1 -1
  347. package/dist/diff.d.mts +7 -3
  348. package/dist/diff.mjs +15 -3
  349. package/dist/diff.mjs.map +1 -0
  350. package/dist/index.d.mts +3 -3
  351. package/dist/index.mjs +2 -2
  352. package/dist/insights/budget.d.mts +18 -0
  353. package/dist/insights/budget.mjs +32 -0
  354. package/dist/insights/budget.mjs.map +1 -0
  355. package/dist/insights/envelope.d.mts +57 -0
  356. package/dist/insights/envelope.mjs +59 -0
  357. package/dist/insights/envelope.mjs.map +1 -0
  358. package/dist/insights/evidence-health.d.mts +30 -0
  359. package/dist/insights/evidence-health.mjs +27 -0
  360. package/dist/insights/evidence-health.mjs.map +1 -0
  361. package/dist/insights/evidence.d.mts +53 -0
  362. package/dist/insights/evidence.mjs +63 -0
  363. package/dist/insights/evidence.mjs.map +1 -0
  364. package/dist/insights/hash.d.mts +16 -0
  365. package/dist/insights/hash.mjs +20 -0
  366. package/dist/insights/hash.mjs.map +1 -0
  367. package/dist/insights/limits.d.mts +22 -0
  368. package/dist/insights/limits.mjs +23 -0
  369. package/dist/insights/limits.mjs.map +1 -0
  370. package/dist/insights/prompts/v1.d.mts +11 -0
  371. package/dist/insights/prompts/v1.mjs +33 -0
  372. package/dist/insights/prompts/v1.mjs.map +1 -0
  373. package/dist/insights/redact.d.mts +7 -0
  374. package/dist/insights/redact.mjs +23 -0
  375. package/dist/insights/redact.mjs.map +1 -0
  376. package/dist/insights/text.mjs +43 -0
  377. package/dist/insights/text.mjs.map +1 -0
  378. package/dist/insights.d.mts +11 -0
  379. package/dist/insights.mjs +12 -0
  380. package/dist/logger.d.mts +0 -2
  381. package/dist/logger.mjs +18 -3
  382. package/dist/logger.mjs.map +1 -1
  383. package/dist/models/ai-budget-alert.d.mts +21 -0
  384. package/dist/models/ai-budget-alert.mjs +37 -0
  385. package/dist/models/ai-budget-alert.mjs.map +1 -0
  386. package/dist/models/ai-usage.d.mts +38 -0
  387. package/dist/models/ai-usage.mjs +60 -0
  388. package/dist/models/ai-usage.mjs.map +1 -0
  389. package/dist/models/baseline-approval.d.mts +18 -0
  390. package/dist/models/baseline-approval.mjs +41 -0
  391. package/dist/models/baseline-approval.mjs.map +1 -0
  392. package/dist/models/baseline-archive.d.mts +82 -0
  393. package/dist/models/baseline-archive.mjs +105 -0
  394. package/dist/models/baseline-archive.mjs.map +1 -0
  395. package/dist/models/baseline-atomic.mjs +66 -0
  396. package/dist/models/baseline-atomic.mjs.map +1 -0
  397. package/dist/models/baseline-conflict.d.mts +6 -0
  398. package/dist/models/baseline-conflict.mjs +9 -0
  399. package/dist/models/baseline-conflict.mjs.map +1 -0
  400. package/dist/models/baseline-export.d.mts +17 -0
  401. package/dist/models/baseline-export.mjs +135 -0
  402. package/dist/models/baseline-export.mjs.map +1 -0
  403. package/dist/models/baseline-import.mjs +117 -0
  404. package/dist/models/baseline-import.mjs.map +1 -0
  405. package/dist/models/baseline-origin.d.mts +16 -0
  406. package/dist/models/baseline-origin.mjs +35 -0
  407. package/dist/models/baseline-origin.mjs.map +1 -0
  408. package/dist/models/baseline-status.d.mts +0 -2
  409. package/dist/models/baseline-status.mjs +1 -2
  410. package/dist/models/baseline-transfer.d.mts +48 -0
  411. package/dist/models/baseline-transfer.mjs +149 -0
  412. package/dist/models/baseline-transfer.mjs.map +1 -0
  413. package/dist/models/baseline.d.mts +37 -7
  414. package/dist/models/baseline.mjs +152 -28
  415. package/dist/models/baseline.mjs.map +1 -1
  416. package/dist/models/build-component.d.mts +26 -0
  417. package/dist/models/build-component.mjs +54 -0
  418. package/dist/models/build-component.mjs.map +1 -0
  419. package/dist/models/build-review-status.d.mts +27 -0
  420. package/dist/models/build-review-status.mjs +36 -0
  421. package/dist/models/build-review-status.mjs.map +1 -0
  422. package/dist/models/build-review.d.mts +26 -0
  423. package/dist/models/build-review.mjs +53 -0
  424. package/dist/models/build-review.mjs.map +1 -0
  425. package/dist/models/build.d.mts +25 -5
  426. package/dist/models/build.mjs +53 -15
  427. package/dist/models/build.mjs.map +1 -1
  428. package/dist/models/capture-attempt.d.mts +7 -3
  429. package/dist/models/capture-attempt.mjs +30 -6
  430. package/dist/models/capture-attempt.mjs.map +1 -1
  431. package/dist/models/capture-job.d.mts +104 -0
  432. package/dist/models/capture-job.mjs +287 -0
  433. package/dist/models/capture-job.mjs.map +1 -0
  434. package/dist/models/capture-log.d.mts +1 -3
  435. package/dist/models/capture-log.mjs +5 -5
  436. package/dist/models/capture-log.mjs.map +1 -1
  437. package/dist/models/capture-shard.d.mts +60 -0
  438. package/dist/models/capture-shard.mjs +189 -0
  439. package/dist/models/capture-shard.mjs.map +1 -0
  440. package/dist/models/changeset.d.mts +46 -0
  441. package/dist/models/changeset.mjs +80 -0
  442. package/dist/models/changeset.mjs.map +1 -0
  443. package/dist/models/columns.mjs +18 -0
  444. package/dist/models/columns.mjs.map +1 -0
  445. package/dist/models/comment.d.mts +4 -3
  446. package/dist/models/comment.mjs +8 -6
  447. package/dist/models/comment.mjs.map +1 -1
  448. package/dist/models/component.d.mts +41 -0
  449. package/dist/models/component.mjs +59 -0
  450. package/dist/models/component.mjs.map +1 -0
  451. package/dist/models/connections.d.mts +39 -0
  452. package/dist/models/connections.mjs +111 -0
  453. package/dist/models/connections.mjs.map +1 -0
  454. package/dist/models/content-ref.d.mts +1 -3
  455. package/dist/models/content-ref.mjs +2 -3
  456. package/dist/models/content-ref.mjs.map +1 -1
  457. package/dist/models/credentials.d.mts +0 -2
  458. package/dist/models/credentials.mjs +13 -4
  459. package/dist/models/credentials.mjs.map +1 -1
  460. package/dist/models/design-credentials.d.mts +39 -0
  461. package/dist/models/design-credentials.mjs +85 -0
  462. package/dist/models/design-credentials.mjs.map +1 -0
  463. package/dist/models/design-health.d.mts +14 -0
  464. package/dist/models/design-health.mjs +24 -0
  465. package/dist/models/design-health.mjs.map +1 -0
  466. package/dist/models/design-nodes.d.mts +81 -0
  467. package/dist/models/design-nodes.mjs +221 -0
  468. package/dist/models/design-nodes.mjs.map +1 -0
  469. package/dist/models/design-renders.mjs +73 -0
  470. package/dist/models/design-renders.mjs.map +1 -0
  471. package/dist/models/design-resolve.d.mts +27 -0
  472. package/dist/models/design-resolve.mjs +40 -0
  473. package/dist/models/design-resolve.mjs.map +1 -0
  474. package/dist/models/design.d.mts +37 -0
  475. package/dist/models/design.mjs +89 -0
  476. package/dist/models/design.mjs.map +1 -0
  477. package/dist/models/inherited-ratio.d.mts +19 -0
  478. package/dist/models/inherited-ratio.mjs +21 -0
  479. package/dist/models/inherited-ratio.mjs.map +1 -0
  480. package/dist/models/insight.d.mts +68 -0
  481. package/dist/models/insight.mjs +161 -0
  482. package/dist/models/insight.mjs.map +1 -0
  483. package/dist/models/label.d.mts +4 -4
  484. package/dist/models/label.mjs +26 -12
  485. package/dist/models/label.mjs.map +1 -1
  486. package/dist/models/member.d.mts +1 -3
  487. package/dist/models/member.mjs +6 -6
  488. package/dist/models/member.mjs.map +1 -1
  489. package/dist/models/notification-channel.d.mts +37 -5
  490. package/dist/models/notification-channel.mjs +89 -11
  491. package/dist/models/notification-channel.mjs.map +1 -1
  492. package/dist/models/notification-subscription.d.mts +1 -4
  493. package/dist/models/notification-subscription.mjs +8 -11
  494. package/dist/models/notification-subscription.mjs.map +1 -1
  495. package/dist/models/project-group-mapping.d.mts +6 -3
  496. package/dist/models/project-group-mapping.mjs +15 -6
  497. package/dist/models/project-group-mapping.mjs.map +1 -1
  498. package/dist/models/project.d.mts +9 -3
  499. package/dist/models/project.mjs +10 -6
  500. package/dist/models/project.mjs.map +1 -1
  501. package/dist/models/public-origin.d.mts +61 -0
  502. package/dist/models/public-origin.mjs +113 -0
  503. package/dist/models/public-origin.mjs.map +1 -0
  504. package/dist/models/review-switch-off.d.mts +12 -0
  505. package/dist/models/review-switch-off.mjs +25 -0
  506. package/dist/models/review-switch-off.mjs.map +1 -0
  507. package/dist/models/site-settings.d.mts +21 -0
  508. package/dist/models/site-settings.mjs +47 -0
  509. package/dist/models/site-settings.mjs.map +1 -0
  510. package/dist/models/snapshot.d.mts +39 -3
  511. package/dist/models/snapshot.mjs +54 -5
  512. package/dist/models/snapshot.mjs.map +1 -1
  513. package/dist/models/token.d.mts +13 -3
  514. package/dist/models/token.mjs +24 -7
  515. package/dist/models/token.mjs.map +1 -1
  516. package/dist/models/usage.d.mts +74 -0
  517. package/dist/models/usage.mjs +148 -0
  518. package/dist/models/usage.mjs.map +1 -0
  519. package/dist/models/user.d.mts +1 -3
  520. package/dist/models/user.mjs +5 -5
  521. package/dist/models/user.mjs.map +1 -1
  522. package/dist/models/webhook.d.mts +15 -3
  523. package/dist/models/webhook.mjs +34 -6
  524. package/dist/models/webhook.mjs.map +1 -1
  525. package/dist/models.d.mts +30 -4
  526. package/dist/models.mjs +31 -6
  527. package/dist/options.d.mts +16 -0
  528. package/dist/options.mjs +88 -0
  529. package/dist/options.mjs.map +1 -0
  530. package/dist/paths.d.mts +21 -6
  531. package/dist/paths.mjs +57 -12
  532. package/dist/paths.mjs.map +1 -1
  533. package/dist/retention/ai.d.mts +16 -0
  534. package/dist/retention/ai.mjs +22 -0
  535. package/dist/retention/ai.mjs.map +1 -0
  536. package/dist/retention/pending.mjs +46 -0
  537. package/dist/retention/pending.mjs.map +1 -0
  538. package/dist/retention/published-gzip-sweep.mjs +28 -0
  539. package/dist/retention/published-gzip-sweep.mjs.map +1 -0
  540. package/dist/retention/screenshot-sweep.d.mts +49 -0
  541. package/dist/retention/screenshot-sweep.mjs +127 -0
  542. package/dist/retention/screenshot-sweep.mjs.map +1 -0
  543. package/dist/retention.d.mts +16 -4
  544. package/dist/retention.mjs +76 -16
  545. package/dist/retention.mjs.map +1 -1
  546. package/dist/schema/baseline.d.mts +8 -2
  547. package/dist/schema/build-component.d.mts +23 -0
  548. package/dist/schema/build-review.d.mts +15 -0
  549. package/dist/schema/build.d.mts +7 -2
  550. package/dist/schema/capture-attempt.d.mts +0 -2
  551. package/dist/schema/capture-job.d.mts +58 -0
  552. package/dist/schema/capture-shard.d.mts +33 -0
  553. package/dist/schema/comment.d.mts +2 -2
  554. package/dist/schema/connection.d.mts +22 -0
  555. package/dist/schema/content-ref.d.mts +0 -2
  556. package/dist/schema/design.d.mts +56 -0
  557. package/dist/schema/insight.d.mts +52 -0
  558. package/dist/schema/label.d.mts +0 -2
  559. package/dist/schema/member.d.mts +0 -2
  560. package/dist/schema/notification.d.mts +4 -2
  561. package/dist/schema/project-group-mapping.d.mts +0 -2
  562. package/dist/schema/project.d.mts +21 -2
  563. package/dist/schema/site-setting.d.mts +19 -0
  564. package/dist/schema/snapshot.d.mts +17 -2
  565. package/dist/schema/token.d.mts +0 -2
  566. package/dist/schema/usage.d.mts +28 -0
  567. package/dist/schema/user.d.mts +0 -2
  568. package/dist/schema/webhook.d.mts +0 -2
  569. package/dist/schema.d.mts +12 -6
  570. package/dist/serverless.d.mts +19 -0
  571. package/dist/serverless.mjs +36 -0
  572. package/dist/serverless.mjs.map +1 -0
  573. package/dist/test-helpers/build-reference-contract.d.mts +14 -0
  574. package/dist/test-helpers/build-reference-contract.mjs +66 -0
  575. package/dist/test-helpers/build-reference-contract.mjs.map +1 -0
  576. package/dist/test-helpers/create-project.d.mts +1 -3
  577. package/dist/test-helpers/create-project.mjs +1 -2
  578. package/dist/test-helpers/database-contract.d.mts +0 -2
  579. package/dist/test-helpers/database-contract.mjs +37 -2
  580. package/dist/test-helpers/database-contract.mjs.map +1 -1
  581. package/dist/test-helpers/deferred.d.mts +37 -0
  582. package/dist/test-helpers/deferred.mjs +60 -0
  583. package/dist/test-helpers/deferred.mjs.map +1 -0
  584. package/dist/test-helpers/design-contract.d.mts +19 -0
  585. package/dist/test-helpers/design-contract.mjs +39 -0
  586. package/dist/test-helpers/design-contract.mjs.map +1 -0
  587. package/dist/test-helpers/fake-adapters.d.mts +0 -2
  588. package/dist/test-helpers/fake-adapters.mjs +1 -2
  589. package/dist/test-helpers/fake-database.d.mts +0 -2
  590. package/dist/test-helpers/fake-database.mjs +21 -4
  591. package/dist/test-helpers/fake-database.mjs.map +1 -1
  592. package/dist/test-helpers/fake-design.d.mts +41 -0
  593. package/dist/test-helpers/fake-design.mjs +113 -0
  594. package/dist/test-helpers/fake-design.mjs.map +1 -0
  595. package/dist/test-helpers/fake-notifier.d.mts +19 -0
  596. package/dist/test-helpers/fake-notifier.mjs +43 -0
  597. package/dist/test-helpers/fake-notifier.mjs.map +1 -0
  598. package/dist/test-helpers/fake-storage.d.mts +0 -2
  599. package/dist/test-helpers/fake-storage.mjs +1 -2
  600. package/dist/test-helpers/fake-tables.mjs +260 -69
  601. package/dist/test-helpers/fake-tables.mjs.map +1 -1
  602. package/dist/test-helpers/manual-clock.d.mts +25 -0
  603. package/dist/test-helpers/manual-clock.mjs +55 -0
  604. package/dist/test-helpers/manual-clock.mjs.map +1 -0
  605. package/dist/test-helpers/notifier-contract.d.mts +7 -3
  606. package/dist/test-helpers/notifier-contract.mjs +33 -5
  607. package/dist/test-helpers/notifier-contract.mjs.map +1 -1
  608. package/dist/test-helpers/queue-contract.d.mts +16 -4
  609. package/dist/test-helpers/queue-contract.mjs +196 -3
  610. package/dist/test-helpers/queue-contract.mjs.map +1 -1
  611. package/dist/test-helpers/queue-multi-instance.d.mts +18 -0
  612. package/dist/test-helpers/queue-multi-instance.mjs +205 -0
  613. package/dist/test-helpers/queue-multi-instance.mjs.map +1 -0
  614. package/dist/test-helpers/runner-contract.d.mts +0 -2
  615. package/dist/test-helpers/runner-contract.mjs +12 -2
  616. package/dist/test-helpers/runner-contract.mjs.map +1 -1
  617. package/dist/test-helpers/sql-chunks.mjs +25 -2
  618. package/dist/test-helpers/sql-chunks.mjs.map +1 -1
  619. package/dist/test-helpers/storage-contract.d.mts +0 -2
  620. package/dist/test-helpers/storage-contract.mjs +2 -3
  621. package/dist/test-helpers.d.mts +10 -4
  622. package/dist/test-helpers.mjs +9 -3
  623. package/dist/tracing.mjs +36 -6
  624. package/dist/tracing.mjs.map +1 -1
  625. package/dist/types.d.mts +14 -5
  626. package/dist/types.mjs +22 -6
  627. package/dist/types.mjs.map +1 -1
  628. package/dist/urls.d.mts +4 -2
  629. package/dist/urls.mjs +12 -4
  630. package/dist/urls.mjs.map +1 -1
  631. package/dist/utils/adaptive-concurrency.d.mts +64 -0
  632. package/dist/utils/adaptive-concurrency.mjs +148 -0
  633. package/dist/utils/adaptive-concurrency.mjs.map +1 -0
  634. package/dist/utils/connect-retry.d.mts +26 -0
  635. package/dist/utils/connect-retry.mjs +42 -0
  636. package/dist/utils/connect-retry.mjs.map +1 -0
  637. package/dist/utils/encrypt.d.mts +0 -2
  638. package/dist/utils/encrypt.mjs +1 -2
  639. package/dist/utils/environment.d.mts +17 -0
  640. package/dist/utils/environment.mjs +58 -0
  641. package/dist/utils/environment.mjs.map +1 -0
  642. package/dist/utils/hash.d.mts +0 -2
  643. package/dist/utils/hash.mjs +1 -2
  644. package/dist/utils/http.d.mts +29 -3
  645. package/dist/utils/http.mjs +100 -19
  646. package/dist/utils/http.mjs.map +1 -1
  647. package/dist/utils/map-adaptive.d.mts +13 -0
  648. package/dist/utils/map-adaptive.mjs +71 -0
  649. package/dist/utils/map-adaptive.mjs.map +1 -0
  650. package/dist/utils/map-limit.d.mts +8 -0
  651. package/dist/utils/map-limit.mjs +31 -0
  652. package/dist/utils/map-limit.mjs.map +1 -0
  653. package/dist/utils/mime.d.mts +0 -2
  654. package/dist/utils/mime.mjs +1 -2
  655. package/dist/utils/page-limiter.d.mts +35 -0
  656. package/dist/utils/page-limiter.mjs +55 -0
  657. package/dist/utils/page-limiter.mjs.map +1 -0
  658. package/dist/utils/path-security.d.mts +0 -2
  659. package/dist/utils/path-security.mjs +2 -4
  660. package/dist/utils/path-security.mjs.map +1 -1
  661. package/dist/utils/public-origin.d.mts +18 -0
  662. package/dist/utils/public-origin.mjs +74 -0
  663. package/dist/utils/public-origin.mjs.map +1 -0
  664. package/dist/utils/redact.d.mts +0 -2
  665. package/dist/utils/redact.mjs +4 -2
  666. package/dist/utils/redact.mjs.map +1 -1
  667. package/dist/utils/remote-environment.d.mts +76 -0
  668. package/dist/utils/remote-environment.mjs +163 -0
  669. package/dist/utils/remote-environment.mjs.map +1 -0
  670. package/dist/utils/resources.d.mts +62 -0
  671. package/dist/utils/resources.mjs +121 -0
  672. package/dist/utils/resources.mjs.map +1 -0
  673. package/dist/utils/screenshot-store.d.mts +13 -0
  674. package/dist/utils/screenshot-store.mjs +40 -0
  675. package/dist/utils/screenshot-store.mjs.map +1 -0
  676. package/dist/utils/session-gate.d.mts +23 -0
  677. package/dist/utils/session-gate.mjs +69 -0
  678. package/dist/utils/session-gate.mjs.map +1 -0
  679. package/dist/utils/storybook-token.d.mts +89 -0
  680. package/dist/utils/storybook-token.mjs +135 -0
  681. package/dist/utils/storybook-token.mjs.map +1 -0
  682. package/dist/utils/storybook-url.d.mts +13 -0
  683. package/dist/utils/storybook-url.mjs +20 -0
  684. package/dist/utils/storybook-url.mjs.map +1 -0
  685. package/dist/utils/timing.d.mts +0 -2
  686. package/dist/utils/timing.mjs +2 -3
  687. package/dist/utils/timing.mjs.map +1 -1
  688. package/dist/utils/ulid.d.mts +0 -2
  689. package/dist/utils/ulid.mjs +1 -2
  690. package/dist/utils/zip-read.mjs +128 -0
  691. package/dist/utils/zip-read.mjs.map +1 -0
  692. package/dist/utils/zip-write.d.mts +16 -0
  693. package/dist/utils/zip-write.mjs +187 -0
  694. package/dist/utils/zip-write.mjs.map +1 -0
  695. package/dist/utils.d.mts +17 -3
  696. package/dist/utils.mjs +18 -4
  697. package/package.json +35 -26
  698. package/dist/adapter/capture-runner.mjs.map +0 -1
  699. package/dist/adapter/git-host/comments.d.mts +0 -41
  700. package/dist/adapter/git-host/comments.mjs +0 -54
  701. package/dist/adapter/git-host/comments.mjs.map +0 -1
  702. package/dist/adapter/git-host/helpers.d.mts +0 -13
  703. package/dist/adapter/git-host/helpers.mjs +0 -30
  704. package/dist/adapter/git-host/helpers.mjs.map +0 -1
  705. package/dist/adapter/git-host.d.mts +0 -42
  706. package/dist/capture/queue.d.mts +0 -38
  707. package/dist/capture/queue.mjs +0 -98
  708. package/dist/capture/queue.mjs.map +0 -1
  709. package/dist/capture/recovery.d.mts +0 -21
  710. package/dist/capture/recovery.mjs +0 -83
  711. package/dist/capture/recovery.mjs.map +0 -1
  712. package/dist/capture/status-fanout.mjs +0 -72
  713. package/dist/capture/status-fanout.mjs.map +0 -1
  714. package/dist/diff/engine.d.mts +0 -16
  715. package/dist/diff/engine.mjs +0 -87
  716. package/dist/diff/engine.mjs.map +0 -1
  717. package/dist/diff/options.d.mts +0 -42
  718. package/dist/diff/options.mjs +0 -15
  719. package/dist/diff/options.mjs.map +0 -1
  720. package/dist/models/status-config.d.mts +0 -38
  721. package/dist/models/status-config.mjs +0 -63
  722. package/dist/models/status-config.mjs.map +0 -1
  723. package/dist/schema/status-config.d.mts +0 -16
  724. package/dist/test-helpers/git-contract.d.mts +0 -11
  725. package/dist/test-helpers/git-contract.mjs +0 -34
  726. package/dist/test-helpers/git-contract.mjs.map +0 -1
  727. /package/dist/adapter/{git-host.mjs → oauth.mjs} +0 -0
@@ -0,0 +1,40 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ // src/adapters/render-runs.ts
5
+ /** In-flight render calls of a capture runner, so `cancel` reaches exactly the runs it names. */
6
+ /**
7
+ * Every render call a runner has in flight, by build and run id.
8
+ *
9
+ * Several renders of one build can run at once in one process (the shards of a sharded build), and
10
+ * even two with the same run id (a redelivered shard). Each call registers its own entry and
11
+ * removes only that entry when it ends, so no render ever drops another's handle.
12
+ */
13
+ var RenderRuns = class {
14
+ #byBuild = /* @__PURE__ */ new Map();
15
+ /**
16
+ * Register a render call. Returns the function that removes it again (call it in `finally`).
17
+ *
18
+ * @param runId - The request's run id; a render without one is keyed by its build id.
19
+ */
20
+ add(buildId, runId, run) {
21
+ const entry = {
22
+ runId: runId ?? buildId,
23
+ run
24
+ };
25
+ const runs = this.#byBuild.get(buildId) ?? /* @__PURE__ */ new Set();
26
+ runs.add(entry);
27
+ this.#byBuild.set(buildId, runs);
28
+ return () => {
29
+ runs.delete(entry);
30
+ if (runs.size === 0 && this.#byBuild.get(buildId) === runs) this.#byBuild.delete(buildId);
31
+ };
32
+ }
33
+ /** The runs `cancel(buildId, runId)` should stop: every run of the build without a run id. */
34
+ matching(buildId, runId) {
35
+ return [...this.#byBuild.get(buildId) ?? []].filter((entry) => runId === void 0 || entry.runId === runId).map((e) => e.run);
36
+ }
37
+ };
38
+ export { RenderRuns };
39
+
40
+ //# sourceMappingURL=render-runs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-runs.mjs","names":[],"sources":["../../src/adapters/render-runs.ts"],"sourcesContent":["/** In-flight render calls of a capture runner, so `cancel` reaches exactly the runs it names. */\n\n/**\n * Every render call a runner has in flight, by build and run id.\n *\n * Several renders of one build can run at once in one process (the shards of a sharded build), and\n * even two with the same run id (a redelivered shard). Each call registers its own entry and\n * removes only that entry when it ends, so no render ever drops another's handle.\n */\nexport class RenderRuns<T> {\n readonly #byBuild = new Map<string, Set<{ runId: string; run: T }>>();\n\n /**\n * Register a render call. Returns the function that removes it again (call it in `finally`).\n *\n * @param runId - The request's run id; a render without one is keyed by its build id.\n */\n add(buildId: string, runId: string | undefined, run: T): () => void {\n const entry = { runId: runId ?? buildId, run };\n const runs = this.#byBuild.get(buildId) ?? new Set();\n runs.add(entry);\n this.#byBuild.set(buildId, runs);\n return () => {\n runs.delete(entry);\n if (runs.size === 0 && this.#byBuild.get(buildId) === runs) {\n this.#byBuild.delete(buildId);\n }\n };\n }\n\n /** The runs `cancel(buildId, runId)` should stop: every run of the build without a run id. */\n matching(buildId: string, runId?: string): T[] {\n const runs = [...(this.#byBuild.get(buildId) ?? [])];\n return runs.filter((entry) => runId === undefined || entry.runId === runId).map((e) => e.run);\n }\n}\n"],"mappings":";;;;;;;;;;;;AASA,IAAa,aAAb,MAA2B;CACzB,2BAAoB,IAAI,IAA4C;;;;;;CAOpE,IAAI,SAAiB,OAA2B,KAAoB;EAClE,MAAM,QAAQ;GAAE,OAAO,SAAS;GAAS;EAAI;EAC7C,MAAM,OAAO,KAAK,SAAS,IAAI,OAAO,qBAAK,IAAI,IAAI;EACnD,KAAK,IAAI,KAAK;EACd,KAAK,SAAS,IAAI,SAAS,IAAI;EAC/B,aAAa;GACX,KAAK,OAAO,KAAK;GACjB,IAAI,KAAK,SAAS,KAAK,KAAK,SAAS,IAAI,OAAO,MAAM,MACpD,KAAK,SAAS,OAAO,OAAO;EAEhC;CACF;;CAGA,SAAS,SAAiB,OAAqB;EAE7C,OAAO,CADO,GAAI,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,CACvC,CAAC,CAAC,QAAQ,UAAU,UAAU,KAAA,KAAa,MAAM,UAAU,KAAK,CAAC,CAAC,KAAK,MAAM,EAAE,GAAG;CAC9F;AACF"}
@@ -3,7 +3,6 @@ import __tsdown_shims_url from 'node:url';
3
3
  import { AdapterSetupContext } from "../adapter/metadata.mjs";
4
4
  import { AdapterSetupResult, AdapterSetupSources, HookEntry } from "../adapter/setup.mjs";
5
5
  import { Logger } from "pino";
6
- //#region src/adapters/setup-runner.d.ts
7
6
  /** Collect every available `setup` hook in deterministic order. */
8
7
  declare function collectSetups(sources: AdapterSetupSources): HookEntry[];
9
8
  /** Collect every available `teardown` hook in deterministic order. */
@@ -18,6 +17,5 @@ declare function bindAdapterLoggers(sources: AdapterSetupSources, logger: Logger
18
17
  declare function runAdapterSetups(entries: HookEntry[], ctx: AdapterSetupContext, logger: Logger): Promise<AdapterSetupResult>;
19
18
  /** Run teardown hooks concurrently; failures are collected, never thrown. */
20
19
  declare function runAdapterTeardowns(entries: HookEntry[], ctx: AdapterSetupContext, logger: Logger): Promise<AdapterSetupResult>;
21
- //#endregion
22
20
  export { bindAdapterLoggers, collectSetups, collectTeardowns, runAdapterSetups, runAdapterTeardowns };
23
21
  //# sourceMappingURL=setup-runner.d.mts.map
@@ -2,7 +2,7 @@ import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
4
  import { sanitizeErrorText } from "../utils/redact.mjs";
5
- //#region src/adapters/setup-runner.ts
5
+ // src/adapters/setup-runner.ts
6
6
  function hookEntry(adapter, hook) {
7
7
  const lifecycle = adapter.lifecycle;
8
8
  if (!lifecycle) return null;
@@ -26,8 +26,7 @@ function pushAll(entries, sources, hook) {
26
26
  pushHook(entries, sources.database, hook);
27
27
  pushHook(entries, sources.storage, hook);
28
28
  pushHook(entries, sources.captureRunner, hook);
29
- pushHook(entries, sources.captureQueue, hook);
30
- for (const provider of sources.gitHosts ?? []) pushHook(entries, provider, hook);
29
+ for (const provider of sources.design ?? []) pushHook(entries, provider, hook);
31
30
  for (const notifier of sources.notifiers ?? []) pushHook(entries, notifier, hook);
32
31
  pushHook(entries, sources.emailSender, hook);
33
32
  }
@@ -53,8 +52,7 @@ function bindAdapterLoggers(sources, logger) {
53
52
  sources.database,
54
53
  sources.storage,
55
54
  sources.captureRunner,
56
- sources.captureQueue,
57
- ...sources.gitHosts ?? [],
55
+ ...sources.design ?? [],
58
56
  ...sources.notifiers ?? [],
59
57
  sources.emailSender
60
58
  ];
@@ -143,7 +141,6 @@ async function runAdapterSetups(entries, ctx, logger) {
143
141
  async function runAdapterTeardowns(entries, ctx, logger) {
144
142
  return await runHooks(entries, ctx, logger, "teardown", SLOW_TEARDOWN_MS);
145
143
  }
146
- //#endregion
147
144
  export { bindAdapterLoggers, collectSetups, collectTeardowns, runAdapterSetups, runAdapterTeardowns };
148
145
 
149
146
  //# sourceMappingURL=setup-runner.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"setup-runner.mjs","names":[],"sources":["../../src/adapters/setup-runner.ts"],"sourcesContent":["import type { Logger } from \"pino\";\nimport { sanitizeErrorText } from \"../utils/redact.ts\";\nimport type { AdapterLifecycle, AdapterMetadata, AdapterSetupContext } from \"./metadata.ts\";\nimport type {\n AdapterSetupFailure,\n AdapterSetupResult,\n AdapterSetupSources,\n HookEntry,\n} from \"./setup.ts\";\n\ninterface LifecycleCarrier {\n readonly metadata: AdapterMetadata;\n readonly lifecycle?: AdapterLifecycle;\n}\n\nfunction hookEntry(adapter: LifecycleCarrier, hook: \"setup\" | \"teardown\"): HookEntry | null {\n const lifecycle = adapter.lifecycle;\n if (!lifecycle) {\n return null;\n }\n const fn = lifecycle[hook];\n const { category, kind, name } = adapter.metadata;\n return {\n category,\n kind,\n name,\n run: async (ctx) => {\n await fn(ctx);\n },\n };\n}\n\nfunction pushHook(\n entries: HookEntry[],\n adapter: LifecycleCarrier | undefined,\n hook: \"setup\" | \"teardown\",\n): void {\n if (!adapter) {\n return;\n }\n const entry = hookEntry(adapter, hook);\n if (entry) {\n entries.push(entry);\n }\n}\n\nfunction pushAll(\n entries: HookEntry[],\n sources: AdapterSetupSources,\n hook: \"setup\" | \"teardown\",\n): void {\n pushHook(entries, sources.database, hook);\n pushHook(entries, sources.storage, hook);\n pushHook(entries, sources.captureRunner, hook);\n pushHook(entries, sources.captureQueue, hook);\n for (const provider of sources.gitHosts ?? []) {\n pushHook(entries, provider, hook);\n }\n for (const notifier of sources.notifiers ?? []) {\n pushHook(entries, notifier, hook);\n }\n pushHook(entries, sources.emailSender, hook);\n}\n\n/** Collect every available `setup` hook in deterministic order. */\nexport function collectSetups(sources: AdapterSetupSources): HookEntry[] {\n const entries: HookEntry[] = [];\n pushAll(entries, sources, \"setup\");\n return entries;\n}\n\n/** Collect every available `teardown` hook in deterministic order. */\nexport function collectTeardowns(sources: AdapterSetupSources): HookEntry[] {\n const entries: HookEntry[] = [];\n pushAll(entries, sources, \"teardown\");\n return entries;\n}\n\ninterface LoggerCarrier {\n readonly metadata: AdapterMetadata;\n readonly setLogger?: (logger: Logger) => void;\n}\n\n/**\n * Bind the host logger on every adapter that accepts one, scoped by kind.\n * Adapters without `setLogger` keep today's behavior (silent when no\n * explicit `options.logger` was passed at construction).\n */\nexport function bindAdapterLoggers(sources: AdapterSetupSources, logger: Logger): void {\n const adapters: ReadonlyArray<LoggerCarrier | undefined> = [\n sources.database,\n sources.storage,\n sources.captureRunner,\n sources.captureQueue,\n ...(sources.gitHosts ?? []),\n ...(sources.notifiers ?? []),\n sources.emailSender,\n ];\n for (const adapter of adapters) {\n adapter?.setLogger?.(logger.child({ component: adapter.metadata.kind }));\n }\n}\n\nfunction messageOf(reason: unknown): string {\n const text = reason instanceof Error ? reason.message : String(reason);\n return sanitizeErrorText(text, 500);\n}\n\n/** Budgets that trigger slow-hook warnings (observe only, never abort). */\nconst SLOW_SETUP_MS = 10_000;\nconst SLOW_TEARDOWN_MS = 5_000;\n\n/** Run one hook with start/done logging and a slow-hook warning. */\nasync function runHook(\n entry: HookEntry,\n ctx: AdapterSetupContext,\n logger: Logger,\n slowMs: number,\n): Promise<void> {\n const { category, kind, name } = entry;\n const started = Date.now();\n logger.info({ category, kind, name }, \"adapter hook start\");\n try {\n await entry.run(ctx);\n } finally {\n const durationMs = Date.now() - started;\n logger.info({ category, kind, name, durationMs }, \"adapter hook done\");\n if (durationMs > slowMs) {\n logger.warn({ category, kind, name, durationMs, slowMs }, \"slow adapter hook\");\n }\n }\n}\n\nfunction toFailure(entry: HookEntry, reason: unknown): AdapterSetupFailure {\n return { category: entry.category, kind: entry.kind, name: entry.name, error: messageOf(reason) };\n}\n\nfunction toResult(\n entries: HookEntry[],\n outcomes: PromiseSettledResult<void>[],\n logger: Logger,\n verb: string,\n): AdapterSetupResult {\n const failures: AdapterSetupFailure[] = [];\n for (const [index, entry] of entries.entries()) {\n const outcome: PromiseSettledResult<void> | undefined = outcomes[index];\n if (outcome?.status === \"rejected\") {\n failures.push(toFailure(entry, outcome.reason));\n }\n }\n if (failures.length > 0) {\n logger.error({ failures }, `adapter ${verb} failed`);\n } else {\n logger.info({ count: entries.length }, `adapters ${verb}d`);\n }\n return { ok: failures.length === 0, failures };\n}\n\n/** One run of collected hooks with start/done logging and hung visibility. */\nasync function runHooks(\n entries: HookEntry[],\n ctx: AdapterSetupContext,\n logger: Logger,\n verb: string,\n slowMs: number,\n): Promise<AdapterSetupResult> {\n let settled = false;\n const timer = setTimeout(() => {\n if (!settled) {\n logger.warn({ count: entries.length, slowMs }, `adapters ${verb} still running`);\n }\n }, slowMs);\n timer.unref?.();\n try {\n const outcomes = await Promise.allSettled(\n entries.map(async (entry) => {\n await runHook(entry, ctx, logger, slowMs);\n }),\n );\n return toResult(entries, outcomes, logger, verb);\n } finally {\n settled = true;\n clearTimeout(timer);\n }\n}\n\n/** Run setup hooks concurrently; failures are collected, never thrown. */\nexport async function runAdapterSetups(\n entries: HookEntry[],\n ctx: AdapterSetupContext,\n logger: Logger,\n): Promise<AdapterSetupResult> {\n return await runHooks(entries, ctx, logger, \"setup\", SLOW_SETUP_MS);\n}\n\n/** Run teardown hooks concurrently; failures are collected, never thrown. */\nexport async function runAdapterTeardowns(\n entries: HookEntry[],\n ctx: AdapterSetupContext,\n logger: Logger,\n): Promise<AdapterSetupResult> {\n return await runHooks(entries, ctx, logger, \"teardown\", SLOW_TEARDOWN_MS);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"setup-runner.mjs","names":[],"sources":["../../src/adapters/setup-runner.ts"],"sourcesContent":["import type { Logger } from \"pino\";\nimport { sanitizeErrorText } from \"../utils/redact.ts\";\nimport type { AdapterLifecycle, AdapterMetadata, AdapterSetupContext } from \"./metadata.ts\";\nimport type {\n AdapterSetupFailure,\n AdapterSetupResult,\n AdapterSetupSources,\n HookEntry,\n} from \"./setup.ts\";\n\ninterface LifecycleCarrier {\n readonly metadata: AdapterMetadata;\n readonly lifecycle?: AdapterLifecycle;\n}\n\nfunction hookEntry(adapter: LifecycleCarrier, hook: \"setup\" | \"teardown\"): HookEntry | null {\n const lifecycle = adapter.lifecycle;\n if (!lifecycle) {\n return null;\n }\n const fn = lifecycle[hook];\n const { category, kind, name } = adapter.metadata;\n return {\n category,\n kind,\n name,\n run: async (ctx) => {\n await fn(ctx);\n },\n };\n}\n\nfunction pushHook(\n entries: HookEntry[],\n adapter: LifecycleCarrier | undefined,\n hook: \"setup\" | \"teardown\",\n): void {\n if (!adapter) {\n return;\n }\n const entry = hookEntry(adapter, hook);\n if (entry) {\n entries.push(entry);\n }\n}\n\nfunction pushAll(\n entries: HookEntry[],\n sources: AdapterSetupSources,\n hook: \"setup\" | \"teardown\",\n): void {\n pushHook(entries, sources.database, hook);\n pushHook(entries, sources.storage, hook);\n pushHook(entries, sources.captureRunner, hook);\n for (const provider of sources.design ?? []) {\n pushHook(entries, provider, hook);\n }\n for (const notifier of sources.notifiers ?? []) {\n pushHook(entries, notifier, hook);\n }\n pushHook(entries, sources.emailSender, hook);\n}\n\n/** Collect every available `setup` hook in deterministic order. */\nexport function collectSetups(sources: AdapterSetupSources): HookEntry[] {\n const entries: HookEntry[] = [];\n pushAll(entries, sources, \"setup\");\n return entries;\n}\n\n/** Collect every available `teardown` hook in deterministic order. */\nexport function collectTeardowns(sources: AdapterSetupSources): HookEntry[] {\n const entries: HookEntry[] = [];\n pushAll(entries, sources, \"teardown\");\n return entries;\n}\n\ninterface LoggerCarrier {\n readonly metadata: AdapterMetadata;\n readonly setLogger?: (logger: Logger) => void;\n}\n\n/**\n * Bind the host logger on every adapter that accepts one, scoped by kind.\n * Adapters without `setLogger` keep today's behavior (silent when no\n * explicit `options.logger` was passed at construction).\n */\nexport function bindAdapterLoggers(sources: AdapterSetupSources, logger: Logger): void {\n const adapters: ReadonlyArray<LoggerCarrier | undefined> = [\n sources.database,\n sources.storage,\n sources.captureRunner,\n ...(sources.design ?? []),\n ...(sources.notifiers ?? []),\n sources.emailSender,\n ];\n for (const adapter of adapters) {\n adapter?.setLogger?.(logger.child({ component: adapter.metadata.kind }));\n }\n}\n\nfunction messageOf(reason: unknown): string {\n const text = reason instanceof Error ? reason.message : String(reason);\n return sanitizeErrorText(text, 500);\n}\n\n/** Budgets that trigger slow-hook warnings (observe only, never abort). */\nconst SLOW_SETUP_MS = 10_000;\nconst SLOW_TEARDOWN_MS = 5_000;\n\n/** Run one hook with start/done logging and a slow-hook warning. */\nasync function runHook(\n entry: HookEntry,\n ctx: AdapterSetupContext,\n logger: Logger,\n slowMs: number,\n): Promise<void> {\n const { category, kind, name } = entry;\n const started = Date.now();\n logger.info({ category, kind, name }, \"adapter hook start\");\n try {\n await entry.run(ctx);\n } finally {\n const durationMs = Date.now() - started;\n logger.info({ category, kind, name, durationMs }, \"adapter hook done\");\n if (durationMs > slowMs) {\n logger.warn({ category, kind, name, durationMs, slowMs }, \"slow adapter hook\");\n }\n }\n}\n\nfunction toFailure(entry: HookEntry, reason: unknown): AdapterSetupFailure {\n return { category: entry.category, kind: entry.kind, name: entry.name, error: messageOf(reason) };\n}\n\nfunction toResult(\n entries: HookEntry[],\n outcomes: PromiseSettledResult<void>[],\n logger: Logger,\n verb: string,\n): AdapterSetupResult {\n const failures: AdapterSetupFailure[] = [];\n for (const [index, entry] of entries.entries()) {\n const outcome: PromiseSettledResult<void> | undefined = outcomes[index];\n if (outcome?.status === \"rejected\") {\n failures.push(toFailure(entry, outcome.reason));\n }\n }\n if (failures.length > 0) {\n logger.error({ failures }, `adapter ${verb} failed`);\n } else {\n logger.info({ count: entries.length }, `adapters ${verb}d`);\n }\n return { ok: failures.length === 0, failures };\n}\n\n/** One run of collected hooks with start/done logging and hung visibility. */\nasync function runHooks(\n entries: HookEntry[],\n ctx: AdapterSetupContext,\n logger: Logger,\n verb: string,\n slowMs: number,\n): Promise<AdapterSetupResult> {\n let settled = false;\n const timer = setTimeout(() => {\n if (!settled) {\n logger.warn({ count: entries.length, slowMs }, `adapters ${verb} still running`);\n }\n }, slowMs);\n timer.unref?.();\n try {\n const outcomes = await Promise.allSettled(\n entries.map(async (entry) => {\n await runHook(entry, ctx, logger, slowMs);\n }),\n );\n return toResult(entries, outcomes, logger, verb);\n } finally {\n settled = true;\n clearTimeout(timer);\n }\n}\n\n/** Run setup hooks concurrently; failures are collected, never thrown. */\nexport async function runAdapterSetups(\n entries: HookEntry[],\n ctx: AdapterSetupContext,\n logger: Logger,\n): Promise<AdapterSetupResult> {\n return await runHooks(entries, ctx, logger, \"setup\", SLOW_SETUP_MS);\n}\n\n/** Run teardown hooks concurrently; failures are collected, never thrown. */\nexport async function runAdapterTeardowns(\n entries: HookEntry[],\n ctx: AdapterSetupContext,\n logger: Logger,\n): Promise<AdapterSetupResult> {\n return await runHooks(entries, ctx, logger, \"teardown\", SLOW_TEARDOWN_MS);\n}\n"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import __tsdown_shims_path from 'node:path';
2
+ import __tsdown_shims_url from 'node:url';
3
+ import { ShelfOptions } from "../config.mjs";
4
+ import { AdapterSetupSources } from "../adapter/setup.mjs";
5
+ /** The adapter slots of `options`, with `auth` carried along for boot validation. */
6
+ declare function adapterSourcesOf(options: ShelfOptions): AdapterSetupSources & {
7
+ auth?: unknown;
8
+ };
9
+ export { adapterSourcesOf };
10
+ //# sourceMappingURL=sources.d.mts.map
@@ -0,0 +1,19 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ // src/adapters/sources.ts
5
+ /** The adapter slots of `options`, with `auth` carried along for boot validation. */
6
+ function adapterSourcesOf(options) {
7
+ return {
8
+ database: options.database,
9
+ storage: options.storage,
10
+ captureRunner: options.testing?.runner,
11
+ design: options.design,
12
+ notifiers: options.notifications?.notifiers,
13
+ emailSender: options.notifications?.emailSender,
14
+ auth: options.auth
15
+ };
16
+ }
17
+ export { adapterSourcesOf };
18
+
19
+ //# sourceMappingURL=sources.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.mjs","names":[],"sources":["../../src/adapters/sources.ts"],"sourcesContent":["/** Maps `ShelfOptions` to the flat adapter slots lifecycle, validation and health probing work on. */\nimport type { ShelfOptions } from \"../config.ts\";\nimport type { AdapterSetupSources } from \"./setup.ts\";\n\n/** The adapter slots of `options`, with `auth` carried along for boot validation. */\nexport function adapterSourcesOf(options: ShelfOptions): AdapterSetupSources & { auth?: unknown } {\n return {\n database: options.database,\n storage: options.storage,\n captureRunner: options.testing?.runner,\n design: options.design,\n notifiers: options.notifications?.notifiers,\n emailSender: options.notifications?.emailSender,\n auth: options.auth,\n };\n}\n"],"mappings":";;;;;AAKA,SAAgB,iBAAiB,SAAiE;CAChG,OAAO;EACL,UAAU,QAAQ;EAClB,SAAS,QAAQ;EACjB,eAAe,QAAQ,SAAS;EAChC,QAAQ,QAAQ;EAChB,WAAW,QAAQ,eAAe;EAClC,aAAa,QAAQ,eAAe;EACpC,MAAM,QAAQ;CAChB;AACF"}
@@ -1,7 +1,6 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
3
  import { AdapterSetupFailure, AdapterSetupSources } from "../adapter/setup.mjs";
4
- //#region src/adapters/validate.d.ts
5
4
  /**
6
5
  * Validate one adapter against its slot. Returns human-readable reasons
7
6
  * (empty when valid). Never throws — callers decide fail-fast vs collect.
@@ -25,6 +24,5 @@ declare function validateAdapterSources(sources: AdapterSetupSources): AdapterSe
25
24
  declare function validateBootAssembly(sources: AdapterSetupSources & {
26
25
  auth?: unknown;
27
26
  }): AdapterSetupFailure[];
28
- //#endregion
29
27
  export { validateAdapter, validateAdapterSources, validateAuth, validateBootAssembly };
30
28
  //# sourceMappingURL=validate.d.mts.map
@@ -3,7 +3,7 @@ import "node:url";
3
3
  import.meta.url;
4
4
  import { REQUIRED_TABLE_KEYS } from "../adapter/database.mjs";
5
5
  import { z } from "zod";
6
- //#region src/adapters/validate.ts
6
+ // src/adapters/validate.ts
7
7
  /**
8
8
  * Boot-time adapter validation: fail fast on third-party adapters that
9
9
  * cannot satisfy their slot contract.
@@ -21,6 +21,7 @@ const metadataSchema = z.object({
21
21
  const DATABASE_METHODS = [
22
22
  "insert",
23
23
  "update",
24
+ "updateWhere",
24
25
  "get",
25
26
  "remove",
26
27
  "list",
@@ -119,13 +120,13 @@ function emailSenderReasons(sender) {
119
120
  if (typeof record["send"] !== "function") reasons.push("missing methods: send");
120
121
  return reasons;
121
122
  }
122
- /** Reasons a git provider lacks its descriptor shape. */
123
- function gitReasons(provider) {
123
+ /** Reasons a design provider lacks its descriptor shape. */
124
+ function designReasons(provider) {
124
125
  const record = asRecord(provider);
125
- if (!record) return ["git provider must be an object"];
126
- const reasons = metadataReasons(record, "git-host");
127
- if (typeof record["create"] !== "function") reasons.push("missing methods: create");
128
- if (!hasSchemaParse(provider)) reasons.push("metadata.schema must be a zod schema");
126
+ if (!record) return ["design provider must be an object"];
127
+ const reasons = metadataReasons(record, "design");
128
+ const missing = ["parseUrl", "create"].filter((name) => typeof record[name] !== "function");
129
+ if (missing.length > 0) reasons.push(`missing methods: ${missing.join(", ")}`);
129
130
  return reasons;
130
131
  }
131
132
  /** Required methods for a slot category. */
@@ -213,17 +214,29 @@ function checkAuth(auth) {
213
214
  error: reasons.join("; ")
214
215
  }];
215
216
  }
216
- /** Failures for git-host or notifier provider lists. */
217
+ const PROVIDER_KINDS = {
218
+ design: {
219
+ reasons: designReasons,
220
+ list: "design",
221
+ category: "design"
222
+ },
223
+ notifier: {
224
+ reasons: notifierReasons,
225
+ list: "notifiers",
226
+ category: "notifier"
227
+ }
228
+ };
229
+ /** Failures for design or notifier provider lists. */
217
230
  function checkProviders(checks) {
218
231
  const failures = [];
219
232
  for (const check of checks) {
220
- const reasons = check.kinds === "git" ? gitReasons(check.provider) : notifierReasons(check.provider);
233
+ const kind = PROVIDER_KINDS[check.kinds];
234
+ const reasons = kind.reasons(check.provider);
221
235
  if (reasons.length === 0) continue;
222
- const slot = check.kinds === "git" ? `gitHosts[${check.index}]` : `notifiers[${check.index}]`;
223
- const category = check.kinds === "git" ? "git-host" : "notifier";
236
+ const slot = `${kind.list}[${check.index}]`;
224
237
  const metadata = asRecord(asRecord(check.provider)?.["metadata"]);
225
238
  failures.push({
226
- category,
239
+ category: kind.category,
227
240
  kind: stringField(metadata, "kind") ?? "unknown",
228
241
  name: stringField(metadata, "name") ?? slot,
229
242
  error: reasons.map((reason) => `${slot}: ${reason}`).join("; ")
@@ -279,15 +292,10 @@ function validateAdapterSources(sources) {
279
292
  category: "capture-runner",
280
293
  slot: "captureRunner"
281
294
  });
282
- if (sources.captureQueue !== void 0) checks.push({
283
- adapter: sources.captureQueue,
284
- category: "capture-queue",
285
- slot: "captureQueue"
286
- });
287
- const providers = [...(sources.gitHosts ?? []).map((provider, index) => ({
295
+ const providers = [...(sources.design ?? []).map((provider, index) => ({
288
296
  provider,
289
297
  index,
290
- kinds: "git"
298
+ kinds: "design"
291
299
  })), ...(sources.notifiers ?? []).map((provider, index) => ({
292
300
  provider,
293
301
  index,
@@ -307,7 +315,6 @@ function validateAdapterSources(sources) {
307
315
  function validateBootAssembly(sources) {
308
316
  return [...validateAdapterSources(sources), ...checkAuth(sources.auth)];
309
317
  }
310
- //#endregion
311
318
  export { validateAdapter, validateAdapterSources, validateAuth, validateBootAssembly };
312
319
 
313
320
  //# sourceMappingURL=validate.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.mjs","names":[],"sources":["../../src/adapters/validate.ts"],"sourcesContent":["/**\n * Boot-time adapter validation: fail fast on third-party adapters that\n * cannot satisfy their slot contract.\n *\n * Types alone cannot stop a bad adapter — this module checks shape at\n * runtime before any I/O runs. `createShelfApp` throws synchronously;\n * the lifecycle runner returns failures without executing hooks.\n */\nimport { z } from \"zod\";\nimport type { Auth } from \"../auth.ts\";\nimport { REQUIRED_TABLE_KEYS } from \"./database.ts\";\nimport type { AdapterSetupFailure, AdapterSetupSources } from \"./setup.ts\";\n\nconst metadataSchema = z.object({\n name: z.string().min(1),\n version: z.string().min(1),\n kind: z.string().min(1),\n category: z.string().min(1),\n});\n\nconst DATABASE_METHODS = [\"insert\", \"update\", \"get\", \"remove\", \"list\", \"count\", \"all\"];\n\nconst STORAGE_METHODS = [\"read\", \"write\", \"delete\", \"exists\", \"list\", \"writeStream\", \"readStream\"];\n\nconst RUNNER_METHODS = [\"render\", \"cancel\"];\n\nconst QUEUE_METHODS = [\"enqueue\", \"status\", \"active\", \"recent\"];\n\n/** Unknown value narrowed to a property bag for shape checks. */\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return typeof value === \"object\" && value !== null ? (value as Record<string, unknown>) : null;\n}\n\n/** String field of a record, or null when absent/non-string. */\nfunction stringField(record: Record<string, unknown> | null, key: string): string | null {\n const value = record?.[key];\n return typeof value === \"string\" ? value : null;\n}\n\n/** Reasons the adapter identity fails for the expected slot. */\nfunction metadataReasons(adapter: Record<string, unknown>, expected: string): string[] {\n const parsed = metadataSchema.safeParse(adapter[\"metadata\"]);\n if (!parsed.success) {\n return [`invalid metadata: ${parsed.error.issues.map((i) => i.path.join(\".\")).join(\",\")}`];\n }\n const category = (parsed.data as { category: string }).category;\n return category === expected ? [] : [`category \"${category}\" does not match slot \"${expected}\"`];\n}\n\n/** Reasons the optional lifecycle violates the all-or-nothing rule. */\nfunction lifecycleReasons(adapter: Record<string, unknown>): string[] {\n const lifecycle = adapter[\"lifecycle\"];\n if (lifecycle === undefined) {\n return [];\n }\n const hooks = asRecord(lifecycle);\n if (!hooks) {\n return [\"lifecycle must be an object with setup/teardown/health\"];\n }\n const missing = [\"setup\", \"teardown\", \"health\"].filter(\n (hook) => typeof hooks[hook] !== \"function\",\n );\n return missing.length > 0 ? [`partial lifecycle (missing: ${missing.join(\",\")})`] : [];\n}\n\n/** Reasons the adapter lacks required slot methods. */\nfunction methodReasons(adapter: Record<string, unknown>, methods: string[]): string[] {\n const missing = methods.filter((method) => typeof adapter[method] !== \"function\");\n return missing.length > 0 ? [`missing methods: ${missing.join(\",\")}`] : [];\n}\n\n/** Reasons a database adapter lacks its table map. */\nfunction tableReasons(adapter: Record<string, unknown>): string[] {\n const tables = asRecord(adapter[\"tables\"]);\n if (!tables) {\n return [\"missing tables map\"];\n }\n const missing = REQUIRED_TABLE_KEYS.filter((table) => tables[table] === undefined);\n return missing.length > 0 ? [`missing tables: ${missing.join(\",\")}`] : [];\n}\n\n/** Reasons a queue adapter has a partial poll extension. */\nfunction queuePollReasons(record: Record<string, unknown>): string[] {\n const present = [\"poll\", \"ack\", \"nack\"].filter((method) => record[method] !== undefined);\n if (present.length === 0 || present.length === 3) {\n const mistyped = [\"poll\", \"ack\", \"nack\"].filter(\n (method) => record[method] !== undefined && typeof record[method] !== \"function\",\n );\n return mistyped.map((method) => `queue poll extension \"${method}\" must be a function`);\n }\n return [`partial poll extension (present: ${present.join(\",\")}; need poll+ack+nack)`];\n}\n\n/** Whether a metadata schema looks like a zod schema (has parse). */\nfunction hasSchemaParse(provider: unknown): boolean {\n const schema = asRecord(asRecord(provider)?.[\"metadata\"])?.[\"schema\"];\n return typeof (schema as { parse?: unknown } | undefined)?.parse === \"function\";\n}\n\n/** Reasons a notifier provider lacks its descriptor shape. */\nfunction notifierReasons(provider: unknown): string[] {\n const record = asRecord(provider);\n if (!record) {\n return [\"notifier provider must be an object\"];\n }\n const reasons = metadataReasons(record, \"notifier\");\n if (typeof record[\"create\"] !== \"function\") {\n reasons.push(\"missing methods: create\");\n }\n if (!hasSchemaParse(provider)) {\n reasons.push(\"metadata.schema must be a zod schema\");\n }\n return reasons;\n}\n\n/** Reasons an email sender lacks its transport shape. */\nfunction emailSenderReasons(sender: unknown): string[] {\n const record = asRecord(sender);\n if (!record) {\n return [\"email sender must be an object\"];\n }\n const reasons = metadataReasons(record, \"notifier\");\n if (typeof record[\"send\"] !== \"function\") {\n reasons.push(\"missing methods: send\");\n }\n return reasons;\n}\n\n/** Reasons a git provider lacks its descriptor shape. */\nfunction gitReasons(provider: unknown): string[] {\n const record = asRecord(provider);\n if (!record) {\n return [\"git provider must be an object\"];\n }\n const reasons = metadataReasons(record, \"git-host\");\n if (typeof record[\"create\"] !== \"function\") {\n reasons.push(\"missing methods: create\");\n }\n if (!hasSchemaParse(provider)) {\n reasons.push(\"metadata.schema must be a zod schema\");\n }\n return reasons;\n}\n\n/** Required methods for a slot category. */\nfunction slotMethods(category: string): string[] {\n if (category === \"database\") {\n return DATABASE_METHODS;\n }\n if (category === \"storage\") {\n return STORAGE_METHODS;\n }\n if (category === \"capture-runner\") {\n return RUNNER_METHODS;\n }\n return QUEUE_METHODS;\n}\n\n/** Extra per-slot reasons (table map for databases, poll rule for queues). */\nfunction slotExtraReasons(record: Record<string, unknown>, category: string): string[] {\n if (category === \"database\") {\n return tableReasons(record);\n }\n return category === \"capture-queue\" ? queuePollReasons(record) : [];\n}\n\n/**\n * Validate one adapter against its slot. Returns human-readable reasons\n * (empty when valid). Never throws — callers decide fail-fast vs collect.\n */\nexport function validateAdapter(\n adapter: unknown,\n expectedCategory: string,\n slot: string,\n): string[] {\n const record = asRecord(adapter);\n if (!record) {\n return [`${slot} adapter must be an object`];\n }\n const reasons = metadataReasons(record, expectedCategory).map((r) => `${slot}: ${r}`);\n const extra = [\n ...lifecycleReasons(record),\n ...methodReasons(record, slotMethods(expectedCategory)),\n ...slotExtraReasons(record, expectedCategory),\n ];\n for (const reason of extra) {\n reasons.push(`${slot}: ${reason}`);\n }\n return reasons;\n}\n\n/** Auth surface methods every engine must expose. */\nconst AUTH_METHODS = [\n \"handler\",\n \"loginMethods\",\n \"setup\",\n \"issueInvite\",\n \"verifyInvite\",\n \"acceptInvite\",\n \"passkeysEnabled\",\n \"listSessions\",\n \"listPasskeys\",\n \"hasPassword\",\n \"setDisabled\",\n \"check\",\n \"createSession\",\n \"destroySession\",\n];\n\n/** Reasons a method-id list is unusable (blank or duplicate ids). */\nfunction methodIdReasons(ids: string[]): string[] {\n const reasons: string[] = [];\n if (ids.some((id) => id.length === 0)) {\n reasons.push(\"login method with blank id\");\n }\n if (new Set(ids).size !== ids.length) {\n reasons.push(\"duplicate login method ids\");\n }\n return reasons;\n}\n\n/** Reasons login method descriptors are unusable (duplicate/blank ids). */\nfunction loginMethodReasons(auth: Auth): string[] {\n let ids: string[];\n try {\n ids = auth.loginMethods().map((method) => method.id);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return [`loginMethods() threw: ${message}`];\n }\n return methodIdReasons(ids);\n}\n\n/**\n * Validate the auth engine shape (auth is optional — undefined is valid).\n * Returns human-readable reasons, empty when sound.\n */\nexport function validateAuth(auth?: unknown): string[] {\n if (auth === undefined) {\n return [];\n }\n const record = asRecord(auth);\n if (!record) {\n return [\"auth must be an object\"];\n }\n const reasons = methodReasons(record, AUTH_METHODS).map((reason) => `auth: ${reason}`);\n if (reasons.length === 0) {\n for (const reason of loginMethodReasons(auth as Auth)) {\n reasons.push(`auth: ${reason}`);\n }\n }\n return reasons;\n}\n\n/** Failure entry for an invalid auth engine. */\nfunction checkAuth(auth: unknown): AdapterSetupFailure[] {\n const reasons = validateAuth(auth);\n if (reasons.length === 0) {\n return [];\n }\n return [{ category: \"auth\", kind: \"auth\", name: \"auth\", error: reasons.join(\"; \") }];\n}\n\n/** One slot check for source validation. */\ninterface SlotCheck {\n adapter: unknown;\n category: string;\n slot: string;\n}\n\n/** Descriptor check for provider lists (git hosts, notifiers). */\ninterface ProviderCheck {\n provider: unknown;\n index: number;\n kinds: \"git\" | \"notifier\";\n}\n\n/** Failures for git-host or notifier provider lists. */\nfunction checkProviders(checks: ProviderCheck[]): AdapterSetupFailure[] {\n const failures: AdapterSetupFailure[] = [];\n for (const check of checks) {\n const reasons =\n check.kinds === \"git\" ? gitReasons(check.provider) : notifierReasons(check.provider);\n if (reasons.length === 0) {\n continue;\n }\n const slot = check.kinds === \"git\" ? `gitHosts[${check.index}]` : `notifiers[${check.index}]`;\n const category = check.kinds === \"git\" ? \"git-host\" : \"notifier\";\n const metadata = asRecord(asRecord(check.provider)?.[\"metadata\"]);\n failures.push({\n category,\n kind: stringField(metadata, \"kind\") ?? \"unknown\",\n name: stringField(metadata, \"name\") ?? slot,\n error: reasons.map((reason) => `${slot}: ${reason}`).join(\"; \"),\n });\n }\n return failures;\n}\n\n/** Failure for the email sender slot. */\nfunction checkEmailSender(sender: unknown): AdapterSetupFailure[] {\n if (sender === undefined) {\n return [];\n }\n const reasons = emailSenderReasons(sender);\n if (reasons.length === 0) {\n return [];\n }\n const metadata = asRecord(asRecord(sender)?.[\"metadata\"]);\n return [\n {\n category: \"notifier\",\n kind: stringField(metadata, \"kind\") ?? \"unknown\",\n name: stringField(metadata, \"name\") ?? \"emailSender\",\n error: reasons.map((reason) => `emailSender: ${reason}`).join(\"; \"),\n },\n ];\n}\n\n/** Failures for the core database/storage/runner/queue slots. */\nfunction checkSlots(checks: SlotCheck[]): AdapterSetupFailure[] {\n const failures: AdapterSetupFailure[] = [];\n for (const check of checks) {\n const reasons = validateAdapter(check.adapter, check.category, check.slot);\n if (reasons.length === 0) {\n continue;\n }\n const metadata = asRecord(asRecord(check.adapter)?.[\"metadata\"]);\n failures.push({\n category: check.category,\n kind: stringField(metadata, \"kind\") ?? \"unknown\",\n name: stringField(metadata, \"name\") ?? check.slot,\n error: reasons.join(\"; \"),\n });\n }\n return failures;\n}\n\n/**\n * Validate every adapter in the boot sources. Returns per-adapter failures\n * (empty when the whole assembly is sound).\n */\nexport function validateAdapterSources(sources: AdapterSetupSources): AdapterSetupFailure[] {\n const checks: SlotCheck[] = [\n { adapter: sources.database, category: \"database\", slot: \"database\" },\n { adapter: sources.storage, category: \"storage\", slot: \"storage\" },\n ];\n if (sources.captureRunner !== undefined) {\n checks.push({\n adapter: sources.captureRunner,\n category: \"capture-runner\",\n slot: \"captureRunner\",\n });\n }\n if (sources.captureQueue !== undefined) {\n checks.push({ adapter: sources.captureQueue, category: \"capture-queue\", slot: \"captureQueue\" });\n }\n const providers: ProviderCheck[] = [\n ...(sources.gitHosts ?? []).map((provider, index) => ({\n provider,\n index,\n kinds: \"git\" as const,\n })),\n ...(sources.notifiers ?? []).map((provider, index) => ({\n provider,\n index,\n kinds: \"notifier\" as const,\n })),\n ];\n return [\n ...checkSlots(checks),\n ...checkProviders(providers),\n ...checkEmailSender(sources.emailSender),\n ];\n}\n\n/**\n * Validate a full boot assembly: adapters plus the optional auth engine.\n * App assembly calls this — `ShelfOptions` carries `auth` alongside the\n * adapter slots, and an invalid engine fails boot like any adapter.\n */\nexport function validateBootAssembly(\n sources: AdapterSetupSources & { auth?: unknown },\n): AdapterSetupFailure[] {\n return [...validateAdapterSources(sources), ...checkAuth(sources.auth)];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"validate.mjs","names":[],"sources":["../../src/adapters/validate.ts"],"sourcesContent":["/**\n * Boot-time adapter validation: fail fast on third-party adapters that\n * cannot satisfy their slot contract.\n *\n * Types alone cannot stop a bad adapter — this module checks shape at\n * runtime before any I/O runs. `createShelfApp` throws synchronously;\n * the lifecycle runner returns failures without executing hooks.\n */\nimport { z } from \"zod\";\nimport type { Auth } from \"../auth.ts\";\nimport { REQUIRED_TABLE_KEYS } from \"./database.ts\";\nimport type { AdapterSetupFailure, AdapterSetupSources } from \"./setup.ts\";\n\nconst metadataSchema = z.object({\n name: z.string().min(1),\n version: z.string().min(1),\n kind: z.string().min(1),\n category: z.string().min(1),\n});\n\nconst DATABASE_METHODS = [\n \"insert\",\n \"update\",\n \"updateWhere\",\n \"get\",\n \"remove\",\n \"list\",\n \"count\",\n \"all\",\n];\n\nconst STORAGE_METHODS = [\"read\", \"write\", \"delete\", \"exists\", \"list\", \"writeStream\", \"readStream\"];\n\nconst RUNNER_METHODS = [\"render\", \"cancel\"];\n\nconst QUEUE_METHODS = [\"enqueue\", \"status\", \"active\", \"recent\"];\n\n/** Unknown value narrowed to a property bag for shape checks. */\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return typeof value === \"object\" && value !== null ? (value as Record<string, unknown>) : null;\n}\n\n/** String field of a record, or null when absent/non-string. */\nfunction stringField(record: Record<string, unknown> | null, key: string): string | null {\n const value = record?.[key];\n return typeof value === \"string\" ? value : null;\n}\n\n/** Reasons the adapter identity fails for the expected slot. */\nfunction metadataReasons(adapter: Record<string, unknown>, expected: string): string[] {\n const parsed = metadataSchema.safeParse(adapter[\"metadata\"]);\n if (!parsed.success) {\n return [`invalid metadata: ${parsed.error.issues.map((i) => i.path.join(\".\")).join(\",\")}`];\n }\n const category = (parsed.data as { category: string }).category;\n return category === expected ? [] : [`category \"${category}\" does not match slot \"${expected}\"`];\n}\n\n/** Reasons the optional lifecycle violates the all-or-nothing rule. */\nfunction lifecycleReasons(adapter: Record<string, unknown>): string[] {\n const lifecycle = adapter[\"lifecycle\"];\n if (lifecycle === undefined) {\n return [];\n }\n const hooks = asRecord(lifecycle);\n if (!hooks) {\n return [\"lifecycle must be an object with setup/teardown/health\"];\n }\n const missing = [\"setup\", \"teardown\", \"health\"].filter(\n (hook) => typeof hooks[hook] !== \"function\",\n );\n return missing.length > 0 ? [`partial lifecycle (missing: ${missing.join(\",\")})`] : [];\n}\n\n/** Reasons the adapter lacks required slot methods. */\nfunction methodReasons(adapter: Record<string, unknown>, methods: string[]): string[] {\n const missing = methods.filter((method) => typeof adapter[method] !== \"function\");\n return missing.length > 0 ? [`missing methods: ${missing.join(\",\")}`] : [];\n}\n\n/** Reasons a database adapter lacks its table map. */\nfunction tableReasons(adapter: Record<string, unknown>): string[] {\n const tables = asRecord(adapter[\"tables\"]);\n if (!tables) {\n return [\"missing tables map\"];\n }\n const missing = REQUIRED_TABLE_KEYS.filter((table) => tables[table] === undefined);\n return missing.length > 0 ? [`missing tables: ${missing.join(\",\")}`] : [];\n}\n\n/** Reasons a queue adapter has a partial poll extension. */\nfunction queuePollReasons(record: Record<string, unknown>): string[] {\n const present = [\"poll\", \"ack\", \"nack\"].filter((method) => record[method] !== undefined);\n if (present.length === 0 || present.length === 3) {\n const mistyped = [\"poll\", \"ack\", \"nack\"].filter(\n (method) => record[method] !== undefined && typeof record[method] !== \"function\",\n );\n return mistyped.map((method) => `queue poll extension \"${method}\" must be a function`);\n }\n return [`partial poll extension (present: ${present.join(\",\")}; need poll+ack+nack)`];\n}\n\n/** Whether a metadata schema looks like a zod schema (has parse). */\nfunction hasSchemaParse(provider: unknown): boolean {\n const schema = asRecord(asRecord(provider)?.[\"metadata\"])?.[\"schema\"];\n return typeof (schema as { parse?: unknown } | undefined)?.parse === \"function\";\n}\n\n/** Reasons a notifier provider lacks its descriptor shape. */\nfunction notifierReasons(provider: unknown): string[] {\n const record = asRecord(provider);\n if (!record) {\n return [\"notifier provider must be an object\"];\n }\n const reasons = metadataReasons(record, \"notifier\");\n if (typeof record[\"create\"] !== \"function\") {\n reasons.push(\"missing methods: create\");\n }\n if (!hasSchemaParse(provider)) {\n reasons.push(\"metadata.schema must be a zod schema\");\n }\n return reasons;\n}\n\n/** Reasons an email sender lacks its transport shape. */\nfunction emailSenderReasons(sender: unknown): string[] {\n const record = asRecord(sender);\n if (!record) {\n return [\"email sender must be an object\"];\n }\n const reasons = metadataReasons(record, \"notifier\");\n if (typeof record[\"send\"] !== \"function\") {\n reasons.push(\"missing methods: send\");\n }\n return reasons;\n}\n\n/** Reasons a design provider lacks its descriptor shape. */\nfunction designReasons(provider: unknown): string[] {\n const record = asRecord(provider);\n if (!record) {\n return [\"design provider must be an object\"];\n }\n const reasons = metadataReasons(record, \"design\");\n const missing = [\"parseUrl\", \"create\"].filter((name) => typeof record[name] !== \"function\");\n if (missing.length > 0) {\n reasons.push(`missing methods: ${missing.join(\", \")}`);\n }\n return reasons;\n}\n\n/** Required methods for a slot category. */\nfunction slotMethods(category: string): string[] {\n if (category === \"database\") {\n return DATABASE_METHODS;\n }\n if (category === \"storage\") {\n return STORAGE_METHODS;\n }\n if (category === \"capture-runner\") {\n return RUNNER_METHODS;\n }\n return QUEUE_METHODS;\n}\n\n/** Extra per-slot reasons (table map for databases, poll rule for queues). */\nfunction slotExtraReasons(record: Record<string, unknown>, category: string): string[] {\n if (category === \"database\") {\n return tableReasons(record);\n }\n return category === \"capture-queue\" ? queuePollReasons(record) : [];\n}\n\n/**\n * Validate one adapter against its slot. Returns human-readable reasons\n * (empty when valid). Never throws — callers decide fail-fast vs collect.\n */\nexport function validateAdapter(\n adapter: unknown,\n expectedCategory: string,\n slot: string,\n): string[] {\n const record = asRecord(adapter);\n if (!record) {\n return [`${slot} adapter must be an object`];\n }\n const reasons = metadataReasons(record, expectedCategory).map((r) => `${slot}: ${r}`);\n const extra = [\n ...lifecycleReasons(record),\n ...methodReasons(record, slotMethods(expectedCategory)),\n ...slotExtraReasons(record, expectedCategory),\n ];\n for (const reason of extra) {\n reasons.push(`${slot}: ${reason}`);\n }\n return reasons;\n}\n\n/** Auth surface methods every engine must expose. */\nconst AUTH_METHODS = [\n \"handler\",\n \"loginMethods\",\n \"setup\",\n \"issueInvite\",\n \"verifyInvite\",\n \"acceptInvite\",\n \"passkeysEnabled\",\n \"listSessions\",\n \"listPasskeys\",\n \"hasPassword\",\n \"setDisabled\",\n \"check\",\n \"createSession\",\n \"destroySession\",\n];\n\n/** Reasons a method-id list is unusable (blank or duplicate ids). */\nfunction methodIdReasons(ids: string[]): string[] {\n const reasons: string[] = [];\n if (ids.some((id) => id.length === 0)) {\n reasons.push(\"login method with blank id\");\n }\n if (new Set(ids).size !== ids.length) {\n reasons.push(\"duplicate login method ids\");\n }\n return reasons;\n}\n\n/** Reasons login method descriptors are unusable (duplicate/blank ids). */\nfunction loginMethodReasons(auth: Auth): string[] {\n let ids: string[];\n try {\n ids = auth.loginMethods().map((method) => method.id);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return [`loginMethods() threw: ${message}`];\n }\n return methodIdReasons(ids);\n}\n\n/**\n * Validate the auth engine shape (auth is optional — undefined is valid).\n * Returns human-readable reasons, empty when sound.\n */\nexport function validateAuth(auth?: unknown): string[] {\n if (auth === undefined) {\n return [];\n }\n const record = asRecord(auth);\n if (!record) {\n return [\"auth must be an object\"];\n }\n const reasons = methodReasons(record, AUTH_METHODS).map((reason) => `auth: ${reason}`);\n if (reasons.length === 0) {\n for (const reason of loginMethodReasons(auth as Auth)) {\n reasons.push(`auth: ${reason}`);\n }\n }\n return reasons;\n}\n\n/** Failure entry for an invalid auth engine. */\nfunction checkAuth(auth: unknown): AdapterSetupFailure[] {\n const reasons = validateAuth(auth);\n if (reasons.length === 0) {\n return [];\n }\n return [{ category: \"auth\", kind: \"auth\", name: \"auth\", error: reasons.join(\"; \") }];\n}\n\n/** One slot check for source validation. */\ninterface SlotCheck {\n adapter: unknown;\n category: string;\n slot: string;\n}\n\n/** Descriptor check for provider lists (design providers, notifiers). */\ninterface ProviderCheck {\n provider: unknown;\n index: number;\n kinds: \"design\" | \"notifier\";\n}\n\nconst PROVIDER_KINDS = {\n design: { reasons: designReasons, list: \"design\", category: \"design\" },\n notifier: { reasons: notifierReasons, list: \"notifiers\", category: \"notifier\" },\n} as const;\n\n/** Failures for design or notifier provider lists. */\nfunction checkProviders(checks: ProviderCheck[]): AdapterSetupFailure[] {\n const failures: AdapterSetupFailure[] = [];\n for (const check of checks) {\n const kind = PROVIDER_KINDS[check.kinds];\n const reasons = kind.reasons(check.provider);\n if (reasons.length === 0) {\n continue;\n }\n const slot = `${kind.list}[${check.index}]`;\n const metadata = asRecord(asRecord(check.provider)?.[\"metadata\"]);\n failures.push({\n category: kind.category,\n kind: stringField(metadata, \"kind\") ?? \"unknown\",\n name: stringField(metadata, \"name\") ?? slot,\n error: reasons.map((reason) => `${slot}: ${reason}`).join(\"; \"),\n });\n }\n return failures;\n}\n\n/** Failure for the email sender slot. */\nfunction checkEmailSender(sender: unknown): AdapterSetupFailure[] {\n if (sender === undefined) {\n return [];\n }\n const reasons = emailSenderReasons(sender);\n if (reasons.length === 0) {\n return [];\n }\n const metadata = asRecord(asRecord(sender)?.[\"metadata\"]);\n return [\n {\n category: \"notifier\",\n kind: stringField(metadata, \"kind\") ?? \"unknown\",\n name: stringField(metadata, \"name\") ?? \"emailSender\",\n error: reasons.map((reason) => `emailSender: ${reason}`).join(\"; \"),\n },\n ];\n}\n\n/** Failures for the core database/storage/runner/queue slots. */\nfunction checkSlots(checks: SlotCheck[]): AdapterSetupFailure[] {\n const failures: AdapterSetupFailure[] = [];\n for (const check of checks) {\n const reasons = validateAdapter(check.adapter, check.category, check.slot);\n if (reasons.length === 0) {\n continue;\n }\n const metadata = asRecord(asRecord(check.adapter)?.[\"metadata\"]);\n failures.push({\n category: check.category,\n kind: stringField(metadata, \"kind\") ?? \"unknown\",\n name: stringField(metadata, \"name\") ?? check.slot,\n error: reasons.join(\"; \"),\n });\n }\n return failures;\n}\n\n/**\n * Validate every adapter in the boot sources. Returns per-adapter failures\n * (empty when the whole assembly is sound).\n */\nexport function validateAdapterSources(sources: AdapterSetupSources): AdapterSetupFailure[] {\n const checks: SlotCheck[] = [\n { adapter: sources.database, category: \"database\", slot: \"database\" },\n { adapter: sources.storage, category: \"storage\", slot: \"storage\" },\n ];\n if (sources.captureRunner !== undefined) {\n checks.push({\n adapter: sources.captureRunner,\n category: \"capture-runner\",\n slot: \"captureRunner\",\n });\n }\n const providers: ProviderCheck[] = [\n ...(sources.design ?? []).map((provider, index) => ({\n provider,\n index,\n kinds: \"design\" as const,\n })),\n ...(sources.notifiers ?? []).map((provider, index) => ({\n provider,\n index,\n kinds: \"notifier\" as const,\n })),\n ];\n return [\n ...checkSlots(checks),\n ...checkProviders(providers),\n ...checkEmailSender(sources.emailSender),\n ];\n}\n\n/**\n * Validate a full boot assembly: adapters plus the optional auth engine.\n * App assembly calls this — `ShelfOptions` carries `auth` alongside the\n * adapter slots, and an invalid engine fails boot like any adapter.\n */\nexport function validateBootAssembly(\n sources: AdapterSetupSources & { auth?: unknown },\n): AdapterSetupFailure[] {\n return [...validateAdapterSources(sources), ...checkAuth(sources.auth)];\n}\n"],"mappings":"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"}
package/dist/ai.d.mts ADDED
@@ -0,0 +1,103 @@
1
+ import __tsdown_shims_path from 'node:path';
2
+ import __tsdown_shims_url from 'node:url';
3
+ import { Logger } from "./logger.mjs";
4
+ import { EvidenceLimits } from "./insights/limits.mjs";
5
+ import { z } from "zod";
6
+ /** Tasks the AI surface routes: build triage and project health. */
7
+ type AiTask = "triage" | "health";
8
+ /** One screenshot sent to a vision-capable model. */
9
+ interface AiImage {
10
+ mediaType: "image/png";
11
+ data: Uint8Array;
12
+ /** Short caption (story, viewport) shown to the model before the image. */
13
+ label: string;
14
+ }
15
+ /** Evidence handed to the model: delimited text plus optional images. */
16
+ interface AiEvidence {
17
+ text: string;
18
+ images: AiImage[];
19
+ }
20
+ /** Provider-reported (or estimated) token usage for one call. */
21
+ interface AiUsageReport {
22
+ inputTokens: number;
23
+ outputTokens: number;
24
+ /** True when the backend reported nothing and a char/4 estimate was used. */
25
+ estimated: boolean;
26
+ }
27
+ /** Input for {@link Ai.summarize}. */
28
+ interface AiSummarizeInput<T> {
29
+ task: AiTask;
30
+ /** Requested profile; falls back to the default profile with a warning. */
31
+ profile?: string;
32
+ system: string;
33
+ evidence: AiEvidence;
34
+ /** Result schema (the model output is validated against it). */
35
+ schema: z.ZodType<T>;
36
+ signal?: AbortSignal;
37
+ }
38
+ /** Result of one successful summarize call. */
39
+ interface AiSummarizeResult<T> {
40
+ object: T;
41
+ usage: AiUsageReport;
42
+ profileRequested: string | null;
43
+ profileEffective: string;
44
+ model: string;
45
+ /** Number of images actually sent to the model. */
46
+ imagesSent: number;
47
+ /** True when images were dropped (no vision model, or provider rejected them). */
48
+ visionSkipped: boolean;
49
+ warnings: string[];
50
+ }
51
+ /** Instance-level budget options (all optional). */
52
+ interface AiBudget {
53
+ /** Site-wide daily token cap (UTC day); undefined = no daily cap. */
54
+ dailyTokens?: number;
55
+ /** Multiplier applied to tokens counted for calls that sent images. */
56
+ visionWeight: number;
57
+ /** Per-project call cap per rolling hour. */
58
+ perProjectCallsPerHour: number;
59
+ }
60
+ /** Why a summarize call failed. */
61
+ type AiErrorCode = "timeout" | "provider" | "schema" | "aborted" | "unknown";
62
+ /** Failure from {@link Ai.summarize}; carries usage the provider still billed. */
63
+ declare class AiError extends Error {
64
+ readonly code: AiErrorCode;
65
+ readonly usage?: AiUsageReport;
66
+ constructor(code: AiErrorCode, message: string, usage?: AiUsageReport, options?: {
67
+ cause?: unknown;
68
+ });
69
+ }
70
+ /** Health probe result. */
71
+ interface AiHealth {
72
+ ok: boolean;
73
+ detail?: string;
74
+ }
75
+ /** The AI surface consumed by `ShelfOptions.ai`. */
76
+ interface Ai {
77
+ /** Run one structured summarize call against a profile's model. */
78
+ summarize<T>(input: AiSummarizeInput<T>): Promise<AiSummarizeResult<T>>;
79
+ /** Configured profile names. */
80
+ profileNames(): string[];
81
+ /** The profile used when none (or an unknown one) is requested. */
82
+ defaultProfile(): string;
83
+ /** Whether the profile has an effective vision model for the task. */
84
+ hasVision(profile: string | undefined, task: AiTask): boolean;
85
+ /** Stable identifier of the model a call would use (for hashing/rows). */
86
+ modelId(profile: string | undefined, task: AiTask, withImages?: boolean): string;
87
+ /** Budget options (with defaults applied). */
88
+ budget(): AiBudget;
89
+ /** Evidence limit overrides configured on the instance. */
90
+ limits(): Partial<EvidenceLimits>;
91
+ /** Per-slot timeout in milliseconds. */
92
+ timeoutMs(profile: string | undefined, task: AiTask, withImages?: boolean): number;
93
+ /** Host-bound scoped logger. */
94
+ setLogger?(logger: Logger): void;
95
+ /** Free boot checks (spec version, wiring); never a billed call. */
96
+ setup(): Promise<void>;
97
+ /** Cheap liveness probe; never inference. */
98
+ health(): Promise<AiHealth>;
99
+ /** Release resources (unregisters nothing global). */
100
+ teardown(): Promise<void>;
101
+ }
102
+ export { Ai, AiBudget, AiError, AiErrorCode, AiEvidence, AiHealth, AiImage, AiSummarizeInput, AiSummarizeResult, AiTask, AiUsageReport };
103
+ //# sourceMappingURL=ai.d.mts.map
package/dist/ai.mjs ADDED
@@ -0,0 +1,18 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ // src/ai.ts
5
+ /** Failure from {@link Ai.summarize}; carries usage the provider still billed. */
6
+ var AiError = class extends Error {
7
+ code;
8
+ usage;
9
+ constructor(code, message, usage, options) {
10
+ super(message, options);
11
+ this.code = code;
12
+ this.usage = usage;
13
+ this.name = "AiError";
14
+ }
15
+ };
16
+ export { AiError };
17
+
18
+ //# sourceMappingURL=ai.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.mjs","names":[],"sources":["../src/ai.ts"],"sourcesContent":["/**\n * AI singleton surface (not an adapter; see ADR 0016).\n *\n * Owned by core so `ShelfOptions.ai` needs no dependency edge into the\n * implementation package (`@storyshelf/ai` already depends on core). The\n * package implements and re-exports {@link Ai}.\n */\nimport type { z } from \"zod\";\nimport type { EvidenceLimits } from \"./insights/limits.ts\";\nimport type { Logger } from \"./logger.ts\";\n\n/** Tasks the AI surface routes: build triage and project health. */\nexport type AiTask = \"triage\" | \"health\";\n\n/** One screenshot sent to a vision-capable model. */\nexport interface AiImage {\n mediaType: \"image/png\";\n data: Uint8Array;\n /** Short caption (story, viewport) shown to the model before the image. */\n label: string;\n}\n\n/** Evidence handed to the model: delimited text plus optional images. */\nexport interface AiEvidence {\n text: string;\n images: AiImage[];\n}\n\n/** Provider-reported (or estimated) token usage for one call. */\nexport interface AiUsageReport {\n inputTokens: number;\n outputTokens: number;\n /** True when the backend reported nothing and a char/4 estimate was used. */\n estimated: boolean;\n}\n\n/** Input for {@link Ai.summarize}. */\nexport interface AiSummarizeInput<T> {\n task: AiTask;\n /** Requested profile; falls back to the default profile with a warning. */\n profile?: string;\n system: string;\n evidence: AiEvidence;\n /** Result schema (the model output is validated against it). */\n schema: z.ZodType<T>;\n signal?: AbortSignal;\n}\n\n/** Result of one successful summarize call. */\nexport interface AiSummarizeResult<T> {\n object: T;\n usage: AiUsageReport;\n profileRequested: string | null;\n profileEffective: string;\n model: string;\n /** Number of images actually sent to the model. */\n imagesSent: number;\n /** True when images were dropped (no vision model, or provider rejected them). */\n visionSkipped: boolean;\n warnings: string[];\n}\n\n/** Instance-level budget options (all optional). */\nexport interface AiBudget {\n /** Site-wide daily token cap (UTC day); undefined = no daily cap. */\n dailyTokens?: number;\n /** Multiplier applied to tokens counted for calls that sent images. */\n visionWeight: number;\n /** Per-project call cap per rolling hour. */\n perProjectCallsPerHour: number;\n}\n\n/** Why a summarize call failed. */\nexport type AiErrorCode = \"timeout\" | \"provider\" | \"schema\" | \"aborted\" | \"unknown\";\n\n/** Failure from {@link Ai.summarize}; carries usage the provider still billed. */\nexport class AiError extends Error {\n readonly code: AiErrorCode;\n readonly usage?: AiUsageReport;\n\n constructor(\n code: AiErrorCode,\n message: string,\n usage?: AiUsageReport,\n options?: { cause?: unknown },\n ) {\n super(message, options);\n this.code = code;\n this.usage = usage;\n this.name = \"AiError\";\n }\n}\n\n/** Health probe result. */\nexport interface AiHealth {\n ok: boolean;\n detail?: string;\n}\n\n/** The AI surface consumed by `ShelfOptions.ai`. */\nexport interface Ai {\n /** Run one structured summarize call against a profile's model. */\n summarize<T>(input: AiSummarizeInput<T>): Promise<AiSummarizeResult<T>>;\n /** Configured profile names. */\n profileNames(): string[];\n /** The profile used when none (or an unknown one) is requested. */\n defaultProfile(): string;\n /** Whether the profile has an effective vision model for the task. */\n hasVision(profile: string | undefined, task: AiTask): boolean;\n /** Stable identifier of the model a call would use (for hashing/rows). */\n modelId(profile: string | undefined, task: AiTask, withImages?: boolean): string;\n /** Budget options (with defaults applied). */\n budget(): AiBudget;\n /** Evidence limit overrides configured on the instance. */\n limits(): Partial<EvidenceLimits>;\n /** Per-slot timeout in milliseconds. */\n timeoutMs(profile: string | undefined, task: AiTask, withImages?: boolean): number;\n /** Host-bound scoped logger. */\n setLogger?(logger: Logger): void;\n /** Free boot checks (spec version, wiring); never a billed call. */\n setup(): Promise<void>;\n /** Cheap liveness probe; never inference. */\n health(): Promise<AiHealth>;\n /** Release resources (unregisters nothing global). */\n teardown(): Promise<void>;\n}\n"],"mappings":";;;;;AA4EA,IAAa,UAAb,cAA6B,MAAM;CACjC;CACA;CAEA,YACE,MACA,SACA,OACA,SACA;EACA,MAAM,SAAS,OAAO;EACtB,KAAK,OAAO;EACZ,KAAK,QAAQ;EACb,KAAK,OAAO;CACd;AACF"}
package/dist/auth.d.mts CHANGED
@@ -1,7 +1,6 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
3
  import { AuthUser } from "./types.mjs";
4
- //#region src/auth.d.ts
5
4
  /** Login widget kinds in display order (the shelf plugin contract). */
6
5
  type EngineLoginMethodKind = "password" | "oauth" | "passkey" | "sso";
7
6
  /**
@@ -96,6 +95,5 @@ declare const MIN_PASSWORD_LENGTH = 12;
96
95
  * Single shared parser: cookies, CSRF binding, and table lookups must agree.
97
96
  */
98
97
  declare function unsignedToken(value: string): string;
99
- //#endregion
100
98
  export { Auth, EngineLoginMethod, EngineLoginMethodKind, EnginePasskeyInfo, EngineSessionInfo, MIN_PASSWORD_LENGTH, unsignedToken };
101
99
  //# sourceMappingURL=auth.d.mts.map
package/dist/auth.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- //#region src/auth.ts
4
+ // src/auth.ts
5
5
  /** Minimum password length for local accounts (matches legacy policy). */
6
6
  const MIN_PASSWORD_LENGTH = 12;
7
7
  /**
@@ -11,7 +11,6 @@ const MIN_PASSWORD_LENGTH = 12;
11
11
  function unsignedToken(value) {
12
12
  return value.split(".")[0] ?? "";
13
13
  }
14
- //#endregion
15
14
  export { MIN_PASSWORD_LENGTH, unsignedToken };
16
15
 
17
16
  //# sourceMappingURL=auth.mjs.map
@@ -1,7 +1,6 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
3
  import { BrandTheme } from "./config.mjs";
4
- //#region src/brand-packs.d.ts
5
4
  /** One named light/dark theme pair. */
6
5
  interface BrandPack {
7
6
  light: BrandTheme;
@@ -11,6 +10,5 @@ interface BrandPack {
11
10
  declare const brandPacks: Record<string, BrandPack>;
12
11
  /** Look up a brand pack by name (undefined for unknown names). */
13
12
  declare function brandPack(name: string): BrandPack | undefined;
14
- //#endregion
15
13
  export { BrandPack, brandPack, brandPacks };
16
14
  //# sourceMappingURL=brand-packs.d.mts.map
@@ -124,7 +124,6 @@ const brandPacks = {
124
124
  function brandPack(name) {
125
125
  return brandPacks[name];
126
126
  }
127
- //#endregion
128
127
  export { brandPack, brandPacks };
129
128
 
130
129
  //# sourceMappingURL=brand-packs.mjs.map
@@ -0,0 +1,16 @@
1
+ import __tsdown_shims_path from 'node:path';
2
+ import __tsdown_shims_url from 'node:url';
3
+ /** Lazy, cached loader for the axe-core browser bundle. */
4
+ /**
5
+ * Read `axe.min.js` (~550 KB) once per process, on first use. Lazy on purpose: servers that never run
6
+ * accessibility checks do not touch the file at boot. A failed read is not cached.
7
+ */
8
+ declare function loadAxeSource(): Promise<string>;
9
+ /**
10
+ * Wrap the axe source so evaluating it twice in one document is a no-op. Evaluate it as a string
11
+ * (CDP `Runtime.evaluate`: not bound by the page's CSP and works over remote browsers, since the
12
+ * source travels over the wire instead of a file path).
13
+ */
14
+ declare function axeInjectionScript(source: string): string;
15
+ export { axeInjectionScript, loadAxeSource };
16
+ //# sourceMappingURL=axe-source.d.mts.map