@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,1161 +1,7 @@
1
- import { statSync } from 'node:fs';
2
- import path from 'node:path';
3
- import { DEFAULT_COMMENTS_CLOSE_AFTER_DAYS } from '../comments/policy.js';
4
- import { readFileIfPresentSync, updateFileAtomically, writeFileAtomicallySync, } from '../files/atomic.js';
5
- import { parseIconSetting } from '../images/icons.js';
6
- import { isLocationSharing, LOCATION_SHARING } from '../content/location.js';
7
- import { sourceFile } from '../images/paths.js';
8
- import { clientIdentifier } from '../indieauth/client-id.js';
9
- import { MAIL_PROVIDERS } from '../mail/provider.js';
10
- import { SITE_DATA_FILE } from '../web/context.js';
11
- import { DEFAULT_FEED_CADENCE, isUpdatePeriod, UPDATE_PERIODS } from '../web/feed-source.js';
12
- import { DEFAULT_NOTIFY_SERVER } from '../web/feeds.js';
13
- import { generateIndexNowKey, isIndexNowKey } from '../web/indexnow.js';
14
- import { classifyLicense, isCreativeCommonsKey, isLicenseUrl, NO_LICENSE } from '../web/license.js';
15
- import { canonicalLocale } from '../web/locale.js';
16
- import { DEFAULT_MENU_NAME, menuItemsFromText, menusOf } from '../web/navigation.js';
17
- import { AI_CRAWLER_POLICIES, robotsRuleLines, robotsRuleProblem } from '../web/robots.js';
18
- import { DEFAULT_TAXONOMY_BASES, taxonomyBaseProblems, taxonomyRedirectsOf, } from '../web/taxonomy.js';
19
- import { readTheme, themeNameProblem } from '../web/themes.js';
20
- import { ADMIN_PREFIX } from './session.js';
1
+ import { ADMIN_PREFIX } from '../site/admin-paths.js';
21
2
  /**
22
3
  * Where the settings live: the General page, and the root every other settings
23
4
  * page hangs off ({@link settingsPagePath}).
24
5
  */
25
6
  export const SETTINGS_PATH = `${ADMIN_PREFIX}/settings`;
26
- /**
27
- * What a language tag may look like: BCP 47's shape rather than its registry —
28
- * a two or three letter primary subtag followed by dash-separated subtags of
29
- * letters and digits.
30
- *
31
- * Checking the shape and not the registry is deliberate. The value ends up in
32
- * `<html lang>`, an RSS `<language>` and an Atom `xml:lang`, where a
33
- * well-formed tag a reader has never heard of is harmless and a malformed one
34
- * is not; refusing a valid tag because this CMS shipped before it was
35
- * registered would be worse than accepting one nobody uses.
36
- */
37
- export const LANGUAGE_TAG_PATTERN = /^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8}){0,4}$/;
38
- /**
39
- * What an email address has to look like before the settings screen will keep
40
- * it: something, an `@`, and a dotted host.
41
- *
42
- * Deliberately loose. The grammar in RFC 5321 allows addresses nobody has ever
43
- * typed, and the only test that settles whether an address works is sending to
44
- * it — which is what the Send test email button is for. This catches the
45
- * typo where a whole field was pasted into the wrong box.
46
- */
47
- export const EMAIL_PATTERN = /^[^\s@]+@[^\s@.]+(?:\.[^\s@.]+)+$/;
48
- /** Whether a string is a {@link ContentSignalChoice}. */
49
- function isContentSignalChoice(value) {
50
- return value === '' || value === 'yes' || value === 'no';
51
- }
52
- /** Whether a value is a count of polls the Syndication module allows: a whole number from 1. */
53
- function isPollCount(value) {
54
- return typeof value === 'number' && Number.isInteger(value) && value > 0;
55
- }
56
- /** Whether a string is an {@link AiCrawlerPolicy}. */
57
- function isAiCrawlerPolicy(value) {
58
- return AI_CRAWLER_POLICIES.includes(value);
59
- }
60
- /** What the settings say the robots file should carry. */
61
- export function robotsPolicyOf(settings) {
62
- const choices = [
63
- ['search', settings.contentSignalSearch],
64
- ['ai-input', settings.contentSignalAiInput],
65
- ['ai-train', settings.contentSignalAiTrain],
66
- ];
67
- const contentSignal = {};
68
- for (const [name, choice] of choices)
69
- if (choice !== '')
70
- contentSignal[name] = choice;
71
- return { aiCrawlers: settings.aiCrawlers, contentSignal, rules: settings.robotsRules };
72
- }
73
- /**
74
- * What a site is worth before anybody has said otherwise.
75
- *
76
- * `baseUrl` is empty rather than a guess: only the resolved config knows what
77
- * port the site is on, so the fallback is applied where the config is in hand.
78
- */
79
- export const DEFAULT_SITE_SETTINGS = {
80
- title: 'Geekity',
81
- tagline: '',
82
- baseUrl: '',
83
- timezone: 'UTC',
84
- language: 'en',
85
- locale: '',
86
- postsPerPage: 10,
87
- homepage: '',
88
- postsPage: '',
89
- author: '',
90
- theme: '',
91
- icon: '',
92
- license: '',
93
- licenseUrl: '',
94
- licenseName: '',
95
- tagBase: DEFAULT_TAXONOMY_BASES.tag,
96
- categoryBase: DEFAULT_TAXONOMY_BASES.category,
97
- comments: true,
98
- commentsCloseAfterDays: DEFAULT_COMMENTS_CLOSE_AFTER_DAYS,
99
- // Forever, so a site that upgrades loses nothing it never chose to lose.
100
- // `geekity init` writes the recommended periods for a new site.
101
- commentEmailRetentionDays: 0,
102
- addressHashRetentionDays: 0,
103
- contactMessageRetentionDays: 0,
104
- webmentionsSend: true,
105
- webmentionsReceive: true,
106
- notifyServer: DEFAULT_NOTIFY_SERVER,
107
- feedUpdatePeriod: DEFAULT_FEED_CADENCE.period,
108
- feedUpdateFrequency: DEFAULT_FEED_CADENCE.frequency,
109
- aiCrawlers: 'allow',
110
- contentSignalSearch: '',
111
- contentSignalAiInput: '',
112
- contentSignalAiTrain: '',
113
- robotsRules: [],
114
- llmsTxt: true,
115
- indexNow: false,
116
- indexNowKey: '',
117
- mailProvider: 'none',
118
- mailFromName: '',
119
- mailFromAddress: '',
120
- mailReplyTo: '',
121
- contactEmail: '',
122
- securityContacts: [],
123
- securityPolicy: '',
124
- securityLanguages: '',
125
- relays: [],
126
- locationSharing: 'none',
127
- menus: {},
128
- taxonomyRedirects: [],
129
- clientsWithoutPkce: [],
130
- };
131
- /** The form field each setting is submitted under. */
132
- export const SETTINGS_FIELDS = {
133
- title: 'title',
134
- tagline: 'tagline',
135
- baseUrl: 'base_url',
136
- timezone: 'timezone',
137
- language: 'language',
138
- locale: 'locale',
139
- postsPerPage: 'posts_per_page',
140
- homepage: 'homepage',
141
- postsPage: 'posts_page',
142
- author: 'author',
143
- theme: 'theme',
144
- icon: 'icon',
145
- license: 'license',
146
- licenseUrl: 'license_url',
147
- licenseName: 'license_name',
148
- tagBase: 'tag_base',
149
- categoryBase: 'category_base',
150
- comments: 'comments',
151
- commentsCloseAfterDays: 'comments_close_after_days',
152
- commentEmailRetentionDays: 'comment_email_retention_days',
153
- addressHashRetentionDays: 'address_hash_retention_days',
154
- contactMessageRetentionDays: 'contact_message_retention_days',
155
- webmentionsSend: 'webmentions_send',
156
- webmentionsReceive: 'webmentions_receive',
157
- notifyServer: 'notify_server',
158
- feedUpdatePeriod: 'feed_update_period',
159
- feedUpdateFrequency: 'feed_update_frequency',
160
- aiCrawlers: 'ai_crawlers',
161
- contentSignalSearch: 'content_signal_search',
162
- contentSignalAiInput: 'content_signal_ai_input',
163
- contentSignalAiTrain: 'content_signal_ai_train',
164
- robotsRules: 'robots_rules',
165
- llmsTxt: 'llms_txt',
166
- indexNow: 'index_now',
167
- mailProvider: 'mail_provider',
168
- mailFromName: 'mail_from_name',
169
- mailFromAddress: 'mail_from_address',
170
- mailReplyTo: 'mail_reply_to',
171
- contactEmail: 'contact_email',
172
- securityContacts: 'security_contacts',
173
- securityPolicy: 'security_policy',
174
- securityLanguages: 'security_languages',
175
- relays: 'relays',
176
- locationSharing: 'location_sharing',
177
- };
178
- /**
179
- * A site's settings, as its `content/_data/site.json` says them right now.
180
- *
181
- * Read on every request that needs one rather than cached, which is what a
182
- * source of truth being a file is worth: a hand edit shows on the public site,
183
- * on the settings screen and in the actor document without a restart and
184
- * without anything being told. The file is a few hundred bytes, so the read
185
- * costs less than the parse of the template that is about to use it.
186
- *
187
- * A file that is missing, or one that will not parse, is the defaults rather
188
- * than an error: a typo in `site.json` should leave a site up and answerable,
189
- * with the settings screen there to put it right.
190
- */
191
- export function readSiteSettings(contentDir) {
192
- return settingsFromSiteJson(readSiteJson(contentDir));
193
- }
194
- export function readSiteJson(contentDir) {
195
- return readSiteJsonSync(siteDataPath(contentDir));
196
- }
197
- /**
198
- * `content/_data/site.json` as the settings it names, defaults filled in.
199
- *
200
- * Read tolerantly, key by key, because the file is public, in git and editable
201
- * by hand: a key of the wrong type, or one a site has never written, falls
202
- * back to the default rather than taking the site down. The empty string is a
203
- * value of its own for `tagline`, `author` and `notifyServer`, where empty is
204
- * a decision — no tagline, no author, notifications off — and not for
205
- * `title`, `timezone`, `language` or the two archive bases, where it is a hole
206
- * only a default can fill.
207
- */
208
- export function settingsFromSiteJson(file) {
209
- const postsPerPage = Number(file['postsPerPage']);
210
- const closeAfterDays = Number(file['commentsCloseAfterDays']);
211
- return {
212
- ...DEFAULT_SITE_SETTINGS,
213
- ...(typeof file['title'] === 'string' && file['title'] !== '' ? { title: file['title'] } : {}),
214
- ...(typeof file['tagline'] === 'string' ? { tagline: file['tagline'] } : {}),
215
- ...(typeof file['author'] === 'string' ? { author: file['author'] } : {}),
216
- ...(typeof file['timezone'] === 'string' && file['timezone'] !== ''
217
- ? { timezone: file['timezone'] }
218
- : {}),
219
- ...(typeof file['language'] === 'string' && file['language'] !== ''
220
- ? { language: file['language'] }
221
- : {}),
222
- ...(typeof file['locale'] === 'string' ? { locale: file['locale'] } : {}),
223
- // Absent is the ordinary state of this one: a site on the packaged theme
224
- // has never written the key, so anything but a string is that site.
225
- ...(typeof file['theme'] === 'string' ? { theme: file['theme'] } : {}),
226
- ...(typeof file['icon'] === 'string' ? { icon: file['icon'].trim() } : {}),
227
- ...licenseFromSiteJson(file),
228
- // Absent is the ordinary state of these two: a site showing its latest
229
- // posts writes neither key, so anything but a string is read as none.
230
- ...(typeof file['homepage'] === 'string' ? { homepage: file['homepage'] } : {}),
231
- ...(typeof file['postsPage'] === 'string' ? { postsPage: file['postsPage'] } : {}),
232
- ...(typeof file['tagBase'] === 'string' && file['tagBase'] !== ''
233
- ? { tagBase: file['tagBase'] }
234
- : {}),
235
- ...(typeof file['categoryBase'] === 'string' && file['categoryBase'] !== ''
236
- ? { categoryBase: file['categoryBase'] }
237
- : {}),
238
- ...(typeof file['comments'] === 'boolean' ? { comments: file['comments'] } : {}),
239
- ...(Number.isInteger(closeAfterDays) && closeAfterDays >= 0
240
- ? { commentsCloseAfterDays: closeAfterDays }
241
- : {}),
242
- ...wholeDays(file, 'commentEmailRetentionDays'),
243
- ...wholeDays(file, 'addressHashRetentionDays'),
244
- ...wholeDays(file, 'contactMessageRetentionDays'),
245
- ...(typeof file['webmentionsSend'] === 'boolean'
246
- ? { webmentionsSend: file['webmentionsSend'] }
247
- : {}),
248
- ...(typeof file['webmentionsReceive'] === 'boolean'
249
- ? { webmentionsReceive: file['webmentionsReceive'] }
250
- : {}),
251
- ...(typeof file['notifyServer'] === 'string' ? { notifyServer: file['notifyServer'] } : {}),
252
- ...(isUpdatePeriod(file['feedUpdatePeriod'])
253
- ? { feedUpdatePeriod: file['feedUpdatePeriod'] }
254
- : {}),
255
- ...(isPollCount(file['feedUpdateFrequency'])
256
- ? { feedUpdateFrequency: file['feedUpdateFrequency'] }
257
- : {}),
258
- // Read the way the form checks them, so a hand edit naming a policy or a
259
- // signal this version does not know is the default rather than a line of
260
- // robots.txt nobody chose, and a rule the form would refuse is left out.
261
- ...(isAiCrawlerPolicy(file['aiCrawlers']) ? { aiCrawlers: file['aiCrawlers'] } : {}),
262
- ...(isContentSignalChoice(file['contentSignalSearch'])
263
- ? { contentSignalSearch: file['contentSignalSearch'] }
264
- : {}),
265
- ...(isContentSignalChoice(file['contentSignalAiInput'])
266
- ? { contentSignalAiInput: file['contentSignalAiInput'] }
267
- : {}),
268
- ...(isContentSignalChoice(file['contentSignalAiTrain'])
269
- ? { contentSignalAiTrain: file['contentSignalAiTrain'] }
270
- : {}),
271
- ...(Array.isArray(file['robotsRules'])
272
- ? {
273
- robotsRules: robotsRuleLines(file['robotsRules'].filter((entry) => typeof entry === 'string')),
274
- }
275
- : {}),
276
- ...(typeof file['llmsTxt'] === 'boolean' ? { llmsTxt: file['llmsTxt'] } : {}),
277
- ...(typeof file['indexNow'] === 'boolean' ? { indexNow: file['indexNow'] } : {}),
278
- // A key IndexNow would refuse is no key: the site then has none to serve
279
- // or send, which is IndexNow off rather than a stream of 403s.
280
- ...(typeof file['indexNowKey'] === 'string' && isIndexNowKey(file['indexNowKey'])
281
- ? { indexNowKey: file['indexNowKey'] }
282
- : {}),
283
- // Only a provider this version ships, for the reason the actor type is
284
- // read that way: a file naming one it has never heard of is a site that
285
- // sends no mail rather than a boot that fails.
286
- ...(typeof file['mailProvider'] === 'string' &&
287
- MAIL_PROVIDERS.includes(file['mailProvider'])
288
- ? { mailProvider: file['mailProvider'] }
289
- : {}),
290
- ...(typeof file['mailFromName'] === 'string' ? { mailFromName: file['mailFromName'] } : {}),
291
- ...(typeof file['mailFromAddress'] === 'string'
292
- ? { mailFromAddress: file['mailFromAddress'] }
293
- : {}),
294
- ...(typeof file['mailReplyTo'] === 'string' ? { mailReplyTo: file['mailReplyTo'] } : {}),
295
- ...(typeof file['contactEmail'] === 'string' ? { contactEmail: file['contactEmail'] } : {}),
296
- // Through the form's own normalisers, and dropped when they refuse: these
297
- // three are printed line by line into security.txt, so a hand edit with a
298
- // line break in it must not become a field nobody set.
299
- ...(Array.isArray(file['securityContacts'])
300
- ? {
301
- securityContacts: securityContactList(file['securityContacts'].filter((entry) => typeof entry === 'string').join('\n')),
302
- }
303
- : {}),
304
- ...(typeof file['securityPolicy'] === 'string'
305
- ? { securityPolicy: normalizeSecurityPolicy(file['securityPolicy']) ?? '' }
306
- : {}),
307
- ...(typeof file['securityLanguages'] === 'string'
308
- ? { securityLanguages: normalizeLanguageList(file['securityLanguages']) ?? '' }
309
- : {}),
310
- // Through the same normaliser a submitted form goes through, so the file
311
- // and the screen cannot mean different things by the same line.
312
- ...(Array.isArray(file['relays'])
313
- ? {
314
- relays: relayList(file['relays'].filter((entry) => typeof entry === 'string').join('\n')),
315
- }
316
- : {}),
317
- ...(isLocationSharing(file['locationSharing'])
318
- ? { locationSharing: file['locationSharing'] }
319
- : {}),
320
- // Every menu the site holds, whether or not the theme in use renders it.
321
- // The `navigation` key the one menu used to live under is not read at all:
322
- // menus were renamed rather than migrated (TASK-107).
323
- ...(file['menus'] === undefined ? {} : { menus: menusOf(file['menus']) }),
324
- // The renames a site has published redirects for: facts about its URLs
325
- // rather than preferences, which is why a content directory restored on
326
- // its own keeps answering the archive URLs it used to.
327
- ...(Array.isArray(file['taxonomyRedirects'])
328
- ? { taxonomyRedirects: taxonomyRedirectsOf(file['taxonomyRedirects']) }
329
- : {}),
330
- ...(Array.isArray(file['clientsWithoutPkce'])
331
- ? { clientsWithoutPkce: clientsWithoutPkceOf(file['clientsWithoutPkce']) }
332
- : {}),
333
- ...(Number.isInteger(postsPerPage) && postsPerPage > 0 ? { postsPerPage } : {}),
334
- ...(typeof file['url'] === 'string' ? { baseUrl: file['url'] } : {}),
335
- };
336
- }
337
- function clientsWithoutPkceOf(entries) {
338
- const valid = entries.filter((entry) => typeof entry === 'string' && clientIdentifier(entry) !== undefined);
339
- return [...new Set(valid)];
340
- }
341
- /** The two archive bases the settings hold, as the URL builders want them. */
342
- export function taxonomyBasesFromSettings(settings) {
343
- return { tag: settings.tagBase, category: settings.categoryBase };
344
- }
345
- /**
346
- * `content/_data/site.json` as it should read for these settings.
347
- *
348
- * Every key the settings model is written whether or not it has a value, so
349
- * the file's shape is stable and an Eleventy template may reference
350
- * `site.tagline` without guarding it. Every other key the file already had is
351
- * kept: a site may put anything in there and reach it from its templates, and
352
- * the settings form is not going to be the thing that throws it away.
353
- *
354
- * `homepage` and `postsPage` are the one exception, and they earn it: a site
355
- * showing its latest posts has no static front page at all rather than an
356
- * empty one, so the keys are absent rather than empty — which is also how a
357
- * `site.json` written before this version reads, and what it should mean.
358
- */
359
- export function siteJsonFor(settings, existing = {}) {
360
- const file = {
361
- ...existing,
362
- title: settings.title,
363
- tagline: settings.tagline,
364
- url: settings.baseUrl,
365
- postsPerPage: settings.postsPerPage,
366
- timezone: settings.timezone,
367
- language: settings.language,
368
- tagBase: settings.tagBase,
369
- categoryBase: settings.categoryBase,
370
- comments: settings.comments,
371
- commentsCloseAfterDays: settings.commentsCloseAfterDays,
372
- commentEmailRetentionDays: settings.commentEmailRetentionDays,
373
- addressHashRetentionDays: settings.addressHashRetentionDays,
374
- contactMessageRetentionDays: settings.contactMessageRetentionDays,
375
- webmentionsSend: settings.webmentionsSend,
376
- webmentionsReceive: settings.webmentionsReceive,
377
- notifyServer: settings.notifyServer,
378
- feedUpdatePeriod: settings.feedUpdatePeriod,
379
- feedUpdateFrequency: settings.feedUpdateFrequency,
380
- aiCrawlers: settings.aiCrawlers,
381
- contentSignalSearch: settings.contentSignalSearch,
382
- contentSignalAiInput: settings.contentSignalAiInput,
383
- contentSignalAiTrain: settings.contentSignalAiTrain,
384
- robotsRules: [...settings.robotsRules],
385
- llmsTxt: settings.llmsTxt,
386
- indexNow: settings.indexNow,
387
- mailProvider: settings.mailProvider,
388
- mailFromName: settings.mailFromName,
389
- mailFromAddress: settings.mailFromAddress,
390
- mailReplyTo: settings.mailReplyTo,
391
- contactEmail: settings.contactEmail,
392
- securityContacts: [...settings.securityContacts],
393
- securityPolicy: settings.securityPolicy,
394
- securityLanguages: settings.securityLanguages,
395
- relays: [...settings.relays],
396
- locationSharing: settings.locationSharing,
397
- // Every menu the site holds, written whole. A settings page never has
398
- // them off its own form — it reads them out of the file inside the write
399
- // and hands them straight back — so the one screen that models them is the
400
- // one that edits them (TASK-108).
401
- menus: Object.fromEntries(Object.entries(settings.menus).map(([name, items]) => [
402
- name,
403
- items.map((item) => ({ ...item })),
404
- ])),
405
- taxonomyRedirects: settings.taxonomyRedirects.map((entry) => ({ ...entry })),
406
- };
407
- // The key the menu lived under before menus had names. A rename leaves
408
- // nothing behind: a `navigation` array sitting beside `menus` in a file
409
- // nothing reads it from is the kind of thing somebody edits for an hour
410
- // before noticing.
411
- delete file['navigation'];
412
- // The Solo author switch, which the author setting now says on its own
413
- // (TASK-192): a username is a solo author site and no author is not.
414
- delete file['soloAuthor'];
415
- // `theme` is absent for a site on the packaged theme, on the same rule and
416
- // for the same reason as the two above: running what the package ships is
417
- // not a choice a site should have to write down, and a `theme` of `""` would
418
- // be a name no directory has. `locale` too: a site whose dates follow its
419
- // language has made no choice to write down.
420
- // `author` too: a site with several authors names nobody (TASK-192).
421
- for (const key of ['homepage', 'postsPage', 'theme', 'locale', 'author', 'icon']) {
422
- if (settings[key] === '')
423
- delete file[key];
424
- else
425
- file[key] = settings[key];
426
- }
427
- delete file['licenseName'];
428
- if (settings.license === '')
429
- delete file['license'];
430
- else if (settings.license !== 'custom')
431
- file['license'] = settings.license;
432
- else {
433
- file['license'] = settings.licenseUrl;
434
- file['licenseName'] = settings.licenseName;
435
- }
436
- // A site that has never turned IndexNow on has no key to write down.
437
- if (settings.indexNowKey !== '')
438
- file['indexNowKey'] = settings.indexNowKey;
439
- else
440
- delete file['indexNowKey'];
441
- if (settings.clientsWithoutPkce.length > 0) {
442
- file['clientsWithoutPkce'] = [...settings.clientsWithoutPkce];
443
- }
444
- else
445
- delete file['clientsWithoutPkce'];
446
- return file;
447
- }
448
- /** The absolute path of one site's `content/_data/site.json`. */
449
- export function siteDataPath(contentDir) {
450
- return path.join(contentDir, ...SITE_DATA_FILE.split('/'));
451
- }
452
- /** The bytes of one settings object, as the file holds them. */
453
- function siteJsonText(settings, existing) {
454
- return `${JSON.stringify(siteJsonFor(settings, existing), null, 2)}\n`;
455
- }
456
- /**
457
- * Rewrite `content/_data/site.json` as these settings, keeping the keys they
458
- * do not model.
459
- *
460
- * {@link updateSiteSettings} for a caller whose new settings depend on the old
461
- * ones, which every screen's is: this is for the callers that have the whole
462
- * object already, a test's set-up among them.
463
- */
464
- export async function writeSiteJson(options) {
465
- await updateSiteSettings({ contentDir: options.contentDir, change: () => options.settings });
466
- }
467
- /**
468
- * Change the settings: re-read the file, apply the change, write it back, with
469
- * nothing able to write that file in between ({@link updateFileAtomically}).
470
- *
471
- * The re-read is what makes the file win the way it wins for a post
472
- * (decision-9). Two people with the settings screen open both save what they
473
- * see, and the second save is applied to what the first one actually wrote
474
- * rather than to what the second one had on screen — so a change to a field
475
- * the second person did not touch survives. The write is a temporary file and
476
- * a rename, so a reader — an Eleventy build, the site data source, another
477
- * process entirely — never sees a half-written file. Keys the settings do not
478
- * model, `feedSize` and anything a site added, are kept.
479
- */
480
- export async function updateSiteSettings(options) {
481
- let written = DEFAULT_SITE_SETTINGS;
482
- await updateFileAtomically(siteDataPath(options.contentDir), (current) => {
483
- const existing = parseSiteJson(current ?? '');
484
- written = options.change(settingsFromSiteJson(existing));
485
- return siteJsonText(written, existing);
486
- });
487
- return written;
488
- }
489
- /**
490
- * Turn an older site's settings rows into `content/_data/site.json`, once, and
491
- * drop the table.
492
- *
493
- * TASK-14 made SQLite the source and the file its mirror; decision-9 reversed
494
- * that, and a site upgrading across the two has rows nothing would ever read
495
- * again. So the first boot of this version writes them out. Which side wins
496
- * when both have something to say is decided the way it is decided everywhere
497
- * else: the file wins when it was written after the last save, because that is
498
- * a hand edit or a restored checkout, and the rows win otherwise. Either way
499
- * the actor handle and type come from the rows, because `site.json` never
500
- * carried them and losing them would rename the site's actor.
501
- *
502
- * Synchronous because `createCms` is: it runs before the server is listening
503
- * and before anything else has touched the file.
504
- */
505
- export function migrateSettingsToFile(options) {
506
- const { admin, contentDir } = options;
507
- const rows = admin.legacySettings();
508
- if (rows !== undefined && rows.length > 0) {
509
- const stored = settingsFromRows(rows);
510
- const file = siteDataPath(contentDir);
511
- const existing = parseSiteJson(readFileIfPresentSync(file) ?? '');
512
- const settings = fileWasEditedLast(file, rows) ? settingsFromSiteJson(existing) : stored;
513
- writeFileAtomicallySync(file, siteJsonText(settings, existing));
514
- }
515
- // Dropped whether or not it had rows: a fresh database gets the table from
516
- // migration 3, which has shipped and so is never edited, and a site that has
517
- // been migrated must not be asked again on the next boot.
518
- admin.dropLegacyTable('settings');
519
- }
520
- /** The old key/value rows as settings, defaults filled in. */
521
- function settingsFromRows(rows) {
522
- const stored = {};
523
- for (const row of rows)
524
- stored[row.key] = row.value;
525
- // Through the file's own reader, so one description of what a setting is
526
- // worth serves both: the rows are spelled as the file spells them and read
527
- // back the same way. `relays`, `navigation` and `taxonomyRedirects` were
528
- // stored one entry per line, which is not how the file holds them.
529
- return settingsFromSiteJson({
530
- ...stored,
531
- ...(stored['baseUrl'] === undefined ? {} : { url: stored['baseUrl'] }),
532
- ...(stored['postsPerPage'] === undefined
533
- ? {}
534
- : { postsPerPage: Number(stored['postsPerPage']) }),
535
- relays: relayList(stored['relays'] ?? ''),
536
- menus: { [DEFAULT_MENU_NAME]: menuItemsFromText(stored['navigation'] ?? '') },
537
- taxonomyRedirects: redirectList(stored['taxonomyRedirects'] ?? ''),
538
- });
539
- }
540
- /**
541
- * Whether `site.json` has been written since the newest settings row was.
542
- *
543
- * A missing file has not, so the rows win. A file whose modification time
544
- * cannot be read is treated the same way: the rows are the only thing that is
545
- * certainly there.
546
- */
547
- function fileWasEditedLast(file, rows) {
548
- let modified;
549
- try {
550
- modified = statSync(file).mtimeMs;
551
- }
552
- catch {
553
- return false;
554
- }
555
- const newest = rows.reduce((latest, row) => {
556
- const at = Date.parse(row.updatedAt);
557
- return Number.isNaN(at) ? latest : Math.max(latest, at);
558
- }, 0);
559
- return modified > newest;
560
- }
561
- /**
562
- * The base URL actually in effect, and why.
563
- *
564
- * A base URL is a deployment fact before it is a preference: it decides the
565
- * absolute URLs in the feeds, the ActivityPub ids, and whether the session
566
- * cookie is `Secure`. So `GEEKITY_BASE_URL` and a `baseUrl` in the config file
567
- * both win over the stored setting, and the settings form says so rather than
568
- * offering a field that would quietly do nothing.
569
- */
570
- export function effectiveBaseUrl(config, settings) {
571
- if (config.baseUrlSource !== 'default')
572
- return config.baseUrl;
573
- return settings.baseUrl === '' ? config.baseUrl : settings.baseUrl;
574
- }
575
- /**
576
- * What is wrong with each field of a submitted form: one check per field, so a
577
- * page can run the checks for the fields it carries and no others.
578
- *
579
- * A field nothing can be wrong with — a tagline, an author, a checkbox — has a
580
- * check all the same, because a table with a hole in it is a field somebody
581
- * added and forgot to think about.
582
- */
583
- const FIELD_CHECKS = {
584
- title: (form) => (form.title.trim() === '' ? 'The site needs a title.' : undefined),
585
- tagline: () => undefined,
586
- author: () => undefined,
587
- baseUrl: (form) => normalizeBaseUrl(form.baseUrl) === undefined
588
- ? 'The base URL has to be an absolute http:// or https:// URL.'
589
- : undefined,
590
- postsPerPage: (form) => {
591
- const perPage = Number(form.postsPerPage);
592
- return !Number.isInteger(perPage) || perPage < 1
593
- ? 'Posts per page has to be a whole number of one or more.'
594
- : undefined;
595
- },
596
- // The two picks are checked as a pair, the way the archive bases are, and
597
- // for the same reason: two of the three rules are about the pair. Neither
598
- // check asks whether the slug still names a published page — the select only
599
- // offers ones that do, and a page drafted after it was picked is a site back
600
- // on its latest posts rather than a settings screen that will not save.
601
- homepage: (form) => slugProblem(form.homepage, 'A homepage'),
602
- postsPage: (form) => {
603
- if (form.postsPage.trim() === '')
604
- return undefined;
605
- if (form.homepage.trim() === '') {
606
- return 'A posts page needs a homepage: pick the page the front page shows first.';
607
- }
608
- if (form.postsPage.trim() === form.homepage.trim()) {
609
- return 'The homepage and the posts page have to be two different pages.';
610
- }
611
- return slugProblem(form.postsPage, 'A posts page');
612
- },
613
- timezone: (form) => isValidTimezone(form.timezone)
614
- ? undefined
615
- : 'That is not an IANA time zone name, such as Europe/London.',
616
- language: (form) => LANGUAGE_TAG_PATTERN.test(form.language.trim())
617
- ? undefined
618
- : 'That is not a language tag, such as en, en-GB or pt-BR.',
619
- // Empty is the ordinary value: the dates follow the language.
620
- locale: (form) => {
621
- const locale = form.locale.trim();
622
- return locale === '' ||
623
- (LANGUAGE_TAG_PATTERN.test(locale) && canonicalLocale(locale) !== undefined)
624
- ? undefined
625
- : 'That is not a locale, such as en-US, fr-CA or pt-BR, or empty for the language.';
626
- },
627
- // Empty is a value here — it is how a site says "the theme the package
628
- // ships" — so only a name has anything to check. A name that is not a theme
629
- // is refused rather than saved and warned about later: the screen has a list
630
- // of the themes that are there, so the only way to type one that is not is a
631
- // theme deleted between drawing the list and saving it, and the person is in
632
- // front of the form and can be told.
633
- theme: (form, context) => {
634
- const name = form.theme.trim();
635
- if (name === '')
636
- return undefined;
637
- const badName = themeNameProblem(name);
638
- if (badName !== undefined)
639
- return badName;
640
- if (context.themesDir === undefined)
641
- return undefined;
642
- const read = readTheme(path.join(context.themesDir, name));
643
- return read.ok ? undefined : `There is no theme called "${name}": ${read.reason}`;
644
- },
645
- icon: (form, context) => iconProblem(form.icon.trim(), context),
646
- license: (form) => isLicenseChoice(form.license.trim()) ? undefined : 'Choose a license from the list.',
647
- licenseUrl: (form) => form.license.trim() === 'custom' && !isLicenseUrl(form.licenseUrl.trim())
648
- ? 'A custom license needs the URL of its terms, starting http:// or https://.'
649
- : undefined,
650
- licenseName: (form) => form.license.trim() === 'custom' && form.licenseName.trim() === ''
651
- ? 'A custom license needs a name for the footer to show.'
652
- : undefined,
653
- comments: () => undefined,
654
- // The empty string is refused rather than read as zero, which is what
655
- // `Number('')` would make it: a cleared field is a mistake, and "never close
656
- // comments" should have to be typed.
657
- commentsCloseAfterDays: (form) => {
658
- const typed = form.commentsCloseAfterDays.trim();
659
- const days = Number(typed);
660
- return typed === '' || !Number.isInteger(days) || days < 0
661
- ? 'Comments close after a whole number of days, or 0 for never.'
662
- : undefined;
663
- },
664
- commentEmailRetentionDays: (form) => retentionProblem(form.commentEmailRetentionDays),
665
- addressHashRetentionDays: (form) => retentionProblem(form.addressHashRetentionDays),
666
- contactMessageRetentionDays: (form) => retentionProblem(form.contactMessageRetentionDays),
667
- webmentionsSend: () => undefined,
668
- webmentionsReceive: () => undefined,
669
- // Empty is a value here — it is how a site turns real-time notification off
670
- // — so only a non-empty one has to be a URL. http as well as https, because
671
- // a notify server on a private network or a loopback port is a real one.
672
- notifyServer: (form) => form.notifyServer.trim() !== '' && normalizeBaseUrl(form.notifyServer) === undefined
673
- ? 'A notify server is an absolute http:// or https:// URL, or empty for none.'
674
- : undefined,
675
- feedUpdatePeriod: (form) => isUpdatePeriod(form.feedUpdatePeriod)
676
- ? undefined
677
- : `An update period is one of ${UPDATE_PERIODS.join(', ')}.`,
678
- feedUpdateFrequency: (form) => form.feedUpdateFrequency.trim() !== '' && isPollCount(Number(form.feedUpdateFrequency))
679
- ? undefined
680
- : 'Polls per period is a whole number, 1 or more.',
681
- aiCrawlers: (form) => isAiCrawlerPolicy(form.aiCrawlers)
682
- ? undefined
683
- : `An AI-crawler policy is one of ${AI_CRAWLER_POLICIES.join(', ')}.`,
684
- contentSignalSearch: (form) => contentSignalProblem(form.contentSignalSearch),
685
- contentSignalAiInput: (form) => contentSignalProblem(form.contentSignalAiInput),
686
- contentSignalAiTrain: (form) => contentSignalProblem(form.contentSignalAiTrain),
687
- robotsRules: (form) => robotsRuleProblem([form.robotsRules]),
688
- llmsTxt: () => undefined,
689
- indexNow: () => undefined,
690
- mailProvider: (form) => MAIL_PROVIDERS.includes(form.mailProvider)
691
- ? undefined
692
- : `A mail provider is one of ${MAIL_PROVIDERS.join(', ')}.`,
693
- mailFromName: () => undefined,
694
- // Empty is a value for both of these — no From address falls back to
695
- // `no-reply@` at the site's host, and no reply-to means replies go to the
696
- // From address — so only a non-empty one has to look like an address.
697
- mailFromAddress: (form) => form.mailFromAddress.trim() !== '' && !EMAIL_PATTERN.test(form.mailFromAddress.trim())
698
- ? 'A From address is an email address, such as blog@example.com, or empty for the default.'
699
- : undefined,
700
- mailReplyTo: (form) => form.mailReplyTo.trim() !== '' && !EMAIL_PATTERN.test(form.mailReplyTo.trim())
701
- ? 'A reply-to is an email address, such as hello@example.com, or empty to reply to the From address.'
702
- : undefined,
703
- // Empty is a value here too — it is how a site says "whichever admin has an
704
- // address" — so only a non-empty one has to look like one.
705
- contactEmail: (form) => form.contactEmail.trim() !== '' && !EMAIL_PATTERN.test(form.contactEmail.trim())
706
- ? 'A contact address is an email address, such as hello@example.com, or empty for the first admin with one.'
707
- : undefined,
708
- // Line by line, like the relays, and for the same reason.
709
- securityContacts: (form) => {
710
- const bad = relayLines(form.securityContacts).find((line) => normalizeSecurityContact(line) === undefined);
711
- return bad === undefined
712
- ? undefined
713
- : 'A security contact is an email address, an https:// URL or a tel: number, one per line. ' +
714
- `"${bad}" is not one.`;
715
- },
716
- // RFC 9116 wants every web URI in the file to be https.
717
- securityPolicy: (form) => form.securityPolicy.trim() !== '' && normalizeSecurityPolicy(form.securityPolicy) === undefined
718
- ? 'A security policy is an https:// URL, or empty for none.'
719
- : undefined,
720
- securityLanguages: (form) => normalizeLanguageList(form.securityLanguages) === undefined
721
- ? 'Preferred languages are language tags separated by commas, such as en, fr, or empty for none.'
722
- : undefined,
723
- // A relay list is checked line by line, and the first bad line is what the
724
- // field says: a textarea has one message, and pointing at the line somebody
725
- // has to fix is more use than counting how many are wrong.
726
- relays: (form) => {
727
- const bad = relayLines(form.relays).find((line) => normalizeRelayInbox(line) === undefined);
728
- return bad === undefined
729
- ? undefined
730
- : `A relay is its inbox as an absolute http:// or https:// URL, one per line. ` +
731
- `"${bad}" is not one.`;
732
- },
733
- locationSharing: (form) => isLocationSharing(form.locationSharing)
734
- ? undefined
735
- : `Location sharing is one of ${LOCATION_SHARING.join(', ')}.`,
736
- // The two archive bases are checked as a pair, because two of the rules —
737
- // that they differ, and that neither takes a path the site already answers
738
- // on — are about the pair rather than either one. They are on one page for
739
- // exactly that reason.
740
- tagBase: (form) => taxonomyBaseProblems({ tag: form.tagBase, category: form.categoryBase }).tag,
741
- categoryBase: (form) => taxonomyBaseProblems({ tag: form.tagBase, category: form.categoryBase }).category,
742
- };
743
- function isLicenseChoice(value) {
744
- return value === '' || value === 'custom' || isCreativeCommonsKey(value);
745
- }
746
- function licenseFromSiteJson(file) {
747
- const said = classifyLicense(file['license']);
748
- if (said === undefined || said === NO_LICENSE)
749
- return {};
750
- if ('key' in said)
751
- return { license: said.key, licenseUrl: '', licenseName: '' };
752
- const name = typeof file['licenseName'] === 'string' ? file['licenseName'].trim() : '';
753
- return { license: 'custom', licenseUrl: said.url, licenseName: name };
754
- }
755
- function iconProblem(icon, context) {
756
- if (icon === '')
757
- return undefined;
758
- const parsed = parseIconSetting(icon);
759
- if ('problem' in parsed) {
760
- return parsed.problem === 'not-an-upload'
761
- ? 'The site icon has to be a file in the media library, a path such as /uploads/2026/10/icon.png.'
762
- : 'The site icon has to be an image: PNG, JPEG, GIF, WebP, AVIF, TIFF or SVG.';
763
- }
764
- if (context.contentDir === undefined)
765
- return undefined;
766
- const file = sourceFile({ contentDir: context.contentDir }, parsed.source);
767
- return file !== undefined && isFile(file)
768
- ? undefined
769
- : `There is no upload at ${icon}. Upload the picture on the Media screen first.`;
770
- }
771
- function isFile(file) {
772
- try {
773
- return statSync(file).isFile();
774
- }
775
- catch {
776
- return false;
777
- }
778
- }
779
- /** What is wrong with a submitted Content-Signal choice. */
780
- function contentSignalProblem(value) {
781
- return isContentSignalChoice(value) ? undefined : 'A content signal is yes, no, or not said.';
782
- }
783
- /** Every field of the settings, in the order the form fields name them. */
784
- export const SETTINGS_FIELD_NAMES = Object.keys(SETTINGS_FIELDS);
785
- /**
786
- * What is wrong with a submitted settings form, one message per field.
787
- *
788
- * `fields` is what a page carries: it validates its own fields and says
789
- * nothing about the rest, so a page cannot refuse a save over a field it does
790
- * not show and gives no way to fix. `context` is what a check needs beyond the
791
- * form; see {@link SettingsContext}.
792
- */
793
- export function settingsProblems(form, fields = SETTINGS_FIELD_NAMES, context = {}) {
794
- const problems = {};
795
- for (const name of fields) {
796
- const problem = FIELD_CHECKS[name](form, context);
797
- if (problem !== undefined)
798
- problems[name] = problem;
799
- }
800
- return problems;
801
- }
802
- /**
803
- * A validated form as settings. Only call it on a form
804
- * {@link settingsProblems} found nothing wrong with.
805
- *
806
- * The archive renames and the menus are carried in rather than read off the
807
- * form, because they are not on it: the taxonomy screens write the one and the
808
- * Navigation screen the other, and a save of the fields that are on the form
809
- * keeps whatever is stored. Passing the settings read inside the write is all
810
- * a caller has to do, since they hold both.
811
- */
812
- export function settingsFromForm(form, carried = {}) {
813
- return {
814
- taxonomyRedirects: carried.taxonomyRedirects ?? DEFAULT_SITE_SETTINGS.taxonomyRedirects,
815
- menus: carried.menus ?? DEFAULT_SITE_SETTINGS.menus,
816
- clientsWithoutPkce: carried.clientsWithoutPkce ?? DEFAULT_SITE_SETTINGS.clientsWithoutPkce,
817
- title: form.title.trim(),
818
- tagline: form.tagline.trim(),
819
- baseUrl: normalizeBaseUrl(form.baseUrl) ?? '',
820
- timezone: form.timezone.trim(),
821
- language: form.language.trim(),
822
- locale: form.locale.trim(),
823
- postsPerPage: Number(form.postsPerPage),
824
- homepage: form.homepage.trim(),
825
- // A posts page means nothing without a homepage, and the validator has
826
- // already refused the pair; this is what makes clearing the homepage clear
827
- // the listing's own page with it rather than leave it stranded.
828
- postsPage: form.homepage.trim() === '' ? '' : form.postsPage.trim(),
829
- author: form.author.trim(),
830
- theme: form.theme.trim(),
831
- icon: form.icon.trim(),
832
- ...licenseFromForm(form),
833
- tagBase: form.tagBase.trim(),
834
- categoryBase: form.categoryBase.trim(),
835
- // A checkbox submits nothing at all when it is clear, which is what the
836
- // empty string here means.
837
- comments: form.comments !== '',
838
- commentsCloseAfterDays: Number(form.commentsCloseAfterDays),
839
- commentEmailRetentionDays: Number(form.commentEmailRetentionDays),
840
- addressHashRetentionDays: Number(form.addressHashRetentionDays),
841
- contactMessageRetentionDays: Number(form.contactMessageRetentionDays),
842
- webmentionsSend: form.webmentionsSend !== '',
843
- webmentionsReceive: form.webmentionsReceive !== '',
844
- notifyServer: normalizeBaseUrl(form.notifyServer) ?? '',
845
- feedUpdatePeriod: isUpdatePeriod(form.feedUpdatePeriod)
846
- ? form.feedUpdatePeriod
847
- : DEFAULT_FEED_CADENCE.period,
848
- feedUpdateFrequency: Number(form.feedUpdateFrequency),
849
- aiCrawlers: isAiCrawlerPolicy(form.aiCrawlers) ? form.aiCrawlers : 'allow',
850
- contentSignalSearch: isContentSignalChoice(form.contentSignalSearch)
851
- ? form.contentSignalSearch
852
- : '',
853
- contentSignalAiInput: isContentSignalChoice(form.contentSignalAiInput)
854
- ? form.contentSignalAiInput
855
- : '',
856
- contentSignalAiTrain: isContentSignalChoice(form.contentSignalAiTrain)
857
- ? form.contentSignalAiTrain
858
- : '',
859
- robotsRules: robotsRuleLines([form.robotsRules]),
860
- llmsTxt: form.llmsTxt !== '',
861
- indexNow: form.indexNow !== '',
862
- // Minted the first time IndexNow is turned on and never again, so the key
863
- // the search engines verified outlives turning it off and on.
864
- indexNowKey: carried.indexNowKey !== undefined && carried.indexNowKey !== ''
865
- ? carried.indexNowKey
866
- : form.indexNow !== ''
867
- ? generateIndexNowKey()
868
- : '',
869
- mailProvider: MAIL_PROVIDERS.includes(form.mailProvider)
870
- ? form.mailProvider
871
- : 'none',
872
- mailFromName: form.mailFromName.trim(),
873
- mailFromAddress: form.mailFromAddress.trim(),
874
- mailReplyTo: form.mailReplyTo.trim(),
875
- contactEmail: form.contactEmail.trim(),
876
- securityContacts: securityContactList(form.securityContacts),
877
- securityPolicy: normalizeSecurityPolicy(form.securityPolicy) ?? '',
878
- securityLanguages: normalizeLanguageList(form.securityLanguages) ?? '',
879
- relays: relayList(form.relays),
880
- locationSharing: isLocationSharing(form.locationSharing) ? form.locationSharing : 'none',
881
- };
882
- }
883
- function licenseFromForm(form) {
884
- const license = form.license.trim();
885
- if (license === 'custom') {
886
- return { license, licenseUrl: form.licenseUrl.trim(), licenseName: form.licenseName.trim() };
887
- }
888
- return {
889
- license: isLicenseChoice(license) ? license : '',
890
- licenseUrl: '',
891
- licenseName: '',
892
- };
893
- }
894
- /** The settings as the form shows them. */
895
- export function formFromSettings(settings) {
896
- return {
897
- title: settings.title,
898
- tagline: settings.tagline,
899
- baseUrl: settings.baseUrl,
900
- timezone: settings.timezone,
901
- language: settings.language,
902
- locale: settings.locale,
903
- postsPerPage: String(settings.postsPerPage),
904
- homepage: settings.homepage,
905
- postsPage: settings.postsPage,
906
- author: settings.author,
907
- theme: settings.theme,
908
- icon: settings.icon,
909
- license: settings.license,
910
- licenseUrl: settings.licenseUrl,
911
- licenseName: settings.licenseName,
912
- tagBase: settings.tagBase,
913
- categoryBase: settings.categoryBase,
914
- comments: settings.comments ? '1' : '',
915
- commentsCloseAfterDays: String(settings.commentsCloseAfterDays),
916
- commentEmailRetentionDays: String(settings.commentEmailRetentionDays),
917
- addressHashRetentionDays: String(settings.addressHashRetentionDays),
918
- contactMessageRetentionDays: String(settings.contactMessageRetentionDays),
919
- webmentionsSend: settings.webmentionsSend ? '1' : '',
920
- webmentionsReceive: settings.webmentionsReceive ? '1' : '',
921
- notifyServer: settings.notifyServer,
922
- feedUpdatePeriod: settings.feedUpdatePeriod,
923
- feedUpdateFrequency: String(settings.feedUpdateFrequency),
924
- aiCrawlers: settings.aiCrawlers,
925
- contentSignalSearch: settings.contentSignalSearch,
926
- contentSignalAiInput: settings.contentSignalAiInput,
927
- contentSignalAiTrain: settings.contentSignalAiTrain,
928
- robotsRules: settings.robotsRules.join('\n'),
929
- llmsTxt: settings.llmsTxt ? '1' : '',
930
- indexNow: settings.indexNow ? '1' : '',
931
- mailProvider: settings.mailProvider,
932
- mailFromName: settings.mailFromName,
933
- mailFromAddress: settings.mailFromAddress,
934
- mailReplyTo: settings.mailReplyTo,
935
- contactEmail: settings.contactEmail,
936
- securityContacts: settings.securityContacts.join('\n'),
937
- securityPolicy: settings.securityPolicy,
938
- securityLanguages: settings.securityLanguages,
939
- relays: settings.relays.join('\n'),
940
- locationSharing: settings.locationSharing,
941
- };
942
- }
943
- /**
944
- * A `taxonomy|from|to` block as the renames it names, which is how the old
945
- * settings table spelled them ({@link migrateSettingsToFile}).
946
- *
947
- * The same tolerance the rest of this file reads its lists with: a line that
948
- * is not three non-empty parts naming a real taxonomy is dropped rather than
949
- * failing the read.
950
- */
951
- function redirectList(value) {
952
- const entries = [];
953
- for (const line of value.split('\n')) {
954
- const parts = line.split('|');
955
- if (parts.length !== 3)
956
- continue;
957
- entries.push({
958
- taxonomy: (parts[0] ?? '').trim(),
959
- from: (parts[1] ?? '').trim(),
960
- to: (parts[2] ?? '').trim(),
961
- });
962
- }
963
- // Through the same reader `site.json` goes through, so the two spellings of
964
- // the list cannot mean different things.
965
- return taxonomyRedirectsOf(entries);
966
- }
967
- /**
968
- * A base URL, normalised the way `resolveConfig` normalises the configured
969
- * one, or `undefined` when it is not an absolute http(s) URL.
970
- */
971
- function normalizeBaseUrl(value) {
972
- const trimmed = value.trim();
973
- if (trimmed === '')
974
- return undefined;
975
- let parsed;
976
- try {
977
- parsed = new URL(trimmed);
978
- }
979
- catch {
980
- return undefined;
981
- }
982
- if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:')
983
- return undefined;
984
- const pathname = parsed.pathname.endsWith('/') ? parsed.pathname.slice(0, -1) : parsed.pathname;
985
- return parsed.origin + pathname;
986
- }
987
- /**
988
- * The non-empty lines of a relay textarea, trimmed.
989
- *
990
- * Blank lines are not an error: somebody pasting a list leaves them, and a
991
- * blank line asks for nothing.
992
- */
993
- function relayLines(value) {
994
- return value
995
- .split('\n')
996
- .map((line) => line.trim())
997
- .filter((line) => line !== '');
998
- }
999
- /**
1000
- * A relay textarea as the list of inboxes it names: normalised, in the order
1001
- * they were given, with repeats dropped.
1002
- *
1003
- * Exported because the same parsing turns a stored setting, a submitted form
1004
- * and a `site.json` array into the one list; a second spelling of it would let
1005
- * the file and the database disagree about what a site subscribes to.
1006
- */
1007
- export function relayList(value) {
1008
- const relays = [];
1009
- for (const line of relayLines(value)) {
1010
- const inbox = normalizeRelayInbox(line);
1011
- if (inbox !== undefined && !relays.includes(inbox))
1012
- relays.push(inbox);
1013
- }
1014
- return relays;
1015
- }
1016
- /**
1017
- * A relay inbox URL, or `undefined` when it is not an absolute http(s) one.
1018
- *
1019
- * Unlike {@link normalizeBaseUrl} this keeps the whole URL bar a trailing
1020
- * slash: a relay inbox is a path — `/user/_____relay_____/inbox` — rather than
1021
- * an origin, and some relays hang one off a query string.
1022
- */
1023
- export function normalizeRelayInbox(value) {
1024
- const trimmed = value.trim();
1025
- if (trimmed === '')
1026
- return undefined;
1027
- let parsed;
1028
- try {
1029
- parsed = new URL(trimmed);
1030
- }
1031
- catch {
1032
- return undefined;
1033
- }
1034
- if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:')
1035
- return undefined;
1036
- const href = parsed.href;
1037
- return href.endsWith('/') && parsed.pathname !== '/' ? href.slice(0, -1) : href;
1038
- }
1039
- /** A security contact textarea as its URIs, in order, repeats dropped. */
1040
- function securityContactList(value) {
1041
- const contacts = [];
1042
- for (const line of relayLines(value)) {
1043
- const contact = normalizeSecurityContact(line);
1044
- if (contact !== undefined && !contacts.includes(contact))
1045
- contacts.push(contact);
1046
- }
1047
- return contacts;
1048
- }
1049
- /** A phone number as a `tel:` URI writes it: digits and visual separators. */
1050
- const TEL_PATTERN = /^tel:\+?[0-9][0-9().-]*$/i;
1051
- /**
1052
- * One security contact as the URI security.txt carries, or `undefined`.
1053
- *
1054
- * A bare address is taken as the `mailto:` it means, since that is what
1055
- * somebody filling in a settings form types.
1056
- */
1057
- function normalizeSecurityContact(value) {
1058
- const trimmed = value.trim();
1059
- const address = trimmed.toLowerCase().startsWith('mailto:') ? trimmed.slice(7) : trimmed;
1060
- if (EMAIL_PATTERN.test(address))
1061
- return `mailto:${address}`;
1062
- if (TEL_PATTERN.test(trimmed))
1063
- return `tel:${trimmed.slice(4)}`;
1064
- return httpsUrl(trimmed);
1065
- }
1066
- /** A security policy URL, or `undefined` when it is not an https one. */
1067
- function normalizeSecurityPolicy(value) {
1068
- return httpsUrl(value.trim());
1069
- }
1070
- /** An absolute https URL as `URL` spells it, or `undefined`. */
1071
- function httpsUrl(value) {
1072
- let parsed;
1073
- try {
1074
- parsed = new URL(value);
1075
- }
1076
- catch {
1077
- return undefined;
1078
- }
1079
- return parsed.protocol === 'https:' ? parsed.href : undefined;
1080
- }
1081
- /**
1082
- * A comma-separated list of language tags, joined the way RFC 9116's example
1083
- * writes them, or `undefined` when one of them is not a tag. Empty is a value.
1084
- */
1085
- function normalizeLanguageList(value) {
1086
- const tags = value
1087
- .split(',')
1088
- .map((tag) => tag.trim())
1089
- .filter((tag) => tag !== '');
1090
- return tags.every((tag) => LANGUAGE_TAG_PATTERN.test(tag)) ? tags.join(', ') : undefined;
1091
- }
1092
- /**
1093
- * What a page slug may be made of on this screen: the shape
1094
- * {@link slugify} produces, which is what the editor writes.
1095
- *
1096
- * The setting travels no further than a lookup by slug, so this is about
1097
- * catching a hand-typed value rather than about safety.
1098
- */
1099
- const PAGE_SLUG_PATTERN = /^[A-Za-z0-9._~-]{1,200}$/;
1100
- /** What is wrong with one page pick, or `undefined`. Empty is a value. */
1101
- function slugProblem(value, what) {
1102
- const slug = value.trim();
1103
- return slug === '' || PAGE_SLUG_PATTERN.test(slug)
1104
- ? undefined
1105
- : `${what} is the slug of one of the site's pages, such as about.`;
1106
- }
1107
- /** Whether `Intl` knows the zone. An empty name is not a zone. */
1108
- function isValidTimezone(value) {
1109
- const zone = value.trim();
1110
- if (zone === '')
1111
- return false;
1112
- try {
1113
- new Intl.DateTimeFormat(undefined, { timeZone: zone });
1114
- return true;
1115
- }
1116
- catch {
1117
- return false;
1118
- }
1119
- }
1120
- /** One site.json as an object, empty when it is missing or will not parse. */
1121
- function readSiteJsonSync(file) {
1122
- return parseSiteJson(readFileIfPresentSync(file) ?? '');
1123
- }
1124
- /** The same, from bytes already in hand. */
1125
- export function parseSiteJson(source) {
1126
- let parsed;
1127
- try {
1128
- parsed = JSON.parse(source);
1129
- }
1130
- catch {
1131
- return {};
1132
- }
1133
- return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)
1134
- ? parsed
1135
- : {};
1136
- }
1137
- /** The three retention periods, as the sweep reads them. */
1138
- export function retentionPolicyOf(settings) {
1139
- return {
1140
- commentEmailDays: settings.commentEmailRetentionDays,
1141
- addressHashDays: settings.addressHashRetentionDays,
1142
- contactMessageDays: settings.contactMessageRetentionDays,
1143
- };
1144
- }
1145
- /** A retention key from `site.json`, when it holds a whole number of days. */
1146
- function wholeDays(file, key) {
1147
- const days = file[key];
1148
- return typeof days === 'number' && Number.isInteger(days) && days >= 0 ? { [key]: days } : {};
1149
- }
1150
- /**
1151
- * What is wrong with a typed retention period, if anything. Empty is refused
1152
- * rather than read as zero, because zero keeps the data forever and a cleared
1153
- * field should not be how a site says that.
1154
- */
1155
- function retentionProblem(typed) {
1156
- const days = Number(typed.trim());
1157
- return typed.trim() === '' || !Number.isInteger(days) || days < 0
1158
- ? 'Keep it for a whole number of days, or 0 to keep it forever.'
1159
- : undefined;
1160
- }
1161
7
  //# sourceMappingURL=settings.js.map