@storyshelf/core 0.7.0 → 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 (531) hide show
  1. package/dist/adapter/capture-queue.d.mts +0 -2
  2. package/dist/adapter/capture-runner.d.mts +9 -4
  3. package/dist/adapter/capture-runner.mjs +6 -2
  4. package/dist/adapter/database.d.mts +63 -3
  5. package/dist/adapter/database.mjs +4 -3
  6. package/dist/adapter/database.mjs.map +1 -1
  7. package/dist/adapter/design.d.mts +0 -2
  8. package/dist/adapter/design.mjs +1 -2
  9. package/dist/adapter/email-sender.d.mts +0 -2
  10. package/dist/adapter/metadata.d.mts +0 -2
  11. package/dist/adapter/oauth.d.mts +0 -2
  12. package/dist/adapter/setup.d.mts +0 -2
  13. package/dist/adapter/setup.mjs +1 -2
  14. package/dist/adapter/storage.d.mts +1 -3
  15. package/dist/adapter/webhook-events.d.mts +0 -2
  16. package/dist/adapter/webhook-events.mjs +12 -13
  17. package/dist/adapter/webhook-events.mjs.map +1 -1
  18. package/dist/adapters/capture-target-offers.d.mts +0 -2
  19. package/dist/adapters/capture-target-offers.mjs +1 -2
  20. package/dist/adapters/capture-target.d.mts +0 -2
  21. package/dist/adapters/capture-target.mjs +1 -2
  22. package/dist/adapters/notifier/build-comment.d.mts +0 -2
  23. package/dist/adapters/notifier/build-comment.mjs +1 -2
  24. package/dist/adapters/notifier/build-state.d.mts +0 -2
  25. package/dist/adapters/notifier/build-state.mjs +1 -2
  26. package/dist/adapters/notifier/events.d.mts +0 -2
  27. package/dist/adapters/notifier/events.mjs +1 -2
  28. package/dist/adapters/notifier/format.d.mts +0 -2
  29. package/dist/adapters/notifier/format.mjs +1 -2
  30. package/dist/adapters/notifier/provider.d.mts +0 -2
  31. package/dist/adapters/notifier/provider.mjs +1 -2
  32. package/dist/adapters/notifier/state.d.mts +0 -2
  33. package/dist/adapters/notifier/state.mjs +1 -2
  34. package/dist/adapters/notifier/types.d.mts +0 -2
  35. package/dist/adapters/remote-browser.d.mts +112 -31
  36. package/dist/adapters/remote-browser.mjs +132 -34
  37. package/dist/adapters/remote-browser.mjs.map +1 -1
  38. package/dist/adapters/remote-lease-attempt.mjs +39 -0
  39. package/dist/adapters/remote-lease-attempt.mjs.map +1 -0
  40. package/dist/adapters/remote-lease-error.d.mts +25 -0
  41. package/dist/adapters/remote-lease-error.mjs +54 -0
  42. package/dist/adapters/remote-lease-error.mjs.map +1 -0
  43. package/dist/adapters/remote-lease-held.d.mts +15 -0
  44. package/dist/adapters/remote-lease-held.mjs +86 -0
  45. package/dist/adapters/remote-lease-held.mjs.map +1 -0
  46. package/dist/adapters/remote-lease-shutdown.d.mts +12 -0
  47. package/dist/adapters/remote-lease-shutdown.mjs +32 -0
  48. package/dist/adapters/remote-lease-shutdown.mjs.map +1 -0
  49. package/dist/adapters/remote-lease.d.mts +39 -0
  50. package/dist/adapters/remote-lease.mjs +175 -0
  51. package/dist/adapters/remote-lease.mjs.map +1 -0
  52. package/dist/adapters/remote-limiter.mjs +121 -0
  53. package/dist/adapters/remote-limiter.mjs.map +1 -0
  54. package/dist/adapters/remote-pool.d.mts +56 -0
  55. package/dist/adapters/remote-pool.mjs +195 -0
  56. package/dist/adapters/remote-pool.mjs.map +1 -0
  57. package/dist/adapters/render-runs.d.mts +0 -2
  58. package/dist/adapters/render-runs.mjs +1 -2
  59. package/dist/adapters/setup-runner.d.mts +0 -2
  60. package/dist/adapters/setup-runner.mjs +1 -2
  61. package/dist/adapters/sources.d.mts +0 -2
  62. package/dist/adapters/sources.mjs +1 -2
  63. package/dist/adapters/validate.d.mts +0 -2
  64. package/dist/adapters/validate.mjs +2 -2
  65. package/dist/adapters/validate.mjs.map +1 -1
  66. package/dist/ai.d.mts +0 -2
  67. package/dist/ai.mjs +1 -2
  68. package/dist/auth.d.mts +0 -2
  69. package/dist/auth.mjs +1 -2
  70. package/dist/brand-packs.d.mts +0 -2
  71. package/dist/brand-packs.mjs +0 -1
  72. package/dist/capture/a11y/axe-source.d.mts +0 -2
  73. package/dist/capture/a11y/axe-source.mjs +1 -2
  74. package/dist/capture/a11y/in-page.d.mts +1 -3
  75. package/dist/capture/a11y/in-page.mjs +3 -4
  76. package/dist/capture/a11y/in-page.mjs.map +1 -1
  77. package/dist/capture/a11y/map.d.mts +0 -2
  78. package/dist/capture/a11y/map.mjs +1 -2
  79. package/dist/capture/a11y/options.d.mts +0 -2
  80. package/dist/capture/a11y/options.mjs +1 -2
  81. package/dist/capture/adapter.d.mts +5 -2
  82. package/dist/capture/adapter.mjs +1 -2
  83. package/dist/capture/adapter.mjs.map +1 -1
  84. package/dist/capture/affected.d.mts +0 -2
  85. package/dist/capture/affected.mjs +1 -2
  86. package/dist/capture/attempt-logger.mjs +1 -2
  87. package/dist/capture/browsers.d.mts +0 -2
  88. package/dist/capture/browsers.mjs +1 -2
  89. package/dist/capture/build-state/deliver.d.mts +0 -2
  90. package/dist/capture/build-state/deliver.mjs +1 -2
  91. package/dist/capture/build-state/notify-job.d.mts +0 -2
  92. package/dist/capture/build-state/notify-job.mjs +1 -2
  93. package/dist/capture/build-state/publisher.d.mts +0 -2
  94. package/dist/capture/build-state/publisher.mjs +1 -2
  95. package/dist/capture/build-state/resume.d.mts +0 -2
  96. package/dist/capture/build-state/resume.mjs +1 -2
  97. package/dist/capture/build-state/types.d.mts +1 -3
  98. package/dist/capture/catalog/catalogue.d.mts +0 -2
  99. package/dist/capture/catalog/catalogue.mjs +1 -2
  100. package/dist/capture/catalog/components.d.mts +0 -2
  101. package/dist/capture/catalog/components.mjs +1 -2
  102. package/dist/capture/catalog/history.d.mts +0 -2
  103. package/dist/capture/catalog/history.mjs +1 -2
  104. package/dist/capture/catalog/hook.d.mts +0 -2
  105. package/dist/capture/catalog/hook.mjs +1 -2
  106. package/dist/capture/catalog/index.d.mts +2 -2
  107. package/dist/capture/catalog/load.d.mts +0 -2
  108. package/dist/capture/catalog/load.mjs +1 -2
  109. package/dist/capture/catalog/parse.d.mts +0 -2
  110. package/dist/capture/catalog/parse.mjs +1 -2
  111. package/dist/capture/catalog/read.d.mts +6 -3
  112. package/dist/capture/catalog/read.mjs +14 -8
  113. package/dist/capture/catalog/read.mjs.map +1 -1
  114. package/dist/capture/catalog/types.d.mts +0 -2
  115. package/dist/capture/comparison-reference.d.mts +27 -0
  116. package/dist/capture/comparison-reference.mjs +75 -0
  117. package/dist/capture/comparison-reference.mjs.map +1 -0
  118. package/dist/capture/consumer/capture-handler.d.mts +1 -3
  119. package/dist/capture/consumer/capture-handler.mjs +1 -2
  120. package/dist/capture/consumer/idle.d.mts +0 -2
  121. package/dist/capture/consumer/idle.mjs +1 -2
  122. package/dist/capture/consumer/index.d.mts +0 -2
  123. package/dist/capture/consumer/index.mjs +1 -2
  124. package/dist/capture/consumer/loop.mjs +1 -2
  125. package/dist/capture/consumer/metrics.d.mts +0 -2
  126. package/dist/capture/consumer/metrics.mjs +1 -2
  127. package/dist/capture/consumer/retry.d.mts +0 -2
  128. package/dist/capture/consumer/retry.mjs +1 -2
  129. package/dist/capture/consumer/run-job.mjs +1 -2
  130. package/dist/capture/consumer/startup.mjs +1 -2
  131. package/dist/capture/consumer/types.d.mts +0 -2
  132. package/dist/capture/crash-failure.d.mts +0 -2
  133. package/dist/capture/crash-failure.mjs +1 -2
  134. package/dist/capture/db-queue/cadence.d.mts +0 -2
  135. package/dist/capture/db-queue/cadence.mjs +1 -2
  136. package/dist/capture/db-queue/claim.d.mts +0 -2
  137. package/dist/capture/db-queue/claim.mjs +20 -4
  138. package/dist/capture/db-queue/claim.mjs.map +1 -1
  139. package/dist/capture/db-queue/clock.mjs +1 -2
  140. package/dist/capture/db-queue/codec.mjs +1 -2
  141. package/dist/capture/db-queue/index.d.mts +0 -2
  142. package/dist/capture/db-queue/index.mjs +3 -3
  143. package/dist/capture/db-queue/index.mjs.map +1 -1
  144. package/dist/capture/db-queue/keeper.d.mts +0 -2
  145. package/dist/capture/db-queue/keeper.mjs +1 -2
  146. package/dist/capture/db-queue/lease.mjs +1 -2
  147. package/dist/capture/db-queue/lifecycle.mjs +1 -2
  148. package/dist/capture/db-queue/operations.mjs +1 -2
  149. package/dist/capture/db-queue/poll-loop.d.mts +0 -2
  150. package/dist/capture/db-queue/poll-loop.mjs +1 -2
  151. package/dist/capture/db-queue/poll.d.mts +0 -2
  152. package/dist/capture/db-queue/poll.mjs +1 -2
  153. package/dist/capture/db-queue/timers.d.mts +0 -2
  154. package/dist/capture/db-queue/timers.mjs +1 -2
  155. package/dist/capture/db-queue/types.d.mts +0 -2
  156. package/dist/capture/db-queue/types.mjs +1 -2
  157. package/dist/capture/db-queue/types.mjs.map +1 -1
  158. package/dist/capture/db-queue/wake.mjs +1 -2
  159. package/dist/capture/design.mjs +1 -2
  160. package/dist/capture/diff-record.mjs +1 -2
  161. package/dist/capture/dispatch.d.mts +1 -3
  162. package/dist/capture/dispatch.mjs +17 -5
  163. package/dist/capture/dispatch.mjs.map +1 -1
  164. package/dist/capture/enrich.mjs +1 -2
  165. package/dist/capture/failure-sets.mjs +1 -2
  166. package/dist/capture/fingerprint.d.mts +0 -2
  167. package/dist/capture/fingerprint.mjs +1 -2
  168. package/dist/capture/forked/channel.d.mts +0 -2
  169. package/dist/capture/forked/child.d.mts +0 -2
  170. package/dist/capture/forked/child.mjs +1 -2
  171. package/dist/capture/forked/crash-tracker.mjs +1 -2
  172. package/dist/capture/forked/decision.d.mts +0 -2
  173. package/dist/capture/forked/decision.mjs +1 -2
  174. package/dist/capture/forked/exit.mjs +1 -2
  175. package/dist/capture/forked/fork.d.mts +0 -2
  176. package/dist/capture/forked/fork.mjs +1 -2
  177. package/dist/capture/forked/forked-capture.d.mts +0 -2
  178. package/dist/capture/forked/forked-capture.mjs +1 -2
  179. package/dist/capture/forked/lease-book.mjs +1 -2
  180. package/dist/capture/forked/protocol.d.mts +0 -2
  181. package/dist/capture/forked/protocol.mjs +1 -2
  182. package/dist/capture/forked/runs.mjs +1 -2
  183. package/dist/capture/guards.mjs +1 -2
  184. package/dist/capture/ignore-regions.d.mts +36 -0
  185. package/dist/capture/ignore-regions.mjs +65 -0
  186. package/dist/capture/ignore-regions.mjs.map +1 -0
  187. package/dist/capture/isolate.mjs +1 -2
  188. package/dist/capture/job-lease.d.mts +0 -2
  189. package/dist/capture/job-lease.mjs +1 -2
  190. package/dist/capture/matrix.mjs +4 -4
  191. package/dist/capture/matrix.mjs.map +1 -1
  192. package/dist/capture/modes.d.mts +0 -2
  193. package/dist/capture/modes.mjs +2 -3
  194. package/dist/capture/modes.mjs.map +1 -1
  195. package/dist/capture/orchestrator.d.mts +0 -2
  196. package/dist/capture/orchestrator.mjs +2 -3
  197. package/dist/capture/pipeline.d.mts +0 -2
  198. package/dist/capture/pipeline.mjs +37 -6
  199. package/dist/capture/pipeline.mjs.map +1 -1
  200. package/dist/capture/progress.d.mts +0 -2
  201. package/dist/capture/progress.mjs +1 -2
  202. package/dist/capture/publish/accept.d.mts +0 -2
  203. package/dist/capture/publish/accept.mjs +1 -2
  204. package/dist/capture/publish/complete.d.mts +1 -3
  205. package/dist/capture/publish/complete.mjs +1 -2
  206. package/dist/capture/publish/extract.d.mts +0 -2
  207. package/dist/capture/publish/extract.mjs +6 -5
  208. package/dist/capture/publish/extract.mjs.map +1 -1
  209. package/dist/capture/publish/handler.d.mts +1 -3
  210. package/dist/capture/publish/handler.mjs +1 -2
  211. package/dist/capture/publish/index.d.mts +2 -1
  212. package/dist/capture/publish/invalid-zip.d.mts +8 -0
  213. package/dist/capture/publish/invalid-zip.mjs +11 -0
  214. package/dist/capture/publish/invalid-zip.mjs.map +1 -0
  215. package/dist/capture/publish/limits.d.mts +0 -2
  216. package/dist/capture/publish/limits.mjs +1 -2
  217. package/dist/capture/publish/published.d.mts +0 -2
  218. package/dist/capture/publish/published.mjs +1 -2
  219. package/dist/capture/publish/run.d.mts +1 -3
  220. package/dist/capture/publish/run.mjs +1 -2
  221. package/dist/capture/rediff.d.mts +1 -3
  222. package/dist/capture/rediff.mjs +19 -6
  223. package/dist/capture/rediff.mjs.map +1 -1
  224. package/dist/capture/render.mjs +1 -2
  225. package/dist/capture/render.mjs.map +1 -1
  226. package/dist/capture/scratch.d.mts +0 -2
  227. package/dist/capture/scratch.mjs +2 -4
  228. package/dist/capture/scratch.mjs.map +1 -1
  229. package/dist/capture/shard-plan.mjs +1 -2
  230. package/dist/capture/shards/context.mjs +3 -3
  231. package/dist/capture/shards/context.mjs.map +1 -1
  232. package/dist/capture/shards/execute.mjs +4 -3
  233. package/dist/capture/shards/execute.mjs.map +1 -1
  234. package/dist/capture/shards/fan-out.mjs +1 -2
  235. package/dist/capture/shards/history.mjs +1 -2
  236. package/dist/capture/shards/reduce.mjs +1 -2
  237. package/dist/capture/sizing.d.mts +0 -2
  238. package/dist/capture/sizing.mjs +1 -2
  239. package/dist/capture/skip-checks.mjs +1 -2
  240. package/dist/capture/statics.d.mts +0 -2
  241. package/dist/capture/statics.mjs +2 -4
  242. package/dist/capture/statics.mjs.map +1 -1
  243. package/dist/capture/storybook-urls.d.mts +0 -2
  244. package/dist/capture/storybook-urls.mjs +3 -3
  245. package/dist/capture/storybook-urls.mjs.map +1 -1
  246. package/dist/capture/storybook.d.mts +0 -2
  247. package/dist/capture/storybook.mjs +8 -4
  248. package/dist/capture/storybook.mjs.map +1 -1
  249. package/dist/capture/target.mjs +1 -2
  250. package/dist/capture/targets.d.mts +0 -2
  251. package/dist/capture/targets.mjs +1 -2
  252. package/dist/capture/tests.d.mts +0 -2
  253. package/dist/capture/tests.mjs +13 -3
  254. package/dist/capture/tests.mjs.map +1 -1
  255. package/dist/capture/token-chunks.mjs +24 -7
  256. package/dist/capture/token-chunks.mjs.map +1 -1
  257. package/dist/capture.d.mts +5 -2
  258. package/dist/capture.mjs +5 -2
  259. package/dist/config.d.mts +16 -3
  260. package/dist/config.mjs +6 -3
  261. package/dist/config.mjs.map +1 -1
  262. package/dist/diff.d.mts +0 -2
  263. package/dist/diff.mjs +1 -2
  264. package/dist/index.d.mts +2 -2
  265. package/dist/index.mjs +2 -2
  266. package/dist/insights/budget.d.mts +0 -2
  267. package/dist/insights/budget.mjs +1 -2
  268. package/dist/insights/envelope.d.mts +0 -2
  269. package/dist/insights/envelope.mjs +1 -2
  270. package/dist/insights/evidence-health.d.mts +0 -2
  271. package/dist/insights/evidence-health.mjs +1 -2
  272. package/dist/insights/evidence.d.mts +0 -2
  273. package/dist/insights/evidence.mjs +1 -2
  274. package/dist/insights/hash.d.mts +0 -2
  275. package/dist/insights/hash.mjs +1 -2
  276. package/dist/insights/limits.d.mts +0 -2
  277. package/dist/insights/limits.mjs +1 -2
  278. package/dist/insights/prompts/v1.d.mts +0 -2
  279. package/dist/insights/prompts/v1.mjs +1 -2
  280. package/dist/insights/redact.d.mts +0 -2
  281. package/dist/insights/redact.mjs +1 -2
  282. package/dist/insights/text.mjs +1 -2
  283. package/dist/logger.d.mts +0 -2
  284. package/dist/logger.mjs +1 -2
  285. package/dist/models/ai-budget-alert.d.mts +0 -2
  286. package/dist/models/ai-budget-alert.mjs +1 -2
  287. package/dist/models/ai-usage.d.mts +0 -2
  288. package/dist/models/ai-usage.mjs +1 -2
  289. package/dist/models/baseline-approval.d.mts +18 -0
  290. package/dist/models/baseline-approval.mjs +41 -0
  291. package/dist/models/baseline-approval.mjs.map +1 -0
  292. package/dist/models/baseline-archive.d.mts +0 -2
  293. package/dist/models/baseline-archive.mjs +1 -2
  294. package/dist/models/baseline-atomic.mjs +66 -0
  295. package/dist/models/baseline-atomic.mjs.map +1 -0
  296. package/dist/models/baseline-conflict.d.mts +6 -0
  297. package/dist/models/baseline-conflict.mjs +9 -0
  298. package/dist/models/baseline-conflict.mjs.map +1 -0
  299. package/dist/models/baseline-export.d.mts +0 -2
  300. package/dist/models/baseline-export.mjs +1 -2
  301. package/dist/models/baseline-import.mjs +1 -2
  302. package/dist/models/baseline-origin.d.mts +16 -0
  303. package/dist/models/baseline-origin.mjs +35 -0
  304. package/dist/models/baseline-origin.mjs.map +1 -0
  305. package/dist/models/baseline-status.d.mts +0 -2
  306. package/dist/models/baseline-status.mjs +1 -2
  307. package/dist/models/baseline-transfer.d.mts +1 -2
  308. package/dist/models/baseline-transfer.mjs +30 -2
  309. package/dist/models/baseline-transfer.mjs.map +1 -1
  310. package/dist/models/baseline.d.mts +5 -2
  311. package/dist/models/baseline.mjs +91 -12
  312. package/dist/models/baseline.mjs.map +1 -1
  313. package/dist/models/build-component.d.mts +0 -2
  314. package/dist/models/build-component.mjs +1 -2
  315. package/dist/models/build-review-status.d.mts +0 -2
  316. package/dist/models/build-review-status.mjs +1 -2
  317. package/dist/models/build-review.d.mts +0 -2
  318. package/dist/models/build-review.mjs +1 -2
  319. package/dist/models/build.d.mts +1 -3
  320. package/dist/models/build.mjs +14 -15
  321. package/dist/models/build.mjs.map +1 -1
  322. package/dist/models/capture-attempt.d.mts +0 -2
  323. package/dist/models/capture-attempt.mjs +1 -2
  324. package/dist/models/capture-job.d.mts +0 -2
  325. package/dist/models/capture-job.mjs +1 -2
  326. package/dist/models/capture-log.d.mts +0 -2
  327. package/dist/models/capture-log.mjs +1 -2
  328. package/dist/models/capture-shard.d.mts +0 -2
  329. package/dist/models/capture-shard.mjs +1 -2
  330. package/dist/models/changeset.d.mts +0 -2
  331. package/dist/models/changeset.mjs +1 -2
  332. package/dist/models/columns.mjs +1 -2
  333. package/dist/models/comment.d.mts +0 -2
  334. package/dist/models/comment.mjs +1 -2
  335. package/dist/models/component.d.mts +0 -2
  336. package/dist/models/component.mjs +1 -2
  337. package/dist/models/connections.d.mts +0 -2
  338. package/dist/models/connections.mjs +1 -2
  339. package/dist/models/content-ref.d.mts +0 -2
  340. package/dist/models/content-ref.mjs +1 -2
  341. package/dist/models/credentials.d.mts +0 -2
  342. package/dist/models/credentials.mjs +1 -2
  343. package/dist/models/design-credentials.d.mts +0 -2
  344. package/dist/models/design-credentials.mjs +1 -2
  345. package/dist/models/design-health.d.mts +0 -2
  346. package/dist/models/design-health.mjs +1 -2
  347. package/dist/models/design-nodes.d.mts +2 -4
  348. package/dist/models/design-nodes.mjs +1 -2
  349. package/dist/models/design-renders.mjs +1 -2
  350. package/dist/models/design-resolve.d.mts +0 -2
  351. package/dist/models/design-resolve.mjs +1 -2
  352. package/dist/models/design.d.mts +0 -2
  353. package/dist/models/design.mjs +1 -2
  354. package/dist/models/inherited-ratio.d.mts +0 -2
  355. package/dist/models/inherited-ratio.mjs +1 -2
  356. package/dist/models/insight.d.mts +0 -2
  357. package/dist/models/insight.mjs +1 -2
  358. package/dist/models/label.d.mts +0 -2
  359. package/dist/models/label.mjs +1 -2
  360. package/dist/models/member.d.mts +0 -2
  361. package/dist/models/member.mjs +1 -2
  362. package/dist/models/notification-channel.d.mts +0 -2
  363. package/dist/models/notification-channel.mjs +1 -2
  364. package/dist/models/notification-subscription.d.mts +0 -2
  365. package/dist/models/notification-subscription.mjs +1 -2
  366. package/dist/models/project-group-mapping.d.mts +0 -2
  367. package/dist/models/project-group-mapping.mjs +1 -2
  368. package/dist/models/project.d.mts +0 -2
  369. package/dist/models/project.mjs +1 -2
  370. package/dist/models/public-origin.d.mts +0 -2
  371. package/dist/models/public-origin.mjs +1 -2
  372. package/dist/models/review-switch-off.d.mts +0 -2
  373. package/dist/models/review-switch-off.mjs +1 -2
  374. package/dist/models/site-settings.d.mts +0 -2
  375. package/dist/models/site-settings.mjs +1 -2
  376. package/dist/models/snapshot.d.mts +3 -2
  377. package/dist/models/snapshot.mjs +4 -2
  378. package/dist/models/snapshot.mjs.map +1 -1
  379. package/dist/models/token.d.mts +0 -2
  380. package/dist/models/token.mjs +1 -2
  381. package/dist/models/usage.d.mts +0 -2
  382. package/dist/models/usage.mjs +1 -2
  383. package/dist/models/user.d.mts +0 -2
  384. package/dist/models/user.mjs +1 -2
  385. package/dist/models/webhook.d.mts +0 -2
  386. package/dist/models/webhook.mjs +1 -2
  387. package/dist/models.d.mts +5 -2
  388. package/dist/models.mjs +5 -2
  389. package/dist/options.d.mts +0 -2
  390. package/dist/options.mjs +2 -4
  391. package/dist/options.mjs.map +1 -1
  392. package/dist/paths.d.mts +3 -3
  393. package/dist/paths.mjs +7 -3
  394. package/dist/paths.mjs.map +1 -1
  395. package/dist/retention/ai.d.mts +1 -3
  396. package/dist/retention/ai.mjs +0 -1
  397. package/dist/retention/pending.mjs +1 -2
  398. package/dist/retention/published-gzip-sweep.mjs +28 -0
  399. package/dist/retention/published-gzip-sweep.mjs.map +1 -0
  400. package/dist/retention/screenshot-sweep.d.mts +0 -2
  401. package/dist/retention/screenshot-sweep.mjs +1 -2
  402. package/dist/retention.d.mts +0 -2
  403. package/dist/retention.mjs +5 -2
  404. package/dist/retention.mjs.map +1 -1
  405. package/dist/schema/baseline.d.mts +2 -2
  406. package/dist/schema/build-component.d.mts +0 -2
  407. package/dist/schema/build-review.d.mts +0 -2
  408. package/dist/schema/build.d.mts +0 -2
  409. package/dist/schema/capture-attempt.d.mts +0 -2
  410. package/dist/schema/capture-job.d.mts +0 -2
  411. package/dist/schema/capture-shard.d.mts +0 -2
  412. package/dist/schema/comment.d.mts +0 -2
  413. package/dist/schema/connection.d.mts +0 -2
  414. package/dist/schema/content-ref.d.mts +0 -2
  415. package/dist/schema/design.d.mts +0 -2
  416. package/dist/schema/insight.d.mts +0 -2
  417. package/dist/schema/label.d.mts +0 -2
  418. package/dist/schema/member.d.mts +0 -2
  419. package/dist/schema/notification.d.mts +0 -2
  420. package/dist/schema/project-group-mapping.d.mts +0 -2
  421. package/dist/schema/project.d.mts +0 -2
  422. package/dist/schema/site-setting.d.mts +0 -2
  423. package/dist/schema/snapshot.d.mts +5 -2
  424. package/dist/schema/token.d.mts +0 -2
  425. package/dist/schema/usage.d.mts +0 -2
  426. package/dist/schema/user.d.mts +0 -2
  427. package/dist/schema/webhook.d.mts +0 -2
  428. package/dist/schema.d.mts +4 -6
  429. package/dist/serverless.d.mts +0 -2
  430. package/dist/serverless.mjs +1 -2
  431. package/dist/test-helpers/build-reference-contract.d.mts +14 -0
  432. package/dist/test-helpers/build-reference-contract.mjs +66 -0
  433. package/dist/test-helpers/build-reference-contract.mjs.map +1 -0
  434. package/dist/test-helpers/create-project.d.mts +0 -2
  435. package/dist/test-helpers/create-project.mjs +1 -2
  436. package/dist/test-helpers/database-contract.d.mts +0 -2
  437. package/dist/test-helpers/database-contract.mjs +37 -2
  438. package/dist/test-helpers/database-contract.mjs.map +1 -1
  439. package/dist/test-helpers/deferred.d.mts +0 -2
  440. package/dist/test-helpers/deferred.mjs +1 -2
  441. package/dist/test-helpers/design-contract.d.mts +0 -2
  442. package/dist/test-helpers/design-contract.mjs +1 -2
  443. package/dist/test-helpers/fake-adapters.d.mts +0 -2
  444. package/dist/test-helpers/fake-adapters.mjs +1 -2
  445. package/dist/test-helpers/fake-database.d.mts +0 -2
  446. package/dist/test-helpers/fake-database.mjs +7 -2
  447. package/dist/test-helpers/fake-database.mjs.map +1 -1
  448. package/dist/test-helpers/fake-design.d.mts +0 -2
  449. package/dist/test-helpers/fake-design.mjs +1 -2
  450. package/dist/test-helpers/fake-notifier.d.mts +0 -2
  451. package/dist/test-helpers/fake-notifier.mjs +1 -2
  452. package/dist/test-helpers/fake-storage.d.mts +0 -2
  453. package/dist/test-helpers/fake-storage.mjs +1 -2
  454. package/dist/test-helpers/fake-tables.mjs +5 -2
  455. package/dist/test-helpers/fake-tables.mjs.map +1 -1
  456. package/dist/test-helpers/manual-clock.d.mts +0 -2
  457. package/dist/test-helpers/manual-clock.mjs +1 -2
  458. package/dist/test-helpers/notifier-contract.d.mts +0 -2
  459. package/dist/test-helpers/notifier-contract.mjs +1 -2
  460. package/dist/test-helpers/queue-contract.d.mts +0 -2
  461. package/dist/test-helpers/queue-contract.mjs +1 -2
  462. package/dist/test-helpers/queue-multi-instance.d.mts +0 -2
  463. package/dist/test-helpers/queue-multi-instance.mjs +1 -2
  464. package/dist/test-helpers/runner-contract.d.mts +0 -2
  465. package/dist/test-helpers/runner-contract.mjs +1 -2
  466. package/dist/test-helpers/sql-chunks.mjs +2 -2
  467. package/dist/test-helpers/sql-chunks.mjs.map +1 -1
  468. package/dist/test-helpers/storage-contract.d.mts +0 -2
  469. package/dist/test-helpers/storage-contract.mjs +1 -2
  470. package/dist/test-helpers.d.mts +2 -1
  471. package/dist/test-helpers.mjs +2 -1
  472. package/dist/tracing.mjs +36 -6
  473. package/dist/tracing.mjs.map +1 -1
  474. package/dist/types.d.mts +0 -2
  475. package/dist/types.mjs +1 -2
  476. package/dist/urls.d.mts +0 -2
  477. package/dist/urls.mjs +1 -2
  478. package/dist/utils/adaptive-concurrency.d.mts +0 -2
  479. package/dist/utils/adaptive-concurrency.mjs +1 -2
  480. package/dist/utils/connect-retry.d.mts +2 -2
  481. package/dist/utils/connect-retry.mjs +2 -3
  482. package/dist/utils/connect-retry.mjs.map +1 -1
  483. package/dist/utils/encrypt.d.mts +0 -2
  484. package/dist/utils/encrypt.mjs +1 -2
  485. package/dist/utils/environment.d.mts +0 -2
  486. package/dist/utils/environment.mjs +1 -2
  487. package/dist/utils/hash.d.mts +0 -2
  488. package/dist/utils/hash.mjs +1 -2
  489. package/dist/utils/http.d.mts +13 -3
  490. package/dist/utils/http.mjs +79 -17
  491. package/dist/utils/http.mjs.map +1 -1
  492. package/dist/utils/map-adaptive.d.mts +0 -2
  493. package/dist/utils/map-adaptive.mjs +1 -2
  494. package/dist/utils/map-limit.d.mts +0 -2
  495. package/dist/utils/map-limit.mjs +1 -2
  496. package/dist/utils/mime.d.mts +0 -2
  497. package/dist/utils/mime.mjs +1 -2
  498. package/dist/utils/page-limiter.d.mts +0 -2
  499. package/dist/utils/page-limiter.mjs +1 -2
  500. package/dist/utils/path-security.d.mts +0 -2
  501. package/dist/utils/path-security.mjs +2 -4
  502. package/dist/utils/path-security.mjs.map +1 -1
  503. package/dist/utils/public-origin.d.mts +0 -2
  504. package/dist/utils/public-origin.mjs +1 -2
  505. package/dist/utils/redact.d.mts +0 -2
  506. package/dist/utils/redact.mjs +1 -2
  507. package/dist/utils/remote-environment.d.mts +40 -3
  508. package/dist/utils/remote-environment.mjs +52 -3
  509. package/dist/utils/remote-environment.mjs.map +1 -1
  510. package/dist/utils/resources.d.mts +0 -2
  511. package/dist/utils/resources.mjs +1 -2
  512. package/dist/utils/screenshot-store.d.mts +0 -2
  513. package/dist/utils/screenshot-store.mjs +1 -2
  514. package/dist/utils/session-gate.d.mts +7 -6
  515. package/dist/utils/session-gate.mjs +28 -12
  516. package/dist/utils/session-gate.mjs.map +1 -1
  517. package/dist/utils/storybook-token.d.mts +11 -3
  518. package/dist/utils/storybook-token.mjs +10 -9
  519. package/dist/utils/storybook-token.mjs.map +1 -1
  520. package/dist/utils/storybook-url.d.mts +0 -2
  521. package/dist/utils/storybook-url.mjs +1 -2
  522. package/dist/utils/timing.d.mts +0 -2
  523. package/dist/utils/timing.mjs +1 -2
  524. package/dist/utils/ulid.d.mts +0 -2
  525. package/dist/utils/ulid.mjs +1 -2
  526. package/dist/utils/zip-read.mjs +1 -2
  527. package/dist/utils/zip-write.d.mts +0 -2
  528. package/dist/utils/zip-write.mjs +1 -2
  529. package/dist/utils.d.mts +5 -5
  530. package/dist/utils.mjs +5 -5
  531. package/package.json +6 -6
@@ -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 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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"}
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 CHANGED
@@ -3,7 +3,6 @@ import __tsdown_shims_url from 'node:url';
3
3
  import { Logger } from "./logger.mjs";
4
4
  import { EvidenceLimits } from "./insights/limits.mjs";
5
5
  import { z } from "zod";
6
- //#region src/ai.d.ts
7
6
  /** Tasks the AI surface routes: build triage and project health. */
8
7
  type AiTask = "triage" | "health";
9
8
  /** One screenshot sent to a vision-capable model. */
@@ -100,6 +99,5 @@ interface Ai {
100
99
  /** Release resources (unregisters nothing global). */
101
100
  teardown(): Promise<void>;
102
101
  }
103
- //#endregion
104
102
  export { Ai, AiBudget, AiError, AiErrorCode, AiEvidence, AiHealth, AiImage, AiSummarizeInput, AiSummarizeResult, AiTask, AiUsageReport };
105
103
  //# sourceMappingURL=ai.d.mts.map
package/dist/ai.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- //#region src/ai.ts
4
+ // src/ai.ts
5
5
  /** Failure from {@link Ai.summarize}; carries usage the provider still billed. */
6
6
  var AiError = class extends Error {
7
7
  code;
@@ -13,7 +13,6 @@ var AiError = class extends Error {
13
13
  this.name = "AiError";
14
14
  }
15
15
  };
16
- //#endregion
17
16
  export { AiError };
18
17
 
19
18
  //# sourceMappingURL=ai.mjs.map
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
@@ -1,6 +1,5 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- //#region src/capture/a11y/axe-source.d.ts
4
3
  /** Lazy, cached loader for the axe-core browser bundle. */
5
4
  /**
6
5
  * Read `axe.min.js` (~550 KB) once per process, on first use. Lazy on purpose: servers that never run
@@ -13,6 +12,5 @@ declare function loadAxeSource(): Promise<string>;
13
12
  * source travels over the wire instead of a file path).
14
13
  */
15
14
  declare function axeInjectionScript(source: string): string;
16
- //#endregion
17
15
  export { axeInjectionScript, loadAxeSource };
18
16
  //# sourceMappingURL=axe-source.d.mts.map
@@ -3,7 +3,7 @@ import "node:url";
3
3
  import.meta.url;
4
4
  import { createRequire } from "node:module";
5
5
  import { readFile } from "node:fs/promises";
6
- //#region src/capture/a11y/axe-source.ts
6
+ // src/capture/a11y/axe-source.ts
7
7
  /** Lazy, cached loader for the axe-core browser bundle. */
8
8
  let cached;
9
9
  /**
@@ -31,7 +31,6 @@ async function readAxeSource() {
31
31
  const path = createRequire(import.meta.url).resolve("axe-core/axe.min.js");
32
32
  return await readFile(path, "utf8");
33
33
  }
34
- //#endregion
35
34
  export { axeInjectionScript, loadAxeSource };
36
35
 
37
36
  //# sourceMappingURL=axe-source.mjs.map
@@ -2,11 +2,10 @@ import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
3
  import { SlimViolation } from "./map.mjs";
4
4
  import { A11yRunPlan } from "./options.mjs";
5
- //#region src/capture/a11y/in-page.d.ts
6
5
  /** What {@link inPageReadA11yParameters} found: the plain-data `parameters.a11y` and what was dropped. */
7
6
  interface A11yParametersRead {
8
7
  params: unknown;
9
- /** Function values (and items that held nothing else) left out because a page cannot hand them over. */
8
+ /** Function, symbol and undefined values left out because a page cannot hand them over. */
10
9
  dropped: number;
11
10
  }
12
11
  /**
@@ -22,6 +21,5 @@ declare function inPageReadA11yParameters(): A11yParametersRead | undefined;
22
21
  * target, node count). Throws when axe is not present in the page.
23
22
  */
24
23
  declare function inPageRunAxe(plan: A11yRunPlan): Promise<SlimViolation[]>;
25
- //#endregion
26
24
  export { A11yParametersRead, inPageReadA11yParameters, inPageRunAxe };
27
25
  //# sourceMappingURL=in-page.d.mts.map
@@ -1,7 +1,7 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- //#region src/capture/a11y/in-page.ts
4
+ // src/capture/a11y/in-page.ts
5
5
  /**
6
6
  * Read the current story's `parameters.a11y` from the running Storybook preview as plain data.
7
7
  * Functions (`config.rules[].matches`, custom checks) cannot cross into the runner, so they are
@@ -29,8 +29,8 @@ function inPageReadA11yParameters() {
29
29
  };
30
30
  try {
31
31
  const params = clean(a11y, 0);
32
- return params === DROP ? void 0 : {
33
- params,
32
+ return {
33
+ params: params === DROP ? void 0 : params,
34
34
  dropped: state.dropped
35
35
  };
36
36
  } catch {
@@ -54,7 +54,6 @@ async function inPageRunAxe(plan) {
54
54
  count: v.nodes.length
55
55
  }));
56
56
  }
57
- //#endregion
58
57
  export { inPageReadA11yParameters, inPageRunAxe };
59
58
 
60
59
  //# sourceMappingURL=in-page.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"in-page.mjs","names":["win"],"sources":["../../../src/capture/a11y/in-page.ts"],"sourcesContent":["/**\n * Functions evaluated inside the story page. Playwright and Puppeteer serialise only a function's\n * source, so each must stay ONE self-contained function: no imports, helpers or module bindings\n * (`in-page.test.ts` rebuilds them from source in a bare scope to guard that).\n */\n\nimport type { SlimViolation } from \"./map.ts\";\nimport type { A11yRunPlan } from \"./options.ts\";\n\n/** What {@link inPageReadA11yParameters} found: the plain-data `parameters.a11y` and what was dropped. */\nexport interface A11yParametersRead {\n params: unknown;\n /** Function values (and items that held nothing else) left out because a page cannot hand them over. */\n dropped: number;\n}\n\n/**\n * Read the current story's `parameters.a11y` from the running Storybook preview as plain data.\n * Functions (`config.rules[].matches`, custom checks) cannot cross into the runner, so they are\n * dropped, and an object or array item that held nothing else goes with them (an emptied rule item\n * would otherwise reset to axe's default). Returns undefined when there is no `a11y` parameter or it\n * cannot be read at all (cyclic).\n */\n// oxlint-disable-next-line eslint/max-statements -- must stay one self-contained function (see above)\nexport function inPageReadA11yParameters(): A11yParametersRead | undefined {\n const win = globalThis as unknown as {\n // oxlint-disable-next-line eslint/no-underscore-dangle -- Storybook global\n __STORYBOOK_PREVIEW__?: {\n currentRender?: { story?: { parameters?: { a11y?: unknown } } };\n };\n };\n // oxlint-disable-next-line eslint/no-underscore-dangle -- Storybook global\n const a11y = win.__STORYBOOK_PREVIEW__?.currentRender?.story?.parameters?.a11y;\n if (a11y === undefined) return undefined;\n const state = { dropped: 0 };\n const DROP = Symbol(\"drop\");\n const clean = (value: unknown, depth: number): unknown => {\n if (depth > 32) throw new Error(\"too deep\");\n if (typeof value === \"function\" || typeof value === \"symbol\" || value === undefined) {\n state.dropped += 1;\n return DROP;\n }\n if (value === null || typeof value !== \"object\") return value;\n const before = state.dropped;\n const entries: [string, unknown][] = Array.isArray(value)\n ? value.map((item, index): [string, unknown] => [String(index), item])\n : Object.entries(value);\n const kept = entries\n .map(([key, item]): [string, unknown] => [key, clean(item, depth + 1)])\n .filter(([, item]) => item !== DROP);\n if (kept.length === 0 && entries.length > 0 && state.dropped > before) return DROP;\n return Array.isArray(value) ? kept.map(([, item]) => item) : Object.fromEntries(kept);\n };\n try {\n const params = clean(a11y, 0);\n return params === DROP ? undefined : { params, dropped: state.dropped };\n } catch {\n return undefined;\n }\n}\n\n/**\n * Run the injected axe over the plan's context and return only slim fields (id, impact, help, first\n * target, node count). Throws when axe is not present in the page.\n */\n// oxlint-disable-next-line eslint/max-statements, eslint/max-lines-per-function -- must stay one self-contained function (see above)\nexport async function inPageRunAxe(plan: A11yRunPlan): Promise<SlimViolation[]> {\n const win = globalThis as unknown as {\n axe?: {\n configure: (config: unknown) => void;\n run: (context: unknown, options: unknown) => Promise<{ violations: AxeViolation[] }>;\n };\n document: { querySelector: (selector: string) => unknown };\n };\n interface AxeViolation {\n id: string;\n impact?: string | null;\n help: string;\n nodes: { target: unknown[] }[];\n }\n if (!win.axe) throw new Error(\"axe is not loaded in the page\");\n if (typeof plan.context === \"string\" && !win.document.querySelector(plan.context)) return [];\n if (Object.keys(plan.config).length > 0) win.axe.configure(plan.config);\n const results = await win.axe.run(plan.context, plan.options);\n return results.violations.map((v) => ({\n id: v.id,\n impact: v.impact ?? null,\n help: v.help,\n target: (v.nodes[0]?.target ?? []).flat(Infinity).join(\" \"),\n count: v.nodes.length,\n }));\n}\n"],"mappings":";;;;;;;;;;;AAwBA,SAAgB,2BAA2D;CAQzE,MAAM,OAAOA,WAAI,uBAAuB,eAAe,OAAO,YAAY;CAC1E,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;CAC/B,MAAM,QAAQ,EAAE,SAAS,EAAE;CAC3B,MAAM,OAAO,OAAO,MAAM;CAC1B,MAAM,SAAS,OAAgB,UAA2B;EACxD,IAAI,QAAQ,IAAI,MAAM,IAAI,MAAM,UAAU;EAC1C,IAAI,OAAO,UAAU,cAAc,OAAO,UAAU,YAAY,UAAU,KAAA,GAAW;GACnF,MAAM,WAAW;GACjB,OAAO;EACT;EACA,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU,OAAO;EACxD,MAAM,SAAS,MAAM;EACrB,MAAM,UAA+B,MAAM,QAAQ,KAAK,IACpD,MAAM,KAAK,MAAM,UAA6B,CAAC,OAAO,KAAK,GAAG,IAAI,CAAC,IACnE,OAAO,QAAQ,KAAK;EACxB,MAAM,OAAO,QACV,KAAK,CAAC,KAAK,UAA6B,CAAC,KAAK,MAAM,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAC,CACtE,QAAQ,GAAG,UAAU,SAAS,IAAI;EACrC,IAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,KAAK,MAAM,UAAU,QAAQ,OAAO;EAC9E,OAAO,MAAM,QAAQ,KAAK,IAAI,KAAK,KAAK,GAAG,UAAU,IAAI,IAAI,OAAO,YAAY,IAAI;CACtF;CACA,IAAI;EACF,MAAM,SAAS,MAAM,MAAM,CAAC;EAC5B,OAAO,WAAW,OAAO,KAAA,IAAY;GAAE;GAAQ,SAAS,MAAM;EAAQ;CACxE,QAAQ;EACN;CACF;AACF;;;;;AAOA,eAAsB,aAAa,MAA6C;CAC9E,MAAM,MAAM;CAaZ,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,+BAA+B;CAC7D,IAAI,OAAO,KAAK,YAAY,YAAY,CAAC,IAAI,SAAS,cAAc,KAAK,OAAO,GAAG,OAAO,CAAC;CAC3F,IAAI,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,SAAS,GAAG,IAAI,IAAI,UAAU,KAAK,MAAM;CAEtE,QAAO,MADe,IAAI,IAAI,IAAI,KAAK,SAAS,KAAK,OAAO,EAAA,CAC7C,WAAW,KAAK,OAAO;EACpC,IAAI,EAAE;EACN,QAAQ,EAAE,UAAU;EACpB,MAAM,EAAE;EACR,SAAS,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC,EAAA,CAAG,KAAK,QAAQ,CAAC,CAAC,KAAK,GAAG;EAC1D,OAAO,EAAE,MAAM;CACjB,EAAE;AACJ"}
1
+ {"version":3,"file":"in-page.mjs","names":["win"],"sources":["../../../src/capture/a11y/in-page.ts"],"sourcesContent":["/**\n * Functions evaluated inside the story page. Playwright and Puppeteer serialise only a function's\n * source, so each must stay ONE self-contained function: no imports, helpers or module bindings\n * (`in-page.test.ts` rebuilds them from source in a bare scope to guard that).\n */\n\nimport type { SlimViolation } from \"./map.ts\";\nimport type { A11yRunPlan } from \"./options.ts\";\n\n/** What {@link inPageReadA11yParameters} found: the plain-data `parameters.a11y` and what was dropped. */\nexport interface A11yParametersRead {\n params: unknown;\n /** Function, symbol and undefined values left out because a page cannot hand them over. */\n dropped: number;\n}\n\n/**\n * Read the current story's `parameters.a11y` from the running Storybook preview as plain data.\n * Functions (`config.rules[].matches`, custom checks) cannot cross into the runner, so they are\n * dropped, and an object or array item that held nothing else goes with them (an emptied rule item\n * would otherwise reset to axe's default). Returns undefined when there is no `a11y` parameter or it\n * cannot be read at all (cyclic).\n */\n// oxlint-disable-next-line eslint/max-statements -- must stay one self-contained function (see above)\nexport function inPageReadA11yParameters(): A11yParametersRead | undefined {\n const win = globalThis as unknown as {\n // oxlint-disable-next-line eslint/no-underscore-dangle -- Storybook global\n __STORYBOOK_PREVIEW__?: {\n currentRender?: { story?: { parameters?: { a11y?: unknown } } };\n };\n };\n // oxlint-disable-next-line eslint/no-underscore-dangle -- Storybook global\n const a11y = win.__STORYBOOK_PREVIEW__?.currentRender?.story?.parameters?.a11y;\n if (a11y === undefined) return undefined;\n const state = { dropped: 0 };\n const DROP = Symbol(\"drop\");\n const clean = (value: unknown, depth: number): unknown => {\n if (depth > 32) throw new Error(\"too deep\");\n if (typeof value === \"function\" || typeof value === \"symbol\" || value === undefined) {\n state.dropped += 1;\n return DROP;\n }\n if (value === null || typeof value !== \"object\") return value;\n const before = state.dropped;\n const entries: [string, unknown][] = Array.isArray(value)\n ? value.map((item, index): [string, unknown] => [String(index), item])\n : Object.entries(value);\n const kept = entries\n .map(([key, item]): [string, unknown] => [key, clean(item, depth + 1)])\n .filter(([, item]) => item !== DROP);\n if (kept.length === 0 && entries.length > 0 && state.dropped > before) return DROP;\n return Array.isArray(value) ? kept.map(([, item]) => item) : Object.fromEntries(kept);\n };\n try {\n const params = clean(a11y, 0);\n return { params: params === DROP ? undefined : params, dropped: state.dropped };\n } catch {\n return undefined;\n }\n}\n\n/**\n * Run the injected axe over the plan's context and return only slim fields (id, impact, help, first\n * target, node count). Throws when axe is not present in the page.\n */\n// oxlint-disable-next-line eslint/max-statements, eslint/max-lines-per-function -- must stay one self-contained function (see above)\nexport async function inPageRunAxe(plan: A11yRunPlan): Promise<SlimViolation[]> {\n const win = globalThis as unknown as {\n axe?: {\n configure: (config: unknown) => void;\n run: (context: unknown, options: unknown) => Promise<{ violations: AxeViolation[] }>;\n };\n document: { querySelector: (selector: string) => unknown };\n };\n interface AxeViolation {\n id: string;\n impact?: string | null;\n help: string;\n nodes: { target: unknown[] }[];\n }\n if (!win.axe) throw new Error(\"axe is not loaded in the page\");\n if (typeof plan.context === \"string\" && !win.document.querySelector(plan.context)) return [];\n if (Object.keys(plan.config).length > 0) win.axe.configure(plan.config);\n const results = await win.axe.run(plan.context, plan.options);\n return results.violations.map((v) => ({\n id: v.id,\n impact: v.impact ?? null,\n help: v.help,\n target: (v.nodes[0]?.target ?? []).flat(Infinity).join(\" \"),\n count: v.nodes.length,\n }));\n}\n"],"mappings":";;;;;;;;;;;AAwBA,SAAgB,2BAA2D;CAQzE,MAAM,OAAOA,WAAI,uBAAuB,eAAe,OAAO,YAAY;CAC1E,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;CAC/B,MAAM,QAAQ,EAAE,SAAS,EAAE;CAC3B,MAAM,OAAO,OAAO,MAAM;CAC1B,MAAM,SAAS,OAAgB,UAA2B;EACxD,IAAI,QAAQ,IAAI,MAAM,IAAI,MAAM,UAAU;EAC1C,IAAI,OAAO,UAAU,cAAc,OAAO,UAAU,YAAY,UAAU,KAAA,GAAW;GACnF,MAAM,WAAW;GACjB,OAAO;EACT;EACA,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU,OAAO;EACxD,MAAM,SAAS,MAAM;EACrB,MAAM,UAA+B,MAAM,QAAQ,KAAK,IACpD,MAAM,KAAK,MAAM,UAA6B,CAAC,OAAO,KAAK,GAAG,IAAI,CAAC,IACnE,OAAO,QAAQ,KAAK;EACxB,MAAM,OAAO,QACV,KAAK,CAAC,KAAK,UAA6B,CAAC,KAAK,MAAM,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAC,CACtE,QAAQ,GAAG,UAAU,SAAS,IAAI;EACrC,IAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,KAAK,MAAM,UAAU,QAAQ,OAAO;EAC9E,OAAO,MAAM,QAAQ,KAAK,IAAI,KAAK,KAAK,GAAG,UAAU,IAAI,IAAI,OAAO,YAAY,IAAI;CACtF;CACA,IAAI;EACF,MAAM,SAAS,MAAM,MAAM,CAAC;EAC5B,OAAO;GAAE,QAAQ,WAAW,OAAO,KAAA,IAAY;GAAQ,SAAS,MAAM;EAAQ;CAChF,QAAQ;EACN;CACF;AACF;;;;;AAOA,eAAsB,aAAa,MAA6C;CAC9E,MAAM,MAAM;CAaZ,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,+BAA+B;CAC7D,IAAI,OAAO,KAAK,YAAY,YAAY,CAAC,IAAI,SAAS,cAAc,KAAK,OAAO,GAAG,OAAO,CAAC;CAC3F,IAAI,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,SAAS,GAAG,IAAI,IAAI,UAAU,KAAK,MAAM;CAEtE,QAAO,MADe,IAAI,IAAI,IAAI,KAAK,SAAS,KAAK,OAAO,EAAA,CAC7C,WAAW,KAAK,OAAO;EACpC,IAAI,EAAE;EACN,QAAQ,EAAE,UAAU;EACpB,MAAM,EAAE;EACR,SAAS,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC,EAAA,CAAG,KAAK,QAAQ,CAAC,CAAC,KAAK,GAAG;EAC1D,OAAO,EAAE,MAAM;CACjB,EAAE;AACJ"}
@@ -1,6 +1,5 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- //#region src/capture/a11y/map.d.ts
4
3
  /** Map slim in-page axe results to `a11y:` violation strings. */
5
4
  /** Most violations reported per snapshot; the rest collapse into "…and N more". */
6
5
  declare const MAX_REPORTED_VIOLATIONS = 10;
@@ -19,6 +18,5 @@ interface SlimViolation {
19
18
  * first. `;` is reserved (the pipeline joins annotations with it), so it never appears in a string.
20
19
  */
21
20
  declare function mapAxeViolations(violations: readonly SlimViolation[]): string[];
22
- //#endregion
23
21
  export { MAX_REPORTED_VIOLATIONS, SlimViolation, mapAxeViolations };
24
22
  //# sourceMappingURL=map.d.mts.map
@@ -1,7 +1,7 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- //#region src/capture/a11y/map.ts
4
+ // src/capture/a11y/map.ts
5
5
  /** Map slim in-page axe results to `a11y:` violation strings. */
6
6
  /** Most violations reported per snapshot; the rest collapse into "…and N more". */
7
7
  const MAX_REPORTED_VIOLATIONS = 10;
@@ -42,7 +42,6 @@ function truncate(text, max) {
42
42
  function clean(text) {
43
43
  return text.replaceAll(/\s+/gu, " ").replaceAll(";", ",");
44
44
  }
45
- //#endregion
46
45
  export { MAX_REPORTED_VIOLATIONS, mapAxeViolations };
47
46
 
48
47
  //# sourceMappingURL=map.mjs.map
@@ -1,6 +1,5 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- //#region src/capture/a11y/options.d.ts
4
3
  /** Turn Storybook's `parameters.a11y` into an axe run plan. */
5
4
  /** The story root axe scans unless `parameters.a11y.element`/`context` says otherwise. */
6
5
  declare const A11Y_ROOT_SELECTOR = "#storybook-root";
@@ -18,6 +17,5 @@ interface A11yRunPlan {
18
17
  * still only annotate, results never fail a build.
19
18
  */
20
19
  declare function resolveA11yRun(raw: unknown): A11yRunPlan;
21
- //#endregion
22
20
  export { A11Y_ROOT_SELECTOR, A11yRunPlan, resolveA11yRun };
23
21
  //# sourceMappingURL=options.d.mts.map
@@ -1,7 +1,7 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- //#region src/capture/a11y/options.ts
4
+ // src/capture/a11y/options.ts
5
5
  /** Turn Storybook's `parameters.a11y` into an axe run plan. */
6
6
  /** The story root axe scans unless `parameters.a11y.element`/`context` says otherwise. */
7
7
  const A11Y_ROOT_SELECTOR = "#storybook-root";
@@ -69,7 +69,6 @@ function skipReason(params) {
69
69
  function asRecord(value) {
70
70
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
71
71
  }
72
- //#endregion
73
72
  export { A11Y_ROOT_SELECTOR, resolveA11yRun };
74
73
 
75
74
  //# sourceMappingURL=options.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 { DepGraph } from "@storyshelf/affected";
4
- //#region src/capture/adapter.d.ts
5
4
  /** A custom viewport registered on a story via `parameters.viewport`. */
6
5
  interface StoryViewportDefinition {
7
6
  name?: string;
@@ -56,6 +55,11 @@ interface StoryParameters {
56
55
  waitForFonts?: boolean;
57
56
  /** Storybook viewport config; adds the story's default viewport to the project list at capture time. */
58
57
  viewport?: StoryViewportConfig;
58
+ /**
59
+ * CSS selectors hidden (`visibility: hidden`) before the screenshot. `storyshelf` replaces
60
+ * `chromatic`; `[data-storyshelf-ignore]` and the Chromatic markers always apply.
61
+ */
62
+ ignoreSelectors?: string[];
59
63
  /** Named modes: extra captures of this story under different globals/viewports. */
60
64
  modes?: ModeMap;
61
65
  }
@@ -126,6 +130,5 @@ interface Viewport {
126
130
  }
127
131
  /** Default viewport used when none is configured. */
128
132
  declare const DEFAULT_VIEWPORTS: Viewport[];
129
- //#endregion
130
133
  export { CapturePage, DEFAULT_VIEWPORTS, DiscoverOptions, ModeDefinition, ModeMap, ModeViewportValue, StoryEntry, StoryParameters, StorySourceAdapter, StoryViewportConfig, StoryViewportDefinition, Viewport, isDisabledStory, isFlakyStory };
131
134
  //# sourceMappingURL=adapter.d.mts.map
@@ -1,7 +1,7 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- //#region src/capture/adapter.ts
4
+ // src/capture/adapter.ts
5
5
  /** Return whether a story is marked flaky (failures stay non-blocking). */
6
6
  function isFlakyStory(entry) {
7
7
  if (entry.parameters?.flakyTest) return true;
@@ -25,7 +25,6 @@ const DEFAULT_VIEWPORTS = [{
25
25
  width: 1280,
26
26
  height: 720
27
27
  }];
28
- //#endregion
29
28
  export { DEFAULT_VIEWPORTS, isDisabledStory, isFlakyStory };
30
29
 
31
30
  //# sourceMappingURL=adapter.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.mjs","names":[],"sources":["../../src/capture/adapter.ts"],"sourcesContent":["import type { DepGraph } from \"@storyshelf/affected\";\n\n/** A custom viewport registered on a story via `parameters.viewport`. */\nexport interface StoryViewportDefinition {\n name?: string;\n styles?: {\n width?: string | number;\n height?: string | number;\n };\n}\n\n/** Storybook `parameters.viewport` config; carried through discovery for per-story viewport capture. */\nexport interface StoryViewportConfig {\n defaultViewport?: string;\n viewports?: Record<string, StoryViewportDefinition>;\n}\n\n/** Viewport a mode captures at: a width, a Storybook viewport name, or explicit dimensions. */\nexport type ModeViewportValue = number | string | { width: number; height: number };\n\n/**\n * One entry of `parameters.{chromatic,storyshelf}.modes`. `viewport` sizes the\n * page, `disable` removes an inherited mode, every other key is a Storybook\n * global (theme, locale, backgrounds, …) applied through the `globals` URL arg.\n */\nexport interface ModeDefinition {\n viewport?: ModeViewportValue;\n disable?: boolean;\n [global: string]: unknown;\n}\n\n/** Named modes keyed by display name (the slug of the name is the baseline identity). */\nexport type ModeMap = Record<string, ModeDefinition>;\n\n/** Per-story capture parameters from the Storybook index. */\nexport interface StoryParameters {\n disableSnapshot?: boolean;\n delay?: number;\n diffThreshold?: number;\n pauseAnimationAtEnd?: boolean;\n flakyTest?: boolean;\n /** Force auto-crop (true) or full viewport (false) for this story; undefined uses 60% whitespace rule. */\n autoCrop?: boolean;\n /** Whitespace fraction (0..1) above which we crop; default 0.6. */\n autoCropThreshold?: number;\n /** Whether overflow should trigger fullPage; default true. */\n fullPageOnOverflow?: boolean;\n /** Min dimensions for the final PNG (clamp after padding). */\n minWidth?: number;\n minHeight?: number;\n maxWidth?: number;\n maxHeight?: number;\n /** Burst count for steady capture (1 = single shot, 3 = burst 100ms); default 1. */\n burst?: number;\n /** Whether to wait for fonts.ready before screenshot; default true when burst >1. */\n waitForFonts?: boolean;\n /** Storybook viewport config; adds the story's default viewport to the project list at capture time. */\n viewport?: StoryViewportConfig;\n /** Named modes: extra captures of this story under different globals/viewports. */\n modes?: ModeMap;\n}\n\n/** Return whether a story is marked flaky (failures stay non-blocking). */\nexport function isFlakyStory(entry: Pick<StoryEntry, \"tags\" | \"parameters\">): boolean {\n if (entry.parameters?.flakyTest) return true;\n const tags = entry.tags ?? [];\n for (const t of tags) {\n if (t.toLowerCase() === \"flaky-test\") return true;\n }\n return false;\n}\n\n/** Return whether a story is excluded from snapshot capture. */\nexport function isDisabledStory(entry: Pick<StoryEntry, \"tags\" | \"parameters\">): boolean {\n if (entry.parameters?.disableSnapshot) return true;\n const tags = entry.tags ?? [];\n for (const t of tags) {\n const lower = t.toLowerCase();\n if (lower === \"skip\" || lower === \"disable\" || lower === \"disable-snapshot\") return true;\n }\n return false;\n}\n\n/** A single discoverable story or docs entry within a Storybook. */\nexport interface StoryEntry {\n id: string;\n title: string;\n name: string;\n importPath?: string;\n tags?: string[];\n type: \"story\" | \"docs\";\n /**\n * Set on a Storybook 10 `.test()` entry (index `subtype: \"test\"`): the id of the story it is\n * written under. Test entries are never captured; a project that runs tests runs them in the\n * iframe (ADR 0004, decision 10).\n */\n parentId?: string;\n parameters?: StoryParameters;\n /** Figma URL declared via `parameters.design` / `parameters.storyshelf.figma`. */\n designUrl?: string;\n /** Declared design value that is not a usable Figma URL (ignored; logged at capture). */\n designInvalid?: string;\n}\n\n/** Minimal structural page handle handed to `StorySourceAdapter.waitForReady`. */\nexport interface CapturePage {\n evaluate(\n pageFunction: string | ((...args: unknown[]) => unknown),\n arg?: unknown,\n ): Promise<unknown>;\n waitForSelector(selector: string, options?: Record<string, unknown>): Promise<unknown>;\n}\n\n/** Optional discovery inputs. */\nexport interface DiscoverOptions {\n /** Validates declared design links (`design` / `storyshelf.figma`); without it none are extracted. */\n parseDesignUrl?: (raw: string) => { url: string } | null;\n}\n\n/** Adapter that discovers and renders stories from a Storybook build. */\nexport interface StorySourceAdapter {\n name: string;\n discover(source: string, options?: DiscoverOptions): Promise<StoryEntry[]>;\n buildUrl(baseUrl: string, storyId: string, globals?: Record<string, unknown>): string;\n screenshotSelector?: string;\n /**\n * Optional hook loading the module dependency graph of an extracted build,\n * enabling affected capture (render only stories downstream of a change).\n * Absent (or resolving `null`) means the source cannot be traced, so the\n * orchestrator renders every story.\n */\n loadDependencyGraph?(sourceDir: string): Promise<DepGraph | null>;\n /**\n * Optional hook invoked after navigation and before the screenshot sequence,\n * letting a custom source wait until it is ready to capture. The built-in\n * Storybook adapter leaves this undefined (rendered via iframe). See\n * ADR 0005.\n */\n waitForReady?(page: CapturePage): Promise<void>;\n}\n\n/** A viewport size at which stories are captured. */\nexport interface Viewport {\n name: string;\n width: number;\n height: number;\n /** Storybook globals applied for this capture (set for modes only). */\n globals?: Record<string, unknown>;\n}\n\n/** Default viewport used when none is configured. */\nexport const DEFAULT_VIEWPORTS: Viewport[] = [{ name: \"desktop\", width: 1280, height: 720 }];\n"],"mappings":";;;;;AA+DA,SAAgB,aAAa,OAAyD;CACpF,IAAI,MAAM,YAAY,WAAW,OAAO;CACxC,MAAM,OAAO,MAAM,QAAQ,CAAC;CAC5B,KAAK,MAAM,KAAK,MACd,IAAI,EAAE,YAAY,MAAM,cAAc,OAAO;CAE/C,OAAO;AACT;;AAGA,SAAgB,gBAAgB,OAAyD;CACvF,IAAI,MAAM,YAAY,iBAAiB,OAAO;CAC9C,MAAM,OAAO,MAAM,QAAQ,CAAC;CAC5B,KAAK,MAAM,KAAK,MAAM;EACpB,MAAM,QAAQ,EAAE,YAAY;EAC5B,IAAI,UAAU,UAAU,UAAU,aAAa,UAAU,oBAAoB,OAAO;CACtF;CACA,OAAO;AACT;;AAsEA,MAAa,oBAAgC,CAAC;CAAE,MAAM;CAAW,OAAO;CAAM,QAAQ;AAAI,CAAC"}
1
+ {"version":3,"file":"adapter.mjs","names":[],"sources":["../../src/capture/adapter.ts"],"sourcesContent":["import type { DepGraph } from \"@storyshelf/affected\";\n\n/** A custom viewport registered on a story via `parameters.viewport`. */\nexport interface StoryViewportDefinition {\n name?: string;\n styles?: {\n width?: string | number;\n height?: string | number;\n };\n}\n\n/** Storybook `parameters.viewport` config; carried through discovery for per-story viewport capture. */\nexport interface StoryViewportConfig {\n defaultViewport?: string;\n viewports?: Record<string, StoryViewportDefinition>;\n}\n\n/** Viewport a mode captures at: a width, a Storybook viewport name, or explicit dimensions. */\nexport type ModeViewportValue = number | string | { width: number; height: number };\n\n/**\n * One entry of `parameters.{chromatic,storyshelf}.modes`. `viewport` sizes the\n * page, `disable` removes an inherited mode, every other key is a Storybook\n * global (theme, locale, backgrounds, …) applied through the `globals` URL arg.\n */\nexport interface ModeDefinition {\n viewport?: ModeViewportValue;\n disable?: boolean;\n [global: string]: unknown;\n}\n\n/** Named modes keyed by display name (the slug of the name is the baseline identity). */\nexport type ModeMap = Record<string, ModeDefinition>;\n\n/** Per-story capture parameters from the Storybook index. */\nexport interface StoryParameters {\n disableSnapshot?: boolean;\n delay?: number;\n diffThreshold?: number;\n pauseAnimationAtEnd?: boolean;\n flakyTest?: boolean;\n /** Force auto-crop (true) or full viewport (false) for this story; undefined uses 60% whitespace rule. */\n autoCrop?: boolean;\n /** Whitespace fraction (0..1) above which we crop; default 0.6. */\n autoCropThreshold?: number;\n /** Whether overflow should trigger fullPage; default true. */\n fullPageOnOverflow?: boolean;\n /** Min dimensions for the final PNG (clamp after padding). */\n minWidth?: number;\n minHeight?: number;\n maxWidth?: number;\n maxHeight?: number;\n /** Burst count for steady capture (1 = single shot, 3 = burst 100ms); default 1. */\n burst?: number;\n /** Whether to wait for fonts.ready before screenshot; default true when burst >1. */\n waitForFonts?: boolean;\n /** Storybook viewport config; adds the story's default viewport to the project list at capture time. */\n viewport?: StoryViewportConfig;\n /**\n * CSS selectors hidden (`visibility: hidden`) before the screenshot. `storyshelf` replaces\n * `chromatic`; `[data-storyshelf-ignore]` and the Chromatic markers always apply.\n */\n ignoreSelectors?: string[];\n /** Named modes: extra captures of this story under different globals/viewports. */\n modes?: ModeMap;\n}\n\n/** Return whether a story is marked flaky (failures stay non-blocking). */\nexport function isFlakyStory(entry: Pick<StoryEntry, \"tags\" | \"parameters\">): boolean {\n if (entry.parameters?.flakyTest) return true;\n const tags = entry.tags ?? [];\n for (const t of tags) {\n if (t.toLowerCase() === \"flaky-test\") return true;\n }\n return false;\n}\n\n/** Return whether a story is excluded from snapshot capture. */\nexport function isDisabledStory(entry: Pick<StoryEntry, \"tags\" | \"parameters\">): boolean {\n if (entry.parameters?.disableSnapshot) return true;\n const tags = entry.tags ?? [];\n for (const t of tags) {\n const lower = t.toLowerCase();\n if (lower === \"skip\" || lower === \"disable\" || lower === \"disable-snapshot\") return true;\n }\n return false;\n}\n\n/** A single discoverable story or docs entry within a Storybook. */\nexport interface StoryEntry {\n id: string;\n title: string;\n name: string;\n importPath?: string;\n tags?: string[];\n type: \"story\" | \"docs\";\n /**\n * Set on a Storybook 10 `.test()` entry (index `subtype: \"test\"`): the id of the story it is\n * written under. Test entries are never captured; a project that runs tests runs them in the\n * iframe (ADR 0004, decision 10).\n */\n parentId?: string;\n parameters?: StoryParameters;\n /** Figma URL declared via `parameters.design` / `parameters.storyshelf.figma`. */\n designUrl?: string;\n /** Declared design value that is not a usable Figma URL (ignored; logged at capture). */\n designInvalid?: string;\n}\n\n/** Minimal structural page handle handed to `StorySourceAdapter.waitForReady`. */\nexport interface CapturePage {\n evaluate(\n pageFunction: string | ((...args: unknown[]) => unknown),\n arg?: unknown,\n ): Promise<unknown>;\n waitForSelector(selector: string, options?: Record<string, unknown>): Promise<unknown>;\n}\n\n/** Optional discovery inputs. */\nexport interface DiscoverOptions {\n /** Validates declared design links (`design` / `storyshelf.figma`); without it none are extracted. */\n parseDesignUrl?: (raw: string) => { url: string } | null;\n}\n\n/** Adapter that discovers and renders stories from a Storybook build. */\nexport interface StorySourceAdapter {\n name: string;\n discover(source: string, options?: DiscoverOptions): Promise<StoryEntry[]>;\n buildUrl(baseUrl: string, storyId: string, globals?: Record<string, unknown>): string;\n screenshotSelector?: string;\n /**\n * Optional hook loading the module dependency graph of an extracted build,\n * enabling affected capture (render only stories downstream of a change).\n * Absent (or resolving `null`) means the source cannot be traced, so the\n * orchestrator renders every story.\n */\n loadDependencyGraph?(sourceDir: string): Promise<DepGraph | null>;\n /**\n * Optional hook invoked after navigation and before the screenshot sequence,\n * letting a custom source wait until it is ready to capture. The built-in\n * Storybook adapter leaves this undefined (rendered via iframe). See\n * ADR 0005.\n */\n waitForReady?(page: CapturePage): Promise<void>;\n}\n\n/** A viewport size at which stories are captured. */\nexport interface Viewport {\n name: string;\n width: number;\n height: number;\n /** Storybook globals applied for this capture (set for modes only). */\n globals?: Record<string, unknown>;\n}\n\n/** Default viewport used when none is configured. */\nexport const DEFAULT_VIEWPORTS: Viewport[] = [{ name: \"desktop\", width: 1280, height: 720 }];\n"],"mappings":";;;;;AAoEA,SAAgB,aAAa,OAAyD;CACpF,IAAI,MAAM,YAAY,WAAW,OAAO;CACxC,MAAM,OAAO,MAAM,QAAQ,CAAC;CAC5B,KAAK,MAAM,KAAK,MACd,IAAI,EAAE,YAAY,MAAM,cAAc,OAAO;CAE/C,OAAO;AACT;;AAGA,SAAgB,gBAAgB,OAAyD;CACvF,IAAI,MAAM,YAAY,iBAAiB,OAAO;CAC9C,MAAM,OAAO,MAAM,QAAQ,CAAC;CAC5B,KAAK,MAAM,KAAK,MAAM;EACpB,MAAM,QAAQ,EAAE,YAAY;EAC5B,IAAI,UAAU,UAAU,UAAU,aAAa,UAAU,oBAAoB,OAAO;CACtF;CACA,OAAO;AACT;;AAsEA,MAAa,oBAAgC,CAAC;CAAE,MAAM;CAAW,OAAO;CAAM,QAAQ;AAAI,CAAC"}
@@ -4,7 +4,6 @@ import { StoryEntry, Viewport } from "./adapter.mjs";
4
4
  import "../adapter/database.mjs";
5
5
  import { Baseline } from "../schema/baseline.mjs";
6
6
  import "../models/baseline.mjs";
7
- //#region src/capture/affected.d.ts
8
7
  /** An inherit candidate paired with the baseline it reuses. */
9
8
  interface InheritedStory {
10
9
  story: StoryEntry;
@@ -13,6 +12,5 @@ interface InheritedStory {
13
12
  /** Engine whose baseline is reused (chromium when absent). */
14
13
  browser?: string;
15
14
  }
16
- //#endregion
17
15
  export { InheritedStory };
18
16
  //# sourceMappingURL=affected.d.mts.map
@@ -5,7 +5,7 @@ import { resolveStoryViewports } from "./storybook.mjs";
5
5
  import { BuildModel } from "../models/build.mjs";
6
6
  import { BaselineModel } from "../models/baseline.mjs";
7
7
  import { selectAffectedStories } from "@storyshelf/affected";
8
- //#region src/capture/affected.ts
8
+ // src/capture/affected.ts
9
9
  /**
10
10
  * Resolve the affected import paths for a build, or `null` for full capture (affected capture
11
11
  * disabled, or no computation was posted). The one rule for the whole and the sharded path alike.
@@ -67,7 +67,6 @@ async function partitionAffectedStories(input) {
67
67
  inherited: merged.inherited
68
68
  };
69
69
  }
70
- //#endregion
71
70
  export { affectedPathsFor, partitionAffectedStories };
72
71
 
73
72
  //# sourceMappingURL=affected.mjs.map
@@ -3,7 +3,7 @@ import "node:url";
3
3
  import.meta.url;
4
4
  import { redactSecrets } from "../utils/redact.mjs";
5
5
  import { emitAttemptLog } from "../models/capture-attempt.mjs";
6
- //#region src/capture/attempt-logger.ts
6
+ // src/capture/attempt-logger.ts
7
7
  /** Longest error text recorded on an attempt-log line. */
8
8
  const ERROR_TEXT_MAX = 500;
9
9
  /** Mirrored levels; `debug` stays in pino only so attempt logs keep the signal. */
@@ -78,7 +78,6 @@ function silentLogger() {
78
78
  stub["child"] = () => stub;
79
79
  return stub;
80
80
  }
81
- //#endregion
82
81
  export { mirrorAttemptLog };
83
82
 
84
83
  //# sourceMappingURL=attempt-logger.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 { CaptureTarget, RunnerTarget } from "../adapters/capture-target.mjs";
4
- //#region src/capture/browsers.d.ts
5
4
  /** Upper bound on targets per project (each multiplies render time). */
6
5
  declare const MAX_BROWSERS = 3;
7
6
  /** Parse the project's JSON `browsers` column; `null` when unset or malformed. */
@@ -30,6 +29,5 @@ declare function refusalFor(target: CaptureTarget, offered?: readonly RunnerTarg
30
29
  declare function listTargets(offered: readonly RunnerTarget[]): string;
31
30
  /** Throw, naming every refusal, when the runner cannot render one of `targets`. */
32
31
  declare function assertSupportedBrowsers(targets: readonly CaptureTarget[], offered?: readonly RunnerTarget[]): void;
33
- //#endregion
34
32
  export { MAX_BROWSERS, assertBrowserCount, assertSupportedBrowsers, listTargets, parseBrowsers, primaryTargetOf, refusalFor, resolveBrowsers };
35
33
  //# sourceMappingURL=browsers.d.mts.map
@@ -2,7 +2,7 @@ import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
4
  import { DEFAULT_BROWSER, isCaptureTarget, unavailableReason } from "../adapters/capture-target.mjs";
5
- //#region src/capture/browsers.ts
5
+ // src/capture/browsers.ts
6
6
  /** Which capture targets a project renders on, and the guards around that list (ADR 0007). */
7
7
  /** Upper bound on targets per project (each multiplies render time). */
8
8
  const MAX_BROWSERS = 3;
@@ -61,7 +61,6 @@ function assertSupportedBrowsers(targets, offered) {
61
61
  function dedupe(browsers) {
62
62
  return [...new Set(browsers)];
63
63
  }
64
- //#endregion
65
64
  export { MAX_BROWSERS, assertBrowserCount, assertSupportedBrowsers, listTargets, parseBrowsers, primaryTargetOf, refusalFor, resolveBrowsers };
66
65
 
67
66
  //# sourceMappingURL=browsers.mjs.map
@@ -3,7 +3,6 @@ import __tsdown_shims_url from 'node:url';
3
3
  import { Build } from "../../schema/build.mjs";
4
4
  import { Project } from "../../schema/project.mjs";
5
5
  import { BuildStateDeps, SkipReason, StateTarget } from "./types.mjs";
6
- //#region src/capture/build-state/deliver.d.ts
7
6
  /**
8
7
  * Show the build's current state on one channel. Throws when the host refuses a status, so the
9
8
  * caller can retry; resolves to why nothing was written when the build or channel is gone.
@@ -27,6 +26,5 @@ declare function writeTo(deps: BuildStateDeps, loaded: {
27
26
  }): Promise<void>;
28
27
  /** The project's enabled channels with a wired `state` provider; unreadable secrets are logged and skipped. */
29
28
  declare function stateTargets(deps: BuildStateDeps, projectId: string): Promise<StateTarget[]>;
30
- //#endregion
31
29
  export { deliverBuildState, loadBuild, stateTargets, writeTo };
32
30
  //# sourceMappingURL=deliver.d.mts.map
@@ -12,7 +12,7 @@ import { BuildReviewModel } from "../../models/build-review.mjs";
12
12
  import { NotificationChannelModel } from "../../models/notification-channel.mjs";
13
13
  import { createUrlBuilder } from "../../urls.mjs";
14
14
  import { publishingOf } from "../publish/published.mjs";
15
- //#region src/capture/build-state/deliver.ts
15
+ // src/capture/build-state/deliver.ts
16
16
  /**
17
17
  * Delivering a build's state to git channels: read the build now, compute what each channel shows
18
18
  * ({@link statusesForBuild}), write it. Reading at delivery time is what makes a retried, delayed
@@ -112,7 +112,6 @@ async function approvalsOf(deps, build, project) {
112
112
  async function changesOf(deps, build, project) {
113
113
  return deps.flags(project).testing && build.changedCount > 0 ? await new SnapshotModel(deps.db).listByBuild(build.id) : void 0;
114
114
  }
115
- //#endregion
116
115
  export { deliverBuildState, loadBuild, stateTargets, writeTo };
117
116
 
118
117
  //# sourceMappingURL=deliver.mjs.map
@@ -3,7 +3,6 @@ import __tsdown_shims_url from 'node:url';
3
3
  import { BuildStateDeps } from "./types.mjs";
4
4
  import { ConsumerJob, KindHandler } from "../consumer/types.mjs";
5
5
  import { QueueJobInput } from "../db-queue/types.mjs";
6
- //#region src/capture/build-state/notify-job.d.ts
7
6
  /** Attempts a delivery gets before it is given up (the first try and four retries). */
8
7
  declare const NOTIFY_MAX_ATTEMPTS = 5;
9
8
  /** Retry delay of a delivery: 10 s, then doubling to at most five minutes. */
@@ -51,6 +50,5 @@ declare function createNotifyEnqueuer(deps: Pick<BuildStateDeps, "db">, queue: N
51
50
  channelId: string;
52
51
  buildId: string;
53
52
  }) => Promise<void>;
54
- //#endregion
55
53
  export { NOTIFY_BACKOFF, NOTIFY_MAX_ATTEMPTS, NotifyFailure, NotifyHandlerOptions, NotifyJobQueue, createNotifyEnqueuer, createNotifyHandler, notifyExhausted };
56
54
  //# sourceMappingURL=notify-job.d.mts.map
@@ -7,7 +7,7 @@ import { deliverBuildState } from "./deliver.mjs";
7
7
  import { CaptureJobModel } from "../../models/capture-job.mjs";
8
8
  import { isFinalAttempt } from "../consumer/retry.mjs";
9
9
  import { decodePayload } from "../db-queue/codec.mjs";
10
- //#region src/capture/build-state/notify-job.ts
10
+ // src/capture/build-state/notify-job.ts
11
11
  /**
12
12
  * The `notify` job kind (ADR 0014, decision 7; ADR 0006, decision 4): one job per `(channel,
13
13
  * build)` state change. The job names a channel and a build, never a status: the handler reads the
@@ -127,7 +127,6 @@ function createNotifyEnqueuer(deps, queue) {
127
127
  });
128
128
  };
129
129
  }
130
- //#endregion
131
130
  export { NOTIFY_BACKOFF, NOTIFY_MAX_ATTEMPTS, createNotifyEnqueuer, createNotifyHandler, notifyExhausted };
132
131
 
133
132
  //# sourceMappingURL=notify-job.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 { BuildStateDeps, BuildStatePublisher } from "./types.mjs";
4
- //#region src/capture/build-state/publisher.d.ts
5
4
  /** What {@link createBuildStatePublisher} needs. */
6
5
  interface BuildStatePublisherOptions {
7
6
  deps: BuildStateDeps;
@@ -18,6 +17,5 @@ interface BuildStatePublisherOptions {
18
17
  declare const PAUSED_MESSAGE = "notifications are paused until a public URL is set (PUBLIC_BASE_URL or a confirmed detected origin)";
19
18
  /** A publisher over `options.deps`. */
20
19
  declare function createBuildStatePublisher(options: BuildStatePublisherOptions): BuildStatePublisher;
21
- //#endregion
22
20
  export { BuildStatePublisherOptions, PAUSED_MESSAGE, createBuildStatePublisher };
23
21
  //# sourceMappingURL=publisher.d.mts.map