@geekity/cms 0.29.0 → 0.31.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 (1393) hide show
  1. package/README.md +26 -4214
  2. package/admin/pages/settings/privacy.njk +1 -1
  3. package/dist/access-log.d.ts +2 -10
  4. package/dist/access-log.d.ts.map +1 -1
  5. package/dist/access-log.js +1 -1
  6. package/dist/access-log.js.map +1 -1
  7. package/dist/{web → admin}/admin-bar.d.ts +3 -2
  8. package/dist/admin/admin-bar.d.ts.map +1 -0
  9. package/dist/{web → admin}/admin-bar.js +20 -17
  10. package/dist/admin/admin-bar.js.map +1 -0
  11. package/dist/{indieauth → admin}/app-activity.d.ts +2 -2
  12. package/dist/admin/app-activity.d.ts.map +1 -0
  13. package/dist/{indieauth → admin}/app-activity.js +5 -5
  14. package/dist/admin/app-activity.js.map +1 -0
  15. package/dist/admin/appearance.d.ts +3 -3
  16. package/dist/admin/appearance.d.ts.map +1 -1
  17. package/dist/admin/appearance.js +12 -6
  18. package/dist/admin/appearance.js.map +1 -1
  19. package/dist/admin/assets.d.ts +1 -8
  20. package/dist/admin/assets.d.ts.map +1 -1
  21. package/dist/admin/assets.js +2 -9
  22. package/dist/admin/assets.js.map +1 -1
  23. package/dist/admin/comments.d.ts +2 -2
  24. package/dist/admin/comments.d.ts.map +1 -1
  25. package/dist/admin/comments.js +16 -17
  26. package/dist/admin/comments.js.map +1 -1
  27. package/dist/{indieauth → admin}/connected-apps.d.ts +2 -2
  28. package/dist/admin/connected-apps.d.ts.map +1 -0
  29. package/dist/{indieauth → admin}/connected-apps.js +18 -19
  30. package/dist/admin/connected-apps.js.map +1 -0
  31. package/dist/admin/credentials.js +1 -1
  32. package/dist/admin/credentials.js.map +1 -1
  33. package/dist/admin/dev-mode.d.ts +1 -1
  34. package/dist/admin/dev-mode.d.ts.map +1 -1
  35. package/dist/admin/documents.d.ts +16 -301
  36. package/dist/admin/documents.d.ts.map +1 -1
  37. package/dist/admin/documents.js +74 -1032
  38. package/dist/admin/documents.js.map +1 -1
  39. package/dist/admin/editor-actions.d.ts +3 -2
  40. package/dist/admin/editor-actions.d.ts.map +1 -1
  41. package/dist/admin/editor-actions.js +8 -8
  42. package/dist/admin/editor-actions.js.map +1 -1
  43. package/dist/admin/editor-fields.d.ts +45 -0
  44. package/dist/admin/editor-fields.d.ts.map +1 -0
  45. package/dist/admin/editor-fields.js +71 -0
  46. package/dist/admin/editor-fields.js.map +1 -0
  47. package/dist/admin/editor-layout.d.ts +2 -10
  48. package/dist/admin/editor-layout.d.ts.map +1 -1
  49. package/dist/admin/editor-layout.js +1 -1
  50. package/dist/admin/editor-layout.js.map +1 -1
  51. package/dist/admin/federation.d.ts +5 -5
  52. package/dist/admin/federation.d.ts.map +1 -1
  53. package/dist/admin/federation.js +16 -18
  54. package/dist/admin/federation.js.map +1 -1
  55. package/dist/admin/flash.d.ts +2 -2
  56. package/dist/admin/flash.d.ts.map +1 -1
  57. package/dist/admin/headers.d.ts +1 -1
  58. package/dist/admin/headers.d.ts.map +1 -1
  59. package/dist/admin/headers.js +1 -1
  60. package/dist/admin/headers.js.map +1 -1
  61. package/dist/admin/index.d.ts +38 -20
  62. package/dist/admin/index.d.ts.map +1 -1
  63. package/dist/admin/index.js +27 -13
  64. package/dist/admin/index.js.map +1 -1
  65. package/dist/{indieauth/consent.d.ts → admin/indieauth-consent.d.ts} +4 -4
  66. package/dist/admin/indieauth-consent.d.ts.map +1 -0
  67. package/dist/{indieauth/consent.js → admin/indieauth-consent.js} +17 -18
  68. package/dist/admin/indieauth-consent.js.map +1 -0
  69. package/dist/admin/legacy-migrations.d.ts +131 -0
  70. package/dist/admin/legacy-migrations.d.ts.map +1 -0
  71. package/dist/admin/legacy-migrations.js +235 -0
  72. package/dist/admin/legacy-migrations.js.map +1 -0
  73. package/dist/admin/media.d.ts +4 -108
  74. package/dist/admin/media.d.ts.map +1 -1
  75. package/dist/admin/media.js +19 -187
  76. package/dist/admin/media.js.map +1 -1
  77. package/dist/admin/menu.d.ts.map +1 -1
  78. package/dist/admin/menu.js +7 -7
  79. package/dist/admin/menu.js.map +1 -1
  80. package/dist/admin/messages.d.ts +1 -1
  81. package/dist/admin/messages.d.ts.map +1 -1
  82. package/dist/admin/messages.js +10 -12
  83. package/dist/admin/messages.js.map +1 -1
  84. package/dist/admin/navigation.d.ts +3 -3
  85. package/dist/admin/navigation.d.ts.map +1 -1
  86. package/dist/admin/navigation.js +9 -12
  87. package/dist/admin/navigation.js.map +1 -1
  88. package/dist/admin/personal-data.d.ts +1 -1
  89. package/dist/admin/personal-data.d.ts.map +1 -1
  90. package/dist/admin/personal-data.js +3 -6
  91. package/dist/admin/personal-data.js.map +1 -1
  92. package/dist/admin/plugins.d.ts +1 -1
  93. package/dist/admin/plugins.d.ts.map +1 -1
  94. package/dist/admin/plugins.js +11 -15
  95. package/dist/admin/plugins.js.map +1 -1
  96. package/dist/admin/preview.d.ts +2 -1
  97. package/dist/admin/preview.d.ts.map +1 -1
  98. package/dist/admin/preview.js +28 -32
  99. package/dist/admin/preview.js.map +1 -1
  100. package/dist/admin/recovery.d.ts +3 -3
  101. package/dist/admin/recovery.d.ts.map +1 -1
  102. package/dist/admin/recovery.js +10 -12
  103. package/dist/admin/recovery.js.map +1 -1
  104. package/dist/admin/routes.d.ts +1 -3
  105. package/dist/admin/routes.d.ts.map +1 -1
  106. package/dist/admin/routes.js +28 -26
  107. package/dist/admin/routes.js.map +1 -1
  108. package/dist/admin/settings-discussion.d.ts.map +1 -1
  109. package/dist/admin/settings-discussion.js +7 -4
  110. package/dist/admin/settings-discussion.js.map +1 -1
  111. package/dist/admin/settings-email.d.ts +1 -1
  112. package/dist/admin/settings-email.d.ts.map +1 -1
  113. package/dist/admin/settings-email.js +13 -10
  114. package/dist/admin/settings-email.js.map +1 -1
  115. package/dist/admin/settings-general.d.ts.map +1 -1
  116. package/dist/admin/settings-general.js +10 -7
  117. package/dist/admin/settings-general.js.map +1 -1
  118. package/dist/admin/settings-page.d.ts +3 -4
  119. package/dist/admin/settings-page.d.ts.map +1 -1
  120. package/dist/admin/settings-page.js +5 -6
  121. package/dist/admin/settings-page.js.map +1 -1
  122. package/dist/admin/settings-pages.d.ts +1 -1
  123. package/dist/admin/settings-pages.d.ts.map +1 -1
  124. package/dist/admin/settings-permalinks.js +1 -1
  125. package/dist/admin/settings-permalinks.js.map +1 -1
  126. package/dist/admin/settings-reading.d.ts +2 -2
  127. package/dist/admin/settings-reading.d.ts.map +1 -1
  128. package/dist/admin/settings-reading.js +4 -3
  129. package/dist/admin/settings-reading.js.map +1 -1
  130. package/dist/admin/settings.d.ts +0 -579
  131. package/dist/admin/settings.d.ts.map +1 -1
  132. package/dist/admin/settings.js +1 -1155
  133. package/dist/admin/settings.js.map +1 -1
  134. package/dist/admin/syndication-targets.d.ts +1 -1
  135. package/dist/admin/syndication-targets.d.ts.map +1 -1
  136. package/dist/admin/syndication-targets.js +11 -15
  137. package/dist/admin/syndication-targets.js.map +1 -1
  138. package/dist/admin/taxonomy.d.ts +2 -2
  139. package/dist/admin/taxonomy.d.ts.map +1 -1
  140. package/dist/admin/taxonomy.js +8 -11
  141. package/dist/admin/taxonomy.js.map +1 -1
  142. package/dist/admin/templates.js +1 -1
  143. package/dist/admin/templates.js.map +1 -1
  144. package/dist/admin/tools.d.ts +4 -4
  145. package/dist/admin/tools.d.ts.map +1 -1
  146. package/dist/admin/tools.js +3 -6
  147. package/dist/admin/tools.js.map +1 -1
  148. package/dist/admin/uploads.d.ts +1 -106
  149. package/dist/admin/uploads.d.ts.map +1 -1
  150. package/dist/admin/uploads.js +2 -191
  151. package/dist/admin/uploads.js.map +1 -1
  152. package/dist/admin/users.d.ts +20 -15
  153. package/dist/admin/users.d.ts.map +1 -1
  154. package/dist/admin/users.js +83 -80
  155. package/dist/admin/users.js.map +1 -1
  156. package/dist/avatars/avatars.d.ts +2 -2
  157. package/dist/avatars/avatars.d.ts.map +1 -1
  158. package/dist/avatars/avatars.js +6 -9
  159. package/dist/avatars/avatars.js.map +1 -1
  160. package/dist/avatars/index.d.ts +0 -1
  161. package/dist/avatars/index.d.ts.map +1 -1
  162. package/dist/avatars/index.js +0 -1
  163. package/dist/avatars/index.js.map +1 -1
  164. package/dist/cache.d.ts +4 -2
  165. package/dist/cache.d.ts.map +1 -1
  166. package/dist/cache.js +11 -5
  167. package/dist/cache.js.map +1 -1
  168. package/dist/cli.d.ts +2 -33
  169. package/dist/cli.d.ts.map +1 -1
  170. package/dist/cli.js +245 -267
  171. package/dist/cli.js.map +1 -1
  172. package/dist/cms/app.d.ts +11 -0
  173. package/dist/cms/app.d.ts.map +1 -0
  174. package/dist/cms/app.js +115 -0
  175. package/dist/cms/app.js.map +1 -0
  176. package/dist/cms/boot.d.ts +14 -0
  177. package/dist/cms/boot.d.ts.map +1 -0
  178. package/dist/cms/boot.js +107 -0
  179. package/dist/cms/boot.js.map +1 -0
  180. package/dist/cms/create.d.ts +248 -0
  181. package/dist/cms/create.d.ts.map +1 -0
  182. package/dist/cms/create.js +167 -0
  183. package/dist/cms/create.js.map +1 -0
  184. package/dist/cms/lifecycle.d.ts +11 -0
  185. package/dist/cms/lifecycle.d.ts.map +1 -0
  186. package/dist/cms/lifecycle.js +15 -0
  187. package/dist/cms/lifecycle.js.map +1 -0
  188. package/dist/{web/errors.d.ts → cms/server-error.d.ts} +2 -8
  189. package/dist/cms/server-error.d.ts.map +1 -0
  190. package/dist/{web/errors.js → cms/server-error.js} +4 -14
  191. package/dist/cms/server-error.js.map +1 -0
  192. package/dist/cms/services.d.ts +55 -0
  193. package/dist/cms/services.d.ts.map +1 -0
  194. package/dist/cms/services.js +353 -0
  195. package/dist/cms/services.js.map +1 -0
  196. package/dist/cms/site-records.d.ts +4 -0
  197. package/dist/cms/site-records.d.ts.map +1 -0
  198. package/dist/cms/site-records.js +15 -0
  199. package/dist/cms/site-records.js.map +1 -0
  200. package/dist/comments/akismet.d.ts +1 -1
  201. package/dist/comments/akismet.d.ts.map +1 -1
  202. package/dist/comments/akismet.js +1 -3
  203. package/dist/comments/akismet.js.map +1 -1
  204. package/dist/comments/conversation.d.ts +334 -0
  205. package/dist/comments/conversation.d.ts.map +1 -0
  206. package/dist/comments/conversation.js +51 -0
  207. package/dist/comments/conversation.js.map +1 -0
  208. package/dist/comments/form.d.ts +2 -2
  209. package/dist/comments/form.d.ts.map +1 -1
  210. package/dist/comments/form.js +2 -2
  211. package/dist/comments/form.js.map +1 -1
  212. package/dist/comments/index.d.ts +12 -6
  213. package/dist/comments/index.d.ts.map +1 -1
  214. package/dist/comments/index.js +7 -4
  215. package/dist/comments/index.js.map +1 -1
  216. package/dist/comments/intake.d.ts +147 -0
  217. package/dist/comments/intake.d.ts.map +1 -0
  218. package/dist/comments/intake.js +161 -0
  219. package/dist/comments/intake.js.map +1 -0
  220. package/dist/comments/markdown.d.ts.map +1 -1
  221. package/dist/comments/markdown.js +2 -9
  222. package/dist/comments/markdown.js.map +1 -1
  223. package/dist/comments/migrations.d.ts +45 -0
  224. package/dist/comments/migrations.d.ts.map +1 -0
  225. package/dist/comments/migrations.js +194 -0
  226. package/dist/comments/migrations.js.map +1 -0
  227. package/dist/comments/moderate.d.ts +2 -2
  228. package/dist/comments/moderate.d.ts.map +1 -1
  229. package/dist/comments/moderate.js +3 -13
  230. package/dist/comments/moderate.js.map +1 -1
  231. package/dist/comments/page-form.d.ts +52 -0
  232. package/dist/comments/page-form.d.ts.map +1 -0
  233. package/dist/comments/page-form.js +62 -0
  234. package/dist/comments/page-form.js.map +1 -0
  235. package/dist/comments/policy.d.ts +1 -9
  236. package/dist/comments/policy.d.ts.map +1 -1
  237. package/dist/comments/policy.js +3 -18
  238. package/dist/comments/policy.js.map +1 -1
  239. package/dist/comments/records.d.ts +25 -173
  240. package/dist/comments/records.d.ts.map +1 -1
  241. package/dist/comments/records.js +69 -265
  242. package/dist/comments/records.js.map +1 -1
  243. package/dist/comments/reply-notices.d.ts +5 -5
  244. package/dist/comments/reply-notices.d.ts.map +1 -1
  245. package/dist/comments/reply-notices.js +6 -6
  246. package/dist/comments/reply-notices.js.map +1 -1
  247. package/dist/comments/reply-post.d.ts +2 -2
  248. package/dist/comments/reply-post.d.ts.map +1 -1
  249. package/dist/comments/reply-post.js +7 -5
  250. package/dist/comments/reply-post.js.map +1 -1
  251. package/dist/comments/routes.d.ts +3 -3
  252. package/dist/comments/routes.d.ts.map +1 -1
  253. package/dist/comments/routes.js +22 -34
  254. package/dist/comments/routes.js.map +1 -1
  255. package/dist/comments/submission.d.ts +5 -100
  256. package/dist/comments/submission.d.ts.map +1 -1
  257. package/dist/comments/submission.js +5 -20
  258. package/dist/comments/submission.js.map +1 -1
  259. package/dist/comments/viewer.d.ts +1 -25
  260. package/dist/comments/viewer.d.ts.map +1 -1
  261. package/dist/comments/viewer.js +1 -44
  262. package/dist/comments/viewer.js.map +1 -1
  263. package/dist/config-loader.d.ts +35 -0
  264. package/dist/config-loader.d.ts.map +1 -0
  265. package/dist/config-loader.js +116 -0
  266. package/dist/config-loader.js.map +1 -0
  267. package/dist/config.d.ts +72 -50
  268. package/dist/config.d.ts.map +1 -1
  269. package/dist/config.js +132 -180
  270. package/dist/config.js.map +1 -1
  271. package/dist/contact/delivery.d.ts +1 -1
  272. package/dist/contact/delivery.d.ts.map +1 -1
  273. package/dist/contact/delivery.js +5 -13
  274. package/dist/contact/delivery.js.map +1 -1
  275. package/dist/contact/form.d.ts +2 -4
  276. package/dist/contact/form.d.ts.map +1 -1
  277. package/dist/contact/form.js +3 -4
  278. package/dist/contact/form.js.map +1 -1
  279. package/dist/contact/index.d.ts +2 -2
  280. package/dist/contact/index.d.ts.map +1 -1
  281. package/dist/contact/index.js +2 -2
  282. package/dist/contact/index.js.map +1 -1
  283. package/dist/contact/records.d.ts.map +1 -1
  284. package/dist/contact/records.js +8 -11
  285. package/dist/contact/records.js.map +1 -1
  286. package/dist/contact/submission.d.ts +2 -2
  287. package/dist/contact/submission.d.ts.map +1 -1
  288. package/dist/contact/submission.js +7 -16
  289. package/dist/contact/submission.js.map +1 -1
  290. package/dist/{images → content}/alt-text.d.ts +1 -1
  291. package/dist/content/alt-text.d.ts.map +1 -0
  292. package/dist/{images → content}/alt-text.js +3 -5
  293. package/dist/content/alt-text.js.map +1 -0
  294. package/dist/content/authors.d.ts +79 -0
  295. package/dist/content/authors.d.ts.map +1 -0
  296. package/dist/content/authors.js +106 -0
  297. package/dist/content/authors.js.map +1 -0
  298. package/dist/content/citation.d.ts +3 -0
  299. package/dist/content/citation.d.ts.map +1 -1
  300. package/dist/content/citation.js +3 -0
  301. package/dist/content/citation.js.map +1 -1
  302. package/dist/content/comments.d.ts +3 -0
  303. package/dist/content/comments.d.ts.map +1 -0
  304. package/dist/content/comments.js +3 -0
  305. package/dist/content/comments.js.map +1 -0
  306. package/dist/content/contact.d.ts +3 -0
  307. package/dist/content/contact.d.ts.map +1 -0
  308. package/dist/content/contact.js +3 -0
  309. package/dist/content/contact.js.map +1 -0
  310. package/dist/content/document-form.d.ts +195 -0
  311. package/dist/content/document-form.d.ts.map +1 -0
  312. package/dist/content/document-form.js +201 -0
  313. package/dist/content/document-form.js.map +1 -0
  314. package/dist/content/document-kind.d.ts +55 -0
  315. package/dist/content/document-kind.d.ts.map +1 -0
  316. package/dist/content/document-kind.js +30 -0
  317. package/dist/content/document-kind.js.map +1 -0
  318. package/dist/{admin/enclosure-field.d.ts → content/enclosure-form.d.ts} +14 -34
  319. package/dist/content/enclosure-form.d.ts.map +1 -0
  320. package/dist/{admin/enclosure-field.js → content/enclosure-form.js} +39 -76
  321. package/dist/content/enclosure-form.js.map +1 -0
  322. package/dist/content/enclosure.d.ts.map +1 -1
  323. package/dist/content/enclosure.js +3 -4
  324. package/dist/content/enclosure.js.map +1 -1
  325. package/dist/{admin/event-field.d.ts → content/event-form.d.ts} +6 -5
  326. package/dist/content/event-form.d.ts.map +1 -0
  327. package/dist/{admin/event-field.js → content/event-form.js} +45 -12
  328. package/dist/content/event-form.js.map +1 -0
  329. package/dist/content/excerpt.d.ts +25 -0
  330. package/dist/content/excerpt.d.ts.map +1 -0
  331. package/dist/content/excerpt.js +43 -0
  332. package/dist/content/excerpt.js.map +1 -0
  333. package/dist/content/form-error.d.ts +10 -0
  334. package/dist/content/form-error.d.ts.map +1 -0
  335. package/dist/content/form-error.js +2 -0
  336. package/dist/content/form-error.js.map +1 -0
  337. package/dist/{web → content}/guids.d.ts +14 -19
  338. package/dist/content/guids.d.ts.map +1 -0
  339. package/dist/{web → content}/guids.js +30 -19
  340. package/dist/content/guids.js.map +1 -0
  341. package/dist/content/image-tags.d.ts +25 -0
  342. package/dist/content/image-tags.d.ts.map +1 -0
  343. package/dist/content/image-tags.js +55 -0
  344. package/dist/content/image-tags.js.map +1 -0
  345. package/dist/content/index.d.ts +9 -4
  346. package/dist/content/index.d.ts.map +1 -1
  347. package/dist/content/index.js +5 -2
  348. package/dist/content/index.js.map +1 -1
  349. package/dist/content/language.d.ts +19 -0
  350. package/dist/content/language.d.ts.map +1 -0
  351. package/dist/content/language.js +19 -0
  352. package/dist/content/language.js.map +1 -0
  353. package/dist/content/license.d.ts.map +1 -0
  354. package/dist/content/license.js.map +1 -0
  355. package/dist/{web → content}/locale.d.ts +0 -6
  356. package/dist/content/locale.d.ts.map +1 -0
  357. package/dist/{web → content}/locale.js +1 -6
  358. package/dist/content/locale.js.map +1 -0
  359. package/dist/content/location-form.d.ts +17 -0
  360. package/dist/content/location-form.d.ts.map +1 -0
  361. package/dist/{admin/location-field.js → content/location-form.js} +2 -23
  362. package/dist/content/location-form.js.map +1 -0
  363. package/dist/content/location.d.ts.map +1 -1
  364. package/dist/content/location.js +1 -3
  365. package/dist/content/location.js.map +1 -1
  366. package/dist/content/markdown-links.d.ts +11 -0
  367. package/dist/content/markdown-links.d.ts.map +1 -0
  368. package/dist/content/markdown-links.js +223 -0
  369. package/dist/content/markdown-links.js.map +1 -0
  370. package/dist/content/markdown.d.ts +2 -1
  371. package/dist/content/markdown.d.ts.map +1 -1
  372. package/dist/content/markdown.js +1 -1
  373. package/dist/content/markdown.js.map +1 -1
  374. package/dist/content/migrated.js +1 -1
  375. package/dist/content/migrated.js.map +1 -1
  376. package/dist/content/parser.d.ts.map +1 -1
  377. package/dist/content/parser.js +1 -12
  378. package/dist/content/parser.js.map +1 -1
  379. package/dist/content/permalinks.d.ts +34 -0
  380. package/dist/content/permalinks.d.ts.map +1 -0
  381. package/dist/{web/documents.js → content/permalinks.js} +6 -56
  382. package/dist/content/permalinks.js.map +1 -0
  383. package/dist/content/photo-form.d.ts +28 -0
  384. package/dist/content/photo-form.d.ts.map +1 -0
  385. package/dist/{admin/photo-field.js → content/photo-form.js} +36 -36
  386. package/dist/content/photo-form.js.map +1 -0
  387. package/dist/content/photo.d.ts +1 -1
  388. package/dist/content/photo.d.ts.map +1 -1
  389. package/dist/content/photo.js +1 -1
  390. package/dist/content/photo.js.map +1 -1
  391. package/dist/content/post-fields.d.ts +40 -0
  392. package/dist/content/post-fields.d.ts.map +1 -0
  393. package/dist/content/post-fields.js +256 -0
  394. package/dist/content/post-fields.js.map +1 -0
  395. package/dist/{admin/read-field.d.ts → content/read-form.d.ts} +6 -4
  396. package/dist/content/read-form.d.ts.map +1 -0
  397. package/dist/content/read-form.js +99 -0
  398. package/dist/content/read-form.js.map +1 -0
  399. package/dist/content/read.d.ts.map +1 -1
  400. package/dist/content/read.js +7 -11
  401. package/dist/content/read.js.map +1 -1
  402. package/dist/content/redirects.d.ts +84 -0
  403. package/dist/content/redirects.d.ts.map +1 -0
  404. package/dist/content/redirects.js +234 -0
  405. package/dist/content/redirects.js.map +1 -0
  406. package/dist/content/sanitize.d.ts +13 -0
  407. package/dist/content/sanitize.d.ts.map +1 -0
  408. package/dist/{web → content}/sanitize.js +4 -71
  409. package/dist/content/sanitize.js.map +1 -0
  410. package/dist/content/save.d.ts +5 -8
  411. package/dist/content/save.d.ts.map +1 -1
  412. package/dist/content/save.js +5 -26
  413. package/dist/content/save.js.map +1 -1
  414. package/dist/content/schedule.d.ts +2 -2
  415. package/dist/content/schedule.d.ts.map +1 -1
  416. package/dist/content/schedule.js +1 -3
  417. package/dist/content/schedule.js.map +1 -1
  418. package/dist/content/served.d.ts +58 -0
  419. package/dist/content/served.d.ts.map +1 -0
  420. package/dist/content/served.js +65 -0
  421. package/dist/content/served.js.map +1 -0
  422. package/dist/content/site-links.d.ts +72 -0
  423. package/dist/content/site-links.d.ts.map +1 -0
  424. package/dist/content/site-links.js +191 -0
  425. package/dist/content/site-links.js.map +1 -0
  426. package/dist/content/sqlite/archive.d.ts +4 -0
  427. package/dist/content/sqlite/archive.d.ts.map +1 -0
  428. package/dist/content/sqlite/archive.js +96 -0
  429. package/dist/content/sqlite/archive.js.map +1 -0
  430. package/dist/content/sqlite/backlinks.d.ts +4 -0
  431. package/dist/content/sqlite/backlinks.d.ts.map +1 -0
  432. package/dist/content/sqlite/backlinks.js +46 -0
  433. package/dist/content/sqlite/backlinks.js.map +1 -0
  434. package/dist/content/sqlite/catalog.d.ts +4 -0
  435. package/dist/content/sqlite/catalog.d.ts.map +1 -0
  436. package/dist/content/sqlite/catalog.js +62 -0
  437. package/dist/content/sqlite/catalog.js.map +1 -0
  438. package/dist/content/sqlite/clauses.d.ts +57 -0
  439. package/dist/content/sqlite/clauses.d.ts.map +1 -0
  440. package/dist/content/sqlite/clauses.js +76 -0
  441. package/dist/content/sqlite/clauses.js.map +1 -0
  442. package/dist/content/sqlite/database.d.ts +26 -0
  443. package/dist/content/sqlite/database.d.ts.map +1 -0
  444. package/dist/content/sqlite/database.js +27 -0
  445. package/dist/content/sqlite/database.js.map +1 -0
  446. package/dist/content/sqlite/documents.d.ts +12 -0
  447. package/dist/content/sqlite/documents.d.ts.map +1 -0
  448. package/dist/content/sqlite/documents.js +40 -0
  449. package/dist/content/sqlite/documents.js.map +1 -0
  450. package/dist/content/sqlite/lookups.d.ts +6 -0
  451. package/dist/content/sqlite/lookups.d.ts.map +1 -0
  452. package/dist/content/sqlite/lookups.js +25 -0
  453. package/dist/content/sqlite/lookups.js.map +1 -0
  454. package/dist/content/sqlite/open.d.ts +8 -0
  455. package/dist/content/sqlite/open.d.ts.map +1 -0
  456. package/dist/content/sqlite/open.js +63 -0
  457. package/dist/content/sqlite/open.js.map +1 -0
  458. package/dist/content/sqlite/replies.d.ts +4 -0
  459. package/dist/content/sqlite/replies.d.ts.map +1 -0
  460. package/dist/content/sqlite/replies.js +21 -0
  461. package/dist/content/sqlite/replies.js.map +1 -0
  462. package/dist/content/sqlite/rows.d.ts +22 -0
  463. package/dist/content/sqlite/rows.d.ts.map +1 -0
  464. package/dist/content/sqlite/rows.js +93 -0
  465. package/dist/content/sqlite/rows.js.map +1 -0
  466. package/dist/content/sqlite/schedule.d.ts +4 -0
  467. package/dist/content/sqlite/schedule.d.ts.map +1 -0
  468. package/dist/content/sqlite/schedule.js +16 -0
  469. package/dist/content/sqlite/schedule.js.map +1 -0
  470. package/dist/content/sqlite/schema.d.ts +10 -0
  471. package/dist/content/sqlite/schema.d.ts.map +1 -0
  472. package/dist/content/sqlite/schema.js +209 -0
  473. package/dist/content/sqlite/schema.js.map +1 -0
  474. package/dist/content/sqlite/search.d.ts +4 -0
  475. package/dist/content/sqlite/search.d.ts.map +1 -0
  476. package/dist/content/sqlite/search.js +54 -0
  477. package/dist/content/sqlite/search.js.map +1 -0
  478. package/dist/content/sqlite/spellings.d.ts +6 -0
  479. package/dist/content/sqlite/spellings.d.ts.map +1 -0
  480. package/dist/content/sqlite/spellings.js +80 -0
  481. package/dist/content/sqlite/spellings.js.map +1 -0
  482. package/dist/content/sqlite/taxonomy.d.ts +4 -0
  483. package/dist/content/sqlite/taxonomy.d.ts.map +1 -0
  484. package/dist/content/sqlite/taxonomy.js +75 -0
  485. package/dist/content/sqlite/taxonomy.js.map +1 -0
  486. package/dist/content/sqlite/writes.d.ts +9 -0
  487. package/dist/content/sqlite/writes.d.ts.map +1 -0
  488. package/dist/content/sqlite/writes.js +164 -0
  489. package/dist/content/sqlite/writes.js.map +1 -0
  490. package/dist/content/store.d.ts +142 -137
  491. package/dist/content/store.d.ts.map +1 -1
  492. package/dist/content/store.js +0 -1050
  493. package/dist/content/store.js.map +1 -1
  494. package/dist/content/sync.d.ts +12 -4
  495. package/dist/content/sync.d.ts.map +1 -1
  496. package/dist/content/sync.js +24 -41
  497. package/dist/content/sync.js.map +1 -1
  498. package/dist/content/syndicate-to.d.ts +25 -0
  499. package/dist/content/syndicate-to.d.ts.map +1 -0
  500. package/dist/content/syndicate-to.js +8 -0
  501. package/dist/content/syndicate-to.js.map +1 -0
  502. package/dist/{web → content}/taxonomy.d.ts +1 -1
  503. package/dist/content/taxonomy.d.ts.map +1 -0
  504. package/dist/{web → content}/taxonomy.js +2 -2
  505. package/dist/content/taxonomy.js.map +1 -0
  506. package/dist/content/time.d.ts +2 -2
  507. package/dist/content/time.d.ts.map +1 -1
  508. package/dist/content/time.js +3 -3
  509. package/dist/content/time.js.map +1 -1
  510. package/dist/content/trash.d.ts +35 -0
  511. package/dist/content/trash.d.ts.map +1 -0
  512. package/dist/content/trash.js +83 -0
  513. package/dist/content/trash.js.map +1 -0
  514. package/dist/content/uploads.d.ts +24 -0
  515. package/dist/content/uploads.d.ts.map +1 -0
  516. package/dist/content/uploads.js +27 -0
  517. package/dist/content/uploads.js.map +1 -0
  518. package/dist/content/video.d.ts.map +1 -1
  519. package/dist/content/video.js +3 -5
  520. package/dist/content/video.js.map +1 -1
  521. package/dist/content/write.d.ts +84 -0
  522. package/dist/content/write.d.ts.map +1 -0
  523. package/dist/content/write.js +566 -0
  524. package/dist/content/write.js.map +1 -0
  525. package/dist/content/writer.d.ts.map +1 -1
  526. package/dist/content/writer.js +1 -2
  527. package/dist/content/writer.js.map +1 -1
  528. package/dist/dev-mode.d.ts +5 -3
  529. package/dist/dev-mode.d.ts.map +1 -1
  530. package/dist/dev-mode.js +3 -3
  531. package/dist/dev-mode.js.map +1 -1
  532. package/dist/drain.d.ts +2 -3
  533. package/dist/drain.d.ts.map +1 -1
  534. package/dist/drain.js +2 -1
  535. package/dist/drain.js.map +1 -1
  536. package/dist/exports.d.ts +26 -0
  537. package/dist/exports.d.ts.map +1 -0
  538. package/dist/exports.js +8 -0
  539. package/dist/exports.js.map +1 -0
  540. package/dist/federation/actor.d.ts +1 -1
  541. package/dist/federation/actor.d.ts.map +1 -1
  542. package/dist/federation/actor.js +6 -13
  543. package/dist/federation/actor.js.map +1 -1
  544. package/dist/federation/article.d.ts +4 -14
  545. package/dist/federation/article.d.ts.map +1 -1
  546. package/dist/federation/article.js +19 -32
  547. package/dist/federation/article.js.map +1 -1
  548. package/dist/federation/backfill.d.ts +4 -4
  549. package/dist/federation/backfill.d.ts.map +1 -1
  550. package/dist/federation/backfill.js +12 -13
  551. package/dist/federation/backfill.js.map +1 -1
  552. package/dist/federation/citations.d.ts.map +1 -1
  553. package/dist/federation/citations.js.map +1 -1
  554. package/dist/federation/cited-post.d.ts.map +1 -1
  555. package/dist/federation/cited-post.js +2 -4
  556. package/dist/federation/cited-post.js.map +1 -1
  557. package/dist/federation/delivery-plan.d.ts +85 -0
  558. package/dist/federation/delivery-plan.d.ts.map +1 -0
  559. package/dist/federation/delivery-plan.js +137 -0
  560. package/dist/federation/delivery-plan.js.map +1 -0
  561. package/dist/federation/delivery.d.ts +7 -32
  562. package/dist/federation/delivery.d.ts.map +1 -1
  563. package/dist/federation/delivery.js +64 -201
  564. package/dist/federation/delivery.js.map +1 -1
  565. package/dist/federation/federation.d.ts +5 -5
  566. package/dist/federation/federation.d.ts.map +1 -1
  567. package/dist/federation/federation.js +7 -6
  568. package/dist/federation/federation.js.map +1 -1
  569. package/dist/federation/followers.d.ts +1 -1
  570. package/dist/federation/followers.d.ts.map +1 -1
  571. package/dist/federation/inbox.d.ts +1 -1
  572. package/dist/federation/inbox.d.ts.map +1 -1
  573. package/dist/federation/inbox.js +5 -4
  574. package/dist/federation/inbox.js.map +1 -1
  575. package/dist/federation/index.d.ts +10 -8
  576. package/dist/federation/index.d.ts.map +1 -1
  577. package/dist/federation/index.js +7 -5
  578. package/dist/federation/index.js.map +1 -1
  579. package/dist/federation/keys.d.ts +8 -27
  580. package/dist/federation/keys.d.ts.map +1 -1
  581. package/dist/federation/keys.js +4 -47
  582. package/dist/federation/keys.js.map +1 -1
  583. package/dist/federation/mount.d.ts +2 -2
  584. package/dist/federation/mount.d.ts.map +1 -1
  585. package/dist/federation/mount.js +9 -7
  586. package/dist/federation/mount.js.map +1 -1
  587. package/dist/federation/paths.d.ts +1 -9
  588. package/dist/federation/paths.d.ts.map +1 -1
  589. package/dist/federation/paths.js +2 -12
  590. package/dist/federation/paths.js.map +1 -1
  591. package/dist/federation/profiles.d.ts +1 -1
  592. package/dist/federation/profiles.d.ts.map +1 -1
  593. package/dist/federation/profiles.js +5 -8
  594. package/dist/federation/profiles.js.map +1 -1
  595. package/dist/federation/quotes.d.ts +2 -2
  596. package/dist/federation/quotes.d.ts.map +1 -1
  597. package/dist/federation/quotes.js +4 -4
  598. package/dist/federation/quotes.js.map +1 -1
  599. package/dist/federation/records.d.ts +2 -2
  600. package/dist/federation/records.d.ts.map +1 -1
  601. package/dist/federation/records.js +12 -19
  602. package/dist/federation/records.js.map +1 -1
  603. package/dist/federation/relays.d.ts +2 -3
  604. package/dist/federation/relays.d.ts.map +1 -1
  605. package/dist/federation/relays.js +22 -30
  606. package/dist/federation/relays.js.map +1 -1
  607. package/dist/federation/site-loaders.js +1 -1
  608. package/dist/federation/site-loaders.js.map +1 -1
  609. package/dist/federation/webfinger.d.ts +23 -0
  610. package/dist/federation/webfinger.d.ts.map +1 -0
  611. package/dist/federation/webfinger.js +70 -0
  612. package/dist/federation/webfinger.js.map +1 -0
  613. package/dist/files/atomic.d.ts.map +1 -1
  614. package/dist/files/atomic.js +4 -9
  615. package/dist/files/atomic.js.map +1 -1
  616. package/dist/files/static-files.d.ts +21 -0
  617. package/dist/files/static-files.d.ts.map +1 -0
  618. package/dist/files/static-files.js +88 -0
  619. package/dist/files/static-files.js.map +1 -0
  620. package/dist/forms/checker.d.ts +93 -0
  621. package/dist/forms/checker.d.ts.map +1 -0
  622. package/dist/forms/checker.js +2 -0
  623. package/dist/forms/checker.js.map +1 -0
  624. package/dist/forms/protection.d.ts +3 -1
  625. package/dist/forms/protection.d.ts.map +1 -1
  626. package/dist/forms/protection.js +3 -1
  627. package/dist/forms/protection.js.map +1 -1
  628. package/dist/images/icons.js +2 -2
  629. package/dist/images/icons.js.map +1 -1
  630. package/dist/images/index.d.ts +2 -1
  631. package/dist/images/index.d.ts.map +1 -1
  632. package/dist/images/index.js +2 -1
  633. package/dist/images/index.js.map +1 -1
  634. package/dist/images/markup.d.ts +0 -20
  635. package/dist/images/markup.d.ts.map +1 -1
  636. package/dist/images/markup.js +5 -64
  637. package/dist/images/markup.js.map +1 -1
  638. package/dist/images/paths.d.ts +0 -10
  639. package/dist/images/paths.d.ts.map +1 -1
  640. package/dist/images/paths.js +3 -11
  641. package/dist/images/paths.js.map +1 -1
  642. package/dist/images/variants.d.ts +2 -2
  643. package/dist/images/variants.d.ts.map +1 -1
  644. package/dist/images/variants.js +4 -3
  645. package/dist/images/variants.js.map +1 -1
  646. package/dist/index.d.ts +3 -291
  647. package/dist/index.d.ts.map +1 -1
  648. package/dist/index.js +2 -838
  649. package/dist/index.js.map +1 -1
  650. package/dist/indexnow.d.ts.map +1 -1
  651. package/dist/indexnow.js +21 -26
  652. package/dist/indexnow.js.map +1 -1
  653. package/dist/indieauth/client.d.ts +1 -1
  654. package/dist/indieauth/client.d.ts.map +1 -1
  655. package/dist/indieauth/client.js +1 -1
  656. package/dist/indieauth/client.js.map +1 -1
  657. package/dist/indieauth/grants.d.ts +1 -1
  658. package/dist/indieauth/grants.d.ts.map +1 -1
  659. package/dist/indieauth/identity.d.ts +2 -2
  660. package/dist/indieauth/identity.d.ts.map +1 -1
  661. package/dist/indieauth/identity.js +5 -7
  662. package/dist/indieauth/identity.js.map +1 -1
  663. package/dist/indieauth/redeem.d.ts +1 -1
  664. package/dist/indieauth/redeem.d.ts.map +1 -1
  665. package/dist/indieauth/redeem.js.map +1 -1
  666. package/dist/indieauth/request.d.ts +5 -1
  667. package/dist/indieauth/request.d.ts.map +1 -1
  668. package/dist/indieauth/request.js +6 -2
  669. package/dist/indieauth/request.js.map +1 -1
  670. package/dist/indieauth/tokens.d.ts +1 -1
  671. package/dist/indieauth/tokens.d.ts.map +1 -1
  672. package/dist/indieauth/tokens.js +2 -2
  673. package/dist/indieauth/tokens.js.map +1 -1
  674. package/dist/mail/index.d.ts +1 -5
  675. package/dist/mail/index.d.ts.map +1 -1
  676. package/dist/mail/index.js +0 -2
  677. package/dist/mail/index.js.map +1 -1
  678. package/dist/mail/provider.d.ts +7 -0
  679. package/dist/mail/provider.d.ts.map +1 -1
  680. package/dist/maintenance.d.ts +1 -1
  681. package/dist/maintenance.d.ts.map +1 -1
  682. package/dist/media/library.d.ts +99 -0
  683. package/dist/media/library.d.ts.map +1 -0
  684. package/dist/media/library.js +157 -0
  685. package/dist/media/library.js.map +1 -0
  686. package/dist/media/uploads.d.ts +106 -0
  687. package/dist/media/uploads.d.ts.map +1 -0
  688. package/dist/media/uploads.js +192 -0
  689. package/dist/media/uploads.js.map +1 -0
  690. package/dist/micropub/content.js +1 -1
  691. package/dist/micropub/content.js.map +1 -1
  692. package/dist/micropub/create.d.ts +7 -15
  693. package/dist/micropub/create.d.ts.map +1 -1
  694. package/dist/micropub/create.js +48 -184
  695. package/dist/micropub/create.js.map +1 -1
  696. package/dist/micropub/endpoint.d.ts +2 -2
  697. package/dist/micropub/endpoint.d.ts.map +1 -1
  698. package/dist/micropub/endpoint.js +29 -40
  699. package/dist/micropub/endpoint.js.map +1 -1
  700. package/dist/micropub/media.d.ts +1 -1
  701. package/dist/micropub/media.d.ts.map +1 -1
  702. package/dist/micropub/media.js +6 -6
  703. package/dist/micropub/media.js.map +1 -1
  704. package/dist/micropub/update.d.ts +6 -14
  705. package/dist/micropub/update.d.ts.map +1 -1
  706. package/dist/micropub/update.js +37 -90
  707. package/dist/micropub/update.js.map +1 -1
  708. package/dist/notifications/comments.d.ts +4 -4
  709. package/dist/notifications/comments.d.ts.map +1 -1
  710. package/dist/notifications/comments.js +6 -14
  711. package/dist/notifications/comments.js.map +1 -1
  712. package/dist/notifications/digest.d.ts +4 -4
  713. package/dist/notifications/digest.d.ts.map +1 -1
  714. package/dist/notifications/digest.js +6 -16
  715. package/dist/notifications/digest.js.map +1 -1
  716. package/dist/notifications/index.d.ts +6 -3
  717. package/dist/notifications/index.d.ts.map +1 -1
  718. package/dist/notifications/index.js +3 -2
  719. package/dist/notifications/index.js.map +1 -1
  720. package/dist/notifications/links.d.ts.map +1 -1
  721. package/dist/notifications/links.js +2 -2
  722. package/dist/notifications/links.js.map +1 -1
  723. package/dist/{mail/service.d.ts → notifications/mail-service.d.ts} +7 -13
  724. package/dist/notifications/mail-service.d.ts.map +1 -0
  725. package/dist/{mail/service.js → notifications/mail-service.js} +33 -54
  726. package/dist/notifications/mail-service.js.map +1 -0
  727. package/dist/{mail/templates.d.ts → notifications/mail-templates.d.ts} +4 -2
  728. package/dist/notifications/mail-templates.d.ts.map +1 -0
  729. package/dist/{mail/templates.js → notifications/mail-templates.js} +5 -3
  730. package/dist/notifications/mail-templates.js.map +1 -0
  731. package/dist/notifications/tokens.d.ts +2 -2
  732. package/dist/notifications/tokens.d.ts.map +1 -1
  733. package/dist/notifications/tokens.js +2 -2
  734. package/dist/notifications/tokens.js.map +1 -1
  735. package/dist/notify.d.ts.map +1 -1
  736. package/dist/notify.js +12 -24
  737. package/dist/notify.js.map +1 -1
  738. package/dist/plugin.d.ts +48 -2
  739. package/dist/plugin.d.ts.map +1 -1
  740. package/dist/plugin.js +28 -2
  741. package/dist/plugin.js.map +1 -1
  742. package/dist/plugins/enabled.d.ts.map +1 -1
  743. package/dist/plugins/enabled.js +2 -4
  744. package/dist/plugins/enabled.js.map +1 -1
  745. package/dist/plugins/fetch.d.ts +1 -1
  746. package/dist/plugins/fetch.d.ts.map +1 -1
  747. package/dist/plugins/fetch.js +1 -1
  748. package/dist/plugins/fetch.js.map +1 -1
  749. package/dist/plugins/folder.d.ts.map +1 -1
  750. package/dist/plugins/folder.js +1 -3
  751. package/dist/plugins/folder.js.map +1 -1
  752. package/dist/plugins/install.d.ts.map +1 -1
  753. package/dist/plugins/install.js +7 -3
  754. package/dist/plugins/install.js.map +1 -1
  755. package/dist/plugins/manage.d.ts +1 -1
  756. package/dist/plugins/manage.d.ts.map +1 -1
  757. package/dist/plugins/registry.d.ts.map +1 -1
  758. package/dist/plugins/registry.js +7 -9
  759. package/dist/plugins/registry.js.map +1 -1
  760. package/dist/plugins/settings.d.ts.map +1 -1
  761. package/dist/plugins/settings.js +2 -3
  762. package/dist/plugins/settings.js.map +1 -1
  763. package/dist/plugins/site.d.ts +1 -1
  764. package/dist/plugins/site.d.ts.map +1 -1
  765. package/dist/plugins/site.js +10 -4
  766. package/dist/plugins/site.js.map +1 -1
  767. package/dist/plugins/upgrade.d.ts.map +1 -1
  768. package/dist/plugins/upgrade.js +4 -3
  769. package/dist/plugins/upgrade.js.map +1 -1
  770. package/dist/privacy/erase.d.ts +1 -1
  771. package/dist/privacy/erase.d.ts.map +1 -1
  772. package/dist/privacy/retention.d.ts +2 -2
  773. package/dist/privacy/retention.d.ts.map +1 -1
  774. package/dist/privacy/retention.js +9 -11
  775. package/dist/privacy/retention.js.map +1 -1
  776. package/dist/site/admin-paths.d.ts +23 -0
  777. package/dist/site/admin-paths.d.ts.map +1 -0
  778. package/dist/site/admin-paths.js +25 -0
  779. package/dist/site/admin-paths.js.map +1 -0
  780. package/dist/site/admin-theme.d.ts.map +1 -0
  781. package/dist/site/admin-theme.js.map +1 -0
  782. package/dist/{web → site}/authors.d.ts +1 -72
  783. package/dist/site/authors.d.ts.map +1 -0
  784. package/dist/site/authors.js +107 -0
  785. package/dist/site/authors.js.map +1 -0
  786. package/dist/site/feed-settings.d.ts +28 -0
  787. package/dist/site/feed-settings.d.ts.map +1 -0
  788. package/dist/site/feed-settings.js +22 -0
  789. package/dist/site/feed-settings.js.map +1 -0
  790. package/dist/{web/indexnow.d.ts → site/indexnow-key.d.ts} +1 -1
  791. package/dist/site/indexnow-key.d.ts.map +1 -0
  792. package/dist/{web/indexnow.js → site/indexnow-key.js} +1 -1
  793. package/dist/site/indexnow-key.js.map +1 -0
  794. package/dist/{web → site}/navigation.d.ts +7 -1
  795. package/dist/site/navigation.d.ts.map +1 -0
  796. package/dist/{web → site}/navigation.js +18 -0
  797. package/dist/site/navigation.js.map +1 -0
  798. package/dist/{notifications/preferences.d.ts → site/notification-preferences.d.ts} +2 -2
  799. package/dist/site/notification-preferences.d.ts.map +1 -0
  800. package/dist/{notifications/preferences.js → site/notification-preferences.js} +1 -1
  801. package/dist/site/notification-preferences.js.map +1 -0
  802. package/dist/site/passwords.d.ts.map +1 -0
  803. package/dist/site/passwords.js.map +1 -0
  804. package/dist/{privacy/policy.d.ts → site/retention-policy.d.ts} +1 -1
  805. package/dist/site/retention-policy.d.ts.map +1 -0
  806. package/dist/{privacy/policy.js → site/retention-policy.js} +1 -1
  807. package/dist/site/retention-policy.js.map +1 -0
  808. package/dist/site/robots.d.ts +62 -0
  809. package/dist/site/robots.d.ts.map +1 -0
  810. package/dist/site/robots.js +130 -0
  811. package/dist/site/robots.js.map +1 -0
  812. package/dist/site/setting-rows.d.ts +46 -0
  813. package/dist/site/setting-rows.d.ts.map +1 -0
  814. package/dist/site/setting-rows.js +480 -0
  815. package/dist/site/setting-rows.js.map +1 -0
  816. package/dist/site/setting-values.d.ts +63 -0
  817. package/dist/site/setting-values.d.ts.map +1 -0
  818. package/dist/site/setting-values.js +170 -0
  819. package/dist/site/setting-values.js.map +1 -0
  820. package/dist/site/settings-form.d.ts +30 -0
  821. package/dist/site/settings-form.d.ts.map +1 -0
  822. package/dist/site/settings-form.js +58 -0
  823. package/dist/site/settings-form.js.map +1 -0
  824. package/dist/site/settings.d.ts +345 -0
  825. package/dist/site/settings.d.ts.map +1 -0
  826. package/dist/site/settings.js +107 -0
  827. package/dist/site/settings.js.map +1 -0
  828. package/dist/site/site-json.d.ts +69 -0
  829. package/dist/site/site-json.d.ts.map +1 -0
  830. package/dist/site/site-json.js +113 -0
  831. package/dist/site/site-json.js.map +1 -0
  832. package/dist/{admin/accounts.d.ts → site/users.d.ts} +25 -41
  833. package/dist/site/users.d.ts.map +1 -0
  834. package/dist/{admin/accounts.js → site/users.js} +49 -155
  835. package/dist/site/users.js.map +1 -0
  836. package/dist/store/admin-store.d.ts +72 -0
  837. package/dist/store/admin-store.d.ts.map +1 -0
  838. package/dist/store/admin-store.js +62 -0
  839. package/dist/store/admin-store.js.map +1 -0
  840. package/dist/store/comments.d.ts +253 -0
  841. package/dist/store/comments.d.ts.map +1 -0
  842. package/dist/store/comments.js +234 -0
  843. package/dist/store/comments.js.map +1 -0
  844. package/dist/store/conversation.d.ts +28 -0
  845. package/dist/store/conversation.d.ts.map +1 -0
  846. package/dist/store/conversation.js +16 -0
  847. package/dist/store/conversation.js.map +1 -0
  848. package/dist/store/deliveries.d.ts +92 -0
  849. package/dist/store/deliveries.d.ts.map +1 -0
  850. package/dist/store/deliveries.js +88 -0
  851. package/dist/store/deliveries.js.map +1 -0
  852. package/dist/store/followers.d.ts +91 -0
  853. package/dist/store/followers.d.ts.map +1 -0
  854. package/dist/store/followers.js +79 -0
  855. package/dist/store/followers.js.map +1 -0
  856. package/dist/{federation/replies.d.ts → store/inbox-replies.d.ts} +2 -2
  857. package/dist/store/inbox-replies.d.ts.map +1 -0
  858. package/dist/{federation/replies.js → store/inbox-replies.js} +2 -4
  859. package/dist/store/inbox-replies.js.map +1 -0
  860. package/dist/store/inbox.d.ts +132 -0
  861. package/dist/store/inbox.d.ts.map +1 -0
  862. package/dist/store/inbox.js +157 -0
  863. package/dist/store/inbox.js.map +1 -0
  864. package/dist/store/profiles.d.ts +49 -0
  865. package/dist/store/profiles.d.ts.map +1 -0
  866. package/dist/store/profiles.js +71 -0
  867. package/dist/store/profiles.js.map +1 -0
  868. package/dist/store/relays.d.ts +66 -0
  869. package/dist/store/relays.d.ts.map +1 -0
  870. package/dist/store/relays.js +69 -0
  871. package/dist/store/relays.js.map +1 -0
  872. package/dist/store/rows.d.ts +33 -0
  873. package/dist/store/rows.d.ts.map +1 -0
  874. package/dist/store/rows.js +44 -0
  875. package/dist/store/rows.js.map +1 -0
  876. package/dist/store/schema.d.ts +14 -0
  877. package/dist/store/schema.d.ts.map +1 -0
  878. package/dist/store/schema.js +588 -0
  879. package/dist/store/schema.js.map +1 -0
  880. package/dist/store/sessions.d.ts +90 -0
  881. package/dist/store/sessions.d.ts.map +1 -0
  882. package/dist/store/sessions.js +107 -0
  883. package/dist/store/sessions.js.map +1 -0
  884. package/dist/store/state.d.ts +18 -0
  885. package/dist/store/state.d.ts.map +1 -0
  886. package/dist/store/state.js +19 -0
  887. package/dist/store/state.js.map +1 -0
  888. package/dist/store/tokens.d.ts +75 -0
  889. package/dist/store/tokens.d.ts.map +1 -0
  890. package/dist/store/tokens.js +82 -0
  891. package/dist/store/tokens.js.map +1 -0
  892. package/dist/store/webmentions.d.ts +66 -0
  893. package/dist/store/webmentions.d.ts.map +1 -0
  894. package/dist/store/webmentions.js +84 -0
  895. package/dist/store/webmentions.js.map +1 -0
  896. package/dist/supervisor/primary.d.ts +1 -1
  897. package/dist/supervisor/primary.d.ts.map +1 -1
  898. package/dist/supervisor/primary.js +31 -11
  899. package/dist/supervisor/primary.js.map +1 -1
  900. package/dist/supervisor/worker.d.ts +6 -2
  901. package/dist/supervisor/worker.d.ts.map +1 -1
  902. package/dist/supervisor/worker.js +4 -4
  903. package/dist/supervisor/worker.js.map +1 -1
  904. package/dist/testing.d.ts +8 -0
  905. package/dist/testing.d.ts.map +1 -0
  906. package/dist/testing.js +6 -0
  907. package/dist/testing.js.map +1 -0
  908. package/dist/{web → theme}/assets.d.ts +1 -32
  909. package/dist/theme/assets.d.ts.map +1 -0
  910. package/dist/{web → theme}/assets.js +2 -100
  911. package/dist/theme/assets.js.map +1 -0
  912. package/dist/theme/site-data.d.ts +187 -0
  913. package/dist/theme/site-data.d.ts.map +1 -0
  914. package/dist/theme/site-data.js +160 -0
  915. package/dist/theme/site-data.js.map +1 -0
  916. package/dist/{web → theme}/templates.d.ts +2 -0
  917. package/dist/theme/templates.d.ts.map +1 -0
  918. package/dist/{web → theme}/templates.js +9 -32
  919. package/dist/theme/templates.js.map +1 -0
  920. package/dist/{web → theme}/themes.d.ts +1 -0
  921. package/dist/theme/themes.d.ts.map +1 -0
  922. package/dist/{web → theme}/themes.js +6 -3
  923. package/dist/theme/themes.js.map +1 -0
  924. package/dist/util/client-id.d.ts.map +1 -0
  925. package/dist/util/client-id.js.map +1 -0
  926. package/dist/util/clock.d.ts +9 -0
  927. package/dist/util/clock.d.ts.map +1 -0
  928. package/dist/util/clock.js +2 -0
  929. package/dist/util/clock.js.map +1 -0
  930. package/dist/util/errors.d.ts +3 -0
  931. package/dist/util/errors.d.ts.map +1 -0
  932. package/dist/util/errors.js +5 -0
  933. package/dist/util/errors.js.map +1 -0
  934. package/dist/util/files.d.ts +5 -0
  935. package/dist/util/files.d.ts.map +1 -0
  936. package/dist/util/files.js +38 -0
  937. package/dist/util/files.js.map +1 -0
  938. package/dist/util/forms.d.ts +5 -0
  939. package/dist/util/forms.d.ts.map +1 -0
  940. package/dist/util/forms.js +17 -0
  941. package/dist/util/forms.js.map +1 -0
  942. package/dist/util/guards.d.ts +4 -0
  943. package/dist/util/guards.d.ts.map +1 -0
  944. package/dist/util/guards.js +12 -0
  945. package/dist/util/guards.js.map +1 -0
  946. package/dist/{webmention/html.d.ts → util/html-tree.d.ts} +2 -2
  947. package/dist/util/html-tree.d.ts.map +1 -0
  948. package/dist/{webmention/html.js → util/html-tree.js} +3 -64
  949. package/dist/util/html-tree.js.map +1 -0
  950. package/dist/util/html.d.ts +4 -0
  951. package/dist/util/html.d.ts.map +1 -0
  952. package/dist/util/html.js +34 -0
  953. package/dist/util/html.js.map +1 -0
  954. package/dist/util/public-address.d.ts.map +1 -0
  955. package/dist/util/public-address.js.map +1 -0
  956. package/dist/util/queue.d.ts +7 -0
  957. package/dist/util/queue.d.ts.map +1 -0
  958. package/dist/util/queue.js +23 -0
  959. package/dist/util/queue.js.map +1 -0
  960. package/dist/util/retry.d.ts +11 -0
  961. package/dist/util/retry.d.ts.map +1 -0
  962. package/dist/util/retry.js +14 -0
  963. package/dist/util/retry.js.map +1 -0
  964. package/dist/util/url.d.ts +11 -0
  965. package/dist/util/url.d.ts.map +1 -0
  966. package/dist/util/url.js +20 -0
  967. package/dist/util/url.js.map +1 -0
  968. package/dist/web/absolute-urls.js +1 -1
  969. package/dist/web/absolute-urls.js.map +1 -1
  970. package/dist/web/archive.js +2 -2
  971. package/dist/web/archive.js.map +1 -1
  972. package/dist/web/asset-routes.d.ts +48 -0
  973. package/dist/web/asset-routes.d.ts.map +1 -0
  974. package/dist/web/asset-routes.js +107 -0
  975. package/dist/web/asset-routes.js.map +1 -0
  976. package/dist/{avatars/routes.d.ts → web/avatar-routes.d.ts} +2 -2
  977. package/dist/web/avatar-routes.d.ts.map +1 -0
  978. package/dist/{avatars/routes.js → web/avatar-routes.js} +3 -3
  979. package/dist/web/avatar-routes.js.map +1 -0
  980. package/dist/web/comment-routes.d.ts +18 -0
  981. package/dist/web/comment-routes.d.ts.map +1 -0
  982. package/dist/web/comment-routes.js +177 -0
  983. package/dist/web/comment-routes.js.map +1 -0
  984. package/dist/web/compression.d.ts.map +1 -1
  985. package/dist/web/compression.js +1 -2
  986. package/dist/web/compression.js.map +1 -1
  987. package/dist/{contact/routes.d.ts → web/contact-routes.d.ts} +2 -2
  988. package/dist/web/contact-routes.d.ts.map +1 -0
  989. package/dist/{contact/routes.js → web/contact-routes.js} +14 -17
  990. package/dist/web/contact-routes.js.map +1 -0
  991. package/dist/web/context.d.ts +1 -187
  992. package/dist/web/context.d.ts.map +1 -1
  993. package/dist/web/context.js +5 -171
  994. package/dist/web/context.js.map +1 -1
  995. package/dist/web/conversation.d.ts +6 -333
  996. package/dist/web/conversation.d.ts.map +1 -1
  997. package/dist/web/conversation.js +280 -220
  998. package/dist/web/conversation.js.map +1 -1
  999. package/dist/web/document-page.d.ts +13 -0
  1000. package/dist/web/document-page.d.ts.map +1 -0
  1001. package/dist/web/document-page.js +136 -0
  1002. package/dist/web/document-page.js.map +1 -0
  1003. package/dist/web/document-site.d.ts +14 -0
  1004. package/dist/web/document-site.d.ts.map +1 -0
  1005. package/dist/web/document-site.js +28 -0
  1006. package/dist/web/document-site.js.map +1 -0
  1007. package/dist/web/embed.d.ts +13 -0
  1008. package/dist/web/embed.d.ts.map +1 -0
  1009. package/dist/web/embed.js +66 -0
  1010. package/dist/web/embed.js.map +1 -0
  1011. package/dist/{env.d.ts → web/env.d.ts} +27 -26
  1012. package/dist/web/env.d.ts.map +1 -0
  1013. package/dist/web/env.js.map +1 -0
  1014. package/dist/web/federation-routes.d.ts +33 -0
  1015. package/dist/web/federation-routes.d.ts.map +1 -0
  1016. package/dist/web/federation-routes.js +280 -0
  1017. package/dist/web/federation-routes.js.map +1 -0
  1018. package/dist/web/feed-atom.d.ts.map +1 -1
  1019. package/dist/web/feed-atom.js +4 -3
  1020. package/dist/web/feed-atom.js.map +1 -1
  1021. package/dist/web/feed-item.d.ts +4 -39
  1022. package/dist/web/feed-item.d.ts.map +1 -1
  1023. package/dist/web/feed-item.js +8 -72
  1024. package/dist/web/feed-item.js.map +1 -1
  1025. package/dist/web/feed-json.js +2 -2
  1026. package/dist/web/feed-json.js.map +1 -1
  1027. package/dist/web/feed-routes.d.ts +36 -0
  1028. package/dist/web/feed-routes.d.ts.map +1 -0
  1029. package/dist/web/feed-routes.js +124 -0
  1030. package/dist/web/feed-routes.js.map +1 -0
  1031. package/dist/web/feed-rss.d.ts.map +1 -1
  1032. package/dist/web/feed-rss.js +9 -6
  1033. package/dist/web/feed-rss.js.map +1 -1
  1034. package/dist/web/feed-source.d.ts +13 -40
  1035. package/dist/web/feed-source.d.ts.map +1 -1
  1036. package/dist/web/feed-source.js +14 -43
  1037. package/dist/web/feed-source.js.map +1 -1
  1038. package/dist/web/feeds.d.ts +4 -2
  1039. package/dist/web/feeds.d.ts.map +1 -1
  1040. package/dist/web/feeds.js +8 -5
  1041. package/dist/web/feeds.js.map +1 -1
  1042. package/dist/web/health.d.ts +1 -1
  1043. package/dist/web/health.d.ts.map +1 -1
  1044. package/dist/web/index.d.ts +53 -29
  1045. package/dist/web/index.d.ts.map +1 -1
  1046. package/dist/web/index.js +37 -18
  1047. package/dist/web/index.js.map +1 -1
  1048. package/dist/{indieauth/activity-log.d.ts → web/indieauth-activity-log.d.ts} +3 -3
  1049. package/dist/web/indieauth-activity-log.d.ts.map +1 -0
  1050. package/dist/{indieauth/activity-log.js → web/indieauth-activity-log.js} +5 -6
  1051. package/dist/web/indieauth-activity-log.js.map +1 -0
  1052. package/dist/{indieauth/bearer.d.ts → web/indieauth-bearer.d.ts} +5 -5
  1053. package/dist/web/indieauth-bearer.d.ts.map +1 -0
  1054. package/dist/{indieauth/bearer.js → web/indieauth-bearer.js} +4 -4
  1055. package/dist/web/indieauth-bearer.js.map +1 -0
  1056. package/dist/{indieauth/discovery.d.ts → web/indieauth-discovery.d.ts} +2 -7
  1057. package/dist/web/indieauth-discovery.d.ts.map +1 -0
  1058. package/dist/{indieauth/discovery.js → web/indieauth-discovery.js} +6 -9
  1059. package/dist/web/indieauth-discovery.js.map +1 -0
  1060. package/dist/{indieauth/token.d.ts → web/indieauth-token.d.ts} +2 -2
  1061. package/dist/web/indieauth-token.d.ts.map +1 -0
  1062. package/dist/{indieauth/token.js → web/indieauth-token.js} +7 -7
  1063. package/dist/web/indieauth-token.js.map +1 -0
  1064. package/dist/web/listing-pages.d.ts +19 -0
  1065. package/dist/web/listing-pages.d.ts.map +1 -0
  1066. package/dist/web/listing-pages.js +148 -0
  1067. package/dist/web/listing-pages.js.map +1 -0
  1068. package/dist/web/listing-subject.d.ts +58 -0
  1069. package/dist/web/listing-subject.d.ts.map +1 -0
  1070. package/dist/web/listing-subject.js +89 -0
  1071. package/dist/web/listing-subject.js.map +1 -0
  1072. package/dist/web/llms.d.ts +16 -15
  1073. package/dist/web/llms.d.ts.map +1 -1
  1074. package/dist/web/llms.js +23 -35
  1075. package/dist/web/llms.js.map +1 -1
  1076. package/dist/web/maintenance.d.ts +1 -1
  1077. package/dist/web/maintenance.d.ts.map +1 -1
  1078. package/dist/web/maintenance.js +7 -13
  1079. package/dist/web/maintenance.js.map +1 -1
  1080. package/dist/web/manifest.d.ts +1 -1
  1081. package/dist/web/manifest.d.ts.map +1 -1
  1082. package/dist/web/manifest.js +2 -1
  1083. package/dist/web/manifest.js.map +1 -1
  1084. package/dist/web/markdown-page.d.ts +76 -0
  1085. package/dist/web/markdown-page.d.ts.map +1 -0
  1086. package/dist/web/markdown-page.js +79 -0
  1087. package/dist/web/markdown-page.js.map +1 -0
  1088. package/dist/web/markdown-representation.d.ts +15 -0
  1089. package/dist/web/markdown-representation.d.ts.map +1 -0
  1090. package/dist/web/markdown-representation.js +130 -0
  1091. package/dist/web/markdown-representation.js.map +1 -0
  1092. package/dist/web/negotiate.d.ts +5 -12
  1093. package/dist/web/negotiate.d.ts.map +1 -1
  1094. package/dist/web/negotiate.js +11 -18
  1095. package/dist/web/negotiate.js.map +1 -1
  1096. package/dist/{notifications/routes.d.ts → web/notification-routes.d.ts} +2 -2
  1097. package/dist/web/notification-routes.d.ts.map +1 -0
  1098. package/dist/{notifications/routes.js → web/notification-routes.js} +24 -29
  1099. package/dist/web/notification-routes.js.map +1 -0
  1100. package/dist/web/oembed.d.ts +2 -2
  1101. package/dist/web/oembed.d.ts.map +1 -1
  1102. package/dist/web/oembed.js +5 -4
  1103. package/dist/web/oembed.js.map +1 -1
  1104. package/dist/web/opensearch.d.ts.map +1 -1
  1105. package/dist/web/opensearch.js +2 -1
  1106. package/dist/web/opensearch.js.map +1 -1
  1107. package/dist/web/page-sources.d.ts +15 -0
  1108. package/dist/web/page-sources.d.ts.map +1 -0
  1109. package/dist/web/page-sources.js +44 -0
  1110. package/dist/web/page-sources.js.map +1 -0
  1111. package/dist/web/pagination.d.ts +1 -0
  1112. package/dist/web/pagination.d.ts.map +1 -1
  1113. package/dist/web/pagination.js +4 -1
  1114. package/dist/web/pagination.js.map +1 -1
  1115. package/dist/web/paths.d.ts +52 -0
  1116. package/dist/web/paths.d.ts.map +1 -0
  1117. package/dist/web/paths.js +208 -0
  1118. package/dist/web/paths.js.map +1 -0
  1119. package/dist/web/pingback-routes.d.ts +5 -0
  1120. package/dist/web/pingback-routes.d.ts.map +1 -0
  1121. package/dist/web/pingback-routes.js +100 -0
  1122. package/dist/web/pingback-routes.js.map +1 -0
  1123. package/dist/{plugins/federation.d.ts → web/plugin-federation.d.ts} +3 -3
  1124. package/dist/web/plugin-federation.d.ts.map +1 -0
  1125. package/dist/{plugins/federation.js → web/plugin-federation.js} +5 -5
  1126. package/dist/web/plugin-federation.js.map +1 -0
  1127. package/dist/{plugins/mount.d.ts → web/plugin-routes.d.ts} +3 -3
  1128. package/dist/web/plugin-routes.d.ts.map +1 -0
  1129. package/dist/{plugins/mount.js → web/plugin-routes.js} +2 -2
  1130. package/dist/web/plugin-routes.js.map +1 -0
  1131. package/dist/web/redirects.d.ts +1 -84
  1132. package/dist/web/redirects.d.ts.map +1 -1
  1133. package/dist/web/redirects.js +0 -232
  1134. package/dist/web/redirects.js.map +1 -1
  1135. package/dist/web/render.d.ts +43 -7
  1136. package/dist/web/render.d.ts.map +1 -1
  1137. package/dist/web/render.js +96 -48
  1138. package/dist/web/render.js.map +1 -1
  1139. package/dist/web/request.d.ts +44 -0
  1140. package/dist/web/request.d.ts.map +1 -0
  1141. package/dist/web/request.js +82 -0
  1142. package/dist/web/request.js.map +1 -0
  1143. package/dist/web/robots.d.ts +1 -46
  1144. package/dist/web/robots.d.ts.map +1 -1
  1145. package/dist/web/robots.js +5 -131
  1146. package/dist/web/robots.js.map +1 -1
  1147. package/dist/web/routes.d.ts +5 -39
  1148. package/dist/web/routes.d.ts.map +1 -1
  1149. package/dist/web/routes.js +112 -1373
  1150. package/dist/web/routes.js.map +1 -1
  1151. package/dist/web/search.d.ts.map +1 -1
  1152. package/dist/web/search.js +2 -9
  1153. package/dist/web/search.js.map +1 -1
  1154. package/dist/{admin → web}/session.d.ts +1 -5
  1155. package/dist/web/session.d.ts.map +1 -0
  1156. package/dist/{admin → web}/session.js +0 -4
  1157. package/dist/web/session.js.map +1 -0
  1158. package/dist/web/share-image.d.ts.map +1 -1
  1159. package/dist/web/share-image.js +3 -2
  1160. package/dist/web/share-image.js.map +1 -1
  1161. package/dist/web/signed-in.d.ts +27 -0
  1162. package/dist/web/signed-in.d.ts.map +1 -0
  1163. package/dist/web/signed-in.js +45 -0
  1164. package/dist/web/signed-in.js.map +1 -0
  1165. package/dist/web/site-index.d.ts +13 -0
  1166. package/dist/web/site-index.d.ts.map +1 -0
  1167. package/dist/web/site-index.js +143 -0
  1168. package/dist/web/site-index.js.map +1 -0
  1169. package/dist/web/site-view.d.ts +45 -0
  1170. package/dist/web/site-view.d.ts.map +1 -0
  1171. package/dist/web/site-view.js +67 -0
  1172. package/dist/web/site-view.js.map +1 -0
  1173. package/dist/web/sitemap.d.ts.map +1 -1
  1174. package/dist/web/sitemap.js +5 -7
  1175. package/dist/web/sitemap.js.map +1 -1
  1176. package/dist/{admin → web}/throttle.d.ts +3 -4
  1177. package/dist/web/throttle.d.ts.map +1 -0
  1178. package/dist/{admin → web}/throttle.js +1 -2
  1179. package/dist/web/throttle.js.map +1 -0
  1180. package/dist/web/webmention-routes.d.ts +11 -0
  1181. package/dist/web/webmention-routes.d.ts.map +1 -0
  1182. package/dist/web/webmention-routes.js +51 -0
  1183. package/dist/web/webmention-routes.js.map +1 -0
  1184. package/dist/web/well-known.d.ts +2 -2
  1185. package/dist/web/well-known.d.ts.map +1 -1
  1186. package/dist/web/well-known.js +5 -14
  1187. package/dist/web/well-known.js.map +1 -1
  1188. package/dist/webmention/cited-picture.d.ts +1 -2
  1189. package/dist/webmention/cited-picture.d.ts.map +1 -1
  1190. package/dist/webmention/cited-picture.js +4 -6
  1191. package/dist/webmention/cited-picture.js.map +1 -1
  1192. package/dist/webmention/discovery.d.ts +2 -13
  1193. package/dist/webmention/discovery.d.ts.map +1 -1
  1194. package/dist/webmention/discovery.js +18 -73
  1195. package/dist/webmention/discovery.js.map +1 -1
  1196. package/dist/webmention/endpoint.d.ts +27 -0
  1197. package/dist/webmention/endpoint.d.ts.map +1 -0
  1198. package/dist/webmention/endpoint.js +26 -0
  1199. package/dist/webmention/endpoint.js.map +1 -0
  1200. package/dist/webmention/fetch-public.d.ts +18 -1
  1201. package/dist/webmention/fetch-public.d.ts.map +1 -1
  1202. package/dist/webmention/fetch-public.js +57 -23
  1203. package/dist/webmention/fetch-public.js.map +1 -1
  1204. package/dist/webmention/index.d.ts +11 -9
  1205. package/dist/webmention/index.d.ts.map +1 -1
  1206. package/dist/webmention/index.js +7 -6
  1207. package/dist/webmention/index.js.map +1 -1
  1208. package/dist/webmention/links.d.ts +0 -55
  1209. package/dist/webmention/links.d.ts.map +1 -1
  1210. package/dist/webmention/links.js +2 -185
  1211. package/dist/webmention/links.js.map +1 -1
  1212. package/dist/webmention/microformats.d.ts +1 -1
  1213. package/dist/webmention/microformats.d.ts.map +1 -1
  1214. package/dist/webmention/microformats.js +1 -1
  1215. package/dist/webmention/microformats.js.map +1 -1
  1216. package/dist/webmention/pingback.d.ts +12 -4
  1217. package/dist/webmention/pingback.d.ts.map +1 -1
  1218. package/dist/webmention/pingback.js +4 -102
  1219. package/dist/webmention/pingback.js.map +1 -1
  1220. package/dist/webmention/receive.d.ts +7 -4
  1221. package/dist/webmention/receive.d.ts.map +1 -1
  1222. package/dist/webmention/receive.js +34 -42
  1223. package/dist/webmention/receive.js.map +1 -1
  1224. package/dist/webmention/reply-context/fediverse.d.ts +29 -0
  1225. package/dist/webmention/reply-context/fediverse.d.ts.map +1 -0
  1226. package/dist/webmention/reply-context/fediverse.js +59 -0
  1227. package/dist/webmention/reply-context/fediverse.js.map +1 -0
  1228. package/dist/webmention/reply-context/json-ld.d.ts +5 -0
  1229. package/dist/webmention/reply-context/json-ld.d.ts.map +1 -0
  1230. package/dist/webmention/reply-context/json-ld.js +78 -0
  1231. package/dist/webmention/reply-context/json-ld.js.map +1 -0
  1232. package/dist/webmention/reply-context/oembed.d.ts +21 -0
  1233. package/dist/webmention/reply-context/oembed.d.ts.map +1 -0
  1234. package/dist/webmention/reply-context/oembed.js +137 -0
  1235. package/dist/webmention/reply-context/oembed.js.map +1 -0
  1236. package/dist/webmention/reply-context/page.d.ts +30 -0
  1237. package/dist/webmention/reply-context/page.d.ts.map +1 -0
  1238. package/dist/webmention/reply-context/page.js +134 -0
  1239. package/dist/webmention/reply-context/page.js.map +1 -0
  1240. package/dist/webmention/reply-context/source.d.ts +29 -0
  1241. package/dist/webmention/reply-context/source.d.ts.map +1 -0
  1242. package/dist/webmention/reply-context/source.js +46 -0
  1243. package/dist/webmention/reply-context/source.js.map +1 -0
  1244. package/dist/webmention/reply-context.d.ts +5 -34
  1245. package/dist/webmention/reply-context.d.ts.map +1 -1
  1246. package/dist/webmention/reply-context.js +9 -432
  1247. package/dist/webmention/reply-context.js.map +1 -1
  1248. package/dist/webmention/reply-contexts.d.ts +3 -3
  1249. package/dist/webmention/reply-contexts.d.ts.map +1 -1
  1250. package/dist/webmention/reply-contexts.js +7 -10
  1251. package/dist/webmention/reply-contexts.js.map +1 -1
  1252. package/dist/webmention/routes.d.ts +1 -1
  1253. package/dist/webmention/routes.d.ts.map +1 -1
  1254. package/dist/webmention/routes.js +5 -8
  1255. package/dist/webmention/routes.js.map +1 -1
  1256. package/dist/webmention/service.d.ts +7 -7
  1257. package/dist/webmention/service.d.ts.map +1 -1
  1258. package/dist/webmention/service.js +49 -61
  1259. package/dist/webmention/service.js.map +1 -1
  1260. package/dist/webmention/syndication.d.ts +3 -26
  1261. package/dist/webmention/syndication.d.ts.map +1 -1
  1262. package/dist/webmention/syndication.js +6 -20
  1263. package/dist/webmention/syndication.js.map +1 -1
  1264. package/package.json +5 -1
  1265. package/themes/default/README.md +36 -2329
  1266. package/themes/default/layouts/base.njk +5 -4
  1267. package/themes/default/layouts/comment.njk +3 -3
  1268. package/themes/default/layouts/front-page.njk +4 -3
  1269. package/themes/default/layouts/page.njk +2 -0
  1270. package/themes/default/partials/comment-form.njk +1 -1
  1271. package/themes/default/partials/comment.njk +5 -5
  1272. package/themes/default/partials/contact-form.njk +1 -2
  1273. package/themes/default/partials/conversation.njk +1 -2
  1274. package/themes/default/partials/markdown-footer.md.njk +24 -0
  1275. package/themes/default/partials/markdown-header.md.njk +31 -0
  1276. package/themes/default/src/style.css +6 -6
  1277. package/dist/admin/accounts.d.ts.map +0 -1
  1278. package/dist/admin/accounts.js.map +0 -1
  1279. package/dist/admin/admin-theme.d.ts.map +0 -1
  1280. package/dist/admin/admin-theme.js.map +0 -1
  1281. package/dist/admin/enclosure-field.d.ts.map +0 -1
  1282. package/dist/admin/enclosure-field.js.map +0 -1
  1283. package/dist/admin/event-field.d.ts.map +0 -1
  1284. package/dist/admin/event-field.js.map +0 -1
  1285. package/dist/admin/location-field.d.ts +0 -27
  1286. package/dist/admin/location-field.d.ts.map +0 -1
  1287. package/dist/admin/location-field.js.map +0 -1
  1288. package/dist/admin/passwords.d.ts.map +0 -1
  1289. package/dist/admin/passwords.js.map +0 -1
  1290. package/dist/admin/photo-field.d.ts +0 -38
  1291. package/dist/admin/photo-field.d.ts.map +0 -1
  1292. package/dist/admin/photo-field.js.map +0 -1
  1293. package/dist/admin/read-field.d.ts.map +0 -1
  1294. package/dist/admin/read-field.js +0 -61
  1295. package/dist/admin/read-field.js.map +0 -1
  1296. package/dist/admin/session.d.ts.map +0 -1
  1297. package/dist/admin/session.js.map +0 -1
  1298. package/dist/admin/store.d.ts +0 -998
  1299. package/dist/admin/store.d.ts.map +0 -1
  1300. package/dist/admin/store.js +0 -1588
  1301. package/dist/admin/store.js.map +0 -1
  1302. package/dist/admin/throttle.d.ts.map +0 -1
  1303. package/dist/admin/throttle.js.map +0 -1
  1304. package/dist/avatars/routes.d.ts.map +0 -1
  1305. package/dist/avatars/routes.js.map +0 -1
  1306. package/dist/contact/routes.d.ts.map +0 -1
  1307. package/dist/contact/routes.js.map +0 -1
  1308. package/dist/env.d.ts.map +0 -1
  1309. package/dist/env.js.map +0 -1
  1310. package/dist/federation/replies.d.ts.map +0 -1
  1311. package/dist/federation/replies.js.map +0 -1
  1312. package/dist/images/alt-text.d.ts.map +0 -1
  1313. package/dist/images/alt-text.js.map +0 -1
  1314. package/dist/indieauth/activity-log.d.ts.map +0 -1
  1315. package/dist/indieauth/activity-log.js.map +0 -1
  1316. package/dist/indieauth/app-activity.d.ts.map +0 -1
  1317. package/dist/indieauth/app-activity.js.map +0 -1
  1318. package/dist/indieauth/bearer.d.ts.map +0 -1
  1319. package/dist/indieauth/bearer.js.map +0 -1
  1320. package/dist/indieauth/client-id.d.ts.map +0 -1
  1321. package/dist/indieauth/client-id.js.map +0 -1
  1322. package/dist/indieauth/connected-apps.d.ts.map +0 -1
  1323. package/dist/indieauth/connected-apps.js.map +0 -1
  1324. package/dist/indieauth/consent.d.ts.map +0 -1
  1325. package/dist/indieauth/consent.js.map +0 -1
  1326. package/dist/indieauth/discovery.d.ts.map +0 -1
  1327. package/dist/indieauth/discovery.js.map +0 -1
  1328. package/dist/indieauth/token.d.ts.map +0 -1
  1329. package/dist/indieauth/token.js.map +0 -1
  1330. package/dist/mail/service.d.ts.map +0 -1
  1331. package/dist/mail/service.js.map +0 -1
  1332. package/dist/mail/templates.d.ts.map +0 -1
  1333. package/dist/mail/templates.js.map +0 -1
  1334. package/dist/notifications/preferences.d.ts.map +0 -1
  1335. package/dist/notifications/preferences.js.map +0 -1
  1336. package/dist/notifications/routes.d.ts.map +0 -1
  1337. package/dist/notifications/routes.js.map +0 -1
  1338. package/dist/plugins/federation.d.ts.map +0 -1
  1339. package/dist/plugins/federation.js.map +0 -1
  1340. package/dist/plugins/mount.d.ts.map +0 -1
  1341. package/dist/plugins/mount.js.map +0 -1
  1342. package/dist/privacy/policy.d.ts.map +0 -1
  1343. package/dist/privacy/policy.js.map +0 -1
  1344. package/dist/web/admin-bar.d.ts.map +0 -1
  1345. package/dist/web/admin-bar.js.map +0 -1
  1346. package/dist/web/assets.d.ts.map +0 -1
  1347. package/dist/web/assets.js.map +0 -1
  1348. package/dist/web/authors.d.ts.map +0 -1
  1349. package/dist/web/authors.js +0 -211
  1350. package/dist/web/authors.js.map +0 -1
  1351. package/dist/web/documents.d.ts +0 -81
  1352. package/dist/web/documents.d.ts.map +0 -1
  1353. package/dist/web/documents.js.map +0 -1
  1354. package/dist/web/errors.d.ts.map +0 -1
  1355. package/dist/web/errors.js.map +0 -1
  1356. package/dist/web/guids.d.ts.map +0 -1
  1357. package/dist/web/guids.js.map +0 -1
  1358. package/dist/web/indexnow.d.ts.map +0 -1
  1359. package/dist/web/indexnow.js.map +0 -1
  1360. package/dist/web/license.d.ts.map +0 -1
  1361. package/dist/web/license.js.map +0 -1
  1362. package/dist/web/locale.d.ts.map +0 -1
  1363. package/dist/web/locale.js.map +0 -1
  1364. package/dist/web/navigation.d.ts.map +0 -1
  1365. package/dist/web/navigation.js.map +0 -1
  1366. package/dist/web/recent.d.ts +0 -43
  1367. package/dist/web/recent.d.ts.map +0 -1
  1368. package/dist/web/recent.js +0 -37
  1369. package/dist/web/recent.js.map +0 -1
  1370. package/dist/web/sanitize.d.ts +0 -29
  1371. package/dist/web/sanitize.d.ts.map +0 -1
  1372. package/dist/web/sanitize.js.map +0 -1
  1373. package/dist/web/taxonomy.d.ts.map +0 -1
  1374. package/dist/web/taxonomy.js.map +0 -1
  1375. package/dist/web/templates.d.ts.map +0 -1
  1376. package/dist/web/templates.js.map +0 -1
  1377. package/dist/web/themes.d.ts.map +0 -1
  1378. package/dist/web/themes.js.map +0 -1
  1379. package/dist/webmention/html.d.ts.map +0 -1
  1380. package/dist/webmention/html.js.map +0 -1
  1381. package/dist/webmention/public-address.d.ts.map +0 -1
  1382. package/dist/webmention/public-address.js.map +0 -1
  1383. /package/dist/{web → content}/license.d.ts +0 -0
  1384. /package/dist/{web → content}/license.js +0 -0
  1385. /package/dist/{admin → site}/admin-theme.d.ts +0 -0
  1386. /package/dist/{admin → site}/admin-theme.js +0 -0
  1387. /package/dist/{admin → site}/passwords.d.ts +0 -0
  1388. /package/dist/{admin → site}/passwords.js +0 -0
  1389. /package/dist/{indieauth → util}/client-id.d.ts +0 -0
  1390. /package/dist/{indieauth → util}/client-id.js +0 -0
  1391. /package/dist/{webmention → util}/public-address.d.ts +0 -0
  1392. /package/dist/{webmention → util}/public-address.js +0 -0
  1393. /package/dist/{env.js → web/env.js} +0 -0
@@ -1,70 +1,54 @@
1
- import { existsSync } from 'node:fs';
2
- import { access, mkdir, readFile, rename, rm } from 'node:fs/promises';
3
- import path from 'node:path';
4
- import { CITATION_PROPERTIES, citationText, CITED_ALT_FRONT_MATTER_KEY, citedHost, citesAnImage, PREVIEW_FRONT_MATTER_KEY, previewShown, } from '../content/citation.js';
5
- import { handleDirectory } from '../content/handles.js';
6
- import { renderMarkdown } from '../content/markdown.js';
7
- import { parseDocument } from '../content/parser.js';
8
- import { PINNED_FRONT_MATTER_KEY, PINNED_POST_LIMIT, pinnedAt } from '../content/pinned.js';
9
- import { discoverPostType, postLabel, replyTarget } from '../content/post-type.js';
10
- import { isReadStatus, READ_OF_FRONT_MATTER_KEY, READ_STATUS_FRONT_MATTER_KEY, READ_STATUS_LABELS, READ_STATUSES, readWork, readWorkFrontMatter, } from '../content/read.js';
11
- import { respellTags } from '../content/tags.js';
12
- import { RSVP_FRONT_MATTER_KEY, RSVP_LABELS, RSVP_VALUES, rsvpValue } from '../content/rsvp.js';
13
- import { ENCLOSURE_FRONT_MATTER_KEY, enclosureOf, isWebUrl, TRANSCRIPT_TYPES, } from '../content/enclosure.js';
14
- import { PHOTO_FRONT_MATTER_KEY, photoFrontMatter } from '../content/photo.js';
15
- import { keptProperties } from '../content/kept-properties.js';
1
+ import { CITATION_PROPERTIES, citedHost, citesAnImage, shownInFull } from '../content/citation.js';
2
+ import { AUTHOR_UNTIL_REQUEST, blankForm, CITATION_FIELDS, COMMENT_SETTINGS, extraFromForm, formFor, formInReplyTo, postFieldsForm, splitTags, } from '../content/document-form.js';
3
+ import { PAGE_KIND, POST_KIND } from '../content/document-kind.js';
4
+ import { TRANSCRIPT_TYPES } from '../content/enclosure.js';
5
+ import { ENCLOSURE_FIELDS } from '../content/enclosure-form.js';
6
+ import { EVENT_FIELDS } from '../content/event-form.js';
7
+ import { BLANK_LOCATION_FORM } from '../content/location-form.js';
16
8
  import { postLocations } from '../content/locations.js';
17
- import { contentFilePath, freeSlug, saveDocument } from '../content/save.js';
9
+ import { PHOTO_FIELDS } from '../content/photo-form.js';
10
+ import { syndicateToField } from '../content/post-fields.js';
11
+ import { postLabel } from '../content/post-type.js';
12
+ import { isReadStatus, READ_STATUS_LABELS, READ_STATUSES } from '../content/read.js';
13
+ import { READ_FIELDS } from '../content/read-form.js';
14
+ import { RSVP_LABELS, RSVP_VALUES, rsvpValue } from '../content/rsvp.js';
18
15
  import { scheduledFor } from '../content/schedule.js';
19
- import { htmlToText } from '../content/search.js';
20
- import { defaultPermalink, slugify } from '../content/slug.js';
21
- import { DuplicatePermalinkError, isTrashedPath, TRASH_DIRECTORY } from '../content/store.js';
22
- import { calendarDayIn, DEFAULT_TIMEZONE, toUtcInstant, wallClockIn, zoneLabel, } from '../content/time.js';
23
- import { isVisibility, VISIBILITY_FRONT_MATTER_KEY, visibilityOf } from '../content/visibility.js';
16
+ import { isTrashedPath } from '../content/store.js';
17
+ import { zoneLabel } from '../content/time.js';
18
+ import { moveDocumentFile } from '../content/trash.js';
19
+ import { isVisibility, visibilityOf } from '../content/visibility.js';
20
+ import { missingAltText, writeDocument } from '../content/write.js';
21
+ import { currentUsername, documentSite } from '../web/document-site.js';
24
22
  import { normalizeBody, serializeDocument } from '../content/writer.js';
25
- import { readAltTexts, undescribedImages, undescribedPhotos } from '../images/alt-text.js';
26
- import { isServed } from '../web/documents.js';
27
- import { LANG_FRONT_MATTER_KEY } from '../web/locale.js';
28
- import { absoluteUrl } from '../web/negotiate.js';
29
- import { COMMENTS_FRONT_MATTER_KEY } from '../comments/policy.js';
30
- import { commentsFile } from '../comments/records.js';
31
- import { CONTACT_FRONT_MATTER_KEY } from '../contact/form.js';
32
- import { authorNames, userForAuthor } from '../web/authors.js';
33
- import { findUserById, listUsers } from './accounts.js';
23
+ import { readAltTexts } from '../content/alt-text.js';
24
+ import { readSiteSettings } from '../site/site-json.js';
25
+ import { listUsers } from '../site/users.js';
26
+ import { stringOrEmpty } from '../util/forms.js';
27
+ import { userForAuthor } from '../content/authors.js';
28
+ import { isServed } from '../content/served.js';
29
+ import { syndicationTargetsReader } from '../webmention/syndication.js';
34
30
  import { editorActionViews } from './editor-actions.js';
31
+ import { BLANK_ALTERNATE_ROW, enclosureChoices, LOCATION_FIELDS, photoChoices, photoRowViews, readLocationForm, } from './editor-fields.js';
32
+ import { openGroups } from './editor-layout.js';
35
33
  import { flash } from './flash.js';
36
34
  import { formatInTimezone } from './formatting.js';
37
- import { LANGUAGE_TAG_PATTERN, readSiteSettings } from './settings.js';
35
+ import { allowGeolocation } from './headers.js';
38
36
  import { PREVIEW_PATH } from './preview.js';
39
- import { ADMIN_PREFIX } from './session.js';
37
+ import { ADMIN_PREFIX } from '../site/admin-paths.js';
40
38
  import { ADMIN_TEMPLATES } from './templates.js';
41
39
  import { UPLOADS_PATH } from './uploads.js';
42
- import { BLANK_ALTERNATE_ROW, BLANK_ENCLOSURE_FORM, ENCLOSURE_FIELDS, enclosureChoices, enclosureForm, enclosureFrontMatter, readEnclosureForm, resolveEnclosure, } from './enclosure-field.js';
43
- import { openGroups } from './editor-layout.js';
44
- import { allowGeolocation } from './headers.js';
45
- import { BLANK_LOCATION_FORM, LOCATION_FIELDS, locationForm, readLocationForm, resolveLocation, } from './location-field.js';
46
- import { PHOTO_FIELDS, photoChoices, photoRows, photoRowViews, readPhotoForm, resolvePhotos, } from './photo-field.js';
47
- import { BLANK_READ_OF_FORM, READ_FIELDS, readOfForm, resolveRead, submittedReadOfForm, } from './read-field.js';
48
- import { BLANK_EVENT_FORM, EVENT_FIELDS, eventForm, eventFrontMatter, resolveEvent, submittedEventForm, } from './event-field.js';
49
- import { eventOf } from '../content/event.js';
50
- import { SYNDICATE_TO_FRONT_MATTER_KEY, syndicateToOf, syndicationTargetsReader, } from '../webmention/syndication.js';
51
- import { shownInFull } from '../webmention/cited-picture.js';
52
- /**
53
- * The Eleventy key that keeps a document out of every collection.
54
- *
55
- * The CMS does not model it — it is not in `KNOWN_FRONT_MATTER_KEYS` — so the
56
- * parser leaves it in {@link Document.extra} and the editor reads and writes it
57
- * there, alongside every other key somebody added by hand.
58
- */
59
- export const EXCLUDE_KEY = 'eleventyExcludeFromCollections';
60
- /**
61
- * What the editor's Comments field can say: leave it to the site's rules, hold
62
- * this document open, or close it.
63
- *
64
- * The values are the strings the form submits and the template renders as
65
- * options, spelled once so the two cannot drift.
66
- */
67
- export const COMMENT_SETTINGS = { site: '', open: 'open', closed: 'closed' };
40
+ export const POST_SCREENS = {
41
+ ...POST_KIND,
42
+ section: 'posts',
43
+ basePath: `${ADMIN_PREFIX}/posts`,
44
+ plural: 'Posts',
45
+ };
46
+ export const PAGE_SCREENS = {
47
+ ...PAGE_KIND,
48
+ section: 'pages',
49
+ basePath: `${ADMIN_PREFIX}/pages`,
50
+ plural: 'Pages',
51
+ };
68
52
  /** A submitted Comments field, or the site default for anything else. */
69
53
  function commentSetting(value) {
70
54
  return value === COMMENT_SETTINGS.open || value === COMMENT_SETTINGS.closed
@@ -76,41 +60,6 @@ function formVisibility(value) {
76
60
  return 'public';
77
61
  return isVisibility(value) ? value : { unrecognized: value };
78
62
  }
79
- /** What a document's front matter already says about comments. */
80
- function commentSettingOf(document) {
81
- const own = document.extra[COMMENTS_FRONT_MATTER_KEY];
82
- if (own === true)
83
- return COMMENT_SETTINGS.open;
84
- if (own === false)
85
- return COMMENT_SETTINGS.closed;
86
- return COMMENT_SETTINGS.site;
87
- }
88
- /** The posts screens: dated, tagged, categorised, filed under `posts/`. */
89
- export const POST_KIND = {
90
- type: 'post',
91
- section: 'posts',
92
- basePath: `${ADMIN_PREFIX}/posts`,
93
- singular: 'post',
94
- plural: 'Posts',
95
- dated: true,
96
- tagged: true,
97
- categorised: true,
98
- excludable: false,
99
- contactable: false,
100
- };
101
- /** The pages screens: standing content, no date prefix and no taxonomy. */
102
- export const PAGE_KIND = {
103
- type: 'page',
104
- section: 'pages',
105
- basePath: `${ADMIN_PREFIX}/pages`,
106
- singular: 'page',
107
- plural: 'Pages',
108
- dated: false,
109
- tagged: false,
110
- categorised: false,
111
- excludable: true,
112
- contactable: true,
113
- };
114
63
  /** The URL of the editor for one document. */
115
64
  export function editorPath(kind, slug) {
116
65
  return `${kind.basePath}/${encodeURIComponent(slug)}`;
@@ -145,7 +94,7 @@ export const DOCUMENTS_PER_PAGE = 25;
145
94
  export function documentFilter(value) {
146
95
  return DOCUMENT_FILTERS.includes(value) ? value : 'all';
147
96
  }
148
- /** {@link ContentStore.listAll} options for one kind and one filter. */
97
+ /** {@link CatalogReader.listAll} options for one kind and one filter. */
149
98
  export function listOptionsFor(kind, filter) {
150
99
  return {
151
100
  type: kind.type,
@@ -159,7 +108,7 @@ export function listOptionsFor(kind, filter) {
159
108
  * Register the listing and the editor for one kind of document.
160
109
  *
161
110
  * Both `/admin/posts` and `/admin/pages` are this function with a different
162
- * {@link DocumentKind}: the screens, the templates and the write path are
111
+ * {@link DocumentScreens}: the screens, the templates and the write path are
163
112
  * shared, and the kind decides what a file is called, whether the form has a
164
113
  * date and a taxonomy, and which section of the navigation marks itself.
165
114
  */
@@ -213,7 +162,7 @@ export function mountDocumentScreens(app, options) {
213
162
  kind,
214
163
  render,
215
164
  document,
216
- form: formFor(document, siteTimezone(c), location),
165
+ form: formFor(kind, document, siteTimezone(c), location),
217
166
  });
218
167
  });
219
168
  app.post(`${kind.basePath}/:slug`, async (c) => {
@@ -221,9 +170,9 @@ export function mountDocumentScreens(app, options) {
221
170
  if (document === undefined)
222
171
  return c.notFound();
223
172
  const body = await c.req.parseBody();
224
- const action = text(body['action']);
173
+ const action = stringOrEmpty(body['action']);
225
174
  if (action === 'trash' || action === 'restore') {
226
- return moveDocument(c, { kind, document, action, returnTo: text(body['return']) });
175
+ return moveDocument(c, { kind, document, action, returnTo: stringOrEmpty(body['return']) });
227
176
  }
228
177
  return saveFromForm(c, { kind, render, document, body });
229
178
  });
@@ -233,40 +182,27 @@ export function mountDocumentScreens(app, options) {
233
182
  * and for an editor action.
234
183
  */
235
184
  export function submittedForm(kind, body, contentDir) {
185
+ const declared = syndicationTargetsReader(contentDir)();
236
186
  return {
237
- title: text(body['title']).trim(),
238
- slug: text(body['slug']).trim(),
239
- permalink: text(body['permalink']).trim(),
240
- date: text(body['date']).trim(),
241
- tags: text(body['tags']).trim(),
242
- categories: text(body['categories']).trim(),
243
- description: text(body['description']).trim(),
244
- author: text(body['author']).trim(),
245
- inReplyTo: text(body['in-reply-to']).trim(),
246
- rsvp: kind.type === 'post' ? text(body[RSVP_FRONT_MATTER_KEY]).trim() : '',
247
- ...citationFields((property) => (kind.type === 'post' ? text(body[property]).trim() : '')),
248
- readStatus: kind.type === 'post' ? text(body[READ_FIELDS.status]).trim() : '',
249
- readOf: kind.type === 'post' ? submittedReadOfForm(body) : BLANK_READ_OF_FORM,
250
- event: kind.type === 'post' ? submittedEventForm(body) : BLANK_EVENT_FORM,
251
- lang: text(body['lang']).trim(),
187
+ title: stringOrEmpty(body['title']).trim(),
188
+ slug: stringOrEmpty(body['slug']).trim(),
189
+ permalink: stringOrEmpty(body['permalink']).trim(),
190
+ date: stringOrEmpty(body['date']).trim(),
191
+ tags: stringOrEmpty(body['tags']).trim(),
192
+ categories: stringOrEmpty(body['categories']).trim(),
193
+ description: stringOrEmpty(body['description']).trim(),
194
+ author: stringOrEmpty(body['author']).trim(),
195
+ inReplyTo: stringOrEmpty(body['in-reply-to']).trim(),
196
+ ...postFieldsForm(kind, (field) => field.submitted(body, declared)),
197
+ lang: stringOrEmpty(body['lang']).trim(),
252
198
  draft: body['draft'] !== undefined,
253
- visibility: formVisibility(text(body['visibility'])),
199
+ visibility: formVisibility(stringOrEmpty(body['visibility'])),
254
200
  exclude: body['exclude'] !== undefined,
255
201
  contact: body['contact'] !== undefined,
256
- pinned: kind.type === 'post' && body['pinned'] !== undefined,
257
- previewHidden: kind.type === 'post' && body[PREVIEW_FRONT_MATTER_KEY] !== undefined,
258
- citedAlt: kind.type === 'post' ? text(body[CITED_ALT_FRONT_MATTER_KEY]).trim() : '',
259
- comments: commentSetting(text(body['comments'])),
260
- enclosure: kind.type === 'post' ? readEnclosureForm(body) : BLANK_ENCLOSURE_FORM,
261
- photos: kind.type === 'post' ? readPhotoForm(body) : [],
262
- location: kind.type === 'post' ? readLocationForm(body) : BLANK_LOCATION_FORM,
263
- syndicateTo: kind.type === 'post'
264
- ? syndicationTargetsReader(contentDir)()
265
- .filter((target) => body[syndicateToField(target)] !== undefined)
266
- .map((target) => target.id)
267
- : [],
268
- body: normalizeBody(text(body['body'])),
269
- hash: text(body['hash']),
202
+ comments: commentSetting(stringOrEmpty(body['comments'])),
203
+ location: kind.located ? readLocationForm(body) : BLANK_LOCATION_FORM,
204
+ body: normalizeBody(stringOrEmpty(body['body'])),
205
+ hash: stringOrEmpty(body['hash']),
270
206
  };
271
207
  }
272
208
  /**
@@ -279,7 +215,7 @@ async function saveFromForm(c, options) {
279
215
  const store = c.var.store;
280
216
  const contentDir = c.var.config.contentDir;
281
217
  const form = submittedForm(kind, body, contentDir);
282
- const action = text(body['action']);
218
+ const action = stringOrEmpty(body['action']);
283
219
  // The buttons doc-5 names are shortcuts past the checkbox: Save draft and
284
220
  // Publish say what they do, and Update leaves the decision to the checkbox.
285
221
  const draft = action === 'save-draft' ? true : action === 'publish' ? false : form.draft;
@@ -314,322 +250,6 @@ async function saveFromForm(c, options) {
314
250
  flash(c, 'warning', missingAltText(undescribed));
315
251
  return c.redirect(documentEditorPath(kind, saved), 303);
316
252
  }
317
- /**
318
- * The write path as one request reaches it, writing as `writer`: by default
319
- * whoever the admin session names.
320
- */
321
- export function documentSite(c, writer = currentUsername(c)) {
322
- return {
323
- store: c.var.store,
324
- config: c.var.config,
325
- announce: c.var.announce,
326
- writer,
327
- citedContext: (target) => c.var.replyContexts.describe(target),
328
- storedContext: (target) => c.var.replyContexts.read(target),
329
- learnHandles: c.var.learnHandles,
330
- };
331
- }
332
- /**
333
- * The write path behind the editor and Micropub (TASK-164): one form in, one
334
- * file out, announced to every subscriber.
335
- *
336
- * The order matters: the form is checked before anything is touched, the
337
- * on-disk file is re-hashed and compared with the hash the form loaded with
338
- * (doc-1's conflict rule), and only then is a file written. A write that is
339
- * refused leaves the content directory exactly as it was.
340
- */
341
- export async function writeDocument(site, write) {
342
- const { store, config, writer } = site;
343
- const { kind, document, form, draft } = write;
344
- const contentDir = config.contentDir;
345
- function refused(message, field) {
346
- return { outcome: 'refused', message, field };
347
- }
348
- // A post with no title is a note; a page is always named.
349
- if (form.title === '' && kind.type === 'page') {
350
- return refused(`A ${kind.singular} needs a title.`, 'editor-title');
351
- }
352
- // A post is a reply only when the target is a URL (Post Type Discovery), so
353
- // anything else would be saved as a reply that is not one.
354
- if (kind.type === 'post' && form.inReplyTo !== '' && replyTarget(form) === undefined) {
355
- return refused('In reply to has to be a web address, like https://example.com/a-post/.', 'editor-in-reply-to');
356
- }
357
- if (kind.type === 'post' && form.rsvp !== '') {
358
- if (rsvpValue(form.rsvp) === undefined) {
359
- return refused(`RSVP is ${RSVP_VALUES.join(', ')}, not ${form.rsvp}.`, 'editor-rsvp');
360
- }
361
- if (form.inReplyTo === '') {
362
- return refused('An RSVP answers an event. Put the event’s address in In reply to.', 'editor-in-reply-to');
363
- }
364
- }
365
- let read;
366
- if (kind.type === 'post') {
367
- for (const property of CITATION_PROPERTIES) {
368
- const cited = form[CITATION_FIELDS[property]];
369
- if (cited !== '' && !isWebUrl(cited)) {
370
- return refused(`${CITATION_LABELS[property]} has to be a web address, like https://example.com/a-post/.`, `editor-${property}`);
371
- }
372
- }
373
- const resolved = resolveRead(form.readStatus, form.readOf);
374
- if ('error' in resolved)
375
- return refused(resolved.error, resolved.field);
376
- read = resolved.read;
377
- }
378
- if (read !== undefined && form.description !== '') {
379
- return refused('A read is described by what it says, so it keeps no Description. Empty Description to save it.', 'editor-description');
380
- }
381
- if (form.lang !== '' && !LANGUAGE_TAG_PATTERN.test(form.lang)) {
382
- return refused('That is not a language tag, such as en, fr or pt-BR.', 'editor-lang');
383
- }
384
- let media = { recording: undefined, photos: [] };
385
- if (kind.type === 'post') {
386
- const resolved = resolveEnclosure(form.enclosure, document === undefined ? undefined : enclosureOf(document.extra), contentDir);
387
- if ('error' in resolved)
388
- return refused(resolved.error, resolved.field);
389
- const photos = resolvePhotos(form.photos, contentDir);
390
- if ('error' in photos)
391
- return refused(photos.error, photos.field);
392
- media = { recording: resolved.enclosure, photos: photos.photos };
393
- }
394
- let location;
395
- if (kind.type === 'post') {
396
- const resolved = resolveLocation(form.location);
397
- if ('error' in resolved)
398
- return refused(resolved.error, resolved.field);
399
- location = resolved.location;
400
- }
401
- // TASK-207: a pin is new when the file does not carry one yet, and only a
402
- // new one can take an author past Mastodon's limit.
403
- if (form.pinned && (document === undefined || pinnedAt(document) === undefined)) {
404
- const users = listUsers(config.dataDir);
405
- const author = userForAuthor(users, chosenAuthor(config.dataDir, form.author, document, writer) ?? '');
406
- const names = author === undefined ? [] : authorNames(users, author);
407
- if (store.listPinnedByAuthor(names).length >= PINNED_POST_LIMIT) {
408
- return refused(`You can pin up to ${String(PINNED_POST_LIMIT)} posts. Unpin one first.`, 'editor-pinned');
409
- }
410
- }
411
- // TASK-141: an image nobody described is a problem to fix before readers
412
- // meet it. A draft is not checked, since nobody meets a draft.
413
- // A photo counts too, unless the media library describes it (TASK-166).
414
- const library = readAltTexts(contentDir);
415
- const undescribed = draft
416
- ? []
417
- : [
418
- ...undescribedPhotos(media.photos, library),
419
- ...undescribedImages(renderMarkdown(form.body), library),
420
- ];
421
- if (undescribed.length > 0 && config.requireAltText) {
422
- return refused(`This site publishes no image without alt text. ${missingAltText(undescribed)}`);
423
- }
424
- if (!draft &&
425
- config.requireAltText &&
426
- kind.type === 'post' &&
427
- (await citesUndescribedImage(site, document, form))) {
428
- return refused('This site publishes no image without alt text. Describe the image this post reposts in its alt text field.', 'editor-cited-alt');
429
- }
430
- const timezone = readSiteSettings(contentDir).timezone;
431
- if (kind.type === 'post') {
432
- const resolved = resolveEvent(form.event, timezone);
433
- if ('error' in resolved)
434
- return refused(resolved.error, resolved.field);
435
- if (resolved.event !== undefined && form.title === '') {
436
- return refused('An event needs a name. Put it in Title.', 'editor-title');
437
- }
438
- }
439
- // decision-11: what the file gets is a UTC instant, and an offset-less field
440
- // is the site's own wall clock rather than the server's.
441
- const typed = kind.dated ? (form.date === '' ? store.now().toISOString() : form.date) : undefined;
442
- if (typed !== undefined && !/^\d{4}-\d{2}-\d{2}/.test(typed)) {
443
- return refused('A date has to start with a year, a month and a day, like 2026-03-04.', 'editor-date');
444
- }
445
- const date = typed === undefined ? undefined : toUtcInstant(typed, timezone);
446
- if (typed !== undefined && date === undefined) {
447
- return refused('That date is not one anybody can read. Try 2026-03-04 09:00.', 'editor-date');
448
- }
449
- const slug = slugify(form.slug) ||
450
- slugify(form.title) ||
451
- (document?.slug ?? '') ||
452
- noteSlug(form.body) ||
453
- slugify(form.readOf.name) ||
454
- (await typeSlug(kind, form, media.photos, site.citedContext)) ||
455
- 'untitled';
456
- const trashed = document !== undefined && isTrashedPath(document.path);
457
- // The calendar day the document is filed under: the site zone's day at its
458
- // date for a new one, and the day already in the filename for one whose date
459
- // has not moved, so a zone changed later never moves a URL that exists.
460
- const filed = filedDay({ date, document, timezone });
461
- // A new document gets out of the way of anything that already holds its
462
- // name; an existing one keeps the slug it was given.
463
- const finalSlug = document === undefined
464
- ? await freeSlug({ contentDir, store, type: kind.type, slug, date: filed })
465
- : slug;
466
- // A URL somebody has been shown only moves when the author asks it to, by
467
- // editing the slug or the permalink: correcting a date refiles the file and
468
- // leaves the URL where it was. An empty permalink field is a form that
469
- // carried none, not a request to move.
470
- const promised = promisedDocument(document, store.now(), contentDir);
471
- const submitted = normalizePermalink(form.permalink);
472
- const asked = promised !== undefined &&
473
- (finalSlug !== promised.slug || (submitted !== undefined && submitted !== promised.permalink));
474
- const permalink = promised !== undefined && !asked
475
- ? promised.permalink
476
- : resolvePermalink({
477
- kind,
478
- form,
479
- slug: finalSlug,
480
- date: filed,
481
- document,
482
- timezone,
483
- });
484
- const target = documentPath({ kind, slug: finalSlug, date: filed, trashed });
485
- if (document !== undefined) {
486
- const conflict = await conflictWith(contentDir, document, form.hash);
487
- if (conflict !== undefined) {
488
- return { outcome: 'conflict', document, media, conflict };
489
- }
490
- }
491
- if (target !== document?.path && store.getByPath(target) !== undefined) {
492
- return refused(`Another ${kind.singular} already lives in ${target}.`, 'editor-slug');
493
- }
494
- const tags = respellTags(kind.tagged ? splitTags(form.tags) : [], (tag) => store.tagSpelling(tag, { excluding: document?.path }));
495
- const content = {
496
- title: form.title,
497
- ...(date === undefined ? {} : { date }),
498
- updated: store.now().toISOString(),
499
- permalink,
500
- ...optional('redirectFrom', formerPermalinks(document, promised, permalink)),
501
- tags: tags.tags,
502
- categories: kind.categorised ? splitTags(form.categories) : [],
503
- draft,
504
- ...(form.description === '' ? {} : { description: form.description }),
505
- ...optional('author', chosenAuthor(config.dataDir, form.author, document, writer)),
506
- ...optional('inReplyTo', replyTo(kind, form, document)),
507
- ...optional('activitypub', keptIdentity(document, promised, permalink, config.baseUrl)),
508
- extra: keptGuid(resolveExtra(kind, document, form, store.now(), media, syndicationTargetsReader(contentDir)(), timezone), promised, permalink, config.baseUrl),
509
- body: form.body,
510
- };
511
- // The row for the old path goes first: a rename briefly leaves two rows
512
- // claiming one permalink, and the index refuses that.
513
- const renamedFrom = document !== undefined && document.path !== target ? document : undefined;
514
- if (renamedFrom !== undefined)
515
- store.remove(renamedFrom.path);
516
- await site.learnHandles(content.body);
517
- let saved;
518
- try {
519
- saved = await saveDocument({ contentDir, store, path: target, content, timezone });
520
- }
521
- catch (error) {
522
- // Nothing was written, so the row that was taken out of the way goes back.
523
- if (renamedFrom !== undefined)
524
- store.upsert(renamedFrom);
525
- if (error instanceof DuplicatePermalinkError)
526
- return refused(error.message);
527
- throw error;
528
- }
529
- if (renamedFrom !== undefined) {
530
- await rm(path.join(contentDir, ...renamedFrom.path.split('/')), { force: true });
531
- }
532
- if (kind.type === 'post') {
533
- const locations = postLocations(config.dataDir);
534
- const kept = keptProperties(config.dataDir);
535
- if (document !== undefined && document.permalink !== saved.permalink) {
536
- await locations.move(document.permalink, saved.permalink);
537
- await kept.move(document.permalink, saved.permalink);
538
- }
539
- await locations.set(saved.permalink, location);
540
- if (write.keptProperties !== undefined) {
541
- await kept.set(saved.permalink, write.keptProperties);
542
- }
543
- }
544
- // Announced rather than left to the watcher: the index already holds what
545
- // was written, so the watcher's re-read is a no-op and nobody would ever
546
- // hear that this post was published. Awaited, so a subscriber that writes
547
- // back to the file — the federation stamping `activitypub` into a post it
548
- // has just announced — has finished before the editor is reloaded with a
549
- // hash that would otherwise be one save behind.
550
- await site.announce({
551
- type: document === undefined ? 'created' : 'updated',
552
- path: saved.path,
553
- previous: document,
554
- next: saved,
555
- origin: 'admin',
556
- });
557
- return { outcome: 'saved', saved, undescribed, respelled: tags.respelled };
558
- }
559
- async function citesUndescribedImage(site, document, form) {
560
- if (form.previewHidden || form.citedAlt !== '' || form.title !== '')
561
- return false;
562
- for (const property of CITATION_PROPERTIES) {
563
- const url = form[CITATION_FIELDS[property]];
564
- if (url === '' || !shownInFull(property, { kind: 'photo' }))
565
- continue;
566
- const context = document === undefined ? await site.citedContext(url) : site.storedContext(url);
567
- if (context !== undefined && citesAnImage(context))
568
- return true;
569
- }
570
- return false;
571
- }
572
- /** What a save says about the images it found with no alt text, naming each. */
573
- function missingAltText(images) {
574
- const names = images.map((image) => image.name).join(', ');
575
- const count = images.length === 1 ? '1 image has' : `${String(images.length)} images have`;
576
- return (`${count} no alt text: ${names}. Describe each one inside its ![…](…), ` +
577
- 'or mark an upload decorative in the media library.');
578
- }
579
- /** How many of an untitled post's first words its slug is made from. */
580
- const NOTE_SLUG_WORDS = 5;
581
- /** The slug a note takes from its first words, or empty when it has none. */
582
- function noteSlug(body) {
583
- const words = htmlToText(renderMarkdown(body)).split(' ').slice(0, NOTE_SLUG_WORDS);
584
- return slugify(words.join(' '));
585
- }
586
- const TARGET_SLUG_WORDS = 4;
587
- const CITED_SLUGS = {
588
- repost: { prefix: 'reposted', field: 'repostOf' },
589
- like: { prefix: 'liked', field: 'likeOf' },
590
- reply: { prefix: 'reply-to', field: 'inReplyTo' },
591
- rsvp: { prefix: 'rsvp', field: 'inReplyTo' },
592
- bookmark: { prefix: 'bookmarked', field: 'bookmarkOf' },
593
- };
594
- async function typeSlug(kind, form, photos, citedContext) {
595
- if (kind.type !== 'post')
596
- return '';
597
- const type = discoverPostType({
598
- 'repost-of': form.repostOf,
599
- 'like-of': form.likeOf,
600
- 'in-reply-to': form.inReplyTo,
601
- rsvp: form.rsvp,
602
- 'bookmark-of': form.bookmarkOf,
603
- photo: photos.map((photo) => photo.url),
604
- });
605
- if (type === 'photo')
606
- return slugWords(photos[0]?.alt ?? '', NOTE_SLUG_WORDS) || 'photo';
607
- const cited = CITED_SLUGS[type];
608
- if (cited === undefined)
609
- return '';
610
- const target = form[cited.field];
611
- const title = slugWords((await citedContext(target))?.name ?? '', NOTE_SLUG_WORDS);
612
- return `${cited.prefix}-${title || targetWords(target)}`;
613
- }
614
- function targetWords(address) {
615
- const url = new URL(address);
616
- const segments = url.pathname.split('/').map(decodedSegment).filter(holdsALetter);
617
- return slugWords([url.hostname.replace(/^www\./, ''), ...segments].join(' '), TARGET_SLUG_WORDS);
618
- }
619
- function slugWords(text, cap) {
620
- return slugify(text).split('-').slice(0, cap).join('-');
621
- }
622
- function holdsALetter(segment) {
623
- return /\p{L}/u.test(segment);
624
- }
625
- function decodedSegment(segment) {
626
- try {
627
- return decodeURIComponent(segment);
628
- }
629
- catch {
630
- return segment;
631
- }
632
- }
633
253
  function respelledMessage(respelled) {
634
254
  const pairs = respelled.map(({ given, site }) => `“${site}” for “${given}”`);
635
255
  const noun = respelled.length === 1 ? 'a tag' : `${String(respelled.length)} tags`;
@@ -649,338 +269,10 @@ function savedMessage(previous, saved, now, cited) {
649
269
  return `Published: ${label}`;
650
270
  return `Updated: ${label}`;
651
271
  }
652
- /** Where a document's file goes, trash included. */
653
- function documentPath(input) {
654
- const relative = contentFilePath({ type: input.kind.type, slug: input.slug, date: input.date });
655
- return input.trashed ? `${TRASH_DIRECTORY}/${relative}` : relative;
656
- }
657
- /**
658
- * The document whose URL has already been promised, or `undefined` when
659
- * nothing has been promised yet.
660
- *
661
- * A published post or page is at a URL readers, search engines and other
662
- * sites may hold, a post that was ever announced is at one its followers hold
663
- * even while it is a draft, and one with comments is at the URL they were
664
- * left on. A draft nobody was told about, a trashed document and one whose
665
- * date has not arrived have been shown to nobody, and may move without
666
- * leaving anything behind.
667
- */
668
- function promisedDocument(document, now, contentDir) {
669
- if (document === undefined)
670
- return undefined;
671
- const announced = document.activitypub?.published !== undefined;
672
- const answered = existsSync(commentsFile(contentDir, document.slug));
673
- return isServed(document, now) || announced || answered ? document : undefined;
674
- }
675
- /**
676
- * The URLs a document is saved as having lived at (TASK-127).
677
- *
678
- * Every entry names the document itself rather than the next hop, so a chain
679
- * of renames collapses by construction: the URL it is leaving joins the ones
680
- * it already left, and all of them redirect straight to where it is now. The
681
- * URL it is arriving at leaves the list, because a document moved back to an
682
- * old URL lives there again.
683
- */
684
- function formerPermalinks(document, promised, permalink) {
685
- const left = promised !== undefined && promised.permalink !== permalink ? [promised.permalink] : [];
686
- const former = [...new Set([...(document?.redirectFrom ?? []), ...left])].filter((url) => url !== permalink);
687
- return former.length === 0 ? undefined : former;
688
- }
689
- /**
690
- * The `activitypub` block to write, which pins the object id when a promised
691
- * post moves (decision-20).
692
- *
693
- * decision-13 makes a post's object id its permalink, and a fediverse server
694
- * cannot rename an object it holds. So the URL the post is leaving is written
695
- * as its stored id, and the stored-id path does the rest: a peer at the old
696
- * URL still gets the `Article`, a browser there is sent on, and every `Update`
697
- * names the id the followers already have. An id the file already stores
698
- * stays, since it is already what they hold.
699
- */
700
- function keptIdentity(document, promised, permalink, baseUrl) {
701
- const block = document?.activitypub;
702
- if (promised === undefined || promised.type !== 'post' || promised.permalink === permalink) {
703
- return block;
704
- }
705
- if (block?.id !== undefined)
706
- return block;
707
- return { ...block, id: absoluteUrl(promised.permalink, baseUrl) };
708
- }
709
- /**
710
- * The extra front matter to write, which pins the feed guid when a promised
711
- * page moves.
712
- *
713
- * A page has no object id, so its feed guid is its permalink (decision-12),
714
- * and the `/replies/` feed a reader subscribed to is keyed by that guid. The
715
- * URL the page is leaving is written as its stored `guid`, as a moved post's
716
- * is written as its `activitypub.id`.
717
- */
718
- function keptGuid(extra, promised, permalink, baseUrl) {
719
- if (promised === undefined || promised.type === 'post' || promised.permalink === permalink) {
720
- return extra;
721
- }
722
- if (extra['guid'] !== undefined)
723
- return extra;
724
- return { ...extra, guid: absoluteUrl(promised.permalink, baseUrl) };
725
- }
726
- /**
727
- * The permalink to write.
728
- *
729
- * A permalink is explicit in the file and the stored value is what counts
730
- * (doc-2), so one that was customised is never quietly rewritten. One that is
731
- * still the URL its old slug and date implied follows them to the new ones,
732
- * which is what makes renaming a slug in the editor do what it looks like it
733
- * does.
734
- */
735
- function resolvePermalink(input) {
736
- const fallback = defaultPermalink({
737
- type: input.kind.type,
738
- slug: input.slug,
739
- date: input.date,
740
- });
741
- const submitted = normalizePermalink(input.form.permalink);
742
- if (submitted === undefined)
743
- return fallback;
744
- const document = input.document;
745
- if (document !== undefined &&
746
- submitted === previousDefaultPermalink(input.kind, document, input.timezone)) {
747
- return fallback;
748
- }
749
- return submitted;
750
- }
751
- /**
752
- * The permalink a document would have had if it had never been customised:
753
- * its own slug over the day it is filed under, which is the day in its
754
- * filename rather than one re-derived from a setting that may have moved.
755
- */
756
- function previousDefaultPermalink(kind, document, timezone) {
757
- try {
758
- return defaultPermalink({
759
- type: kind.type,
760
- slug: document.slug,
761
- date: filedDay({ date: document.date, document, timezone }),
762
- });
763
- }
764
- catch {
765
- return undefined;
766
- }
767
- }
768
- /**
769
- * The calendar day a document is filed under, which is what its filename and
770
- * its `/{yyyy}/{mm}/` permalink are cut from.
771
- *
772
- * For a new document it is the day the site's own zone was on at its date, so
773
- * a post published at half past midnight on 1 October in Berlin is filed under
774
- * October rather than the September UTC was still on.
775
- *
776
- * For a document whose date has not moved it is the day already in its
777
- * filename. That is the whole of decision-11's promise that changing the
778
- * timezone setting cannot move an existing URL: the instant is the same, the
779
- * zone is a lens, and the day this post was filed under was decided once, when
780
- * it was written, and is on disk where no setting can reach it.
781
- */
782
- function filedDay(input) {
783
- const { document } = input;
784
- const date = input.date === undefined ? undefined : toUtcInstant(input.date, input.timezone);
785
- if (date === undefined)
786
- return undefined;
787
- const was = document?.date === undefined ? undefined : toUtcInstant(document.date, input.timezone);
788
- if (was === date) {
789
- const existing = /(?:^|\/)(\d{4}-\d{2}-\d{2})-/.exec(document?.path ?? '')?.[1];
790
- if (existing !== undefined)
791
- return existing;
792
- }
793
- return calendarDayIn(date, input.timezone) ?? date;
794
- }
795
272
  /** The site's time zone, which is what every offset-less date in the admin means. */
796
273
  function siteTimezone(c) {
797
274
  return readSiteSettings(c.var.config.contentDir).timezone;
798
275
  }
799
- /** A submitted permalink as a URL path, or `undefined` when the field is empty. */
800
- function normalizePermalink(value) {
801
- const trimmed = value.trim();
802
- if (trimmed === '')
803
- return undefined;
804
- const withLeading = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
805
- const last = withLeading.split('/').at(-1) ?? '';
806
- // `/feed.xml` is a file and keeps its name; everything else is a directory
807
- // and gets the trailing slash that is canonical here.
808
- if (last === '' || last.includes('.'))
809
- return withLeading;
810
- return `${withLeading}/`;
811
- }
812
- /**
813
- * The front matter to write that the CMS does not model.
814
- *
815
- * What the file already carried comes back out untouched, so a key somebody
816
- * added by hand survives every admin save (doc-2). The one such key the editor
817
- * has a field for is `eleventyExcludeFromCollections`: ticking the box writes
818
- * it, and clearing the box takes the key back out rather than leaving a
819
- * `false` behind — unless the file spelled the key out itself, in which case
820
- * the `false` is written, because a key somebody wrote by hand is not the
821
- * editor's to delete.
822
- */
823
- function resolveExtra(kind, document, form, now, media, declared, timezone) {
824
- const extra = { ...(document?.extra ?? {}) };
825
- if (kind.type === 'post') {
826
- if (media.recording === undefined)
827
- delete extra[ENCLOSURE_FRONT_MATTER_KEY];
828
- else
829
- extra[ENCLOSURE_FRONT_MATTER_KEY] = enclosureFrontMatter(media.recording);
830
- if (media.photos.length === 0)
831
- delete extra[PHOTO_FRONT_MATTER_KEY];
832
- else
833
- extra[PHOTO_FRONT_MATTER_KEY] = photoFrontMatter(media.photos);
834
- for (const property of CITATION_PROPERTIES) {
835
- const cited = form[CITATION_FIELDS[property]];
836
- if (cited === '')
837
- delete extra[property];
838
- else
839
- extra[property] = cited;
840
- }
841
- const rsvp = rsvpValue(form.rsvp);
842
- if (rsvp === undefined)
843
- delete extra[RSVP_FRONT_MATTER_KEY];
844
- else
845
- extra[RSVP_FRONT_MATTER_KEY] = rsvp;
846
- const event = resolveEvent(form.event, timezone);
847
- if ('event' in event && isOrWasEvent(event.event, document)) {
848
- for (const [key, value] of Object.entries(eventFrontMatter(event.event))) {
849
- if (value === undefined)
850
- delete extra[key];
851
- else
852
- extra[key] = value;
853
- }
854
- }
855
- if (form.previewHidden)
856
- extra[PREVIEW_FRONT_MATTER_KEY] = false;
857
- else
858
- delete extra[PREVIEW_FRONT_MATTER_KEY];
859
- if (form.citedAlt === '')
860
- delete extra[CITED_ALT_FRONT_MATTER_KEY];
861
- else
862
- extra[CITED_ALT_FRONT_MATTER_KEY] = form.citedAlt;
863
- const resolved = resolveRead(form.readStatus, form.readOf);
864
- if ('read' in resolved) {
865
- const { read } = resolved;
866
- if (read === undefined) {
867
- delete extra[READ_OF_FRONT_MATTER_KEY];
868
- delete extra[READ_STATUS_FRONT_MATTER_KEY];
869
- }
870
- else {
871
- extra[READ_OF_FRONT_MATTER_KEY] = readWorkFrontMatter(read.of);
872
- extra[READ_STATUS_FRONT_MATTER_KEY] = read.status;
873
- }
874
- }
875
- }
876
- // The checkboxes speak for the targets the site declares (TASK-155). An id
877
- // the file lists that names no declared target has no checkbox, so it is
878
- // kept as written rather than lost to a save.
879
- if (kind.type === 'post') {
880
- const offered = new Set(declared.map((target) => target.id));
881
- const kept = syndicateToOf(extra).filter((id) => !offered.has(id));
882
- // A form loaded from the file (a Micropub update) already holds those ids.
883
- const listed = [...new Set([...form.syndicateTo, ...kept])];
884
- if (listed.length === 0)
885
- delete extra[SYNDICATE_TO_FRONT_MATTER_KEY];
886
- else
887
- extra[SYNDICATE_TO_FRONT_MATTER_KEY] = listed;
888
- }
889
- // The moment a post was pinned is what orders the featured collection, so a
890
- // pin the file already carries keeps its moment through every later save,
891
- // and unpinning takes the key out rather than writing `false` (TASK-207).
892
- if (kind.type === 'post') {
893
- const pinned = document === undefined ? undefined : pinnedAt(document);
894
- if (!form.pinned)
895
- delete extra[PINNED_FRONT_MATTER_KEY];
896
- else if (pinned === undefined)
897
- extra[PINNED_FRONT_MATTER_KEY] = toUtcInstant(now, 'UTC');
898
- }
899
- if (form.visibility === 'public')
900
- delete extra[VISIBILITY_FRONT_MATTER_KEY];
901
- else if (typeof form.visibility === 'string')
902
- extra[VISIBILITY_FRONT_MATTER_KEY] = form.visibility;
903
- else
904
- extra[VISIBILITY_FRONT_MATTER_KEY] = form.visibility.unrecognized;
905
- // Empty is the site's language, which is the key's absence (TASK-154).
906
- if (form.lang === '')
907
- delete extra[LANG_FRONT_MATTER_KEY];
908
- else
909
- extra[LANG_FRONT_MATTER_KEY] = form.lang;
910
- // The post's own answer about comments, or none at all: "site default" is
911
- // the absence of the key rather than a value, because that is what every
912
- // reader of it — the CMS, an Eleventy build, a person looking at the file —
913
- // already understands, and writing `comments: null` would say nothing new.
914
- if (form.comments === COMMENT_SETTINGS.open)
915
- extra[COMMENTS_FRONT_MATTER_KEY] = true;
916
- else if (form.comments === COMMENT_SETTINGS.closed)
917
- extra[COMMENTS_FRONT_MATTER_KEY] = false;
918
- else
919
- delete extra[COMMENTS_FRONT_MATTER_KEY];
920
- if (kind.excludable) {
921
- if (form.exclude)
922
- extra[EXCLUDE_KEY] = true;
923
- else if (EXCLUDE_KEY in extra)
924
- extra[EXCLUDE_KEY] = false;
925
- }
926
- if (kind.contactable) {
927
- // Written or removed, never `false`: it is the CMS's own key, and absent
928
- // and false mean the same thing to everything that reads it (TASK-56).
929
- if (form.contact)
930
- extra[CONTACT_FRONT_MATTER_KEY] = true;
931
- else
932
- delete extra[CONTACT_FRONT_MATTER_KEY];
933
- }
934
- return extra;
935
- }
936
- function isOrWasEvent(saved, document) {
937
- return saved !== undefined || (document !== undefined && eventOf(document.extra) !== undefined);
938
- }
939
- /** The editor checkbox that selects one syndication target. */
940
- function syndicateToField(target) {
941
- return `${SYNDICATE_TO_FRONT_MATTER_KEY}-${target.id}`;
942
- }
943
- /**
944
- * A comma-separated taxonomy field as a list, without the blanks and the
945
- * repeats. Tags and categories are both entered this way.
946
- */
947
- export function splitTags(value) {
948
- const tags = [];
949
- for (const tag of value.split(',')) {
950
- const trimmed = tag.trim();
951
- if (trimmed !== '' && !tags.includes(trimmed))
952
- tags.push(trimmed);
953
- }
954
- return tags;
955
- }
956
- /** The signed-in user's login, which is what doc-2's `author` holds. */
957
- function currentUsername(c) {
958
- const userId = c.var.session?.userId;
959
- if (userId == null)
960
- return undefined;
961
- return findUserById(c.var.config.dataDir, userId)?.username;
962
- }
963
- /**
964
- * What a save writes into the front matter's `author`.
965
- *
966
- * The submitted value is resolved through the same rule the public site reads
967
- * it by ({@link userForAuthor}), and what is written is that user's login: so
968
- * a file carrying a display name from before decision-14 is rewritten as a
969
- * username the first time somebody saves it, which is exactly the "until it is
970
- * next saved" doc-2 promises.
971
- *
972
- * A value naming nobody this site has changes nothing. There is no form this
973
- * CMS renders that could submit one — the select only ever offers the users
974
- * and, for a file that names a stranger, that file's own value — so the case
975
- * is either a hand-made request or a user deleted between the load and the
976
- * save, and neither is a reason to reattribute somebody's post.
977
- */
978
- function chosenAuthor(dataDir, submitted, document, writer) {
979
- const named = userForAuthor(listUsers(dataDir), submitted);
980
- if (named !== undefined)
981
- return named.username;
982
- return document?.author ?? writer;
983
- }
984
276
  /**
985
277
  * The Author select: every user, whoever the document names, and — for a file
986
278
  * naming somebody with no account here — that name too.
@@ -997,7 +289,7 @@ function chosenAuthor(dataDir, submitted, document, writer) {
997
289
  export function authorChoices(c, current) {
998
290
  const users = listUsers(c.var.config.dataDir);
999
291
  const named = userForAuthor(users, current);
1000
- const chosen = named?.username ?? (current === '' ? currentUsername(c) : current);
292
+ const chosen = named?.username ?? (current === AUTHOR_UNTIL_REQUEST ? currentUsername(c) : current);
1001
293
  const choices = users.map((user) => ({
1002
294
  value: user.username,
1003
295
  label: authorLabel(user),
@@ -1005,7 +297,7 @@ export function authorChoices(c, current) {
1005
297
  }));
1006
298
  // A name the file holds that is nobody here: offered last, and marked, so it
1007
299
  // is plain that the post is attributed to somebody this site cannot reach.
1008
- if (named === undefined && current !== '') {
300
+ if (named === undefined && current !== AUTHOR_UNTIL_REQUEST) {
1009
301
  choices.push({ value: current, label: `${current} (no account here)`, chosen: true });
1010
302
  }
1011
303
  return choices;
@@ -1015,36 +307,6 @@ function authorLabel(user) {
1015
307
  const displayName = user.profile?.displayName;
1016
308
  return displayName === undefined ? user.username : `${displayName} (${user.username})`;
1017
309
  }
1018
- /**
1019
- * Whether the file has moved on since the form loaded, per doc-1: files win,
1020
- * and an edit made behind the editor's back is never silently overwritten.
1021
- *
1022
- * The file is read and re-parsed rather than trusted to the index, so the
1023
- * check is right even when the watcher is off or has not caught up.
1024
- */
1025
- async function conflictWith(contentDir, document, submittedHash) {
1026
- const file = path.join(contentDir, ...document.path.split('/'));
1027
- let source;
1028
- try {
1029
- source = await readFile(file, 'utf8');
1030
- }
1031
- catch {
1032
- // The file is gone. There is nothing to lose by writing it again.
1033
- return undefined;
1034
- }
1035
- let hash;
1036
- try {
1037
- hash = parseDocument(source, { path: document.path, type: document.type }).hash;
1038
- }
1039
- catch {
1040
- // A file that will not parse cannot be compared, and overwriting it would
1041
- // throw away whatever is wrong with it before anyone has seen it.
1042
- hash = '';
1043
- }
1044
- if (hash === submittedHash)
1045
- return undefined;
1046
- return { current: source, hash };
1047
- }
1048
310
  /**
1049
311
  * The refused save, side by side with the file it would have overwritten.
1050
312
  *
@@ -1054,6 +316,7 @@ async function conflictWith(contentDir, document, submittedHash) {
1054
316
  */
1055
317
  function renderConflict(c, options) {
1056
318
  const { kind, document, form, conflict } = options;
319
+ const inReplyTo = formInReplyTo(kind, form, document);
1057
320
  const submitted = serializeDocument({
1058
321
  title: form.title,
1059
322
  ...(form.date === '' ? {} : { date: form.date }),
@@ -1062,10 +325,10 @@ function renderConflict(c, options) {
1062
325
  categories: kind.categorised ? splitTags(form.categories) : [],
1063
326
  draft: form.draft,
1064
327
  ...(form.description === '' ? {} : { description: form.description }),
1065
- ...optional('author', document.author),
1066
- ...optional('inReplyTo', replyTo(kind, form, document)),
1067
- ...optional('activitypub', document.activitypub),
1068
- extra: resolveExtra(kind, document, form, c.var.store.now(), options.media, syndicationTargetsReader(c.var.config.contentDir)(), siteTimezone(c)),
328
+ ...(document.author === undefined ? {} : { author: document.author }),
329
+ ...(inReplyTo === undefined ? {} : { inReplyTo }),
330
+ ...(document.activitypub === undefined ? {} : { activitypub: document.activitypub }),
331
+ extra: extraFromForm(kind, document, form, c.var.store.now(), options.media, syndicationTargetsReader(c.var.config.contentDir)(), siteTimezone(c)),
1069
332
  body: form.body,
1070
333
  });
1071
334
  c.status(409);
@@ -1105,91 +368,6 @@ async function moveDocument(c, options) {
1105
368
  return c.redirect(returnPath(options.returnTo) ??
1106
369
  (action === 'trash' ? kind.basePath : documentEditorPath(kind, moved.document)), 303);
1107
370
  }
1108
- /**
1109
- * Move a document into `content/_trash/` or back out of it, the move behind
1110
- * the editor's trash and restore and Micropub's delete and undelete
1111
- * (TASK-167).
1112
- *
1113
- * The trash mirrors the content tree — `posts/2026-03-04-x.md` becomes
1114
- * `_trash/posts/2026-03-04-x.md` — so restoring is the same move backwards and
1115
- * needs to remember nothing. The index is corrected as soon as the file has
1116
- * landed rather than waiting for the watcher, so the public site stops or
1117
- * starts serving the document with this request (doc-1).
1118
- *
1119
- * A live document may take a trashed one's URL, and its file name with it
1120
- * (TASK-195). So a restore that would land on either is refused, and a trashed
1121
- * file already at the name is kept by numbering the newcomer: the permalink in
1122
- * the front matter, not the file name, is what the document answers at.
1123
- */
1124
- export async function moveDocumentFile(site, document, action) {
1125
- const { store, contentDir } = site;
1126
- let target;
1127
- if (action === 'trash') {
1128
- target = await freeTrashPath(contentDir, document.path);
1129
- }
1130
- else {
1131
- target = document.path
1132
- .split('/')
1133
- .filter((segment) => segment !== TRASH_DIRECTORY)
1134
- .join('/');
1135
- const holder = store.getByPermalink(document.permalink);
1136
- if (holder !== undefined && !isTrashedPath(holder.path)) {
1137
- return refusedMove(`${holder.path} now holds ${document.permalink}, so this cannot go back there. ` +
1138
- 'Change one of their permalinks first.');
1139
- }
1140
- if (await exists(path.join(contentDir, ...target.split('/')))) {
1141
- return refusedMove(`${target} already exists, so this cannot go back there.`);
1142
- }
1143
- }
1144
- const from = path.join(contentDir, ...document.path.split('/'));
1145
- const to = path.join(contentDir, ...target.split('/'));
1146
- let source;
1147
- try {
1148
- source = await readFile(from, 'utf8');
1149
- await mkdir(path.dirname(to), { recursive: true });
1150
- await rename(from, to);
1151
- }
1152
- catch {
1153
- return refusedMove(`Could not move ${document.path}. Is the file still there?`);
1154
- }
1155
- const moved = parseDocument(source, {
1156
- path: target,
1157
- type: document.type,
1158
- handles: handleDirectory(contentDir),
1159
- });
1160
- store.remove(document.path);
1161
- store.upsert(moved);
1162
- // Trashing takes a post off the public site and restoring puts it back, so
1163
- // both are visibility changes a subscriber has to hear about.
1164
- await site.announce({
1165
- type: 'updated',
1166
- path: target,
1167
- previous: document,
1168
- next: moved,
1169
- origin: 'admin',
1170
- });
1171
- return { outcome: 'moved', document: moved };
1172
- }
1173
- function refusedMove(reason) {
1174
- return { outcome: 'refused', reason };
1175
- }
1176
- async function freeTrashPath(contentDir, relative) {
1177
- const { dir, name, ext } = path.posix.parse(`${TRASH_DIRECTORY}/${relative}`);
1178
- for (let suffix = 1;; suffix += 1) {
1179
- const candidate = `${dir}/${name}${suffix === 1 ? '' : `-${String(suffix)}`}${ext}`;
1180
- if (!(await exists(path.join(contentDir, ...candidate.split('/')))))
1181
- return candidate;
1182
- }
1183
- }
1184
- async function exists(file) {
1185
- try {
1186
- await access(file);
1187
- return true;
1188
- }
1189
- catch {
1190
- return false;
1191
- }
1192
- }
1193
371
  /** Report a move that did not happen and go back where the form came from. */
1194
372
  function backTo(c, options, message) {
1195
373
  flash(c, 'error', message);
@@ -1209,142 +387,6 @@ export function returnPath(value) {
1209
387
  return undefined;
1210
388
  return trimmed;
1211
389
  }
1212
- function optional(key, value) {
1213
- return value === undefined ? {} : { [key]: value };
1214
- }
1215
- /** A form field as a string. A file upload, or a missing field, is the empty one. */
1216
- function text(value) {
1217
- return typeof value === 'string' ? value : '';
1218
- }
1219
- /**
1220
- * The `in-reply-to` a save writes: the field for a post, where an empty one
1221
- * clears it, and whatever the file had for a page, whose editor has no field.
1222
- */
1223
- function replyTo(kind, form, document) {
1224
- if (kind.type !== 'post')
1225
- return document?.inReplyTo;
1226
- return form.inReplyTo === '' ? undefined : form.inReplyTo;
1227
- }
1228
- /**
1229
- * The editor field each citing property fills (TASK-169). The form submits it
1230
- * under the property's own name, as `in-reply-to` is.
1231
- */
1232
- export const CITATION_FIELDS = {
1233
- 'repost-of': 'repostOf',
1234
- 'like-of': 'likeOf',
1235
- 'bookmark-of': 'bookmarkOf',
1236
- };
1237
- /** What the editor calls each citing field, which a refusal names. */
1238
- const CITATION_LABELS = {
1239
- 'repost-of': 'Repost of',
1240
- 'like-of': 'Like of',
1241
- 'bookmark-of': 'Bookmark of',
1242
- };
1243
- /** The three citing fields, each filled from its property. */
1244
- function citationFields(value) {
1245
- return {
1246
- repostOf: value('repost-of'),
1247
- likeOf: value('like-of'),
1248
- bookmarkOf: value('bookmark-of'),
1249
- };
1250
- }
1251
- /**
1252
- * The editor for a document that does not exist yet.
1253
- *
1254
- * The date field is filled in with the clock as the site's own zone reads it,
1255
- * not with an instant: what a form offers is what a form takes back, and per
1256
- * decision-11 an offset-less date in this field means the site's zone.
1257
- */
1258
- export function blankForm(kind, timezone = DEFAULT_TIMEZONE, now = new Date()) {
1259
- return {
1260
- title: '',
1261
- slug: '',
1262
- permalink: '',
1263
- date: kind.dated ? wallClockIn(now, timezone) : '',
1264
- tags: '',
1265
- categories: '',
1266
- description: '',
1267
- // Empty rather than the signed-in user: `blankForm` is a pure function
1268
- // over a kind and a clock, and who is signed in is a fact about a request.
1269
- // {@link authorChoices} is where the default is applied.
1270
- author: '',
1271
- inReplyTo: '',
1272
- rsvp: '',
1273
- ...citationFields(() => ''),
1274
- readStatus: '',
1275
- readOf: BLANK_READ_OF_FORM,
1276
- event: BLANK_EVENT_FORM,
1277
- lang: '',
1278
- draft: false,
1279
- visibility: 'public',
1280
- exclude: false,
1281
- contact: false,
1282
- pinned: false,
1283
- previewHidden: false,
1284
- citedAlt: '',
1285
- comments: COMMENT_SETTINGS.site,
1286
- enclosure: BLANK_ENCLOSURE_FORM,
1287
- photos: [],
1288
- location: BLANK_LOCATION_FORM,
1289
- syndicateTo: [],
1290
- body: '',
1291
- hash: '',
1292
- };
1293
- }
1294
- /**
1295
- * The editor for a document that does.
1296
- *
1297
- * The stored instant is shown as the clock in the site's zone reads it, and
1298
- * {@link wallClockIn} keeps whatever precision the instant has, so a form
1299
- * submitted with the field untouched writes back the very instant it was
1300
- * filled in from.
1301
- *
1302
- * `location` is what `data/locations.json` holds for the post (decision-29),
1303
- * which a document does not carry. It is required because a form loaded
1304
- * without it would remove the stored location on save.
1305
- */
1306
- export function formFor(document, timezone, location) {
1307
- return {
1308
- title: document.title,
1309
- slug: document.slug,
1310
- permalink: document.permalink,
1311
- date: document.date === undefined ? '' : wallClockIn(document.date, timezone),
1312
- tags: document.tags.join(', '),
1313
- categories: document.categories.join(', '),
1314
- description: document.description ?? '',
1315
- author: document.author ?? '',
1316
- inReplyTo: document.inReplyTo ?? '',
1317
- rsvp: document.type === 'post' && typeof document.extra[RSVP_FRONT_MATTER_KEY] === 'string'
1318
- ? document.extra[RSVP_FRONT_MATTER_KEY]
1319
- : '',
1320
- // As the file spells it, so a save writes back what it read.
1321
- ...citationFields((property) => document.type === 'post' ? citationText(document.extra[property]) : ''),
1322
- readStatus: document.type === 'post' && typeof document.extra[READ_STATUS_FRONT_MATTER_KEY] === 'string'
1323
- ? document.extra[READ_STATUS_FRONT_MATTER_KEY]
1324
- : '',
1325
- readOf: readOfForm(document.type === 'post' ? readWork(document.extra[READ_OF_FRONT_MATTER_KEY]) : undefined),
1326
- event: document.type === 'post' ? eventForm(document.extra, timezone) : BLANK_EVENT_FORM,
1327
- lang: typeof document.extra[LANG_FRONT_MATTER_KEY] === 'string'
1328
- ? document.extra[LANG_FRONT_MATTER_KEY]
1329
- : '',
1330
- draft: document.draft,
1331
- visibility: visibilityOf(document),
1332
- exclude: document.extra[EXCLUDE_KEY] === true,
1333
- contact: document.extra[CONTACT_FRONT_MATTER_KEY] === true,
1334
- pinned: pinnedAt(document) !== undefined,
1335
- previewHidden: document.type === 'post' && !previewShown(document.extra),
1336
- citedAlt: document.type === 'post' && typeof document.extra[CITED_ALT_FRONT_MATTER_KEY] === 'string'
1337
- ? document.extra[CITED_ALT_FRONT_MATTER_KEY]
1338
- : '',
1339
- comments: commentSettingOf(document),
1340
- enclosure: document.type === 'post' ? enclosureForm(document) : BLANK_ENCLOSURE_FORM,
1341
- photos: document.type === 'post' ? photoRows(document) : [],
1342
- location: document.type === 'post' ? locationForm(location) : BLANK_LOCATION_FORM,
1343
- syndicateTo: document.type === 'post' ? syndicateToOf(document.extra) : [],
1344
- body: document.body,
1345
- hash: document.hash,
1346
- };
1347
- }
1348
390
  /**
1349
391
  * The editor screen.
1350
392
  *
@@ -1376,7 +418,7 @@ async function renderEditor(c, options) {
1376
418
  if (options.status !== undefined)
1377
419
  c.status(options.status);
1378
420
  const permissions = c.var.config.securityHeaders['permissions-policy'];
1379
- if (kind.type === 'post' && permissions !== undefined) {
421
+ if (kind.located && permissions !== undefined) {
1380
422
  c.header('Permissions-Policy', allowGeolocation(permissions));
1381
423
  }
1382
424
  return options.render(c, ADMIN_TEMPLATES.documentEditor, {
@@ -1433,7 +475,7 @@ async function renderEditor(c, options) {
1433
475
  viewUrl: document !== undefined && isServed(document, now) ? document.permalink : undefined,
1434
476
  // Named beside the date field, because a wall clock with no zone on it is
1435
477
  // exactly the ambiguity decision-11 exists to remove.
1436
- ...(kind.dated ? { dateZone: zoneLabel(form.date === '' ? now : form.date, timezone) } : {}),
478
+ ...(kind.dated ? { dateZone: zoneLabel(form.date, timezone, now) } : {}),
1437
479
  ...(scheduledAt === undefined ? {} : { scheduledFor: formatInTimezone(scheduledAt, timezone) }),
1438
480
  ...(options.refusal === undefined
1439
481
  ? {}