@geekity/cms 0.3.0 → 0.4.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 (637) hide show
  1. package/README.md +2091 -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/pages/documents/editor.njk +196 -0
  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/media/library.njk +160 -0
  19. package/admin/pages/messages/all.njk +110 -0
  20. package/admin/{layouts → pages}/placeholder.njk +5 -1
  21. package/admin/pages/settings/discussion.njk +99 -0
  22. package/admin/pages/settings/email.njk +203 -0
  23. package/admin/pages/settings/federation.njk +75 -0
  24. package/admin/pages/settings/general.njk +29 -0
  25. package/admin/pages/settings/permalinks.njk +50 -0
  26. package/admin/pages/settings/reading.njk +72 -0
  27. package/admin/pages/users/edit.njk +239 -0
  28. package/admin/pages/users/list.njk +48 -0
  29. package/admin/pages/users/new.njk +41 -0
  30. package/admin/static/admin.css +498 -3
  31. package/admin/static/copy.js +52 -0
  32. package/admin/static/editor.js +16 -16
  33. package/admin/static/slug.js +61 -0
  34. package/dist/admin/accounts.d.ts +413 -0
  35. package/dist/admin/accounts.d.ts.map +1 -0
  36. package/dist/admin/accounts.js +680 -0
  37. package/dist/admin/accounts.js.map +1 -0
  38. package/dist/admin/appearance.d.ts +80 -0
  39. package/dist/admin/appearance.d.ts.map +1 -0
  40. package/dist/admin/appearance.js +136 -0
  41. package/dist/admin/appearance.js.map +1 -0
  42. package/dist/admin/comments.d.ts +90 -0
  43. package/dist/admin/comments.d.ts.map +1 -0
  44. package/dist/admin/comments.js +244 -0
  45. package/dist/admin/comments.js.map +1 -0
  46. package/dist/admin/credentials.d.ts +26 -2
  47. package/dist/admin/credentials.d.ts.map +1 -1
  48. package/dist/admin/credentials.js +35 -2
  49. package/dist/admin/credentials.js.map +1 -1
  50. package/dist/admin/documents.d.ts +127 -10
  51. package/dist/admin/documents.d.ts.map +1 -1
  52. package/dist/admin/documents.js +360 -41
  53. package/dist/admin/documents.js.map +1 -1
  54. package/dist/admin/federation.d.ts +151 -50
  55. package/dist/admin/federation.d.ts.map +1 -1
  56. package/dist/admin/federation.js +225 -93
  57. package/dist/admin/federation.js.map +1 -1
  58. package/dist/admin/formatting.d.ts +20 -0
  59. package/dist/admin/formatting.d.ts.map +1 -0
  60. package/dist/admin/formatting.js +72 -0
  61. package/dist/admin/formatting.js.map +1 -0
  62. package/dist/admin/headers.d.ts +65 -0
  63. package/dist/admin/headers.d.ts.map +1 -0
  64. package/dist/admin/headers.js +104 -0
  65. package/dist/admin/headers.js.map +1 -0
  66. package/dist/admin/index.d.ts +38 -12
  67. package/dist/admin/index.d.ts.map +1 -1
  68. package/dist/admin/index.js +25 -7
  69. package/dist/admin/index.js.map +1 -1
  70. package/dist/admin/media.d.ts +168 -0
  71. package/dist/admin/media.d.ts.map +1 -0
  72. package/dist/admin/media.js +295 -0
  73. package/dist/admin/media.js.map +1 -0
  74. package/dist/admin/menu.d.ts +79 -0
  75. package/dist/admin/menu.d.ts.map +1 -0
  76. package/dist/admin/menu.js +126 -0
  77. package/dist/admin/menu.js.map +1 -0
  78. package/dist/admin/messages.d.ts +80 -0
  79. package/dist/admin/messages.d.ts.map +1 -0
  80. package/dist/admin/messages.js +152 -0
  81. package/dist/admin/messages.js.map +1 -0
  82. package/dist/admin/preview.d.ts.map +1 -1
  83. package/dist/admin/preview.js +31 -7
  84. package/dist/admin/preview.js.map +1 -1
  85. package/dist/admin/recovery.d.ts +92 -0
  86. package/dist/admin/recovery.d.ts.map +1 -0
  87. package/dist/admin/recovery.js +229 -0
  88. package/dist/admin/recovery.js.map +1 -0
  89. package/dist/admin/routes.d.ts +0 -20
  90. package/dist/admin/routes.d.ts.map +1 -1
  91. package/dist/admin/routes.js +155 -105
  92. package/dist/admin/routes.js.map +1 -1
  93. package/dist/admin/settings-discussion.d.ts +37 -0
  94. package/dist/admin/settings-discussion.d.ts.map +1 -0
  95. package/dist/admin/settings-discussion.js +117 -0
  96. package/dist/admin/settings-discussion.js.map +1 -0
  97. package/dist/admin/settings-email.d.ts +54 -0
  98. package/dist/admin/settings-email.d.ts.map +1 -0
  99. package/dist/admin/settings-email.js +189 -0
  100. package/dist/admin/settings-email.js.map +1 -0
  101. package/dist/admin/settings-federation.d.ts +39 -0
  102. package/dist/admin/settings-federation.d.ts.map +1 -0
  103. package/dist/admin/settings-federation.js +103 -0
  104. package/dist/admin/settings-federation.js.map +1 -0
  105. package/dist/admin/settings-general.d.ts +12 -0
  106. package/dist/admin/settings-general.d.ts.map +1 -0
  107. package/dist/admin/settings-general.js +48 -0
  108. package/dist/admin/settings-general.js.map +1 -0
  109. package/dist/admin/settings-page.d.ts +102 -0
  110. package/dist/admin/settings-page.d.ts.map +1 -0
  111. package/dist/admin/settings-page.js +126 -0
  112. package/dist/admin/settings-page.js.map +1 -0
  113. package/dist/admin/settings-pages.d.ts +19 -0
  114. package/dist/admin/settings-pages.d.ts.map +1 -0
  115. package/dist/admin/settings-pages.js +33 -0
  116. package/dist/admin/settings-pages.js.map +1 -0
  117. package/dist/admin/settings-permalinks.d.ts +16 -0
  118. package/dist/admin/settings-permalinks.d.ts.map +1 -0
  119. package/dist/admin/settings-permalinks.js +32 -0
  120. package/dist/admin/settings-permalinks.js.map +1 -0
  121. package/dist/admin/settings-reading.d.ts +33 -0
  122. package/dist/admin/settings-reading.d.ts.map +1 -0
  123. package/dist/admin/settings-reading.js +48 -0
  124. package/dist/admin/settings-reading.js.map +1 -0
  125. package/dist/admin/settings.d.ts +325 -96
  126. package/dist/admin/settings.d.ts.map +1 -1
  127. package/dist/admin/settings.js +650 -308
  128. package/dist/admin/settings.js.map +1 -1
  129. package/dist/admin/store.d.ts +606 -152
  130. package/dist/admin/store.d.ts.map +1 -1
  131. package/dist/admin/store.js +863 -268
  132. package/dist/admin/store.js.map +1 -1
  133. package/dist/admin/taxonomy.d.ts +114 -0
  134. package/dist/admin/taxonomy.d.ts.map +1 -0
  135. package/dist/admin/taxonomy.js +289 -0
  136. package/dist/admin/taxonomy.js.map +1 -0
  137. package/dist/admin/templates.d.ts +44 -14
  138. package/dist/admin/templates.d.ts.map +1 -1
  139. package/dist/admin/templates.js +44 -14
  140. package/dist/admin/templates.js.map +1 -1
  141. package/dist/admin/throttle.d.ts +84 -0
  142. package/dist/admin/throttle.d.ts.map +1 -0
  143. package/dist/admin/throttle.js +143 -0
  144. package/dist/admin/throttle.js.map +1 -0
  145. package/dist/admin/uploads.d.ts +28 -2
  146. package/dist/admin/uploads.d.ts.map +1 -1
  147. package/dist/admin/uploads.js +43 -4
  148. package/dist/admin/uploads.js.map +1 -1
  149. package/dist/admin/users.d.ts +100 -13
  150. package/dist/admin/users.d.ts.map +1 -1
  151. package/dist/admin/users.js +412 -39
  152. package/dist/admin/users.js.map +1 -1
  153. package/dist/cache.d.ts +141 -0
  154. package/dist/cache.d.ts.map +1 -0
  155. package/dist/cache.js +207 -0
  156. package/dist/cache.js.map +1 -0
  157. package/dist/cli.d.ts +14 -2
  158. package/dist/cli.d.ts.map +1 -1
  159. package/dist/cli.js +424 -21
  160. package/dist/cli.js.map +1 -1
  161. package/dist/comments/akismet.d.ts +130 -0
  162. package/dist/comments/akismet.d.ts.map +1 -0
  163. package/dist/comments/akismet.js +274 -0
  164. package/dist/comments/akismet.js.map +1 -0
  165. package/dist/comments/conversation.d.ts +29 -0
  166. package/dist/comments/conversation.d.ts.map +1 -0
  167. package/dist/comments/conversation.js +60 -0
  168. package/dist/comments/conversation.js.map +1 -0
  169. package/dist/comments/form.d.ts +75 -0
  170. package/dist/comments/form.d.ts.map +1 -0
  171. package/dist/comments/form.js +64 -0
  172. package/dist/comments/form.js.map +1 -0
  173. package/dist/comments/index.d.ts +15 -0
  174. package/dist/comments/index.d.ts.map +1 -0
  175. package/dist/comments/index.js +9 -0
  176. package/dist/comments/index.js.map +1 -0
  177. package/dist/comments/markdown.d.ts +8 -0
  178. package/dist/comments/markdown.d.ts.map +1 -0
  179. package/dist/comments/markdown.js +85 -0
  180. package/dist/comments/markdown.js.map +1 -0
  181. package/dist/comments/moderate.d.ts +71 -0
  182. package/dist/comments/moderate.d.ts.map +1 -0
  183. package/dist/comments/moderate.js +88 -0
  184. package/dist/comments/moderate.js.map +1 -0
  185. package/dist/comments/policy.d.ts +57 -0
  186. package/dist/comments/policy.d.ts.map +1 -0
  187. package/dist/comments/policy.js +80 -0
  188. package/dist/comments/policy.js.map +1 -0
  189. package/dist/comments/records.d.ts +266 -0
  190. package/dist/comments/records.d.ts.map +1 -0
  191. package/dist/comments/records.js +487 -0
  192. package/dist/comments/records.js.map +1 -0
  193. package/dist/comments/routes.d.ts +58 -0
  194. package/dist/comments/routes.d.ts.map +1 -0
  195. package/dist/comments/routes.js +177 -0
  196. package/dist/comments/routes.js.map +1 -0
  197. package/dist/comments/submission.d.ts +263 -0
  198. package/dist/comments/submission.d.ts.map +1 -0
  199. package/dist/comments/submission.js +241 -0
  200. package/dist/comments/submission.js.map +1 -0
  201. package/dist/config.d.ts +190 -5
  202. package/dist/config.d.ts.map +1 -1
  203. package/dist/config.js +118 -6
  204. package/dist/config.js.map +1 -1
  205. package/dist/contact/delivery.d.ts +60 -0
  206. package/dist/contact/delivery.d.ts.map +1 -0
  207. package/dist/contact/delivery.js +87 -0
  208. package/dist/contact/delivery.js.map +1 -0
  209. package/dist/contact/form.d.ts +130 -0
  210. package/dist/contact/form.d.ts.map +1 -0
  211. package/dist/contact/form.js +163 -0
  212. package/dist/contact/form.js.map +1 -0
  213. package/dist/contact/index.d.ts +17 -0
  214. package/dist/contact/index.d.ts.map +1 -0
  215. package/dist/contact/index.js +13 -0
  216. package/dist/contact/index.js.map +1 -0
  217. package/dist/contact/records.d.ts +124 -0
  218. package/dist/contact/records.d.ts.map +1 -0
  219. package/dist/contact/records.js +218 -0
  220. package/dist/contact/records.js.map +1 -0
  221. package/dist/contact/routes.d.ts +17 -0
  222. package/dist/contact/routes.d.ts.map +1 -0
  223. package/dist/contact/routes.js +127 -0
  224. package/dist/contact/routes.js.map +1 -0
  225. package/dist/contact/submission.d.ts +103 -0
  226. package/dist/contact/submission.d.ts.map +1 -0
  227. package/dist/contact/submission.js +166 -0
  228. package/dist/contact/submission.js.map +1 -0
  229. package/dist/content/document.d.ts +7 -2
  230. package/dist/content/document.d.ts.map +1 -1
  231. package/dist/content/document.js +1 -0
  232. package/dist/content/document.js.map +1 -1
  233. package/dist/content/index.d.ts +7 -2
  234. package/dist/content/index.d.ts.map +1 -1
  235. package/dist/content/index.js +4 -1
  236. package/dist/content/index.js.map +1 -1
  237. package/dist/content/markdown.d.ts.map +1 -1
  238. package/dist/content/markdown.js +24 -2
  239. package/dist/content/markdown.js.map +1 -1
  240. package/dist/content/parser.d.ts.map +1 -1
  241. package/dist/content/parser.js +11 -4
  242. package/dist/content/parser.js.map +1 -1
  243. package/dist/content/save.d.ts +5 -0
  244. package/dist/content/save.d.ts.map +1 -1
  245. package/dist/content/save.js +44 -1
  246. package/dist/content/save.js.map +1 -1
  247. package/dist/content/schedule.d.ts +125 -0
  248. package/dist/content/schedule.d.ts.map +1 -0
  249. package/dist/content/schedule.js +207 -0
  250. package/dist/content/schedule.js.map +1 -0
  251. package/dist/content/search.d.ts +64 -0
  252. package/dist/content/search.d.ts.map +1 -0
  253. package/dist/content/search.js +136 -0
  254. package/dist/content/search.js.map +1 -0
  255. package/dist/content/store.d.ts +202 -7
  256. package/dist/content/store.d.ts.map +1 -1
  257. package/dist/content/store.js +374 -67
  258. package/dist/content/store.js.map +1 -1
  259. package/dist/content/sync.d.ts +7 -1
  260. package/dist/content/sync.d.ts.map +1 -1
  261. package/dist/content/sync.js +18 -10
  262. package/dist/content/sync.js.map +1 -1
  263. package/dist/content/time.d.ts +56 -0
  264. package/dist/content/time.d.ts.map +1 -0
  265. package/dist/content/time.js +141 -0
  266. package/dist/content/time.js.map +1 -0
  267. package/dist/content/writer.d.ts.map +1 -1
  268. package/dist/content/writer.js +3 -0
  269. package/dist/content/writer.js.map +1 -1
  270. package/dist/env.d.ts +58 -4
  271. package/dist/env.d.ts.map +1 -1
  272. package/dist/federation/actor.d.ts +95 -41
  273. package/dist/federation/actor.d.ts.map +1 -1
  274. package/dist/federation/actor.js +180 -53
  275. package/dist/federation/actor.js.map +1 -1
  276. package/dist/federation/article.d.ts +44 -17
  277. package/dist/federation/article.d.ts.map +1 -1
  278. package/dist/federation/article.js +98 -46
  279. package/dist/federation/article.js.map +1 -1
  280. package/dist/federation/delivery.d.ts +63 -15
  281. package/dist/federation/delivery.d.ts.map +1 -1
  282. package/dist/federation/delivery.js +154 -80
  283. package/dist/federation/delivery.js.map +1 -1
  284. package/dist/federation/federation.d.ts +22 -17
  285. package/dist/federation/federation.d.ts.map +1 -1
  286. package/dist/federation/federation.js +98 -77
  287. package/dist/federation/federation.js.map +1 -1
  288. package/dist/federation/followers.d.ts +3 -2
  289. package/dist/federation/followers.d.ts.map +1 -1
  290. package/dist/federation/followers.js +6 -5
  291. package/dist/federation/followers.js.map +1 -1
  292. package/dist/federation/import-wordpress.d.ts +128 -0
  293. package/dist/federation/import-wordpress.d.ts.map +1 -0
  294. package/dist/federation/import-wordpress.js +426 -0
  295. package/dist/federation/import-wordpress.js.map +1 -0
  296. package/dist/federation/inbox.d.ts +36 -13
  297. package/dist/federation/inbox.d.ts.map +1 -1
  298. package/dist/federation/inbox.js +120 -49
  299. package/dist/federation/inbox.js.map +1 -1
  300. package/dist/federation/index.d.ts +22 -10
  301. package/dist/federation/index.d.ts.map +1 -1
  302. package/dist/federation/index.js +13 -8
  303. package/dist/federation/index.js.map +1 -1
  304. package/dist/federation/keys.d.ts +98 -20
  305. package/dist/federation/keys.d.ts.map +1 -1
  306. package/dist/federation/keys.js +269 -39
  307. package/dist/federation/keys.js.map +1 -1
  308. package/dist/federation/mount.d.ts +42 -10
  309. package/dist/federation/mount.d.ts.map +1 -1
  310. package/dist/federation/mount.js +266 -26
  311. package/dist/federation/mount.js.map +1 -1
  312. package/dist/federation/paths.d.ts +23 -35
  313. package/dist/federation/paths.d.ts.map +1 -1
  314. package/dist/federation/paths.js +26 -39
  315. package/dist/federation/paths.js.map +1 -1
  316. package/dist/federation/records.d.ts +223 -0
  317. package/dist/federation/records.d.ts.map +1 -0
  318. package/dist/federation/records.js +506 -0
  319. package/dist/federation/records.js.map +1 -0
  320. package/dist/federation/relays.d.ts +114 -0
  321. package/dist/federation/relays.d.ts.map +1 -0
  322. package/dist/federation/relays.js +290 -0
  323. package/dist/federation/relays.js.map +1 -0
  324. package/dist/federation/replies.d.ts +80 -0
  325. package/dist/federation/replies.d.ts.map +1 -0
  326. package/dist/federation/replies.js +166 -0
  327. package/dist/federation/replies.js.map +1 -0
  328. package/dist/federation/wordpress.d.ts +131 -0
  329. package/dist/federation/wordpress.d.ts.map +1 -0
  330. package/dist/federation/wordpress.js +341 -0
  331. package/dist/federation/wordpress.js.map +1 -0
  332. package/dist/files/atomic.d.ts +103 -0
  333. package/dist/files/atomic.d.ts.map +1 -0
  334. package/dist/files/atomic.js +150 -0
  335. package/dist/files/atomic.js.map +1 -0
  336. package/dist/files/index.d.ts +3 -0
  337. package/dist/files/index.d.ts.map +1 -0
  338. package/dist/files/index.js +2 -0
  339. package/dist/files/index.js.map +1 -0
  340. package/dist/forms/protection.d.ts +85 -0
  341. package/dist/forms/protection.d.ts.map +1 -0
  342. package/dist/forms/protection.js +116 -0
  343. package/dist/forms/protection.js.map +1 -0
  344. package/dist/images/icons.d.ts +59 -0
  345. package/dist/images/icons.d.ts.map +1 -0
  346. package/dist/images/icons.js +131 -0
  347. package/dist/images/icons.js.map +1 -0
  348. package/dist/images/index.d.ts +7 -0
  349. package/dist/images/index.d.ts.map +1 -0
  350. package/dist/images/index.js +4 -0
  351. package/dist/images/index.js.map +1 -0
  352. package/dist/images/markup.d.ts +47 -0
  353. package/dist/images/markup.d.ts.map +1 -0
  354. package/dist/images/markup.js +175 -0
  355. package/dist/images/markup.js.map +1 -0
  356. package/dist/images/paths.d.ts +34 -0
  357. package/dist/images/paths.d.ts.map +1 -0
  358. package/dist/images/paths.js +41 -0
  359. package/dist/images/paths.js.map +1 -0
  360. package/dist/images/variants.d.ts +104 -0
  361. package/dist/images/variants.d.ts.map +1 -0
  362. package/dist/images/variants.js +320 -0
  363. package/dist/images/variants.js.map +1 -0
  364. package/dist/index.d.ts +123 -19
  365. package/dist/index.d.ts.map +1 -1
  366. package/dist/index.js +327 -25
  367. package/dist/index.js.map +1 -1
  368. package/dist/init.d.ts +18 -0
  369. package/dist/init.d.ts.map +1 -1
  370. package/dist/init.js +34 -3
  371. package/dist/init.js.map +1 -1
  372. package/dist/mail/brevo.d.ts +35 -0
  373. package/dist/mail/brevo.d.ts.map +1 -0
  374. package/dist/mail/brevo.js +85 -0
  375. package/dist/mail/brevo.js.map +1 -0
  376. package/dist/mail/credentials.d.ts +62 -0
  377. package/dist/mail/credentials.d.ts.map +1 -0
  378. package/dist/mail/credentials.js +86 -0
  379. package/dist/mail/credentials.js.map +1 -0
  380. package/dist/mail/index.d.ts +15 -0
  381. package/dist/mail/index.d.ts.map +1 -0
  382. package/dist/mail/index.js +8 -0
  383. package/dist/mail/index.js.map +1 -0
  384. package/dist/mail/memory.d.ts +35 -0
  385. package/dist/mail/memory.d.ts.map +1 -0
  386. package/dist/mail/memory.js +29 -0
  387. package/dist/mail/memory.js.map +1 -0
  388. package/dist/mail/provider.d.ts +80 -0
  389. package/dist/mail/provider.d.ts.map +1 -0
  390. package/dist/mail/provider.js +23 -0
  391. package/dist/mail/provider.js.map +1 -0
  392. package/dist/mail/service.d.ts +156 -0
  393. package/dist/mail/service.d.ts.map +1 -0
  394. package/dist/mail/service.js +265 -0
  395. package/dist/mail/service.js.map +1 -0
  396. package/dist/mail/smtp.d.ts +39 -0
  397. package/dist/mail/smtp.d.ts.map +1 -0
  398. package/dist/mail/smtp.js +58 -0
  399. package/dist/mail/smtp.js.map +1 -0
  400. package/dist/mail/templates.d.ts +91 -0
  401. package/dist/mail/templates.d.ts.map +1 -0
  402. package/dist/mail/templates.js +69 -0
  403. package/dist/mail/templates.js.map +1 -0
  404. package/dist/notifications/comments.d.ts +66 -0
  405. package/dist/notifications/comments.d.ts.map +1 -0
  406. package/dist/notifications/comments.js +151 -0
  407. package/dist/notifications/comments.js.map +1 -0
  408. package/dist/notifications/digest.d.ts +135 -0
  409. package/dist/notifications/digest.d.ts.map +1 -0
  410. package/dist/notifications/digest.js +287 -0
  411. package/dist/notifications/digest.js.map +1 -0
  412. package/dist/notifications/index.d.ts +13 -0
  413. package/dist/notifications/index.d.ts.map +1 -0
  414. package/dist/notifications/index.js +8 -0
  415. package/dist/notifications/index.js.map +1 -0
  416. package/dist/notifications/links.d.ts +60 -0
  417. package/dist/notifications/links.d.ts.map +1 -0
  418. package/dist/notifications/links.js +63 -0
  419. package/dist/notifications/links.js.map +1 -0
  420. package/dist/notifications/optouts.d.ts +48 -0
  421. package/dist/notifications/optouts.d.ts.map +1 -0
  422. package/dist/notifications/optouts.js +93 -0
  423. package/dist/notifications/optouts.js.map +1 -0
  424. package/dist/notifications/preferences.d.ts +158 -0
  425. package/dist/notifications/preferences.d.ts.map +1 -0
  426. package/dist/notifications/preferences.js +195 -0
  427. package/dist/notifications/preferences.js.map +1 -0
  428. package/dist/notifications/routes.d.ts +28 -0
  429. package/dist/notifications/routes.d.ts.map +1 -0
  430. package/dist/notifications/routes.js +184 -0
  431. package/dist/notifications/routes.js.map +1 -0
  432. package/dist/notifications/tokens.d.ts +60 -0
  433. package/dist/notifications/tokens.d.ts.map +1 -0
  434. package/dist/notifications/tokens.js +125 -0
  435. package/dist/notifications/tokens.js.map +1 -0
  436. package/dist/notify.d.ts +84 -0
  437. package/dist/notify.d.ts.map +1 -0
  438. package/dist/notify.js +149 -0
  439. package/dist/notify.js.map +1 -0
  440. package/dist/web/archive.d.ts +49 -0
  441. package/dist/web/archive.d.ts.map +1 -0
  442. package/dist/web/archive.js +59 -0
  443. package/dist/web/archive.js.map +1 -0
  444. package/dist/web/assets.d.ts +6 -5
  445. package/dist/web/assets.d.ts.map +1 -1
  446. package/dist/web/assets.js +5 -7
  447. package/dist/web/assets.js.map +1 -1
  448. package/dist/web/authors.d.ts +143 -0
  449. package/dist/web/authors.d.ts.map +1 -0
  450. package/dist/web/authors.js +178 -0
  451. package/dist/web/authors.js.map +1 -0
  452. package/dist/web/comments.d.ts +60 -0
  453. package/dist/web/comments.d.ts.map +1 -0
  454. package/dist/web/comments.js +207 -0
  455. package/dist/web/comments.js.map +1 -0
  456. package/dist/web/context.d.ts +162 -28
  457. package/dist/web/context.d.ts.map +1 -1
  458. package/dist/web/context.js +123 -26
  459. package/dist/web/context.js.map +1 -1
  460. package/dist/web/conversation.d.ts +209 -0
  461. package/dist/web/conversation.d.ts.map +1 -0
  462. package/dist/web/conversation.js +557 -0
  463. package/dist/web/conversation.js.map +1 -0
  464. package/dist/web/documents.d.ts +36 -6
  465. package/dist/web/documents.d.ts.map +1 -1
  466. package/dist/web/documents.js +52 -10
  467. package/dist/web/documents.js.map +1 -1
  468. package/dist/web/feed-atom.d.ts +22 -0
  469. package/dist/web/feed-atom.d.ts.map +1 -0
  470. package/dist/web/feed-atom.js +83 -0
  471. package/dist/web/feed-atom.js.map +1 -0
  472. package/dist/web/feed-item.d.ts +145 -0
  473. package/dist/web/feed-item.d.ts.map +1 -0
  474. package/dist/web/feed-item.js +120 -0
  475. package/dist/web/feed-item.js.map +1 -0
  476. package/dist/web/feed-json.d.ts +79 -0
  477. package/dist/web/feed-json.d.ts.map +1 -0
  478. package/dist/web/feed-json.js +53 -0
  479. package/dist/web/feed-json.js.map +1 -0
  480. package/dist/web/feed-rss.d.ts +26 -0
  481. package/dist/web/feed-rss.d.ts.map +1 -0
  482. package/dist/web/feed-rss.js +203 -0
  483. package/dist/web/feed-rss.js.map +1 -0
  484. package/dist/web/feed-source.d.ts +244 -0
  485. package/dist/web/feed-source.d.ts.map +1 -0
  486. package/dist/web/feed-source.js +201 -0
  487. package/dist/web/feed-source.js.map +1 -0
  488. package/dist/web/feed-xml.d.ts +63 -0
  489. package/dist/web/feed-xml.d.ts.map +1 -0
  490. package/dist/web/feed-xml.js +116 -0
  491. package/dist/web/feed-xml.js.map +1 -0
  492. package/dist/web/feeds.d.ts +31 -96
  493. package/dist/web/feeds.d.ts.map +1 -1
  494. package/dist/web/feeds.js +94 -198
  495. package/dist/web/feeds.js.map +1 -1
  496. package/dist/web/health.d.ts +31 -0
  497. package/dist/web/health.d.ts.map +1 -0
  498. package/dist/web/health.js +44 -0
  499. package/dist/web/health.js.map +1 -0
  500. package/dist/web/index.d.ts +30 -10
  501. package/dist/web/index.d.ts.map +1 -1
  502. package/dist/web/index.js +18 -7
  503. package/dist/web/index.js.map +1 -1
  504. package/dist/web/navigation.d.ts +73 -0
  505. package/dist/web/navigation.d.ts.map +1 -0
  506. package/dist/web/navigation.js +110 -0
  507. package/dist/web/navigation.js.map +1 -0
  508. package/dist/web/negotiate.d.ts +9 -0
  509. package/dist/web/negotiate.d.ts.map +1 -1
  510. package/dist/web/negotiate.js +6 -1
  511. package/dist/web/negotiate.js.map +1 -1
  512. package/dist/web/recent.d.ts +43 -0
  513. package/dist/web/recent.d.ts.map +1 -0
  514. package/dist/web/recent.js +37 -0
  515. package/dist/web/recent.js.map +1 -0
  516. package/dist/web/render.d.ts +197 -9
  517. package/dist/web/render.d.ts.map +1 -1
  518. package/dist/web/render.js +334 -17
  519. package/dist/web/render.js.map +1 -1
  520. package/dist/web/routes.d.ts +25 -8
  521. package/dist/web/routes.d.ts.map +1 -1
  522. package/dist/web/routes.js +845 -93
  523. package/dist/web/routes.js.map +1 -1
  524. package/dist/web/sanitize.d.ts +19 -0
  525. package/dist/web/sanitize.d.ts.map +1 -0
  526. package/dist/web/sanitize.js +272 -0
  527. package/dist/web/sanitize.js.map +1 -0
  528. package/dist/web/search.d.ts +79 -0
  529. package/dist/web/search.d.ts.map +1 -0
  530. package/dist/web/search.js +94 -0
  531. package/dist/web/search.js.map +1 -0
  532. package/dist/web/sitemap.d.ts +120 -0
  533. package/dist/web/sitemap.d.ts.map +1 -0
  534. package/dist/web/sitemap.js +199 -0
  535. package/dist/web/sitemap.js.map +1 -0
  536. package/dist/web/taxonomy.d.ts +152 -0
  537. package/dist/web/taxonomy.d.ts.map +1 -0
  538. package/dist/web/taxonomy.js +237 -0
  539. package/dist/web/taxonomy.js.map +1 -0
  540. package/dist/web/templates.d.ts +54 -16
  541. package/dist/web/templates.d.ts.map +1 -1
  542. package/dist/web/templates.js +109 -28
  543. package/dist/web/templates.js.map +1 -1
  544. package/dist/web/themes.d.ts +205 -0
  545. package/dist/web/themes.d.ts.map +1 -0
  546. package/dist/web/themes.js +277 -0
  547. package/dist/web/themes.js.map +1 -0
  548. package/dist/webmention/discovery.d.ts +51 -0
  549. package/dist/webmention/discovery.d.ts.map +1 -0
  550. package/dist/webmention/discovery.js +176 -0
  551. package/dist/webmention/discovery.js.map +1 -0
  552. package/dist/webmention/html.d.ts +71 -0
  553. package/dist/webmention/html.d.ts.map +1 -0
  554. package/dist/webmention/html.js +285 -0
  555. package/dist/webmention/html.js.map +1 -0
  556. package/dist/webmention/index.d.ts +12 -0
  557. package/dist/webmention/index.d.ts.map +1 -0
  558. package/dist/webmention/index.js +8 -0
  559. package/dist/webmention/index.js.map +1 -0
  560. package/dist/webmention/links.d.ts +18 -0
  561. package/dist/webmention/links.d.ts.map +1 -0
  562. package/dist/webmention/links.js +64 -0
  563. package/dist/webmention/links.js.map +1 -0
  564. package/dist/webmention/microformats.d.ts +93 -0
  565. package/dist/webmention/microformats.d.ts.map +1 -0
  566. package/dist/webmention/microformats.js +376 -0
  567. package/dist/webmention/microformats.js.map +1 -0
  568. package/dist/webmention/receive.d.ts +141 -0
  569. package/dist/webmention/receive.d.ts.map +1 -0
  570. package/dist/webmention/receive.js +264 -0
  571. package/dist/webmention/receive.js.map +1 -0
  572. package/dist/webmention/routes.d.ts +37 -0
  573. package/dist/webmention/routes.d.ts.map +1 -0
  574. package/dist/webmention/routes.js +75 -0
  575. package/dist/webmention/routes.js.map +1 -0
  576. package/dist/webmention/service.d.ts +94 -0
  577. package/dist/webmention/service.d.ts.map +1 -0
  578. package/dist/webmention/service.js +207 -0
  579. package/dist/webmention/service.js.map +1 -0
  580. package/package.json +11 -6
  581. package/templates/site/content/_data/site.json +1 -0
  582. package/templates/site/content/posts/2026-01-01-hello-world.md +5 -3
  583. package/templates/site/geekity.config.ts +11 -1
  584. package/templates/site/tsconfig.json +1 -1
  585. package/themes/default/README.md +1096 -50
  586. package/themes/default/layouts/404.njk +2 -3
  587. package/themes/default/layouts/author.njk +37 -0
  588. package/themes/default/layouts/base.njk +172 -31
  589. package/themes/default/layouts/category.njk +27 -0
  590. package/themes/default/layouts/front-page.njk +57 -0
  591. package/themes/default/layouts/home.njk +17 -1
  592. package/themes/default/layouts/page.njk +57 -5
  593. package/themes/default/layouts/post.njk +78 -19
  594. package/themes/default/layouts/search.njk +57 -0
  595. package/themes/default/layouts/tag.njk +3 -6
  596. package/themes/default/mail/comment-digest.html.njk +37 -0
  597. package/themes/default/mail/comment-digest.subject.njk +3 -0
  598. package/themes/default/mail/comment-digest.txt.njk +40 -0
  599. package/themes/default/mail/comment-pending.html.njk +27 -0
  600. package/themes/default/mail/comment-pending.subject.njk +2 -0
  601. package/themes/default/mail/comment-pending.txt.njk +24 -0
  602. package/themes/default/mail/comment-reply.html.njk +21 -0
  603. package/themes/default/mail/comment-reply.subject.njk +2 -0
  604. package/themes/default/mail/comment-reply.txt.njk +22 -0
  605. package/themes/default/mail/contact-message.html.njk +24 -0
  606. package/themes/default/mail/contact-message.subject.njk +5 -0
  607. package/themes/default/mail/contact-message.txt.njk +20 -0
  608. package/themes/default/mail/password-changed.html.njk +18 -0
  609. package/themes/default/mail/password-changed.subject.njk +2 -0
  610. package/themes/default/mail/password-changed.txt.njk +17 -0
  611. package/themes/default/mail/password-reset.html.njk +22 -0
  612. package/themes/default/mail/password-reset.subject.njk +2 -0
  613. package/themes/default/mail/password-reset.txt.njk +18 -0
  614. package/themes/default/mail/test.html.njk +14 -0
  615. package/themes/default/mail/test.subject.njk +2 -0
  616. package/themes/default/mail/test.txt.njk +12 -0
  617. package/themes/default/partials/archive.njk +27 -0
  618. package/themes/default/partials/bio.njk +77 -0
  619. package/themes/default/partials/comment-form.njk +109 -0
  620. package/themes/default/partials/contact-form.njk +88 -0
  621. package/themes/default/partials/conversation.njk +139 -0
  622. package/themes/default/partials/feeds.njk +26 -0
  623. package/themes/default/partials/jsonld.njk +120 -0
  624. package/themes/default/partials/pagination.njk +12 -6
  625. package/themes/default/partials/post-list.njk +51 -18
  626. package/themes/default/partials/search-form.njk +17 -0
  627. package/themes/default/partials/tags.njk +26 -5
  628. package/themes/default/static/highlight.js +4 -0
  629. package/themes/default/static/style.css +1119 -194
  630. package/themes/default/theme.json +5 -0
  631. package/admin/layouts/document-editor.njk +0 -167
  632. package/admin/layouts/federation.njk +0 -145
  633. package/admin/layouts/login.njk +0 -23
  634. package/admin/layouts/settings.njk +0 -116
  635. package/admin/layouts/setup.njk +0 -27
  636. package/admin/layouts/users.njk +0 -91
  637. /package/admin/{layouts/_flash.njk → components/flash.njk} +0 -0
@@ -0,0 +1,64 @@
1
+ import { COMMENT_FIELDS, MAXIMUM_BODY_LENGTH, MAXIMUM_NAME_LENGTH } from './submission.js';
2
+ /** Where the comment form posts. */
3
+ export const COMMENT_POST_PATH = '/_geekity/comments';
4
+ /** The query the redirect after a submission carries, and what it can say. */
5
+ export const COMMENT_NOTICE_PARAM = 'comment';
6
+ /**
7
+ * The query a Reply link on a comment carries.
8
+ *
9
+ * Threading without a line of JavaScript: the link goes to the form with the
10
+ * comment it answers named in the URL, the form puts that in its hidden field,
11
+ * and Cancel is a link back to the page without the query.
12
+ */
13
+ export const COMMENT_REPLY_PARAM = 'reply_to';
14
+ /**
15
+ * What that query means, and what the reader is told.
16
+ *
17
+ * A redirect rather than a rendered page, so a refresh does not post the
18
+ * comment again; a query rather than a flash, because a reader has no session
19
+ * to hang one on.
20
+ */
21
+ export const COMMENT_NOTICES = {
22
+ posted: 'Thank you — your comment is on the page.',
23
+ pending: 'Thank you — your comment is waiting to be approved.',
24
+ };
25
+ /** A fresh, empty form for a post that is taking comments. */
26
+ export function commentForm(document, now = new Date(), notifiable = false) {
27
+ return refilledCommentForm(document, blankValues(), {}, now, undefined, notifiable);
28
+ }
29
+ /**
30
+ * The same form with what somebody typed still in it.
31
+ *
32
+ * What a refused submission is answered with: losing a paragraph because an
33
+ * email address had a typo in it is the fastest way to lose a commenter.
34
+ */
35
+ export function refilledCommentForm(document, values, problems, now = new Date(), error, notifiable = false) {
36
+ return {
37
+ action: COMMENT_POST_PATH,
38
+ fields: COMMENT_FIELDS,
39
+ post: document.slug,
40
+ loaded: String(now.getTime()),
41
+ values,
42
+ problems,
43
+ notifiable,
44
+ nameLength: MAXIMUM_NAME_LENGTH,
45
+ bodyLength: MAXIMUM_BODY_LENGTH,
46
+ ...(error === undefined ? {} : { error }),
47
+ };
48
+ }
49
+ /** What a form holds before anybody has typed in it. */
50
+ export function blankValues() {
51
+ return { name: '', email: '', url: '', body: '', inReplyTo: '', notify: '' };
52
+ }
53
+ /** What a submitted form typed, for putting back in a refused one. */
54
+ export function valuesOf(form) {
55
+ return {
56
+ name: form.name,
57
+ email: form.email,
58
+ url: form.url,
59
+ body: form.body,
60
+ inReplyTo: form.inReplyTo,
61
+ notify: form.notify,
62
+ };
63
+ }
64
+ //# sourceMappingURL=form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form.js","sourceRoot":"","sources":["../../src/comments/form.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AA0C3F,oCAAoC;AACpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AAEtD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqC;IAC/D,MAAM,EAAE,0CAA0C;IAClD,OAAO,EAAE,qDAAqD;CAC/D,CAAC;AAEF,8DAA8D;AAC9D,MAAM,UAAU,WAAW,CACzB,QAAkB,EAClB,GAAG,GAAS,IAAI,IAAI,EAAE,EACtB,UAAU,GAAG,KAAK;IAElB,OAAO,mBAAmB,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AACtF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAkB,EAClB,MAAoC,EACpC,QAAyB,EACzB,GAAG,GAAS,IAAI,IAAI,EAAE,EACtB,KAAc,EACd,UAAU,GAAG,KAAK;IAElB,OAAO;QACL,MAAM,EAAE,iBAAiB;QACzB,MAAM,EAAE,cAAc;QACtB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAC7B,MAAM;QACN,QAAQ;QACR,UAAU;QACV,UAAU,EAAE,mBAAmB;QAC/B,UAAU,EAAE,mBAAmB;QAC/B,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,WAAW;IACzB,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AAC/E,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,QAAQ,CAAC,IAAiB;IACxC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ export { AKISMET_ENDPOINT, AKISMET_KEY_FILE, AKISMET_TIMEOUT_MS, AKISMET_USER_AGENT, akismetKeyPath, createAkismetChecker, readAkismetKey, removeAkismetKey, verifyAkismetKey, writeAkismetKey, } from './akismet.ts';
2
+ export type { AkismetCheckerOptions, AkismetKeyRecord, AkismetKeyStatus, VerifyAkismetKeyOptions, } from './akismet.ts';
3
+ export { blankValues, COMMENT_NOTICE_PARAM, COMMENT_NOTICES, COMMENT_POST_PATH, COMMENT_REPLY_PARAM, commentForm, refilledCommentForm, valuesOf, } from './form.ts';
4
+ export type { CommentFormContext } from './form.ts';
5
+ export { renderCommentMarkdown } from './markdown.ts';
6
+ export { isModerationAction, moderateComment, MODERATION_ACTIONS } from './moderate.ts';
7
+ export type { ModerateCommentOptions, ModerationAction, ModerationOutcome } from './moderate.ts';
8
+ export { COMMENTS_FRONT_MATTER_KEY, commentPolicyOf, commentsOpen, DEFAULT_COMMENTS_CLOSE_AFTER_DAYS, } from './policy.ts';
9
+ export type { CommentPolicy } from './policy.ts';
10
+ export { addComment, COMMENTS_DATA_DIRECTORY, commentsDirectory, commentsFile, deleteComment, heldWebmention, intakeComment, readComments, rebuildCommentIndexes, updateComment, } from './records.ts';
11
+ export type { CommentIndexReport, CommentIntakeOutcome, CommentNotices, CommentOrigin, CommentRecords, IntakeCommentOptions, NewComment, ProposedComment, } from './records.ts';
12
+ export { commentFormFor, commentNoticeFor, mountComments } from './routes.ts';
13
+ export { COMMENT_FIELDS, COMMENT_RATE_LIMIT, COMMENT_RATE_WINDOW_SECONDS, COMMENT_SALT_FILE, commentKeys, commentProblems, hashClientAddress, MAXIMUM_BODY_LENGTH, MAXIMUM_NAME_LENGTH, MAXIMUM_URL_LENGTH, MAXIMUM_FORM_AGE_SECONDS, MINIMUM_SUBMIT_SECONDS, normalizeWebsite, submitComment, } from './submission.ts';
14
+ export type { CommentChecker, CommentForm, CommentOutcome, CommentProblems, CommentRefusal, CommentReport, CommentSubmission, SubmissionType, CommentThrottle, CommentVerdict, SubmitCommentOptions, } from './submission.ts';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/comments/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,QAAQ,GACT,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxF,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EACL,yBAAyB,EACzB,eAAe,EACf,YAAY,EACZ,iCAAiC,GAClC,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,UAAU,EACV,uBAAuB,EACvB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACZ,qBAAqB,EACrB,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,UAAU,EACV,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,2BAA2B,EAC3B,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,cAAc,EACd,WAAW,EACX,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,cAAc,EACd,oBAAoB,GACrB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,9 @@
1
+ export { AKISMET_ENDPOINT, AKISMET_KEY_FILE, AKISMET_TIMEOUT_MS, AKISMET_USER_AGENT, akismetKeyPath, createAkismetChecker, readAkismetKey, removeAkismetKey, verifyAkismetKey, writeAkismetKey, } from './akismet.js';
2
+ export { blankValues, COMMENT_NOTICE_PARAM, COMMENT_NOTICES, COMMENT_POST_PATH, COMMENT_REPLY_PARAM, commentForm, refilledCommentForm, valuesOf, } from './form.js';
3
+ export { renderCommentMarkdown } from './markdown.js';
4
+ export { isModerationAction, moderateComment, MODERATION_ACTIONS } from './moderate.js';
5
+ export { COMMENTS_FRONT_MATTER_KEY, commentPolicyOf, commentsOpen, DEFAULT_COMMENTS_CLOSE_AFTER_DAYS, } from './policy.js';
6
+ export { addComment, COMMENTS_DATA_DIRECTORY, commentsDirectory, commentsFile, deleteComment, heldWebmention, intakeComment, readComments, rebuildCommentIndexes, updateComment, } from './records.js';
7
+ export { commentFormFor, commentNoticeFor, mountComments } from './routes.js';
8
+ export { COMMENT_FIELDS, COMMENT_RATE_LIMIT, COMMENT_RATE_WINDOW_SECONDS, COMMENT_SALT_FILE, commentKeys, commentProblems, hashClientAddress, MAXIMUM_BODY_LENGTH, MAXIMUM_NAME_LENGTH, MAXIMUM_URL_LENGTH, MAXIMUM_FORM_AGE_SECONDS, MINIMUM_SUBMIT_SECONDS, normalizeWebsite, submitComment, } from './submission.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/comments/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,cAAc,CAAC;AAOtB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,QAAQ,GACT,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExF,OAAO,EACL,yBAAyB,EACzB,eAAe,EACf,YAAY,EACZ,iCAAiC,GAClC,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,UAAU,EACV,uBAAuB,EACvB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACZ,qBAAqB,EACrB,aAAa,GACd,MAAM,cAAc,CAAC;AAWtB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,2BAA2B,EAC3B,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,GACd,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * A comment body as the HTML the page and the feeds carry.
3
+ *
4
+ * An empty body is empty HTML rather than a stray newline, so nothing calling
5
+ * this has to decide whether "nothing" is worth printing.
6
+ */
7
+ export declare function renderCommentMarkdown(body: string): string;
8
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/comments/markdown.ts"],"names":[],"mappings":"AA2EA;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG1D"}
@@ -0,0 +1,85 @@
1
+ import MarkdownIt from 'markdown-it';
2
+ /**
3
+ * The Markdown a stranger is allowed to write.
4
+ *
5
+ * A post is written by somebody who has signed in, so `content/markdown.ts`
6
+ * renders it with Eleventy's own options — raw HTML included. A comment is
7
+ * written by anybody at all, so it gets its own renderer rather than a
8
+ * sanitising pass over the same one: what is not produced cannot leak, and a
9
+ * profile is easier to read than a list of what was taken out again.
10
+ *
11
+ * Three things are different from the site's own renderer:
12
+ *
13
+ * - **No raw HTML.** `html: false` escapes it, so a `<script>` a commenter
14
+ * typed is the word they typed.
15
+ * - **Every link marked.** `rel="nofollow ugc"` on links written and on bare
16
+ * URLs alike: a comment is user-generated content pointing somewhere else,
17
+ * which is exactly what the two tokens are for.
18
+ * - **No embedding.** An image becomes a link to it. Rendering `<img>` would
19
+ * let a commenter put a stranger's file — and a tracking pixel that logs
20
+ * every reader's address — on somebody else's page.
21
+ *
22
+ * Links are also held to an allowlist of schemes, so nothing reaches a reader
23
+ * that a browser would treat as a program. That is the same list
24
+ * `web/sanitize.ts` publishes remote HTML through, spelled again here because
25
+ * this renderer never sees that module's output.
26
+ */
27
+ /**
28
+ * URL schemes a link in a comment may use.
29
+ *
30
+ * An allowlist rather than a `javascript:` denylist: `data:` and `vbscript:`
31
+ * are as dangerous, and the next scheme somebody thinks of is on no list
32
+ * written today.
33
+ */
34
+ const ALLOWED_SCHEMES = ['http://', 'https://', 'mailto:'];
35
+ /** What every link a comment carries is marked with. */
36
+ const LINK_REL = 'nofollow ugc';
37
+ const markdown = new MarkdownIt({
38
+ html: false,
39
+ linkify: true,
40
+ breaks: true,
41
+ });
42
+ markdown.validateLink = (url) => {
43
+ const lowered = url.trim().toLowerCase();
44
+ return ALLOWED_SCHEMES.some((scheme) => lowered.startsWith(scheme));
45
+ };
46
+ // Every link, however it was written: `[words](url)`, a bare URL linkify
47
+ // found, or a reference definition. One rule covers all three, because
48
+ // markdown-it emits the same token for each.
49
+ markdown.renderer.rules['link_open'] = (tokens, index, options, _env, self) => {
50
+ const token = tokens[index];
51
+ token?.attrSet('rel', LINK_REL);
52
+ return self.renderToken(tokens, index, options);
53
+ };
54
+ // An image, as the link it points at. The alt text is what the commenter meant
55
+ // to say about it, so that is what the link reads; an image with no alt is
56
+ // linked by its URL, which is better than an empty anchor.
57
+ markdown.renderer.rules['image'] = (tokens, index, options, env, self) => {
58
+ const token = tokens[index];
59
+ const alt = self.renderInlineAsText(token?.children ?? [], options, env);
60
+ const href = String(token?.attrGet('src') ?? '');
61
+ // A source this site would not publish as a link is not published as one
62
+ // here either; the words the commenter wrote about it stay.
63
+ if (!markdown.validateLink(href))
64
+ return escapeText(alt);
65
+ return `<a href="${escapeAttribute(href)}" rel="${LINK_REL}">${escapeText(alt || href)}</a>`;
66
+ };
67
+ /**
68
+ * A comment body as the HTML the page and the feeds carry.
69
+ *
70
+ * An empty body is empty HTML rather than a stray newline, so nothing calling
71
+ * this has to decide whether "nothing" is worth printing.
72
+ */
73
+ export function renderCommentMarkdown(body) {
74
+ const trimmed = body.trim();
75
+ return trimmed === '' ? '' : markdown.render(trimmed);
76
+ }
77
+ /** A URL as an attribute value. */
78
+ function escapeAttribute(value) {
79
+ return escapeText(value).replaceAll('"', '&quot;');
80
+ }
81
+ /** Text as markup. */
82
+ function escapeText(value) {
83
+ return value.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
84
+ }
85
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/comments/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,aAAa,CAAC;AAGrC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;GAMG;AACH,MAAM,eAAe,GAAsB,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;AAE9E,wDAAwD;AACxD,MAAM,QAAQ,GAAG,cAAc,CAAC;AAEhC,MAAM,QAAQ,GAAuB,IAAI,UAAU,CAAC;IAClD,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,IAAI;CACb,CAAC,CAAC;AAEH,QAAQ,CAAC,YAAY,GAAG,CAAC,GAAG,EAAE,EAAE;IAC9B,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzC,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC;AAEF,yEAAyE;AACzE,uEAAuE;AACvE,6CAA6C;AAC7C,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAChC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC,CAAC;AAEF,+EAA+E;AAC/E,2EAA2E;AAC3E,2DAA2D;AAC3D,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;IACvE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,QAAQ,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACjD,yEAAyE;IACzE,4DAA4D;IAC5D,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC;QAAE,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;IAEzD,OAAO,YAAY,eAAe,CAAC,IAAI,CAAC,UAAU,QAAQ,KAAK,UAAU,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC;AAC/F,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACxD,CAAC;AAED,mCAAmC;AACnC,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACrD,CAAC;AAED,sBAAsB;AACtB,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACxF,CAAC"}
@@ -0,0 +1,71 @@
1
+ import type { CommentStatus, PostComment } from '../admin/store.ts';
2
+ import type { CommentRecords } from './records.ts';
3
+ import type { CommentChecker } from './submission.ts';
4
+ /**
5
+ * The three things that can be done to a stored comment, in one place.
6
+ *
7
+ * There are two doors onto them — the moderation screen, and the one-click
8
+ * links a notification carries (TASK-55) — and they have to agree about
9
+ * everything: which file is rewritten, when the index moves, and when a spam
10
+ * checker is told a human disagreed with it. Two copies of that would drift,
11
+ * and the way they would drift is that the email links would quietly stop
12
+ * training Akismet.
13
+ *
14
+ * So this is the whole of moderation, and both doors are a thin skin over it:
15
+ * one turns the outcome into a flash and a redirect, the other into a page a
16
+ * mail reader can show.
17
+ */
18
+ /** What a button, or a link in a message, can do to a comment. */
19
+ export declare const MODERATION_ACTIONS: readonly ['approve', 'spam', 'delete'];
20
+ /** One of {@link MODERATION_ACTIONS}. */
21
+ export type ModerationAction = (typeof MODERATION_ACTIONS)[number];
22
+ /** Whether a name is one of them. */
23
+ export declare function isModerationAction(value: string): value is ModerationAction;
24
+ /** What became of one moderation. */
25
+ export type ModerationOutcome =
26
+ /** There is no such comment; somebody else has already dealt with it. */
27
+ {
28
+ readonly kind: 'gone';
29
+ }
30
+ /** It was already exactly that, so nothing was written. */
31
+ | {
32
+ readonly kind: 'unchanged';
33
+ readonly comment: PostComment;
34
+ }
35
+ /** It moved, and this is where it was before. */
36
+ | {
37
+ readonly kind: 'moved';
38
+ readonly comment: PostComment;
39
+ readonly before: CommentStatus;
40
+ }
41
+ /** It is gone now. The comment is what it was when it went. */
42
+ | {
43
+ readonly kind: 'deleted';
44
+ readonly comment: PostComment;
45
+ };
46
+ /** What {@link moderateComment} needs around it. */
47
+ export interface ModerateCommentOptions {
48
+ /** The files and the index every action writes through. */
49
+ records: CommentRecords;
50
+ /** Which comment. */
51
+ id: string;
52
+ /** What to do to it. */
53
+ action: ModerationAction;
54
+ /** The checker, when the site named one, so a change of mind can be reported. */
55
+ checker?: CommentChecker | undefined;
56
+ /** The site's public origin, which a report names the post by. */
57
+ baseUrl: string;
58
+ /** Where a checker that will not take a correction is reported. */
59
+ logger?: {
60
+ warn(message: string): void;
61
+ } | undefined;
62
+ }
63
+ /**
64
+ * Approve a comment, file it as spam, or forget it.
65
+ *
66
+ * The file is rewritten first and the index inside the same step, exactly as
67
+ * the form on the public site does it: the file is the comment (decision-9),
68
+ * and moderation only ever moves it.
69
+ */
70
+ export declare function moderateComment(options: ModerateCommentOptions): Promise<ModerationOutcome>;
71
+ //# sourceMappingURL=moderate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moderate.d.ts","sourceRoot":"","sources":["../../src/comments/moderate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,iBAAiB,CAAC;AAErE;;;;;;;;;;;;;GAaG;AAEH,kEAAkE;AAClE,eAAO,MAAM,kBAAkB,YAAI,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAEzE,yCAAyC;AACzC,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnE,qCAAqC;AACrC,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,gBAAgB,CAE3E;AAED,qCAAqC;AACrC,MAAM,MAAM,iBAAiB;AAC3B,yEAAyE;AACvE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAC3B,2DAA2D;GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE;AAC/D,iDAAiD;GAC/C;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAAE;AAC3F,+DAA+D;GAC7D;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AAEhE,oDAAoD;AACpD,MAAM,WAAW,sBAAsB;IACrC,2DAA2D;IAC3D,OAAO,EAAE,cAAc,CAAC;IACxB,qBAAqB;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,wBAAwB;IACxB,MAAM,EAAE,gBAAgB,CAAC;IACzB,iFAAiF;IACjF,OAAO,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACrC,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,SAAS,CAAC;CACtD;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkBjG"}
@@ -0,0 +1,88 @@
1
+ import { deleteComment, updateComment } from './records.js';
2
+ /**
3
+ * The three things that can be done to a stored comment, in one place.
4
+ *
5
+ * There are two doors onto them — the moderation screen, and the one-click
6
+ * links a notification carries (TASK-55) — and they have to agree about
7
+ * everything: which file is rewritten, when the index moves, and when a spam
8
+ * checker is told a human disagreed with it. Two copies of that would drift,
9
+ * and the way they would drift is that the email links would quietly stop
10
+ * training Akismet.
11
+ *
12
+ * So this is the whole of moderation, and both doors are a thin skin over it:
13
+ * one turns the outcome into a flash and a redirect, the other into a page a
14
+ * mail reader can show.
15
+ */
16
+ /** What a button, or a link in a message, can do to a comment. */
17
+ export const MODERATION_ACTIONS = ['approve', 'spam', 'delete'];
18
+ /** Whether a name is one of them. */
19
+ export function isModerationAction(value) {
20
+ return MODERATION_ACTIONS.includes(value);
21
+ }
22
+ /**
23
+ * Approve a comment, file it as spam, or forget it.
24
+ *
25
+ * The file is rewritten first and the index inside the same step, exactly as
26
+ * the form on the public site does it: the file is the comment (decision-9),
27
+ * and moderation only ever moves it.
28
+ */
29
+ export async function moderateComment(options) {
30
+ const { records, id, action } = options;
31
+ const held = records.admin.getComment(id);
32
+ if (held === undefined)
33
+ return { kind: 'gone' };
34
+ if (action === 'delete') {
35
+ await deleteComment(records, id);
36
+ return { kind: 'deleted', comment: held };
37
+ }
38
+ const status = action === 'approve' ? 'approved' : 'spam';
39
+ if (held.status === status)
40
+ return { kind: 'unchanged', comment: held };
41
+ const moved = await updateComment(records, id, { status });
42
+ if (moved === undefined)
43
+ return { kind: 'gone' };
44
+ await tellChecker(options, moved, held.status);
45
+ return { kind: 'moved', comment: moved, before: held.status };
46
+ }
47
+ /**
48
+ * Tell the checker, when there is one, that a human disagreed with it.
49
+ *
50
+ * Only a real change of mind is reported. Approving something that was merely
51
+ * waiting says nothing a checker did not already assume, and a service charged
52
+ * per call should not be told it twice.
53
+ */
54
+ async function tellChecker(options, comment, before) {
55
+ const checker = options.checker;
56
+ if (checker === undefined)
57
+ return;
58
+ const report = {
59
+ comment,
60
+ url: absolute(comment.permalink, options.baseUrl),
61
+ baseUrl: options.baseUrl,
62
+ };
63
+ try {
64
+ if (comment.status === 'spam')
65
+ await checker.reportSpam?.(report);
66
+ else if (before === 'spam')
67
+ await checker.reportHam?.(report);
68
+ }
69
+ catch (error) {
70
+ // The comment has already moved; a checker that cannot be told is a worse
71
+ // spam filter tomorrow, not a failed moderation action today.
72
+ const logger = options.logger ?? console;
73
+ logger.warn(`The comment checker would not take the correction: ${messageOf(error)}`);
74
+ }
75
+ }
76
+ /** A site-root path as an absolute URL. */
77
+ function absolute(pathname, baseUrl) {
78
+ try {
79
+ return new URL(pathname, baseUrl).href;
80
+ }
81
+ catch {
82
+ return pathname;
83
+ }
84
+ }
85
+ function messageOf(error) {
86
+ return error instanceof Error ? error.message : String(error);
87
+ }
88
+ //# sourceMappingURL=moderate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moderate.js","sourceRoot":"","sources":["../../src/comments/moderate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI5D;;;;;;;;;;;;;GAaG;AAEH,kEAAkE;AAClE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAKzE,qCAAqC;AACrC,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAQ,kBAAwC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACnE,CAAC;AA6BD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAA+B;IACnE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC1C,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAEhD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,MAAM,GAAkB,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;IACzE,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAExE,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3D,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAEjD,MAAM,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAChE,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,WAAW,CACxB,OAA+B,EAC/B,OAAoB,EACpB,MAAqB;IAErB,MAAM,OAAO,GAA+B,OAAO,CAAC,OAAO,CAAC;IAC5D,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO;IAElC,MAAM,MAAM,GAAkB;QAC5B,OAAO;QACP,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC;QACjD,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;IAEF,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;YAAE,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC;aAC7D,IAAI,MAAM,KAAK,MAAM;YAAE,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0EAA0E;QAC1E,8DAA8D;QAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,sDAAsD,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACxF,CAAC;AACH,CAAC;AAED,2CAA2C;AAC3C,SAAS,QAAQ,CAAC,QAAgB,EAAE,OAAe;IACjD,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,57 @@
1
+ import type { Document } from '../content/document.ts';
2
+ /**
3
+ * When a post is taking comments, and when it has stopped.
4
+ *
5
+ * WordPress spells this as three things that argue with each other — a site
6
+ * switch, an age, and a per-post override — and so does this. They are read in
7
+ * one place so the form under a post and the endpoint that refuses a
8
+ * submission can never disagree about whether a post is open, which is the
9
+ * only way a comment form can lie to somebody who has just typed a paragraph.
10
+ */
11
+ /** The front-matter key a post opens or closes its own comments with. */
12
+ export declare const COMMENTS_FRONT_MATTER_KEY = "comments";
13
+ /**
14
+ * How long a post takes comments for, in days, before this is decided
15
+ * otherwise. WordPress's own default, and the age at which a post stops being
16
+ * a conversation and starts being a spam target.
17
+ */
18
+ export declare const DEFAULT_COMMENTS_CLOSE_AFTER_DAYS = 14;
19
+ /** The site's half of the decision: the two settings that apply to every post. */
20
+ export interface CommentPolicy {
21
+ /** Whether the site takes comments at all. Off means off everywhere. */
22
+ enabled: boolean;
23
+ /** Days after a post's `date` that it stops taking them. Zero never closes. */
24
+ closeAfterDays: number;
25
+ }
26
+ /**
27
+ * Whether this document is taking native comments right now.
28
+ *
29
+ * The order is what the rules mean rather than what is cheapest to check:
30
+ *
31
+ * - The site switch is absolute. A site that has turned comments off has
32
+ * turned them off, and no post reopens itself past it.
33
+ * - A draft or a trashed document takes none either. Nobody can read it to
34
+ * comment on, so a form would only be a way of writing to a post that does
35
+ * not exist yet.
36
+ * - `comments: true` or `comments: false` in the front matter is the post's
37
+ * own answer and beats everything below it, in both directions.
38
+ * - A page is closed. A page is standing content — an about page, a colophon —
39
+ * and WordPress defaults them closed for the same reason.
40
+ * - Otherwise a post is open until it is `closeAfterDays` old, counted from
41
+ * its `date`. A post with no date has no age and stays open.
42
+ *
43
+ * None of this touches the fediverse. A reply, a like or a boost arrives
44
+ * because a remote server sent it, which nothing here can stop and nothing
45
+ * here should hide: a closed post still shows every one of them.
46
+ */
47
+ export declare function commentsOpen(document: Document, policy: CommentPolicy, now?: Date): boolean;
48
+ /**
49
+ * The site's comment policy, as `content/_data/site.json` says it.
50
+ *
51
+ * Read off the site data rather than the typed settings so the public site can
52
+ * ask without reaching into the admin: the two keys are ordinary keys of that
53
+ * file, and a site that has never saved its settings gets the defaults —
54
+ * comments on, closing after a fortnight.
55
+ */
56
+ export declare function commentPolicyOf(site: Record<string, unknown>): CommentPolicy;
57
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/comments/policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD;;;;;;;;GAQG;AAEH,yEAAyE;AACzE,eAAO,MAAM,yBAAyB,aAAa,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,KAAK,CAAC;AAEpD,kFAAkF;AAClF,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,OAAO,EAAE,OAAO,CAAC;IACjB,+EAA+E;IAC/E,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,aAAa,EACrB,GAAG,GAAE,IAAiB,GACrB,OAAO,CAiBT;AAKD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa,CAU5E"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * When a post is taking comments, and when it has stopped.
3
+ *
4
+ * WordPress spells this as three things that argue with each other — a site
5
+ * switch, an age, and a per-post override — and so does this. They are read in
6
+ * one place so the form under a post and the endpoint that refuses a
7
+ * submission can never disagree about whether a post is open, which is the
8
+ * only way a comment form can lie to somebody who has just typed a paragraph.
9
+ */
10
+ /** The front-matter key a post opens or closes its own comments with. */
11
+ export const COMMENTS_FRONT_MATTER_KEY = 'comments';
12
+ /**
13
+ * How long a post takes comments for, in days, before this is decided
14
+ * otherwise. WordPress's own default, and the age at which a post stops being
15
+ * a conversation and starts being a spam target.
16
+ */
17
+ export const DEFAULT_COMMENTS_CLOSE_AFTER_DAYS = 14;
18
+ /**
19
+ * Whether this document is taking native comments right now.
20
+ *
21
+ * The order is what the rules mean rather than what is cheapest to check:
22
+ *
23
+ * - The site switch is absolute. A site that has turned comments off has
24
+ * turned them off, and no post reopens itself past it.
25
+ * - A draft or a trashed document takes none either. Nobody can read it to
26
+ * comment on, so a form would only be a way of writing to a post that does
27
+ * not exist yet.
28
+ * - `comments: true` or `comments: false` in the front matter is the post's
29
+ * own answer and beats everything below it, in both directions.
30
+ * - A page is closed. A page is standing content — an about page, a colophon —
31
+ * and WordPress defaults them closed for the same reason.
32
+ * - Otherwise a post is open until it is `closeAfterDays` old, counted from
33
+ * its `date`. A post with no date has no age and stays open.
34
+ *
35
+ * None of this touches the fediverse. A reply, a like or a boost arrives
36
+ * because a remote server sent it, which nothing here can stop and nothing
37
+ * here should hide: a closed post still shows every one of them.
38
+ */
39
+ export function commentsOpen(document, policy, now = new Date()) {
40
+ if (!policy.enabled)
41
+ return false;
42
+ if (document.draft)
43
+ return false;
44
+ const own = document.extra[COMMENTS_FRONT_MATTER_KEY];
45
+ if (own === false)
46
+ return false;
47
+ if (own === true)
48
+ return true;
49
+ if (document.type !== 'post')
50
+ return false;
51
+ if (policy.closeAfterDays <= 0)
52
+ return true;
53
+ if (document.date === undefined)
54
+ return true;
55
+ const published = new Date(document.date);
56
+ if (Number.isNaN(published.getTime()))
57
+ return true;
58
+ const closesAt = published.getTime() + policy.closeAfterDays * DAY_MS;
59
+ return now.getTime() < closesAt;
60
+ }
61
+ /** A day, in milliseconds. */
62
+ const DAY_MS = 24 * 60 * 60 * 1000;
63
+ /**
64
+ * The site's comment policy, as `content/_data/site.json` says it.
65
+ *
66
+ * Read off the site data rather than the typed settings so the public site can
67
+ * ask without reaching into the admin: the two keys are ordinary keys of that
68
+ * file, and a site that has never saved its settings gets the defaults —
69
+ * comments on, closing after a fortnight.
70
+ */
71
+ export function commentPolicyOf(site) {
72
+ const closeAfterDays = Number(site['commentsCloseAfterDays']);
73
+ return {
74
+ enabled: site['comments'] !== false,
75
+ closeAfterDays: Number.isInteger(closeAfterDays) && closeAfterDays >= 0
76
+ ? closeAfterDays
77
+ : DEFAULT_COMMENTS_CLOSE_AFTER_DAYS,
78
+ };
79
+ }
80
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/comments/policy.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,yBAAyB,GAAG,UAAU,CAAC;AAEpD;;;;GAIG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,EAAE,CAAC;AAUpD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAkB,EAClB,MAAqB,EACrB,GAAG,GAAS,IAAI,IAAI,EAAE;IAEtB,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAClC,IAAI,QAAQ,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEjC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACtD,IAAI,GAAG,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAE9B,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,MAAM,CAAC,cAAc,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAE7C,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC;IACtE,OAAO,GAAG,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC;AAClC,CAAC;AAED,8BAA8B;AAC9B,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnC;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,IAA6B;IAC3D,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAE9D,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,KAAK;QACnC,cAAc,EACZ,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,cAAc,IAAI,CAAC;YACrD,CAAC,CAAC,cAAc;YAChB,CAAC,CAAC,iCAAiC;KACxC,CAAC;AACJ,CAAC"}