@storyshelf/core 0.3.2 → 0.5.4

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 (393) hide show
  1. package/README.md +38 -31
  2. package/dist/adapter/capture-queue.d.mts +29 -1
  3. package/dist/adapter/capture-runner.d.mts +18 -2
  4. package/dist/adapter/capture-runner.mjs +12 -1
  5. package/dist/adapter/capture-runner.mjs.map +1 -0
  6. package/dist/adapter/database.d.mts +67 -17
  7. package/dist/adapter/database.mjs +22 -55
  8. package/dist/adapter/database.mjs.map +1 -1
  9. package/dist/adapter/email-sender.d.mts +27 -0
  10. package/dist/adapter/email-sender.mjs +4 -0
  11. package/dist/adapter/metadata.d.mts +21 -15
  12. package/dist/adapter/notifier.d.mts +7 -0
  13. package/dist/adapter/notifier.mjs +6 -0
  14. package/dist/adapter/setup.d.mts +61 -0
  15. package/dist/adapter/setup.mjs +29 -0
  16. package/dist/adapter/setup.mjs.map +1 -0
  17. package/dist/adapter/webhook-events.d.mts +29 -0
  18. package/dist/adapter/webhook-events.mjs +83 -0
  19. package/dist/adapter/webhook-events.mjs.map +1 -0
  20. package/dist/adapters/notifier/events.d.mts +26 -0
  21. package/dist/adapters/notifier/events.mjs +66 -0
  22. package/dist/adapters/notifier/events.mjs.map +1 -0
  23. package/dist/adapters/notifier/format.d.mts +14 -0
  24. package/dist/adapters/notifier/format.mjs +96 -0
  25. package/dist/adapters/notifier/format.mjs.map +1 -0
  26. package/dist/adapters/notifier/provider.d.mts +32 -0
  27. package/dist/adapters/notifier/types.d.mts +56 -0
  28. package/dist/adapters/setup-runner.d.mts +23 -0
  29. package/dist/adapters/setup-runner.mjs +149 -0
  30. package/dist/adapters/setup-runner.mjs.map +1 -0
  31. package/dist/adapters/validate.d.mts +30 -0
  32. package/dist/adapters/validate.mjs +313 -0
  33. package/dist/adapters/validate.mjs.map +1 -0
  34. package/dist/auth.d.mts +94 -0
  35. package/dist/auth.mjs +4 -0
  36. package/dist/brand-packs.d.mts +16 -0
  37. package/dist/brand-packs.mjs +130 -0
  38. package/dist/brand-packs.mjs.map +1 -0
  39. package/dist/capture/adapter.d.mts +51 -1
  40. package/dist/capture/adapter.mjs.map +1 -1
  41. package/dist/capture/affected.d.mts +16 -0
  42. package/dist/capture/affected.mjs +64 -0
  43. package/dist/capture/affected.mjs.map +1 -0
  44. package/dist/capture/diff-record.mjs +30 -0
  45. package/dist/capture/diff-record.mjs.map +1 -0
  46. package/dist/capture/dispatch.d.mts +36 -0
  47. package/dist/capture/dispatch.mjs +88 -31
  48. package/dist/capture/dispatch.mjs.map +1 -1
  49. package/dist/capture/guards.mjs +31 -0
  50. package/dist/capture/guards.mjs.map +1 -0
  51. package/dist/capture/orchestrator.d.mts +41 -6
  52. package/dist/capture/orchestrator.mjs +151 -28
  53. package/dist/capture/orchestrator.mjs.map +1 -1
  54. package/dist/capture/pipeline.d.mts +30 -16
  55. package/dist/capture/pipeline.mjs +143 -39
  56. package/dist/capture/pipeline.mjs.map +1 -1
  57. package/dist/capture/recovery.d.mts +21 -0
  58. package/dist/capture/recovery.mjs +83 -0
  59. package/dist/capture/recovery.mjs.map +1 -0
  60. package/dist/capture/rediff.d.mts +35 -0
  61. package/dist/capture/rediff.mjs +77 -0
  62. package/dist/capture/rediff.mjs.map +1 -0
  63. package/dist/capture/sizing.d.mts +58 -0
  64. package/dist/capture/sizing.mjs +119 -0
  65. package/dist/capture/sizing.mjs.map +1 -0
  66. package/dist/capture/skip-checks.mjs +3 -3
  67. package/dist/capture/skip-checks.mjs.map +1 -1
  68. package/dist/capture/statics.d.mts +38 -0
  69. package/dist/capture/statics.mjs +38 -4
  70. package/dist/capture/statics.mjs.map +1 -1
  71. package/dist/capture/status-fanout.mjs +7 -2
  72. package/dist/capture/status-fanout.mjs.map +1 -1
  73. package/dist/capture/storybook.d.mts +31 -2
  74. package/dist/capture/storybook.mjs +77 -2
  75. package/dist/capture/storybook.mjs.map +1 -1
  76. package/dist/capture.d.mts +10 -4
  77. package/dist/capture.mjs +7 -2
  78. package/dist/config.d.mts +121 -4
  79. package/dist/config.mjs +55 -8
  80. package/dist/config.mjs.map +1 -1
  81. package/dist/index.d.mts +5 -56
  82. package/dist/index.mjs +4 -284
  83. package/dist/logger.d.mts +26 -17
  84. package/dist/logger.mjs +10 -5
  85. package/dist/logger.mjs.map +1 -1
  86. package/dist/models/baseline-status.d.mts +29 -0
  87. package/dist/models/baseline-status.mjs +26 -0
  88. package/dist/models/baseline-status.mjs.map +1 -0
  89. package/dist/models/baseline.d.mts +33 -0
  90. package/dist/models/baseline.mjs +35 -13
  91. package/dist/models/baseline.mjs.map +1 -1
  92. package/dist/models/build.d.mts +87 -0
  93. package/dist/models/build.mjs +83 -35
  94. package/dist/models/build.mjs.map +1 -1
  95. package/dist/models/capture-attempt.d.mts +40 -0
  96. package/dist/models/capture-attempt.mjs +85 -0
  97. package/dist/models/capture-attempt.mjs.map +1 -0
  98. package/dist/models/capture-log.d.mts +21 -0
  99. package/dist/models/capture-log.mjs +44 -0
  100. package/dist/models/capture-log.mjs.map +1 -0
  101. package/dist/models/comment.d.mts +29 -0
  102. package/dist/models/comment.mjs +11 -8
  103. package/dist/models/comment.mjs.map +1 -1
  104. package/dist/models/content-ref.d.mts +21 -0
  105. package/dist/models/content-ref.mjs +49 -0
  106. package/dist/models/content-ref.mjs.map +1 -0
  107. package/dist/models/credentials.d.mts +36 -0
  108. package/dist/models/credentials.mjs +103 -0
  109. package/dist/models/credentials.mjs.map +1 -0
  110. package/dist/models/label.d.mts +58 -0
  111. package/dist/models/label.mjs +32 -27
  112. package/dist/models/label.mjs.map +1 -1
  113. package/dist/models/member.d.mts +34 -0
  114. package/dist/models/member.mjs +20 -11
  115. package/dist/models/member.mjs.map +1 -1
  116. package/dist/models/notification-channel.d.mts +52 -0
  117. package/dist/models/notification-channel.mjs +93 -0
  118. package/dist/models/notification-channel.mjs.map +1 -0
  119. package/dist/models/notification-subscription.d.mts +44 -0
  120. package/dist/models/notification-subscription.mjs +89 -0
  121. package/dist/models/notification-subscription.mjs.map +1 -0
  122. package/dist/models/project-group-mapping.d.mts +30 -0
  123. package/dist/models/project-group-mapping.mjs +46 -0
  124. package/dist/models/project-group-mapping.mjs.map +1 -0
  125. package/dist/models/project.d.mts +54 -0
  126. package/dist/models/project.mjs +15 -11
  127. package/dist/models/project.mjs.map +1 -1
  128. package/dist/models/snapshot.d.mts +58 -0
  129. package/dist/models/snapshot.mjs +13 -7
  130. package/dist/models/snapshot.mjs.map +1 -1
  131. package/dist/models/status-config.d.mts +38 -0
  132. package/dist/models/status-config.mjs +12 -11
  133. package/dist/models/status-config.mjs.map +1 -1
  134. package/dist/models/token.d.mts +44 -0
  135. package/dist/models/token.mjs +18 -15
  136. package/dist/models/token.mjs.map +1 -1
  137. package/dist/models/user.d.mts +42 -0
  138. package/dist/models/user.mjs +65 -0
  139. package/dist/models/user.mjs.map +1 -0
  140. package/dist/models/webhook.d.mts +50 -0
  141. package/dist/models/webhook.mjs +12 -10
  142. package/dist/models/webhook.mjs.map +1 -1
  143. package/dist/models.d.mts +22 -0
  144. package/dist/models.mjs +23 -0
  145. package/dist/paths.mjs +29 -0
  146. package/dist/paths.mjs.map +1 -1
  147. package/dist/retention.d.mts +45 -0
  148. package/dist/retention.mjs +145 -0
  149. package/dist/retention.mjs.map +1 -0
  150. package/dist/schema/baseline.d.mts +1 -0
  151. package/dist/schema/build.d.mts +8 -0
  152. package/dist/schema/capture-attempt.d.mts +38 -0
  153. package/dist/schema/comment.d.mts +1 -1
  154. package/dist/schema/content-ref.d.mts +13 -0
  155. package/dist/schema/member.d.mts +2 -0
  156. package/dist/schema/notification.d.mts +35 -0
  157. package/dist/schema/project-group-mapping.d.mts +15 -0
  158. package/dist/schema/project.d.mts +4 -0
  159. package/dist/schema/snapshot.d.mts +7 -0
  160. package/dist/schema/token.d.mts +2 -0
  161. package/dist/schema/user.d.mts +11 -1
  162. package/dist/schema.d.mts +9 -46
  163. package/dist/schema.mjs +1 -55
  164. package/dist/test-helpers/create-project.d.mts +15 -0
  165. package/dist/test-helpers/create-project.mjs +28 -0
  166. package/dist/test-helpers/create-project.mjs.map +1 -0
  167. package/dist/test-helpers/database-contract.d.mts +13 -0
  168. package/dist/test-helpers/database-contract.mjs +58 -0
  169. package/dist/test-helpers/database-contract.mjs.map +1 -0
  170. package/dist/test-helpers/fake-adapters.d.mts +14 -0
  171. package/dist/test-helpers/fake-adapters.mjs +20 -0
  172. package/dist/test-helpers/fake-adapters.mjs.map +1 -0
  173. package/dist/test-helpers/fake-database.d.mts +11 -0
  174. package/dist/test-helpers/fake-database.mjs +104 -0
  175. package/dist/test-helpers/fake-database.mjs.map +1 -0
  176. package/dist/test-helpers/fake-storage.d.mts +14 -0
  177. package/dist/test-helpers/fake-storage.mjs +49 -0
  178. package/dist/test-helpers/fake-storage.mjs.map +1 -0
  179. package/dist/test-helpers/fake-tables.mjs +276 -0
  180. package/dist/test-helpers/fake-tables.mjs.map +1 -0
  181. package/dist/test-helpers/git-contract.d.mts +11 -0
  182. package/dist/test-helpers/git-contract.mjs +34 -0
  183. package/dist/test-helpers/git-contract.mjs.map +1 -0
  184. package/dist/test-helpers/notifier-contract.d.mts +11 -0
  185. package/dist/test-helpers/notifier-contract.mjs +34 -0
  186. package/dist/test-helpers/notifier-contract.mjs.map +1 -0
  187. package/dist/test-helpers/queue-contract.d.mts +11 -0
  188. package/dist/test-helpers/queue-contract.mjs +64 -0
  189. package/dist/test-helpers/queue-contract.mjs.map +1 -0
  190. package/dist/test-helpers/runner-contract.d.mts +11 -0
  191. package/dist/test-helpers/runner-contract.mjs +32 -0
  192. package/dist/test-helpers/runner-contract.mjs.map +1 -0
  193. package/dist/test-helpers/sql-chunks.mjs +138 -0
  194. package/dist/test-helpers/sql-chunks.mjs.map +1 -0
  195. package/dist/test-helpers/storage-contract.d.mts +11 -0
  196. package/dist/test-helpers/storage-contract.mjs +87 -0
  197. package/dist/test-helpers/storage-contract.mjs.map +1 -0
  198. package/dist/test-helpers.d.mts +13 -0
  199. package/dist/test-helpers.mjs +14 -0
  200. package/dist/tracing.mjs +63 -0
  201. package/dist/tracing.mjs.map +1 -0
  202. package/dist/types.d.mts +38 -5
  203. package/dist/types.mjs +18 -5
  204. package/dist/types.mjs.map +1 -1
  205. package/dist/urls.d.mts +12 -1
  206. package/dist/urls.mjs +22 -3
  207. package/dist/urls.mjs.map +1 -1
  208. package/dist/utils/encrypt.d.mts +48 -0
  209. package/dist/utils/encrypt.mjs +67 -13
  210. package/dist/utils/encrypt.mjs.map +1 -1
  211. package/dist/utils/hash.d.mts +17 -0
  212. package/dist/utils/hash.mjs +8 -2
  213. package/dist/utils/hash.mjs.map +1 -1
  214. package/dist/utils/http.d.mts +58 -0
  215. package/dist/utils/http.mjs +147 -0
  216. package/dist/utils/http.mjs.map +1 -0
  217. package/dist/utils/mime.d.mts +9 -0
  218. package/dist/utils/mime.mjs +33 -0
  219. package/dist/utils/mime.mjs.map +1 -0
  220. package/dist/utils/path-security.d.mts +12 -0
  221. package/dist/utils/path-security.mjs +24 -0
  222. package/dist/utils/path-security.mjs.map +1 -0
  223. package/dist/utils/redact.d.mts +17 -0
  224. package/dist/utils/redact.mjs +42 -0
  225. package/dist/utils/redact.mjs.map +1 -0
  226. package/dist/utils/timing.d.mts +19 -0
  227. package/dist/utils/timing.mjs +46 -0
  228. package/dist/utils/timing.mjs.map +1 -0
  229. package/dist/utils/ulid.d.mts +10 -0
  230. package/dist/utils/ulid.mjs +8 -8
  231. package/dist/utils/ulid.mjs.map +1 -1
  232. package/dist/utils.d.mts +12 -0
  233. package/dist/utils.mjs +13 -0
  234. package/package.json +69 -28
  235. package/dist/adapter/auth.d.mts +0 -50
  236. package/dist/adapter/auth.mjs +0 -10
  237. package/dist/adapter/auth.mjs.map +0 -1
  238. package/dist/adapter/init.d.mts +0 -58
  239. package/dist/adapter/init.mjs +0 -93
  240. package/dist/adapter/init.mjs.map +0 -1
  241. package/dist/adapters/webhook-events.mjs +0 -55
  242. package/dist/adapters/webhook-events.mjs.map +0 -1
  243. package/dist/ddl.d.mts +0 -8
  244. package/dist/ddl.mjs +0 -158
  245. package/dist/ddl.mjs.map +0 -1
  246. package/dist/index.mjs.map +0 -1
  247. package/dist/middleware/auth-gate.mjs +0 -36
  248. package/dist/middleware/auth-gate.mjs.map +0 -1
  249. package/dist/middleware/csrf.mjs +0 -40
  250. package/dist/middleware/csrf.mjs.map +0 -1
  251. package/dist/middleware/rate-limit.mjs +0 -39
  252. package/dist/middleware/rate-limit.mjs.map +0 -1
  253. package/dist/middleware/request-log.mjs +0 -28
  254. package/dist/middleware/request-log.mjs.map +0 -1
  255. package/dist/middleware/store-scope.mjs +0 -29
  256. package/dist/middleware/store-scope.mjs.map +0 -1
  257. package/dist/pages/build-detail.mjs +0 -339
  258. package/dist/pages/build-detail.mjs.map +0 -1
  259. package/dist/pages/build-diff-comments.mjs +0 -113
  260. package/dist/pages/build-diff-comments.mjs.map +0 -1
  261. package/dist/pages/build-diff-header.mjs +0 -163
  262. package/dist/pages/build-diff-header.mjs.map +0 -1
  263. package/dist/pages/build-diff-nav.mjs +0 -66
  264. package/dist/pages/build-diff-nav.mjs.map +0 -1
  265. package/dist/pages/build-diff-viewer.mjs +0 -197
  266. package/dist/pages/build-diff-viewer.mjs.map +0 -1
  267. package/dist/pages/build-diff.mjs +0 -90
  268. package/dist/pages/build-diff.mjs.map +0 -1
  269. package/dist/pages/compute-jobs.mjs +0 -198
  270. package/dist/pages/compute-jobs.mjs.map +0 -1
  271. package/dist/pages/label-detail.mjs +0 -228
  272. package/dist/pages/label-detail.mjs.map +0 -1
  273. package/dist/pages/login.mjs +0 -78
  274. package/dist/pages/login.mjs.map +0 -1
  275. package/dist/pages/project-builds.mjs +0 -231
  276. package/dist/pages/project-builds.mjs.map +0 -1
  277. package/dist/pages/project-create.mjs +0 -169
  278. package/dist/pages/project-create.mjs.map +0 -1
  279. package/dist/pages/project-settings.mjs +0 -102
  280. package/dist/pages/project-settings.mjs.map +0 -1
  281. package/dist/pages/projects.mjs +0 -184
  282. package/dist/pages/projects.mjs.map +0 -1
  283. package/dist/pages/root.mjs +0 -94
  284. package/dist/pages/root.mjs.map +0 -1
  285. package/dist/pages/settings-general.mjs +0 -192
  286. package/dist/pages/settings-general.mjs.map +0 -1
  287. package/dist/pages/settings-labels.mjs +0 -150
  288. package/dist/pages/settings-labels.mjs.map +0 -1
  289. package/dist/pages/settings-members.mjs +0 -125
  290. package/dist/pages/settings-members.mjs.map +0 -1
  291. package/dist/pages/settings-status.mjs +0 -152
  292. package/dist/pages/settings-status.mjs.map +0 -1
  293. package/dist/pages/settings-tests.mjs +0 -149
  294. package/dist/pages/settings-tests.mjs.map +0 -1
  295. package/dist/pages/settings-tokens.mjs +0 -96
  296. package/dist/pages/settings-tokens.mjs.map +0 -1
  297. package/dist/pages/settings-webhooks.mjs +0 -150
  298. package/dist/pages/settings-webhooks.mjs.map +0 -1
  299. package/dist/pages/storybook.mjs +0 -96
  300. package/dist/pages/storybook.mjs.map +0 -1
  301. package/dist/retention/purge.mjs +0 -70
  302. package/dist/retention/purge.mjs.map +0 -1
  303. package/dist/routers/admin.mjs +0 -42
  304. package/dist/routers/admin.mjs.map +0 -1
  305. package/dist/routers/assets.mjs +0 -25
  306. package/dist/routers/assets.mjs.map +0 -1
  307. package/dist/routers/auth.mjs +0 -78
  308. package/dist/routers/auth.mjs.map +0 -1
  309. package/dist/routers/builds.handlers.mjs +0 -184
  310. package/dist/routers/builds.handlers.mjs.map +0 -1
  311. package/dist/routers/builds.mjs +0 -185
  312. package/dist/routers/builds.mjs.map +0 -1
  313. package/dist/routers/comments.mjs +0 -90
  314. package/dist/routers/comments.mjs.map +0 -1
  315. package/dist/routers/health.mjs +0 -137
  316. package/dist/routers/health.mjs.map +0 -1
  317. package/dist/routers/helpers.mjs +0 -82
  318. package/dist/routers/helpers.mjs.map +0 -1
  319. package/dist/routers/htmx.mjs +0 -20
  320. package/dist/routers/htmx.mjs.map +0 -1
  321. package/dist/routers/labels.mjs +0 -110
  322. package/dist/routers/labels.mjs.map +0 -1
  323. package/dist/routers/media.mjs +0 -55
  324. package/dist/routers/media.mjs.map +0 -1
  325. package/dist/routers/members.mjs +0 -102
  326. package/dist/routers/members.mjs.map +0 -1
  327. package/dist/routers/projects.mjs +0 -122
  328. package/dist/routers/projects.mjs.map +0 -1
  329. package/dist/routers/schemas.mjs +0 -224
  330. package/dist/routers/schemas.mjs.map +0 -1
  331. package/dist/routers/settings-general.mjs +0 -95
  332. package/dist/routers/settings-general.mjs.map +0 -1
  333. package/dist/routers/settings-labels.mjs +0 -49
  334. package/dist/routers/settings-labels.mjs.map +0 -1
  335. package/dist/routers/settings-members.mjs +0 -30
  336. package/dist/routers/settings-members.mjs.map +0 -1
  337. package/dist/routers/settings-status.mjs +0 -73
  338. package/dist/routers/settings-status.mjs.map +0 -1
  339. package/dist/routers/settings-tokens.mjs +0 -40
  340. package/dist/routers/settings-tokens.mjs.map +0 -1
  341. package/dist/routers/settings-webhooks.mjs +0 -63
  342. package/dist/routers/settings-webhooks.mjs.map +0 -1
  343. package/dist/routers/settings.handlers.mjs +0 -93
  344. package/dist/routers/settings.handlers.mjs.map +0 -1
  345. package/dist/routers/settings.mjs +0 -23
  346. package/dist/routers/settings.mjs.map +0 -1
  347. package/dist/routers/snapshots.mjs +0 -144
  348. package/dist/routers/snapshots.mjs.map +0 -1
  349. package/dist/routers/status-configs.mjs +0 -101
  350. package/dist/routers/status-configs.mjs.map +0 -1
  351. package/dist/routers/storybook.mjs +0 -120
  352. package/dist/routers/storybook.mjs.map +0 -1
  353. package/dist/routers/tokens.mjs +0 -81
  354. package/dist/routers/tokens.mjs.map +0 -1
  355. package/dist/routers/ui.mjs +0 -165
  356. package/dist/routers/ui.mjs.map +0 -1
  357. package/dist/routers/webhooks.mjs +0 -90
  358. package/dist/routers/webhooks.mjs.map +0 -1
  359. package/dist/schema/baseline.mjs +0 -22
  360. package/dist/schema/baseline.mjs.map +0 -1
  361. package/dist/schema/build.mjs +0 -29
  362. package/dist/schema/build.mjs.map +0 -1
  363. package/dist/schema/comment.mjs +0 -26
  364. package/dist/schema/comment.mjs.map +0 -1
  365. package/dist/schema/label.mjs +0 -30
  366. package/dist/schema/label.mjs.map +0 -1
  367. package/dist/schema/member.mjs +0 -19
  368. package/dist/schema/member.mjs.map +0 -1
  369. package/dist/schema/project.mjs +0 -25
  370. package/dist/schema/project.mjs.map +0 -1
  371. package/dist/schema/snapshot.mjs +0 -34
  372. package/dist/schema/snapshot.mjs.map +0 -1
  373. package/dist/schema/status-config.mjs +0 -20
  374. package/dist/schema/status-config.mjs.map +0 -1
  375. package/dist/schema/token.mjs +0 -19
  376. package/dist/schema/token.mjs.map +0 -1
  377. package/dist/schema/user.mjs +0 -19
  378. package/dist/schema/user.mjs.map +0 -1
  379. package/dist/schema/webhook.mjs +0 -20
  380. package/dist/schema/webhook.mjs.map +0 -1
  381. package/dist/schema.mjs.map +0 -1
  382. package/dist/store.mjs +0 -20
  383. package/dist/store.mjs.map +0 -1
  384. package/dist/ui/document.mjs +0 -348
  385. package/dist/ui/document.mjs.map +0 -1
  386. package/dist/ui/feedback.mjs +0 -24
  387. package/dist/ui/feedback.mjs.map +0 -1
  388. package/dist/ui/forms.mjs +0 -117
  389. package/dist/ui/forms.mjs.map +0 -1
  390. package/dist/ui/styles.mjs +0 -174
  391. package/dist/ui/styles.mjs.map +0 -1
  392. package/dist/ui/theme.mjs +0 -44
  393. package/dist/ui/theme.mjs.map +0 -1
package/package.json CHANGED
@@ -1,7 +1,14 @@
1
1
  {
2
2
  "name": "@storyshelf/core",
3
- "version": "0.3.2",
4
- "description": "StoryShelf core: Hono router, adapter interfaces, models, capture pipeline, diff, retention.",
3
+ "version": "0.5.4",
4
+ "description": "StoryShelf core: adapter interfaces, models, capture pipeline, diff, and retention (no HTTP).",
5
+ "keywords": [
6
+ "chromatic-alternative",
7
+ "self-hosted",
8
+ "storybook",
9
+ "visual-regression-testing",
10
+ "visual-testing"
11
+ ],
5
12
  "homepage": "https://github.com/GuptaSiddhant/StoryShelf#readme",
6
13
  "bugs": {
7
14
  "url": "https://github.com/GuptaSiddhant/StoryShelf/issues"
@@ -27,10 +34,6 @@
27
34
  "source": "./src/index.tsx",
28
35
  "default": "./dist/index.mjs"
29
36
  },
30
- "./adapter/auth": {
31
- "source": "./src/adapters/auth.ts",
32
- "default": "./dist/adapter/auth.mjs"
33
- },
34
37
  "./adapter/capture-queue": {
35
38
  "source": "./src/adapters/capture-queue.ts",
36
39
  "default": "./dist/adapter/capture-queue.mjs"
@@ -43,6 +46,10 @@
43
46
  "source": "./src/adapters/database.ts",
44
47
  "default": "./dist/adapter/database.mjs"
45
48
  },
49
+ "./adapter/email-sender": {
50
+ "source": "./src/adapters/email-sender.ts",
51
+ "default": "./dist/adapter/email-sender.mjs"
52
+ },
46
53
  "./adapter/git-host": {
47
54
  "source": "./src/adapters/git-host/index.ts",
48
55
  "default": "./dist/adapter/git-host.mjs"
@@ -55,25 +62,37 @@
55
62
  "source": "./src/adapters/git-host/helpers.ts",
56
63
  "default": "./dist/adapter/git-host/helpers.mjs"
57
64
  },
58
- "./adapter/init": {
59
- "source": "./src/adapters/init.ts",
60
- "default": "./dist/adapter/init.mjs"
61
- },
62
65
  "./adapter/metadata": {
63
66
  "source": "./src/adapters/metadata.ts",
64
67
  "default": "./dist/adapter/metadata.mjs"
65
68
  },
69
+ "./adapter/notifier": {
70
+ "source": "./src/adapters/notifier/index.ts",
71
+ "default": "./dist/adapter/notifier.mjs"
72
+ },
73
+ "./adapter/setup": {
74
+ "source": "./src/adapters/setup.ts",
75
+ "default": "./dist/adapter/setup.mjs"
76
+ },
66
77
  "./adapter/storage": {
67
78
  "source": "./src/adapters/storage.ts",
68
79
  "default": "./dist/adapter/storage.mjs"
69
80
  },
81
+ "./adapter/webhook-events": {
82
+ "source": "./src/adapters/webhook-events.ts",
83
+ "default": "./dist/adapter/webhook-events.mjs"
84
+ },
85
+ "./auth": {
86
+ "source": "./src/auth.ts",
87
+ "default": "./dist/auth.mjs"
88
+ },
70
89
  "./capture": {
71
90
  "source": "./src/capture/index.ts",
72
91
  "default": "./dist/capture.mjs"
73
92
  },
74
- "./ddl": {
75
- "source": "./src/ddl.ts",
76
- "default": "./dist/ddl.mjs"
93
+ "./config": {
94
+ "source": "./src/config.ts",
95
+ "default": "./dist/config.mjs"
77
96
  },
78
97
  "./diff": {
79
98
  "source": "./src/diff/index.ts",
@@ -83,14 +102,26 @@
83
102
  "source": "./src/logger.ts",
84
103
  "default": "./dist/logger.mjs"
85
104
  },
105
+ "./models": {
106
+ "source": "./src/models/index.ts",
107
+ "default": "./dist/models.mjs"
108
+ },
86
109
  "./paths": {
87
110
  "source": "./src/utils/paths.ts",
88
111
  "default": "./dist/paths.mjs"
89
112
  },
113
+ "./retention": {
114
+ "source": "./src/retention/purge.ts",
115
+ "default": "./dist/retention.mjs"
116
+ },
90
117
  "./schema": {
91
118
  "source": "./src/schema/index.ts",
92
119
  "default": "./dist/schema.mjs"
93
120
  },
121
+ "./test-helpers": {
122
+ "source": "./src/test-helpers/index.ts",
123
+ "default": "./dist/test-helpers.mjs"
124
+ },
94
125
  "./types": {
95
126
  "source": "./src/types.ts",
96
127
  "default": "./dist/types.mjs"
@@ -99,29 +130,40 @@
99
130
  "source": "./src/urls.ts",
100
131
  "default": "./dist/urls.mjs"
101
132
  },
133
+ "./utils": {
134
+ "source": "./src/utils/index.ts",
135
+ "default": "./dist/utils.mjs"
136
+ },
102
137
  "./package.json": "./package.json"
103
138
  },
104
139
  "publishConfig": {
105
140
  "exports": {
106
141
  ".": "./dist/index.mjs",
107
- "./adapter/auth": "./dist/adapter/auth.mjs",
108
142
  "./adapter/capture-queue": "./dist/adapter/capture-queue.mjs",
109
143
  "./adapter/capture-runner": "./dist/adapter/capture-runner.mjs",
110
144
  "./adapter/database": "./dist/adapter/database.mjs",
145
+ "./adapter/email-sender": "./dist/adapter/email-sender.mjs",
111
146
  "./adapter/git-host": "./dist/adapter/git-host.mjs",
112
147
  "./adapter/git-host/comments": "./dist/adapter/git-host/comments.mjs",
113
148
  "./adapter/git-host/helpers": "./dist/adapter/git-host/helpers.mjs",
114
- "./adapter/init": "./dist/adapter/init.mjs",
115
149
  "./adapter/metadata": "./dist/adapter/metadata.mjs",
150
+ "./adapter/notifier": "./dist/adapter/notifier.mjs",
151
+ "./adapter/setup": "./dist/adapter/setup.mjs",
116
152
  "./adapter/storage": "./dist/adapter/storage.mjs",
153
+ "./adapter/webhook-events": "./dist/adapter/webhook-events.mjs",
154
+ "./auth": "./dist/auth.mjs",
117
155
  "./capture": "./dist/capture.mjs",
118
- "./ddl": "./dist/ddl.mjs",
156
+ "./config": "./dist/config.mjs",
119
157
  "./diff": "./dist/diff.mjs",
120
158
  "./logger": "./dist/logger.mjs",
159
+ "./models": "./dist/models.mjs",
121
160
  "./paths": "./dist/paths.mjs",
161
+ "./retention": "./dist/retention.mjs",
122
162
  "./schema": "./dist/schema.mjs",
163
+ "./test-helpers": "./dist/test-helpers.mjs",
123
164
  "./types": "./dist/types.mjs",
124
165
  "./urls": "./dist/urls.mjs",
166
+ "./utils": "./dist/utils.mjs",
125
167
  "./package.json": "./package.json"
126
168
  },
127
169
  "access": "public"
@@ -138,10 +180,9 @@
138
180
  "test:watch": "vitest"
139
181
  },
140
182
  "dependencies": {
141
- "@hono/swagger-ui": "^0.6.1",
142
- "@hono/zod-openapi": "^1.1.5",
183
+ "@opentelemetry/api": "^1.9.0",
184
+ "@storyshelf/affected": "0.5.4",
143
185
  "drizzle-orm": "^0.44.0",
144
- "hono": "^4.11.0",
145
186
  "pino": "^10.3.1",
146
187
  "pixelmatch": "^7.1.0",
147
188
  "pngjs": "^7.0.0",
@@ -149,17 +190,17 @@
149
190
  "zod": "^4.2.0"
150
191
  },
151
192
  "devDependencies": {
152
- "@types/node": "catalog:",
193
+ "@types/node": "^26.0.0",
153
194
  "@types/pngjs": "^6.0.5",
154
195
  "@types/unzipper": "0.10.11",
155
- "@vitest/coverage-v8": "catalog:",
156
- "adm-zip": "0.6.0",
157
- "oxfmt": "catalog:",
158
- "oxlint": "catalog:",
159
- "oxlint-tsgolint": "catalog:",
160
- "tsdown": "catalog:",
161
- "typescript": "catalog:",
162
- "vitest": "catalog:"
196
+ "@vitest/coverage-v8": "^4.0.0",
197
+ "adm-zip": "^0.6.1",
198
+ "oxfmt": "^0.65.0",
199
+ "oxlint": "^1.80.0",
200
+ "oxlint-tsgolint": "^7.0.2001",
201
+ "tsdown": "^0.22.14",
202
+ "typescript": "^7.0.2",
203
+ "vitest": "^5.0.0"
163
204
  },
164
205
  "jsr": {
165
206
  "runtimeCompat": {
@@ -1,50 +0,0 @@
1
- import __tsdown_shims_path from 'node:path';
2
- import __tsdown_shims_url from 'node:url';
3
- import { ProjectRole, SiteRole } from "../types.mjs";
4
- import { Adapter } from "./metadata.mjs";
5
- //#region src/adapters/auth.d.ts
6
- /** Shared session cookie name used by all auth adapters (ADR 0008). */
7
- declare const SESSION_COOKIE = "storyshelf_session";
8
- /** An authenticated user of the platform. */
9
- interface AuthUser {
10
- /** User ID. */
11
- id: string;
12
- /** User email. */
13
- email: string;
14
- /** Display name. */
15
- name: string;
16
- /** Optional avatar URL. */
17
- avatarUrl?: string;
18
- /** Site-wide role. */
19
- role: SiteRole;
20
- }
21
- /** Data passed to an auth adapter when an OAuth callback is received. */
22
- interface AuthCallback {
23
- /** Provider name. */
24
- provider: string;
25
- /** Authorization code from the provider. */
26
- code: string;
27
- /** Anti-CSRF state value. */
28
- state: string;
29
- }
30
- /** Access controls granted to a user for a specific project. */
31
- interface ProjectAccess {
32
- /** Project role. */
33
- role: ProjectRole;
34
- }
35
- /** Pluggable authentication abstraction (ADR 0008). */
36
- interface AuthAdapter extends Adapter<{
37
- readonly category: "auth";
38
- }> {
39
- /** Resolve the current user from a request, or null if unauthenticated. */
40
- check(request: Request): Promise<AuthUser | null>;
41
- /** Create a session for a user and return a session token. */
42
- createSession(user: AuthUser): Promise<string>;
43
- /** Destroy a session by its id. */
44
- destroySession(sessionId: string): Promise<void>;
45
- /** Handle an OAuth callback and return the resolved user, if supported. */
46
- handleCallback?(callback: AuthCallback): Promise<AuthUser | null>;
47
- }
48
- //#endregion
49
- export { AuthAdapter, AuthCallback, AuthUser, ProjectAccess, SESSION_COOKIE };
50
- //# sourceMappingURL=auth.d.mts.map
@@ -1,10 +0,0 @@
1
- import "node:path";
2
- import "node:url";
3
- import.meta.url;
4
- //#region src/adapters/auth.ts
5
- /** Shared session cookie name used by all auth adapters (ADR 0008). */
6
- const SESSION_COOKIE = "storyshelf_session";
7
- //#endregion
8
- export { SESSION_COOKIE };
9
-
10
- //# sourceMappingURL=auth.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.mjs","names":[],"sources":["../../src/adapters/auth.ts"],"sourcesContent":["import type { ProjectRole, SiteRole } from \"../types.ts\";\n/**\n * Auth adapter interface: authenticate users and resolve project access.\n */\nimport type { Adapter } from \"./metadata.ts\";\n\n/** Shared session cookie name used by all auth adapters (ADR 0008). */\nexport const SESSION_COOKIE = \"storyshelf_session\";\n\n/** An authenticated user of the platform. */\nexport interface AuthUser {\n /** User ID. */\n id: string;\n /** User email. */\n email: string;\n /** Display name. */\n name: string;\n /** Optional avatar URL. */\n avatarUrl?: string;\n /** Site-wide role. */\n role: SiteRole;\n}\n\n/** Data passed to an auth adapter when an OAuth callback is received. */\nexport interface AuthCallback {\n /** Provider name. */\n provider: string;\n /** Authorization code from the provider. */\n code: string;\n /** Anti-CSRF state value. */\n state: string;\n}\n\n/** Access controls granted to a user for a specific project. */\nexport interface ProjectAccess {\n /** Project role. */\n role: ProjectRole;\n}\n\n/** Pluggable authentication abstraction (ADR 0008). */\nexport interface AuthAdapter extends Adapter<{ readonly category: \"auth\" }> {\n /** Resolve the current user from a request, or null if unauthenticated. */\n check(request: Request): Promise<AuthUser | null>;\n /** Create a session for a user and return a session token. */\n createSession(user: AuthUser): Promise<string>;\n /** Destroy a session by its id. */\n destroySession(sessionId: string): Promise<void>;\n /** Handle an OAuth callback and return the resolved user, if supported. */\n handleCallback?(callback: AuthCallback): Promise<AuthUser | null>;\n}\n"],"mappings":";;;;;AAOA,MAAa,iBAAiB"}
@@ -1,58 +0,0 @@
1
- import __tsdown_shims_path from 'node:path';
2
- import __tsdown_shims_url from 'node:url';
3
- import { CaptureQueue } from "./capture-queue.mjs";
4
- import { CaptureRunner } from "./capture-runner.mjs";
5
- import { DatabaseAdapter } from "./database.mjs";
6
- import { GitHostProvider } from "./git-host.mjs";
7
- import { StorageAdapter } from "./storage.mjs";
8
- import { AdapterInitContext } from "./metadata.mjs";
9
- import { AuthAdapter } from "./auth.mjs";
10
- import { Logger } from "pino";
11
- //#region src/adapters/init.d.ts
12
- /** Adapters that can take part in lifecycle runs. */
13
- interface AdapterInitSources {
14
- database: DatabaseAdapter;
15
- storage: StorageAdapter;
16
- captureRunner?: CaptureRunner;
17
- captureQueue?: CaptureQueue;
18
- auth?: AuthAdapter;
19
- gitHosts?: GitHostProvider[];
20
- }
21
- /** One collected hook bound to its adapter identity. */
22
- interface HookEntry {
23
- readonly category: string;
24
- readonly kind: string;
25
- readonly name: string;
26
- readonly run: (ctx: AdapterInitContext) => Promise<void>;
27
- }
28
- /** One failed hook, with its adapter identity attached. */
29
- interface AdapterInitFailure {
30
- readonly category: string;
31
- readonly kind: string;
32
- readonly name: string;
33
- readonly error: string;
34
- }
35
- /** Settled outcome of a lifecycle run (never rejects — use `ok`). */
36
- interface AdapterInitResult {
37
- readonly ok: boolean;
38
- readonly failures: AdapterInitFailure[];
39
- }
40
- /** Lifecycle phase a run covers. */
41
- type LifecyclePhase = "init" | "close";
42
- /** Thrown when an `app.lifecycle.init()` or `close()` run has failures. */
43
- declare class AdapterLifecycleError extends Error {
44
- readonly phase: LifecyclePhase;
45
- readonly failures: AdapterInitFailure[];
46
- constructor(phase: LifecyclePhase, failures: AdapterInitFailure[]);
47
- }
48
- /** Collect every available `init` hook in deterministic order. */
49
- declare function collectInits(sources: AdapterInitSources): HookEntry[];
50
- /** Collect every available `close` hook in deterministic order. */
51
- declare function collectCloses(sources: AdapterInitSources): HookEntry[];
52
- /** Run init hooks concurrently; failures are collected, never thrown. */
53
- declare function runAdapterInits(entries: HookEntry[], ctx: AdapterInitContext, logger: Logger): Promise<AdapterInitResult>;
54
- /** Run close hooks concurrently; failures are collected, never thrown. */
55
- declare function runAdapterCloses(entries: HookEntry[], ctx: AdapterInitContext, logger: Logger): Promise<AdapterInitResult>;
56
- //#endregion
57
- export { AdapterInitFailure, AdapterInitResult, AdapterInitSources, AdapterLifecycleError, HookEntry, LifecyclePhase, collectCloses, collectInits, runAdapterCloses, runAdapterInits };
58
- //# sourceMappingURL=init.d.mts.map
@@ -1,93 +0,0 @@
1
- import "node:path";
2
- import "node:url";
3
- import.meta.url;
4
- //#region src/adapters/init.ts
5
- /** Thrown when an `app.lifecycle.init()` or `close()` run has failures. */
6
- var AdapterLifecycleError = class extends Error {
7
- phase;
8
- failures;
9
- constructor(phase, failures) {
10
- super(`Adapter ${phase} failed: ${failures.map((f) => `${f.category}/${f.kind}`).join(", ")}`);
11
- this.name = "AdapterLifecycleError";
12
- this.phase = phase;
13
- this.failures = failures;
14
- }
15
- };
16
- function hookEntry(adapter, hook) {
17
- const fn = adapter.lifecycle?.[hook];
18
- if (!fn) return null;
19
- const { category, kind, name } = adapter.metadata;
20
- return {
21
- category,
22
- kind,
23
- name,
24
- run: async (ctx) => {
25
- await fn(ctx);
26
- }
27
- };
28
- }
29
- function pushHook(entries, adapter, hook) {
30
- if (!adapter) return;
31
- const entry = hookEntry(adapter, hook);
32
- if (entry) entries.push(entry);
33
- }
34
- function pushAll(entries, sources, hook) {
35
- pushHook(entries, sources.database, hook);
36
- pushHook(entries, sources.storage, hook);
37
- pushHook(entries, sources.captureRunner, hook);
38
- pushHook(entries, sources.captureQueue, hook);
39
- pushHook(entries, sources.auth, hook);
40
- for (const provider of sources.gitHosts ?? []) pushHook(entries, provider, hook);
41
- }
42
- /** Collect every available `init` hook in deterministic order. */
43
- function collectInits(sources) {
44
- const entries = [];
45
- pushAll(entries, sources, "init");
46
- return entries;
47
- }
48
- /** Collect every available `close` hook in deterministic order. */
49
- function collectCloses(sources) {
50
- const entries = [];
51
- pushAll(entries, sources, "close");
52
- return entries;
53
- }
54
- function messageOf(reason) {
55
- return reason instanceof Error ? reason.message : String(reason);
56
- }
57
- function toFailure(entry, reason) {
58
- return {
59
- category: entry.category,
60
- kind: entry.kind,
61
- name: entry.name,
62
- error: messageOf(reason)
63
- };
64
- }
65
- function toResult(entries, outcomes, logger, verb) {
66
- const failures = [];
67
- for (const [index, entry] of entries.entries()) {
68
- const outcome = outcomes[index];
69
- if (outcome?.status === "rejected") failures.push(toFailure(entry, outcome.reason));
70
- }
71
- if (failures.length > 0) logger.error({ failures }, `adapter ${verb} failed`);
72
- else logger.info({ count: entries.length }, `adapters ${verb}d`);
73
- return {
74
- ok: failures.length === 0,
75
- failures
76
- };
77
- }
78
- /** Run init hooks concurrently; failures are collected, never thrown. */
79
- async function runAdapterInits(entries, ctx, logger) {
80
- return toResult(entries, await Promise.allSettled(entries.map(async (entry) => {
81
- await entry.run(ctx);
82
- })), logger, "init");
83
- }
84
- /** Run close hooks concurrently; failures are collected, never thrown. */
85
- async function runAdapterCloses(entries, ctx, logger) {
86
- return toResult(entries, await Promise.allSettled(entries.map(async (entry) => {
87
- await entry.run(ctx);
88
- })), logger, "close");
89
- }
90
- //#endregion
91
- export { AdapterLifecycleError, collectCloses, collectInits, runAdapterCloses, runAdapterInits };
92
-
93
- //# sourceMappingURL=init.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"init.mjs","names":[],"sources":["../../src/adapters/init.ts"],"sourcesContent":["/**\n * Adapter lifecycle runner: collect and execute `init`/`close` hooks.\n *\n * `createShelfRouter` kicks `init` eagerly via `Promise.allSettled` (so one\n * slow adapter never starves the others) and gates the first request on the\n * shared result. `app.lifecycle.init()` re-runs for fail-fast startup;\n * `app.lifecycle.close()` fans out teardown. All hooks must be idempotent.\n */\nimport type { Logger } from \"pino\";\nimport type { AuthAdapter } from \"./auth.ts\";\nimport type { CaptureQueue } from \"./capture-queue.ts\";\nimport type { CaptureRunner } from \"./capture-runner.ts\";\nimport type { DatabaseAdapter } from \"./database.ts\";\nimport type { GitHostProvider } from \"./git-host/index.ts\";\nimport type { AdapterInitContext, AdapterLifecycle, AdapterMetadata } from \"./metadata.ts\";\nimport type { StorageAdapter } from \"./storage.ts\";\n\n/** Adapters that can take part in lifecycle runs. */\nexport interface AdapterInitSources {\n database: DatabaseAdapter;\n storage: StorageAdapter;\n captureRunner?: CaptureRunner;\n captureQueue?: CaptureQueue;\n auth?: AuthAdapter;\n gitHosts?: GitHostProvider[];\n}\n\ninterface LifecycleCarrier {\n readonly metadata: AdapterMetadata;\n readonly lifecycle?: AdapterLifecycle;\n}\n\n/** One collected hook bound to its adapter identity. */\nexport interface HookEntry {\n readonly category: string;\n readonly kind: string;\n readonly name: string;\n readonly run: (ctx: AdapterInitContext) => Promise<void>;\n}\n\n/** One failed hook, with its adapter identity attached. */\nexport interface AdapterInitFailure {\n readonly category: string;\n readonly kind: string;\n readonly name: string;\n readonly error: string;\n}\n\n/** Settled outcome of a lifecycle run (never rejects — use `ok`). */\nexport interface AdapterInitResult {\n readonly ok: boolean;\n readonly failures: AdapterInitFailure[];\n}\n\n/** Lifecycle phase a run covers. */\nexport type LifecyclePhase = \"init\" | \"close\";\n\n/** Thrown when an `app.lifecycle.init()` or `close()` run has failures. */\nexport class AdapterLifecycleError extends Error {\n readonly phase: LifecyclePhase;\n readonly failures: AdapterInitFailure[];\n constructor(phase: LifecyclePhase, failures: AdapterInitFailure[]) {\n super(`Adapter ${phase} failed: ${failures.map((f) => `${f.category}/${f.kind}`).join(\", \")}`);\n this.name = \"AdapterLifecycleError\";\n this.phase = phase;\n this.failures = failures;\n }\n}\n\nfunction hookEntry(adapter: LifecycleCarrier, hook: \"init\" | \"close\"): HookEntry | null {\n const fn = adapter.lifecycle?.[hook];\n if (!fn) {\n return null;\n }\n const { category, kind, name } = adapter.metadata;\n return {\n category,\n kind,\n name,\n run: async (ctx) => {\n await fn(ctx);\n },\n };\n}\n\nfunction pushHook(\n entries: HookEntry[],\n adapter: LifecycleCarrier | undefined,\n hook: \"init\" | \"close\",\n): void {\n if (!adapter) {\n return;\n }\n const entry = hookEntry(adapter, hook);\n if (entry) {\n entries.push(entry);\n }\n}\n\nfunction pushAll(entries: HookEntry[], sources: AdapterInitSources, hook: \"init\" | \"close\"): void {\n pushHook(entries, sources.database, hook);\n pushHook(entries, sources.storage, hook);\n pushHook(entries, sources.captureRunner, hook);\n pushHook(entries, sources.captureQueue, hook);\n pushHook(entries, sources.auth, hook);\n for (const provider of sources.gitHosts ?? []) {\n pushHook(entries, provider, hook);\n }\n}\n\n/** Collect every available `init` hook in deterministic order. */\nexport function collectInits(sources: AdapterInitSources): HookEntry[] {\n const entries: HookEntry[] = [];\n pushAll(entries, sources, \"init\");\n return entries;\n}\n\n/** Collect every available `close` hook in deterministic order. */\nexport function collectCloses(sources: AdapterInitSources): HookEntry[] {\n const entries: HookEntry[] = [];\n pushAll(entries, sources, \"close\");\n return entries;\n}\n\nfunction messageOf(reason: unknown): string {\n return reason instanceof Error ? reason.message : String(reason);\n}\n\nfunction toFailure(entry: HookEntry, reason: unknown): AdapterInitFailure {\n return { category: entry.category, kind: entry.kind, name: entry.name, error: messageOf(reason) };\n}\n\nfunction toResult(\n entries: HookEntry[],\n outcomes: PromiseSettledResult<void>[],\n logger: Logger,\n verb: string,\n): AdapterInitResult {\n const failures: AdapterInitFailure[] = [];\n for (const [index, entry] of entries.entries()) {\n const outcome: PromiseSettledResult<void> | undefined = outcomes[index];\n if (outcome?.status === \"rejected\") {\n failures.push(toFailure(entry, outcome.reason));\n }\n }\n if (failures.length > 0) {\n logger.error({ failures }, `adapter ${verb} failed`);\n } else {\n logger.info({ count: entries.length }, `adapters ${verb}d`);\n }\n return { ok: failures.length === 0, failures };\n}\n\n/** Run init hooks concurrently; failures are collected, never thrown. */\nexport async function runAdapterInits(\n entries: HookEntry[],\n ctx: AdapterInitContext,\n logger: Logger,\n): Promise<AdapterInitResult> {\n const outcomes = await Promise.allSettled(\n entries.map(async (entry) => {\n await entry.run(ctx);\n }),\n );\n return toResult(entries, outcomes, logger, \"init\");\n}\n\n/** Run close hooks concurrently; failures are collected, never thrown. */\nexport async function runAdapterCloses(\n entries: HookEntry[],\n ctx: AdapterInitContext,\n logger: Logger,\n): Promise<AdapterInitResult> {\n const outcomes = await Promise.allSettled(\n entries.map(async (entry) => {\n await entry.run(ctx);\n }),\n );\n return toResult(entries, outcomes, logger, \"close\");\n}\n"],"mappings":";;;;;AA0DA,IAAa,wBAAb,cAA2C,MAAM;CAC/C;CACA;CACA,YAAY,OAAuB,UAAgC;EACjE,MAAM,WAAW,MAAM,WAAW,SAAS,KAAK,MAAM,GAAG,EAAE,SAAS,GAAG,EAAE,MAAM,CAAC,CAAC,KAAK,IAAI,GAAG;EAC7F,KAAK,OAAO;EACZ,KAAK,QAAQ;EACb,KAAK,WAAW;CAClB;AACF;AAEA,SAAS,UAAU,SAA2B,MAA0C;CACtF,MAAM,KAAK,QAAQ,YAAY;CAC/B,IAAI,CAAC,IACH,OAAO;CAET,MAAM,EAAE,UAAU,MAAM,SAAS,QAAQ;CACzC,OAAO;EACL;EACA;EACA;EACA,KAAK,OAAO,QAAQ;GAClB,MAAM,GAAG,GAAG;EACd;CACF;AACF;AAEA,SAAS,SACP,SACA,SACA,MACM;CACN,IAAI,CAAC,SACH;CAEF,MAAM,QAAQ,UAAU,SAAS,IAAI;CACrC,IAAI,OACF,QAAQ,KAAK,KAAK;AAEtB;AAEA,SAAS,QAAQ,SAAsB,SAA6B,MAA8B;CAChG,SAAS,SAAS,QAAQ,UAAU,IAAI;CACxC,SAAS,SAAS,QAAQ,SAAS,IAAI;CACvC,SAAS,SAAS,QAAQ,eAAe,IAAI;CAC7C,SAAS,SAAS,QAAQ,cAAc,IAAI;CAC5C,SAAS,SAAS,QAAQ,MAAM,IAAI;CACpC,KAAK,MAAM,YAAY,QAAQ,YAAY,CAAC,GAC1C,SAAS,SAAS,UAAU,IAAI;AAEpC;;AAGA,SAAgB,aAAa,SAA0C;CACrE,MAAM,UAAuB,CAAC;CAC9B,QAAQ,SAAS,SAAS,MAAM;CAChC,OAAO;AACT;;AAGA,SAAgB,cAAc,SAA0C;CACtE,MAAM,UAAuB,CAAC;CAC9B,QAAQ,SAAS,SAAS,OAAO;CACjC,OAAO;AACT;AAEA,SAAS,UAAU,QAAyB;CAC1C,OAAO,kBAAkB,QAAQ,OAAO,UAAU,OAAO,MAAM;AACjE;AAEA,SAAS,UAAU,OAAkB,QAAqC;CACxE,OAAO;EAAE,UAAU,MAAM;EAAU,MAAM,MAAM;EAAM,MAAM,MAAM;EAAM,OAAO,UAAU,MAAM;CAAE;AAClG;AAEA,SAAS,SACP,SACA,UACA,QACA,MACmB;CACnB,MAAM,WAAiC,CAAC;CACxC,KAAK,MAAM,CAAC,OAAO,UAAU,QAAQ,QAAQ,GAAG;EAC9C,MAAM,UAAkD,SAAS;EACjE,IAAI,SAAS,WAAW,YACtB,SAAS,KAAK,UAAU,OAAO,QAAQ,MAAM,CAAC;CAElD;CACA,IAAI,SAAS,SAAS,GACpB,OAAO,MAAM,EAAE,SAAS,GAAG,WAAW,KAAK,QAAQ;MAEnD,OAAO,KAAK,EAAE,OAAO,QAAQ,OAAO,GAAG,YAAY,KAAK,EAAE;CAE5D,OAAO;EAAE,IAAI,SAAS,WAAW;EAAG;CAAS;AAC/C;;AAGA,eAAsB,gBACpB,SACA,KACA,QAC4B;CAM5B,OAAO,SAAS,SAAS,MALF,QAAQ,WAC7B,QAAQ,IAAI,OAAO,UAAU;EAC3B,MAAM,MAAM,IAAI,GAAG;CACrB,CAAC,CACH,GACmC,QAAQ,MAAM;AACnD;;AAGA,eAAsB,iBACpB,SACA,KACA,QAC4B;CAM5B,OAAO,SAAS,SAAS,MALF,QAAQ,WAC7B,QAAQ,IAAI,OAAO,UAAU;EAC3B,MAAM,MAAM,IAAI,GAAG;CACrB,CAAC,CACH,GACmC,QAAQ,OAAO;AACpD"}
@@ -1,55 +0,0 @@
1
- import "node:path";
2
- import "node:url";
3
- import.meta.url;
4
- import { WebhookModel } from "../models/webhook.mjs";
5
- import { hmacSha256 } from "../utils/hash.mjs";
6
- //#region src/adapters/webhook-events.ts
7
- async function sendWebhook(url, secret, event) {
8
- const body = JSON.stringify(event);
9
- const signature = hmacSha256(secret, body);
10
- await fetch(url, {
11
- method: "POST",
12
- headers: {
13
- "Content-Type": "application/json",
14
- "X-StoryShelf-Event": event.event,
15
- "X-StoryShelf-Signature": signature
16
- },
17
- body
18
- });
19
- }
20
- /**
21
- * Deliver an event to every subscribed webhook of a project.
22
- *
23
- * @param db - Database adapter for loading subscriptions.
24
- * @param projectId - Project whose webhooks receive the event.
25
- * @param event - Event name (e.g. "baseline:created").
26
- * @param data - Event payload.
27
- * @param secret - Server secret for decrypting webhook secrets (in memory only).
28
- */
29
- async function emitWebhookEvent(db, projectId, event, data, secret) {
30
- const webhookModel = new WebhookModel(db, secret);
31
- const webhooks = await webhookModel.list(projectId);
32
- const eventPayload = {
33
- event,
34
- projectId,
35
- data,
36
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
37
- };
38
- await Promise.allSettled(webhooks.map(async (webhook) => {
39
- const events = WebhookModel.eventsOf(webhook);
40
- if (events.length > 0 && !events.includes(event)) return;
41
- let plaintext;
42
- try {
43
- plaintext = webhookModel.decryptSecret(webhook);
44
- } catch {
45
- return;
46
- }
47
- try {
48
- await sendWebhook(webhook.url, plaintext, eventPayload);
49
- } catch {}
50
- }));
51
- }
52
- //#endregion
53
- export { emitWebhookEvent };
54
-
55
- //# sourceMappingURL=webhook-events.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"webhook-events.mjs","names":[],"sources":["../../src/adapters/webhook-events.ts"],"sourcesContent":["import { WebhookModel } from \"../models/webhook.ts\";\nimport { hmacSha256 } from \"../utils/hash.ts\";\nimport type { DatabaseAdapter } from \"./database.ts\";\n\n/** Outbound webhook payload delivered to subscribers. */\nexport interface WebhookEvent {\n event: string;\n projectId: string;\n data: Record<string, unknown>;\n timestamp: string;\n}\n\nasync function sendWebhook(url: string, secret: string, event: WebhookEvent): Promise<void> {\n const body = JSON.stringify(event);\n const signature = hmacSha256(secret, body);\n await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-StoryShelf-Event\": event.event,\n \"X-StoryShelf-Signature\": signature,\n },\n body,\n });\n}\n\n/**\n * Deliver an event to every subscribed webhook of a project.\n *\n * @param db - Database adapter for loading subscriptions.\n * @param projectId - Project whose webhooks receive the event.\n * @param event - Event name (e.g. \"baseline:created\").\n * @param data - Event payload.\n * @param secret - Server secret for decrypting webhook secrets (in memory only).\n */\nexport async function emitWebhookEvent(\n db: DatabaseAdapter,\n projectId: string,\n event: string,\n data: Record<string, unknown>,\n secret: string | undefined,\n): Promise<void> {\n const webhookModel = new WebhookModel(db, secret);\n const webhooks = await webhookModel.list(projectId);\n const eventPayload: WebhookEvent = {\n event,\n projectId,\n data,\n timestamp: new Date().toISOString(),\n };\n\n await Promise.allSettled(\n webhooks.map(async (webhook) => {\n const events = WebhookModel.eventsOf(webhook);\n if (events.length > 0 && !events.includes(event)) {\n return;\n }\n let plaintext: string;\n try {\n plaintext = webhookModel.decryptSecret(webhook);\n } catch {\n // Undecryptable secret (e.g. rotated server SECRET) — skip, don't leak\n return;\n }\n try {\n await sendWebhook(webhook.url, plaintext, eventPayload);\n } catch {\n // Webhook delivery failures are non-fatal\n }\n }),\n );\n}\n"],"mappings":";;;;;;AAYA,eAAe,YAAY,KAAa,QAAgB,OAAoC;CAC1F,MAAM,OAAO,KAAK,UAAU,KAAK;CACjC,MAAM,YAAY,WAAW,QAAQ,IAAI;CACzC,MAAM,MAAM,KAAK;EACf,QAAQ;EACR,SAAS;GACP,gBAAgB;GAChB,sBAAsB,MAAM;GAC5B,0BAA0B;EAC5B;EACA;CACF,CAAC;AACH;;;;;;;;;;AAWA,eAAsB,iBACpB,IACA,WACA,OACA,MACA,QACe;CACf,MAAM,eAAe,IAAI,aAAa,IAAI,MAAM;CAChD,MAAM,WAAW,MAAM,aAAa,KAAK,SAAS;CAClD,MAAM,eAA6B;EACjC;EACA;EACA;EACA,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;CACpC;CAEA,MAAM,QAAQ,WACZ,SAAS,IAAI,OAAO,YAAY;EAC9B,MAAM,SAAS,aAAa,SAAS,OAAO;EAC5C,IAAI,OAAO,SAAS,KAAK,CAAC,OAAO,SAAS,KAAK,GAC7C;EAEF,IAAI;EACJ,IAAI;GACF,YAAY,aAAa,cAAc,OAAO;EAChD,QAAQ;GAEN;EACF;EACA,IAAI;GACF,MAAM,YAAY,QAAQ,KAAK,WAAW,YAAY;EACxD,QAAQ,CAER;CACF,CAAC,CACH;AACF"}
package/dist/ddl.d.mts DELETED
@@ -1,8 +0,0 @@
1
- import __tsdown_shims_path from 'node:path';
2
- import __tsdown_shims_url from 'node:url';
3
- //#region src/ddl.d.ts
4
- /** Canonical SQLite DDL for all StoryShelf tables and indexes. */
5
- declare const DDL = "\nCREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n slug TEXT NOT NULL UNIQUE,\n git_repository TEXT,\n git_default_branch TEXT NOT NULL DEFAULT 'main',\n pixel_threshold REAL NOT NULL DEFAULT 0.1,\n max_diff_ratio REAL NOT NULL DEFAULT 0.01,\n public_branch_regex TEXT,\n storybook_meta TEXT,\n execute_play INTEGER NOT NULL DEFAULT 0,\n play_timeout_ms INTEGER NOT NULL DEFAULT 10000,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS project_status_configs (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n provider TEXT NOT NULL,\n config TEXT NOT NULL,\n token_encrypted TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS builds (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n git_sha TEXT NOT NULL,\n git_branch TEXT NOT NULL,\n is_default INTEGER NOT NULL DEFAULT 0,\n author_email TEXT,\n author_name TEXT,\n message TEXT,\n public INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL DEFAULT 'pending',\n snapshot_count INTEGER NOT NULL DEFAULT 0,\n changed_count INTEGER NOT NULL DEFAULT 0,\n approved_count INTEGER NOT NULL DEFAULT 0,\n rejected_count INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS builds_project_gitsha_idx ON builds (project_id, git_sha);\nCREATE INDEX IF NOT EXISTS builds_git_branch_idx ON builds (git_branch);\nCREATE TABLE IF NOT EXISTS snapshots (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n story_name TEXT NOT NULL,\n story_title TEXT NOT NULL,\n story_import_path TEXT,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n viewport_width INTEGER NOT NULL DEFAULT 1280,\n viewport_height INTEGER NOT NULL DEFAULT 720,\n screenshot_path TEXT NOT NULL,\n diff_path TEXT,\n diff_pixels INTEGER,\n diff_ratio REAL,\n diff_passed INTEGER,\n status TEXT NOT NULL DEFAULT 'pending',\n reviewed_by TEXT,\n reviewed_at TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS snapshots_build_story_viewport_idx ON snapshots (build_id, story_id, viewport_name);\nCREATE INDEX IF NOT EXISTS snapshots_build_id_idx ON snapshots (build_id);\nCREATE TABLE IF NOT EXISTS baselines (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n story_id TEXT NOT NULL,\n viewport_name TEXT NOT NULL DEFAULT 'desktop',\n branch TEXT NOT NULL,\n snapshot_id TEXT,\n screenshot_path TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS baselines_project_story_viewport_branch_idx ON baselines (project_id, story_id, viewport_name, branch);\nCREATE INDEX IF NOT EXISTS baselines_project_story_idx ON baselines (project_id, story_id);\nCREATE TABLE IF NOT EXISTS comments (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n snapshot_id TEXT REFERENCES snapshots(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n body TEXT NOT NULL,\n parent_id TEXT,\n resolved INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS comments_build_id_idx ON comments (build_id);\nCREATE TABLE IF NOT EXISTS label_types (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n key TEXT NOT NULL,\n name TEXT NOT NULL,\n link_template TEXT,\n color TEXT,\n created_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS label_types_project_key_idx ON label_types (project_id, key);\nCREATE TABLE IF NOT EXISTS build_labels (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n build_id TEXT NOT NULL REFERENCES builds(id) ON DELETE CASCADE,\n type_key TEXT NOT NULL,\n value TEXT NOT NULL,\n created_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS build_labels_build_type_value_idx ON build_labels (build_id, type_key, value);\nCREATE TABLE IF NOT EXISTS tokens (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n hash TEXT NOT NULL UNIQUE,\n last_used_at TEXT,\n created_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS webhooks (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n url TEXT NOT NULL,\n secret_encrypted TEXT NOT NULL,\n events TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS users (\n id TEXT PRIMARY KEY,\n email TEXT NOT NULL UNIQUE,\n name TEXT NOT NULL,\n avatar_url TEXT,\n role TEXT NOT NULL DEFAULT 'member',\n last_login_at TEXT,\n created_at TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS project_members (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n role TEXT NOT NULL DEFAULT 'viewer',\n created_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS project_members_project_user_idx ON project_members (project_id, user_id);\n";
6
- //#endregion
7
- export { DDL };
8
- //# sourceMappingURL=ddl.d.mts.map