cursedbelt-server 1.0.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 (606) hide show
  1. package/LICENSE +15 -0
  2. package/dist/server/activity/index.d.ts +36 -0
  3. package/dist/server/activity/index.js +36 -0
  4. package/dist/server/activity/migrations.d.ts +21 -0
  5. package/dist/server/activity/migrations.js +55 -0
  6. package/dist/server/activity/shareSource.d.ts +11 -0
  7. package/dist/server/activity/shareSource.js +45 -0
  8. package/dist/server/activity/store.d.ts +123 -0
  9. package/dist/server/activity/store.js +178 -0
  10. package/dist/server/app.d.ts +56 -0
  11. package/dist/server/app.js +45 -0
  12. package/dist/server/audit/index.d.ts +2 -0
  13. package/dist/server/audit/index.js +2 -0
  14. package/dist/server/audit/migrations.d.ts +2 -0
  15. package/dist/server/audit/migrations.js +79 -0
  16. package/dist/server/audit/sqliteSink.d.ts +36 -0
  17. package/dist/server/audit/sqliteSink.js +95 -0
  18. package/dist/server/audit/sqliteSink.test.d.ts +1 -0
  19. package/dist/server/audit/sqliteSink.test.js +180 -0
  20. package/dist/server/auth/cookie.d.ts +22 -0
  21. package/dist/server/auth/cookie.js +35 -0
  22. package/dist/server/auth/csrf.d.ts +42 -0
  23. package/dist/server/auth/csrf.js +36 -0
  24. package/dist/server/auth/fileTokenSigner.d.ts +10 -0
  25. package/dist/server/auth/fileTokenSigner.js +22 -0
  26. package/dist/server/auth/getOnly.d.ts +20 -0
  27. package/dist/server/auth/getOnly.js +27 -0
  28. package/dist/server/auth/index.d.ts +12 -0
  29. package/dist/server/auth/index.js +15 -0
  30. package/dist/server/auth/jwt.d.ts +18 -0
  31. package/dist/server/auth/jwt.js +56 -0
  32. package/dist/server/auth/loginThrottle.d.ts +118 -0
  33. package/dist/server/auth/loginThrottle.js +204 -0
  34. package/dist/server/auth/middleware.d.ts +14 -0
  35. package/dist/server/auth/middleware.js +47 -0
  36. package/dist/server/auth/password.d.ts +14 -0
  37. package/dist/server/auth/password.js +65 -0
  38. package/dist/server/auth/sessionStore.d.ts +19 -0
  39. package/dist/server/auth/sessionStore.js +221 -0
  40. package/dist/server/auth/totp.d.ts +34 -0
  41. package/dist/server/auth/totp.js +81 -0
  42. package/dist/server/auth/types.d.ts +133 -0
  43. package/dist/server/auth/types.js +1 -0
  44. package/dist/server/auth/vault.d.ts +27 -0
  45. package/dist/server/auth/vault.js +57 -0
  46. package/dist/server/context.d.ts +35 -0
  47. package/dist/server/context.js +1 -0
  48. package/dist/server/ctgr.d.ts +32 -0
  49. package/dist/server/ctgr.js +69 -0
  50. package/dist/server/db/kysely.d.ts +14 -0
  51. package/dist/server/db/kysely.js +16 -0
  52. package/dist/server/db/plumbingTypes.d.ts +116 -0
  53. package/dist/server/db/plumbingTypes.js +12 -0
  54. package/dist/server/dropzone/duplicates.d.ts +82 -0
  55. package/dist/server/dropzone/duplicates.js +90 -0
  56. package/dist/server/dropzone/index.d.ts +13 -0
  57. package/dist/server/dropzone/index.js +13 -0
  58. package/dist/server/dropzone/scan.d.ts +166 -0
  59. package/dist/server/dropzone/scan.js +272 -0
  60. package/dist/server/errors.d.ts +7 -0
  61. package/dist/server/errors.js +7 -0
  62. package/dist/server/guard/argon2Binding.d.ts +97 -0
  63. package/dist/server/guard/argon2Binding.js +138 -0
  64. package/dist/server/guard/index.d.ts +4 -0
  65. package/dist/server/guard/index.js +6 -0
  66. package/dist/server/guard/kdfWorker.d.ts +101 -0
  67. package/dist/server/guard/kdfWorker.js +301 -0
  68. package/dist/server/guard/kdfWorkerEntry.d.ts +1 -0
  69. package/dist/server/guard/kdfWorkerEntry.js +15 -0
  70. package/dist/server/guard/passwordVerifier.d.ts +65 -0
  71. package/dist/server/guard/passwordVerifier.js +122 -0
  72. package/dist/server/guard/revocationStore.d.ts +132 -0
  73. package/dist/server/guard/revocationStore.js +211 -0
  74. package/dist/server/guard/sessionSigner.d.ts +132 -0
  75. package/dist/server/guard/sessionSigner.js +303 -0
  76. package/dist/server/guard/verifier.d.ts +21 -0
  77. package/dist/server/guard/verifier.js +1 -0
  78. package/dist/server/incidents/channels.d.ts +161 -0
  79. package/dist/server/incidents/channels.js +357 -0
  80. package/dist/server/incidents/checks.d.ts +61 -0
  81. package/dist/server/incidents/checks.js +55 -0
  82. package/dist/server/incidents/index.d.ts +51 -0
  83. package/dist/server/incidents/index.js +51 -0
  84. package/dist/server/incidents/migrations.d.ts +20 -0
  85. package/dist/server/incidents/migrations.js +58 -0
  86. package/dist/server/incidents/notifier.d.ts +79 -0
  87. package/dist/server/incidents/notifier.js +141 -0
  88. package/dist/server/incidents/reporter.d.ts +60 -0
  89. package/dist/server/incidents/reporter.js +49 -0
  90. package/dist/server/incidents/routes.d.ts +91 -0
  91. package/dist/server/incidents/routes.js +202 -0
  92. package/dist/server/incidents/store.d.ts +75 -0
  93. package/dist/server/incidents/store.js +176 -0
  94. package/dist/server/incidents/types.d.ts +107 -0
  95. package/dist/server/incidents/types.js +32 -0
  96. package/dist/server/index.d.ts +25 -0
  97. package/dist/server/index.js +53 -0
  98. package/dist/server/jobs/fireQueue.d.ts +12 -0
  99. package/dist/server/jobs/fireQueue.js +37 -0
  100. package/dist/server/jobs/index.d.ts +6 -0
  101. package/dist/server/jobs/index.js +10 -0
  102. package/dist/server/jobs/logger.d.ts +10 -0
  103. package/dist/server/jobs/logger.js +14 -0
  104. package/dist/server/jobs/plainjobAdapter.d.ts +19 -0
  105. package/dist/server/jobs/plainjobAdapter.js +48 -0
  106. package/dist/server/jobs/polling.d.ts +17 -0
  107. package/dist/server/jobs/polling.js +79 -0
  108. package/dist/server/jobs/runner.d.ts +24 -0
  109. package/dist/server/jobs/runner.js +186 -0
  110. package/dist/server/jobs/timeout.d.ts +28 -0
  111. package/dist/server/jobs/timeout.js +47 -0
  112. package/dist/server/jobs/types.d.ts +167 -0
  113. package/dist/server/jobs/types.js +12 -0
  114. package/dist/server/master-lock/guard.d.ts +53 -0
  115. package/dist/server/master-lock/guard.js +205 -0
  116. package/dist/server/master-lock/index.d.ts +21 -0
  117. package/dist/server/master-lock/index.js +21 -0
  118. package/dist/server/master-lock/lockPage.d.ts +34 -0
  119. package/dist/server/master-lock/lockPage.js +281 -0
  120. package/dist/server/master-lock/masterLock.d.ts +294 -0
  121. package/dist/server/master-lock/masterLock.js +523 -0
  122. package/dist/server/master-lock/principals.d.ts +76 -0
  123. package/dist/server/master-lock/principals.js +157 -0
  124. package/dist/server/master-lock/seed.d.ts +47 -0
  125. package/dist/server/master-lock/seed.js +93 -0
  126. package/dist/server/master-lock/store.d.ts +19 -0
  127. package/dist/server/master-lock/store.js +20 -0
  128. package/dist/server/media-bun/image.d.ts +7 -0
  129. package/dist/server/media-bun/image.js +96 -0
  130. package/dist/server/media-bun/index.d.ts +4 -0
  131. package/dist/server/media-bun/index.js +10 -0
  132. package/dist/server/media-bun/streaming.d.ts +86 -0
  133. package/dist/server/media-bun/streaming.js +237 -0
  134. package/dist/server/media-bun/video.d.ts +35 -0
  135. package/dist/server/media-bun/video.js +181 -0
  136. package/dist/server/metrics/metricsBuffer.d.ts +39 -0
  137. package/dist/server/metrics/metricsBuffer.js +36 -0
  138. package/dist/server/metrics/normalizeRoute.d.ts +5 -0
  139. package/dist/server/metrics/normalizeRoute.js +58 -0
  140. package/dist/server/middleware/correlationId.d.ts +9 -0
  141. package/dist/server/middleware/correlationId.js +20 -0
  142. package/dist/server/middleware/corsAllowlist.d.ts +38 -0
  143. package/dist/server/middleware/corsAllowlist.js +37 -0
  144. package/dist/server/middleware/errorEnvelope.d.ts +17 -0
  145. package/dist/server/middleware/errorEnvelope.js +32 -0
  146. package/dist/server/middleware/index.d.ts +9 -0
  147. package/dist/server/middleware/index.js +10 -0
  148. package/dist/server/middleware/localOrigin.d.ts +71 -0
  149. package/dist/server/middleware/localOrigin.js +119 -0
  150. package/dist/server/middleware/rateLimit.d.ts +56 -0
  151. package/dist/server/middleware/rateLimit.js +86 -0
  152. package/dist/server/middleware/requestLogger.d.ts +29 -0
  153. package/dist/server/middleware/requestLogger.js +47 -0
  154. package/dist/server/middleware/securityHeaders.d.ts +29 -0
  155. package/dist/server/middleware/securityHeaders.js +44 -0
  156. package/dist/server/middleware/zValidator.d.ts +29 -0
  157. package/dist/server/middleware/zValidator.js +57 -0
  158. package/dist/server/migration/runner.d.ts +42 -0
  159. package/dist/server/migration/runner.js +70 -0
  160. package/dist/server/migration/types.d.ts +16 -0
  161. package/dist/server/migration/types.js +1 -0
  162. package/dist/server/net/outboundGuard.d.ts +30 -0
  163. package/dist/server/net/outboundGuard.js +199 -0
  164. package/dist/server/notifications/hub.d.ts +67 -0
  165. package/dist/server/notifications/hub.js +187 -0
  166. package/dist/server/notifications/index.d.ts +47 -0
  167. package/dist/server/notifications/index.js +46 -0
  168. package/dist/server/notifications/migrations.d.ts +13 -0
  169. package/dist/server/notifications/migrations.js +20 -0
  170. package/dist/server/notifications/routes.d.ts +58 -0
  171. package/dist/server/notifications/routes.js +113 -0
  172. package/dist/server/notifications/service.d.ts +58 -0
  173. package/dist/server/notifications/service.js +41 -0
  174. package/dist/server/paths/appDataHome.d.ts +19 -0
  175. package/dist/server/paths/appDataHome.js +68 -0
  176. package/dist/server/private-media/crypto.d.ts +37 -0
  177. package/dist/server/private-media/crypto.js +111 -0
  178. package/dist/server/private-media/index-store.d.ts +31 -0
  179. package/dist/server/private-media/index-store.js +36 -0
  180. package/dist/server/private-media/mountPrivateRoutes.d.ts +26 -0
  181. package/dist/server/private-media/mountPrivateRoutes.js +219 -0
  182. package/dist/server/private-media/pipeline.d.ts +37 -0
  183. package/dist/server/private-media/pipeline.js +97 -0
  184. package/dist/server/private-media/unlock.d.ts +52 -0
  185. package/dist/server/private-media/unlock.js +55 -0
  186. package/dist/server/resume/index.d.ts +2 -0
  187. package/dist/server/resume/index.js +2 -0
  188. package/dist/server/resume/routes.d.ts +41 -0
  189. package/dist/server/resume/routes.js +50 -0
  190. package/dist/server/resume/store.d.ts +37 -0
  191. package/dist/server/resume/store.js +38 -0
  192. package/dist/server/retention/archive.d.ts +78 -0
  193. package/dist/server/retention/archive.js +284 -0
  194. package/dist/server/retention/fleet.d.ts +50 -0
  195. package/dist/server/retention/fleet.js +66 -0
  196. package/dist/server/retention/index.d.ts +38 -0
  197. package/dist/server/retention/index.js +38 -0
  198. package/dist/server/retention/policy.d.ts +263 -0
  199. package/dist/server/retention/policy.js +264 -0
  200. package/dist/server/retention/store.d.ts +101 -0
  201. package/dist/server/retention/store.js +251 -0
  202. package/dist/server/retention/sweeper.d.ts +69 -0
  203. package/dist/server/retention/sweeper.js +289 -0
  204. package/dist/server/retention/target.d.ts +143 -0
  205. package/dist/server/retention/target.js +438 -0
  206. package/dist/server/search/index.d.ts +2 -0
  207. package/dist/server/search/index.js +6 -0
  208. package/dist/server/search/pgSearchProvider.d.ts +91 -0
  209. package/dist/server/search/pgSearchProvider.js +330 -0
  210. package/dist/server/search/pgSearchProvider.pg.test.d.ts +1 -0
  211. package/dist/server/search/pgSearchProvider.pg.test.js +338 -0
  212. package/dist/server/search/pgSearchSchema.d.ts +81 -0
  213. package/dist/server/search/pgSearchSchema.js +89 -0
  214. package/dist/server/sharing/index.d.ts +18 -0
  215. package/dist/server/sharing/index.js +16 -0
  216. package/dist/server/sharing/migrations.d.ts +6 -0
  217. package/dist/server/sharing/migrations.js +79 -0
  218. package/dist/server/sharing/router.d.ts +111 -0
  219. package/dist/server/sharing/router.js +93 -0
  220. package/dist/server/sharing/sql.d.ts +67 -0
  221. package/dist/server/sharing/sql.js +88 -0
  222. package/dist/server/sharing/store.d.ts +173 -0
  223. package/dist/server/sharing/store.js +484 -0
  224. package/dist/server/sqlite/backup.d.ts +48 -0
  225. package/dist/server/sqlite/backup.js +97 -0
  226. package/dist/server/sqlite/browse.d.ts +42 -0
  227. package/dist/server/sqlite/browse.js +84 -0
  228. package/dist/server/sqlite/export.d.ts +32 -0
  229. package/dist/server/sqlite/export.js +42 -0
  230. package/dist/server/sqlite/fts5.d.ts +106 -0
  231. package/dist/server/sqlite/fts5.js +154 -0
  232. package/dist/server/sqlite/health.d.ts +44 -0
  233. package/dist/server/sqlite/health.js +52 -0
  234. package/dist/server/sqlite/import.d.ts +36 -0
  235. package/dist/server/sqlite/import.js +108 -0
  236. package/dist/server/sqlite/index.d.ts +9 -0
  237. package/dist/server/sqlite/index.js +15 -0
  238. package/dist/server/sqlite/readonlySql.d.ts +15 -0
  239. package/dist/server/sqlite/readonlySql.js +65 -0
  240. package/dist/server/sqlite/stats.d.ts +22 -0
  241. package/dist/server/sqlite/stats.js +32 -0
  242. package/dist/server/sqlite/viewer.d.ts +17 -0
  243. package/dist/server/sqlite/viewer.js +56 -0
  244. package/dist/server/storage/binaryServerProcessing.d.ts +23 -0
  245. package/dist/server/storage/binaryServerProcessing.js +81 -0
  246. package/dist/server/storage/binaryServerStore.d.ts +3 -0
  247. package/dist/server/storage/binaryServerStore.js +95 -0
  248. package/dist/server/storage/diskStore.d.ts +2 -0
  249. package/dist/server/storage/diskStore.js +88 -0
  250. package/dist/server/storage/files/adapter.d.ts +33 -0
  251. package/dist/server/storage/files/adapter.js +203 -0
  252. package/dist/server/storage/files/catalogue.d.ts +72 -0
  253. package/dist/server/storage/files/catalogue.js +1033 -0
  254. package/dist/server/storage/files/chunkedUpload.d.ts +56 -0
  255. package/dist/server/storage/files/chunkedUpload.js +70 -0
  256. package/dist/server/storage/files/fileRoutes.d.ts +51 -0
  257. package/dist/server/storage/files/fileRoutes.js +405 -0
  258. package/dist/server/storage/files/index.d.ts +9 -0
  259. package/dist/server/storage/files/index.js +11 -0
  260. package/dist/server/storage/files/migrations.d.ts +2 -0
  261. package/dist/server/storage/files/migrations.js +163 -0
  262. package/dist/server/storage/files/mimeByExt.d.ts +1 -0
  263. package/dist/server/storage/files/mimeByExt.js +13 -0
  264. package/dist/server/storage/files/stack.d.ts +136 -0
  265. package/dist/server/storage/files/stack.js +132 -0
  266. package/dist/server/storage/files/storageOps.d.ts +54 -0
  267. package/dist/server/storage/files/storageOps.js +110 -0
  268. package/dist/server/storage/files/types.d.ts +261 -0
  269. package/dist/server/storage/files/types.js +22 -0
  270. package/dist/server/storage/imageThumbnail.d.ts +3 -0
  271. package/dist/server/storage/imageThumbnail.js +50 -0
  272. package/dist/server/storage/index.d.ts +15 -0
  273. package/dist/server/storage/index.js +27 -0
  274. package/dist/server/storage/mountMediaRoutes.d.ts +28 -0
  275. package/dist/server/storage/mountMediaRoutes.js +141 -0
  276. package/dist/server/storage/objectStoreMediaStore.d.ts +4 -0
  277. package/dist/server/storage/objectStoreMediaStore.js +57 -0
  278. package/dist/server/storage/s3ObjectStore.d.ts +63 -0
  279. package/dist/server/storage/s3ObjectStore.js +187 -0
  280. package/dist/server/storage/sources.d.ts +47 -0
  281. package/dist/server/storage/sources.js +148 -0
  282. package/dist/server/storage/streamRange.d.ts +19 -0
  283. package/dist/server/storage/streamRange.js +69 -0
  284. package/dist/server/storage/streamToken.d.ts +16 -0
  285. package/dist/server/storage/streamToken.js +54 -0
  286. package/dist/server/storage/transcodeJobs.d.ts +65 -0
  287. package/dist/server/storage/transcodeJobs.js +104 -0
  288. package/dist/server/storage/types.d.ts +193 -0
  289. package/dist/server/storage/types.js +41 -0
  290. package/dist/server/storage/videoDerivativeKeys.d.ts +127 -0
  291. package/dist/server/storage/videoDerivativeKeys.js +149 -0
  292. package/dist/server/storage/videoProcessor.d.ts +30 -0
  293. package/dist/server/storage/videoProcessor.js +148 -0
  294. package/dist/server/sync/alarm.d.ts +34 -0
  295. package/dist/server/sync/alarm.js +91 -0
  296. package/dist/server/sync/commands.d.ts +87 -0
  297. package/dist/server/sync/commands.js +241 -0
  298. package/dist/server/sync/engine.d.ts +62 -0
  299. package/dist/server/sync/engine.js +184 -0
  300. package/dist/server/sync/http.d.ts +106 -0
  301. package/dist/server/sync/http.js +243 -0
  302. package/dist/server/sync/index.d.ts +41 -0
  303. package/dist/server/sync/index.js +41 -0
  304. package/dist/server/sync/opLog.d.ts +61 -0
  305. package/dist/server/sync/opLog.js +96 -0
  306. package/dist/server/sync/planner.d.ts +31 -0
  307. package/dist/server/sync/planner.js +30 -0
  308. package/dist/server/sync/status.d.ts +63 -0
  309. package/dist/server/sync/status.js +49 -0
  310. package/dist/server/sync/timer.d.ts +52 -0
  311. package/dist/server/sync/timer.js +170 -0
  312. package/dist/server/sync/tokens.d.ts +25 -0
  313. package/dist/server/sync/tokens.js +51 -0
  314. package/dist/server/sync/types.d.ts +101 -0
  315. package/dist/server/sync/types.js +29 -0
  316. package/dist/server/ws/eventBus.d.ts +14 -0
  317. package/dist/server/ws/eventBus.js +42 -0
  318. package/dist/server/ws/hub.d.ts +20 -0
  319. package/dist/server/ws/hub.js +154 -0
  320. package/dist/server/ws/index.d.ts +5 -0
  321. package/dist/server/ws/index.js +7 -0
  322. package/dist/server/ws/presence.d.ts +11 -0
  323. package/dist/server/ws/presence.js +20 -0
  324. package/dist/server/ws/room.d.ts +17 -0
  325. package/dist/server/ws/room.js +23 -0
  326. package/dist/server/ws/types.d.ts +122 -0
  327. package/dist/server/ws/types.js +1 -0
  328. package/package.json +234 -0
  329. package/src/declaredDepsAreImported.spec.ts +87 -0
  330. package/src/leafSubpathsImportNothing.spec.ts +358 -0
  331. package/src/lockfileIsTracked.spec.ts +50 -0
  332. package/src/namedSubpathsResolve.spec.ts +122 -0
  333. package/src/noPathDeps.spec.ts +24 -0
  334. package/src/publishShape.spec.ts +89 -0
  335. package/src/server/activity/index.ts +59 -0
  336. package/src/server/activity/migrations.ts +67 -0
  337. package/src/server/activity/shareSource.ts +57 -0
  338. package/src/server/activity/store.spec.ts +255 -0
  339. package/src/server/activity/store.ts +368 -0
  340. package/src/server/app.spec.ts +243 -0
  341. package/src/server/app.ts +89 -0
  342. package/src/server/audit/index.ts +2 -0
  343. package/src/server/audit/migrations.ts +88 -0
  344. package/src/server/audit/sqliteSink.test.ts +200 -0
  345. package/src/server/audit/sqliteSink.ts +162 -0
  346. package/src/server/auth/cookie.spec.ts +46 -0
  347. package/src/server/auth/cookie.ts +42 -0
  348. package/src/server/auth/csrf.spec.ts +81 -0
  349. package/src/server/auth/csrf.ts +83 -0
  350. package/src/server/auth/fileTokenSigner.ts +40 -0
  351. package/src/server/auth/getOnly.spec.ts +53 -0
  352. package/src/server/auth/getOnly.ts +32 -0
  353. package/src/server/auth/index.ts +51 -0
  354. package/src/server/auth/jwt.spec.ts +106 -0
  355. package/src/server/auth/jwt.ts +75 -0
  356. package/src/server/auth/loginThrottle.spec.ts +213 -0
  357. package/src/server/auth/loginThrottle.ts +261 -0
  358. package/src/server/auth/middleware.spec.ts +148 -0
  359. package/src/server/auth/middleware.ts +56 -0
  360. package/src/server/auth/password.spec.ts +48 -0
  361. package/src/server/auth/password.ts +71 -0
  362. package/src/server/auth/sessionStore.spec.ts +189 -0
  363. package/src/server/auth/sessionStore.ts +261 -0
  364. package/src/server/auth/totp.spec.ts +73 -0
  365. package/src/server/auth/totp.ts +92 -0
  366. package/src/server/auth/types.ts +146 -0
  367. package/src/server/auth/vault.spec.ts +51 -0
  368. package/src/server/auth/vault.ts +71 -0
  369. package/src/server/context.ts +37 -0
  370. package/src/server/ctgr.spec.ts +138 -0
  371. package/src/server/ctgr.ts +108 -0
  372. package/src/server/db/kysely.spec.ts +62 -0
  373. package/src/server/db/kysely.ts +21 -0
  374. package/src/server/db/plumbingTypes.ts +126 -0
  375. package/src/server/dropzone/duplicates.ts +121 -0
  376. package/src/server/dropzone/index.ts +30 -0
  377. package/src/server/dropzone/scan.spec.ts +255 -0
  378. package/src/server/dropzone/scan.ts +342 -0
  379. package/src/server/errors.spec.ts +76 -0
  380. package/src/server/errors.ts +22 -0
  381. package/src/server/guard/argon2Binding.spec.ts +117 -0
  382. package/src/server/guard/argon2Binding.ts +195 -0
  383. package/src/server/guard/argon2Kat.spec.ts +250 -0
  384. package/src/server/guard/guard.spec.ts +390 -0
  385. package/src/server/guard/index.ts +6 -0
  386. package/src/server/guard/kdfWorker.spec.ts +283 -0
  387. package/src/server/guard/kdfWorker.ts +367 -0
  388. package/src/server/guard/kdfWorkerEntry.ts +16 -0
  389. package/src/server/guard/passwordVerifier.spec.ts +71 -0
  390. package/src/server/guard/passwordVerifier.ts +175 -0
  391. package/src/server/guard/revocationStore.spec.ts +135 -0
  392. package/src/server/guard/revocationStore.ts +291 -0
  393. package/src/server/guard/sessionSigner.ts +425 -0
  394. package/src/server/guard/verifier.ts +27 -0
  395. package/src/server/incidents/channels.ts +487 -0
  396. package/src/server/incidents/checks.ts +120 -0
  397. package/src/server/incidents/incidents.spec.ts +463 -0
  398. package/src/server/incidents/index.ts +96 -0
  399. package/src/server/incidents/migrations.ts +66 -0
  400. package/src/server/incidents/notifier.ts +215 -0
  401. package/src/server/incidents/reporter.ts +110 -0
  402. package/src/server/incidents/routes.ts +314 -0
  403. package/src/server/incidents/store.ts +329 -0
  404. package/src/server/incidents/types.ts +116 -0
  405. package/src/server/index.ts +248 -0
  406. package/src/server/jobs/fireQueue.spec.ts +85 -0
  407. package/src/server/jobs/fireQueue.ts +37 -0
  408. package/src/server/jobs/index.ts +26 -0
  409. package/src/server/jobs/logger.ts +16 -0
  410. package/src/server/jobs/plainjobAdapter.spec.ts +34 -0
  411. package/src/server/jobs/plainjobAdapter.ts +54 -0
  412. package/src/server/jobs/polling.spec.ts +219 -0
  413. package/src/server/jobs/polling.ts +81 -0
  414. package/src/server/jobs/runner.spec.ts +213 -0
  415. package/src/server/jobs/runner.ts +213 -0
  416. package/src/server/jobs/timeout.spec.ts +35 -0
  417. package/src/server/jobs/timeout.ts +53 -0
  418. package/src/server/jobs/types.ts +188 -0
  419. package/src/server/master-lock/guard.spec.ts +347 -0
  420. package/src/server/master-lock/guard.ts +290 -0
  421. package/src/server/master-lock/index.ts +44 -0
  422. package/src/server/master-lock/lockPage.spec.ts +88 -0
  423. package/src/server/master-lock/lockPage.ts +313 -0
  424. package/src/server/master-lock/masterLock.spec.ts +338 -0
  425. package/src/server/master-lock/masterLock.ts +627 -0
  426. package/src/server/master-lock/principals.spec.ts +378 -0
  427. package/src/server/master-lock/principals.ts +175 -0
  428. package/src/server/master-lock/seed.spec.ts +69 -0
  429. package/src/server/master-lock/seed.ts +112 -0
  430. package/src/server/master-lock/store.ts +35 -0
  431. package/src/server/media-bun/image.spec.ts +115 -0
  432. package/src/server/media-bun/image.ts +134 -0
  433. package/src/server/media-bun/index.ts +52 -0
  434. package/src/server/media-bun/streaming.spec.ts +134 -0
  435. package/src/server/media-bun/streaming.ts +347 -0
  436. package/src/server/media-bun/video.spec.ts +115 -0
  437. package/src/server/media-bun/video.ts +232 -0
  438. package/src/server/metrics/metricsBuffer.ts +92 -0
  439. package/src/server/metrics/normalizeRoute.spec.ts +51 -0
  440. package/src/server/metrics/normalizeRoute.ts +63 -0
  441. package/src/server/middleware/correlationId.ts +24 -0
  442. package/src/server/middleware/corsAllowlist.spec.ts +118 -0
  443. package/src/server/middleware/corsAllowlist.ts +69 -0
  444. package/src/server/middleware/errorEnvelope.ts +38 -0
  445. package/src/server/middleware/index.ts +19 -0
  446. package/src/server/middleware/localOrigin.spec.ts +168 -0
  447. package/src/server/middleware/localOrigin.ts +139 -0
  448. package/src/server/middleware/rateLimit.spec.ts +72 -0
  449. package/src/server/middleware/rateLimit.ts +125 -0
  450. package/src/server/middleware/requestLogger.ts +95 -0
  451. package/src/server/middleware/securityHeaders.ts +78 -0
  452. package/src/server/middleware/zValidator.spec.ts +251 -0
  453. package/src/server/middleware/zValidator.ts +114 -0
  454. package/src/server/migration/runner.spec.ts +88 -0
  455. package/src/server/migration/runner.ts +87 -0
  456. package/src/server/migration/types.ts +17 -0
  457. package/src/server/net/outboundGuard.spec.ts +90 -0
  458. package/src/server/net/outboundGuard.ts +205 -0
  459. package/src/server/notifications/hub.ts +245 -0
  460. package/src/server/notifications/index.ts +77 -0
  461. package/src/server/notifications/migrations.ts +39 -0
  462. package/src/server/notifications/routes.ts +177 -0
  463. package/src/server/notifications/service.spec.ts +305 -0
  464. package/src/server/notifications/service.ts +112 -0
  465. package/src/server/paths/appDataHome.spec.ts +87 -0
  466. package/src/server/paths/appDataHome.ts +84 -0
  467. package/src/server/private-media/blobRoute.spec.ts +165 -0
  468. package/src/server/private-media/crypto.spec.ts +81 -0
  469. package/src/server/private-media/crypto.ts +155 -0
  470. package/src/server/private-media/gatePolicy.spec.ts +98 -0
  471. package/src/server/private-media/index-store.ts +83 -0
  472. package/src/server/private-media/mountPrivateRoutes.ts +265 -0
  473. package/src/server/private-media/pipeline.spec.ts +111 -0
  474. package/src/server/private-media/pipeline.ts +170 -0
  475. package/src/server/private-media/routes.spec.ts +265 -0
  476. package/src/server/private-media/unlock.ts +112 -0
  477. package/src/server/resume/index.ts +8 -0
  478. package/src/server/resume/resume.spec.ts +118 -0
  479. package/src/server/resume/routes.ts +92 -0
  480. package/src/server/resume/store.ts +82 -0
  481. package/src/server/retention/archive.spec.ts +181 -0
  482. package/src/server/retention/archive.ts +353 -0
  483. package/src/server/retention/fleet.ts +104 -0
  484. package/src/server/retention/index.ts +101 -0
  485. package/src/server/retention/policy.spec.ts +132 -0
  486. package/src/server/retention/policy.ts +392 -0
  487. package/src/server/retention/store.spec.ts +236 -0
  488. package/src/server/retention/store.ts +338 -0
  489. package/src/server/retention/sweeper.spec.ts +321 -0
  490. package/src/server/retention/sweeper.ts +367 -0
  491. package/src/server/retention/target.spec.ts +592 -0
  492. package/src/server/retention/target.ts +613 -0
  493. package/src/server/search/index.ts +12 -0
  494. package/src/server/search/pgSearchProvider.pg.test.ts +392 -0
  495. package/src/server/search/pgSearchProvider.ts +421 -0
  496. package/src/server/search/pgSearchSchema.ts +147 -0
  497. package/src/server/sharing/index.ts +65 -0
  498. package/src/server/sharing/migrations.ts +128 -0
  499. package/src/server/sharing/router.spec.ts +167 -0
  500. package/src/server/sharing/router.ts +194 -0
  501. package/src/server/sharing/sql.ts +109 -0
  502. package/src/server/sharing/store.spec.ts +408 -0
  503. package/src/server/sharing/store.ts +737 -0
  504. package/src/server/sqlite/backup.spec.ts +114 -0
  505. package/src/server/sqlite/backup.ts +154 -0
  506. package/src/server/sqlite/browse.spec.ts +70 -0
  507. package/src/server/sqlite/browse.ts +120 -0
  508. package/src/server/sqlite/export.spec.ts +43 -0
  509. package/src/server/sqlite/export.ts +74 -0
  510. package/src/server/sqlite/fts5.spec.ts +175 -0
  511. package/src/server/sqlite/fts5.ts +255 -0
  512. package/src/server/sqlite/health.spec.ts +79 -0
  513. package/src/server/sqlite/health.ts +105 -0
  514. package/src/server/sqlite/import.spec.ts +75 -0
  515. package/src/server/sqlite/import.ts +141 -0
  516. package/src/server/sqlite/index.ts +64 -0
  517. package/src/server/sqlite/readonlySql.spec.ts +58 -0
  518. package/src/server/sqlite/readonlySql.ts +67 -0
  519. package/src/server/sqlite/stats.spec.ts +21 -0
  520. package/src/server/sqlite/stats.ts +61 -0
  521. package/src/server/sqlite/viewer.spec.ts +127 -0
  522. package/src/server/sqlite/viewer.ts +72 -0
  523. package/src/server/storage/binaryServerProcessing.integration.spec.ts +222 -0
  524. package/src/server/storage/binaryServerProcessing.spec.ts +150 -0
  525. package/src/server/storage/binaryServerProcessing.ts +127 -0
  526. package/src/server/storage/binaryServerStore.ts +102 -0
  527. package/src/server/storage/chunked.integration.spec.ts +185 -0
  528. package/src/server/storage/diskStore.ts +83 -0
  529. package/src/server/storage/files/adapter.photo.display.spec.ts +169 -0
  530. package/src/server/storage/files/adapter.photo.spec.ts +128 -0
  531. package/src/server/storage/files/adapter.spec.ts +121 -0
  532. package/src/server/storage/files/adapter.ts +255 -0
  533. package/src/server/storage/files/catalogue.media-host.spec.ts +184 -0
  534. package/src/server/storage/files/catalogue.orderings.spec.ts +157 -0
  535. package/src/server/storage/files/catalogue.private.spec.ts +106 -0
  536. package/src/server/storage/files/catalogue.recover.spec.ts +131 -0
  537. package/src/server/storage/files/catalogue.sort.spec.ts +154 -0
  538. package/src/server/storage/files/catalogue.spec.ts +133 -0
  539. package/src/server/storage/files/catalogue.trash-import.spec.ts +125 -0
  540. package/src/server/storage/files/catalogue.ts +1326 -0
  541. package/src/server/storage/files/chunkedUpload.spec.ts +111 -0
  542. package/src/server/storage/files/chunkedUpload.ts +146 -0
  543. package/src/server/storage/files/collections.spec.ts +294 -0
  544. package/src/server/storage/files/fileRoutes.replace.spec.ts +88 -0
  545. package/src/server/storage/files/fileRoutes.spec.ts +327 -0
  546. package/src/server/storage/files/fileRoutes.ts +462 -0
  547. package/src/server/storage/files/index.ts +66 -0
  548. package/src/server/storage/files/migrations.ts +187 -0
  549. package/src/server/storage/files/mimeByExt.ts +14 -0
  550. package/src/server/storage/files/stack.spec.ts +258 -0
  551. package/src/server/storage/files/stack.ts +284 -0
  552. package/src/server/storage/files/storageOps.spec.ts +126 -0
  553. package/src/server/storage/files/storageOps.ts +213 -0
  554. package/src/server/storage/files/types.ts +285 -0
  555. package/src/server/storage/imageThumbnail.spec.ts +81 -0
  556. package/src/server/storage/imageThumbnail.ts +60 -0
  557. package/src/server/storage/index.ts +122 -0
  558. package/src/server/storage/mountMediaRoutes.ts +231 -0
  559. package/src/server/storage/objectStore.spec.ts +272 -0
  560. package/src/server/storage/objectStoreMediaStore.ts +63 -0
  561. package/src/server/storage/s3ObjectStore.ts +239 -0
  562. package/src/server/storage/sources.ts +245 -0
  563. package/src/server/storage/storage.spec.ts +219 -0
  564. package/src/server/storage/streamRange.ts +92 -0
  565. package/src/server/storage/streamToken.ts +76 -0
  566. package/src/server/storage/transcode.integration.spec.ts +134 -0
  567. package/src/server/storage/transcodeJobs.spec.ts +152 -0
  568. package/src/server/storage/transcodeJobs.ts +171 -0
  569. package/src/server/storage/types.ts +230 -0
  570. package/src/server/storage/videoDerivativeKeys.spec.ts +112 -0
  571. package/src/server/storage/videoDerivativeKeys.ts +172 -0
  572. package/src/server/storage/videoProcessor.posterOnly.spec.ts +106 -0
  573. package/src/server/storage/videoProcessor.ts +229 -0
  574. package/src/server/sync/alarm.spec.ts +149 -0
  575. package/src/server/sync/alarm.ts +137 -0
  576. package/src/server/sync/commands.spec.ts +145 -0
  577. package/src/server/sync/commands.ts +361 -0
  578. package/src/server/sync/engine.spec.ts +496 -0
  579. package/src/server/sync/engine.ts +255 -0
  580. package/src/server/sync/http.ts +316 -0
  581. package/src/server/sync/httpRemote.spec.ts +158 -0
  582. package/src/server/sync/index.ts +90 -0
  583. package/src/server/sync/opLog.spec.ts +110 -0
  584. package/src/server/sync/opLog.ts +189 -0
  585. package/src/server/sync/planner.spec.ts +53 -0
  586. package/src/server/sync/planner.ts +62 -0
  587. package/src/server/sync/status.spec.ts +92 -0
  588. package/src/server/sync/status.ts +108 -0
  589. package/src/server/sync/timer.spec.ts +150 -0
  590. package/src/server/sync/timer.ts +207 -0
  591. package/src/server/sync/tokens.spec.ts +38 -0
  592. package/src/server/sync/tokens.ts +94 -0
  593. package/src/server/sync/types.ts +108 -0
  594. package/src/server/ws/eventBus.spec.ts +67 -0
  595. package/src/server/ws/eventBus.ts +46 -0
  596. package/src/server/ws/hub.integration.spec.ts +93 -0
  597. package/src/server/ws/hub.spec.ts +282 -0
  598. package/src/server/ws/hub.ts +168 -0
  599. package/src/server/ws/index.ts +20 -0
  600. package/src/server/ws/presence.spec.ts +27 -0
  601. package/src/server/ws/presence.ts +26 -0
  602. package/src/server/ws/room.spec.ts +36 -0
  603. package/src/server/ws/room.ts +29 -0
  604. package/src/server/ws/types.ts +134 -0
  605. package/src/skippedTestsAreAnswered.spec.ts +215 -0
  606. package/src/testTmpRoot.spec.ts +102 -0
@@ -0,0 +1,50 @@
1
+ /**
2
+ * 🔴 Rule 2 of this generation: `bun install --frozen-lockfile` must pass on a
3
+ * CLEAN CHECKOUT — not merely in the tree an agent happens to be sitting in.
4
+ *
5
+ * ── What this cost, 2026-09-13 ──────────────────────────────────────────────
6
+ * `.gitignore` carried a `bun.lock` stanza with a comment explaining it was
7
+ * temporary: the only lockfile that could exist at the time recorded a
8
+ * proof-only local pack of `cwip`, and committing that would have reintroduced
9
+ * the `file:` dependency the package had just removed. The reasoning was sound
10
+ * and the expiry condition — "until cwip is on the registry" — was real. It was
11
+ * also written in a comment, which nothing can evaluate. `cwip@3.0.2` went to
12
+ * the registry and the stanza stayed, so rule 2 was true of every working tree
13
+ * and false of every fresh clone: exactly the case the rule exists for, and the
14
+ * one nobody hits until they are the person doing the clone.
15
+ *
16
+ * A temporary ignore needs a check that notices when it stopped being true.
17
+ * This is that check. `git check-ignore` is the whole mechanism, because the
18
+ * failure is not "the lockfile is missing" — it is "git has been told to throw
19
+ * it away", which is invisible in a tree that already has one.
20
+ *
21
+ * Deliberately NOT `git ls-files bun.lock`: a regenerated lockfile is untracked
22
+ * until it is staged, and a check that reds on work-in-progress teaches people
23
+ * to skip it. Ignored-vs-not is the property that actually regresses.
24
+ */
25
+ import { describe, expect, test } from 'bun:test'
26
+ import { spawnSync } from 'node:child_process'
27
+ import { existsSync } from 'node:fs'
28
+ import { fileURLToPath } from 'node:url'
29
+
30
+ const repoRoot = fileURLToPath(new URL('..', import.meta.url))
31
+
32
+ describe('bun.lock is part of the checkout', () => {
33
+ test('the lockfile exists', () => {
34
+ expect(
35
+ existsSync(new URL('../bun.lock', import.meta.url)),
36
+ 'no bun.lock — regenerate it with `bun install`, or `bun install --frozen-lockfile` cannot pass for anyone cloning this',
37
+ ).toBe(true)
38
+ })
39
+
40
+ test('git is not told to ignore it', () => {
41
+ const git = spawnSync('git', ['check-ignore', '-q', 'bun.lock'], { cwd: repoRoot })
42
+ if (git.error) return // no git on this host: nothing to assert about ignore rules
43
+
44
+ // exit 0 = the path IS ignored; 1 = it is not; anything else = git could not tell us.
45
+ expect(
46
+ git.status,
47
+ 'bun.lock is gitignored, so a fresh clone has no lockfile and `bun install --frozen-lockfile` cannot pass there. Delete the stanza from .gitignore rather than the assertion.',
48
+ ).not.toBe(0)
49
+ })
50
+ })
@@ -0,0 +1,122 @@
1
+ import { describe, expect, it } from 'bun:test';
2
+ import pkg from '../package.json';
3
+
4
+ /**
5
+ * Every `cursedbelt/<subpath>` this repo NAMES must be one it actually exports
6
+ * (2026-09-13).
7
+ *
8
+ * Removing the 23 subpaths nothing referenced left 19 sentences in `src` and
9
+ * `docs` still advertising them — `cursedbelt/ctgr`, `cursedbelt/server/media`,
10
+ * `cursedbelt/tokens` and friends, each one a copy-pasteable import that now
11
+ * throws ERR_PACKAGE_PATH_NOT_EXPORTED. Nothing could see them, because a
12
+ * subpath named in prose is invisible to `tsc` (it is a comment), invisible to
13
+ * Biome (it is a string), and invisible to `check-paths.ts` (it is not a
14
+ * filesystem path). The only reason those 19 were found is that one agent
15
+ * grepped for them by hand while deleting the exports.
16
+ *
17
+ * That is the drift this file exists to make impossible: the manifest and the
18
+ * prose describing it can no longer disagree without something going red.
19
+ *
20
+ * 🔴 Bun.Glob + Bun.file, NOT node:fs — this package's test preload virtualizes
21
+ * node:fs, so a readdirSync/readFileSync scan reads MOCK data and passes against
22
+ * files it never opened. Same trap as publishShape.spec.ts; see its header.
23
+ *
24
+ * Escape hatch: a line that must name a removed subpath (a changelog entry, a
25
+ * migration note) carries `subpath-check:ignore` and is skipped.
26
+ */
27
+ const ROOTS = ['src', 'scripts', 'docs'] as const;
28
+
29
+ const BINARY = /\.(png|jpe?g|gif|webp|avif|ico|mp4|webm|mp3|wav|pdf|zip|gz|woff2?|ttf|otf|eot|wasm)$/i;
30
+
31
+ const IGNORE = 'subpath-check:ignore';
32
+
33
+ /**
34
+ * `cursedbelt/<subpath>` wherever it appears — code, comment or markdown. The
35
+ * trailing class stops `cursedbelt/react` from matching inside
36
+ * `cursedbelt/react/timeline`, so a removed deep subpath cannot hide behind a
37
+ * live shallow one.
38
+ *
39
+ * The leading `(?<![\w/.-])` is what separates an IMPORT SPECIFIER from a REPO
40
+ * PATH: `packages/cursedbelt/src/...` and `../cursedbelt/scripts/...` name files
41
+ * on disk (check-paths.ts' job), not subpaths, and flagging them would make this
42
+ * gate unpassable and therefore useless.
43
+ */
44
+ // Parameterized on pkg.name since the 2026-09-15 split: in THIS repo a bare
45
+ // `cursedbelt/...` mention names the react package's surface, not ours, and
46
+ // only `cursedbelt-core/...` mentions are checkable against our own manifest.
47
+ const NAMED = new RegExp(String.raw`(?<![\w/.-])${pkg.name}(\/[a-z0-9][a-z0-9._/-]*[a-z0-9])`, 'gi');
48
+
49
+ /** First segment is a directory in THIS repo ⇒ the mention is a file path. */
50
+ const REPO_DIRS = /^\/(src|scripts|dist|docs|e2e|demo|node_modules|releases)(\/|$)/;
51
+
52
+ /**
53
+ * Ends in a file extension ⇒ a file path, not a subpath — except the three CSS
54
+ * entries, which genuinely ARE exports (`cursedbelt/styles.css`).
55
+ */
56
+ const FILE_EXT = /\.(?!css$)[a-z0-9]+$/i;
57
+
58
+ const exported = new Set(Object.keys(pkg.exports).map((k) => k.replace(/^\./, '')));
59
+
60
+ // This file and the task/report prose quoting the removal are allowed to name them.
61
+ const SELF = 'namedSubpathsResolve.spec.ts';
62
+
63
+ type Offence = { file: string; line: number; subpath: string; text: string };
64
+
65
+ let cache: Promise<Offence[]> | undefined;
66
+ const offences = (): Promise<Offence[]> => {
67
+ cache ??= (async () => {
68
+ const repo = `${import.meta.dir}/..`;
69
+ const found: Offence[] = [];
70
+ for (const root of ROOTS) {
71
+ const dir = `${repo}/${root}`;
72
+ for (const rel of new Bun.Glob('**/*').scanSync({ cwd: dir, onlyFiles: true })) {
73
+ if (BINARY.test(rel) || rel.endsWith(SELF)) continue;
74
+ const text = await Bun.file(`${dir}/${rel}`).text();
75
+ const lines = text.split('\n');
76
+ for (let i = 0; i < lines.length; i++) {
77
+ const line = lines[i] ?? '';
78
+ if (line.includes(IGNORE)) continue;
79
+ for (const m of line.matchAll(NAMED)) {
80
+ const subpath = m[1] ?? '';
81
+ if (exported.has(subpath)) continue;
82
+ if (REPO_DIRS.test(subpath) || FILE_EXT.test(subpath)) continue;
83
+ found.push({ file: `${root}/${rel}`, line: i + 1, subpath, text: line.trim() });
84
+ }
85
+ }
86
+ }
87
+ }
88
+ return found;
89
+ })();
90
+ return cache;
91
+ };
92
+
93
+ describe('subpaths named in this repo resolve', () => {
94
+ it('has scanned a real source tree', async () => {
95
+ // Guards the whole file: if the glob or the fs mock ever returns nothing,
96
+ // the assertion below passes vacuously and the gate quietly dies.
97
+ const repo = `${import.meta.dir}/..`;
98
+ let seen = 0;
99
+ for (const root of ROOTS) {
100
+ for (const _ of new Bun.Glob('**/*').scanSync({ cwd: `${repo}/${root}`, onlyFiles: true })) seen++;
101
+ }
102
+ expect(seen).toBeGreaterThan(100);
103
+ });
104
+
105
+ it('knows what the manifest exports', () => {
106
+ // If `exports` is ever read wrong, every offence below silently becomes one.
107
+ expect(exported.has('')).toBe(true); // the "." root entry
108
+ expect(exported.has('/master-lock')).toBe(true);
109
+ expect(exported.has('/react')).toBe(false); // the react tier stayed in `cursedbelt` at the 2026-09-15 split
110
+ });
111
+
112
+ it('names no subpath package.json does not export', async () => {
113
+ const dead = await offences();
114
+ expect(
115
+ dead,
116
+ `these name a cursedbelt subpath that is not in package.json exports — a consumer who\n` +
117
+ `copies one gets ERR_PACKAGE_PATH_NOT_EXPORTED. Point at the surviving subpath, or at\n` +
118
+ `the repo path, or mark the line \`${IGNORE}\`:\n` +
119
+ dead.map((d) => ` ${d.file}:${d.line} cursedbelt${d.subpath}\n ${d.text}`).join('\n'),
120
+ ).toEqual([]);
121
+ });
122
+ });
@@ -0,0 +1,24 @@
1
+ import { describe, expect, it } from 'bun:test';
2
+ import pkg from '../package.json';
3
+
4
+ /**
5
+ * Rule 1 of `~/code` (2026-09-12): share by published version, never by path.
6
+ *
7
+ * `file:`, `link:`, `workspace:*` and a directory-valued `overrides` entry each
8
+ * defeat `bun install --frozen-lockfile`, and a `file:` install is served from a
9
+ * cache keyed on the VERSION STRING — so re-packing the same version silently
10
+ * ships stale bytes straight through `bun install --force`. That is the defect
11
+ * that made a `cursed-satellites` change cost twenty minutes; this is the line
12
+ * that stops it coming back one convenient shortcut at a time.
13
+ */
14
+ const PATHY = /^(file:|link:|workspace:|portal:)/;
15
+
16
+ describe('no path dependencies', () => {
17
+ for (const field of ['dependencies', 'devDependencies', 'peerDependencies', 'overrides'] as const) {
18
+ it(`${field} names no path-valued spec`, () => {
19
+ const block = (pkg as Record<string, unknown>)[field] as Record<string, string> | undefined;
20
+ const bad = Object.entries(block ?? {}).filter(([, v]) => typeof v === 'string' && PATHY.test(v));
21
+ expect(bad, `share by published version, never by path:\n ${bad.map(([k, v]) => `${k} = ${v}`).join('\n ')}`).toEqual([]);
22
+ });
23
+ }
24
+ });
@@ -0,0 +1,89 @@
1
+ import { describe, expect, it } from 'bun:test';
2
+ import pkg from '../package.json';
3
+
4
+ /**
5
+ * What this exists for (2026-09-12).
6
+ *
7
+ * Two ways this package can publish something that installs clean and does not
8
+ * work, both found the hard way while extracting it from the monorepo:
9
+ *
10
+ * 1. `exports` resolves the `bun` and `source` conditions to `./src/*.ts`, but
11
+ * `files` shipped only `dist`. Every consumer runs bun, so every subpath
12
+ * resolved to a path that was not in the tarball. Invisible under a `file:`
13
+ * link, because the whole directory was there.
14
+ *
15
+ * 2. A `tsc` run with no tsconfig falls back to defaults and emits `.js`/`.d.ts`
16
+ * NEXT TO the sources. Those get packed, and a consumer's bun condition then
17
+ * loads the stale `.js` instead of the `.ts` — a second module instance, so
18
+ * every module-level singleton silently doubles.
19
+ *
20
+ * Both are one assertion each, and both fail loudly at `bun test` rather than at
21
+ * a consumer's runtime three repos away.
22
+ */
23
+ // 🔴 Bun.Glob, NOT node:fs: this package's own test preload virtualizes node:fs
24
+ // (`[cwip/testing] System mocks enabled`), so readdirSync here returns MOCK data
25
+ // and the assertion below passes against a directory it never read. Cost an hour
26
+ // to find; the scan must not go through a mocked module.
27
+ const emittedInSrc = (): string[] => {
28
+ const all = new Set([...new Bun.Glob('**/*').scanSync({ cwd: import.meta.dir })]);
29
+ // A hand-written ambient declaration (css.d.ts) has no .ts sibling and is
30
+ // legitimate; an EMITTED one always sits next to the source it came from.
31
+ return [...all].filter((f) => {
32
+ if (f.endsWith('.js') || f.endsWith('.js.map')) return true;
33
+ if (!f.endsWith('.d.ts')) return false;
34
+ return all.has(`${f.slice(0, -5)}.ts`) || all.has(`${f.slice(0, -5)}.tsx`);
35
+ });
36
+ };
37
+
38
+ describe('publish shape', () => {
39
+ it('ships every directory its exports resolve into', () => {
40
+ const files = (pkg as { files?: string[] }).files ?? [];
41
+ const roots = new Set<string>();
42
+ for (const entry of Object.values((pkg as { exports: Record<string, unknown> }).exports)) {
43
+ if (typeof entry !== 'object' || entry === null) continue;
44
+ for (const target of Object.values(entry as Record<string, string>)) {
45
+ if (typeof target === 'string' && target.startsWith('./')) {
46
+ const top = target.slice(2).split('/')[0];
47
+ if (top !== undefined) roots.add(top);
48
+ }
49
+ }
50
+ }
51
+ for (const root of roots) {
52
+ expect(
53
+ files.some((f) => f === root || f.startsWith(`${root}/`)),
54
+ `exports resolve into "${root}/" but package.json files does not ship it`,
55
+ ).toBe(true);
56
+ }
57
+ });
58
+
59
+ it('has no compiled output sitting in src', () => {
60
+ const emitted = emittedInSrc();
61
+ expect(emitted, `tsc emitted into src instead of dist:\n ${emitted.slice(0, 10).join('\n ')}`).toEqual([]);
62
+ });
63
+
64
+ it('declares bin paths npm will actually keep', () => {
65
+ // npm rejects a "./"-prefixed bin value, calls the NAME invalid, and drops
66
+ // the entry — with a warning, not an error. The package publishes fine and
67
+ // installs with no CLI at all. Invisible under a file: link, where the bin
68
+ // is linked from the source manifest before npm ever normalises it.
69
+ const bin = (pkg as { bin?: Record<string, string> }).bin ?? {};
70
+ const prefixed = Object.entries(bin).filter(([, v]) => v.startsWith('./'));
71
+ expect(
72
+ prefixed,
73
+ `npm drops "./"-prefixed bin entries on publish:\n ${prefixed.map(([k, v]) => `${k} = ${v}`).join('\n ')}`,
74
+ ).toEqual([]);
75
+ });
76
+
77
+ it('lists "types" first in every conditional export', () => {
78
+ // Condition order is significant and "types" must win, or tsc resolves the
79
+ // `bun`/`source` condition and typechecks our shipped .ts instead of the
80
+ // .d.ts. A consumer then inherits type errors from OUR optional peers —
81
+ // cursedbelt could not typecheck against cwip because `unpdf`, an optional
82
+ // peer it does not install, was reachable through cwip/src.
83
+ const wrong = Object.entries((pkg as { exports: Record<string, unknown> }).exports)
84
+ .filter(([, e]) => typeof e === 'object' && e !== null && 'types' in e)
85
+ .filter(([, e]) => Object.keys(e as object)[0] !== 'types')
86
+ .map(([k]) => k);
87
+ expect(wrong, `"types" must be the first condition:\n ${wrong.join('\n ')}`).toEqual([]);
88
+ });
89
+ });
@@ -0,0 +1,59 @@
1
+ /**
2
+ * `cursedbelt-server/activity` — the fleet's ONE append-only activity/audit
3
+ * stream: who did what, to which record, when, and how it went.
4
+ *
5
+ * The vocabulary is `cursedbelt-core/activity` (pure), this is the storage + query
6
+ * half, and the console's **Event Logs** tab is the fleet-wide reader — it asks
7
+ * every live deployment through `satellite-kit/metrics`' bearer-gated
8
+ * `?view=events`, so an app is on the board by writing events, with no
9
+ * admin-side wiring at all.
10
+ *
11
+ * ── Retention ───────────────────────────────────────────────────────────────
12
+ * This package never deletes an event. An app whose stream is high-volume opts
13
+ * into the fleet standard (`docs/retention.md` in `cursed-satellites`) by
14
+ * declaring the table, which puts the number under the owner's control in the
15
+ * station rather than in a constant here:
16
+ *
17
+ * ```ts
18
+ * createSqliteTableTarget({
19
+ * db, table: ACTIVITY_EVENTS_TABLE, timeColumn: "at", timeFormat: "iso",
20
+ * declaration: { app: "notes", id: "activity", label: "Activity log",
21
+ * category: "event-log", unit: "rows", location: "notes.sqlite · activity_events",
22
+ * consequence: "Who did what, for hindsight. Losing it costs no data." },
23
+ * })
24
+ * ```
25
+ *
26
+ * An app whose stream is a handful of rows a month — an audit of destructive
27
+ * actions, say — is right to declare NOTHING and say so: the standard is opt-in
28
+ * by category, and an audit trail of production deletions is precisely the data
29
+ * a 14-day cutoff must not reach.
30
+ */
31
+ export { ACTIVITY_EVENTS_TABLE, ACTIVITY_MIGRATIONS } from "./migrations";
32
+ export { shareEventsSource, type ShareEventsSourceOptions } from "./shareSource";
33
+ export { createActivityLog } from "./store";
34
+ export type {
35
+ ActivityFacet,
36
+ ActivityFacets,
37
+ ActivityLog,
38
+ ActivityLogOptions,
39
+ ActivityPage,
40
+ ActivityQuery,
41
+ ActivitySource,
42
+ } from "./store";
43
+ // Re-exported so a server consumer needs ONE import for the whole contract; the
44
+ // pure entry (`cursedbelt-core/activity`) stays available for a browser or a spec.
45
+ export {
46
+ ACTIVITY_OUTCOMES,
47
+ activityFromShareEvent,
48
+ activitySubject,
49
+ describeActivityEvent,
50
+ describeActivityResource,
51
+ isActivityAction,
52
+ isActivityOutcome,
53
+ } from "cursedbelt-core/activity/model";
54
+ export type {
55
+ ActivityEvent,
56
+ ActivityEventInput,
57
+ ActivityOutcome,
58
+ ActivityResource,
59
+ } from "cursedbelt-core/activity/model";
@@ -0,0 +1,67 @@
1
+ import type { Database } from "bun:sqlite";
2
+ import type { Migration } from "../migration/types";
3
+
4
+ /** The one table this primitive owns. Exported so an app can declare a retention
5
+ * target over it (see this module's `index.ts` for the recipe). */
6
+ export const ACTIVITY_EVENTS_TABLE = "activity_events";
7
+
8
+ /**
9
+ * ONE append-only table per app, not a shadow table per business table.
10
+ *
11
+ * The stream's whole value is being readable as one list — "everything that
12
+ * happened in `notes` yesterday", "everything `curt@…` did", "everything that
13
+ * touched person `3f2`" — and a per-table history cannot answer any of those
14
+ * without a UNION nobody maintains. `(kind, resource_id)` plays the role a
15
+ * shadow table would, and is a business key the app already has rather than a
16
+ * migration in `cursedbelt`.
17
+ *
18
+ * 🔴 **Append only.** There is no update and no delete verb anywhere in this
19
+ * package. The one sanctioned deleter is the fleet retention standard
20
+ * (`satellite-kit/retention`), which an app opts into by declaring this table as
21
+ * an `event-log`/`audit-log` resource — a control the owner can see and change,
22
+ * rather than a cutoff buried in a store.
23
+ */
24
+ export const ACTIVITY_MIGRATIONS: readonly Migration[] = [
25
+ {
26
+ name: "0001_activity_events",
27
+ up(db: Database): void {
28
+ db.run(`
29
+ CREATE TABLE IF NOT EXISTS ${ACTIVITY_EVENTS_TABLE} (
30
+ event_id INTEGER PRIMARY KEY AUTOINCREMENT,
31
+ at TEXT NOT NULL,
32
+ app TEXT NOT NULL,
33
+ actor TEXT NOT NULL,
34
+ action TEXT NOT NULL,
35
+ kind TEXT,
36
+ resource_id TEXT,
37
+ outcome TEXT NOT NULL DEFAULT 'ok'
38
+ CHECK (outcome IN ('ok', 'denied', 'error')),
39
+ note TEXT NOT NULL DEFAULT '',
40
+ data TEXT
41
+ )
42
+ `);
43
+ // The stream itself, newest first — the read every screen starts from.
44
+ db.run(
45
+ `CREATE INDEX IF NOT EXISTS idx_activity_events_at
46
+ ON ${ACTIVITY_EVENTS_TABLE} (at DESC, event_id DESC)`,
47
+ );
48
+ // "Everything this person did" — the offboarding and the who-broke-it
49
+ // question, and the one a fleet-wide search runs first.
50
+ db.run(
51
+ `CREATE INDEX IF NOT EXISTS idx_activity_events_actor
52
+ ON ${ACTIVITY_EVENTS_TABLE} (actor, event_id DESC)`,
53
+ );
54
+ // "Everything that ever happened to this record."
55
+ db.run(
56
+ `CREATE INDEX IF NOT EXISTS idx_activity_events_resource
57
+ ON ${ACTIVITY_EVENTS_TABLE} (kind, resource_id, event_id DESC)`,
58
+ );
59
+ // "Everything backups ever did" — an action-prefix filter is a range
60
+ // scan on this index, which is why the vocabulary is dotted.
61
+ db.run(
62
+ `CREATE INDEX IF NOT EXISTS idx_activity_events_action
63
+ ON ${ACTIVITY_EVENTS_TABLE} (action, event_id DESC)`,
64
+ );
65
+ },
66
+ },
67
+ ];
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The sharing primitive, as a contributor to the activity stream.
3
+ *
4
+ * 🔴 This is the whole point of `sources`: `cursedbelt-server/sharing` already
5
+ * keeps an audit trail nothing ever deletes, in `share_events`, and it is
6
+ * guaranteed to be complete (no grant can be made without a row — see that
7
+ * store's property 1). So the activity stream READS it where it lives rather
8
+ * than asking an app to mirror it. One row, one truth, no drift, and nothing to
9
+ * reconcile if a mirror write is ever missed.
10
+ *
11
+ * ```ts
12
+ * const activity = createActivityLog({
13
+ * db, app: "family", sources: [shareEventsSource({ app: "family" })],
14
+ * });
15
+ * ```
16
+ *
17
+ * The mapping is field-for-field the one `activityFromShareEvent` performs in
18
+ * the vocabulary, and `store.spec.ts` asserts the two agree — a SQL projection
19
+ * and a TypeScript function are two implementations of one shape, so the suite
20
+ * pins them together rather than trusting that they were written on the same
21
+ * afternoon.
22
+ *
23
+ * `share_events.app` is NULL for a GROUP lifecycle event (creating a group is
24
+ * about no single resource), so the app is coalesced to the log's own name: a
25
+ * fleet-wide board merges on that column and an unlabeled row would be
26
+ * unattributable.
27
+ */
28
+ import { SHARE_EVENTS_TABLE } from "../sharing/migrations";
29
+ import type { ActivitySource } from "./store";
30
+
31
+ export interface ShareEventsSourceOptions {
32
+ /** The satellite this log speaks for — the same value passed to
33
+ * `createActivityLog`, used where a group event names no resource. */
34
+ app: string;
35
+ /** Overridden only by a test hosting the table under another name. */
36
+ table?: string;
37
+ /** The contributor name, which prefixes every id it produces. */
38
+ name?: string;
39
+ }
40
+
41
+ export function shareEventsSource(options: ShareEventsSourceOptions): ActivitySource {
42
+ const table = options.table ?? SHARE_EVENTS_TABLE;
43
+ const name = options.name ?? "share";
44
+ return {
45
+ name,
46
+ requiresTable: table,
47
+ // Column contract: source, seq, at, app, actor, action, kind, resource_id,
48
+ // outcome, note, data — in this order. See `ActivitySource`.
49
+ sql: `SELECT '${name}' AS source, event_id AS seq, at, COALESCE(app, ?) AS app, actor,
50
+ 'share.' || action AS action, kind, resource_id,
51
+ 'ok' AS outcome, note,
52
+ json_object('subjectType', subject_type, 'subjectId', subject_id,
53
+ 'level', level, 'previousLevel', previous_level) AS data
54
+ FROM ${table}`,
55
+ params: [options.app],
56
+ };
57
+ }