@geekity/cms 0.3.0 → 0.5.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 (660) hide show
  1. package/README.md +2217 -214
  2. package/admin/components/fields.njk +165 -0
  3. package/admin/layouts/base.njk +1 -1
  4. package/admin/layouts/settings-page.njk +26 -0
  5. package/admin/layouts/shell.njk +17 -3
  6. package/admin/pages/account/forgot.njk +47 -0
  7. package/admin/pages/account/login.njk +26 -0
  8. package/admin/pages/account/reset.njk +38 -0
  9. package/admin/pages/account/setup.njk +28 -0
  10. package/admin/pages/appearance/themes.njk +69 -0
  11. package/admin/pages/comments/all.njk +133 -0
  12. package/admin/{layouts/dashboard.njk → pages/dashboard/home.njk} +8 -15
  13. package/admin/{layouts/document-conflict.njk → pages/documents/conflict.njk} +1 -0
  14. package/admin/{layouts/document-editor.njk → pages/documents/editor.njk} +75 -59
  15. package/admin/{layouts/document-list.njk → pages/documents/list.njk} +19 -2
  16. package/admin/pages/documents/taxonomy.njk +95 -0
  17. package/admin/pages/federation/followers.njk +238 -0
  18. package/admin/pages/federation/settings.njk +77 -0
  19. package/admin/pages/media/library.njk +160 -0
  20. package/admin/pages/messages/all.njk +110 -0
  21. package/admin/pages/navigation/menus.njk +129 -0
  22. package/admin/{layouts → pages}/placeholder.njk +5 -1
  23. package/admin/pages/settings/discussion.njk +99 -0
  24. package/admin/pages/settings/email.njk +203 -0
  25. package/admin/pages/settings/general.njk +29 -0
  26. package/admin/pages/settings/permalinks.njk +50 -0
  27. package/admin/pages/settings/reading.njk +64 -0
  28. package/admin/pages/tools/content-index.njk +89 -0
  29. package/admin/pages/users/edit.njk +239 -0
  30. package/admin/pages/users/list.njk +51 -0
  31. package/admin/pages/users/new.njk +41 -0
  32. package/admin/static/admin.css +558 -3
  33. package/admin/static/copy.js +52 -0
  34. package/admin/static/editor.js +16 -16
  35. package/admin/static/slug.js +61 -0
  36. package/dist/access-log.d.ts +44 -0
  37. package/dist/access-log.d.ts.map +1 -0
  38. package/dist/access-log.js +71 -0
  39. package/dist/access-log.js.map +1 -0
  40. package/dist/admin/accounts.d.ts +413 -0
  41. package/dist/admin/accounts.d.ts.map +1 -0
  42. package/dist/admin/accounts.js +680 -0
  43. package/dist/admin/accounts.js.map +1 -0
  44. package/dist/admin/appearance.d.ts +80 -0
  45. package/dist/admin/appearance.d.ts.map +1 -0
  46. package/dist/admin/appearance.js +136 -0
  47. package/dist/admin/appearance.js.map +1 -0
  48. package/dist/admin/comments.d.ts +90 -0
  49. package/dist/admin/comments.d.ts.map +1 -0
  50. package/dist/admin/comments.js +244 -0
  51. package/dist/admin/comments.js.map +1 -0
  52. package/dist/admin/credentials.d.ts +26 -2
  53. package/dist/admin/credentials.d.ts.map +1 -1
  54. package/dist/admin/credentials.js +35 -2
  55. package/dist/admin/credentials.js.map +1 -1
  56. package/dist/admin/documents.d.ts +117 -10
  57. package/dist/admin/documents.d.ts.map +1 -1
  58. package/dist/admin/documents.js +328 -41
  59. package/dist/admin/documents.js.map +1 -1
  60. package/dist/admin/federation.d.ts +161 -50
  61. package/dist/admin/federation.d.ts.map +1 -1
  62. package/dist/admin/federation.js +235 -93
  63. package/dist/admin/federation.js.map +1 -1
  64. package/dist/admin/formatting.d.ts +20 -0
  65. package/dist/admin/formatting.d.ts.map +1 -0
  66. package/dist/admin/formatting.js +72 -0
  67. package/dist/admin/formatting.js.map +1 -0
  68. package/dist/admin/headers.d.ts +65 -0
  69. package/dist/admin/headers.d.ts.map +1 -0
  70. package/dist/admin/headers.js +104 -0
  71. package/dist/admin/headers.js.map +1 -0
  72. package/dist/admin/index.d.ts +38 -12
  73. package/dist/admin/index.d.ts.map +1 -1
  74. package/dist/admin/index.js +25 -7
  75. package/dist/admin/index.js.map +1 -1
  76. package/dist/admin/media.d.ts +168 -0
  77. package/dist/admin/media.d.ts.map +1 -0
  78. package/dist/admin/media.js +295 -0
  79. package/dist/admin/media.js.map +1 -0
  80. package/dist/admin/menu.d.ts +79 -0
  81. package/dist/admin/menu.d.ts.map +1 -0
  82. package/dist/admin/menu.js +143 -0
  83. package/dist/admin/menu.js.map +1 -0
  84. package/dist/admin/messages.d.ts +80 -0
  85. package/dist/admin/messages.d.ts.map +1 -0
  86. package/dist/admin/messages.js +152 -0
  87. package/dist/admin/messages.js.map +1 -0
  88. package/dist/admin/navigation.d.ts +155 -0
  89. package/dist/admin/navigation.d.ts.map +1 -0
  90. package/dist/admin/navigation.js +292 -0
  91. package/dist/admin/navigation.js.map +1 -0
  92. package/dist/admin/preview.d.ts.map +1 -1
  93. package/dist/admin/preview.js +31 -7
  94. package/dist/admin/preview.js.map +1 -1
  95. package/dist/admin/recovery.d.ts +92 -0
  96. package/dist/admin/recovery.d.ts.map +1 -0
  97. package/dist/admin/recovery.js +229 -0
  98. package/dist/admin/recovery.js.map +1 -0
  99. package/dist/admin/routes.d.ts +0 -20
  100. package/dist/admin/routes.d.ts.map +1 -1
  101. package/dist/admin/routes.js +164 -105
  102. package/dist/admin/routes.js.map +1 -1
  103. package/dist/admin/session.d.ts +17 -3
  104. package/dist/admin/session.d.ts.map +1 -1
  105. package/dist/admin/session.js +19 -5
  106. package/dist/admin/session.js.map +1 -1
  107. package/dist/admin/settings-discussion.d.ts +37 -0
  108. package/dist/admin/settings-discussion.d.ts.map +1 -0
  109. package/dist/admin/settings-discussion.js +117 -0
  110. package/dist/admin/settings-discussion.js.map +1 -0
  111. package/dist/admin/settings-email.d.ts +54 -0
  112. package/dist/admin/settings-email.d.ts.map +1 -0
  113. package/dist/admin/settings-email.js +189 -0
  114. package/dist/admin/settings-email.js.map +1 -0
  115. package/dist/admin/settings-federation.d.ts +48 -0
  116. package/dist/admin/settings-federation.d.ts.map +1 -0
  117. package/dist/admin/settings-federation.js +123 -0
  118. package/dist/admin/settings-federation.js.map +1 -0
  119. package/dist/admin/settings-general.d.ts +12 -0
  120. package/dist/admin/settings-general.d.ts.map +1 -0
  121. package/dist/admin/settings-general.js +48 -0
  122. package/dist/admin/settings-general.js.map +1 -0
  123. package/dist/admin/settings-page.d.ts +119 -0
  124. package/dist/admin/settings-page.d.ts.map +1 -0
  125. package/dist/admin/settings-page.js +132 -0
  126. package/dist/admin/settings-page.js.map +1 -0
  127. package/dist/admin/settings-pages.d.ts +30 -0
  128. package/dist/admin/settings-pages.d.ts.map +1 -0
  129. package/dist/admin/settings-pages.js +43 -0
  130. package/dist/admin/settings-pages.js.map +1 -0
  131. package/dist/admin/settings-permalinks.d.ts +16 -0
  132. package/dist/admin/settings-permalinks.d.ts.map +1 -0
  133. package/dist/admin/settings-permalinks.js +32 -0
  134. package/dist/admin/settings-permalinks.js.map +1 -0
  135. package/dist/admin/settings-reading.d.ts +34 -0
  136. package/dist/admin/settings-reading.d.ts.map +1 -0
  137. package/dist/admin/settings-reading.js +49 -0
  138. package/dist/admin/settings-reading.js.map +1 -0
  139. package/dist/admin/settings.d.ts +339 -96
  140. package/dist/admin/settings.d.ts.map +1 -1
  141. package/dist/admin/settings.js +600 -308
  142. package/dist/admin/settings.js.map +1 -1
  143. package/dist/admin/store.d.ts +606 -152
  144. package/dist/admin/store.d.ts.map +1 -1
  145. package/dist/admin/store.js +863 -268
  146. package/dist/admin/store.js.map +1 -1
  147. package/dist/admin/taxonomy.d.ts +114 -0
  148. package/dist/admin/taxonomy.d.ts.map +1 -0
  149. package/dist/admin/taxonomy.js +289 -0
  150. package/dist/admin/taxonomy.js.map +1 -0
  151. package/dist/admin/templates.d.ts +46 -14
  152. package/dist/admin/templates.d.ts.map +1 -1
  153. package/dist/admin/templates.js +46 -14
  154. package/dist/admin/templates.js.map +1 -1
  155. package/dist/admin/throttle.d.ts +84 -0
  156. package/dist/admin/throttle.d.ts.map +1 -0
  157. package/dist/admin/throttle.js +143 -0
  158. package/dist/admin/throttle.js.map +1 -0
  159. package/dist/admin/tools.d.ts +111 -0
  160. package/dist/admin/tools.d.ts.map +1 -0
  161. package/dist/admin/tools.js +182 -0
  162. package/dist/admin/tools.js.map +1 -0
  163. package/dist/admin/uploads.d.ts +28 -2
  164. package/dist/admin/uploads.d.ts.map +1 -1
  165. package/dist/admin/uploads.js +43 -4
  166. package/dist/admin/uploads.js.map +1 -1
  167. package/dist/admin/users.d.ts +100 -13
  168. package/dist/admin/users.d.ts.map +1 -1
  169. package/dist/admin/users.js +412 -39
  170. package/dist/admin/users.js.map +1 -1
  171. package/dist/cache.d.ts +141 -0
  172. package/dist/cache.d.ts.map +1 -0
  173. package/dist/cache.js +207 -0
  174. package/dist/cache.js.map +1 -0
  175. package/dist/cli.d.ts +14 -2
  176. package/dist/cli.d.ts.map +1 -1
  177. package/dist/cli.js +429 -21
  178. package/dist/cli.js.map +1 -1
  179. package/dist/comments/akismet.d.ts +130 -0
  180. package/dist/comments/akismet.d.ts.map +1 -0
  181. package/dist/comments/akismet.js +274 -0
  182. package/dist/comments/akismet.js.map +1 -0
  183. package/dist/comments/conversation.d.ts +29 -0
  184. package/dist/comments/conversation.d.ts.map +1 -0
  185. package/dist/comments/conversation.js +60 -0
  186. package/dist/comments/conversation.js.map +1 -0
  187. package/dist/comments/form.d.ts +123 -0
  188. package/dist/comments/form.d.ts.map +1 -0
  189. package/dist/comments/form.js +79 -0
  190. package/dist/comments/form.js.map +1 -0
  191. package/dist/comments/index.d.ts +16 -0
  192. package/dist/comments/index.d.ts.map +1 -0
  193. package/dist/comments/index.js +10 -0
  194. package/dist/comments/index.js.map +1 -0
  195. package/dist/comments/markdown.d.ts +8 -0
  196. package/dist/comments/markdown.d.ts.map +1 -0
  197. package/dist/comments/markdown.js +85 -0
  198. package/dist/comments/markdown.js.map +1 -0
  199. package/dist/comments/moderate.d.ts +71 -0
  200. package/dist/comments/moderate.d.ts.map +1 -0
  201. package/dist/comments/moderate.js +88 -0
  202. package/dist/comments/moderate.js.map +1 -0
  203. package/dist/comments/policy.d.ts +57 -0
  204. package/dist/comments/policy.d.ts.map +1 -0
  205. package/dist/comments/policy.js +80 -0
  206. package/dist/comments/policy.js.map +1 -0
  207. package/dist/comments/records.d.ts +266 -0
  208. package/dist/comments/records.d.ts.map +1 -0
  209. package/dist/comments/records.js +487 -0
  210. package/dist/comments/records.js.map +1 -0
  211. package/dist/comments/routes.d.ts +60 -0
  212. package/dist/comments/routes.d.ts.map +1 -0
  213. package/dist/comments/routes.js +212 -0
  214. package/dist/comments/routes.js.map +1 -0
  215. package/dist/comments/submission.d.ts +297 -0
  216. package/dist/comments/submission.d.ts.map +1 -0
  217. package/dist/comments/submission.js +280 -0
  218. package/dist/comments/submission.js.map +1 -0
  219. package/dist/comments/viewer.d.ts +21 -0
  220. package/dist/comments/viewer.d.ts.map +1 -0
  221. package/dist/comments/viewer.js +45 -0
  222. package/dist/comments/viewer.js.map +1 -0
  223. package/dist/config.d.ts +225 -5
  224. package/dist/config.d.ts.map +1 -1
  225. package/dist/config.js +121 -6
  226. package/dist/config.js.map +1 -1
  227. package/dist/contact/delivery.d.ts +60 -0
  228. package/dist/contact/delivery.d.ts.map +1 -0
  229. package/dist/contact/delivery.js +87 -0
  230. package/dist/contact/delivery.js.map +1 -0
  231. package/dist/contact/form.d.ts +130 -0
  232. package/dist/contact/form.d.ts.map +1 -0
  233. package/dist/contact/form.js +163 -0
  234. package/dist/contact/form.js.map +1 -0
  235. package/dist/contact/index.d.ts +17 -0
  236. package/dist/contact/index.d.ts.map +1 -0
  237. package/dist/contact/index.js +13 -0
  238. package/dist/contact/index.js.map +1 -0
  239. package/dist/contact/records.d.ts +124 -0
  240. package/dist/contact/records.d.ts.map +1 -0
  241. package/dist/contact/records.js +218 -0
  242. package/dist/contact/records.js.map +1 -0
  243. package/dist/contact/routes.d.ts +17 -0
  244. package/dist/contact/routes.d.ts.map +1 -0
  245. package/dist/contact/routes.js +127 -0
  246. package/dist/contact/routes.js.map +1 -0
  247. package/dist/contact/submission.d.ts +103 -0
  248. package/dist/contact/submission.d.ts.map +1 -0
  249. package/dist/contact/submission.js +166 -0
  250. package/dist/contact/submission.js.map +1 -0
  251. package/dist/content/document.d.ts +7 -2
  252. package/dist/content/document.d.ts.map +1 -1
  253. package/dist/content/document.js +1 -0
  254. package/dist/content/document.js.map +1 -1
  255. package/dist/content/index.d.ts +7 -2
  256. package/dist/content/index.d.ts.map +1 -1
  257. package/dist/content/index.js +4 -1
  258. package/dist/content/index.js.map +1 -1
  259. package/dist/content/markdown.d.ts.map +1 -1
  260. package/dist/content/markdown.js +24 -2
  261. package/dist/content/markdown.js.map +1 -1
  262. package/dist/content/parser.d.ts.map +1 -1
  263. package/dist/content/parser.js +11 -4
  264. package/dist/content/parser.js.map +1 -1
  265. package/dist/content/save.d.ts +5 -0
  266. package/dist/content/save.d.ts.map +1 -1
  267. package/dist/content/save.js +44 -1
  268. package/dist/content/save.js.map +1 -1
  269. package/dist/content/schedule.d.ts +125 -0
  270. package/dist/content/schedule.d.ts.map +1 -0
  271. package/dist/content/schedule.js +207 -0
  272. package/dist/content/schedule.js.map +1 -0
  273. package/dist/content/search.d.ts +64 -0
  274. package/dist/content/search.d.ts.map +1 -0
  275. package/dist/content/search.js +136 -0
  276. package/dist/content/search.js.map +1 -0
  277. package/dist/content/store.d.ts +220 -7
  278. package/dist/content/store.d.ts.map +1 -1
  279. package/dist/content/store.js +392 -67
  280. package/dist/content/store.js.map +1 -1
  281. package/dist/content/sync.d.ts +7 -1
  282. package/dist/content/sync.d.ts.map +1 -1
  283. package/dist/content/sync.js +18 -10
  284. package/dist/content/sync.js.map +1 -1
  285. package/dist/content/time.d.ts +56 -0
  286. package/dist/content/time.d.ts.map +1 -0
  287. package/dist/content/time.js +141 -0
  288. package/dist/content/time.js.map +1 -0
  289. package/dist/content/writer.d.ts.map +1 -1
  290. package/dist/content/writer.js +3 -0
  291. package/dist/content/writer.js.map +1 -1
  292. package/dist/env.d.ts +70 -5
  293. package/dist/env.d.ts.map +1 -1
  294. package/dist/federation/actor.d.ts +95 -41
  295. package/dist/federation/actor.d.ts.map +1 -1
  296. package/dist/federation/actor.js +180 -53
  297. package/dist/federation/actor.js.map +1 -1
  298. package/dist/federation/article.d.ts +44 -17
  299. package/dist/federation/article.d.ts.map +1 -1
  300. package/dist/federation/article.js +98 -46
  301. package/dist/federation/article.js.map +1 -1
  302. package/dist/federation/delivery.d.ts +63 -15
  303. package/dist/federation/delivery.d.ts.map +1 -1
  304. package/dist/federation/delivery.js +154 -80
  305. package/dist/federation/delivery.js.map +1 -1
  306. package/dist/federation/federation.d.ts +22 -17
  307. package/dist/federation/federation.d.ts.map +1 -1
  308. package/dist/federation/federation.js +98 -77
  309. package/dist/federation/federation.js.map +1 -1
  310. package/dist/federation/followers.d.ts +3 -2
  311. package/dist/federation/followers.d.ts.map +1 -1
  312. package/dist/federation/followers.js +6 -5
  313. package/dist/federation/followers.js.map +1 -1
  314. package/dist/federation/import-wordpress.d.ts +128 -0
  315. package/dist/federation/import-wordpress.d.ts.map +1 -0
  316. package/dist/federation/import-wordpress.js +426 -0
  317. package/dist/federation/import-wordpress.js.map +1 -0
  318. package/dist/federation/inbox.d.ts +36 -13
  319. package/dist/federation/inbox.d.ts.map +1 -1
  320. package/dist/federation/inbox.js +120 -49
  321. package/dist/federation/inbox.js.map +1 -1
  322. package/dist/federation/index.d.ts +22 -10
  323. package/dist/federation/index.d.ts.map +1 -1
  324. package/dist/federation/index.js +13 -8
  325. package/dist/federation/index.js.map +1 -1
  326. package/dist/federation/keys.d.ts +98 -20
  327. package/dist/federation/keys.d.ts.map +1 -1
  328. package/dist/federation/keys.js +269 -39
  329. package/dist/federation/keys.js.map +1 -1
  330. package/dist/federation/mount.d.ts +46 -10
  331. package/dist/federation/mount.d.ts.map +1 -1
  332. package/dist/federation/mount.js +300 -28
  333. package/dist/federation/mount.js.map +1 -1
  334. package/dist/federation/paths.d.ts +23 -35
  335. package/dist/federation/paths.d.ts.map +1 -1
  336. package/dist/federation/paths.js +26 -39
  337. package/dist/federation/paths.js.map +1 -1
  338. package/dist/federation/records.d.ts +223 -0
  339. package/dist/federation/records.d.ts.map +1 -0
  340. package/dist/federation/records.js +506 -0
  341. package/dist/federation/records.js.map +1 -0
  342. package/dist/federation/relays.d.ts +114 -0
  343. package/dist/federation/relays.d.ts.map +1 -0
  344. package/dist/federation/relays.js +290 -0
  345. package/dist/federation/relays.js.map +1 -0
  346. package/dist/federation/replies.d.ts +80 -0
  347. package/dist/federation/replies.d.ts.map +1 -0
  348. package/dist/federation/replies.js +166 -0
  349. package/dist/federation/replies.js.map +1 -0
  350. package/dist/federation/wordpress.d.ts +131 -0
  351. package/dist/federation/wordpress.d.ts.map +1 -0
  352. package/dist/federation/wordpress.js +341 -0
  353. package/dist/federation/wordpress.js.map +1 -0
  354. package/dist/files/atomic.d.ts +103 -0
  355. package/dist/files/atomic.d.ts.map +1 -0
  356. package/dist/files/atomic.js +150 -0
  357. package/dist/files/atomic.js.map +1 -0
  358. package/dist/files/index.d.ts +3 -0
  359. package/dist/files/index.d.ts.map +1 -0
  360. package/dist/files/index.js +2 -0
  361. package/dist/files/index.js.map +1 -0
  362. package/dist/forms/protection.d.ts +85 -0
  363. package/dist/forms/protection.d.ts.map +1 -0
  364. package/dist/forms/protection.js +116 -0
  365. package/dist/forms/protection.js.map +1 -0
  366. package/dist/images/icons.d.ts +59 -0
  367. package/dist/images/icons.d.ts.map +1 -0
  368. package/dist/images/icons.js +131 -0
  369. package/dist/images/icons.js.map +1 -0
  370. package/dist/images/index.d.ts +7 -0
  371. package/dist/images/index.d.ts.map +1 -0
  372. package/dist/images/index.js +4 -0
  373. package/dist/images/index.js.map +1 -0
  374. package/dist/images/markup.d.ts +47 -0
  375. package/dist/images/markup.d.ts.map +1 -0
  376. package/dist/images/markup.js +175 -0
  377. package/dist/images/markup.js.map +1 -0
  378. package/dist/images/paths.d.ts +34 -0
  379. package/dist/images/paths.d.ts.map +1 -0
  380. package/dist/images/paths.js +41 -0
  381. package/dist/images/paths.js.map +1 -0
  382. package/dist/images/variants.d.ts +104 -0
  383. package/dist/images/variants.d.ts.map +1 -0
  384. package/dist/images/variants.js +320 -0
  385. package/dist/images/variants.js.map +1 -0
  386. package/dist/index.d.ts +123 -19
  387. package/dist/index.d.ts.map +1 -1
  388. package/dist/index.js +344 -25
  389. package/dist/index.js.map +1 -1
  390. package/dist/init.d.ts +18 -0
  391. package/dist/init.d.ts.map +1 -1
  392. package/dist/init.js +34 -3
  393. package/dist/init.js.map +1 -1
  394. package/dist/mail/brevo.d.ts +35 -0
  395. package/dist/mail/brevo.d.ts.map +1 -0
  396. package/dist/mail/brevo.js +85 -0
  397. package/dist/mail/brevo.js.map +1 -0
  398. package/dist/mail/credentials.d.ts +62 -0
  399. package/dist/mail/credentials.d.ts.map +1 -0
  400. package/dist/mail/credentials.js +86 -0
  401. package/dist/mail/credentials.js.map +1 -0
  402. package/dist/mail/index.d.ts +15 -0
  403. package/dist/mail/index.d.ts.map +1 -0
  404. package/dist/mail/index.js +8 -0
  405. package/dist/mail/index.js.map +1 -0
  406. package/dist/mail/memory.d.ts +35 -0
  407. package/dist/mail/memory.d.ts.map +1 -0
  408. package/dist/mail/memory.js +29 -0
  409. package/dist/mail/memory.js.map +1 -0
  410. package/dist/mail/provider.d.ts +80 -0
  411. package/dist/mail/provider.d.ts.map +1 -0
  412. package/dist/mail/provider.js +23 -0
  413. package/dist/mail/provider.js.map +1 -0
  414. package/dist/mail/service.d.ts +156 -0
  415. package/dist/mail/service.d.ts.map +1 -0
  416. package/dist/mail/service.js +265 -0
  417. package/dist/mail/service.js.map +1 -0
  418. package/dist/mail/smtp.d.ts +39 -0
  419. package/dist/mail/smtp.d.ts.map +1 -0
  420. package/dist/mail/smtp.js +58 -0
  421. package/dist/mail/smtp.js.map +1 -0
  422. package/dist/mail/templates.d.ts +91 -0
  423. package/dist/mail/templates.d.ts.map +1 -0
  424. package/dist/mail/templates.js +69 -0
  425. package/dist/mail/templates.js.map +1 -0
  426. package/dist/notifications/comments.d.ts +66 -0
  427. package/dist/notifications/comments.d.ts.map +1 -0
  428. package/dist/notifications/comments.js +151 -0
  429. package/dist/notifications/comments.js.map +1 -0
  430. package/dist/notifications/digest.d.ts +135 -0
  431. package/dist/notifications/digest.d.ts.map +1 -0
  432. package/dist/notifications/digest.js +287 -0
  433. package/dist/notifications/digest.js.map +1 -0
  434. package/dist/notifications/index.d.ts +13 -0
  435. package/dist/notifications/index.d.ts.map +1 -0
  436. package/dist/notifications/index.js +8 -0
  437. package/dist/notifications/index.js.map +1 -0
  438. package/dist/notifications/links.d.ts +60 -0
  439. package/dist/notifications/links.d.ts.map +1 -0
  440. package/dist/notifications/links.js +63 -0
  441. package/dist/notifications/links.js.map +1 -0
  442. package/dist/notifications/optouts.d.ts +48 -0
  443. package/dist/notifications/optouts.d.ts.map +1 -0
  444. package/dist/notifications/optouts.js +93 -0
  445. package/dist/notifications/optouts.js.map +1 -0
  446. package/dist/notifications/preferences.d.ts +158 -0
  447. package/dist/notifications/preferences.d.ts.map +1 -0
  448. package/dist/notifications/preferences.js +195 -0
  449. package/dist/notifications/preferences.js.map +1 -0
  450. package/dist/notifications/routes.d.ts +28 -0
  451. package/dist/notifications/routes.d.ts.map +1 -0
  452. package/dist/notifications/routes.js +184 -0
  453. package/dist/notifications/routes.js.map +1 -0
  454. package/dist/notifications/tokens.d.ts +60 -0
  455. package/dist/notifications/tokens.d.ts.map +1 -0
  456. package/dist/notifications/tokens.js +125 -0
  457. package/dist/notifications/tokens.js.map +1 -0
  458. package/dist/notify.d.ts +84 -0
  459. package/dist/notify.d.ts.map +1 -0
  460. package/dist/notify.js +149 -0
  461. package/dist/notify.js.map +1 -0
  462. package/dist/web/archive.d.ts +49 -0
  463. package/dist/web/archive.d.ts.map +1 -0
  464. package/dist/web/archive.js +59 -0
  465. package/dist/web/archive.js.map +1 -0
  466. package/dist/web/assets.d.ts +6 -5
  467. package/dist/web/assets.d.ts.map +1 -1
  468. package/dist/web/assets.js +5 -7
  469. package/dist/web/assets.js.map +1 -1
  470. package/dist/web/authors.d.ts +143 -0
  471. package/dist/web/authors.d.ts.map +1 -0
  472. package/dist/web/authors.js +178 -0
  473. package/dist/web/authors.js.map +1 -0
  474. package/dist/web/comments.d.ts +60 -0
  475. package/dist/web/comments.d.ts.map +1 -0
  476. package/dist/web/comments.js +207 -0
  477. package/dist/web/comments.js.map +1 -0
  478. package/dist/web/context.d.ts +162 -28
  479. package/dist/web/context.d.ts.map +1 -1
  480. package/dist/web/context.js +123 -26
  481. package/dist/web/context.js.map +1 -1
  482. package/dist/web/conversation.d.ts +209 -0
  483. package/dist/web/conversation.d.ts.map +1 -0
  484. package/dist/web/conversation.js +557 -0
  485. package/dist/web/conversation.js.map +1 -0
  486. package/dist/web/documents.d.ts +36 -6
  487. package/dist/web/documents.d.ts.map +1 -1
  488. package/dist/web/documents.js +52 -10
  489. package/dist/web/documents.js.map +1 -1
  490. package/dist/web/feed-atom.d.ts +22 -0
  491. package/dist/web/feed-atom.d.ts.map +1 -0
  492. package/dist/web/feed-atom.js +83 -0
  493. package/dist/web/feed-atom.js.map +1 -0
  494. package/dist/web/feed-item.d.ts +145 -0
  495. package/dist/web/feed-item.d.ts.map +1 -0
  496. package/dist/web/feed-item.js +120 -0
  497. package/dist/web/feed-item.js.map +1 -0
  498. package/dist/web/feed-json.d.ts +79 -0
  499. package/dist/web/feed-json.d.ts.map +1 -0
  500. package/dist/web/feed-json.js +53 -0
  501. package/dist/web/feed-json.js.map +1 -0
  502. package/dist/web/feed-rss.d.ts +26 -0
  503. package/dist/web/feed-rss.d.ts.map +1 -0
  504. package/dist/web/feed-rss.js +203 -0
  505. package/dist/web/feed-rss.js.map +1 -0
  506. package/dist/web/feed-source.d.ts +244 -0
  507. package/dist/web/feed-source.d.ts.map +1 -0
  508. package/dist/web/feed-source.js +201 -0
  509. package/dist/web/feed-source.js.map +1 -0
  510. package/dist/web/feed-xml.d.ts +63 -0
  511. package/dist/web/feed-xml.d.ts.map +1 -0
  512. package/dist/web/feed-xml.js +116 -0
  513. package/dist/web/feed-xml.js.map +1 -0
  514. package/dist/web/feeds.d.ts +31 -96
  515. package/dist/web/feeds.d.ts.map +1 -1
  516. package/dist/web/feeds.js +94 -198
  517. package/dist/web/feeds.js.map +1 -1
  518. package/dist/web/health.d.ts +31 -0
  519. package/dist/web/health.d.ts.map +1 -0
  520. package/dist/web/health.js +44 -0
  521. package/dist/web/health.js.map +1 -0
  522. package/dist/web/index.d.ts +30 -10
  523. package/dist/web/index.d.ts.map +1 -1
  524. package/dist/web/index.js +18 -7
  525. package/dist/web/index.js.map +1 -1
  526. package/dist/web/navigation.d.ts +195 -0
  527. package/dist/web/navigation.d.ts.map +1 -0
  528. package/dist/web/navigation.js +300 -0
  529. package/dist/web/navigation.js.map +1 -0
  530. package/dist/web/negotiate.d.ts +31 -0
  531. package/dist/web/negotiate.d.ts.map +1 -1
  532. package/dist/web/negotiate.js +31 -11
  533. package/dist/web/negotiate.js.map +1 -1
  534. package/dist/web/recent.d.ts +43 -0
  535. package/dist/web/recent.d.ts.map +1 -0
  536. package/dist/web/recent.js +37 -0
  537. package/dist/web/recent.js.map +1 -0
  538. package/dist/web/render.d.ts +203 -9
  539. package/dist/web/render.d.ts.map +1 -1
  540. package/dist/web/render.js +341 -17
  541. package/dist/web/render.js.map +1 -1
  542. package/dist/web/routes.d.ts +25 -8
  543. package/dist/web/routes.d.ts.map +1 -1
  544. package/dist/web/routes.js +854 -93
  545. package/dist/web/routes.js.map +1 -1
  546. package/dist/web/sanitize.d.ts +19 -0
  547. package/dist/web/sanitize.d.ts.map +1 -0
  548. package/dist/web/sanitize.js +272 -0
  549. package/dist/web/sanitize.js.map +1 -0
  550. package/dist/web/search.d.ts +79 -0
  551. package/dist/web/search.d.ts.map +1 -0
  552. package/dist/web/search.js +94 -0
  553. package/dist/web/search.js.map +1 -0
  554. package/dist/web/sitemap.d.ts +120 -0
  555. package/dist/web/sitemap.d.ts.map +1 -0
  556. package/dist/web/sitemap.js +199 -0
  557. package/dist/web/sitemap.js.map +1 -0
  558. package/dist/web/taxonomy.d.ts +152 -0
  559. package/dist/web/taxonomy.d.ts.map +1 -0
  560. package/dist/web/taxonomy.js +237 -0
  561. package/dist/web/taxonomy.js.map +1 -0
  562. package/dist/web/templates.d.ts +54 -16
  563. package/dist/web/templates.d.ts.map +1 -1
  564. package/dist/web/templates.js +109 -28
  565. package/dist/web/templates.js.map +1 -1
  566. package/dist/web/themes.d.ts +226 -0
  567. package/dist/web/themes.d.ts.map +1 -0
  568. package/dist/web/themes.js +314 -0
  569. package/dist/web/themes.js.map +1 -0
  570. package/dist/webmention/discovery.d.ts +51 -0
  571. package/dist/webmention/discovery.d.ts.map +1 -0
  572. package/dist/webmention/discovery.js +176 -0
  573. package/dist/webmention/discovery.js.map +1 -0
  574. package/dist/webmention/html.d.ts +71 -0
  575. package/dist/webmention/html.d.ts.map +1 -0
  576. package/dist/webmention/html.js +285 -0
  577. package/dist/webmention/html.js.map +1 -0
  578. package/dist/webmention/index.d.ts +12 -0
  579. package/dist/webmention/index.d.ts.map +1 -0
  580. package/dist/webmention/index.js +8 -0
  581. package/dist/webmention/index.js.map +1 -0
  582. package/dist/webmention/links.d.ts +18 -0
  583. package/dist/webmention/links.d.ts.map +1 -0
  584. package/dist/webmention/links.js +64 -0
  585. package/dist/webmention/links.js.map +1 -0
  586. package/dist/webmention/microformats.d.ts +93 -0
  587. package/dist/webmention/microformats.d.ts.map +1 -0
  588. package/dist/webmention/microformats.js +376 -0
  589. package/dist/webmention/microformats.js.map +1 -0
  590. package/dist/webmention/receive.d.ts +141 -0
  591. package/dist/webmention/receive.d.ts.map +1 -0
  592. package/dist/webmention/receive.js +264 -0
  593. package/dist/webmention/receive.js.map +1 -0
  594. package/dist/webmention/routes.d.ts +37 -0
  595. package/dist/webmention/routes.d.ts.map +1 -0
  596. package/dist/webmention/routes.js +75 -0
  597. package/dist/webmention/routes.js.map +1 -0
  598. package/dist/webmention/service.d.ts +94 -0
  599. package/dist/webmention/service.d.ts.map +1 -0
  600. package/dist/webmention/service.js +207 -0
  601. package/dist/webmention/service.js.map +1 -0
  602. package/package.json +11 -6
  603. package/templates/site/content/_data/site.json +8 -0
  604. package/templates/site/content/pages/about.md +7 -0
  605. package/templates/site/content/posts/2026-01-01-hello-world.md +5 -3
  606. package/templates/site/geekity.config.ts +11 -1
  607. package/templates/site/tsconfig.json +1 -1
  608. package/themes/default/README.md +1216 -50
  609. package/themes/default/layouts/404.njk +2 -3
  610. package/themes/default/layouts/author.njk +36 -0
  611. package/themes/default/layouts/base.njk +161 -31
  612. package/themes/default/layouts/category.njk +27 -0
  613. package/themes/default/layouts/front-page.njk +56 -0
  614. package/themes/default/layouts/home.njk +17 -1
  615. package/themes/default/layouts/page.njk +57 -5
  616. package/themes/default/layouts/post.njk +78 -19
  617. package/themes/default/layouts/search.njk +57 -0
  618. package/themes/default/layouts/tag.njk +3 -6
  619. package/themes/default/mail/comment-digest.html.njk +37 -0
  620. package/themes/default/mail/comment-digest.subject.njk +3 -0
  621. package/themes/default/mail/comment-digest.txt.njk +40 -0
  622. package/themes/default/mail/comment-pending.html.njk +27 -0
  623. package/themes/default/mail/comment-pending.subject.njk +2 -0
  624. package/themes/default/mail/comment-pending.txt.njk +24 -0
  625. package/themes/default/mail/comment-reply.html.njk +21 -0
  626. package/themes/default/mail/comment-reply.subject.njk +2 -0
  627. package/themes/default/mail/comment-reply.txt.njk +22 -0
  628. package/themes/default/mail/contact-message.html.njk +24 -0
  629. package/themes/default/mail/contact-message.subject.njk +5 -0
  630. package/themes/default/mail/contact-message.txt.njk +20 -0
  631. package/themes/default/mail/password-changed.html.njk +18 -0
  632. package/themes/default/mail/password-changed.subject.njk +2 -0
  633. package/themes/default/mail/password-changed.txt.njk +17 -0
  634. package/themes/default/mail/password-reset.html.njk +22 -0
  635. package/themes/default/mail/password-reset.subject.njk +2 -0
  636. package/themes/default/mail/password-reset.txt.njk +18 -0
  637. package/themes/default/mail/test.html.njk +14 -0
  638. package/themes/default/mail/test.subject.njk +2 -0
  639. package/themes/default/mail/test.txt.njk +12 -0
  640. package/themes/default/partials/archive.njk +27 -0
  641. package/themes/default/partials/bio.njk +71 -0
  642. package/themes/default/partials/comment-form.njk +137 -0
  643. package/themes/default/partials/contact-form.njk +88 -0
  644. package/themes/default/partials/conversation.njk +139 -0
  645. package/themes/default/partials/feeds.njk +26 -0
  646. package/themes/default/partials/jsonld.njk +120 -0
  647. package/themes/default/partials/menu.njk +32 -0
  648. package/themes/default/partials/pagination.njk +12 -6
  649. package/themes/default/partials/post-list.njk +51 -18
  650. package/themes/default/partials/search-form.njk +22 -0
  651. package/themes/default/partials/tags.njk +26 -5
  652. package/themes/default/static/highlight.js +4 -0
  653. package/themes/default/static/style.css +1142 -194
  654. package/themes/default/theme.json +9 -0
  655. package/admin/layouts/federation.njk +0 -145
  656. package/admin/layouts/login.njk +0 -23
  657. package/admin/layouts/settings.njk +0 -116
  658. package/admin/layouts/setup.njk +0 -27
  659. package/admin/layouts/users.njk +0 -91
  660. /package/admin/{layouts/_flash.njk → components/flash.njk} +0 -0
@@ -0,0 +1,290 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { Accept, Follow, PUBLIC_COLLECTION, Reject, Undo } from '@fedify/vocab';
3
+ import { primaryUser } from '../admin/accounts.js';
4
+ import { readSiteSettings } from '../admin/settings.js';
5
+ import { actorId, senderKeyPairs } from './actor.js';
6
+ /**
7
+ * One relay as the {@link Recipient} Fedify delivers to.
8
+ *
9
+ * The inbox stands in for the id until the relay has answered, because the
10
+ * `Follow` goes out before the site knows what to call it: Fedify drops a
11
+ * recipient with no id, so `null` would silently send nothing. The id is only
12
+ * ever used to key the inbox and to build a collection synchronisation header
13
+ * for a shared inbox, and a relay publishes no shared inbox — a relay *is* one
14
+ * — so standing the inbox in for it costs the relay nothing.
15
+ */
16
+ export function relayRecipient(relay) {
17
+ return {
18
+ id: new URL(relay.actorId ?? relay.inboxId),
19
+ inboxId: new URL(relay.inboxId),
20
+ };
21
+ }
22
+ /**
23
+ * The relays a public activity is delivered to: the accepted ones, and only
24
+ * those.
25
+ *
26
+ * A pending subscription has not been agreed to and a rejected one has been
27
+ * refused; delivering to either would be posting into an inbox that has not
28
+ * said it wants this, which is what the handshake exists to establish.
29
+ */
30
+ export function acceptedRelays(admin) {
31
+ return admin.listRelays().filter((relay) => relay.state === 'accepted');
32
+ }
33
+ /**
34
+ * Build the relay service for one site.
35
+ *
36
+ * FEP-ae0c is the whole of the protocol: a `Follow` whose object is the
37
+ * literal Public collection, sent to the relay's inbox and signed the way any
38
+ * other activity is; an `Accept` or a `Reject` back, which may take days
39
+ * because a relay is allowed to hold a subscription for a human to approve;
40
+ * and an `Undo` of that same `Follow` to leave.
41
+ */
42
+ export function createRelayService(options) {
43
+ const { federation, admin, store, config } = options;
44
+ const logger = options.logger ?? console;
45
+ // Follows and undos are chained rather than run at once, for the reason
46
+ // deliveries are: a relay that is told to unfollow before it has been told
47
+ // to follow keeps the subscription. The chain never rejects.
48
+ let chain = Promise.resolve();
49
+ function enqueue(task) {
50
+ const result = chain.then(task);
51
+ chain = result.then(ignore, ignore);
52
+ return result;
53
+ }
54
+ /** A context outside any request, which is where a follow is sent from. */
55
+ function relayContext() {
56
+ return federation.createContext(new URL(config.baseUrl), { admin, store, config });
57
+ }
58
+ /**
59
+ * Who subscribes to a relay: the site's first account (decision-14).
60
+ *
61
+ * A relay subscription is an instance-wide agreement — it boosts everything
62
+ * public this site sends, whoever wrote it — and after decision-14 there is
63
+ * no site actor left to make one. The first account is the one actor that
64
+ * can be chosen without asking, and it is the account a one-person blog has
65
+ * anyway. `undefined` before anybody has signed up, and then nothing is
66
+ * sent: a site in first-run setup has no identity to sign with.
67
+ */
68
+ function subscriber() {
69
+ return primaryUser(config.dataDir);
70
+ }
71
+ /**
72
+ * Send one activity to one relay inbox.
73
+ *
74
+ * The key that signs the request is the subscriber's whether or not the
75
+ * relay has answered yet; see {@link relayRecipient} for what stands in for
76
+ * the id until it has.
77
+ */
78
+ async function send(context, user, relay, activity) {
79
+ await context.sendActivity(await senderKeyPairs(context, user), relayRecipient(relay), activity, {
80
+ // A relay has one inbox and no shared one, and its activities are about
81
+ // the subscription rather than about any post, so they are ordered
82
+ // against each other rather than against a post's Create.
83
+ orderingKey: relay.inboxId,
84
+ });
85
+ }
86
+ /**
87
+ * Follow one relay: write the record first, then send the `Follow`.
88
+ *
89
+ * The record is written before the activity goes out, not after, so an
90
+ * `Accept` that arrives while the POST is still in flight — a fast relay,
91
+ * a synchronous test — finds something to mark accepted.
92
+ */
93
+ async function follow(relay) {
94
+ const context = relayContext();
95
+ const user = subscriber();
96
+ if (user === undefined) {
97
+ logger.warn(`Could not follow the relay at ${relay.inboxId}: the site has no accounts, ` +
98
+ 'and decision-14 makes a user the actor a subscription is made by.');
99
+ return admin.putRelay({ ...relay, reason: 'The site has no account to subscribe with.' });
100
+ }
101
+ const id = actorId(context, user);
102
+ const followId = new URL(`#relay-follow/${randomUUID()}`, id);
103
+ const stored = admin.putRelay({
104
+ inboxId: relay.inboxId,
105
+ actorId: relay.actorId,
106
+ state: 'pending',
107
+ reason: null,
108
+ followId: followId.href,
109
+ createdAt: relay.createdAt,
110
+ });
111
+ try {
112
+ await send(context, user, stored, new Follow({
113
+ id: followId,
114
+ actor: id,
115
+ // The literal Public collection, expanded, which is what FEP-ae0c
116
+ // says a relay looks for and what tells it this is a subscription
117
+ // rather than somebody following an account.
118
+ object: PUBLIC_COLLECTION,
119
+ }));
120
+ }
121
+ catch (thrown) {
122
+ // The record stays pending with the reason on it: the relay may simply
123
+ // have been down, and Retry is what the screen offers for that.
124
+ const message = messageOf(thrown);
125
+ logger.warn(`Could not follow the relay at ${stored.inboxId}: ${message}`);
126
+ return admin.putRelay({ ...stored, reason: message });
127
+ }
128
+ return stored;
129
+ }
130
+ /** Undo one relay's follow and forget it. */
131
+ async function unfollow(relay) {
132
+ const user = subscriber();
133
+ if (relay.followId !== null && user !== undefined) {
134
+ try {
135
+ const context = relayContext();
136
+ const id = actorId(context, user);
137
+ await send(context, user, relay, new Undo({
138
+ id: new URL(`#undo/${randomUUID()}`, id),
139
+ actor: id,
140
+ // The follow by id rather than embedded, which FEP-ae0c allows and
141
+ // which is what the relay matched its own record on.
142
+ object: new URL(relay.followId),
143
+ }));
144
+ }
145
+ catch (thrown) {
146
+ // The subscription is gone from this side whatever the relay heard: a
147
+ // relay that keeps sending is one whose activities land in the inbox
148
+ // log, which is a nuisance rather than a leak, and re-adding it would
149
+ // strand the record against a list that no longer names it.
150
+ logger.warn(`Could not tell the relay at ${relay.inboxId} to stop: ${messageOf(thrown)}`);
151
+ }
152
+ }
153
+ admin.deleteRelay(relay.inboxId);
154
+ }
155
+ return {
156
+ sync() {
157
+ const listed = readSiteSettings(config.contentDir).relays;
158
+ const known = admin.listRelays();
159
+ const followed = [];
160
+ const unfollowed = [];
161
+ for (const inboxId of listed) {
162
+ if (known.some((relay) => relay.inboxId === inboxId))
163
+ continue;
164
+ followed.push(inboxId);
165
+ queue(() => follow({
166
+ inboxId,
167
+ actorId: null,
168
+ state: 'pending',
169
+ reason: null,
170
+ followId: null,
171
+ createdAt: new Date().toISOString(),
172
+ updatedAt: new Date().toISOString(),
173
+ }));
174
+ }
175
+ for (const relay of known) {
176
+ if (listed.includes(relay.inboxId))
177
+ continue;
178
+ unfollowed.push(relay.inboxId);
179
+ queue(() => unfollow(relay));
180
+ }
181
+ return { followed, unfollowed };
182
+ },
183
+ async retry(inboxId) {
184
+ const relay = admin.getRelay(inboxId);
185
+ if (relay === undefined)
186
+ return undefined;
187
+ return await enqueue(() => follow(relay));
188
+ },
189
+ settled() {
190
+ return chain.then(ignore);
191
+ },
192
+ };
193
+ /**
194
+ * Put one subscription change on the queue and stop caring about its result.
195
+ *
196
+ * Nothing is waiting for the follow a settings save set off, so a rejection
197
+ * here has nowhere to go but the log; a failed follow has already been
198
+ * written to its record by then.
199
+ */
200
+ function queue(task) {
201
+ enqueue(task).catch((thrown) => {
202
+ logger.warn(`A relay subscription failed: ${messageOf(thrown)}`);
203
+ });
204
+ }
205
+ }
206
+ /**
207
+ * Mark the subscription an `Accept` answers as accepted, and record who the
208
+ * relay turned out to be. `undefined` when it answers no follow this site
209
+ * sent — the site follows nothing but relays (doc-4), so that is a stray.
210
+ *
211
+ * A free function over the store rather than a method on the service: nothing
212
+ * about it is queued or sent, and the inbox listener that calls it has the
213
+ * store on its context and no service.
214
+ */
215
+ export function acceptRelay(admin, activity) {
216
+ const relay = relayAnswering(admin, activity);
217
+ if (relay === undefined)
218
+ return undefined;
219
+ return admin.putRelay({
220
+ ...relay,
221
+ actorId: activity.actorId?.href ?? relay.actorId,
222
+ state: 'accepted',
223
+ reason: null,
224
+ });
225
+ }
226
+ /** The same for a `Reject`, which marks the relay rejected with its reason. */
227
+ export function rejectRelay(admin, activity) {
228
+ const relay = relayAnswering(admin, activity);
229
+ if (relay === undefined)
230
+ return undefined;
231
+ return admin.putRelay({
232
+ ...relay,
233
+ actorId: activity.actorId?.href ?? relay.actorId,
234
+ state: 'rejected',
235
+ reason: rejectionReason(activity),
236
+ });
237
+ }
238
+ /**
239
+ * Match an `Accept` or a `Reject` to the subscription it answers.
240
+ *
241
+ * The follow id is what FEP-ae0c says the answer names, so it is tried first.
242
+ * A relay that has answered before is then recognised by its actor id, which
243
+ * covers a re-follow whose answer echoes a stale id. Last, a single pending
244
+ * subscription on the answering relay's own origin is taken as the one meant:
245
+ * a relay answering from the host its inbox is on is answering about that
246
+ * inbox, and there is nothing else it could be about. Two pending
247
+ * subscriptions on one host are left alone rather than guessed between.
248
+ */
249
+ export function relayAnswering(admin, activity) {
250
+ const followId = activity.objectId?.href;
251
+ if (followId !== undefined) {
252
+ const byFollow = admin.getRelayByFollow(followId);
253
+ if (byFollow !== undefined)
254
+ return byFollow;
255
+ }
256
+ const actorId = activity.actorId?.href;
257
+ if (actorId === undefined)
258
+ return undefined;
259
+ const relays = admin.listRelays();
260
+ const byActor = relays.find((relay) => relay.actorId === actorId);
261
+ if (byActor !== undefined)
262
+ return byActor;
263
+ const origin = originOf(actorId);
264
+ if (origin === undefined)
265
+ return undefined;
266
+ const pending = relays.filter((relay) => relay.state === 'pending' && originOf(relay.inboxId) === origin);
267
+ return pending.length === 1 ? pending[0] : undefined;
268
+ }
269
+ /** Why a `Reject` was a rejection, in the relay's own words, or `null`. */
270
+ function rejectionReason(activity) {
271
+ const summary = activity.summary?.toString() ?? activity.content?.toString();
272
+ return summary === undefined || summary === '' ? null : summary;
273
+ }
274
+ /** A URL's origin, or `undefined` for something that is not one. */
275
+ function originOf(value) {
276
+ try {
277
+ return new URL(value).origin;
278
+ }
279
+ catch {
280
+ return undefined;
281
+ }
282
+ }
283
+ function messageOf(error) {
284
+ return error instanceof Error ? error.message : String(error);
285
+ }
286
+ function ignore() {
287
+ // Deliberately empty: the chain must not reject, and a failure has already
288
+ // been logged and written to the record it happened to.
289
+ }
290
+ //# sourceMappingURL=relays.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relays.js","sourceRoot":"","sources":["../../src/federation/relays.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * What a logged inbound activity means as a reply.
3
+ *
4
+ * The inbox keeps every `Create` it is sent whole (doc-4), and a reply is
5
+ * simply one whose object answers something: `inReplyTo` naming a post's
6
+ * ActivityStreams object id. Everything the comments feeds show is read back
7
+ * out of that stored JSON-LD rather than out of columns, so the index can be
8
+ * thrown away and rebuilt from the files TASK-32 writes.
9
+ */
10
+ import type { InboxActivity } from '../admin/store.ts';
11
+ /** The activity type a reply arrives as. A comment is a note somebody created. */
12
+ export declare const REPLY_ACTIVITY_TYPE = "Create";
13
+ /** One logged reply, as everything that shows a comment wants it. */
14
+ export interface Reply {
15
+ /** The note's own id: its name in the fediverse, and the feed item's `guid`. */
16
+ id: string;
17
+ /** Where the note can be read — its `url`, else its id. */
18
+ url: string;
19
+ /** Who wrote it, as a name to show. */
20
+ author: string;
21
+ /** Who wrote it, as an id. */
22
+ actorId: string;
23
+ /**
24
+ * What it says, as the remote server rendered it and *not* sanitised.
25
+ *
26
+ * Sanitising belongs to whatever publishes the reply, so there is one place
27
+ * that has to be right rather than one per caller.
28
+ */
29
+ html: string;
30
+ /** When the note says it was published, or when it arrived if it did not. */
31
+ published: Date;
32
+ /** The object it answers: a post's ActivityStreams id. */
33
+ inReplyTo: string;
34
+ }
35
+ /**
36
+ * A logged activity as the reply it is, or `undefined` when it is not one.
37
+ *
38
+ * Everything is read back out of the stored JSON-LD rather than out of columns
39
+ * beside it, so what a comment shows survives the index being deleted.
40
+ *
41
+ * `nameFor` is the site's chance to name the author better than the activity
42
+ * can: the actor document is not in the activity, so without it the best
43
+ * available name is the `@user@host` the actor's own URL implies.
44
+ */
45
+ export declare function replyFrom(activity: InboxActivity, nameFor?: (actorId: string) => string | undefined): Reply | undefined;
46
+ /**
47
+ * `@user@host` for an actor URL, or `undefined` when the URL implies none.
48
+ *
49
+ * A guess, and deliberately so: naming the author properly would mean
50
+ * dereferencing the actor, which is a network round trip per comment shown. A
51
+ * follower the site already knows is named from its stored profile instead,
52
+ * and this is the fallback for everybody else.
53
+ */
54
+ export declare function actorHandle(actorId: string): string | undefined;
55
+ /**
56
+ * What a stored activity replies to, or `null` when it replies to nothing.
57
+ *
58
+ * This is the whole definition of the `in_reply_to` index column: it is
59
+ * derived from the activity and never supplied, so a database rebuilt from the
60
+ * inbox log holds exactly what the live one holds.
61
+ *
62
+ * JSON-LD lets `inReplyTo` be a string, a node object or an array of either,
63
+ * and a compacted activity may carry the object as a bare id instead of
64
+ * inlining it. Anything that is not a single absolute URI is no target.
65
+ */
66
+ export declare function replyTargetOf(json: string): string | null;
67
+ /**
68
+ * A JSON-LD value as the one absolute URI it names, or `null`.
69
+ *
70
+ * The three spellings a compacted document may use — a string, `{"id": …}`,
71
+ * and either of those wrapped in an array — all mean the same thing here, and
72
+ * the first of a list is the one that is kept: a note that answers several
73
+ * things is shown under the first one it names.
74
+ *
75
+ * Exported for the inbox log's sake: every id column of the index is read out
76
+ * of the stored activity by this, so what a rebuilt row says about an actor or
77
+ * an object is what a live one says.
78
+ */
79
+ export declare function uriOf(value: unknown): string | null;
80
+ //# sourceMappingURL=replies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replies.d.ts","sourceRoot":"","sources":["../../src/federation/replies.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,kFAAkF;AAClF,eAAO,MAAM,mBAAmB,WAAW,CAAC;AAE5C,qEAAqE;AACrE,MAAM,WAAW,KAAK;IACpB,gFAAgF;IAChF,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,GAAG,EAAE,MAAM,CAAC;IACZ,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,SAAS,EAAE,IAAI,CAAC;IAChB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAChD,KAAK,GAAG,SAAS,CAsBnB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAc/D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIzD;AAiBD;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAkBnD"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * What a logged inbound activity means as a reply.
3
+ *
4
+ * The inbox keeps every `Create` it is sent whole (doc-4), and a reply is
5
+ * simply one whose object answers something: `inReplyTo` naming a post's
6
+ * ActivityStreams object id. Everything the comments feeds show is read back
7
+ * out of that stored JSON-LD rather than out of columns, so the index can be
8
+ * thrown away and rebuilt from the files TASK-32 writes.
9
+ */
10
+ /** The activity type a reply arrives as. A comment is a note somebody created. */
11
+ export const REPLY_ACTIVITY_TYPE = 'Create';
12
+ /**
13
+ * A logged activity as the reply it is, or `undefined` when it is not one.
14
+ *
15
+ * Everything is read back out of the stored JSON-LD rather than out of columns
16
+ * beside it, so what a comment shows survives the index being deleted.
17
+ *
18
+ * `nameFor` is the site's chance to name the author better than the activity
19
+ * can: the actor document is not in the activity, so without it the best
20
+ * available name is the `@user@host` the actor's own URL implies.
21
+ */
22
+ export function replyFrom(activity, nameFor) {
23
+ if (activity.activityType !== REPLY_ACTIVITY_TYPE)
24
+ return undefined;
25
+ const object = activityObject(activity.json);
26
+ if (object === undefined)
27
+ return undefined;
28
+ const inReplyTo = uriOf(object['inReplyTo']);
29
+ const id = uriOf(object['id']) ?? activity.objectId;
30
+ if (inReplyTo === null || id === null)
31
+ return undefined;
32
+ const actorId = activity.actorId;
33
+ const published = new Date(textOf(object['published']) ?? '');
34
+ return {
35
+ id,
36
+ url: uriOf(object['url']) ?? id,
37
+ author: nameFor?.(actorId) ?? actorHandle(actorId) ?? actorId,
38
+ actorId,
39
+ html: textOf(object['content']) ?? languageText(object['contentMap']) ?? '',
40
+ published: Number.isNaN(published.getTime()) ? new Date(activity.receivedAt) : published,
41
+ inReplyTo,
42
+ };
43
+ }
44
+ /**
45
+ * `@user@host` for an actor URL, or `undefined` when the URL implies none.
46
+ *
47
+ * A guess, and deliberately so: naming the author properly would mean
48
+ * dereferencing the actor, which is a network round trip per comment shown. A
49
+ * follower the site already knows is named from its stored profile instead,
50
+ * and this is the fallback for everybody else.
51
+ */
52
+ export function actorHandle(actorId) {
53
+ let url;
54
+ try {
55
+ url = new URL(actorId);
56
+ }
57
+ catch {
58
+ return undefined;
59
+ }
60
+ const last = url.pathname
61
+ .split('/')
62
+ .filter((segment) => segment !== '')
63
+ .pop();
64
+ if (last === undefined || last === '')
65
+ return undefined;
66
+ return `@${last.replace(/^@/, '')}@${url.host}`;
67
+ }
68
+ /**
69
+ * What a stored activity replies to, or `null` when it replies to nothing.
70
+ *
71
+ * This is the whole definition of the `in_reply_to` index column: it is
72
+ * derived from the activity and never supplied, so a database rebuilt from the
73
+ * inbox log holds exactly what the live one holds.
74
+ *
75
+ * JSON-LD lets `inReplyTo` be a string, a node object or an array of either,
76
+ * and a compacted activity may carry the object as a bare id instead of
77
+ * inlining it. Anything that is not a single absolute URI is no target.
78
+ */
79
+ export function replyTargetOf(json) {
80
+ const object = activityObject(json);
81
+ if (object === undefined)
82
+ return null;
83
+ return uriOf(object['inReplyTo']);
84
+ }
85
+ /** The inlined object of a stored activity, or `undefined` when there is none. */
86
+ function activityObject(json) {
87
+ let parsed;
88
+ try {
89
+ parsed = JSON.parse(json);
90
+ }
91
+ catch {
92
+ // A row whose JSON does not parse is not a reply. It is not anything.
93
+ return undefined;
94
+ }
95
+ if (!isRecord(parsed))
96
+ return undefined;
97
+ const object = parsed['object'];
98
+ return isRecord(object) ? object : undefined;
99
+ }
100
+ /**
101
+ * A JSON-LD value as the one absolute URI it names, or `null`.
102
+ *
103
+ * The three spellings a compacted document may use — a string, `{"id": …}`,
104
+ * and either of those wrapped in an array — all mean the same thing here, and
105
+ * the first of a list is the one that is kept: a note that answers several
106
+ * things is shown under the first one it names.
107
+ *
108
+ * Exported for the inbox log's sake: every id column of the index is read out
109
+ * of the stored activity by this, so what a rebuilt row says about an actor or
110
+ * an object is what a live one says.
111
+ */
112
+ export function uriOf(value) {
113
+ if (Array.isArray(value)) {
114
+ for (const item of value) {
115
+ const found = uriOf(item);
116
+ if (found !== null)
117
+ return found;
118
+ }
119
+ return null;
120
+ }
121
+ // A node object names its subject with `id`; a `Link` — which is how a note
122
+ // often spells its `url` — names its target with `href`.
123
+ if (isRecord(value))
124
+ return uriOf(value['id'] ?? value['@id'] ?? value['href']);
125
+ if (typeof value !== 'string')
126
+ return null;
127
+ try {
128
+ return new URL(value).href;
129
+ }
130
+ catch {
131
+ return null;
132
+ }
133
+ }
134
+ /** A JSON-LD value as the one string it holds, or `undefined`. */
135
+ function textOf(value) {
136
+ if (Array.isArray(value)) {
137
+ for (const item of value) {
138
+ const found = textOf(item);
139
+ if (found !== undefined)
140
+ return found;
141
+ }
142
+ return undefined;
143
+ }
144
+ if (isRecord(value))
145
+ return textOf(value['@value']);
146
+ return typeof value === 'string' ? value : undefined;
147
+ }
148
+ /**
149
+ * One value out of a language map, which is how a compacted document spells a
150
+ * property that named its language. Which language is not worth choosing: a
151
+ * note is written in one, and the map holds that one.
152
+ */
153
+ function languageText(value) {
154
+ if (!isRecord(value))
155
+ return undefined;
156
+ for (const entry of Object.values(value)) {
157
+ const found = textOf(entry);
158
+ if (found !== undefined)
159
+ return found;
160
+ }
161
+ return undefined;
162
+ }
163
+ function isRecord(value) {
164
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
165
+ }
166
+ //# sourceMappingURL=replies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replies.js","sourceRoot":"","sources":["../../src/federation/replies.ts"],"names":[],"mappings":"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"}