@storyshelf/core 0.6.1 → 0.7.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 (631) hide show
  1. package/README.md +49 -32
  2. package/dist/adapter/capture-queue.d.mts +44 -2
  3. package/dist/adapter/capture-runner.d.mts +127 -10
  4. package/dist/adapter/capture-runner.mjs +5 -12
  5. package/dist/adapter/database.d.mts +27 -8
  6. package/dist/adapter/database.mjs.map +1 -1
  7. package/dist/adapter/design.d.mts +85 -0
  8. package/dist/adapter/design.mjs +28 -0
  9. package/dist/adapter/design.mjs.map +1 -0
  10. package/dist/adapter/metadata.d.mts +3 -10
  11. package/dist/adapter/notifier.d.mts +6 -3
  12. package/dist/adapter/notifier.mjs +5 -1
  13. package/dist/adapter/oauth.d.mts +52 -0
  14. package/dist/adapter/setup.d.mts +4 -5
  15. package/dist/adapter/setup.mjs +2 -1
  16. package/dist/adapter/setup.mjs.map +1 -1
  17. package/dist/adapter/webhook-events.mjs +1 -1
  18. package/dist/adapters/capture-target-offers.d.mts +28 -0
  19. package/dist/adapters/capture-target-offers.mjs +58 -0
  20. package/dist/adapters/capture-target-offers.mjs.map +1 -0
  21. package/dist/adapters/capture-target.d.mts +71 -0
  22. package/dist/adapters/capture-target.mjs +76 -0
  23. package/dist/adapters/capture-target.mjs.map +1 -0
  24. package/dist/adapters/notifier/build-comment.d.mts +24 -0
  25. package/dist/adapters/notifier/build-comment.mjs +24 -0
  26. package/dist/adapters/notifier/build-comment.mjs.map +1 -0
  27. package/dist/adapters/notifier/build-state.d.mts +99 -0
  28. package/dist/adapters/notifier/build-state.mjs +218 -0
  29. package/dist/adapters/notifier/build-state.mjs.map +1 -0
  30. package/dist/adapters/notifier/events.d.mts +4 -2
  31. package/dist/adapters/notifier/events.mjs +31 -18
  32. package/dist/adapters/notifier/events.mjs.map +1 -1
  33. package/dist/adapters/notifier/provider.d.mts +53 -7
  34. package/dist/adapters/notifier/provider.mjs +12 -0
  35. package/dist/adapters/notifier/provider.mjs.map +1 -0
  36. package/dist/adapters/notifier/state.d.mts +24 -0
  37. package/dist/adapters/notifier/state.mjs +66 -0
  38. package/dist/adapters/notifier/state.mjs.map +1 -0
  39. package/dist/adapters/notifier/types.d.mts +51 -2
  40. package/dist/adapters/remote-browser.d.mts +87 -0
  41. package/dist/adapters/remote-browser.mjs +103 -0
  42. package/dist/adapters/remote-browser.mjs.map +1 -0
  43. package/dist/adapters/render-runs.d.mts +25 -0
  44. package/dist/adapters/render-runs.mjs +41 -0
  45. package/dist/adapters/render-runs.mjs.map +1 -0
  46. package/dist/adapters/setup-runner.mjs +2 -4
  47. package/dist/adapters/setup-runner.mjs.map +1 -1
  48. package/dist/adapters/sources.d.mts +12 -0
  49. package/dist/adapters/sources.mjs +20 -0
  50. package/dist/adapters/sources.mjs.map +1 -0
  51. package/dist/adapters/validate.mjs +25 -18
  52. package/dist/adapters/validate.mjs.map +1 -1
  53. package/dist/ai.d.mts +105 -0
  54. package/dist/ai.mjs +19 -0
  55. package/dist/ai.mjs.map +1 -0
  56. package/dist/auth.d.mts +8 -1
  57. package/dist/auth.mjs +14 -1
  58. package/dist/auth.mjs.map +1 -0
  59. package/dist/capture/a11y/axe-source.d.mts +18 -0
  60. package/dist/capture/a11y/axe-source.mjs +37 -0
  61. package/dist/capture/a11y/axe-source.mjs.map +1 -0
  62. package/dist/capture/a11y/in-page.d.mts +27 -0
  63. package/dist/capture/a11y/in-page.mjs +60 -0
  64. package/dist/capture/a11y/in-page.mjs.map +1 -0
  65. package/dist/capture/a11y/map.d.mts +24 -0
  66. package/dist/capture/a11y/map.mjs +48 -0
  67. package/dist/capture/a11y/map.mjs.map +1 -0
  68. package/dist/capture/a11y/options.d.mts +23 -0
  69. package/dist/capture/a11y/options.mjs +75 -0
  70. package/dist/capture/a11y/options.mjs.map +1 -0
  71. package/dist/capture/adapter.d.mts +41 -3
  72. package/dist/capture/adapter.mjs.map +1 -1
  73. package/dist/capture/affected.d.mts +2 -0
  74. package/dist/capture/affected.mjs +13 -4
  75. package/dist/capture/affected.mjs.map +1 -1
  76. package/dist/capture/attempt-logger.mjs +84 -0
  77. package/dist/capture/attempt-logger.mjs.map +1 -0
  78. package/dist/capture/browsers.d.mts +35 -0
  79. package/dist/capture/browsers.mjs +67 -0
  80. package/dist/capture/browsers.mjs.map +1 -0
  81. package/dist/capture/build-state/deliver.d.mts +32 -0
  82. package/dist/capture/build-state/deliver.mjs +118 -0
  83. package/dist/capture/build-state/deliver.mjs.map +1 -0
  84. package/dist/capture/build-state/index.d.mts +8 -0
  85. package/dist/capture/build-state/notify-job.d.mts +56 -0
  86. package/dist/capture/build-state/notify-job.mjs +133 -0
  87. package/dist/capture/build-state/notify-job.mjs.map +1 -0
  88. package/dist/capture/build-state/publisher.d.mts +23 -0
  89. package/dist/capture/build-state/publisher.mjs +107 -0
  90. package/dist/capture/build-state/publisher.mjs.map +1 -0
  91. package/dist/capture/build-state/resume.d.mts +9 -0
  92. package/dist/capture/build-state/resume.mjs +47 -0
  93. package/dist/capture/build-state/resume.mjs.map +1 -0
  94. package/dist/capture/build-state/types.d.mts +49 -0
  95. package/dist/capture/catalog/catalogue.d.mts +22 -0
  96. package/dist/capture/catalog/catalogue.mjs +53 -0
  97. package/dist/capture/catalog/catalogue.mjs.map +1 -0
  98. package/dist/capture/catalog/components.d.mts +23 -0
  99. package/dist/capture/catalog/components.mjs +55 -0
  100. package/dist/capture/catalog/components.mjs.map +1 -0
  101. package/dist/capture/catalog/history.d.mts +30 -0
  102. package/dist/capture/catalog/history.mjs +51 -0
  103. package/dist/capture/catalog/history.mjs.map +1 -0
  104. package/dist/capture/catalog/hook.d.mts +14 -0
  105. package/dist/capture/catalog/hook.mjs +19 -0
  106. package/dist/capture/catalog/hook.mjs.map +1 -0
  107. package/dist/capture/catalog/index.d.mts +11 -0
  108. package/dist/capture/catalog/load.d.mts +26 -0
  109. package/dist/capture/catalog/load.mjs +49 -0
  110. package/dist/capture/catalog/load.mjs.map +1 -0
  111. package/dist/capture/catalog/parse.d.mts +15 -0
  112. package/dist/capture/catalog/parse.mjs +56 -0
  113. package/dist/capture/catalog/parse.mjs.map +1 -0
  114. package/dist/capture/catalog/read.d.mts +12 -0
  115. package/dist/capture/catalog/read.mjs +33 -0
  116. package/dist/capture/catalog/read.mjs.map +1 -0
  117. package/dist/capture/catalog/types.d.mts +33 -0
  118. package/dist/capture/consumer/capture-handler.d.mts +58 -0
  119. package/dist/capture/consumer/capture-handler.mjs +118 -0
  120. package/dist/capture/consumer/capture-handler.mjs.map +1 -0
  121. package/dist/capture/consumer/idle.d.mts +17 -0
  122. package/dist/capture/consumer/idle.mjs +25 -0
  123. package/dist/capture/consumer/idle.mjs.map +1 -0
  124. package/dist/capture/consumer/index.d.mts +13 -0
  125. package/dist/capture/consumer/index.mjs +139 -0
  126. package/dist/capture/consumer/index.mjs.map +1 -0
  127. package/dist/capture/consumer/loop.mjs +110 -0
  128. package/dist/capture/consumer/loop.mjs.map +1 -0
  129. package/dist/capture/consumer/metrics.d.mts +41 -0
  130. package/dist/capture/consumer/metrics.mjs +38 -0
  131. package/dist/capture/consumer/metrics.mjs.map +1 -0
  132. package/dist/capture/consumer/retry.d.mts +33 -0
  133. package/dist/capture/consumer/retry.mjs +34 -0
  134. package/dist/capture/consumer/retry.mjs.map +1 -0
  135. package/dist/capture/consumer/run-job.mjs +195 -0
  136. package/dist/capture/consumer/run-job.mjs.map +1 -0
  137. package/dist/capture/consumer/startup.mjs +38 -0
  138. package/dist/capture/consumer/startup.mjs.map +1 -0
  139. package/dist/capture/consumer/types.d.mts +97 -0
  140. package/dist/capture/crash-failure.d.mts +25 -0
  141. package/dist/capture/crash-failure.mjs +70 -0
  142. package/dist/capture/crash-failure.mjs.map +1 -0
  143. package/dist/capture/db-queue/cadence.d.mts +32 -0
  144. package/dist/capture/db-queue/cadence.mjs +38 -0
  145. package/dist/capture/db-queue/cadence.mjs.map +1 -0
  146. package/dist/capture/db-queue/claim.d.mts +9 -0
  147. package/dist/capture/db-queue/claim.mjs +132 -0
  148. package/dist/capture/db-queue/claim.mjs.map +1 -0
  149. package/dist/capture/db-queue/clock.mjs +12 -0
  150. package/dist/capture/db-queue/clock.mjs.map +1 -0
  151. package/dist/capture/db-queue/codec.mjs +76 -0
  152. package/dist/capture/db-queue/codec.mjs.map +1 -0
  153. package/dist/capture/db-queue/index.d.mts +20 -0
  154. package/dist/capture/db-queue/index.mjs +89 -0
  155. package/dist/capture/db-queue/index.mjs.map +1 -0
  156. package/dist/capture/db-queue/keeper.d.mts +36 -0
  157. package/dist/capture/db-queue/keeper.mjs +92 -0
  158. package/dist/capture/db-queue/keeper.mjs.map +1 -0
  159. package/dist/capture/db-queue/lease.mjs +46 -0
  160. package/dist/capture/db-queue/lease.mjs.map +1 -0
  161. package/dist/capture/db-queue/lifecycle.mjs +36 -0
  162. package/dist/capture/db-queue/lifecycle.mjs.map +1 -0
  163. package/dist/capture/db-queue/operations.mjs +94 -0
  164. package/dist/capture/db-queue/operations.mjs.map +1 -0
  165. package/dist/capture/db-queue/poll-loop.d.mts +30 -0
  166. package/dist/capture/db-queue/poll-loop.mjs +89 -0
  167. package/dist/capture/db-queue/poll-loop.mjs.map +1 -0
  168. package/dist/capture/db-queue/poll.d.mts +10 -0
  169. package/dist/capture/db-queue/poll.mjs +69 -0
  170. package/dist/capture/db-queue/poll.mjs.map +1 -0
  171. package/dist/capture/db-queue/timers.d.mts +12 -0
  172. package/dist/capture/db-queue/timers.mjs +37 -0
  173. package/dist/capture/db-queue/timers.mjs.map +1 -0
  174. package/dist/capture/db-queue/types.d.mts +83 -0
  175. package/dist/capture/db-queue/types.mjs +12 -0
  176. package/dist/capture/db-queue/types.mjs.map +1 -0
  177. package/dist/capture/db-queue/wake.mjs +48 -0
  178. package/dist/capture/db-queue/wake.mjs.map +1 -0
  179. package/dist/capture/design.mjs +39 -0
  180. package/dist/capture/design.mjs.map +1 -0
  181. package/dist/capture/diff-record.mjs +23 -3
  182. package/dist/capture/diff-record.mjs.map +1 -1
  183. package/dist/capture/dispatch.d.mts +12 -7
  184. package/dist/capture/dispatch.mjs +86 -107
  185. package/dist/capture/dispatch.mjs.map +1 -1
  186. package/dist/capture/enrich.mjs +60 -0
  187. package/dist/capture/enrich.mjs.map +1 -0
  188. package/dist/capture/failure-sets.mjs +22 -0
  189. package/dist/capture/failure-sets.mjs.map +1 -0
  190. package/dist/capture/fingerprint.d.mts +42 -0
  191. package/dist/capture/fingerprint.mjs +83 -0
  192. package/dist/capture/fingerprint.mjs.map +1 -0
  193. package/dist/capture/forked/channel.d.mts +25 -0
  194. package/dist/capture/forked/child.d.mts +34 -0
  195. package/dist/capture/forked/child.mjs +202 -0
  196. package/dist/capture/forked/child.mjs.map +1 -0
  197. package/dist/capture/forked/crash-tracker.mjs +23 -0
  198. package/dist/capture/forked/crash-tracker.mjs.map +1 -0
  199. package/dist/capture/forked/decision.d.mts +26 -0
  200. package/dist/capture/forked/decision.mjs +27 -0
  201. package/dist/capture/forked/decision.mjs.map +1 -0
  202. package/dist/capture/forked/exit.mjs +12 -0
  203. package/dist/capture/forked/exit.mjs.map +1 -0
  204. package/dist/capture/forked/fork.d.mts +31 -0
  205. package/dist/capture/forked/fork.mjs +93 -0
  206. package/dist/capture/forked/fork.mjs.map +1 -0
  207. package/dist/capture/forked/forked-capture.d.mts +40 -0
  208. package/dist/capture/forked/forked-capture.mjs +240 -0
  209. package/dist/capture/forked/forked-capture.mjs.map +1 -0
  210. package/dist/capture/forked/lease-book.mjs +46 -0
  211. package/dist/capture/forked/lease-book.mjs.map +1 -0
  212. package/dist/capture/forked/protocol.d.mts +38 -0
  213. package/dist/capture/forked/protocol.mjs +25 -0
  214. package/dist/capture/forked/protocol.mjs.map +1 -0
  215. package/dist/capture/forked/runs.mjs +75 -0
  216. package/dist/capture/forked/runs.mjs.map +1 -0
  217. package/dist/capture/isolate.mjs +141 -0
  218. package/dist/capture/isolate.mjs.map +1 -0
  219. package/dist/capture/job-lease.d.mts +28 -0
  220. package/dist/capture/job-lease.mjs +57 -0
  221. package/dist/capture/job-lease.mjs.map +1 -0
  222. package/dist/capture/matrix.mjs +298 -0
  223. package/dist/capture/matrix.mjs.map +1 -0
  224. package/dist/capture/modes.d.mts +25 -0
  225. package/dist/capture/modes.mjs +107 -0
  226. package/dist/capture/modes.mjs.map +1 -0
  227. package/dist/capture/orchestrator.d.mts +37 -5
  228. package/dist/capture/orchestrator.mjs +118 -107
  229. package/dist/capture/orchestrator.mjs.map +1 -1
  230. package/dist/capture/pipeline.d.mts +9 -2
  231. package/dist/capture/pipeline.mjs +250 -45
  232. package/dist/capture/pipeline.mjs.map +1 -1
  233. package/dist/capture/progress.d.mts +11 -0
  234. package/dist/capture/progress.mjs +28 -0
  235. package/dist/capture/progress.mjs.map +1 -0
  236. package/dist/capture/publish/accept.d.mts +39 -0
  237. package/dist/capture/publish/accept.mjs +28 -0
  238. package/dist/capture/publish/accept.mjs.map +1 -0
  239. package/dist/capture/publish/complete.d.mts +46 -0
  240. package/dist/capture/publish/complete.mjs +64 -0
  241. package/dist/capture/publish/complete.mjs.map +1 -0
  242. package/dist/capture/publish/extract.d.mts +20 -0
  243. package/dist/capture/publish/extract.mjs +119 -0
  244. package/dist/capture/publish/extract.mjs.map +1 -0
  245. package/dist/capture/publish/handler.d.mts +28 -0
  246. package/dist/capture/publish/handler.mjs +62 -0
  247. package/dist/capture/publish/handler.mjs.map +1 -0
  248. package/dist/capture/publish/index.d.mts +10 -0
  249. package/dist/capture/publish/limits.d.mts +37 -0
  250. package/dist/capture/publish/limits.mjs +39 -0
  251. package/dist/capture/publish/limits.mjs.map +1 -0
  252. package/dist/capture/publish/published.d.mts +15 -0
  253. package/dist/capture/publish/published.mjs +18 -0
  254. package/dist/capture/publish/published.mjs.map +1 -0
  255. package/dist/capture/publish/run.d.mts +33 -0
  256. package/dist/capture/publish/run.mjs +30 -0
  257. package/dist/capture/publish/run.mjs.map +1 -0
  258. package/dist/capture/rediff.d.mts +1 -1
  259. package/dist/capture/rediff.mjs +4 -3
  260. package/dist/capture/rediff.mjs.map +1 -1
  261. package/dist/capture/render.mjs +53 -0
  262. package/dist/capture/render.mjs.map +1 -0
  263. package/dist/capture/scratch.d.mts +44 -0
  264. package/dist/capture/scratch.mjs +138 -0
  265. package/dist/capture/scratch.mjs.map +1 -0
  266. package/dist/capture/shard-plan.mjs +128 -0
  267. package/dist/capture/shard-plan.mjs.map +1 -0
  268. package/dist/capture/shards/context.mjs +51 -0
  269. package/dist/capture/shards/context.mjs.map +1 -0
  270. package/dist/capture/shards/execute.mjs +174 -0
  271. package/dist/capture/shards/execute.mjs.map +1 -0
  272. package/dist/capture/shards/fan-out.mjs +126 -0
  273. package/dist/capture/shards/fan-out.mjs.map +1 -0
  274. package/dist/capture/shards/history.mjs +35 -0
  275. package/dist/capture/shards/history.mjs.map +1 -0
  276. package/dist/capture/shards/reduce.mjs +97 -0
  277. package/dist/capture/shards/reduce.mjs.map +1 -0
  278. package/dist/capture/sizing.mjs +1 -11
  279. package/dist/capture/sizing.mjs.map +1 -1
  280. package/dist/capture/skip-checks.mjs +2 -65
  281. package/dist/capture/skip-checks.mjs.map +1 -1
  282. package/dist/capture/statics.d.mts +7 -8
  283. package/dist/capture/statics.mjs +25 -71
  284. package/dist/capture/statics.mjs.map +1 -1
  285. package/dist/capture/storybook-urls.d.mts +40 -0
  286. package/dist/capture/storybook-urls.mjs +41 -0
  287. package/dist/capture/storybook-urls.mjs.map +1 -0
  288. package/dist/capture/storybook.d.mts +12 -4
  289. package/dist/capture/storybook.mjs +56 -16
  290. package/dist/capture/storybook.mjs.map +1 -1
  291. package/dist/capture/target.mjs +21 -0
  292. package/dist/capture/target.mjs.map +1 -0
  293. package/dist/capture/targets.d.mts +25 -0
  294. package/dist/capture/targets.mjs +32 -0
  295. package/dist/capture/targets.mjs.map +1 -0
  296. package/dist/capture/tests.d.mts +37 -0
  297. package/dist/capture/tests.mjs +126 -0
  298. package/dist/capture/tests.mjs.map +1 -0
  299. package/dist/capture/token-chunks.mjs +74 -0
  300. package/dist/capture/token-chunks.mjs.map +1 -0
  301. package/dist/capture.d.mts +60 -7
  302. package/dist/capture.mjs +48 -3
  303. package/dist/config.d.mts +121 -12
  304. package/dist/config.mjs +9 -6
  305. package/dist/config.mjs.map +1 -1
  306. package/dist/diff.d.mts +9 -3
  307. package/dist/diff.mjs +16 -3
  308. package/dist/diff.mjs.map +1 -0
  309. package/dist/index.d.mts +1 -1
  310. package/dist/insights/budget.d.mts +20 -0
  311. package/dist/insights/budget.mjs +33 -0
  312. package/dist/insights/budget.mjs.map +1 -0
  313. package/dist/insights/envelope.d.mts +59 -0
  314. package/dist/insights/envelope.mjs +60 -0
  315. package/dist/insights/envelope.mjs.map +1 -0
  316. package/dist/insights/evidence-health.d.mts +32 -0
  317. package/dist/insights/evidence-health.mjs +28 -0
  318. package/dist/insights/evidence-health.mjs.map +1 -0
  319. package/dist/insights/evidence.d.mts +55 -0
  320. package/dist/insights/evidence.mjs +64 -0
  321. package/dist/insights/evidence.mjs.map +1 -0
  322. package/dist/insights/hash.d.mts +18 -0
  323. package/dist/insights/hash.mjs +21 -0
  324. package/dist/insights/hash.mjs.map +1 -0
  325. package/dist/insights/limits.d.mts +24 -0
  326. package/dist/insights/limits.mjs +24 -0
  327. package/dist/insights/limits.mjs.map +1 -0
  328. package/dist/insights/prompts/v1.d.mts +13 -0
  329. package/dist/insights/prompts/v1.mjs +34 -0
  330. package/dist/insights/prompts/v1.mjs.map +1 -0
  331. package/dist/insights/redact.d.mts +9 -0
  332. package/dist/insights/redact.mjs +24 -0
  333. package/dist/insights/redact.mjs.map +1 -0
  334. package/dist/insights/text.mjs +44 -0
  335. package/dist/insights/text.mjs.map +1 -0
  336. package/dist/insights.d.mts +11 -0
  337. package/dist/insights.mjs +12 -0
  338. package/dist/logger.mjs +17 -1
  339. package/dist/logger.mjs.map +1 -1
  340. package/dist/models/ai-budget-alert.d.mts +23 -0
  341. package/dist/models/ai-budget-alert.mjs +38 -0
  342. package/dist/models/ai-budget-alert.mjs.map +1 -0
  343. package/dist/models/ai-usage.d.mts +40 -0
  344. package/dist/models/ai-usage.mjs +61 -0
  345. package/dist/models/ai-usage.mjs.map +1 -0
  346. package/dist/models/baseline-archive.d.mts +84 -0
  347. package/dist/models/baseline-archive.mjs +106 -0
  348. package/dist/models/baseline-archive.mjs.map +1 -0
  349. package/dist/models/baseline-export.d.mts +19 -0
  350. package/dist/models/baseline-export.mjs +136 -0
  351. package/dist/models/baseline-export.mjs.map +1 -0
  352. package/dist/models/baseline-import.mjs +118 -0
  353. package/dist/models/baseline-import.mjs.map +1 -0
  354. package/dist/models/baseline-transfer.d.mts +49 -0
  355. package/dist/models/baseline-transfer.mjs +121 -0
  356. package/dist/models/baseline-transfer.mjs.map +1 -0
  357. package/dist/models/baseline.d.mts +32 -5
  358. package/dist/models/baseline.mjs +65 -20
  359. package/dist/models/baseline.mjs.map +1 -1
  360. package/dist/models/build-component.d.mts +28 -0
  361. package/dist/models/build-component.mjs +55 -0
  362. package/dist/models/build-component.mjs.map +1 -0
  363. package/dist/models/build-review-status.d.mts +29 -0
  364. package/dist/models/build-review-status.mjs +37 -0
  365. package/dist/models/build-review-status.mjs.map +1 -0
  366. package/dist/models/build-review.d.mts +28 -0
  367. package/dist/models/build-review.mjs +54 -0
  368. package/dist/models/build-review.mjs.map +1 -0
  369. package/dist/models/build.d.mts +25 -3
  370. package/dist/models/build.mjs +50 -11
  371. package/dist/models/build.mjs.map +1 -1
  372. package/dist/models/capture-attempt.d.mts +7 -1
  373. package/dist/models/capture-attempt.mjs +29 -4
  374. package/dist/models/capture-attempt.mjs.map +1 -1
  375. package/dist/models/capture-job.d.mts +106 -0
  376. package/dist/models/capture-job.mjs +288 -0
  377. package/dist/models/capture-job.mjs.map +1 -0
  378. package/dist/models/capture-log.d.mts +1 -1
  379. package/dist/models/capture-log.mjs +4 -3
  380. package/dist/models/capture-log.mjs.map +1 -1
  381. package/dist/models/capture-shard.d.mts +62 -0
  382. package/dist/models/capture-shard.mjs +190 -0
  383. package/dist/models/capture-shard.mjs.map +1 -0
  384. package/dist/models/changeset.d.mts +48 -0
  385. package/dist/models/changeset.mjs +81 -0
  386. package/dist/models/changeset.mjs.map +1 -0
  387. package/dist/models/columns.mjs +19 -0
  388. package/dist/models/columns.mjs.map +1 -0
  389. package/dist/models/comment.d.mts +4 -1
  390. package/dist/models/comment.mjs +7 -4
  391. package/dist/models/comment.mjs.map +1 -1
  392. package/dist/models/component.d.mts +43 -0
  393. package/dist/models/component.mjs +60 -0
  394. package/dist/models/component.mjs.map +1 -0
  395. package/dist/models/connections.d.mts +41 -0
  396. package/dist/models/connections.mjs +112 -0
  397. package/dist/models/connections.mjs.map +1 -0
  398. package/dist/models/content-ref.d.mts +1 -1
  399. package/dist/models/content-ref.mjs +1 -1
  400. package/dist/models/content-ref.mjs.map +1 -1
  401. package/dist/models/credentials.mjs +12 -2
  402. package/dist/models/credentials.mjs.map +1 -1
  403. package/dist/models/design-credentials.d.mts +41 -0
  404. package/dist/models/design-credentials.mjs +86 -0
  405. package/dist/models/design-credentials.mjs.map +1 -0
  406. package/dist/models/design-health.d.mts +16 -0
  407. package/dist/models/design-health.mjs +25 -0
  408. package/dist/models/design-health.mjs.map +1 -0
  409. package/dist/models/design-nodes.d.mts +83 -0
  410. package/dist/models/design-nodes.mjs +222 -0
  411. package/dist/models/design-nodes.mjs.map +1 -0
  412. package/dist/models/design-renders.mjs +74 -0
  413. package/dist/models/design-renders.mjs.map +1 -0
  414. package/dist/models/design-resolve.d.mts +29 -0
  415. package/dist/models/design-resolve.mjs +41 -0
  416. package/dist/models/design-resolve.mjs.map +1 -0
  417. package/dist/models/design.d.mts +39 -0
  418. package/dist/models/design.mjs +90 -0
  419. package/dist/models/design.mjs.map +1 -0
  420. package/dist/models/inherited-ratio.d.mts +21 -0
  421. package/dist/models/inherited-ratio.mjs +22 -0
  422. package/dist/models/inherited-ratio.mjs.map +1 -0
  423. package/dist/models/insight.d.mts +70 -0
  424. package/dist/models/insight.mjs +162 -0
  425. package/dist/models/insight.mjs.map +1 -0
  426. package/dist/models/label.d.mts +4 -2
  427. package/dist/models/label.mjs +25 -10
  428. package/dist/models/label.mjs.map +1 -1
  429. package/dist/models/member.d.mts +1 -1
  430. package/dist/models/member.mjs +5 -4
  431. package/dist/models/member.mjs.map +1 -1
  432. package/dist/models/notification-channel.d.mts +37 -3
  433. package/dist/models/notification-channel.mjs +88 -9
  434. package/dist/models/notification-channel.mjs.map +1 -1
  435. package/dist/models/notification-subscription.d.mts +1 -2
  436. package/dist/models/notification-subscription.mjs +7 -9
  437. package/dist/models/notification-subscription.mjs.map +1 -1
  438. package/dist/models/project-group-mapping.d.mts +6 -1
  439. package/dist/models/project-group-mapping.mjs +14 -4
  440. package/dist/models/project-group-mapping.mjs.map +1 -1
  441. package/dist/models/project.d.mts +9 -1
  442. package/dist/models/project.mjs +9 -4
  443. package/dist/models/project.mjs.map +1 -1
  444. package/dist/models/public-origin.d.mts +63 -0
  445. package/dist/models/public-origin.mjs +114 -0
  446. package/dist/models/public-origin.mjs.map +1 -0
  447. package/dist/models/review-switch-off.d.mts +14 -0
  448. package/dist/models/review-switch-off.mjs +26 -0
  449. package/dist/models/review-switch-off.mjs.map +1 -0
  450. package/dist/models/site-settings.d.mts +23 -0
  451. package/dist/models/site-settings.mjs +48 -0
  452. package/dist/models/site-settings.mjs.map +1 -0
  453. package/dist/models/snapshot.d.mts +36 -1
  454. package/dist/models/snapshot.mjs +50 -3
  455. package/dist/models/snapshot.mjs.map +1 -1
  456. package/dist/models/token.d.mts +13 -1
  457. package/dist/models/token.mjs +23 -5
  458. package/dist/models/token.mjs.map +1 -1
  459. package/dist/models/usage.d.mts +76 -0
  460. package/dist/models/usage.mjs +149 -0
  461. package/dist/models/usage.mjs.map +1 -0
  462. package/dist/models/user.d.mts +1 -1
  463. package/dist/models/user.mjs +4 -3
  464. package/dist/models/user.mjs.map +1 -1
  465. package/dist/models/webhook.d.mts +15 -1
  466. package/dist/models/webhook.mjs +33 -4
  467. package/dist/models/webhook.mjs.map +1 -1
  468. package/dist/models.d.mts +26 -3
  469. package/dist/models.mjs +27 -5
  470. package/dist/options.d.mts +18 -0
  471. package/dist/options.mjs +90 -0
  472. package/dist/options.mjs.map +1 -0
  473. package/dist/paths.d.mts +19 -4
  474. package/dist/paths.mjs +51 -10
  475. package/dist/paths.mjs.map +1 -1
  476. package/dist/retention/ai.d.mts +18 -0
  477. package/dist/retention/ai.mjs +23 -0
  478. package/dist/retention/ai.mjs.map +1 -0
  479. package/dist/retention/pending.mjs +47 -0
  480. package/dist/retention/pending.mjs.map +1 -0
  481. package/dist/retention/screenshot-sweep.d.mts +51 -0
  482. package/dist/retention/screenshot-sweep.mjs +128 -0
  483. package/dist/retention/screenshot-sweep.mjs.map +1 -0
  484. package/dist/retention.d.mts +16 -2
  485. package/dist/retention.mjs +71 -14
  486. package/dist/retention.mjs.map +1 -1
  487. package/dist/schema/baseline.d.mts +6 -0
  488. package/dist/schema/build-component.d.mts +25 -0
  489. package/dist/schema/build-review.d.mts +17 -0
  490. package/dist/schema/build.d.mts +7 -0
  491. package/dist/schema/capture-job.d.mts +60 -0
  492. package/dist/schema/capture-shard.d.mts +35 -0
  493. package/dist/schema/comment.d.mts +2 -0
  494. package/dist/schema/connection.d.mts +24 -0
  495. package/dist/schema/design.d.mts +58 -0
  496. package/dist/schema/insight.d.mts +54 -0
  497. package/dist/schema/notification.d.mts +4 -0
  498. package/dist/schema/project.d.mts +21 -0
  499. package/dist/schema/site-setting.d.mts +21 -0
  500. package/dist/schema/snapshot.d.mts +12 -0
  501. package/dist/schema/usage.d.mts +30 -0
  502. package/dist/schema.d.mts +11 -3
  503. package/dist/serverless.d.mts +21 -0
  504. package/dist/serverless.mjs +37 -0
  505. package/dist/serverless.mjs.map +1 -0
  506. package/dist/test-helpers/create-project.d.mts +1 -1
  507. package/dist/test-helpers/deferred.d.mts +39 -0
  508. package/dist/test-helpers/deferred.mjs +61 -0
  509. package/dist/test-helpers/deferred.mjs.map +1 -0
  510. package/dist/test-helpers/design-contract.d.mts +21 -0
  511. package/dist/test-helpers/design-contract.mjs +40 -0
  512. package/dist/test-helpers/design-contract.mjs.map +1 -0
  513. package/dist/test-helpers/fake-database.mjs +14 -2
  514. package/dist/test-helpers/fake-database.mjs.map +1 -1
  515. package/dist/test-helpers/fake-design.d.mts +43 -0
  516. package/dist/test-helpers/fake-design.mjs +114 -0
  517. package/dist/test-helpers/fake-design.mjs.map +1 -0
  518. package/dist/test-helpers/fake-notifier.d.mts +21 -0
  519. package/dist/test-helpers/fake-notifier.mjs +44 -0
  520. package/dist/test-helpers/fake-notifier.mjs.map +1 -0
  521. package/dist/test-helpers/fake-tables.mjs +255 -67
  522. package/dist/test-helpers/fake-tables.mjs.map +1 -1
  523. package/dist/test-helpers/manual-clock.d.mts +27 -0
  524. package/dist/test-helpers/manual-clock.mjs +56 -0
  525. package/dist/test-helpers/manual-clock.mjs.map +1 -0
  526. package/dist/test-helpers/notifier-contract.d.mts +7 -1
  527. package/dist/test-helpers/notifier-contract.mjs +32 -3
  528. package/dist/test-helpers/notifier-contract.mjs.map +1 -1
  529. package/dist/test-helpers/queue-contract.d.mts +16 -2
  530. package/dist/test-helpers/queue-contract.mjs +195 -1
  531. package/dist/test-helpers/queue-contract.mjs.map +1 -1
  532. package/dist/test-helpers/queue-multi-instance.d.mts +20 -0
  533. package/dist/test-helpers/queue-multi-instance.mjs +206 -0
  534. package/dist/test-helpers/queue-multi-instance.mjs.map +1 -0
  535. package/dist/test-helpers/runner-contract.mjs +11 -0
  536. package/dist/test-helpers/runner-contract.mjs.map +1 -1
  537. package/dist/test-helpers/sql-chunks.mjs +23 -0
  538. package/dist/test-helpers/sql-chunks.mjs.map +1 -1
  539. package/dist/test-helpers/storage-contract.mjs +1 -1
  540. package/dist/test-helpers.d.mts +9 -4
  541. package/dist/test-helpers.mjs +8 -3
  542. package/dist/types.d.mts +14 -3
  543. package/dist/types.mjs +21 -4
  544. package/dist/types.mjs.map +1 -1
  545. package/dist/urls.d.mts +4 -0
  546. package/dist/urls.mjs +11 -2
  547. package/dist/urls.mjs.map +1 -1
  548. package/dist/utils/adaptive-concurrency.d.mts +66 -0
  549. package/dist/utils/adaptive-concurrency.mjs +149 -0
  550. package/dist/utils/adaptive-concurrency.mjs.map +1 -0
  551. package/dist/utils/connect-retry.d.mts +26 -0
  552. package/dist/utils/connect-retry.mjs +43 -0
  553. package/dist/utils/connect-retry.mjs.map +1 -0
  554. package/dist/utils/environment.d.mts +19 -0
  555. package/dist/utils/environment.mjs +59 -0
  556. package/dist/utils/environment.mjs.map +1 -0
  557. package/dist/utils/http.d.mts +17 -1
  558. package/dist/utils/http.mjs +22 -3
  559. package/dist/utils/http.mjs.map +1 -1
  560. package/dist/utils/map-adaptive.d.mts +15 -0
  561. package/dist/utils/map-adaptive.mjs +72 -0
  562. package/dist/utils/map-adaptive.mjs.map +1 -0
  563. package/dist/utils/map-limit.d.mts +10 -0
  564. package/dist/utils/map-limit.mjs +32 -0
  565. package/dist/utils/map-limit.mjs.map +1 -0
  566. package/dist/utils/page-limiter.d.mts +37 -0
  567. package/dist/utils/page-limiter.mjs +56 -0
  568. package/dist/utils/page-limiter.mjs.map +1 -0
  569. package/dist/utils/public-origin.d.mts +20 -0
  570. package/dist/utils/public-origin.mjs +75 -0
  571. package/dist/utils/public-origin.mjs.map +1 -0
  572. package/dist/utils/redact.mjs +3 -0
  573. package/dist/utils/redact.mjs.map +1 -1
  574. package/dist/utils/remote-environment.d.mts +39 -0
  575. package/dist/utils/remote-environment.mjs +114 -0
  576. package/dist/utils/remote-environment.mjs.map +1 -0
  577. package/dist/utils/resources.d.mts +64 -0
  578. package/dist/utils/resources.mjs +122 -0
  579. package/dist/utils/resources.mjs.map +1 -0
  580. package/dist/utils/screenshot-store.d.mts +15 -0
  581. package/dist/utils/screenshot-store.mjs +41 -0
  582. package/dist/utils/screenshot-store.mjs.map +1 -0
  583. package/dist/utils/session-gate.d.mts +22 -0
  584. package/dist/utils/session-gate.mjs +53 -0
  585. package/dist/utils/session-gate.mjs.map +1 -0
  586. package/dist/utils/storybook-token.d.mts +81 -0
  587. package/dist/utils/storybook-token.mjs +134 -0
  588. package/dist/utils/storybook-token.mjs.map +1 -0
  589. package/dist/utils/storybook-url.d.mts +15 -0
  590. package/dist/utils/storybook-url.mjs +21 -0
  591. package/dist/utils/storybook-url.mjs.map +1 -0
  592. package/dist/utils/timing.mjs +1 -1
  593. package/dist/utils/timing.mjs.map +1 -1
  594. package/dist/utils/zip-read.mjs +129 -0
  595. package/dist/utils/zip-read.mjs.map +1 -0
  596. package/dist/utils/zip-write.d.mts +18 -0
  597. package/dist/utils/zip-write.mjs +188 -0
  598. package/dist/utils/zip-write.mjs.map +1 -0
  599. package/dist/utils.d.mts +17 -3
  600. package/dist/utils.mjs +18 -4
  601. package/package.json +32 -20
  602. package/dist/adapter/capture-runner.mjs.map +0 -1
  603. package/dist/adapter/git-host/comments.d.mts +0 -41
  604. package/dist/adapter/git-host/comments.mjs +0 -54
  605. package/dist/adapter/git-host/comments.mjs.map +0 -1
  606. package/dist/adapter/git-host/helpers.d.mts +0 -13
  607. package/dist/adapter/git-host/helpers.mjs +0 -30
  608. package/dist/adapter/git-host/helpers.mjs.map +0 -1
  609. package/dist/adapter/git-host.d.mts +0 -42
  610. package/dist/capture/queue.d.mts +0 -38
  611. package/dist/capture/queue.mjs +0 -98
  612. package/dist/capture/queue.mjs.map +0 -1
  613. package/dist/capture/recovery.d.mts +0 -21
  614. package/dist/capture/recovery.mjs +0 -83
  615. package/dist/capture/recovery.mjs.map +0 -1
  616. package/dist/capture/status-fanout.mjs +0 -72
  617. package/dist/capture/status-fanout.mjs.map +0 -1
  618. package/dist/diff/engine.d.mts +0 -16
  619. package/dist/diff/engine.mjs +0 -87
  620. package/dist/diff/engine.mjs.map +0 -1
  621. package/dist/diff/options.d.mts +0 -42
  622. package/dist/diff/options.mjs +0 -15
  623. package/dist/diff/options.mjs.map +0 -1
  624. package/dist/models/status-config.d.mts +0 -38
  625. package/dist/models/status-config.mjs +0 -63
  626. package/dist/models/status-config.mjs.map +0 -1
  627. package/dist/schema/status-config.d.mts +0 -16
  628. package/dist/test-helpers/git-contract.d.mts +0 -11
  629. package/dist/test-helpers/git-contract.mjs +0 -34
  630. package/dist/test-helpers/git-contract.mjs.map +0 -1
  631. /package/dist/adapter/{git-host.mjs → oauth.mjs} +0 -0
@@ -0,0 +1,129 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ import "node:buffer";
5
+ import { crc32, inflateRawSync } from "node:zlib";
6
+ //#region src/utils/zip-read.ts
7
+ /** A malformed, unsafe, or over-limit archive. */
8
+ var ZipFormatError = class extends Error {
9
+ name = "ZipFormatError";
10
+ };
11
+ /**
12
+ * Index the file entries of `archive` by name (directories are skipped).
13
+ *
14
+ * @throws {ZipFormatError} On malformed, unsafe, or over-limit archives.
15
+ */
16
+ function readZip(archive, limits) {
17
+ const end = findEndOfCentralDirectory(archive);
18
+ const count = archive.readUInt16LE(end + 10);
19
+ if (count > limits.maxEntries) throw new ZipFormatError(`Archive has more than ${limits.maxEntries} entries`);
20
+ const records = readCentralDirectory(archive, archive.readUInt32LE(end + 16), count);
21
+ if (records.reduce((sum, record) => sum + record.size, 0) > limits.maxTotalBytes) throw new ZipFormatError(`Archive expands beyond ${limits.maxTotalBytes} bytes`);
22
+ return indexEntries(archive, records, limits.maxEntryBytes);
23
+ }
24
+ const EOCD_SIGNATURE = 101010256;
25
+ const CENTRAL_SIGNATURE = 33639248;
26
+ const LOCAL_SIGNATURE = 67324752;
27
+ const EOCD_SIZE = 22;
28
+ const MAX_COMMENT = 65535;
29
+ const STORE = 0;
30
+ const DEFLATE = 8;
31
+ function fail(message) {
32
+ throw new ZipFormatError(message);
33
+ }
34
+ function findEndOfCentralDirectory(archive) {
35
+ const floor = Math.max(0, archive.length - EOCD_SIZE - MAX_COMMENT);
36
+ for (let at = archive.length - EOCD_SIZE; at >= floor; at -= 1) if (archive.readUInt32LE(at) === EOCD_SIGNATURE) {
37
+ assertSingleDisk(archive, at);
38
+ return at;
39
+ }
40
+ return fail("Not a zip archive (no end of central directory)");
41
+ }
42
+ function assertSingleDisk(archive, end) {
43
+ const multiDisk = archive.readUInt16LE(end + 4) !== 0 || archive.readUInt16LE(end + 6) !== 0;
44
+ const entriesMismatch = archive.readUInt16LE(end + 8) !== archive.readUInt16LE(end + 10);
45
+ if (multiDisk || entriesMismatch || archive.readUInt32LE(end + 16) === 4294967295) fail("Multi-disk and zip64 archives are not supported");
46
+ }
47
+ function readCentralDirectory(archive, start, count) {
48
+ const records = [];
49
+ let at = start;
50
+ for (let index = 0; index < count; index += 1) {
51
+ const { record, next } = readCentralRecord(archive, at);
52
+ records.push(record);
53
+ at = next;
54
+ }
55
+ return records;
56
+ }
57
+ function readCentralRecord(archive, at) {
58
+ assertRange(archive, at, 46);
59
+ if (archive.readUInt32LE(at) !== CENTRAL_SIGNATURE) fail("Corrupt central directory");
60
+ const nameLength = archive.readUInt16LE(at + 28);
61
+ const extras = archive.readUInt16LE(at + 30) + archive.readUInt16LE(at + 32);
62
+ assertRange(archive, at + 46, nameLength);
63
+ return {
64
+ record: {
65
+ name: archive.toString("utf8", at + 46, at + 46 + nameLength),
66
+ method: archive.readUInt16LE(at + 10),
67
+ flags: archive.readUInt16LE(at + 8),
68
+ crc: archive.readUInt32LE(at + 16),
69
+ compressedSize: archive.readUInt32LE(at + 20),
70
+ size: archive.readUInt32LE(at + 24),
71
+ localOffset: archive.readUInt32LE(at + 42)
72
+ },
73
+ next: at + 46 + nameLength + extras
74
+ };
75
+ }
76
+ function assertRange(archive, start, length) {
77
+ if (start < 0 || start + length > archive.length) fail("Truncated zip archive");
78
+ }
79
+ /** Whether an entry name could escape an extraction root or confuse lookups. */
80
+ function isUnsafeEntryName(name) {
81
+ return name.length === 0 || name.startsWith("/") || name.includes("\\") || name.includes("\0") || /^[a-z]:/iu.test(name) || name.split("/").some((segment) => segment === ".." || segment === ".");
82
+ }
83
+ function indexEntries(archive, records, maxEntryBytes) {
84
+ const entries = /* @__PURE__ */ new Map();
85
+ for (const record of records) {
86
+ if (record.name.endsWith("/")) continue;
87
+ validateRecord(record, maxEntryBytes);
88
+ if (entries.has(record.name)) fail(`Duplicate zip entry: ${record.name}`);
89
+ entries.set(record.name, {
90
+ name: record.name,
91
+ size: record.size,
92
+ read: () => extract(archive, record)
93
+ });
94
+ }
95
+ return entries;
96
+ }
97
+ function validateRecord(record, maxEntryBytes) {
98
+ if (isUnsafeEntryName(record.name)) fail(`Unsafe zip entry name: ${record.name}`);
99
+ if (record.flags % 2 === 1) fail(`Encrypted zip entries are not supported: ${record.name}`);
100
+ if (record.method !== STORE && record.method !== DEFLATE) fail(`Unsupported compression method ${record.method}: ${record.name}`);
101
+ if (record.size > maxEntryBytes) fail(`Zip entry exceeds ${maxEntryBytes} bytes: ${record.name}`);
102
+ }
103
+ function extract(archive, record) {
104
+ const at = record.localOffset;
105
+ assertRange(archive, at, 30);
106
+ if (archive.readUInt32LE(at) !== LOCAL_SIGNATURE) fail(`Corrupt local header: ${record.name}`);
107
+ const raw = entryData(archive, record);
108
+ const data = record.method === STORE ? raw : inflate(raw, record);
109
+ if (data.length !== record.size || crc32(data) !== record.crc) fail(`Zip entry failed integrity check: ${record.name}`);
110
+ return data;
111
+ }
112
+ /** Compressed bytes of an entry, located through its local header. */
113
+ function entryData(archive, record) {
114
+ const at = record.localOffset;
115
+ const start = at + 30 + archive.readUInt16LE(at + 26) + archive.readUInt16LE(at + 28);
116
+ assertRange(archive, start, record.compressedSize);
117
+ return archive.subarray(start, start + record.compressedSize);
118
+ }
119
+ function inflate(raw, record) {
120
+ try {
121
+ return inflateRawSync(raw, { maxOutputLength: record.size + 1 });
122
+ } catch {
123
+ return fail(`Zip entry failed to inflate: ${record.name}`);
124
+ }
125
+ }
126
+ //#endregion
127
+ export { ZipFormatError, isUnsafeEntryName, readZip };
128
+
129
+ //# sourceMappingURL=zip-read.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zip-read.mjs","names":[],"sources":["../../src/utils/zip-read.ts"],"sourcesContent":["/**\n * Defensive in-memory zip reader for untrusted archives.\n *\n * Reads the central directory of a buffered archive and inflates entries\n * lazily, enforcing entry-count, per-entry and total size limits before any\n * decompression (zip-bomb guard) and verifying each entry's CRC. Entry names\n * that could traverse paths are rejected outright. Supports STORE and\n * DEFLATE; rejects encryption, multi-disk and zip64 archives.\n */\nimport { Buffer } from \"node:buffer\";\nimport { crc32, inflateRawSync } from \"node:zlib\";\n\n/** Limits applied while reading an archive. */\nexport interface ZipReadLimits {\n /** Maximum number of entries in the central directory. */\n maxEntries: number;\n /** Maximum uncompressed size of one entry, in bytes. */\n maxEntryBytes: number;\n /** Maximum combined uncompressed size of all entries, in bytes. */\n maxTotalBytes: number;\n}\n\n/** One file in an archive; `read()` inflates and CRC-checks it. */\nexport interface ZipEntry {\n name: string;\n size: number;\n read: () => Buffer;\n}\n\n/** A malformed, unsafe, or over-limit archive. */\nexport class ZipFormatError extends Error {\n override readonly name = \"ZipFormatError\";\n}\n\n/**\n * Index the file entries of `archive` by name (directories are skipped).\n *\n * @throws {ZipFormatError} On malformed, unsafe, or over-limit archives.\n */\nexport function readZip(archive: Buffer, limits: ZipReadLimits): Map<string, ZipEntry> {\n const end = findEndOfCentralDirectory(archive);\n const count = archive.readUInt16LE(end + 10);\n if (count > limits.maxEntries) {\n throw new ZipFormatError(`Archive has more than ${limits.maxEntries} entries`);\n }\n const records = readCentralDirectory(archive, archive.readUInt32LE(end + 16), count);\n const total = records.reduce((sum, record) => sum + record.size, 0);\n if (total > limits.maxTotalBytes) {\n throw new ZipFormatError(`Archive expands beyond ${limits.maxTotalBytes} bytes`);\n }\n return indexEntries(archive, records, limits.maxEntryBytes);\n}\n\n/** Central-directory fields needed to extract an entry. */\ninterface CentralRecord {\n name: string;\n method: number;\n flags: number;\n crc: number;\n compressedSize: number;\n size: number;\n localOffset: number;\n}\n\nconst EOCD_SIGNATURE = 0x06_05_4b_50;\nconst CENTRAL_SIGNATURE = 0x02_01_4b_50;\nconst LOCAL_SIGNATURE = 0x04_03_4b_50;\nconst EOCD_SIZE = 22;\nconst MAX_COMMENT = 0xff_ff;\nconst STORE = 0;\nconst DEFLATE = 8;\n\nfunction fail(message: string): never {\n throw new ZipFormatError(message);\n}\n\nfunction findEndOfCentralDirectory(archive: Buffer): number {\n const floor = Math.max(0, archive.length - EOCD_SIZE - MAX_COMMENT);\n for (let at = archive.length - EOCD_SIZE; at >= floor; at -= 1) {\n if (archive.readUInt32LE(at) === EOCD_SIGNATURE) {\n assertSingleDisk(archive, at);\n return at;\n }\n }\n return fail(\"Not a zip archive (no end of central directory)\");\n}\n\nfunction assertSingleDisk(archive: Buffer, end: number): void {\n const multiDisk = archive.readUInt16LE(end + 4) !== 0 || archive.readUInt16LE(end + 6) !== 0;\n const entriesMismatch = archive.readUInt16LE(end + 8) !== archive.readUInt16LE(end + 10);\n if (multiDisk || entriesMismatch || archive.readUInt32LE(end + 16) === 0xff_ff_ff_ff) {\n fail(\"Multi-disk and zip64 archives are not supported\");\n }\n}\n\nfunction readCentralDirectory(archive: Buffer, start: number, count: number): CentralRecord[] {\n const records: CentralRecord[] = [];\n let at = start;\n for (let index = 0; index < count; index += 1) {\n const { record, next } = readCentralRecord(archive, at);\n records.push(record);\n at = next;\n }\n return records;\n}\n\nfunction readCentralRecord(archive: Buffer, at: number): { record: CentralRecord; next: number } {\n assertRange(archive, at, 46);\n if (archive.readUInt32LE(at) !== CENTRAL_SIGNATURE) {\n fail(\"Corrupt central directory\");\n }\n const nameLength = archive.readUInt16LE(at + 28);\n const extras = archive.readUInt16LE(at + 30) + archive.readUInt16LE(at + 32);\n assertRange(archive, at + 46, nameLength);\n const record: CentralRecord = {\n name: archive.toString(\"utf8\", at + 46, at + 46 + nameLength),\n method: archive.readUInt16LE(at + 10),\n flags: archive.readUInt16LE(at + 8),\n crc: archive.readUInt32LE(at + 16),\n compressedSize: archive.readUInt32LE(at + 20),\n size: archive.readUInt32LE(at + 24),\n localOffset: archive.readUInt32LE(at + 42),\n };\n return { record, next: at + 46 + nameLength + extras };\n}\n\nfunction assertRange(archive: Buffer, start: number, length: number): void {\n if (start < 0 || start + length > archive.length) {\n fail(\"Truncated zip archive\");\n }\n}\n\n/** Whether an entry name could escape an extraction root or confuse lookups. */\nexport function isUnsafeEntryName(name: string): boolean {\n return (\n name.length === 0 ||\n name.startsWith(\"/\") ||\n name.includes(\"\\\\\") ||\n name.includes(\"\\0\") ||\n /^[a-z]:/iu.test(name) ||\n name.split(\"/\").some((segment) => segment === \"..\" || segment === \".\")\n );\n}\n\nfunction indexEntries(\n archive: Buffer,\n records: CentralRecord[],\n maxEntryBytes: number,\n): Map<string, ZipEntry> {\n const entries = new Map<string, ZipEntry>();\n for (const record of records) {\n if (record.name.endsWith(\"/\")) {\n continue;\n }\n validateRecord(record, maxEntryBytes);\n if (entries.has(record.name)) {\n fail(`Duplicate zip entry: ${record.name}`);\n }\n entries.set(record.name, {\n name: record.name,\n size: record.size,\n read: () => extract(archive, record),\n });\n }\n return entries;\n}\n\nfunction validateRecord(record: CentralRecord, maxEntryBytes: number): void {\n if (isUnsafeEntryName(record.name)) {\n fail(`Unsafe zip entry name: ${record.name}`);\n }\n if (record.flags % 2 === 1) {\n fail(`Encrypted zip entries are not supported: ${record.name}`);\n }\n if (record.method !== STORE && record.method !== DEFLATE) {\n fail(`Unsupported compression method ${record.method}: ${record.name}`);\n }\n if (record.size > maxEntryBytes) {\n fail(`Zip entry exceeds ${maxEntryBytes} bytes: ${record.name}`);\n }\n}\n\nfunction extract(archive: Buffer, record: CentralRecord): Buffer {\n const at = record.localOffset;\n assertRange(archive, at, 30);\n if (archive.readUInt32LE(at) !== LOCAL_SIGNATURE) {\n fail(`Corrupt local header: ${record.name}`);\n }\n const raw = entryData(archive, record);\n const data = record.method === STORE ? raw : inflate(raw, record);\n if (data.length !== record.size || crc32(data) !== record.crc) {\n fail(`Zip entry failed integrity check: ${record.name}`);\n }\n return data;\n}\n\n/** Compressed bytes of an entry, located through its local header. */\nfunction entryData(archive: Buffer, record: CentralRecord): Buffer {\n const at = record.localOffset;\n const start = at + 30 + archive.readUInt16LE(at + 26) + archive.readUInt16LE(at + 28);\n assertRange(archive, start, record.compressedSize);\n return archive.subarray(start, start + record.compressedSize);\n}\n\nfunction inflate(raw: Buffer, record: CentralRecord): Buffer {\n try {\n // Cap output at the declared size (+1 so overruns are detectable, not truncated).\n return inflateRawSync(raw, { maxOutputLength: record.size + 1 });\n } catch {\n return fail(`Zip entry failed to inflate: ${record.name}`);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import __tsdown_shims_path from 'node:path';
2
+ import __tsdown_shims_url from 'node:url';
3
+ import { Buffer } from "node:buffer";
4
+ //#region src/utils/zip-write.d.ts
5
+ /** One file to add to an archive; a `data` function is called lazily when the entry is written. */
6
+ interface ZipSource {
7
+ name: string;
8
+ data: Buffer | (() => Promise<Buffer>);
9
+ }
10
+ /**
11
+ * Stream a zip archive for `sources`, yielding header/data chunks in order.
12
+ *
13
+ * @throws When the archive would need zip64 (more than 65535 entries or 4 GiB).
14
+ */
15
+ declare function zipStream(sources: Iterable<ZipSource> | AsyncIterable<ZipSource>): AsyncGenerator<Buffer>;
16
+ //#endregion
17
+ export { ZipSource, zipStream };
18
+ //# sourceMappingURL=zip-write.d.mts.map
@@ -0,0 +1,188 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ import { Buffer } from "node:buffer";
5
+ import { crc32 } from "node:zlib";
6
+ //#region src/utils/zip-write.ts
7
+ /**
8
+ * Minimal streaming zip writer (STORE method, no zip64).
9
+ *
10
+ * Baseline exports are PNGs — already deflated — so entries are stored
11
+ * uncompressed. Entries are produced one at a time, so memory stays bounded
12
+ * by the largest single entry rather than the whole archive.
13
+ */
14
+ /**
15
+ * Stream a zip archive for `sources`, yielding header/data chunks in order.
16
+ *
17
+ * @throws When the archive would need zip64 (more than 65535 entries or 4 GiB).
18
+ */
19
+ async function* zipStream(sources) {
20
+ const central = [];
21
+ let offset = 0;
22
+ for await (const source of sources) {
23
+ const data = typeof source.data === "function" ? await source.data() : source.data;
24
+ const record = entryRecord(source.name, data);
25
+ central.push(centralHeader(record, offset));
26
+ yield* [localHeader(record), data];
27
+ offset = checkedSize(offset + 30 + record.name.length + data.length);
28
+ }
29
+ yield* trailer(central, offset);
30
+ }
31
+ const MAX_U32 = 4294967295;
32
+ const MAX_ENTRIES = 65535;
33
+ /** General-purpose flag bit 11: file names are UTF-8. */
34
+ const UTF8_FLAG = 2048;
35
+ /** 1980-01-01 in DOS date format — fixed so archives are byte-reproducible. */
36
+ const DOS_DATE = 33;
37
+ const VERSION = 20;
38
+ function entryRecord(name, data) {
39
+ return {
40
+ name: Buffer.from(name, "utf8"),
41
+ crc: crc32(data),
42
+ size: checkedSize(data.length)
43
+ };
44
+ }
45
+ function checkedSize(size) {
46
+ if (size > MAX_U32) throw new Error("Archive exceeds 4 GiB (zip64 is not supported)");
47
+ return size;
48
+ }
49
+ function header(size, fields, name) {
50
+ const out = Buffer.alloc(size);
51
+ for (const [offset, width, value] of fields) if (width === 2) out.writeUInt16LE(value, offset);
52
+ else out.writeUInt32LE(value, offset);
53
+ return name ? Buffer.concat([out, name]) : out;
54
+ }
55
+ function localHeader(record) {
56
+ return header(30, [
57
+ [
58
+ 0,
59
+ 4,
60
+ 67324752
61
+ ],
62
+ [
63
+ 4,
64
+ 2,
65
+ VERSION
66
+ ],
67
+ [
68
+ 6,
69
+ 2,
70
+ UTF8_FLAG
71
+ ],
72
+ [
73
+ 12,
74
+ 2,
75
+ DOS_DATE
76
+ ],
77
+ [
78
+ 14,
79
+ 4,
80
+ record.crc
81
+ ],
82
+ [
83
+ 18,
84
+ 4,
85
+ record.size
86
+ ],
87
+ [
88
+ 22,
89
+ 4,
90
+ record.size
91
+ ],
92
+ [
93
+ 26,
94
+ 2,
95
+ record.name.length
96
+ ]
97
+ ], record.name);
98
+ }
99
+ function centralHeader(record, offset) {
100
+ return header(46, [
101
+ [
102
+ 0,
103
+ 4,
104
+ 33639248
105
+ ],
106
+ [
107
+ 4,
108
+ 2,
109
+ VERSION
110
+ ],
111
+ [
112
+ 6,
113
+ 2,
114
+ VERSION
115
+ ],
116
+ [
117
+ 8,
118
+ 2,
119
+ UTF8_FLAG
120
+ ],
121
+ [
122
+ 14,
123
+ 2,
124
+ DOS_DATE
125
+ ],
126
+ [
127
+ 16,
128
+ 4,
129
+ record.crc
130
+ ],
131
+ [
132
+ 20,
133
+ 4,
134
+ record.size
135
+ ],
136
+ [
137
+ 24,
138
+ 4,
139
+ record.size
140
+ ],
141
+ [
142
+ 28,
143
+ 2,
144
+ record.name.length
145
+ ],
146
+ [
147
+ 42,
148
+ 4,
149
+ offset
150
+ ]
151
+ ], record.name);
152
+ }
153
+ function* trailer(central, offset) {
154
+ if (central.length > MAX_ENTRIES) throw new Error("Archive exceeds 65535 entries (zip64 is not supported)");
155
+ const directory = Buffer.concat(central);
156
+ yield directory;
157
+ yield header(22, [
158
+ [
159
+ 0,
160
+ 4,
161
+ 101010256
162
+ ],
163
+ [
164
+ 8,
165
+ 2,
166
+ central.length
167
+ ],
168
+ [
169
+ 10,
170
+ 2,
171
+ central.length
172
+ ],
173
+ [
174
+ 12,
175
+ 4,
176
+ directory.length
177
+ ],
178
+ [
179
+ 16,
180
+ 4,
181
+ checkedSize(offset)
182
+ ]
183
+ ]);
184
+ }
185
+ //#endregion
186
+ export { zipStream };
187
+
188
+ //# sourceMappingURL=zip-write.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zip-write.mjs","names":[],"sources":["../../src/utils/zip-write.ts"],"sourcesContent":["/**\n * Minimal streaming zip writer (STORE method, no zip64).\n *\n * Baseline exports are PNGs — already deflated — so entries are stored\n * uncompressed. Entries are produced one at a time, so memory stays bounded\n * by the largest single entry rather than the whole archive.\n */\nimport { Buffer } from \"node:buffer\";\nimport { crc32 } from \"node:zlib\";\n\n/** One file to add to an archive; a `data` function is called lazily when the entry is written. */\nexport interface ZipSource {\n name: string;\n data: Buffer | (() => Promise<Buffer>);\n}\n\n/**\n * Stream a zip archive for `sources`, yielding header/data chunks in order.\n *\n * @throws When the archive would need zip64 (more than 65535 entries or 4 GiB).\n */\nexport async function* zipStream(\n sources: Iterable<ZipSource> | AsyncIterable<ZipSource>,\n): AsyncGenerator<Buffer> {\n const central: Buffer[] = [];\n let offset = 0;\n for await (const source of sources) {\n const data = typeof source.data === \"function\" ? await source.data() : source.data;\n const record = entryRecord(source.name, data);\n central.push(centralHeader(record, offset));\n yield* [localHeader(record), data];\n offset = checkedSize(offset + 30 + record.name.length + data.length);\n }\n yield* trailer(central, offset);\n}\n\n/** Header fields shared by the local and central records of an entry. */\ninterface EntryRecord {\n name: Buffer;\n crc: number;\n size: number;\n}\n\nconst MAX_U32 = 0xff_ff_ff_ff;\nconst MAX_ENTRIES = 0xff_ff;\n/** General-purpose flag bit 11: file names are UTF-8. */\nconst UTF8_FLAG = 0x08_00;\n/** 1980-01-01 in DOS date format — fixed so archives are byte-reproducible. */\nconst DOS_DATE = 0x00_21;\nconst VERSION = 20;\n\nfunction entryRecord(name: string, data: Buffer): EntryRecord {\n return { name: Buffer.from(name, \"utf8\"), crc: crc32(data), size: checkedSize(data.length) };\n}\n\nfunction checkedSize(size: number): number {\n if (size > MAX_U32) {\n throw new Error(\"Archive exceeds 4 GiB (zip64 is not supported)\");\n }\n return size;\n}\n\n/** `[offset, width, value]` triples for a fixed-size header. */\ntype Fields = readonly (readonly [offset: number, width: 2 | 4, value: number])[];\n\nfunction header(size: number, fields: Fields, name?: Buffer): Buffer {\n const out = Buffer.alloc(size);\n for (const [offset, width, value] of fields) {\n if (width === 2) {\n out.writeUInt16LE(value, offset);\n } else {\n out.writeUInt32LE(value, offset);\n }\n }\n return name ? Buffer.concat([out, name]) : out;\n}\n\nfunction localHeader(record: EntryRecord): Buffer {\n return header(\n 30,\n [\n [0, 4, 0x04_03_4b_50],\n [4, 2, VERSION],\n [6, 2, UTF8_FLAG],\n [12, 2, DOS_DATE],\n [14, 4, record.crc],\n [18, 4, record.size],\n [22, 4, record.size],\n [26, 2, record.name.length],\n ],\n record.name,\n );\n}\n\nfunction centralHeader(record: EntryRecord, offset: number): Buffer {\n return header(\n 46,\n [\n [0, 4, 0x02_01_4b_50],\n [4, 2, VERSION],\n [6, 2, VERSION],\n [8, 2, UTF8_FLAG],\n [14, 2, DOS_DATE],\n [16, 4, record.crc],\n [20, 4, record.size],\n [24, 4, record.size],\n [28, 2, record.name.length],\n [42, 4, offset],\n ],\n record.name,\n );\n}\n\nfunction* trailer(central: Buffer[], offset: number): Generator<Buffer> {\n if (central.length > MAX_ENTRIES) {\n throw new Error(\"Archive exceeds 65535 entries (zip64 is not supported)\");\n }\n const directory = Buffer.concat(central);\n yield directory;\n yield header(22, [\n [0, 4, 0x06_05_4b_50],\n [8, 2, central.length],\n [10, 2, central.length],\n [12, 4, directory.length],\n [16, 4, checkedSize(offset)],\n ]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,gBAAuB,UACrB,SACwB;CACxB,MAAM,UAAoB,CAAC;CAC3B,IAAI,SAAS;CACb,WAAW,MAAM,UAAU,SAAS;EAClC,MAAM,OAAO,OAAO,OAAO,SAAS,aAAa,MAAM,OAAO,KAAK,IAAI,OAAO;EAC9E,MAAM,SAAS,YAAY,OAAO,MAAM,IAAI;EAC5C,QAAQ,KAAK,cAAc,QAAQ,MAAM,CAAC;EAC1C,OAAO,CAAC,YAAY,MAAM,GAAG,IAAI;EACjC,SAAS,YAAY,SAAS,KAAK,OAAO,KAAK,SAAS,KAAK,MAAM;CACrE;CACA,OAAO,QAAQ,SAAS,MAAM;AAChC;AASA,MAAM,UAAU;AAChB,MAAM,cAAc;;AAEpB,MAAM,YAAY;;AAElB,MAAM,WAAW;AACjB,MAAM,UAAU;AAEhB,SAAS,YAAY,MAAc,MAA2B;CAC5D,OAAO;EAAE,MAAM,OAAO,KAAK,MAAM,MAAM;EAAG,KAAK,MAAM,IAAI;EAAG,MAAM,YAAY,KAAK,MAAM;CAAE;AAC7F;AAEA,SAAS,YAAY,MAAsB;CACzC,IAAI,OAAO,SACT,MAAM,IAAI,MAAM,gDAAgD;CAElE,OAAO;AACT;AAKA,SAAS,OAAO,MAAc,QAAgB,MAAuB;CACnE,MAAM,MAAM,OAAO,MAAM,IAAI;CAC7B,KAAK,MAAM,CAAC,QAAQ,OAAO,UAAU,QACnC,IAAI,UAAU,GACZ,IAAI,cAAc,OAAO,MAAM;MAE/B,IAAI,cAAc,OAAO,MAAM;CAGnC,OAAO,OAAO,OAAO,OAAO,CAAC,KAAK,IAAI,CAAC,IAAI;AAC7C;AAEA,SAAS,YAAY,QAA6B;CAChD,OAAO,OACL,IACA;EACE;GAAC;GAAG;GAAG;EAAa;EACpB;GAAC;GAAG;GAAG;EAAO;EACd;GAAC;GAAG;GAAG;EAAS;EAChB;GAAC;GAAI;GAAG;EAAQ;EAChB;GAAC;GAAI;GAAG,OAAO;EAAG;EAClB;GAAC;GAAI;GAAG,OAAO;EAAI;EACnB;GAAC;GAAI;GAAG,OAAO;EAAI;EACnB;GAAC;GAAI;GAAG,OAAO,KAAK;EAAM;CAC5B,GACA,OAAO,IACT;AACF;AAEA,SAAS,cAAc,QAAqB,QAAwB;CAClE,OAAO,OACL,IACA;EACE;GAAC;GAAG;GAAG;EAAa;EACpB;GAAC;GAAG;GAAG;EAAO;EACd;GAAC;GAAG;GAAG;EAAO;EACd;GAAC;GAAG;GAAG;EAAS;EAChB;GAAC;GAAI;GAAG;EAAQ;EAChB;GAAC;GAAI;GAAG,OAAO;EAAG;EAClB;GAAC;GAAI;GAAG,OAAO;EAAI;EACnB;GAAC;GAAI;GAAG,OAAO;EAAI;EACnB;GAAC;GAAI;GAAG,OAAO,KAAK;EAAM;EAC1B;GAAC;GAAI;GAAG;EAAM;CAChB,GACA,OAAO,IACT;AACF;AAEA,UAAU,QAAQ,SAAmB,QAAmC;CACtE,IAAI,QAAQ,SAAS,aACnB,MAAM,IAAI,MAAM,wDAAwD;CAE1E,MAAM,YAAY,OAAO,OAAO,OAAO;CACvC,MAAM;CACN,MAAM,OAAO,IAAI;EACf;GAAC;GAAG;GAAG;EAAa;EACpB;GAAC;GAAG;GAAG,QAAQ;EAAM;EACrB;GAAC;GAAI;GAAG,QAAQ;EAAM;EACtB;GAAC;GAAI;GAAG,UAAU;EAAM;EACxB;GAAC;GAAI;GAAG,YAAY,MAAM;EAAC;CAC7B,CAAC;AACH"}
package/dist/utils.d.mts CHANGED
@@ -1,12 +1,26 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
3
  import { KeyUsed, SecretInput, SecretKeys, UndecryptableCredentialError, decrypt, decryptCredential, decryptWithKey, encrypt } from "./utils/encrypt.mjs";
4
+ import { Env, detectPublicBaseUrl, normalizeOrigin } from "./utils/public-origin.mjs";
4
5
  import { hmacSha256, randomToken, sha256, timingSafeEqualString } from "./utils/hash.mjs";
5
- import { HttpError, HttpRequestOptions, HttpTextOptions, httpJson, httpText } from "./utils/http.mjs";
6
- import { baselinePath, diffPath, screenshotPath, storybookDir, storybookZipPath } from "./paths.mjs";
6
+ import { HttpError, HttpRequestOptions, HttpTextOptions, httpBytes, httpJson, httpText } from "./utils/http.mjs";
7
+ import { baselinePath, catalogPath, contentDir, contentPath, designRenderPath, diffPath, isContentPath, modeSegment, screenshotPath, storybookDir, storybookZipPath } from "./paths.mjs";
8
+ import { AdaptiveConcurrency, AdaptiveOptions, Observation, isTimeoutError } from "./utils/adaptive-concurrency.mjs";
9
+ import { detectCaptureEnvironment, systemFontsHash } from "./utils/environment.mjs";
10
+ import { RetryConnectOptions, isRetryableConnectError, retryConnect } from "./utils/connect-retry.mjs";
11
+ import { BrowserProbe, FONT_PROBE_FAMILIES, inPageProbe, remoteEnvironment } from "./utils/remote-environment.mjs";
12
+ import { storybookBase } from "./utils/storybook-url.mjs";
13
+ import { DEFAULT_STORYBOOK_URL_TTL, MAX_STORYBOOK_URL_TTL, MIN_CAPTURES_PER_SLICE, MIN_STORYBOOK_URL_TTL, MIN_STORYBOOK_URL_TTL_OVERRIDE, PER_CAPTURE_BUDGET_MS, STORYBOOK_TOKEN_PREFIX, STORYBOOK_TOKEN_SOURCE, STORYBOOK_URL_TTL_GRACE, SignStorybookTokenInput, StorybookTokenClaims, StorybookTokenFailure, StorybookTokenResult, assertStorybookUrlTtl, signStorybookToken, storybookTokenPath, storybookUrlTtl, storybookUrlTtlOverrideError, verifyStorybookToken } from "./utils/storybook-token.mjs";
14
+ import { SessionGate, createSessionGate, sessionGateFor } from "./utils/session-gate.mjs";
15
+ import { storeScreenshot } from "./utils/screenshot-store.mjs";
16
+ import { PageLimiter, PageLimiterOptions, createPageLimiter } from "./utils/page-limiter.mjs";
17
+ import { mapAdaptive } from "./utils/map-adaptive.mjs";
18
+ import { chunk, mapLimit } from "./utils/map-limit.mjs";
19
+ import { CaptureHostSummary, DEFAULT_RECYCLE_BROWSER_EVERY, HostResources, describeCaptureHost, describeSizing, detectResources, engineWeight, maxPageConcurrency, recommendedBuildConcurrency, recommendedNavigationTimeoutMs, recommendedPageConcurrency } from "./utils/resources.mjs";
7
20
  import { MIME_TYPES, mimeFor } from "./utils/mime.mjs";
8
21
  import { isBlockedTarget, isPathSafe, isSafeSegment } from "./utils/path-security.mjs";
9
22
  import { redactSecrets, sanitizeErrorText } from "./utils/redact.mjs";
10
23
  import { TimingMap, addTiming, roundedTimings, runWithTimings, timed } from "./utils/timing.mjs";
11
24
  import { slugify, ulid } from "./utils/ulid.mjs";
12
- export { HttpError, type HttpRequestOptions, type HttpTextOptions, type KeyUsed, MIME_TYPES, type SecretInput, type SecretKeys, type TimingMap, UndecryptableCredentialError, addTiming, baselinePath, decrypt, decryptCredential, decryptWithKey, diffPath, encrypt, hmacSha256, httpJson, httpText, isBlockedTarget, isPathSafe, isSafeSegment, mimeFor, randomToken, redactSecrets, roundedTimings, runWithTimings, sanitizeErrorText, screenshotPath, sha256, slugify, storybookDir, storybookZipPath, timed, timingSafeEqualString, ulid };
25
+ import { ZipSource, zipStream } from "./utils/zip-write.mjs";
26
+ export { AdaptiveConcurrency, type AdaptiveOptions, type BrowserProbe, type CaptureHostSummary, DEFAULT_RECYCLE_BROWSER_EVERY, DEFAULT_STORYBOOK_URL_TTL, type Env, FONT_PROBE_FAMILIES, type HostResources, HttpError, type HttpRequestOptions, type HttpTextOptions, type KeyUsed, MAX_STORYBOOK_URL_TTL, MIME_TYPES, MIN_CAPTURES_PER_SLICE, MIN_STORYBOOK_URL_TTL, MIN_STORYBOOK_URL_TTL_OVERRIDE, type Observation, PER_CAPTURE_BUDGET_MS, type PageLimiter, type PageLimiterOptions, type RetryConnectOptions, STORYBOOK_TOKEN_PREFIX, STORYBOOK_TOKEN_SOURCE, STORYBOOK_URL_TTL_GRACE, type SecretInput, type SecretKeys, type SessionGate, type SignStorybookTokenInput, type StorybookTokenClaims, type StorybookTokenFailure, type StorybookTokenResult, type TimingMap, UndecryptableCredentialError, type ZipSource, addTiming, assertStorybookUrlTtl, baselinePath, catalogPath, chunk, contentDir, contentPath, createPageLimiter, createSessionGate, decrypt, decryptCredential, decryptWithKey, describeCaptureHost, describeSizing, designRenderPath, detectCaptureEnvironment, detectPublicBaseUrl, detectResources, diffPath, encrypt, engineWeight, hmacSha256, httpBytes, httpJson, httpText, inPageProbe, isBlockedTarget, isContentPath, isPathSafe, isRetryableConnectError, isSafeSegment, isTimeoutError, mapAdaptive, mapLimit, maxPageConcurrency, mimeFor, modeSegment, normalizeOrigin, randomToken, recommendedBuildConcurrency, recommendedNavigationTimeoutMs, recommendedPageConcurrency, redactSecrets, remoteEnvironment, retryConnect, roundedTimings, runWithTimings, sanitizeErrorText, screenshotPath, sessionGateFor, sha256, signStorybookToken, slugify, storeScreenshot, storybookBase, storybookDir, storybookTokenPath, storybookUrlTtl, storybookUrlTtlOverrideError, storybookZipPath, systemFontsHash, timed, timingSafeEqualString, ulid, verifyStorybookToken, zipStream };
package/dist/utils.mjs CHANGED
@@ -1,13 +1,27 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
+ import { hmacSha256, randomToken, sha256, timingSafeEqualString } from "./utils/hash.mjs";
5
+ import { DEFAULT_STORYBOOK_URL_TTL, MAX_STORYBOOK_URL_TTL, MIN_CAPTURES_PER_SLICE, MIN_STORYBOOK_URL_TTL, MIN_STORYBOOK_URL_TTL_OVERRIDE, PER_CAPTURE_BUDGET_MS, STORYBOOK_TOKEN_PREFIX, STORYBOOK_TOKEN_SOURCE, STORYBOOK_URL_TTL_GRACE, assertStorybookUrlTtl, signStorybookToken, storybookTokenPath, storybookUrlTtl, storybookUrlTtlOverrideError, verifyStorybookToken } from "./utils/storybook-token.mjs";
4
6
  import { redactSecrets, sanitizeErrorText } from "./utils/redact.mjs";
5
7
  import { UndecryptableCredentialError, decrypt, decryptCredential, decryptWithKey, encrypt } from "./utils/encrypt.mjs";
6
8
  import { slugify, ulid } from "./utils/ulid.mjs";
7
- import { hmacSha256, randomToken, sha256, timingSafeEqualString } from "./utils/hash.mjs";
8
9
  import { addTiming, roundedTimings, runWithTimings, timed } from "./utils/timing.mjs";
9
10
  import { isBlockedTarget, isPathSafe, isSafeSegment } from "./utils/path-security.mjs";
10
- import { baselinePath, diffPath, screenshotPath, storybookDir, storybookZipPath } from "./paths.mjs";
11
- import { HttpError, httpJson, httpText } from "./utils/http.mjs";
11
+ import { baselinePath, catalogPath, contentDir, contentPath, designRenderPath, diffPath, isContentPath, modeSegment, screenshotPath, storybookDir, storybookZipPath } from "./paths.mjs";
12
+ import { storeScreenshot } from "./utils/screenshot-store.mjs";
13
+ import { chunk, mapLimit } from "./utils/map-limit.mjs";
14
+ import { DEFAULT_RECYCLE_BROWSER_EVERY, describeCaptureHost, describeSizing, detectResources, engineWeight, maxPageConcurrency, recommendedBuildConcurrency, recommendedNavigationTimeoutMs, recommendedPageConcurrency } from "./utils/resources.mjs";
15
+ import { detectPublicBaseUrl, normalizeOrigin } from "./utils/public-origin.mjs";
16
+ import { zipStream } from "./utils/zip-write.mjs";
17
+ import { HttpError, httpBytes, httpJson, httpText } from "./utils/http.mjs";
18
+ import { AdaptiveConcurrency, isTimeoutError } from "./utils/adaptive-concurrency.mjs";
19
+ import { detectCaptureEnvironment, systemFontsHash } from "./utils/environment.mjs";
20
+ import { isRetryableConnectError, retryConnect } from "./utils/connect-retry.mjs";
21
+ import { FONT_PROBE_FAMILIES, inPageProbe, remoteEnvironment } from "./utils/remote-environment.mjs";
22
+ import { storybookBase } from "./utils/storybook-url.mjs";
23
+ import { createSessionGate, sessionGateFor } from "./utils/session-gate.mjs";
24
+ import { mapAdaptive } from "./utils/map-adaptive.mjs";
25
+ import { createPageLimiter } from "./utils/page-limiter.mjs";
12
26
  import { MIME_TYPES, mimeFor } from "./utils/mime.mjs";
13
- export { HttpError, MIME_TYPES, UndecryptableCredentialError, addTiming, baselinePath, decrypt, decryptCredential, decryptWithKey, diffPath, encrypt, hmacSha256, httpJson, httpText, isBlockedTarget, isPathSafe, isSafeSegment, mimeFor, randomToken, redactSecrets, roundedTimings, runWithTimings, sanitizeErrorText, screenshotPath, sha256, slugify, storybookDir, storybookZipPath, timed, timingSafeEqualString, ulid };
27
+ export { AdaptiveConcurrency, DEFAULT_RECYCLE_BROWSER_EVERY, DEFAULT_STORYBOOK_URL_TTL, FONT_PROBE_FAMILIES, HttpError, MAX_STORYBOOK_URL_TTL, MIME_TYPES, MIN_CAPTURES_PER_SLICE, MIN_STORYBOOK_URL_TTL, MIN_STORYBOOK_URL_TTL_OVERRIDE, PER_CAPTURE_BUDGET_MS, STORYBOOK_TOKEN_PREFIX, STORYBOOK_TOKEN_SOURCE, STORYBOOK_URL_TTL_GRACE, UndecryptableCredentialError, addTiming, assertStorybookUrlTtl, baselinePath, catalogPath, chunk, contentDir, contentPath, createPageLimiter, createSessionGate, decrypt, decryptCredential, decryptWithKey, describeCaptureHost, describeSizing, designRenderPath, detectCaptureEnvironment, detectPublicBaseUrl, detectResources, diffPath, encrypt, engineWeight, hmacSha256, httpBytes, httpJson, httpText, inPageProbe, isBlockedTarget, isContentPath, isPathSafe, isRetryableConnectError, isSafeSegment, isTimeoutError, mapAdaptive, mapLimit, maxPageConcurrency, mimeFor, modeSegment, normalizeOrigin, randomToken, recommendedBuildConcurrency, recommendedNavigationTimeoutMs, recommendedPageConcurrency, redactSecrets, remoteEnvironment, retryConnect, roundedTimings, runWithTimings, sanitizeErrorText, screenshotPath, sessionGateFor, sha256, signStorybookToken, slugify, storeScreenshot, storybookBase, storybookDir, storybookTokenPath, storybookUrlTtl, storybookUrlTtlOverrideError, storybookZipPath, systemFontsHash, timed, timingSafeEqualString, ulid, verifyStorybookToken, zipStream };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storyshelf/core",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "StoryShelf core: adapter interfaces, models, capture pipeline, diff, and retention (no HTTP).",
5
5
  "keywords": [
6
6
  "chromatic-alternative",
@@ -46,22 +46,14 @@
46
46
  "source": "./src/adapters/database.ts",
47
47
  "default": "./dist/adapter/database.mjs"
48
48
  },
49
+ "./adapter/design": {
50
+ "source": "./src/adapters/design.ts",
51
+ "default": "./dist/adapter/design.mjs"
52
+ },
49
53
  "./adapter/email-sender": {
50
54
  "source": "./src/adapters/email-sender.ts",
51
55
  "default": "./dist/adapter/email-sender.mjs"
52
56
  },
53
- "./adapter/git-host": {
54
- "source": "./src/adapters/git-host/index.ts",
55
- "default": "./dist/adapter/git-host.mjs"
56
- },
57
- "./adapter/git-host/comments": {
58
- "source": "./src/adapters/git-host/comments.ts",
59
- "default": "./dist/adapter/git-host/comments.mjs"
60
- },
61
- "./adapter/git-host/helpers": {
62
- "source": "./src/adapters/git-host/helpers.ts",
63
- "default": "./dist/adapter/git-host/helpers.mjs"
64
- },
65
57
  "./adapter/metadata": {
66
58
  "source": "./src/adapters/metadata.ts",
67
59
  "default": "./dist/adapter/metadata.mjs"
@@ -70,6 +62,10 @@
70
62
  "source": "./src/adapters/notifier/index.ts",
71
63
  "default": "./dist/adapter/notifier.mjs"
72
64
  },
65
+ "./adapter/oauth": {
66
+ "source": "./src/adapters/oauth.ts",
67
+ "default": "./dist/adapter/oauth.mjs"
68
+ },
73
69
  "./adapter/setup": {
74
70
  "source": "./src/adapters/setup.ts",
75
71
  "default": "./dist/adapter/setup.mjs"
@@ -82,6 +78,10 @@
82
78
  "source": "./src/adapters/webhook-events.ts",
83
79
  "default": "./dist/adapter/webhook-events.mjs"
84
80
  },
81
+ "./ai": {
82
+ "source": "./src/ai.ts",
83
+ "default": "./dist/ai.mjs"
84
+ },
85
85
  "./auth": {
86
86
  "source": "./src/auth.ts",
87
87
  "default": "./dist/auth.mjs"
@@ -98,6 +98,10 @@
98
98
  "source": "./src/diff/index.ts",
99
99
  "default": "./dist/diff.mjs"
100
100
  },
101
+ "./insights": {
102
+ "source": "./src/insights/index.ts",
103
+ "default": "./dist/insights.mjs"
104
+ },
101
105
  "./logger": {
102
106
  "source": "./src/logger.ts",
103
107
  "default": "./dist/logger.mjs"
@@ -154,19 +158,20 @@
154
158
  "./adapter/capture-queue": "./dist/adapter/capture-queue.mjs",
155
159
  "./adapter/capture-runner": "./dist/adapter/capture-runner.mjs",
156
160
  "./adapter/database": "./dist/adapter/database.mjs",
161
+ "./adapter/design": "./dist/adapter/design.mjs",
157
162
  "./adapter/email-sender": "./dist/adapter/email-sender.mjs",
158
- "./adapter/git-host": "./dist/adapter/git-host.mjs",
159
- "./adapter/git-host/comments": "./dist/adapter/git-host/comments.mjs",
160
- "./adapter/git-host/helpers": "./dist/adapter/git-host/helpers.mjs",
161
163
  "./adapter/metadata": "./dist/adapter/metadata.mjs",
162
164
  "./adapter/notifier": "./dist/adapter/notifier.mjs",
165
+ "./adapter/oauth": "./dist/adapter/oauth.mjs",
163
166
  "./adapter/setup": "./dist/adapter/setup.mjs",
164
167
  "./adapter/storage": "./dist/adapter/storage.mjs",
165
168
  "./adapter/webhook-events": "./dist/adapter/webhook-events.mjs",
169
+ "./ai": "./dist/ai.mjs",
166
170
  "./auth": "./dist/auth.mjs",
167
171
  "./capture": "./dist/capture.mjs",
168
172
  "./config": "./dist/config.mjs",
169
173
  "./diff": "./dist/diff.mjs",
174
+ "./insights": "./dist/insights.mjs",
170
175
  "./logger": "./dist/logger.mjs",
171
176
  "./models": "./dist/models.mjs",
172
177
  "./orm": "./dist/orm.mjs",
@@ -192,31 +197,38 @@
192
197
  "prepublishOnly": "nub run build",
193
198
  "test": "vitest run",
194
199
  "test:coverage": "vitest run --coverage",
195
- "test:watch": "vitest"
200
+ "test:watch": "vitest",
201
+ "test:flake": "vitest run --repeats=20 --maxWorkers=1 --no-file-parallelism src/utils/map-limit.test.ts src/utils/session-gate.test.ts src/utils/page-limiter.test.ts src/utils/adaptive-concurrency.test.ts src/capture/rediff.test.ts src/models/build.test.ts src/models/design-credentials.test.ts"
196
202
  },
197
203
  "dependencies": {
198
204
  "@opentelemetry/api": "^1.9.0",
199
- "@storyshelf/affected": "0.6.1",
205
+ "@storyshelf/affected": "0.7.0",
206
+ "@storyshelf/image": "0.7.0",
207
+ "axe-core": "4.13.0",
200
208
  "drizzle-orm": "^0.44.0",
201
209
  "pino": "^10.3.1",
202
- "pixelmatch": "^7.1.0",
203
- "pngjs": "^7.0.0",
204
210
  "unzipper": "0.12.5",
205
211
  "zod": "^4.2.0"
206
212
  },
207
213
  "devDependencies": {
214
+ "@types/jsdom": "^30.0.0",
208
215
  "@types/node": "^26.0.0",
209
216
  "@types/pngjs": "^6.0.5",
210
217
  "@types/unzipper": "0.10.11",
211
218
  "@vitest/coverage-v8": "^4.0.0",
212
219
  "adm-zip": "^0.6.1",
220
+ "jsdom": "^30.0.1",
213
221
  "oxfmt": "^0.65.0",
214
222
  "oxlint": "^1.80.0",
215
223
  "oxlint-tsgolint": "^7.0.2001",
224
+ "pngjs": "^7.0.0",
216
225
  "tsdown": "^0.22.14",
217
226
  "typescript": "^7.0.2",
218
227
  "vitest": "^5.0.0"
219
228
  },
229
+ "engines": {
230
+ "node": ">=24"
231
+ },
220
232
  "jsr": {
221
233
  "runtimeCompat": {
222
234
  "node": true,
@@ -1 +0,0 @@
1
- {"version":3,"file":"capture-runner.mjs","names":[],"sources":["../../src/adapters/capture-runner.ts"],"sourcesContent":["/**\n * Capture-runner adapter interface: render story screenshots for a build.\n */\nimport type { Logger } from \"pino\";\nimport type { StoryEntry, StorySourceAdapter, Viewport } from \"../capture/adapter.ts\";\nimport type { Adapter } from \"./metadata.ts\";\n\nexport type { JobStatus } from \"./capture-queue.ts\";\nexport type { StoryEntry, StorySourceAdapter, Viewport } from \"../capture/adapter.ts\";\n\n/** A screenshot produced by a capture renderer. */\nexport interface RenderedSnapshot {\n /** The rendered story (echoed back from the render request). */\n story: StoryEntry;\n /** Viewport name the screenshot was captured at. */\n viewportName: string;\n /** Exact viewport dimensions captured at; falls back to the project list lookup in the pipeline. */\n viewport?: Viewport;\n /** PNG screenshot bytes. */\n screenshot: Buffer;\n}\n\n/** A story/viewport that a renderer could not capture. */\nexport interface RenderFailure {\n /** Story that failed to render. */\n storyId: string;\n /** Viewport that failed to render. */\n viewportName: string;\n /** Error message. */\n error: string;\n}\n\n/** The outcome of a render request. */\nexport interface RenderResult {\n /** Screenshots the renderer produced successfully. */\n captures: RenderedSnapshot[];\n /** Story/viewport pairs the renderer could not capture. */\n failures: RenderFailure[];\n}\n\n/**\n * A pure capture renderer.\n *\n * Adapters implementing `CaptureRunner` render screenshots from an\n * already-extracted Storybook directory and return PNG buffers. They are\n * intentionally pure: they perform **no** database, storage, or build-state\n * management. Loading the build, extracting the uploaded archive, persisting\n * snapshots/baselines/diffs, and advancing build status are the capture\n * orchestrator's job (see `capture/orchestrator.ts`), keeping every adapter\n * implementation free of server concerns.\n */\nexport type BrowserName = \"chromium\" | \"firefox\" | \"webkit\" | \"chrome\";\n\n/** Browser names accepted for capture rendering (Chromium default). */\nexport const BROWSER_NAMES = [\"chromium\", \"firefox\", \"webkit\", \"chrome\"] as const;\n\nexport interface CaptureRunner extends Adapter<{\n readonly category: \"capture-runner\";\n readonly supportedBrowsers?: readonly BrowserName[];\n}> {\n /**\n * Render configured viewports for the given stories of an extracted\n * Storybook and return the screenshot buffers.\n *\n * @param input - Render request with the extracted Storybook directory.\n */\n render(input: {\n /** Build being captured, used to correlate cancels with in-flight work. */\n buildId: string;\n /** Root of the already-extracted Storybook build. */\n storybookDir: string;\n /** Stories to render. */\n stories: StoryEntry[];\n /** Viewports to capture. */\n viewports: Viewport[];\n /** Optional logger for render-time diagnostics. */\n logger?: Logger;\n /** Whether to execute Storybook play functions before screenshot. */\n executePlay?: boolean;\n /** Timeout for play function execution in ms. */\n playTimeoutMs?: number;\n /** Whether to run a11y checks (axe) before screenshot; annotated as non-blocking. */\n runA11y?: boolean;\n /** Browser to use for rendering (chromium default). */\n browser?: BrowserName;\n /**\n * Test/extension seam: override the story source adapter (defaults to\n * `StorybookAdapter`). Only the renderer uses it; discovery stays the\n * orchestrator's job.\n */\n adapter?: StorySourceAdapter;\n }): Promise<RenderResult>;\n\n /** Cancel a pending or in-flight render for a build. */\n cancel(buildId: string): Promise<void>;\n}\n"],"mappings":";;;;;AAsDA,MAAa,gBAAgB;CAAC;CAAY;CAAW;CAAU;AAAQ"}
@@ -1,41 +0,0 @@
1
- import __tsdown_shims_path from 'node:path';
2
- import __tsdown_shims_url from 'node:url';
3
- import { Logger } from "pino";
4
- //#region src/adapters/git-host/comments.d.ts
5
- /** A review thread (PR or MR) hosting a single StoryShelf comment. */
6
- interface ReviewThread {
7
- /** List existing comments as id/body pairs. */
8
- list(): Promise<{
9
- id: string | number;
10
- body: string;
11
- }[]>;
12
- /** Replace the body of an existing comment, returning its id. */
13
- update(id: string | number, body: string): Promise<string>;
14
- /** Create a comment, returning its id. */
15
- create(body: string): Promise<string>;
16
- }
17
- /** Dependencies for an idempotent review-comment upsert. */
18
- interface UpsertReviewCommentOptions {
19
- /** Canonical build/review URL — anchors the idempotency marker. */
20
- url: string;
21
- /** Markdown body appended below the marker. */
22
- markdown: string;
23
- /** Known thread number, skipping the lookup when provided. */
24
- prNumber?: number;
25
- /** Commit SHA used for the thread lookup and log context. */
26
- sha: string;
27
- logger?: Logger;
28
- /** Resolve the thread number for the commit (PR number or MR iid). */
29
- resolveNumber: () => Promise<number | undefined>;
30
- /** Open the thread's comment store once the number is known. */
31
- thread: (number: number) => ReviewThread;
32
- }
33
- /**
34
- * Create or update the single StoryShelf review comment for a build,
35
- * idempotent via the url marker. Returns the comment id, or `""` when no
36
- * review thread exists for the commit.
37
- */
38
- declare function upsertReviewComment(opts: UpsertReviewCommentOptions): Promise<string>;
39
- //#endregion
40
- export { ReviewThread, UpsertReviewCommentOptions, upsertReviewComment };
41
- //# sourceMappingURL=comments.d.mts.map