@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,54 @@
1
+ /**
2
+ * Email: how the site sends mail, and where a message written to it goes.
3
+ *
4
+ * The settings are here and the credentials are not: an API key and an SMTP
5
+ * password live in `data/mail.json` at mode 0600, never in the public
6
+ * `site.json`, and they are their own pair of forms so a credential typed wrong
7
+ * cannot lose an edit to the From line beside it.
8
+ */
9
+ import type { SettingsPage } from './settings-page.ts';
10
+ import type { SiteSettings } from './settings.ts';
11
+ /**
12
+ * Where the mail credential's form and its Remove button post.
13
+ *
14
+ * Its own endpoint for the reason the Akismet key has one: an API key and an
15
+ * SMTP password are credentials, they live in `data/mail.json` rather than in
16
+ * `content/_data/site.json`, and a credential typed wrong must not lose an edit
17
+ * to the From line. Which provider is in use and who mail is from are settings
18
+ * and stay on the Email form.
19
+ */
20
+ export declare const MAIL_PATH = "/admin/settings/mail";
21
+ /** The fields the credential form and its Remove button submit. */
22
+ export declare const MAIL_FIELDS: {
23
+ readonly brevoApiKey: 'brevo_api_key';
24
+ readonly smtpHost: 'smtp_host';
25
+ readonly smtpPort: 'smtp_port';
26
+ readonly smtpSecure: 'smtp_secure';
27
+ readonly smtpUser: 'smtp_user';
28
+ readonly smtpPassword: 'smtp_password';
29
+ readonly action: 'action';
30
+ };
31
+ /** The {@link MAIL_FIELDS.action} that forgets every mail credential. */
32
+ export declare const MAIL_REMOVE = "remove";
33
+ /** Where the Send test email button posts. */
34
+ export declare const MAIL_TEST_PATH = "/admin/settings/mail/test";
35
+ /** The field that form submits: where to send the test message. */
36
+ export declare const MAIL_TEST_FIELDS: {
37
+ readonly to: 'to';
38
+ };
39
+ /** The message the Send test email button sends, as the theme names it. */
40
+ export declare const MAIL_TEST_TEMPLATE = "test";
41
+ /** The Email settings page. */
42
+ export declare const EMAIL_SETTINGS: SettingsPage;
43
+ /**
44
+ * What the page says about email: which provider is chosen, whether the
45
+ * credential it needs is there, and enough of it to recognise which one.
46
+ *
47
+ * Nothing here ever prints a key or a password. A settings screen that echoed
48
+ * one would put a credential in every browser cache, every screenshot and every
49
+ * `view-source`; the last four characters of an API key and the host and user
50
+ * of an SMTP connection are enough for somebody to tell what is stored without
51
+ * being handed the means to use it.
52
+ */
53
+ export declare function mailPanel(dataDir: string, settings: SiteSettings): Record<string, unknown>;
54
+ //# sourceMappingURL=settings-email.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-email.d.ts","sourceRoot":"","sources":["../../src/admin/settings-email.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAcH,OAAO,KAAK,EAAwB,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,yBAA0B,CAAC;AAEjD,mEAAmE;AACnE,eAAO,MAAM,WAAW;aACtB,WAAW,EAAE,eAAe;aAC5B,QAAQ,EAAE,WAAW;aACrB,QAAQ,EAAE,WAAW;aACrB,UAAU,EAAE,aAAa;aACzB,QAAQ,EAAE,WAAW;aACrB,YAAY,EAAE,eAAe;aAC7B,MAAM,EAAE,QAAQ;CACR,CAAC;AAEX,yEAAyE;AACzE,eAAO,MAAM,WAAW,WAAW,CAAC;AAEpC,8CAA8C;AAC9C,eAAO,MAAM,cAAc,8BAA+B,CAAC;AAE3D,mEAAmE;AACnE,eAAO,MAAM,gBAAgB;aAAK,EAAE,EAAE,IAAI;CAAW,CAAC;AAEtD,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,SAAS,CAAC;AAEzC,+BAA+B;AAC/B,eAAO,MAAM,cAAc,EAAE,YAU5B,CAAC;AA+GF;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA2C1F"}
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Email: how the site sends mail, and where a message written to it goes.
3
+ *
4
+ * The settings are here and the credentials are not: an API key and an SMTP
5
+ * password live in `data/mail.json` at mode 0600, never in the public
6
+ * `site.json`, and they are their own pair of forms so a credential typed wrong
7
+ * cannot lose an edit to the From line beside it.
8
+ */
9
+ import { readMailCredentials, removeMailCredentials, writeMailCredentials, } from '../mail/credentials.js';
10
+ import { MAIL_PROVIDERS } from '../mail/provider.js';
11
+ import { flash } from './flash.js';
12
+ import { bodyField, settingsPagePath } from './settings-page.js';
13
+ import { EMAIL_PATTERN, readSiteSettings, SETTINGS_PATH } from './settings.js';
14
+ import { ADMIN_TEMPLATES } from './templates.js';
15
+ /**
16
+ * Where the mail credential's form and its Remove button post.
17
+ *
18
+ * Its own endpoint for the reason the Akismet key has one: an API key and an
19
+ * SMTP password are credentials, they live in `data/mail.json` rather than in
20
+ * `content/_data/site.json`, and a credential typed wrong must not lose an edit
21
+ * to the From line. Which provider is in use and who mail is from are settings
22
+ * and stay on the Email form.
23
+ */
24
+ export const MAIL_PATH = `${SETTINGS_PATH}/mail`;
25
+ /** The fields the credential form and its Remove button submit. */
26
+ export const MAIL_FIELDS = {
27
+ brevoApiKey: 'brevo_api_key',
28
+ smtpHost: 'smtp_host',
29
+ smtpPort: 'smtp_port',
30
+ smtpSecure: 'smtp_secure',
31
+ smtpUser: 'smtp_user',
32
+ smtpPassword: 'smtp_password',
33
+ action: 'action',
34
+ };
35
+ /** The {@link MAIL_FIELDS.action} that forgets every mail credential. */
36
+ export const MAIL_REMOVE = 'remove';
37
+ /** Where the Send test email button posts. */
38
+ export const MAIL_TEST_PATH = `${SETTINGS_PATH}/mail/test`;
39
+ /** The field that form submits: where to send the test message. */
40
+ export const MAIL_TEST_FIELDS = { to: 'to' };
41
+ /** The message the Send test email button sends, as the theme names it. */
42
+ export const MAIL_TEST_TEMPLATE = 'test';
43
+ /** The Email settings page. */
44
+ export const EMAIL_SETTINGS = {
45
+ child: 'email',
46
+ label: 'Email',
47
+ path: settingsPagePath('email'),
48
+ template: ADMIN_TEMPLATES.settingsEmail,
49
+ fields: ['mailProvider', 'mailFromName', 'mailFromAddress', 'mailReplyTo', 'contactEmail'],
50
+ panels: (c, settings) => mailPanel(c.var.config.dataDir, settings),
51
+ endpoints: mountMail,
52
+ };
53
+ /** The mail credential's endpoints: save it, forget it, and prove it works. */
54
+ function mountMail(app, _options) {
55
+ const here = EMAIL_SETTINGS.path;
56
+ /**
57
+ * The mail credential: one form saves it, a second forgets it.
58
+ *
59
+ * It keeps both providers' credentials at once, so a site trying SMTP after
60
+ * Brevo can switch the provider back without pasting the key in again.
61
+ *
62
+ * A blank secret keeps the stored one. The form cannot render a password back
63
+ * into a page, so a blank field has to mean "unchanged" or nobody could ever
64
+ * edit the SMTP port without retyping the password.
65
+ */
66
+ app.post(MAIL_PATH, async (c) => {
67
+ const body = await c.req.parseBody();
68
+ const { config } = c.var;
69
+ const stored = readMailCredentials(config.dataDir);
70
+ if (bodyField(body[MAIL_FIELDS.action]) === MAIL_REMOVE) {
71
+ await removeMailCredentials(config.dataDir);
72
+ flash(c, 'notice', 'The mail credentials are gone. No email is sent any more.');
73
+ return c.redirect(here, 303);
74
+ }
75
+ const apiKey = bodyField(body[MAIL_FIELDS.brevoApiKey]).trim();
76
+ const host = bodyField(body[MAIL_FIELDS.smtpHost]).trim();
77
+ const port = Number(bodyField(body[MAIL_FIELDS.smtpPort]).trim());
78
+ const password = bodyField(body[MAIL_FIELDS.smtpPassword]);
79
+ if (host !== '' && (!Number.isInteger(port) || port < 1 || port > 65535)) {
80
+ flash(c, 'error', 'An SMTP port is a whole number between 1 and 65535. Nothing was saved.');
81
+ return c.redirect(here, 303);
82
+ }
83
+ const credentials = {
84
+ ...(apiKey === ''
85
+ ? stored.brevo === undefined
86
+ ? {}
87
+ : { brevo: stored.brevo }
88
+ : { brevo: { apiKey } }),
89
+ ...(host === ''
90
+ ? stored.smtp === undefined
91
+ ? {}
92
+ : { smtp: stored.smtp }
93
+ : {
94
+ smtp: {
95
+ host,
96
+ port,
97
+ secure: bodyField(body[MAIL_FIELDS.smtpSecure]) !== '',
98
+ user: bodyField(body[MAIL_FIELDS.smtpUser]).trim(),
99
+ // A blank password keeps the stored one, so the port and the user
100
+ // can be edited without retyping a secret the form was never
101
+ // allowed to show.
102
+ password: password === '' ? (stored.smtp?.password ?? '') : password,
103
+ },
104
+ }),
105
+ };
106
+ await writeMailCredentials(config.dataDir, credentials);
107
+ const settings = readSiteSettings(config.contentDir);
108
+ flash(c, 'notice', settings.mailProvider === 'none'
109
+ ? 'Saved. Choose a provider above and save the settings to start sending.'
110
+ : 'Saved. Send a test message to prove it reaches you.');
111
+ return c.redirect(here, 303);
112
+ });
113
+ /**
114
+ * Send test email: the one button that proves the whole chain.
115
+ *
116
+ * It goes through the same mail service every feature will, so what it proves
117
+ * is not "these credentials parse" but "a message from this site arrives" —
118
+ * the template, the From line, the provider and the retry included. Whatever
119
+ * the provider said comes back on the flash, its own words and all, because a
120
+ * refusal names the field to fix and a summary of one never does.
121
+ */
122
+ app.post(MAIL_TEST_PATH, async (c) => {
123
+ const body = await c.req.parseBody();
124
+ const to = bodyField(body[MAIL_TEST_FIELDS.to]).trim();
125
+ if (!EMAIL_PATTERN.test(to)) {
126
+ flash(c, 'error', 'Type the address to send the test message to.');
127
+ return c.redirect(here, 303);
128
+ }
129
+ const result = await c.var.mail.send({ to, template: MAIL_TEST_TEMPLATE });
130
+ flash(c, result.ok && !result.skipped ? 'notice' : 'error', result.skipped
131
+ ? 'No mail is configured, so nothing was sent. Choose a provider and save a credential first.'
132
+ : result.ok
133
+ ? `A test message was sent to ${to} via ${result.provider}${result.messageId === undefined ? '' : ` (${result.messageId})`}. If it does not arrive, look in the spam folder and at the provider's own log.`
134
+ : `${result.provider} would not send to ${to} after ${String(result.attempts)} ${result.attempts === 1 ? 'attempt' : 'attempts'}: ${result.error ?? 'no reason given'}`);
135
+ return c.redirect(here, 303);
136
+ });
137
+ }
138
+ /**
139
+ * What the page says about email: which provider is chosen, whether the
140
+ * credential it needs is there, and enough of it to recognise which one.
141
+ *
142
+ * Nothing here ever prints a key or a password. A settings screen that echoed
143
+ * one would put a credential in every browser cache, every screenshot and every
144
+ * `view-source`; the last four characters of an API key and the host and user
145
+ * of an SMTP connection are enough for somebody to tell what is stored without
146
+ * being handed the means to use it.
147
+ */
148
+ export function mailPanel(dataDir, settings) {
149
+ const stored = readMailCredentials(dataDir);
150
+ const present = settings.mailProvider === 'brevo' ? stored.brevo !== undefined : stored.smtp !== undefined;
151
+ return {
152
+ mailUrl: MAIL_PATH,
153
+ mailFields: MAIL_FIELDS,
154
+ mailRemove: MAIL_REMOVE,
155
+ mailTestUrl: MAIL_TEST_PATH,
156
+ mailTestFields: MAIL_TEST_FIELDS,
157
+ mailProviders: MAIL_PROVIDERS,
158
+ mailProvider: settings.mailProvider,
159
+ // Whether the chosen provider has what it needs. A key stored for the
160
+ // provider that is not chosen is not "configured": nothing would use it.
161
+ mailConfigured: settings.mailProvider !== 'none' && present,
162
+ mailBrevoPresent: stored.brevo !== undefined,
163
+ mailSmtpPresent: stored.smtp !== undefined,
164
+ ...(stored.brevo === undefined
165
+ ? {}
166
+ : { mailBrevoKeyHint: `…${stored.brevo.apiKey.slice(-4)}` }),
167
+ ...(stored.smtp === undefined
168
+ ? {}
169
+ : {
170
+ mailSmtp: {
171
+ host: stored.smtp.host,
172
+ port: stored.smtp.port,
173
+ secure: stored.smtp.secure,
174
+ user: stored.smtp.user,
175
+ // Not the password. Whether there is one at all is all the screen
176
+ // needs to say.
177
+ hasPassword: stored.smtp.password !== '',
178
+ },
179
+ }),
180
+ mailHint: settings.mailProvider === 'none'
181
+ ? 'This site sends no email. Password resets, moderation notices and contact messages are still recorded; they are simply not sent.'
182
+ : present
183
+ ? 'Mail is configured. Send a test message to prove it reaches you.'
184
+ : settings.mailProvider === 'brevo'
185
+ ? 'Brevo is chosen but there is no API key, so nothing is sent.'
186
+ : 'SMTP is chosen but there is no server, so nothing is sent.',
187
+ };
188
+ }
189
+ //# sourceMappingURL=settings-email.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-email.js","sourceRoot":"","sources":["../../src/admin/settings-email.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Federation: which relays the site subscribes to.
3
+ *
4
+ * There is nothing else on this page any more. decision-14 replaced the site
5
+ * actor with one actor per user, so the handle, the type and the picture a
6
+ * site used to federate under are a user's profile, edited on the users
7
+ * screen; what is left here is the one setting that is an instruction as well
8
+ * as a value — a line added is a `Follow` to send and a line removed is an
9
+ * `Undo` — so a save of this page reconciles them.
10
+ */
11
+ import type { WordPressRequests } from '../federation/wordpress.ts';
12
+ import type { User } from './accounts.ts';
13
+ import type { SettingsPage } from './settings-page.ts';
14
+ /** The Federation settings page. */
15
+ export declare const FEDERATION_SETTINGS: SettingsPage;
16
+ /** One compatibility path, as the panel beside the switch shows it. */
17
+ export interface WordPressRouteRow {
18
+ /** The path itself, which is what a peer still holds. */
19
+ readonly path: string;
20
+ /** Whose it is, or the empty string for the instance-wide inbox. */
21
+ readonly username: string;
22
+ /** When it was last asked for, or `null` for never. */
23
+ readonly lastRequestedAt: string | null;
24
+ }
25
+ /**
26
+ * Every path the compatibility switch answers, and when each was last asked
27
+ * for.
28
+ *
29
+ * The whole point of the panel: the switch can come off once no follower's
30
+ * server is delivering to the old URLs any more, and that is a question only
31
+ * the record of what was asked for can answer. So a route nobody has ever
32
+ * asked for is listed too, saying never — an empty table would read as "no
33
+ * such path" rather than as "nobody is using it".
34
+ *
35
+ * A user with no WordPress number is not here at all: the plugin never
36
+ * published a path for them, so there is nothing for a peer to be holding.
37
+ */
38
+ export declare function wordPressRoutes(users: readonly User[], requests: WordPressRequests): WordPressRouteRow[];
39
+ //# sourceMappingURL=settings-federation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-federation.d.ts","sourceRoot":"","sources":["../../src/admin/settings-federation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,OAAO,KAAK,EAAE,iBAAiB,EAAkB,MAAM,4BAA4B,CAAC;AAEpF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,oCAAoC;AACpC,eAAO,MAAM,mBAAmB,EAAE,YAmBjC,CAAC;AAwCF,uEAAuE;AACvE,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,uDAAuD;IACvD,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,QAAQ,EAAE,iBAAiB,GAC1B,iBAAiB,EAAE,CA6BrB"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Federation: which relays the site subscribes to.
3
+ *
4
+ * There is nothing else on this page any more. decision-14 replaced the site
5
+ * actor with one actor per user, so the handle, the type and the picture a
6
+ * site used to federate under are a user's profile, edited on the users
7
+ * screen; what is left here is the one setting that is an instruction as well
8
+ * as a value — a line added is a `Follow` to send and a line removed is an
9
+ * `Undo` — so a save of this page reconciles them.
10
+ */
11
+ import { readWordPressRequests, WORDPRESS_ACTIVITYPUB_BASE, WORDPRESS_SHARED_INBOX_PATH, } from '../federation/wordpress.js';
12
+ import { listUsers } from './accounts.js';
13
+ import { settingsPagePath } from './settings-page.js';
14
+ import { ADMIN_TEMPLATES } from './templates.js';
15
+ /** The Federation settings page. */
16
+ export const FEDERATION_SETTINGS = {
17
+ child: 'federation',
18
+ label: 'Federation',
19
+ path: settingsPagePath('federation'),
20
+ template: ADMIN_TEMPLATES.settingsFederation,
21
+ fields: ['relays', 'wordpressActivityPub'],
22
+ panels: (c) => ({
23
+ wordpressRoutes: wordPressRoutes(listUsers(c.var.config.dataDir), readWordPressRequests(c.var.config.dataDir)),
24
+ }),
25
+ saved: (c) => {
26
+ // The reconciliation reads the settings that were just written, so it has
27
+ // to come after the save rather than be derived from the form.
28
+ return toldRelays(c.var.relays.sync());
29
+ },
30
+ };
31
+ /**
32
+ * The sentence a flash adds about the relays a save subscribed to or left.
33
+ *
34
+ * A relay does not answer at once — FEP-ae0c allows a human to approve the
35
+ * subscription days later — so the message says a follow was sent rather than
36
+ * that the site is now on the relay, and points at the screen that will say.
37
+ */
38
+ function toldRelays(report) {
39
+ const parts = [];
40
+ if (report.followed.length > 0) {
41
+ parts.push(report.followed.length === 1
42
+ ? 'A follow has been sent to one new relay'
43
+ : `Follows have been sent to ${String(report.followed.length)} new relays`);
44
+ }
45
+ if (report.unfollowed.length > 0) {
46
+ parts.push(report.unfollowed.length === 1
47
+ ? 'one relay has been unfollowed'
48
+ : `${String(report.unfollowed.length)} relays have been unfollowed`);
49
+ }
50
+ if (parts.length === 0)
51
+ return '';
52
+ const sentence = parts.join(', and ');
53
+ return ` ${sentence.charAt(0).toUpperCase()}${sentence.slice(1)}; the Federation screen says where each stands.`;
54
+ }
55
+ /** The order the paths are listed in, which is the order the plugin's actor names them. */
56
+ const WORDPRESS_ROUTE_ORDER = [
57
+ 'actor',
58
+ 'inbox',
59
+ 'outbox',
60
+ 'followers',
61
+ 'following',
62
+ ];
63
+ /**
64
+ * Every path the compatibility switch answers, and when each was last asked
65
+ * for.
66
+ *
67
+ * The whole point of the panel: the switch can come off once no follower's
68
+ * server is delivering to the old URLs any more, and that is a question only
69
+ * the record of what was asked for can answer. So a route nobody has ever
70
+ * asked for is listed too, saying never — an empty table would read as "no
71
+ * such path" rather than as "nobody is using it".
72
+ *
73
+ * A user with no WordPress number is not here at all: the plugin never
74
+ * published a path for them, so there is nothing for a peer to be holding.
75
+ */
76
+ export function wordPressRoutes(users, requests) {
77
+ const rows = [];
78
+ for (const user of users) {
79
+ if (user.wordpressActorId === undefined)
80
+ continue;
81
+ const asked = requests.users[user.username] ?? {};
82
+ const actor = `${WORDPRESS_ACTIVITYPUB_BASE}/actors/${String(user.wordpressActorId)}`;
83
+ for (const route of WORDPRESS_ROUTE_ORDER) {
84
+ rows.push({
85
+ path: route === 'actor' ? actor : `${actor}/${route}`,
86
+ username: user.username,
87
+ lastRequestedAt: asked[route] ?? null,
88
+ });
89
+ }
90
+ }
91
+ // The shared inbox last, and only when somebody could be delivered through
92
+ // it: it belongs to the site rather than to a person, and a site with nobody
93
+ // to deliver to has no use for it.
94
+ if (rows.length > 0) {
95
+ rows.push({
96
+ path: WORDPRESS_SHARED_INBOX_PATH,
97
+ username: '',
98
+ lastRequestedAt: requests.sharedInbox ?? null,
99
+ });
100
+ }
101
+ return rows;
102
+ }
103
+ //# sourceMappingURL=settings-federation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-federation.js","sourceRoot":"","sources":["../../src/admin/settings-federation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,oCAAoC;AACpC,MAAM,CAAC,MAAM,mBAAmB,GAAiB;IAC/C,KAAK,EAAE,YAAY;IACnB,KAAK,EAAE,YAAY;IACnB,IAAI,EAAE,gBAAgB,CAAC,YAAY,CAAC;IACpC,QAAQ,EAAE,eAAe,CAAC,kBAAkB;IAC5C,MAAM,EAAE,CAAC,QAAQ,EAAE,sBAAsB,CAAC;IAE1C,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACd,eAAe,EAAE,eAAe,CAC9B,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAC/B,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAC5C;KACF,CAAC;IAEF,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;QACX,0EAA0E;QAC1E,+DAA+D;QAC/D,OAAO,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;CACF,CAAC;AAEF;;;;;;GAMG;AACH,SAAS,UAAU,CAAC,MAAuB;IACzC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CACR,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAC1B,CAAC,CAAC,yCAAyC;YAC3C,CAAC,CAAC,6BAA6B,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAC7E,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CACR,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;YAC5B,CAAC,CAAC,+BAA+B;YACjC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,8BAA8B,CACtE,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtC,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,iDAAiD,CAAC;AACnH,CAAC;AAED,2FAA2F;AAC3F,MAAM,qBAAqB,GAA8B;IACvD,OAAO;IACP,OAAO;IACP,QAAQ;IACR,WAAW;IACX,WAAW;CACZ,CAAC;AAYF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAsB,EACtB,QAA2B;IAE3B,MAAM,IAAI,GAAwB,EAAE,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS;YAAE,SAAS;QAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,GAAG,0BAA0B,WAAW,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAEtF,KAAK,MAAM,KAAK,IAAI,qBAAqB,EAAE,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC;gBACR,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,KAAK,EAAE;gBACrD,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,eAAe,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI;aACtC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,6EAA6E;IAC7E,mCAAmC;IACnC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC;YACR,IAAI,EAAE,2BAA2B;YACjC,QAAQ,EAAE,EAAE;YACZ,eAAe,EAAE,QAAQ,CAAC,WAAW,IAAI,IAAI;SAC9C,CAAC,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * General: what the site is called, where it lives, and what it looks like.
3
+ *
4
+ * WordPress's own first settings page, and the one the Settings heading lands
5
+ * on. There is no avatar here any more: decision-14 made every user an actor
6
+ * with a picture of their own, so the picture a site shows the fediverse is a
7
+ * user's, edited on the users screen beside the rest of their profile.
8
+ */
9
+ import type { SettingsPage } from './settings-page.ts';
10
+ /** The General settings page. */
11
+ export declare const GENERAL_SETTINGS: SettingsPage;
12
+ //# sourceMappingURL=settings-general.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-general.d.ts","sourceRoot":"","sources":["../../src/admin/settings-general.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKvD,iCAAiC;AACjC,eAAO,MAAM,gBAAgB,EAAE,YAwB9B,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * General: what the site is called, where it lives, and what it looks like.
3
+ *
4
+ * WordPress's own first settings page, and the one the Settings heading lands
5
+ * on. There is no avatar here any more: decision-14 made every user an actor
6
+ * with a picture of their own, so the picture a site shows the fediverse is a
7
+ * user's, edited on the users screen beside the rest of their profile.
8
+ */
9
+ import { bodyField, settingsPagePath } from './settings-page.js';
10
+ import { effectiveBaseUrl, SETTINGS_FIELDS } from './settings.js';
11
+ import { ADMIN_TEMPLATES } from './templates.js';
12
+ /** The General settings page. */
13
+ export const GENERAL_SETTINGS = {
14
+ child: 'general',
15
+ label: 'General',
16
+ path: settingsPagePath('general'),
17
+ template: ADMIN_TEMPLATES.settingsGeneral,
18
+ fields: ['title', 'tagline', 'author', 'baseUrl', 'timezone', 'language'],
19
+ // The base URL field shows the one in effect rather than the one the file
20
+ // happens to hold: a site.json with no `url` at all would otherwise render an
21
+ // empty field that the validator refuses the moment anything is saved.
22
+ shown: (config, settings) => ({ ...settings, baseUrl: effectiveBaseUrl(config, settings) }),
23
+ panels: (c, settings) => baseUrlPanel(c.var.config, settings),
24
+ // A field the form rendered read-only is not submitted, so an overridden base
25
+ // URL keeps the value it had rather than being cleared by a save.
26
+ reads: ({ c, body, current }) => ({
27
+ baseUrl: c.var.config.baseUrlSource === 'default'
28
+ ? bodyField(body[SETTINGS_FIELDS.baseUrl])
29
+ : current.baseUrl === ''
30
+ ? c.var.config.baseUrl
31
+ : current.baseUrl,
32
+ }),
33
+ };
34
+ /** What the page says about the base URL: the one in effect, and why it is. */
35
+ function baseUrlPanel(config, settings) {
36
+ const overridden = config.baseUrlSource !== 'default';
37
+ return {
38
+ baseUrlInEffect: effectiveBaseUrl(config, settings),
39
+ baseUrlOverridden: overridden,
40
+ baseUrlSource: config.baseUrlSource,
41
+ baseUrlNote: overridden
42
+ ? config.baseUrlSource === 'environment'
43
+ ? 'GEEKITY_BASE_URL is set, so it is the base URL in effect and this field is not editable here.'
44
+ : 'The config file sets baseUrl, so it is the base URL in effect and this field is not editable here.'
45
+ : 'Absolute URLs, the feeds and the session cookie pick this up when the site next starts.',
46
+ };
47
+ }
48
+ //# sourceMappingURL=settings-general.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-general.js","sourceRoot":"","sources":["../../src/admin/settings-general.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAElE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,iCAAiC;AACjC,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC;IACjC,QAAQ,EAAE,eAAe,CAAC,eAAe;IACzC,MAAM,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,CAAC;IAEzE,0EAA0E;IAC1E,8EAA8E;IAC9E,uEAAuE;IACvE,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;IAE3F,MAAM,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC;IAE7D,8EAA8E;IAC9E,kEAAkE;IAClE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAChC,OAAO,EACL,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS;YACtC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC1C,CAAC,CAAC,OAAO,CAAC,OAAO,KAAK,EAAE;gBACtB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO;gBACtB,CAAC,CAAC,OAAO,CAAC,OAAO;KACxB,CAAC;CACH,CAAC;AAEF,+EAA+E;AAC/E,SAAS,YAAY,CACnB,MAAyD,EACzD,QAAsB;IAEtB,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC;IAEtD,OAAO;QACL,eAAe,EAAE,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC;QACnD,iBAAiB,EAAE,UAAU;QAC7B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,WAAW,EAAE,UAAU;YACrB,CAAC,CAAC,MAAM,CAAC,aAAa,KAAK,aAAa;gBACtC,CAAC,CAAC,+FAA+F;gBACjG,CAAC,CAAC,oGAAoG;YACxG,CAAC,CAAC,yFAAyF;KAC9F,CAAC;AACJ,CAAC"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * What every settings page is made of.
3
+ *
4
+ * The settings used to be one form with twelve headings. They are six pages
5
+ * now — General, Reading, Permalinks, Discussion, Email and Federation — and
6
+ * this is what they have in common: a description of the page, and the one
7
+ * pair of routes that turns it into a screen you can read and a form you can
8
+ * save. A page module describes itself and writes its own template; nothing
9
+ * about how a page is wired lives in the page.
10
+ *
11
+ * The save is the part worth reading twice. A page writes only the fields it
12
+ * carries, and it writes them onto `content/_data/site.json` as re-read inside
13
+ * the atomic update (decision-9), not onto the copy the form was rendered
14
+ * from. So two people saving two different pages at the same moment both land:
15
+ * the second save is applied to what the first one actually wrote, and a
16
+ * setting neither page shows is not even in the picture.
17
+ */
18
+ import type { Context, Hono } from 'hono';
19
+ import type { ResolvedConfig } from '../config.ts';
20
+ import type { GeekityEnv } from '../env.ts';
21
+ import type { DeliveryReport } from '../federation/delivery.ts';
22
+ import type { AdminRender } from './documents.ts';
23
+ import type { SettingsField, SettingsForm, SiteSettings } from './settings.ts';
24
+ /** What {@link mountSettingsPage} needs from the admin around it. */
25
+ export interface MountSettingsOptions {
26
+ /** The admin's renderer, which injects the chrome, the CSRF token and the flash. */
27
+ render: AdminRender;
28
+ }
29
+ /** A submitted form, before anything has been read out of it. */
30
+ export type SubmittedBody = Record<string, unknown>;
31
+ /** One page under Settings. */
32
+ export interface SettingsPage {
33
+ /** The child of the Settings section it is, as `src/admin/menu.ts` names it. */
34
+ child: string;
35
+ /** What the menu calls it, and what the page is headed. */
36
+ label: string;
37
+ /** Where it is: {@link settingsPagePath}. */
38
+ path: string;
39
+ /** The template it renders, from {@link ADMIN_TEMPLATES}. */
40
+ template: string;
41
+ /** The settings it carries. Every setting is on exactly one page. */
42
+ fields: readonly SettingsField[];
43
+ /**
44
+ * The settings as this page shows them, where what is stored is not what is
45
+ * in effect. Only General has one, for the base URL a deployment overrides.
46
+ */
47
+ shown?: (config: ResolvedConfig, settings: SiteSettings) => SiteSettings;
48
+ /** What the page renders beyond its own fields: a panel, a credential, a list. */
49
+ panels?: (c: Context<GeekityEnv>, settings: SiteSettings) => Record<string, unknown>;
50
+ /**
51
+ * The fields this page does not read straight off the body, because
52
+ * something other than the form decides them — a field rendered read-only
53
+ * submits nothing, and a save must not clear it.
54
+ */
55
+ reads?: (options: {
56
+ c: Context<GeekityEnv>;
57
+ body: SubmittedBody;
58
+ current: SiteSettings;
59
+ }) => Partial<SettingsForm>;
60
+ /**
61
+ * What a save of this page sets off beyond the file, as the sentence the
62
+ * flash adds. The side effect stays where the field is: the actor is told
63
+ * about a profile change on the page the profile is on, and the relays are
64
+ * reconciled on the page the relay list is on.
65
+ */
66
+ saved?: (c: Context<GeekityEnv>, before: SiteSettings, after: SiteSettings) => Promise<string> | string;
67
+ /**
68
+ * The page's own endpoints: a credential, a test message. Each is its own
69
+ * POST so a refused one cannot lose an edit to a field.
70
+ */
71
+ endpoints?: (app: Hono<GeekityEnv>, options: MountSettingsOptions) => void;
72
+ }
73
+ /**
74
+ * Where one settings page lives.
75
+ *
76
+ * General is `/admin/settings` itself rather than `/admin/settings/general`:
77
+ * it is where the Settings heading lands, where every save that has nothing
78
+ * better to say redirects, and the URL every older bookmark holds.
79
+ */
80
+ export declare function settingsPagePath(child: string): string;
81
+ /**
82
+ * Register one settings page: the screen, the save, and whatever endpoints of
83
+ * its own it has.
84
+ *
85
+ * Every read is of `content/_data/site.json` as it is at that moment, and a
86
+ * save rewrites it: a page is a view of the file rather than of anything this
87
+ * process remembers (decision-9). A form the page's own validator has anything
88
+ * to say about is a 400 that writes nothing at all and comes back with the
89
+ * problems on the fields that have them.
90
+ */
91
+ export declare function mountSettingsPage(app: Hono<GeekityEnv>, page: SettingsPage, options: MountSettingsOptions): void;
92
+ /** Everything one settings page's template renders. */
93
+ export declare function settingsScreen(c: Context<GeekityEnv>, page: SettingsPage, settings: SiteSettings): Record<string, unknown>;
94
+ /** A form field as a string. A file upload, or a missing field, is the empty one. */
95
+ export declare function bodyField(value: unknown): string;
96
+ /**
97
+ * The sentence a flash adds about the followers, when there were any: a save
98
+ * of the profile is also an announcement, and it should say so rather than
99
+ * leave the admin wondering.
100
+ */
101
+ export declare function toldFollowers(report: DeliveryReport | undefined): string;
102
+ //# sourceMappingURL=settings-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-page.d.ts","sourceRoot":"","sources":["../../src/admin/settings-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAWlD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE/E,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACnC,oFAAoF;IACpF,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,iEAAiE;AACjE,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD,+BAA+B;AAC/B,MAAM,WAAW,YAAY;IAC3B,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,KAAK,YAAY,CAAC;IACzE,kFAAkF;IAClF,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,YAAY,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrF;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE;QAChB,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QACvB,IAAI,EAAE,aAAa,CAAC;QACpB,OAAO,EAAE,YAAY,CAAC;KACvB,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,CACN,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EACtB,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,YAAY,KAChB,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAC9B;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC5E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,EACrB,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,oBAAoB,GAC5B,IAAI,CA4CN;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAC5B,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EACtB,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,YAAY,GACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB;AAsBD,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,GAAG,MAAM,CAMxE"}