@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
@@ -2,7 +2,7 @@ import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
4
  import { describe, expect, it } from "vitest";
5
- //#region src/test-helpers/queue-contract.ts
5
+ // src/test-helpers/queue-contract.ts
6
6
  /**
7
7
  * Published queue contract suite for first- and third-party adapters.
8
8
  *
@@ -252,7 +252,6 @@ function cancelCases(make) {
252
252
  expect(await queue.cancel("b-contract-unknown")).toBe(false);
253
253
  });
254
254
  }
255
- //#endregion
256
255
  export { queueContractSuite };
257
256
 
258
257
  //# sourceMappingURL=queue-contract.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 { DatabaseAdapter } from "../adapter/database.mjs";
4
- //#region src/test-helpers/queue-multi-instance.d.ts
5
4
  /** A set-up database the instances of one case share. */
6
5
  type SharedDatabaseFactory = () => DatabaseAdapter | Promise<DatabaseAdapter>;
7
6
  /** Options of {@link databaseQueueMultiInstanceSuite}. */
@@ -15,6 +14,5 @@ interface MultiInstanceOptions {
15
14
  }
16
15
  /** Run the multi-instance suite against databases from `makeDb`. */
17
16
  declare function databaseQueueMultiInstanceSuite(label: string, makeDb: SharedDatabaseFactory, options?: MultiInstanceOptions): void;
18
- //#endregion
19
17
  export { MultiInstanceOptions, SharedDatabaseFactory, databaseQueueMultiInstanceSuite };
20
18
  //# sourceMappingURL=queue-multi-instance.d.mts.map
@@ -5,7 +5,7 @@ import { CaptureJobModel, attemptRowId } from "../models/capture-job.mjs";
5
5
  import { LEASE_EXHAUSTED_ERROR } from "../capture/db-queue/claim.mjs";
6
6
  import { createDatabaseCaptureQueue } from "../capture/db-queue/index.mjs";
7
7
  import { describe, expect, it } from "vitest";
8
- //#region src/test-helpers/queue-multi-instance.ts
8
+ // src/test-helpers/queue-multi-instance.ts
9
9
  /**
10
10
  * Multi-instance suite for the database capture queue: several queue instances (one per simulated
11
11
  * app instance) share ONE database, the way horizontally scaled app instances do. Database packages
@@ -200,7 +200,6 @@ function cancelAndKindCases(makeDb, size, timeoutMs) {
200
200
  expect((await capture.queues[0].status(buildId))?.status).toBe("completed");
201
201
  }, timeoutMs);
202
202
  }
203
- //#endregion
204
203
  export { databaseQueueMultiInstanceSuite };
205
204
 
206
205
  //# sourceMappingURL=queue-multi-instance.mjs.map
@@ -1,11 +1,9 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
3
  import { CaptureRunner } from "../adapter/capture-runner.mjs";
4
- //#region src/test-helpers/runner-contract.d.ts
5
4
  /** Build the adapter under test (sync or async factories both work). */
6
5
  type RunnerFactory = () => CaptureRunner | Promise<CaptureRunner>;
7
6
  /** Run the runner contract against a factory. */
8
7
  declare function runnerContractSuite(label: string, make: RunnerFactory): void;
9
- //#endregion
10
8
  export { RunnerFactory, runnerContractSuite };
11
9
  //# sourceMappingURL=runner-contract.d.mts.map
@@ -3,7 +3,7 @@ import "node:url";
3
3
  import.meta.url;
4
4
  import { isCaptureTarget } from "../adapters/capture-target.mjs";
5
5
  import { describe, expect, it } from "vitest";
6
- //#region src/test-helpers/runner-contract.ts
6
+ // src/test-helpers/runner-contract.ts
7
7
  /**
8
8
  * Published runner contract suite for first- and third-party adapters.
9
9
  *
@@ -37,7 +37,6 @@ function runnerContractSuite(label, make) {
37
37
  });
38
38
  });
39
39
  }
40
- //#endregion
41
40
  export { runnerContractSuite };
42
41
 
43
42
  //# sourceMappingURL=runner-contract.mjs.map
@@ -2,7 +2,7 @@ import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
4
  import { getTableColumns } from "drizzle-orm";
5
- //#region src/test-helpers/sql-chunks.ts
5
+ // src/test-helpers/sql-chunks.ts
6
6
  /** Flatten the string parts of a drizzle SQL chunk into a single string. */
7
7
  function textOf(chunk) {
8
8
  if (chunk === void 0 || !Array.isArray(chunk.value) || !chunk.value.every((part) => typeof part === "string")) return;
@@ -24,6 +24,7 @@ function matchChunk(chunks, row, table) {
24
24
  const text = chunks.map((c) => textOf(c) ?? "").join("");
25
25
  if (/is not null/iu.test(text)) return isNullMatches(chunks, row, table, true);
26
26
  if (/is null/iu.test(text)) return isNullMatches(chunks, row, table, false);
27
+ if (text.includes(" <> ")) return !eqMatches(chunks, row, table);
27
28
  if (text.includes(" like ")) return likeMatches(chunks, row, table);
28
29
  if (text.includes(" in ")) return inArrayMatches(chunks, row, table);
29
30
  if (text.includes(" >= ")) return !ltMatches(chunks, row, table);
@@ -155,7 +156,6 @@ function columnKey(table, dbName) {
155
156
  for (const [property, column] of Object.entries(getTableColumns(table))) if (column.name === dbName) return property;
156
157
  return dbName;
157
158
  }
158
- //#endregion
159
159
  export { orderRows, whereMatches };
160
160
 
161
161
  //# sourceMappingURL=sql-chunks.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sql-chunks.mjs","names":[],"sources":["../../src/test-helpers/sql-chunks.ts"],"sourcesContent":["import { getTableColumns, type SQL, type Table } from \"drizzle-orm\";\n\n/* eslint-disable require-await, no-unnecessary-type-assertion, no-unnecessary-type-parameters, non-nullable-type-assertion-style */\n\n/** A drizzle SQL chunk inspected for matching and ordering. */\nexport interface SqlChunk {\n value?: unknown;\n name?: string;\n table?: unknown;\n brand?: unknown;\n queryChunks?: SqlChunk[];\n}\n\n/** Flatten the string parts of a drizzle SQL chunk into a single string. */\nfunction textOf(chunk: SqlChunk | undefined): string | undefined {\n if (\n chunk === undefined ||\n !Array.isArray(chunk.value) ||\n !chunk.value.every((part) => typeof part === \"string\")\n ) {\n return undefined;\n }\n return chunk.value.join(\"\");\n}\n\n/** Test whether an in-memory row satisfies a drizzle where-clause. */\nexport function whereMatches(where: SQL, row: Record<string, unknown>, table: Table): boolean {\n let current = where.queryChunks as unknown as SqlChunk[];\n let wrapped = current[1]?.queryChunks;\n while (wrapped !== undefined && textOf(current[0]) === \"(\" && textOf(current.at(-1)) === \")\") {\n current = wrapped;\n wrapped = current[1]?.queryChunks;\n }\n // Drizzle's `and(singleCondition)` emits the condition directly, without\n // the enclosing parens produced for two or more clauses, so unwrap it.\n if (current.length === 1 && current[0]?.queryChunks !== undefined) {\n current = current[0].queryChunks as unknown as SqlChunk[];\n }\n if (current.some((chunk) => textOf(chunk)?.trim() === \"and\")) {\n return current\n .filter((chunk) => textOf(chunk) === undefined)\n .every((chunk) => matchChunk(chunk.queryChunks ?? [], row, table));\n }\n return matchChunk(current, row, table);\n}\n\nfunction matchChunk(chunks: SqlChunk[], row: Record<string, unknown>, table: Table): boolean {\n const text = chunks.map((c) => textOf(c) ?? \"\").join(\"\");\n if (/is not null/iu.test(text)) {\n return isNullMatches(chunks, row, table, true);\n }\n if (/is null/iu.test(text)) {\n return isNullMatches(chunks, row, table, false);\n }\n if (text.includes(\" like \")) {\n return likeMatches(chunks, row, table);\n }\n if (text.includes(\" in \")) {\n return inArrayMatches(chunks, row, table);\n }\n if (text.includes(\" >= \")) {\n return !ltMatches(chunks, row, table);\n }\n if (text.includes(\" <= \")) {\n return lteMatches(chunks, row, table);\n }\n if (text.includes(\" < \")) {\n return ltMatches(chunks, row, table);\n }\n return eqMatches(chunks, row, table);\n}\n\n/** Match `is null` / `is not null` predicates (no value argument). */\nfunction isNullMatches(\n chunks: SqlChunk[],\n row: Record<string, unknown>,\n table: Table,\n negated: boolean,\n): boolean {\n let columnName: string | undefined;\n for (const chunk of chunks) {\n if (typeof chunk.name === \"string\" && chunk.table !== undefined) {\n columnName = chunk.name;\n }\n }\n if (columnName === undefined) {\n return false;\n }\n const cell = row[columnKey(table, columnName)];\n const missing = cell === null || cell === undefined;\n return negated ? !missing : missing;\n}\n\nfunction eqMatches(chunks: SqlChunk[], row: Record<string, unknown>, table: Table): boolean {\n let columnName: string | undefined;\n let argument: unknown;\n for (const chunk of chunks) {\n if (typeof chunk.name === \"string\" && chunk.table !== undefined) {\n columnName = chunk.name;\n } else if (\"brand\" in chunk) {\n argument = chunk.value;\n }\n }\n if (columnName === undefined) {\n return false;\n }\n return row[columnKey(table, columnName)] === argument;\n}\n\n/** Match `column like 'pattern'`: `%` is any run of characters, `_` any one; everything else literal. */\nfunction likeMatches(chunks: SqlChunk[], row: Record<string, unknown>, table: Table): boolean {\n let columnName: string | undefined;\n let pattern: unknown;\n for (const chunk of chunks as unknown[]) {\n if (typeof chunk === \"string\") {\n pattern = chunk;\n } else if (chunk !== null && typeof chunk === \"object\") {\n const node = chunk as SqlChunk;\n if (typeof node.name === \"string\" && node.table !== undefined) {\n columnName = node.name;\n } else if (\"brand\" in node) {\n pattern = node.value;\n }\n }\n }\n const cell = columnName === undefined ? undefined : row[columnKey(table, columnName)];\n if (typeof cell !== \"string\" || typeof pattern !== \"string\") {\n return false;\n }\n const source = pattern.replaceAll(/[.*+?^${}()|[\\]\\\\]/gu, String.raw`\\$&`);\n return new RegExp(`^${source.replaceAll(\"%\", \".*\").replaceAll(\"_\", \".\")}$`, \"su\").test(cell);\n}\n\n/* eslint-disable complexity, max-depth -- handles drizzle's varied chunk shapes */\nfunction inArrayMatches(chunks: SqlChunk[], row: Record<string, unknown>, table: Table): boolean {\n let columnName: string | undefined;\n const values: unknown[] = [];\n const collect = (nodes: unknown[]): void => {\n for (const raw of nodes as SqlChunk[]) {\n const chunk = raw as SqlChunk & Record<string, unknown>;\n // Handle array-like chunk (inArray values stored as array of chunks)\n if (\n Array.isArray(chunk) ||\n (chunk && typeof chunk === \"object\" && Object.keys(chunk).every((k) => /^\\d+$/u.test(k)))\n ) {\n collect(Object.values(chunk as unknown as Record<string, unknown>) as unknown[]);\n continue;\n }\n if (typeof chunk.name === \"string\" && chunk.table !== undefined) {\n columnName = chunk.name as string;\n }\n if (\"brand\" in chunk && (chunk as Record<string, unknown>)[\"value\"] !== undefined) {\n const val = (chunk as Record<string, unknown>)[\"value\"];\n if (Array.isArray(val)) {\n values.push(...(val as unknown[]));\n } else {\n values.push(val);\n }\n }\n if (chunk.queryChunks) {\n collect(chunk.queryChunks as unknown[]);\n }\n const val = (chunk as Record<string, unknown>)[\"value\"];\n if (Array.isArray(val)) {\n for (const item of val as unknown[]) {\n if (\n item &&\n typeof item === \"object\" &&\n \"queryChunks\" in (item as Record<string, unknown>)\n ) {\n collect(((item as Record<string, unknown>)[\"queryChunks\"] as unknown[]) ?? []);\n }\n if (item && typeof item === \"object\" && \"value\" in (item as Record<string, unknown>)) {\n const iv = (item as Record<string, unknown>)[\"value\"];\n if (iv !== undefined) {\n values.push(iv);\n }\n }\n if (typeof item === \"string\") {\n values.push(item);\n }\n }\n }\n }\n };\n collect(chunks as unknown[]);\n if (columnName === undefined) {\n return false;\n }\n const key = columnKey(table, columnName);\n return values.includes(row[key]);\n}\n/* eslint-enable complexity, max-depth */\n\n/** `column <= value`: the cell is present and not greater than the argument. */\nfunction lteMatches(chunks: SqlChunk[], row: Record<string, unknown>, table: Table): boolean {\n if (ltMatches(chunks, row, table)) {\n return true;\n }\n return eqMatches(chunks, row, table);\n}\n\nfunction ltMatches(chunks: SqlChunk[], row: Record<string, unknown>, table: Table): boolean {\n let columnName: string | undefined;\n let argument: unknown;\n for (const chunk of chunks) {\n if (typeof chunk.name === \"string\" && chunk.table !== undefined) {\n columnName = chunk.name;\n } else if (\"brand\" in chunk) {\n argument = chunk.value;\n }\n }\n if (columnName === undefined) {\n return false;\n }\n const key = columnKey(table, columnName);\n const cell = row[key];\n if (typeof cell === \"string\" && typeof argument === \"string\") {\n return cell < argument;\n }\n if (typeof cell === \"number\" && typeof argument === \"number\") {\n return cell < argument;\n }\n return String(cell) < String(argument);\n}\n\nfunction compareCells(left: unknown, right: unknown): number {\n if (typeof left === \"string\" && typeof right === \"string\") {\n if (left === right) {\n return 0;\n }\n return left < right ? -1 : 1;\n }\n if (typeof left === \"number\" && typeof right === \"number\") {\n return left - right;\n }\n const leftText = String(left);\n const rightText = String(right);\n if (leftText === rightText) {\n return 0;\n }\n return leftText < rightText ? -1 : 1;\n}\n\n/** Collect every raw string part of a drizzle SQL chunk tree. */\nfunction sqlText(nodes: SqlChunk[]): string {\n return nodes\n .map((node) => {\n const own = textOf(node) ?? \"\";\n const nested = node.queryChunks ? sqlText(node.queryChunks as unknown as SqlChunk[]) : \"\";\n return own + nested;\n })\n .join(\"\");\n}\n\n/** Find the ordered column reference in a drizzle order-by expression. */\nfunction findOrderColumn(nodes: SqlChunk[]): string | undefined {\n for (const node of nodes) {\n if (typeof node.name === \"string\" && node.table !== undefined) {\n return node.name;\n }\n if (node.queryChunks) {\n const nested = findOrderColumn(node.queryChunks as unknown as SqlChunk[]);\n if (nested !== undefined) {\n return nested;\n }\n }\n }\n return undefined;\n}\n\n/** Sort rows per a drizzle order-by expression (single-column asc/desc). */\nexport function orderRows(rows: unknown[], orderBy: SQL, table: Table): unknown[] {\n const chunks = orderBy.queryChunks as unknown as SqlChunk[];\n const columnName = findOrderColumn(chunks);\n if (columnName === undefined) {\n return rows;\n }\n const key = columnKey(table, columnName);\n const descending = /desc/iu.test(sqlText(chunks));\n return rows.toSorted((left, right) => {\n const order = compareCells(\n (left as Record<string, unknown>)[key],\n (right as Record<string, unknown>)[key],\n );\n return descending ? -order : order;\n });\n}\n\nfunction columnKey(table: Table, dbName: string): string {\n for (const [property, column] of Object.entries(getTableColumns(table))) {\n if (column.name === dbName) {\n return property;\n }\n }\n return dbName;\n}\n/* eslint-enable require-await, no-unnecessary-type-assertion, no-unnecessary-type-parameters, non-nullable-type-assertion-style */\n"],"mappings":"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"}
1
+ {"version":3,"file":"sql-chunks.mjs","names":[],"sources":["../../src/test-helpers/sql-chunks.ts"],"sourcesContent":["import { getTableColumns, type SQL, type Table } from \"drizzle-orm\";\n\n/* eslint-disable require-await, no-unnecessary-type-assertion, no-unnecessary-type-parameters, non-nullable-type-assertion-style */\n\n/** A drizzle SQL chunk inspected for matching and ordering. */\nexport interface SqlChunk {\n value?: unknown;\n name?: string;\n table?: unknown;\n brand?: unknown;\n queryChunks?: SqlChunk[];\n}\n\n/** Flatten the string parts of a drizzle SQL chunk into a single string. */\nfunction textOf(chunk: SqlChunk | undefined): string | undefined {\n if (\n chunk === undefined ||\n !Array.isArray(chunk.value) ||\n !chunk.value.every((part) => typeof part === \"string\")\n ) {\n return undefined;\n }\n return chunk.value.join(\"\");\n}\n\n/** Test whether an in-memory row satisfies a drizzle where-clause. */\nexport function whereMatches(where: SQL, row: Record<string, unknown>, table: Table): boolean {\n let current = where.queryChunks as unknown as SqlChunk[];\n let wrapped = current[1]?.queryChunks;\n while (wrapped !== undefined && textOf(current[0]) === \"(\" && textOf(current.at(-1)) === \")\") {\n current = wrapped;\n wrapped = current[1]?.queryChunks;\n }\n // Drizzle's `and(singleCondition)` emits the condition directly, without\n // the enclosing parens produced for two or more clauses, so unwrap it.\n if (current.length === 1 && current[0]?.queryChunks !== undefined) {\n current = current[0].queryChunks as unknown as SqlChunk[];\n }\n if (current.some((chunk) => textOf(chunk)?.trim() === \"and\")) {\n return current\n .filter((chunk) => textOf(chunk) === undefined)\n .every((chunk) => matchChunk(chunk.queryChunks ?? [], row, table));\n }\n return matchChunk(current, row, table);\n}\n\nfunction matchChunk(chunks: SqlChunk[], row: Record<string, unknown>, table: Table): boolean {\n const text = chunks.map((c) => textOf(c) ?? \"\").join(\"\");\n if (/is not null/iu.test(text)) {\n return isNullMatches(chunks, row, table, true);\n }\n if (/is null/iu.test(text)) {\n return isNullMatches(chunks, row, table, false);\n }\n if (text.includes(\" <> \")) {\n return !eqMatches(chunks, row, table);\n }\n if (text.includes(\" like \")) {\n return likeMatches(chunks, row, table);\n }\n if (text.includes(\" in \")) {\n return inArrayMatches(chunks, row, table);\n }\n if (text.includes(\" >= \")) {\n return !ltMatches(chunks, row, table);\n }\n if (text.includes(\" <= \")) {\n return lteMatches(chunks, row, table);\n }\n if (text.includes(\" < \")) {\n return ltMatches(chunks, row, table);\n }\n return eqMatches(chunks, row, table);\n}\n\n/** Match `is null` / `is not null` predicates (no value argument). */\nfunction isNullMatches(\n chunks: SqlChunk[],\n row: Record<string, unknown>,\n table: Table,\n negated: boolean,\n): boolean {\n let columnName: string | undefined;\n for (const chunk of chunks) {\n if (typeof chunk.name === \"string\" && chunk.table !== undefined) {\n columnName = chunk.name;\n }\n }\n if (columnName === undefined) {\n return false;\n }\n const cell = row[columnKey(table, columnName)];\n const missing = cell === null || cell === undefined;\n return negated ? !missing : missing;\n}\n\nfunction eqMatches(chunks: SqlChunk[], row: Record<string, unknown>, table: Table): boolean {\n let columnName: string | undefined;\n let argument: unknown;\n for (const chunk of chunks) {\n if (typeof chunk.name === \"string\" && chunk.table !== undefined) {\n columnName = chunk.name;\n } else if (\"brand\" in chunk) {\n argument = chunk.value;\n }\n }\n if (columnName === undefined) {\n return false;\n }\n return row[columnKey(table, columnName)] === argument;\n}\n\n/** Match `column like 'pattern'`: `%` is any run of characters, `_` any one; everything else literal. */\nfunction likeMatches(chunks: SqlChunk[], row: Record<string, unknown>, table: Table): boolean {\n let columnName: string | undefined;\n let pattern: unknown;\n for (const chunk of chunks as unknown[]) {\n if (typeof chunk === \"string\") {\n pattern = chunk;\n } else if (chunk !== null && typeof chunk === \"object\") {\n const node = chunk as SqlChunk;\n if (typeof node.name === \"string\" && node.table !== undefined) {\n columnName = node.name;\n } else if (\"brand\" in node) {\n pattern = node.value;\n }\n }\n }\n const cell = columnName === undefined ? undefined : row[columnKey(table, columnName)];\n if (typeof cell !== \"string\" || typeof pattern !== \"string\") {\n return false;\n }\n const source = pattern.replaceAll(/[.*+?^${}()|[\\]\\\\]/gu, String.raw`\\$&`);\n return new RegExp(`^${source.replaceAll(\"%\", \".*\").replaceAll(\"_\", \".\")}$`, \"su\").test(cell);\n}\n\n/* eslint-disable complexity, max-depth -- handles drizzle's varied chunk shapes */\nfunction inArrayMatches(chunks: SqlChunk[], row: Record<string, unknown>, table: Table): boolean {\n let columnName: string | undefined;\n const values: unknown[] = [];\n const collect = (nodes: unknown[]): void => {\n for (const raw of nodes as SqlChunk[]) {\n const chunk = raw as SqlChunk & Record<string, unknown>;\n // Handle array-like chunk (inArray values stored as array of chunks)\n if (\n Array.isArray(chunk) ||\n (chunk && typeof chunk === \"object\" && Object.keys(chunk).every((k) => /^\\d+$/u.test(k)))\n ) {\n collect(Object.values(chunk as unknown as Record<string, unknown>) as unknown[]);\n continue;\n }\n if (typeof chunk.name === \"string\" && chunk.table !== undefined) {\n columnName = chunk.name as string;\n }\n if (\"brand\" in chunk && (chunk as Record<string, unknown>)[\"value\"] !== undefined) {\n const val = (chunk as Record<string, unknown>)[\"value\"];\n if (Array.isArray(val)) {\n values.push(...(val as unknown[]));\n } else {\n values.push(val);\n }\n }\n if (chunk.queryChunks) {\n collect(chunk.queryChunks as unknown[]);\n }\n const val = (chunk as Record<string, unknown>)[\"value\"];\n if (Array.isArray(val)) {\n for (const item of val as unknown[]) {\n if (\n item &&\n typeof item === \"object\" &&\n \"queryChunks\" in (item as Record<string, unknown>)\n ) {\n collect(((item as Record<string, unknown>)[\"queryChunks\"] as unknown[]) ?? []);\n }\n if (item && typeof item === \"object\" && \"value\" in (item as Record<string, unknown>)) {\n const iv = (item as Record<string, unknown>)[\"value\"];\n if (iv !== undefined) {\n values.push(iv);\n }\n }\n if (typeof item === \"string\") {\n values.push(item);\n }\n }\n }\n }\n };\n collect(chunks as unknown[]);\n if (columnName === undefined) {\n return false;\n }\n const key = columnKey(table, columnName);\n return values.includes(row[key]);\n}\n/* eslint-enable complexity, max-depth */\n\n/** `column <= value`: the cell is present and not greater than the argument. */\nfunction lteMatches(chunks: SqlChunk[], row: Record<string, unknown>, table: Table): boolean {\n if (ltMatches(chunks, row, table)) {\n return true;\n }\n return eqMatches(chunks, row, table);\n}\n\nfunction ltMatches(chunks: SqlChunk[], row: Record<string, unknown>, table: Table): boolean {\n let columnName: string | undefined;\n let argument: unknown;\n for (const chunk of chunks) {\n if (typeof chunk.name === \"string\" && chunk.table !== undefined) {\n columnName = chunk.name;\n } else if (\"brand\" in chunk) {\n argument = chunk.value;\n }\n }\n if (columnName === undefined) {\n return false;\n }\n const key = columnKey(table, columnName);\n const cell = row[key];\n if (typeof cell === \"string\" && typeof argument === \"string\") {\n return cell < argument;\n }\n if (typeof cell === \"number\" && typeof argument === \"number\") {\n return cell < argument;\n }\n return String(cell) < String(argument);\n}\n\nfunction compareCells(left: unknown, right: unknown): number {\n if (typeof left === \"string\" && typeof right === \"string\") {\n if (left === right) {\n return 0;\n }\n return left < right ? -1 : 1;\n }\n if (typeof left === \"number\" && typeof right === \"number\") {\n return left - right;\n }\n const leftText = String(left);\n const rightText = String(right);\n if (leftText === rightText) {\n return 0;\n }\n return leftText < rightText ? -1 : 1;\n}\n\n/** Collect every raw string part of a drizzle SQL chunk tree. */\nfunction sqlText(nodes: SqlChunk[]): string {\n return nodes\n .map((node) => {\n const own = textOf(node) ?? \"\";\n const nested = node.queryChunks ? sqlText(node.queryChunks as unknown as SqlChunk[]) : \"\";\n return own + nested;\n })\n .join(\"\");\n}\n\n/** Find the ordered column reference in a drizzle order-by expression. */\nfunction findOrderColumn(nodes: SqlChunk[]): string | undefined {\n for (const node of nodes) {\n if (typeof node.name === \"string\" && node.table !== undefined) {\n return node.name;\n }\n if (node.queryChunks) {\n const nested = findOrderColumn(node.queryChunks as unknown as SqlChunk[]);\n if (nested !== undefined) {\n return nested;\n }\n }\n }\n return undefined;\n}\n\n/** Sort rows per a drizzle order-by expression (single-column asc/desc). */\nexport function orderRows(rows: unknown[], orderBy: SQL, table: Table): unknown[] {\n const chunks = orderBy.queryChunks as unknown as SqlChunk[];\n const columnName = findOrderColumn(chunks);\n if (columnName === undefined) {\n return rows;\n }\n const key = columnKey(table, columnName);\n const descending = /desc/iu.test(sqlText(chunks));\n return rows.toSorted((left, right) => {\n const order = compareCells(\n (left as Record<string, unknown>)[key],\n (right as Record<string, unknown>)[key],\n );\n return descending ? -order : order;\n });\n}\n\nfunction columnKey(table: Table, dbName: string): string {\n for (const [property, column] of Object.entries(getTableColumns(table))) {\n if (column.name === dbName) {\n return property;\n }\n }\n return dbName;\n}\n/* eslint-enable require-await, no-unnecessary-type-assertion, no-unnecessary-type-parameters, non-nullable-type-assertion-style */\n"],"mappings":"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"}
@@ -1,11 +1,9 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
3
  import { StorageAdapter } from "../adapter/storage.mjs";
4
- //#region src/test-helpers/storage-contract.d.ts
5
4
  /** Build the adapter under test (sync or async factories both work). */
6
5
  type StorageFactory = () => StorageAdapter | Promise<StorageAdapter>;
7
6
  /** Run the full storage contract against a factory. */
8
7
  declare function storageContractSuite(label: string, make: StorageFactory): void;
9
- //#endregion
10
8
  export { StorageFactory, storageContractSuite };
11
9
  //# sourceMappingURL=storage-contract.d.mts.map
@@ -3,7 +3,7 @@ import "node:url";
3
3
  import.meta.url;
4
4
  import { Readable } from "node:stream";
5
5
  import { describe, expect, it } from "vitest";
6
- //#region src/test-helpers/storage-contract.ts
6
+ // src/test-helpers/storage-contract.ts
7
7
  /**
8
8
  * Published storage contract suite for first- and third-party adapters.
9
9
  *
@@ -81,7 +81,6 @@ function storageContractSuite(label, make) {
81
81
  });
82
82
  });
83
83
  }
84
- //#endregion
85
84
  export { storageContractSuite };
86
85
 
87
86
  //# sourceMappingURL=storage-contract.mjs.map
@@ -15,4 +15,5 @@ import { ManualClock, createManualClock } from "./test-helpers/manual-clock.mjs"
15
15
  import { runnerContractSuite } from "./test-helpers/runner-contract.mjs";
16
16
  import { storageContractSuite } from "./test-helpers/storage-contract.mjs";
17
17
  import { FakeStateNotifier, makeFakeStateNotifier } from "./test-helpers/fake-notifier.mjs";
18
- export { type Deferred, type DesignContractSamples, FAKE_PNG, type FakeDesign, type FakeStateNotifier, type FakeStorage, type Latch, type ManualClock, type MultiInstanceOptions, type PollableContractOptions, type QueueContractOptions, type QueueFactory, REQUIRED_TABLES, type ReleaseQueue, type SharedDatabaseFactory, createLatch, createManualClock, createReleaseQueue, createTestBuild, createTestProject, databaseContractSuite, databaseQueueMultiInstanceSuite, deferred, designContractSuite, fakeUrl, makeDatabase, makeFakeDesign, makeFakeStateNotifier, makeStorage, notifierContractSuite, queueContractSuite, runnerContractSuite, stateNotifierContractSuite, storageContractSuite, stubTables };
18
+ import { BuildReferenceContractFixture, BuildReferenceContractFixtureRunner, buildReferenceContractSuite } from "./test-helpers/build-reference-contract.mjs";
19
+ export { type BuildReferenceContractFixture, type BuildReferenceContractFixtureRunner, type Deferred, type DesignContractSamples, FAKE_PNG, type FakeDesign, type FakeStateNotifier, type FakeStorage, type Latch, type ManualClock, type MultiInstanceOptions, type PollableContractOptions, type QueueContractOptions, type QueueFactory, REQUIRED_TABLES, type ReleaseQueue, type SharedDatabaseFactory, buildReferenceContractSuite, createLatch, createManualClock, createReleaseQueue, createTestBuild, createTestProject, databaseContractSuite, databaseQueueMultiInstanceSuite, deferred, designContractSuite, fakeUrl, makeDatabase, makeFakeDesign, makeFakeStateNotifier, makeStorage, notifierContractSuite, queueContractSuite, runnerContractSuite, stateNotifierContractSuite, storageContractSuite, stubTables };
@@ -16,4 +16,5 @@ import { createManualClock } from "./test-helpers/manual-clock.mjs";
16
16
  import { runnerContractSuite } from "./test-helpers/runner-contract.mjs";
17
17
  import { storageContractSuite } from "./test-helpers/storage-contract.mjs";
18
18
  import { makeFakeStateNotifier } from "./test-helpers/fake-notifier.mjs";
19
- export { FAKE_PNG, REQUIRED_TABLES, createLatch, createManualClock, createReleaseQueue, createTestBuild, createTestProject, databaseContractSuite, databaseQueueMultiInstanceSuite, deferred, designContractSuite, fakeUrl, makeDatabase, makeFakeDesign, makeFakeStateNotifier, makeStorage, notifierContractSuite, queueContractSuite, runnerContractSuite, stateNotifierContractSuite, storageContractSuite, stubTables };
19
+ import { buildReferenceContractSuite } from "./test-helpers/build-reference-contract.mjs";
20
+ export { FAKE_PNG, REQUIRED_TABLES, buildReferenceContractSuite, createLatch, createManualClock, createReleaseQueue, createTestBuild, createTestProject, databaseContractSuite, databaseQueueMultiInstanceSuite, deferred, designContractSuite, fakeUrl, makeDatabase, makeFakeDesign, makeFakeStateNotifier, makeStorage, notifierContractSuite, queueContractSuite, runnerContractSuite, stateNotifierContractSuite, storageContractSuite, stubTables };
package/dist/tracing.mjs CHANGED
@@ -1,8 +1,9 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
+ import { redactSecrets } from "./utils/redact.mjs";
4
5
  import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
5
- //#region src/tracing.ts
6
+ // src/tracing.ts
6
7
  /**
7
8
  * Internal span and propagation helpers over `@opentelemetry/api`.
8
9
  *
@@ -15,11 +16,41 @@ import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentele
15
16
  const SCOPE = "storyshelf.core";
16
17
  /** W3C traceparent header name. */
17
18
  const TRACEPARENT_HEADER = "traceparent";
19
+ /** What a span records of an error instead of its message, set by the code that knows the error. */
20
+ const spanMessages = /* @__PURE__ */ new WeakMap();
21
+ /**
22
+ * State what spans record as the message of `error`, instead of its own: an outbound HTTP failure
23
+ * is recorded as its status, never the response body it carries. The error itself is not touched,
24
+ * so what a caller catches is unchanged.
25
+ */
26
+ function setSpanMessage(error, message) {
27
+ if (typeof error === "object" && error !== null) spanMessages.set(error, message);
28
+ }
29
+ /**
30
+ * The form of a failure that may be recorded on a span: a new error of the same name whose message
31
+ * (the one given to {@link setSpanMessage}, else the error's own) has gone through
32
+ * `redactSecrets`, with the original's stack frames. Never the original, whose message, stack
33
+ * header or `cause` can repeat a URL, a token or a response body. A thrown non-error is stringified
34
+ * and redacted. This is the one way core records an exception on a span.
35
+ */
36
+ function spanException(error) {
37
+ if (!(error instanceof Error)) return redactSecrets(String(error));
38
+ const message = redactSecrets(spanMessages.get(error) ?? error.message);
39
+ const copy = new Error(message);
40
+ copy.name = error.name;
41
+ copy.stack = `${error.name}: ${message}${redactSecrets(framesOf(error))}`;
42
+ return copy;
43
+ }
44
+ /** The stack after its `Name: message` header, which may hold what the span must not record. */
45
+ function framesOf(error) {
46
+ const header = `${error.name}: ${error.message}`;
47
+ return error.stack?.startsWith(header) ? error.stack.slice(header.length) : "";
48
+ }
18
49
  /**
19
50
  * Run `fn` inside an internal span.
20
51
  *
21
- * On throw the span records the exception, is marked ERROR, and the error
22
- * is rethrown — mirroring the pino `{ err }` convention.
52
+ * On throw the span records a redacted copy of the exception ({@link spanException}), is marked
53
+ * ERROR, and the original error is rethrown untouched — mirroring the pino `{ err }` convention.
23
54
  *
24
55
  * @param name - Span name (`domain.operation`, never a high-cardinality value).
25
56
  * @param fn - Work to run with the span active.
@@ -35,7 +66,7 @@ async function withSpan(name, fn, attributes, parent) {
35
66
  try {
36
67
  return await fn(span);
37
68
  } catch (error) {
38
- span.recordException(error instanceof Error ? error : String(error));
69
+ span.recordException(spanException(error));
39
70
  span.setStatus({ code: SpanStatusCode.ERROR });
40
71
  throw error;
41
72
  } finally {
@@ -57,7 +88,6 @@ function parentContext(traceparent) {
57
88
  function injectTraceContext(headers) {
58
89
  propagation.inject(context.active(), headers);
59
90
  }
60
- //#endregion
61
- export { injectTraceContext, parentContext, withSpan };
91
+ export { injectTraceContext, parentContext, setSpanMessage, spanException, withSpan };
62
92
 
63
93
  //# sourceMappingURL=tracing.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"tracing.mjs","names":[],"sources":["../src/tracing.ts"],"sourcesContent":["/**\n * Internal span and propagation helpers over `@opentelemetry/api`.\n *\n * Not exported from the package surface (see `package.json` exports): other\n * packages use `@storyshelf/observability`. Without a configured provider\n * every helper is a cheap noop, so call sites need no enabled-checks and\n * the hermetic vitest suite stays network-free.\n */\nimport {\n SpanKind,\n SpanStatusCode,\n context,\n propagation,\n trace,\n type Attributes,\n type Context,\n type Span,\n} from \"@opentelemetry/api\";\n\n/** Instrumentation scope for core spans. */\nconst SCOPE = \"storyshelf.core\";\n\n/** W3C traceparent header name. */\nconst TRACEPARENT_HEADER = \"traceparent\";\n\n/**\n * Run `fn` inside an internal span.\n *\n * On throw the span records the exception, is marked ERROR, and the error\n * is rethrown — mirroring the pino `{ err }` convention.\n *\n * @param name - Span name (`domain.operation`, never a high-cardinality value).\n * @param fn - Work to run with the span active.\n * @param attributes - Fixed span attributes.\n * @param parent - Parent context (defaults to the active context).\n * @returns Whatever `fn` returns.\n */\nexport async function withSpan<T>(\n name: string,\n fn: (span: Span) => Promise<T>,\n attributes?: Attributes,\n parent?: Context,\n): Promise<T> {\n const tracer = trace.getTracer(SCOPE);\n return await tracer.startActiveSpan(\n name,\n { kind: SpanKind.INTERNAL, attributes },\n parent ?? context.active(),\n async (span) => {\n try {\n return await fn(span);\n } catch (error) {\n span.recordException(error instanceof Error ? error : String(error));\n span.setStatus({ code: SpanStatusCode.ERROR });\n throw error;\n } finally {\n span.end();\n }\n },\n );\n}\n\n/**\n * Resolve the parent context from an inbound `traceparent` value.\n *\n * @param traceparent - W3C value from a queue payload; absent keeps context.\n * @returns The extracted remote context, or the active context when absent.\n */\nexport function parentContext(traceparent?: string): Context {\n if (!traceparent) {\n return context.active();\n }\n return propagation.extract(context.active(), { [TRACEPARENT_HEADER]: traceparent });\n}\n\n/** Inject the active span context into a mutable header record. */\nexport function injectTraceContext(headers: Record<string, string>): void {\n propagation.inject(context.active(), headers);\n}\n\n/**\n * Read the current W3C `traceparent` value for queue payloads.\n *\n * @returns The header value, or undefined when no span is active.\n */\nexport function currentTraceparent(): string | undefined {\n const carrier: Record<string, string> = {};\n propagation.inject(context.active(), carrier);\n return carrier[TRACEPARENT_HEADER];\n}\n"],"mappings":";;;;;;;;;;;;;;AAoBA,MAAM,QAAQ;;AAGd,MAAM,qBAAqB;;;;;;;;;;;;;AAc3B,eAAsB,SACpB,MACA,IACA,YACA,QACY;CAEZ,OAAO,MADQ,MAAM,UAAU,KACb,CAAC,CAAC,gBAClB,MACA;EAAE,MAAM,SAAS;EAAU;CAAW,GACtC,UAAU,QAAQ,OAAO,GACzB,OAAO,SAAS;EACd,IAAI;GACF,OAAO,MAAM,GAAG,IAAI;EACtB,SAAS,OAAO;GACd,KAAK,gBAAgB,iBAAiB,QAAQ,QAAQ,OAAO,KAAK,CAAC;GACnE,KAAK,UAAU,EAAE,MAAM,eAAe,MAAM,CAAC;GAC7C,MAAM;EACR,UAAU;GACR,KAAK,IAAI;EACX;CACF,CACF;AACF;;;;;;;AAQA,SAAgB,cAAc,aAA+B;CAC3D,IAAI,CAAC,aACH,OAAO,QAAQ,OAAO;CAExB,OAAO,YAAY,QAAQ,QAAQ,OAAO,GAAG,GAAG,qBAAqB,YAAY,CAAC;AACpF;;AAGA,SAAgB,mBAAmB,SAAuC;CACxE,YAAY,OAAO,QAAQ,OAAO,GAAG,OAAO;AAC9C"}
1
+ {"version":3,"file":"tracing.mjs","names":[],"sources":["../src/tracing.ts"],"sourcesContent":["/**\n * Internal span and propagation helpers over `@opentelemetry/api`.\n *\n * Not exported from the package surface (see `package.json` exports): other\n * packages use `@storyshelf/observability`. Without a configured provider\n * every helper is a cheap noop, so call sites need no enabled-checks and\n * the hermetic vitest suite stays network-free.\n */\nimport {\n SpanKind,\n SpanStatusCode,\n context,\n propagation,\n trace,\n type Attributes,\n type Context,\n type Span,\n} from \"@opentelemetry/api\";\nimport { redactSecrets } from \"./utils/redact.ts\";\n\n/** Instrumentation scope for core spans. */\nconst SCOPE = \"storyshelf.core\";\n\n/** W3C traceparent header name. */\nconst TRACEPARENT_HEADER = \"traceparent\";\n\n/** What a span records of an error instead of its message, set by the code that knows the error. */\nconst spanMessages = new WeakMap<object, string>();\n\n/**\n * State what spans record as the message of `error`, instead of its own: an outbound HTTP failure\n * is recorded as its status, never the response body it carries. The error itself is not touched,\n * so what a caller catches is unchanged.\n */\nexport function setSpanMessage(error: unknown, message: string): void {\n if (typeof error === \"object\" && error !== null) {\n spanMessages.set(error, message);\n }\n}\n\n/**\n * The form of a failure that may be recorded on a span: a new error of the same name whose message\n * (the one given to {@link setSpanMessage}, else the error's own) has gone through\n * `redactSecrets`, with the original's stack frames. Never the original, whose message, stack\n * header or `cause` can repeat a URL, a token or a response body. A thrown non-error is stringified\n * and redacted. This is the one way core records an exception on a span.\n */\nexport function spanException(error: unknown): Error | string {\n if (!(error instanceof Error)) {\n return redactSecrets(String(error));\n }\n const message = redactSecrets(spanMessages.get(error) ?? error.message);\n const copy = new Error(message);\n copy.name = error.name;\n copy.stack = `${error.name}: ${message}${redactSecrets(framesOf(error))}`;\n return copy;\n}\n\n/** The stack after its `Name: message` header, which may hold what the span must not record. */\nfunction framesOf(error: Error): string {\n const header = `${error.name}: ${error.message}`;\n return error.stack?.startsWith(header) ? error.stack.slice(header.length) : \"\";\n}\n\n/**\n * Run `fn` inside an internal span.\n *\n * On throw the span records a redacted copy of the exception ({@link spanException}), is marked\n * ERROR, and the original error is rethrown untouched — mirroring the pino `{ err }` convention.\n *\n * @param name - Span name (`domain.operation`, never a high-cardinality value).\n * @param fn - Work to run with the span active.\n * @param attributes - Fixed span attributes.\n * @param parent - Parent context (defaults to the active context).\n * @returns Whatever `fn` returns.\n */\nexport async function withSpan<T>(\n name: string,\n fn: (span: Span) => Promise<T>,\n attributes?: Attributes,\n parent?: Context,\n): Promise<T> {\n const tracer = trace.getTracer(SCOPE);\n return await tracer.startActiveSpan(\n name,\n { kind: SpanKind.INTERNAL, attributes },\n parent ?? context.active(),\n async (span) => {\n try {\n return await fn(span);\n } catch (error) {\n span.recordException(spanException(error));\n span.setStatus({ code: SpanStatusCode.ERROR });\n throw error;\n } finally {\n span.end();\n }\n },\n );\n}\n\n/**\n * Resolve the parent context from an inbound `traceparent` value.\n *\n * @param traceparent - W3C value from a queue payload; absent keeps context.\n * @returns The extracted remote context, or the active context when absent.\n */\nexport function parentContext(traceparent?: string): Context {\n if (!traceparent) {\n return context.active();\n }\n return propagation.extract(context.active(), { [TRACEPARENT_HEADER]: traceparent });\n}\n\n/** Inject the active span context into a mutable header record. */\nexport function injectTraceContext(headers: Record<string, string>): void {\n propagation.inject(context.active(), headers);\n}\n\n/**\n * Read the current W3C `traceparent` value for queue payloads.\n *\n * @returns The header value, or undefined when no span is active.\n */\nexport function currentTraceparent(): string | undefined {\n const carrier: Record<string, string> = {};\n propagation.inject(context.active(), carrier);\n return carrier[TRACEPARENT_HEADER];\n}\n"],"mappings":";;;;;;;;;;;;;;;AAqBA,MAAM,QAAQ;;AAGd,MAAM,qBAAqB;;AAG3B,MAAM,+BAAe,IAAI,QAAwB;;;;;;AAOjD,SAAgB,eAAe,OAAgB,SAAuB;CACpE,IAAI,OAAO,UAAU,YAAY,UAAU,MACzC,aAAa,IAAI,OAAO,OAAO;AAEnC;;;;;;;;AASA,SAAgB,cAAc,OAAgC;CAC5D,IAAI,EAAE,iBAAiB,QACrB,OAAO,cAAc,OAAO,KAAK,CAAC;CAEpC,MAAM,UAAU,cAAc,aAAa,IAAI,KAAK,KAAK,MAAM,OAAO;CACtE,MAAM,OAAO,IAAI,MAAM,OAAO;CAC9B,KAAK,OAAO,MAAM;CAClB,KAAK,QAAQ,GAAG,MAAM,KAAK,IAAI,UAAU,cAAc,SAAS,KAAK,CAAC;CACtE,OAAO;AACT;;AAGA,SAAS,SAAS,OAAsB;CACtC,MAAM,SAAS,GAAG,MAAM,KAAK,IAAI,MAAM;CACvC,OAAO,MAAM,OAAO,WAAW,MAAM,IAAI,MAAM,MAAM,MAAM,OAAO,MAAM,IAAI;AAC9E;;;;;;;;;;;;;AAcA,eAAsB,SACpB,MACA,IACA,YACA,QACY;CAEZ,OAAO,MADQ,MAAM,UAAU,KACb,CAAC,CAAC,gBAClB,MACA;EAAE,MAAM,SAAS;EAAU;CAAW,GACtC,UAAU,QAAQ,OAAO,GACzB,OAAO,SAAS;EACd,IAAI;GACF,OAAO,MAAM,GAAG,IAAI;EACtB,SAAS,OAAO;GACd,KAAK,gBAAgB,cAAc,KAAK,CAAC;GACzC,KAAK,UAAU,EAAE,MAAM,eAAe,MAAM,CAAC;GAC7C,MAAM;EACR,UAAU;GACR,KAAK,IAAI;EACX;CACF,CACF;AACF;;;;;;;AAQA,SAAgB,cAAc,aAA+B;CAC3D,IAAI,CAAC,aACH,OAAO,QAAQ,OAAO;CAExB,OAAO,YAAY,QAAQ,QAAQ,OAAO,GAAG,GAAG,qBAAqB,YAAY,CAAC;AACpF;;AAGA,SAAgB,mBAAmB,SAAuC;CACxE,YAAY,OAAO,QAAQ,OAAO,GAAG,OAAO;AAC9C"}
package/dist/types.d.mts CHANGED
@@ -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/types.d.ts
4
3
  /** All lifecycle statuses a build can carry. */
5
4
  declare const BUILD_STATUSES: readonly ["pending", "capturing", "comparing", "reviewing", "approved", "rejected", "failed", "cancelled"];
6
5
  /** Lifecycle status of a build. */
@@ -69,6 +68,5 @@ declare const RESERVED_LABEL_KEYS: readonly ["build"];
69
68
  * Attach `persistent=true` to keep a build indefinitely, even after its TTL expires.
70
69
  */
71
70
  declare const PERSISTENT_LABEL_KEY = "persistent";
72
- //#endregion
73
71
  export { AuthUser, BUILD_STATUSES, BuildStatus, CANCELLABLE_BUILD_STATUSES, PERSISTENT_LABEL_KEY, PROJECT_ROLES, ProjectRole, RESERVED_LABEL_KEYS, REVIEW_VERDICTS, ReviewVerdict, SEEDED_LABEL_KEYS, SESSION_COOKIE, SITE_ROLES, SNAPSHOT_STATUSES, SiteRole, SnapshotStatus, TERMINAL_BUILD_STATUSES, isProjectRole };
74
72
  //# sourceMappingURL=types.d.mts.map
package/dist/types.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- //#region src/types.ts
4
+ // src/types.ts
5
5
  /** All lifecycle statuses a build can carry. */
6
6
  const BUILD_STATUSES = [
7
7
  "pending",
@@ -81,7 +81,6 @@ const RESERVED_LABEL_KEYS = ["build"];
81
81
  * Attach `persistent=true` to keep a build indefinitely, even after its TTL expires.
82
82
  */
83
83
  const PERSISTENT_LABEL_KEY = "persistent";
84
- //#endregion
85
84
  export { BUILD_STATUSES, CANCELLABLE_BUILD_STATUSES, PERSISTENT_LABEL_KEY, PROJECT_ROLES, RESERVED_LABEL_KEYS, REVIEW_VERDICTS, SEEDED_LABEL_KEYS, SESSION_COOKIE, SITE_ROLES, SNAPSHOT_STATUSES, TERMINAL_BUILD_STATUSES, isProjectRole };
86
85
 
87
86
  //# sourceMappingURL=types.mjs.map
package/dist/urls.d.mts CHANGED
@@ -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/urls.d.ts
4
3
  /** Type-safe URL builder for project pages and published Storybooks. */
5
4
  interface UrlBuilder {
6
5
  projectsList(): string;
@@ -37,6 +36,5 @@ declare function createUrlBuilder(baseUrl: string, publishedBaseDomain?: string)
37
36
  * app-relative paths only, so `javascript:`/`data:` payloads fall back.
38
37
  */
39
38
  declare function safeImageUrl(value: string | undefined): string | null;
40
- //#endregion
41
39
  export { UrlBuilder, createUrlBuilder, safeImageUrl };
42
40
  //# sourceMappingURL=urls.d.mts.map
package/dist/urls.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- //#region src/urls.ts
4
+ // src/urls.ts
5
5
  /**
6
6
  * Create a URL builder rooted at the given base URL.
7
7
  *
@@ -52,7 +52,6 @@ function safeImageUrl(value) {
52
52
  function encodePath(value) {
53
53
  return value.split("/").map((segment) => encodeURIComponent(segment)).join("/");
54
54
  }
55
- //#endregion
56
55
  export { createUrlBuilder, safeImageUrl };
57
56
 
58
57
  //# sourceMappingURL=urls.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 { Logger } from "../logger.mjs";
4
- //#region src/utils/adaptive-concurrency.d.ts
5
4
  /** Tuning for {@link AdaptiveConcurrency}. */
6
5
  interface AdaptiveOptions {
7
6
  /** Starting in-flight limit. */
@@ -61,6 +60,5 @@ declare class AdaptiveConcurrency {
61
60
  }
62
61
  /** Whether an error is a navigation/action timeout (Playwright and Puppeteer both name it `TimeoutError`). */
63
62
  declare function isTimeoutError(error: unknown): boolean;
64
- //#endregion
65
63
  export { AdaptiveConcurrency, AdaptiveOptions, Observation, isTimeoutError };
66
64
  //# sourceMappingURL=adaptive-concurrency.d.mts.map
@@ -2,7 +2,7 @@ import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
4
  import { monitorEventLoopDelay } from "node:perf_hooks";
5
- //#region src/utils/adaptive-concurrency.ts
5
+ // src/utils/adaptive-concurrency.ts
6
6
  /** Adaptive page concurrency: raise while capture stays healthy, back off when it does not. */
7
7
  const MIN_WINDOW = 8;
8
8
  /**
@@ -143,7 +143,6 @@ function eventLoopLagReader() {
143
143
  }
144
144
  };
145
145
  }
146
- //#endregion
147
146
  export { AdaptiveConcurrency, isTimeoutError };
148
147
 
149
148
  //# sourceMappingURL=adaptive-concurrency.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/utils/connect-retry.d.ts
4
3
  /** Retrying a connection to a remote browser service (ADR 0007, decision 4). */
5
4
  /** Options of {@link retryConnect}. */
6
5
  interface RetryConnectOptions {
@@ -8,6 +7,8 @@ interface RetryConnectOptions {
8
7
  retries: number;
9
8
  /** Delay before the first retry in ms; doubles each time, with jitter, capped at 10 s. */
10
9
  backoffMs: number;
10
+ /** Whether an error is worth another attempt; defaults to {@link isRetryableConnectError}. */
11
+ retryable?: (error: unknown) => boolean;
11
12
  /** Called before each retry with the error, the retry's number (from 1) and its delay. */
12
13
  onRetry?: (error: unknown, retry: number, delayMs: number) => void;
13
14
  /** Injectable for tests. */
@@ -21,6 +22,5 @@ declare function isRetryableConnectError(error: unknown): boolean;
21
22
  * while rendering. The last error is thrown once the retries are spent.
22
23
  */
23
24
  declare function retryConnect<T>(connect: () => Promise<T>, options: RetryConnectOptions): Promise<T>;
24
- //#endregion
25
25
  export { RetryConnectOptions, isRetryableConnectError, retryConnect };
26
26
  //# sourceMappingURL=connect-retry.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/utils/connect-retry.ts
4
+ // src/utils/connect-retry.ts
5
5
  const MAX_DELAY_MS = 1e4;
6
6
  /** Errors that no retry fixes: a refused credential, a missing endpoint, mismatched versions. */
7
7
  const PERMANENT = /\b(?:401|403|404|428|unauthorized|forbidden|version mismatch|invalid (?:token|credentials)|not found)\b/iu;
@@ -22,7 +22,7 @@ async function retryConnect(connect, options) {
22
22
  for (let retry = 0;; retry += 1) try {
23
23
  return await connect();
24
24
  } catch (error) {
25
- if (retry >= options.retries || !isRetryableConnectError(error)) throw error;
25
+ if (retry >= options.retries || !(options.retryable ?? isRetryableConnectError)(error)) throw error;
26
26
  const delayMs = Math.min(MAX_DELAY_MS, options.backoffMs * 2 ** retry) * jitter();
27
27
  options.onRetry?.(error, retry + 1, Math.round(delayMs));
28
28
  await sleep(delayMs);
@@ -37,7 +37,6 @@ async function sleepFor(ms) {
37
37
  setTimeout(resolve, ms);
38
38
  });
39
39
  }
40
- //#endregion
41
40
  export { isRetryableConnectError, retryConnect };
42
41
 
43
42
  //# sourceMappingURL=connect-retry.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect-retry.mjs","names":[],"sources":["../../src/utils/connect-retry.ts"],"sourcesContent":["/** Retrying a connection to a remote browser service (ADR 0007, decision 4). */\n\n/** Options of {@link retryConnect}. */\nexport interface RetryConnectOptions {\n /** Retries after the first attempt. */\n retries: number;\n /** Delay before the first retry in ms; doubles each time, with jitter, capped at 10 s. */\n backoffMs: number;\n /** Called before each retry with the error, the retry's number (from 1) and its delay. */\n onRetry?: (error: unknown, retry: number, delayMs: number) => void;\n /** Injectable for tests. */\n sleep?: (ms: number) => Promise<void>;\n}\n\nconst MAX_DELAY_MS = 10_000;\n\n/** Errors that no retry fixes: a refused credential, a missing endpoint, mismatched versions. */\nconst PERMANENT =\n /\\b(?:401|403|404|428|unauthorized|forbidden|version mismatch|invalid (?:token|credentials)|not found)\\b/iu;\n\n/** Errors of the connection itself: refused, dropped, timed out, or a service with no free session. */\nconst CONNECTION =\n /(?:ECONNREFUSED|ECONNRESET|EPIPE|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|EHOSTUNREACH|socket hang up|websocket error|connection (?:closed|refused|reset)|timeout|timed out|capacity|too many|queue(?:d)? full|no (?:free )?(?:session|browser)|\\b(?:408|425|429|500|502|503|504)\\b)/iu;\n\n/** Whether a connect error is worth retrying: connection-level, not a configuration mistake. */\nexport function isRetryableConnectError(error: unknown): boolean {\n const text = error instanceof Error ? error.message : String(error);\n return !PERMANENT.test(text) && CONNECTION.test(text);\n}\n\n/**\n * Run `connect`, retrying a connection-level failure with exponential backoff, so a provider\n * outage or a full plan is absorbed here and crash isolation only ever sees a browser that died\n * while rendering. The last error is thrown once the retries are spent.\n */\nexport async function retryConnect<T>(\n connect: () => Promise<T>,\n options: RetryConnectOptions,\n): Promise<T> {\n const sleep = options.sleep ?? sleepFor;\n for (let retry = 0; ; retry += 1) {\n try {\n // oxlint-disable-next-line eslint/no-await-in-loop -- attempts are sequential by design\n return await connect();\n } catch (error) {\n if (retry >= options.retries || !isRetryableConnectError(error)) {\n throw error;\n }\n const delayMs = Math.min(MAX_DELAY_MS, options.backoffMs * 2 ** retry) * jitter();\n options.onRetry?.(error, retry + 1, Math.round(delayMs));\n // oxlint-disable-next-line eslint/no-await-in-loop -- backoff between sequential attempts\n await sleep(delayMs);\n }\n }\n}\n\n/** 0.75 to 1.25: providers refusing for capacity should not see every shard retry in step. */\nfunction jitter(): number {\n return 0.75 + Math.random() * 0.5;\n}\n\nasync function sleepFor(ms: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n"],"mappings":";;;;AAcA,MAAM,eAAe;;AAGrB,MAAM,YACJ;;AAGF,MAAM,aACJ;;AAGF,SAAgB,wBAAwB,OAAyB;CAC/D,MAAM,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CAClE,OAAO,CAAC,UAAU,KAAK,IAAI,KAAK,WAAW,KAAK,IAAI;AACtD;;;;;;AAOA,eAAsB,aACpB,SACA,SACY;CACZ,MAAM,QAAQ,QAAQ,SAAS;CAC/B,KAAK,IAAI,QAAQ,IAAK,SAAS,GAC7B,IAAI;EAEF,OAAO,MAAM,QAAQ;CACvB,SAAS,OAAO;EACd,IAAI,SAAS,QAAQ,WAAW,CAAC,wBAAwB,KAAK,GAC5D,MAAM;EAER,MAAM,UAAU,KAAK,IAAI,cAAc,QAAQ,YAAY,KAAK,KAAK,IAAI,OAAO;EAChF,QAAQ,UAAU,OAAO,QAAQ,GAAG,KAAK,MAAM,OAAO,CAAC;EAEvD,MAAM,MAAM,OAAO;CACrB;AAEJ;;AAGA,SAAS,SAAiB;CACxB,OAAO,MAAO,KAAK,OAAO,IAAI;AAChC;AAEA,eAAe,SAAS,IAA2B;CACjD,MAAM,IAAI,SAAe,YAAY;EACnC,WAAW,SAAS,EAAE;CACxB,CAAC;AACH"}
1
+ {"version":3,"file":"connect-retry.mjs","names":[],"sources":["../../src/utils/connect-retry.ts"],"sourcesContent":["/** Retrying a connection to a remote browser service (ADR 0007, decision 4). */\n\n/** Options of {@link retryConnect}. */\nexport interface RetryConnectOptions {\n /** Retries after the first attempt. */\n retries: number;\n /** Delay before the first retry in ms; doubles each time, with jitter, capped at 10 s. */\n backoffMs: number;\n /** Whether an error is worth another attempt; defaults to {@link isRetryableConnectError}. */\n retryable?: (error: unknown) => boolean;\n /** Called before each retry with the error, the retry's number (from 1) and its delay. */\n onRetry?: (error: unknown, retry: number, delayMs: number) => void;\n /** Injectable for tests. */\n sleep?: (ms: number) => Promise<void>;\n}\n\nconst MAX_DELAY_MS = 10_000;\n\n/** Errors that no retry fixes: a refused credential, a missing endpoint, mismatched versions. */\nconst PERMANENT =\n /\\b(?:401|403|404|428|unauthorized|forbidden|version mismatch|invalid (?:token|credentials)|not found)\\b/iu;\n\n/** Errors of the connection itself: refused, dropped, timed out, or a service with no free session. */\nconst CONNECTION =\n /(?:ECONNREFUSED|ECONNRESET|EPIPE|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|EHOSTUNREACH|socket hang up|websocket error|connection (?:closed|refused|reset)|timeout|timed out|capacity|too many|queue(?:d)? full|no (?:free )?(?:session|browser)|\\b(?:408|425|429|500|502|503|504)\\b)/iu;\n\n/** Whether a connect error is worth retrying: connection-level, not a configuration mistake. */\nexport function isRetryableConnectError(error: unknown): boolean {\n const text = error instanceof Error ? error.message : String(error);\n return !PERMANENT.test(text) && CONNECTION.test(text);\n}\n\n/**\n * Run `connect`, retrying a connection-level failure with exponential backoff, so a provider\n * outage or a full plan is absorbed here and crash isolation only ever sees a browser that died\n * while rendering. The last error is thrown once the retries are spent.\n */\nexport async function retryConnect<T>(\n connect: () => Promise<T>,\n options: RetryConnectOptions,\n): Promise<T> {\n const sleep = options.sleep ?? sleepFor;\n for (let retry = 0; ; retry += 1) {\n try {\n // oxlint-disable-next-line eslint/no-await-in-loop -- attempts are sequential by design\n return await connect();\n } catch (error) {\n if (retry >= options.retries || !(options.retryable ?? isRetryableConnectError)(error)) {\n throw error;\n }\n const delayMs = Math.min(MAX_DELAY_MS, options.backoffMs * 2 ** retry) * jitter();\n options.onRetry?.(error, retry + 1, Math.round(delayMs));\n // oxlint-disable-next-line eslint/no-await-in-loop -- backoff between sequential attempts\n await sleep(delayMs);\n }\n }\n}\n\n/** 0.75 to 1.25: providers refusing for capacity should not see every shard retry in step. */\nfunction jitter(): number {\n return 0.75 + Math.random() * 0.5;\n}\n\nasync function sleepFor(ms: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n"],"mappings":";;;;AAgBA,MAAM,eAAe;;AAGrB,MAAM,YACJ;;AAGF,MAAM,aACJ;;AAGF,SAAgB,wBAAwB,OAAyB;CAC/D,MAAM,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CAClE,OAAO,CAAC,UAAU,KAAK,IAAI,KAAK,WAAW,KAAK,IAAI;AACtD;;;;;;AAOA,eAAsB,aACpB,SACA,SACY;CACZ,MAAM,QAAQ,QAAQ,SAAS;CAC/B,KAAK,IAAI,QAAQ,IAAK,SAAS,GAC7B,IAAI;EAEF,OAAO,MAAM,QAAQ;CACvB,SAAS,OAAO;EACd,IAAI,SAAS,QAAQ,WAAW,EAAE,QAAQ,aAAa,wBAAA,CAAyB,KAAK,GACnF,MAAM;EAER,MAAM,UAAU,KAAK,IAAI,cAAc,QAAQ,YAAY,KAAK,KAAK,IAAI,OAAO;EAChF,QAAQ,UAAU,OAAO,QAAQ,GAAG,KAAK,MAAM,OAAO,CAAC;EAEvD,MAAM,MAAM,OAAO;CACrB;AAEJ;;AAGA,SAAS,SAAiB;CACxB,OAAO,MAAO,KAAK,OAAO,IAAI;AAChC;AAEA,eAAe,SAAS,IAA2B;CACjD,MAAM,IAAI,SAAe,YAAY;EACnC,WAAW,SAAS,EAAE;CACxB,CAAC;AACH"}
@@ -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/utils/encrypt.d.ts
4
3
  /** Current server secret plus the one it replaced, kept only to decrypt older rows. */
5
4
  interface SecretKeys {
6
5
  current: string;
@@ -43,6 +42,5 @@ declare function decryptWithKey(input: SecretInput, ciphertext: string): {
43
42
  * rotation hint. A missing secret keeps its own configuration error.
44
43
  */
45
44
  declare function decryptCredential(input: SecretInput, ciphertext: string): string;
46
- //#endregion
47
45
  export { KeyUsed, SecretInput, SecretKeys, UndecryptableCredentialError, decrypt, decryptCredential, decryptWithKey, encrypt };
48
46
  //# sourceMappingURL=encrypt.d.mts.map
@@ -2,7 +2,7 @@ import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
4
  import { createCipheriv, createDecipheriv, createHash, randomBytes } from "node:crypto";
5
- //#region src/utils/encrypt.ts
5
+ // src/utils/encrypt.ts
6
6
  /** Thrown when a stored credential cannot be decrypted with any configured key. */
7
7
  var UndecryptableCredentialError = class extends Error {
8
8
  constructor(cause) {
@@ -97,7 +97,6 @@ function decryptWith(secret, ciphertext) {
97
97
  function deriveKey(secret) {
98
98
  return createHash("sha256").update(secret).digest();
99
99
  }
100
- //#endregion
101
100
  export { UndecryptableCredentialError, decrypt, decryptCredential, decryptWithKey, encrypt };
102
101
 
103
102
  //# sourceMappingURL=encrypt.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 { CaptureEnvironment } from "../adapter/capture-runner.mjs";
4
- //#region src/utils/environment.d.ts
5
4
  /**
6
5
  * Digest of the installed system font families (`fc-list`), or undefined where fontconfig is not
7
6
  * available. Cached for the process (fonts do not change under a running server), except a failed
@@ -14,6 +13,5 @@ declare function systemFontsHash(): Promise<string | undefined>;
14
13
  * font digest. Runners call this once per render with the version their driver reports.
15
14
  */
16
15
  declare function detectCaptureEnvironment(browserVersion?: string, deviceScaleFactor?: number): Promise<CaptureEnvironment>;
17
- //#endregion
18
16
  export { detectCaptureEnvironment, systemFontsHash };
19
17
  //# sourceMappingURL=environment.d.mts.map
@@ -2,7 +2,7 @@ import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
4
  import { sha256 } from "./hash.mjs";
5
- //#region src/utils/environment.ts
5
+ // src/utils/environment.ts
6
6
  let fonts;
7
7
  /**
8
8
  * Digest of the installed system font families (`fc-list`), or undefined where fontconfig is not
@@ -53,7 +53,6 @@ function digestOf(stdout) {
53
53
  const families = [...new Set(stdout.split("\n").map((line) => line.trim()))].filter(Boolean);
54
54
  return families.length > 0 ? sha256(families.toSorted().join("\n")).slice(0, 16) : void 0;
55
55
  }
56
- //#endregion
57
56
  export { detectCaptureEnvironment, systemFontsHash };
58
57
 
59
58
  //# sourceMappingURL=environment.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/utils/hash.d.ts
4
3
  /** Hash a value with SHA-256, returning lowercase hex. */
5
4
  declare function sha256(value: string): string;
6
5
  /** Sign a value with HMAC-SHA-256, returning lowercase hex. */
@@ -12,6 +11,5 @@ declare function randomToken(prefix: string): {
12
11
  };
13
12
  /** Compare two strings in constant time to avoid timing leaks. */
14
13
  declare function timingSafeEqualString(a: string, b: string): boolean;
15
- //#endregion
16
14
  export { hmacSha256, randomToken, sha256, timingSafeEqualString };
17
15
  //# sourceMappingURL=hash.d.mts.map
@@ -2,7 +2,7 @@ import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
4
  import { createHash, createHmac, randomBytes, timingSafeEqual } from "node:crypto";
5
- //#region src/utils/hash.ts
5
+ // src/utils/hash.ts
6
6
  /** Hash a value with SHA-256, returning lowercase hex. */
7
7
  function sha256(value) {
8
8
  return createHash("sha256").update(value).digest("hex");
@@ -25,7 +25,6 @@ function timingSafeEqualString(a, b) {
25
25
  const bb = Buffer.from(b);
26
26
  return ab.length === bb.length && timingSafeEqual(ab, bb);
27
27
  }
28
- //#endregion
29
28
  export { hmacSha256, randomToken, sha256, timingSafeEqualString };
30
29
 
31
30
  //# sourceMappingURL=hash.mjs.map