@geekity/cms 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (660) hide show
  1. package/README.md +2217 -214
  2. package/admin/components/fields.njk +165 -0
  3. package/admin/layouts/base.njk +1 -1
  4. package/admin/layouts/settings-page.njk +26 -0
  5. package/admin/layouts/shell.njk +17 -3
  6. package/admin/pages/account/forgot.njk +47 -0
  7. package/admin/pages/account/login.njk +26 -0
  8. package/admin/pages/account/reset.njk +38 -0
  9. package/admin/pages/account/setup.njk +28 -0
  10. package/admin/pages/appearance/themes.njk +69 -0
  11. package/admin/pages/comments/all.njk +133 -0
  12. package/admin/{layouts/dashboard.njk → pages/dashboard/home.njk} +8 -15
  13. package/admin/{layouts/document-conflict.njk → pages/documents/conflict.njk} +1 -0
  14. package/admin/{layouts/document-editor.njk → pages/documents/editor.njk} +75 -59
  15. package/admin/{layouts/document-list.njk → pages/documents/list.njk} +19 -2
  16. package/admin/pages/documents/taxonomy.njk +95 -0
  17. package/admin/pages/federation/followers.njk +238 -0
  18. package/admin/pages/federation/settings.njk +77 -0
  19. package/admin/pages/media/library.njk +160 -0
  20. package/admin/pages/messages/all.njk +110 -0
  21. package/admin/pages/navigation/menus.njk +129 -0
  22. package/admin/{layouts → pages}/placeholder.njk +5 -1
  23. package/admin/pages/settings/discussion.njk +99 -0
  24. package/admin/pages/settings/email.njk +203 -0
  25. package/admin/pages/settings/general.njk +29 -0
  26. package/admin/pages/settings/permalinks.njk +50 -0
  27. package/admin/pages/settings/reading.njk +64 -0
  28. package/admin/pages/tools/content-index.njk +89 -0
  29. package/admin/pages/users/edit.njk +239 -0
  30. package/admin/pages/users/list.njk +51 -0
  31. package/admin/pages/users/new.njk +41 -0
  32. package/admin/static/admin.css +558 -3
  33. package/admin/static/copy.js +52 -0
  34. package/admin/static/editor.js +16 -16
  35. package/admin/static/slug.js +61 -0
  36. package/dist/access-log.d.ts +44 -0
  37. package/dist/access-log.d.ts.map +1 -0
  38. package/dist/access-log.js +71 -0
  39. package/dist/access-log.js.map +1 -0
  40. package/dist/admin/accounts.d.ts +413 -0
  41. package/dist/admin/accounts.d.ts.map +1 -0
  42. package/dist/admin/accounts.js +680 -0
  43. package/dist/admin/accounts.js.map +1 -0
  44. package/dist/admin/appearance.d.ts +80 -0
  45. package/dist/admin/appearance.d.ts.map +1 -0
  46. package/dist/admin/appearance.js +136 -0
  47. package/dist/admin/appearance.js.map +1 -0
  48. package/dist/admin/comments.d.ts +90 -0
  49. package/dist/admin/comments.d.ts.map +1 -0
  50. package/dist/admin/comments.js +244 -0
  51. package/dist/admin/comments.js.map +1 -0
  52. package/dist/admin/credentials.d.ts +26 -2
  53. package/dist/admin/credentials.d.ts.map +1 -1
  54. package/dist/admin/credentials.js +35 -2
  55. package/dist/admin/credentials.js.map +1 -1
  56. package/dist/admin/documents.d.ts +117 -10
  57. package/dist/admin/documents.d.ts.map +1 -1
  58. package/dist/admin/documents.js +328 -41
  59. package/dist/admin/documents.js.map +1 -1
  60. package/dist/admin/federation.d.ts +161 -50
  61. package/dist/admin/federation.d.ts.map +1 -1
  62. package/dist/admin/federation.js +235 -93
  63. package/dist/admin/federation.js.map +1 -1
  64. package/dist/admin/formatting.d.ts +20 -0
  65. package/dist/admin/formatting.d.ts.map +1 -0
  66. package/dist/admin/formatting.js +72 -0
  67. package/dist/admin/formatting.js.map +1 -0
  68. package/dist/admin/headers.d.ts +65 -0
  69. package/dist/admin/headers.d.ts.map +1 -0
  70. package/dist/admin/headers.js +104 -0
  71. package/dist/admin/headers.js.map +1 -0
  72. package/dist/admin/index.d.ts +38 -12
  73. package/dist/admin/index.d.ts.map +1 -1
  74. package/dist/admin/index.js +25 -7
  75. package/dist/admin/index.js.map +1 -1
  76. package/dist/admin/media.d.ts +168 -0
  77. package/dist/admin/media.d.ts.map +1 -0
  78. package/dist/admin/media.js +295 -0
  79. package/dist/admin/media.js.map +1 -0
  80. package/dist/admin/menu.d.ts +79 -0
  81. package/dist/admin/menu.d.ts.map +1 -0
  82. package/dist/admin/menu.js +143 -0
  83. package/dist/admin/menu.js.map +1 -0
  84. package/dist/admin/messages.d.ts +80 -0
  85. package/dist/admin/messages.d.ts.map +1 -0
  86. package/dist/admin/messages.js +152 -0
  87. package/dist/admin/messages.js.map +1 -0
  88. package/dist/admin/navigation.d.ts +155 -0
  89. package/dist/admin/navigation.d.ts.map +1 -0
  90. package/dist/admin/navigation.js +292 -0
  91. package/dist/admin/navigation.js.map +1 -0
  92. package/dist/admin/preview.d.ts.map +1 -1
  93. package/dist/admin/preview.js +31 -7
  94. package/dist/admin/preview.js.map +1 -1
  95. package/dist/admin/recovery.d.ts +92 -0
  96. package/dist/admin/recovery.d.ts.map +1 -0
  97. package/dist/admin/recovery.js +229 -0
  98. package/dist/admin/recovery.js.map +1 -0
  99. package/dist/admin/routes.d.ts +0 -20
  100. package/dist/admin/routes.d.ts.map +1 -1
  101. package/dist/admin/routes.js +164 -105
  102. package/dist/admin/routes.js.map +1 -1
  103. package/dist/admin/session.d.ts +17 -3
  104. package/dist/admin/session.d.ts.map +1 -1
  105. package/dist/admin/session.js +19 -5
  106. package/dist/admin/session.js.map +1 -1
  107. package/dist/admin/settings-discussion.d.ts +37 -0
  108. package/dist/admin/settings-discussion.d.ts.map +1 -0
  109. package/dist/admin/settings-discussion.js +117 -0
  110. package/dist/admin/settings-discussion.js.map +1 -0
  111. package/dist/admin/settings-email.d.ts +54 -0
  112. package/dist/admin/settings-email.d.ts.map +1 -0
  113. package/dist/admin/settings-email.js +189 -0
  114. package/dist/admin/settings-email.js.map +1 -0
  115. package/dist/admin/settings-federation.d.ts +48 -0
  116. package/dist/admin/settings-federation.d.ts.map +1 -0
  117. package/dist/admin/settings-federation.js +123 -0
  118. package/dist/admin/settings-federation.js.map +1 -0
  119. package/dist/admin/settings-general.d.ts +12 -0
  120. package/dist/admin/settings-general.d.ts.map +1 -0
  121. package/dist/admin/settings-general.js +48 -0
  122. package/dist/admin/settings-general.js.map +1 -0
  123. package/dist/admin/settings-page.d.ts +119 -0
  124. package/dist/admin/settings-page.d.ts.map +1 -0
  125. package/dist/admin/settings-page.js +132 -0
  126. package/dist/admin/settings-page.js.map +1 -0
  127. package/dist/admin/settings-pages.d.ts +30 -0
  128. package/dist/admin/settings-pages.d.ts.map +1 -0
  129. package/dist/admin/settings-pages.js +43 -0
  130. package/dist/admin/settings-pages.js.map +1 -0
  131. package/dist/admin/settings-permalinks.d.ts +16 -0
  132. package/dist/admin/settings-permalinks.d.ts.map +1 -0
  133. package/dist/admin/settings-permalinks.js +32 -0
  134. package/dist/admin/settings-permalinks.js.map +1 -0
  135. package/dist/admin/settings-reading.d.ts +34 -0
  136. package/dist/admin/settings-reading.d.ts.map +1 -0
  137. package/dist/admin/settings-reading.js +49 -0
  138. package/dist/admin/settings-reading.js.map +1 -0
  139. package/dist/admin/settings.d.ts +339 -96
  140. package/dist/admin/settings.d.ts.map +1 -1
  141. package/dist/admin/settings.js +600 -308
  142. package/dist/admin/settings.js.map +1 -1
  143. package/dist/admin/store.d.ts +606 -152
  144. package/dist/admin/store.d.ts.map +1 -1
  145. package/dist/admin/store.js +863 -268
  146. package/dist/admin/store.js.map +1 -1
  147. package/dist/admin/taxonomy.d.ts +114 -0
  148. package/dist/admin/taxonomy.d.ts.map +1 -0
  149. package/dist/admin/taxonomy.js +289 -0
  150. package/dist/admin/taxonomy.js.map +1 -0
  151. package/dist/admin/templates.d.ts +46 -14
  152. package/dist/admin/templates.d.ts.map +1 -1
  153. package/dist/admin/templates.js +46 -14
  154. package/dist/admin/templates.js.map +1 -1
  155. package/dist/admin/throttle.d.ts +84 -0
  156. package/dist/admin/throttle.d.ts.map +1 -0
  157. package/dist/admin/throttle.js +143 -0
  158. package/dist/admin/throttle.js.map +1 -0
  159. package/dist/admin/tools.d.ts +111 -0
  160. package/dist/admin/tools.d.ts.map +1 -0
  161. package/dist/admin/tools.js +182 -0
  162. package/dist/admin/tools.js.map +1 -0
  163. package/dist/admin/uploads.d.ts +28 -2
  164. package/dist/admin/uploads.d.ts.map +1 -1
  165. package/dist/admin/uploads.js +43 -4
  166. package/dist/admin/uploads.js.map +1 -1
  167. package/dist/admin/users.d.ts +100 -13
  168. package/dist/admin/users.d.ts.map +1 -1
  169. package/dist/admin/users.js +412 -39
  170. package/dist/admin/users.js.map +1 -1
  171. package/dist/cache.d.ts +141 -0
  172. package/dist/cache.d.ts.map +1 -0
  173. package/dist/cache.js +207 -0
  174. package/dist/cache.js.map +1 -0
  175. package/dist/cli.d.ts +14 -2
  176. package/dist/cli.d.ts.map +1 -1
  177. package/dist/cli.js +429 -21
  178. package/dist/cli.js.map +1 -1
  179. package/dist/comments/akismet.d.ts +130 -0
  180. package/dist/comments/akismet.d.ts.map +1 -0
  181. package/dist/comments/akismet.js +274 -0
  182. package/dist/comments/akismet.js.map +1 -0
  183. package/dist/comments/conversation.d.ts +29 -0
  184. package/dist/comments/conversation.d.ts.map +1 -0
  185. package/dist/comments/conversation.js +60 -0
  186. package/dist/comments/conversation.js.map +1 -0
  187. package/dist/comments/form.d.ts +123 -0
  188. package/dist/comments/form.d.ts.map +1 -0
  189. package/dist/comments/form.js +79 -0
  190. package/dist/comments/form.js.map +1 -0
  191. package/dist/comments/index.d.ts +16 -0
  192. package/dist/comments/index.d.ts.map +1 -0
  193. package/dist/comments/index.js +10 -0
  194. package/dist/comments/index.js.map +1 -0
  195. package/dist/comments/markdown.d.ts +8 -0
  196. package/dist/comments/markdown.d.ts.map +1 -0
  197. package/dist/comments/markdown.js +85 -0
  198. package/dist/comments/markdown.js.map +1 -0
  199. package/dist/comments/moderate.d.ts +71 -0
  200. package/dist/comments/moderate.d.ts.map +1 -0
  201. package/dist/comments/moderate.js +88 -0
  202. package/dist/comments/moderate.js.map +1 -0
  203. package/dist/comments/policy.d.ts +57 -0
  204. package/dist/comments/policy.d.ts.map +1 -0
  205. package/dist/comments/policy.js +80 -0
  206. package/dist/comments/policy.js.map +1 -0
  207. package/dist/comments/records.d.ts +266 -0
  208. package/dist/comments/records.d.ts.map +1 -0
  209. package/dist/comments/records.js +487 -0
  210. package/dist/comments/records.js.map +1 -0
  211. package/dist/comments/routes.d.ts +60 -0
  212. package/dist/comments/routes.d.ts.map +1 -0
  213. package/dist/comments/routes.js +212 -0
  214. package/dist/comments/routes.js.map +1 -0
  215. package/dist/comments/submission.d.ts +297 -0
  216. package/dist/comments/submission.d.ts.map +1 -0
  217. package/dist/comments/submission.js +280 -0
  218. package/dist/comments/submission.js.map +1 -0
  219. package/dist/comments/viewer.d.ts +21 -0
  220. package/dist/comments/viewer.d.ts.map +1 -0
  221. package/dist/comments/viewer.js +45 -0
  222. package/dist/comments/viewer.js.map +1 -0
  223. package/dist/config.d.ts +225 -5
  224. package/dist/config.d.ts.map +1 -1
  225. package/dist/config.js +121 -6
  226. package/dist/config.js.map +1 -1
  227. package/dist/contact/delivery.d.ts +60 -0
  228. package/dist/contact/delivery.d.ts.map +1 -0
  229. package/dist/contact/delivery.js +87 -0
  230. package/dist/contact/delivery.js.map +1 -0
  231. package/dist/contact/form.d.ts +130 -0
  232. package/dist/contact/form.d.ts.map +1 -0
  233. package/dist/contact/form.js +163 -0
  234. package/dist/contact/form.js.map +1 -0
  235. package/dist/contact/index.d.ts +17 -0
  236. package/dist/contact/index.d.ts.map +1 -0
  237. package/dist/contact/index.js +13 -0
  238. package/dist/contact/index.js.map +1 -0
  239. package/dist/contact/records.d.ts +124 -0
  240. package/dist/contact/records.d.ts.map +1 -0
  241. package/dist/contact/records.js +218 -0
  242. package/dist/contact/records.js.map +1 -0
  243. package/dist/contact/routes.d.ts +17 -0
  244. package/dist/contact/routes.d.ts.map +1 -0
  245. package/dist/contact/routes.js +127 -0
  246. package/dist/contact/routes.js.map +1 -0
  247. package/dist/contact/submission.d.ts +103 -0
  248. package/dist/contact/submission.d.ts.map +1 -0
  249. package/dist/contact/submission.js +166 -0
  250. package/dist/contact/submission.js.map +1 -0
  251. package/dist/content/document.d.ts +7 -2
  252. package/dist/content/document.d.ts.map +1 -1
  253. package/dist/content/document.js +1 -0
  254. package/dist/content/document.js.map +1 -1
  255. package/dist/content/index.d.ts +7 -2
  256. package/dist/content/index.d.ts.map +1 -1
  257. package/dist/content/index.js +4 -1
  258. package/dist/content/index.js.map +1 -1
  259. package/dist/content/markdown.d.ts.map +1 -1
  260. package/dist/content/markdown.js +24 -2
  261. package/dist/content/markdown.js.map +1 -1
  262. package/dist/content/parser.d.ts.map +1 -1
  263. package/dist/content/parser.js +11 -4
  264. package/dist/content/parser.js.map +1 -1
  265. package/dist/content/save.d.ts +5 -0
  266. package/dist/content/save.d.ts.map +1 -1
  267. package/dist/content/save.js +44 -1
  268. package/dist/content/save.js.map +1 -1
  269. package/dist/content/schedule.d.ts +125 -0
  270. package/dist/content/schedule.d.ts.map +1 -0
  271. package/dist/content/schedule.js +207 -0
  272. package/dist/content/schedule.js.map +1 -0
  273. package/dist/content/search.d.ts +64 -0
  274. package/dist/content/search.d.ts.map +1 -0
  275. package/dist/content/search.js +136 -0
  276. package/dist/content/search.js.map +1 -0
  277. package/dist/content/store.d.ts +220 -7
  278. package/dist/content/store.d.ts.map +1 -1
  279. package/dist/content/store.js +392 -67
  280. package/dist/content/store.js.map +1 -1
  281. package/dist/content/sync.d.ts +7 -1
  282. package/dist/content/sync.d.ts.map +1 -1
  283. package/dist/content/sync.js +18 -10
  284. package/dist/content/sync.js.map +1 -1
  285. package/dist/content/time.d.ts +56 -0
  286. package/dist/content/time.d.ts.map +1 -0
  287. package/dist/content/time.js +141 -0
  288. package/dist/content/time.js.map +1 -0
  289. package/dist/content/writer.d.ts.map +1 -1
  290. package/dist/content/writer.js +3 -0
  291. package/dist/content/writer.js.map +1 -1
  292. package/dist/env.d.ts +70 -5
  293. package/dist/env.d.ts.map +1 -1
  294. package/dist/federation/actor.d.ts +95 -41
  295. package/dist/federation/actor.d.ts.map +1 -1
  296. package/dist/federation/actor.js +180 -53
  297. package/dist/federation/actor.js.map +1 -1
  298. package/dist/federation/article.d.ts +44 -17
  299. package/dist/federation/article.d.ts.map +1 -1
  300. package/dist/federation/article.js +98 -46
  301. package/dist/federation/article.js.map +1 -1
  302. package/dist/federation/delivery.d.ts +63 -15
  303. package/dist/federation/delivery.d.ts.map +1 -1
  304. package/dist/federation/delivery.js +154 -80
  305. package/dist/federation/delivery.js.map +1 -1
  306. package/dist/federation/federation.d.ts +22 -17
  307. package/dist/federation/federation.d.ts.map +1 -1
  308. package/dist/federation/federation.js +98 -77
  309. package/dist/federation/federation.js.map +1 -1
  310. package/dist/federation/followers.d.ts +3 -2
  311. package/dist/federation/followers.d.ts.map +1 -1
  312. package/dist/federation/followers.js +6 -5
  313. package/dist/federation/followers.js.map +1 -1
  314. package/dist/federation/import-wordpress.d.ts +128 -0
  315. package/dist/federation/import-wordpress.d.ts.map +1 -0
  316. package/dist/federation/import-wordpress.js +426 -0
  317. package/dist/federation/import-wordpress.js.map +1 -0
  318. package/dist/federation/inbox.d.ts +36 -13
  319. package/dist/federation/inbox.d.ts.map +1 -1
  320. package/dist/federation/inbox.js +120 -49
  321. package/dist/federation/inbox.js.map +1 -1
  322. package/dist/federation/index.d.ts +22 -10
  323. package/dist/federation/index.d.ts.map +1 -1
  324. package/dist/federation/index.js +13 -8
  325. package/dist/federation/index.js.map +1 -1
  326. package/dist/federation/keys.d.ts +98 -20
  327. package/dist/federation/keys.d.ts.map +1 -1
  328. package/dist/federation/keys.js +269 -39
  329. package/dist/federation/keys.js.map +1 -1
  330. package/dist/federation/mount.d.ts +46 -10
  331. package/dist/federation/mount.d.ts.map +1 -1
  332. package/dist/federation/mount.js +300 -28
  333. package/dist/federation/mount.js.map +1 -1
  334. package/dist/federation/paths.d.ts +23 -35
  335. package/dist/federation/paths.d.ts.map +1 -1
  336. package/dist/federation/paths.js +26 -39
  337. package/dist/federation/paths.js.map +1 -1
  338. package/dist/federation/records.d.ts +223 -0
  339. package/dist/federation/records.d.ts.map +1 -0
  340. package/dist/federation/records.js +506 -0
  341. package/dist/federation/records.js.map +1 -0
  342. package/dist/federation/relays.d.ts +114 -0
  343. package/dist/federation/relays.d.ts.map +1 -0
  344. package/dist/federation/relays.js +290 -0
  345. package/dist/federation/relays.js.map +1 -0
  346. package/dist/federation/replies.d.ts +80 -0
  347. package/dist/federation/replies.d.ts.map +1 -0
  348. package/dist/federation/replies.js +166 -0
  349. package/dist/federation/replies.js.map +1 -0
  350. package/dist/federation/wordpress.d.ts +131 -0
  351. package/dist/federation/wordpress.d.ts.map +1 -0
  352. package/dist/federation/wordpress.js +341 -0
  353. package/dist/federation/wordpress.js.map +1 -0
  354. package/dist/files/atomic.d.ts +103 -0
  355. package/dist/files/atomic.d.ts.map +1 -0
  356. package/dist/files/atomic.js +150 -0
  357. package/dist/files/atomic.js.map +1 -0
  358. package/dist/files/index.d.ts +3 -0
  359. package/dist/files/index.d.ts.map +1 -0
  360. package/dist/files/index.js +2 -0
  361. package/dist/files/index.js.map +1 -0
  362. package/dist/forms/protection.d.ts +85 -0
  363. package/dist/forms/protection.d.ts.map +1 -0
  364. package/dist/forms/protection.js +116 -0
  365. package/dist/forms/protection.js.map +1 -0
  366. package/dist/images/icons.d.ts +59 -0
  367. package/dist/images/icons.d.ts.map +1 -0
  368. package/dist/images/icons.js +131 -0
  369. package/dist/images/icons.js.map +1 -0
  370. package/dist/images/index.d.ts +7 -0
  371. package/dist/images/index.d.ts.map +1 -0
  372. package/dist/images/index.js +4 -0
  373. package/dist/images/index.js.map +1 -0
  374. package/dist/images/markup.d.ts +47 -0
  375. package/dist/images/markup.d.ts.map +1 -0
  376. package/dist/images/markup.js +175 -0
  377. package/dist/images/markup.js.map +1 -0
  378. package/dist/images/paths.d.ts +34 -0
  379. package/dist/images/paths.d.ts.map +1 -0
  380. package/dist/images/paths.js +41 -0
  381. package/dist/images/paths.js.map +1 -0
  382. package/dist/images/variants.d.ts +104 -0
  383. package/dist/images/variants.d.ts.map +1 -0
  384. package/dist/images/variants.js +320 -0
  385. package/dist/images/variants.js.map +1 -0
  386. package/dist/index.d.ts +123 -19
  387. package/dist/index.d.ts.map +1 -1
  388. package/dist/index.js +344 -25
  389. package/dist/index.js.map +1 -1
  390. package/dist/init.d.ts +18 -0
  391. package/dist/init.d.ts.map +1 -1
  392. package/dist/init.js +34 -3
  393. package/dist/init.js.map +1 -1
  394. package/dist/mail/brevo.d.ts +35 -0
  395. package/dist/mail/brevo.d.ts.map +1 -0
  396. package/dist/mail/brevo.js +85 -0
  397. package/dist/mail/brevo.js.map +1 -0
  398. package/dist/mail/credentials.d.ts +62 -0
  399. package/dist/mail/credentials.d.ts.map +1 -0
  400. package/dist/mail/credentials.js +86 -0
  401. package/dist/mail/credentials.js.map +1 -0
  402. package/dist/mail/index.d.ts +15 -0
  403. package/dist/mail/index.d.ts.map +1 -0
  404. package/dist/mail/index.js +8 -0
  405. package/dist/mail/index.js.map +1 -0
  406. package/dist/mail/memory.d.ts +35 -0
  407. package/dist/mail/memory.d.ts.map +1 -0
  408. package/dist/mail/memory.js +29 -0
  409. package/dist/mail/memory.js.map +1 -0
  410. package/dist/mail/provider.d.ts +80 -0
  411. package/dist/mail/provider.d.ts.map +1 -0
  412. package/dist/mail/provider.js +23 -0
  413. package/dist/mail/provider.js.map +1 -0
  414. package/dist/mail/service.d.ts +156 -0
  415. package/dist/mail/service.d.ts.map +1 -0
  416. package/dist/mail/service.js +265 -0
  417. package/dist/mail/service.js.map +1 -0
  418. package/dist/mail/smtp.d.ts +39 -0
  419. package/dist/mail/smtp.d.ts.map +1 -0
  420. package/dist/mail/smtp.js +58 -0
  421. package/dist/mail/smtp.js.map +1 -0
  422. package/dist/mail/templates.d.ts +91 -0
  423. package/dist/mail/templates.d.ts.map +1 -0
  424. package/dist/mail/templates.js +69 -0
  425. package/dist/mail/templates.js.map +1 -0
  426. package/dist/notifications/comments.d.ts +66 -0
  427. package/dist/notifications/comments.d.ts.map +1 -0
  428. package/dist/notifications/comments.js +151 -0
  429. package/dist/notifications/comments.js.map +1 -0
  430. package/dist/notifications/digest.d.ts +135 -0
  431. package/dist/notifications/digest.d.ts.map +1 -0
  432. package/dist/notifications/digest.js +287 -0
  433. package/dist/notifications/digest.js.map +1 -0
  434. package/dist/notifications/index.d.ts +13 -0
  435. package/dist/notifications/index.d.ts.map +1 -0
  436. package/dist/notifications/index.js +8 -0
  437. package/dist/notifications/index.js.map +1 -0
  438. package/dist/notifications/links.d.ts +60 -0
  439. package/dist/notifications/links.d.ts.map +1 -0
  440. package/dist/notifications/links.js +63 -0
  441. package/dist/notifications/links.js.map +1 -0
  442. package/dist/notifications/optouts.d.ts +48 -0
  443. package/dist/notifications/optouts.d.ts.map +1 -0
  444. package/dist/notifications/optouts.js +93 -0
  445. package/dist/notifications/optouts.js.map +1 -0
  446. package/dist/notifications/preferences.d.ts +158 -0
  447. package/dist/notifications/preferences.d.ts.map +1 -0
  448. package/dist/notifications/preferences.js +195 -0
  449. package/dist/notifications/preferences.js.map +1 -0
  450. package/dist/notifications/routes.d.ts +28 -0
  451. package/dist/notifications/routes.d.ts.map +1 -0
  452. package/dist/notifications/routes.js +184 -0
  453. package/dist/notifications/routes.js.map +1 -0
  454. package/dist/notifications/tokens.d.ts +60 -0
  455. package/dist/notifications/tokens.d.ts.map +1 -0
  456. package/dist/notifications/tokens.js +125 -0
  457. package/dist/notifications/tokens.js.map +1 -0
  458. package/dist/notify.d.ts +84 -0
  459. package/dist/notify.d.ts.map +1 -0
  460. package/dist/notify.js +149 -0
  461. package/dist/notify.js.map +1 -0
  462. package/dist/web/archive.d.ts +49 -0
  463. package/dist/web/archive.d.ts.map +1 -0
  464. package/dist/web/archive.js +59 -0
  465. package/dist/web/archive.js.map +1 -0
  466. package/dist/web/assets.d.ts +6 -5
  467. package/dist/web/assets.d.ts.map +1 -1
  468. package/dist/web/assets.js +5 -7
  469. package/dist/web/assets.js.map +1 -1
  470. package/dist/web/authors.d.ts +143 -0
  471. package/dist/web/authors.d.ts.map +1 -0
  472. package/dist/web/authors.js +178 -0
  473. package/dist/web/authors.js.map +1 -0
  474. package/dist/web/comments.d.ts +60 -0
  475. package/dist/web/comments.d.ts.map +1 -0
  476. package/dist/web/comments.js +207 -0
  477. package/dist/web/comments.js.map +1 -0
  478. package/dist/web/context.d.ts +162 -28
  479. package/dist/web/context.d.ts.map +1 -1
  480. package/dist/web/context.js +123 -26
  481. package/dist/web/context.js.map +1 -1
  482. package/dist/web/conversation.d.ts +209 -0
  483. package/dist/web/conversation.d.ts.map +1 -0
  484. package/dist/web/conversation.js +557 -0
  485. package/dist/web/conversation.js.map +1 -0
  486. package/dist/web/documents.d.ts +36 -6
  487. package/dist/web/documents.d.ts.map +1 -1
  488. package/dist/web/documents.js +52 -10
  489. package/dist/web/documents.js.map +1 -1
  490. package/dist/web/feed-atom.d.ts +22 -0
  491. package/dist/web/feed-atom.d.ts.map +1 -0
  492. package/dist/web/feed-atom.js +83 -0
  493. package/dist/web/feed-atom.js.map +1 -0
  494. package/dist/web/feed-item.d.ts +145 -0
  495. package/dist/web/feed-item.d.ts.map +1 -0
  496. package/dist/web/feed-item.js +120 -0
  497. package/dist/web/feed-item.js.map +1 -0
  498. package/dist/web/feed-json.d.ts +79 -0
  499. package/dist/web/feed-json.d.ts.map +1 -0
  500. package/dist/web/feed-json.js +53 -0
  501. package/dist/web/feed-json.js.map +1 -0
  502. package/dist/web/feed-rss.d.ts +26 -0
  503. package/dist/web/feed-rss.d.ts.map +1 -0
  504. package/dist/web/feed-rss.js +203 -0
  505. package/dist/web/feed-rss.js.map +1 -0
  506. package/dist/web/feed-source.d.ts +244 -0
  507. package/dist/web/feed-source.d.ts.map +1 -0
  508. package/dist/web/feed-source.js +201 -0
  509. package/dist/web/feed-source.js.map +1 -0
  510. package/dist/web/feed-xml.d.ts +63 -0
  511. package/dist/web/feed-xml.d.ts.map +1 -0
  512. package/dist/web/feed-xml.js +116 -0
  513. package/dist/web/feed-xml.js.map +1 -0
  514. package/dist/web/feeds.d.ts +31 -96
  515. package/dist/web/feeds.d.ts.map +1 -1
  516. package/dist/web/feeds.js +94 -198
  517. package/dist/web/feeds.js.map +1 -1
  518. package/dist/web/health.d.ts +31 -0
  519. package/dist/web/health.d.ts.map +1 -0
  520. package/dist/web/health.js +44 -0
  521. package/dist/web/health.js.map +1 -0
  522. package/dist/web/index.d.ts +30 -10
  523. package/dist/web/index.d.ts.map +1 -1
  524. package/dist/web/index.js +18 -7
  525. package/dist/web/index.js.map +1 -1
  526. package/dist/web/navigation.d.ts +195 -0
  527. package/dist/web/navigation.d.ts.map +1 -0
  528. package/dist/web/navigation.js +300 -0
  529. package/dist/web/navigation.js.map +1 -0
  530. package/dist/web/negotiate.d.ts +31 -0
  531. package/dist/web/negotiate.d.ts.map +1 -1
  532. package/dist/web/negotiate.js +31 -11
  533. package/dist/web/negotiate.js.map +1 -1
  534. package/dist/web/recent.d.ts +43 -0
  535. package/dist/web/recent.d.ts.map +1 -0
  536. package/dist/web/recent.js +37 -0
  537. package/dist/web/recent.js.map +1 -0
  538. package/dist/web/render.d.ts +203 -9
  539. package/dist/web/render.d.ts.map +1 -1
  540. package/dist/web/render.js +341 -17
  541. package/dist/web/render.js.map +1 -1
  542. package/dist/web/routes.d.ts +25 -8
  543. package/dist/web/routes.d.ts.map +1 -1
  544. package/dist/web/routes.js +854 -93
  545. package/dist/web/routes.js.map +1 -1
  546. package/dist/web/sanitize.d.ts +19 -0
  547. package/dist/web/sanitize.d.ts.map +1 -0
  548. package/dist/web/sanitize.js +272 -0
  549. package/dist/web/sanitize.js.map +1 -0
  550. package/dist/web/search.d.ts +79 -0
  551. package/dist/web/search.d.ts.map +1 -0
  552. package/dist/web/search.js +94 -0
  553. package/dist/web/search.js.map +1 -0
  554. package/dist/web/sitemap.d.ts +120 -0
  555. package/dist/web/sitemap.d.ts.map +1 -0
  556. package/dist/web/sitemap.js +199 -0
  557. package/dist/web/sitemap.js.map +1 -0
  558. package/dist/web/taxonomy.d.ts +152 -0
  559. package/dist/web/taxonomy.d.ts.map +1 -0
  560. package/dist/web/taxonomy.js +237 -0
  561. package/dist/web/taxonomy.js.map +1 -0
  562. package/dist/web/templates.d.ts +54 -16
  563. package/dist/web/templates.d.ts.map +1 -1
  564. package/dist/web/templates.js +109 -28
  565. package/dist/web/templates.js.map +1 -1
  566. package/dist/web/themes.d.ts +226 -0
  567. package/dist/web/themes.d.ts.map +1 -0
  568. package/dist/web/themes.js +314 -0
  569. package/dist/web/themes.js.map +1 -0
  570. package/dist/webmention/discovery.d.ts +51 -0
  571. package/dist/webmention/discovery.d.ts.map +1 -0
  572. package/dist/webmention/discovery.js +176 -0
  573. package/dist/webmention/discovery.js.map +1 -0
  574. package/dist/webmention/html.d.ts +71 -0
  575. package/dist/webmention/html.d.ts.map +1 -0
  576. package/dist/webmention/html.js +285 -0
  577. package/dist/webmention/html.js.map +1 -0
  578. package/dist/webmention/index.d.ts +12 -0
  579. package/dist/webmention/index.d.ts.map +1 -0
  580. package/dist/webmention/index.js +8 -0
  581. package/dist/webmention/index.js.map +1 -0
  582. package/dist/webmention/links.d.ts +18 -0
  583. package/dist/webmention/links.d.ts.map +1 -0
  584. package/dist/webmention/links.js +64 -0
  585. package/dist/webmention/links.js.map +1 -0
  586. package/dist/webmention/microformats.d.ts +93 -0
  587. package/dist/webmention/microformats.d.ts.map +1 -0
  588. package/dist/webmention/microformats.js +376 -0
  589. package/dist/webmention/microformats.js.map +1 -0
  590. package/dist/webmention/receive.d.ts +141 -0
  591. package/dist/webmention/receive.d.ts.map +1 -0
  592. package/dist/webmention/receive.js +264 -0
  593. package/dist/webmention/receive.js.map +1 -0
  594. package/dist/webmention/routes.d.ts +37 -0
  595. package/dist/webmention/routes.d.ts.map +1 -0
  596. package/dist/webmention/routes.js +75 -0
  597. package/dist/webmention/routes.js.map +1 -0
  598. package/dist/webmention/service.d.ts +94 -0
  599. package/dist/webmention/service.d.ts.map +1 -0
  600. package/dist/webmention/service.js +207 -0
  601. package/dist/webmention/service.js.map +1 -0
  602. package/package.json +11 -6
  603. package/templates/site/content/_data/site.json +8 -0
  604. package/templates/site/content/pages/about.md +7 -0
  605. package/templates/site/content/posts/2026-01-01-hello-world.md +5 -3
  606. package/templates/site/geekity.config.ts +11 -1
  607. package/templates/site/tsconfig.json +1 -1
  608. package/themes/default/README.md +1216 -50
  609. package/themes/default/layouts/404.njk +2 -3
  610. package/themes/default/layouts/author.njk +36 -0
  611. package/themes/default/layouts/base.njk +161 -31
  612. package/themes/default/layouts/category.njk +27 -0
  613. package/themes/default/layouts/front-page.njk +56 -0
  614. package/themes/default/layouts/home.njk +17 -1
  615. package/themes/default/layouts/page.njk +57 -5
  616. package/themes/default/layouts/post.njk +78 -19
  617. package/themes/default/layouts/search.njk +57 -0
  618. package/themes/default/layouts/tag.njk +3 -6
  619. package/themes/default/mail/comment-digest.html.njk +37 -0
  620. package/themes/default/mail/comment-digest.subject.njk +3 -0
  621. package/themes/default/mail/comment-digest.txt.njk +40 -0
  622. package/themes/default/mail/comment-pending.html.njk +27 -0
  623. package/themes/default/mail/comment-pending.subject.njk +2 -0
  624. package/themes/default/mail/comment-pending.txt.njk +24 -0
  625. package/themes/default/mail/comment-reply.html.njk +21 -0
  626. package/themes/default/mail/comment-reply.subject.njk +2 -0
  627. package/themes/default/mail/comment-reply.txt.njk +22 -0
  628. package/themes/default/mail/contact-message.html.njk +24 -0
  629. package/themes/default/mail/contact-message.subject.njk +5 -0
  630. package/themes/default/mail/contact-message.txt.njk +20 -0
  631. package/themes/default/mail/password-changed.html.njk +18 -0
  632. package/themes/default/mail/password-changed.subject.njk +2 -0
  633. package/themes/default/mail/password-changed.txt.njk +17 -0
  634. package/themes/default/mail/password-reset.html.njk +22 -0
  635. package/themes/default/mail/password-reset.subject.njk +2 -0
  636. package/themes/default/mail/password-reset.txt.njk +18 -0
  637. package/themes/default/mail/test.html.njk +14 -0
  638. package/themes/default/mail/test.subject.njk +2 -0
  639. package/themes/default/mail/test.txt.njk +12 -0
  640. package/themes/default/partials/archive.njk +27 -0
  641. package/themes/default/partials/bio.njk +71 -0
  642. package/themes/default/partials/comment-form.njk +137 -0
  643. package/themes/default/partials/contact-form.njk +88 -0
  644. package/themes/default/partials/conversation.njk +139 -0
  645. package/themes/default/partials/feeds.njk +26 -0
  646. package/themes/default/partials/jsonld.njk +120 -0
  647. package/themes/default/partials/menu.njk +32 -0
  648. package/themes/default/partials/pagination.njk +12 -6
  649. package/themes/default/partials/post-list.njk +51 -18
  650. package/themes/default/partials/search-form.njk +22 -0
  651. package/themes/default/partials/tags.njk +26 -5
  652. package/themes/default/static/highlight.js +4 -0
  653. package/themes/default/static/style.css +1142 -194
  654. package/themes/default/theme.json +9 -0
  655. package/admin/layouts/federation.njk +0 -145
  656. package/admin/layouts/login.njk +0 -23
  657. package/admin/layouts/settings.njk +0 -116
  658. package/admin/layouts/setup.njk +0 -27
  659. package/admin/layouts/users.njk +0 -91
  660. /package/admin/{layouts/_flash.njk → components/flash.njk} +0 -0
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Where a theme is, and what makes a directory one.
3
+ *
4
+ * This module is the only place that knows the packaged theme's path and the
5
+ * order the directories are searched in. The template environment, the
6
+ * `/theme/` asset finder, the mail environment and the per-render probe for
7
+ * the optional front-page and posts-page layouts all ask here, so there is one
8
+ * answer to "which theme is this render reading from" rather than four copies
9
+ * of the same two-element array (decision-15).
10
+ *
11
+ * The admin is deliberately not a theme. Its templates and its static files
12
+ * live at `admin/` with a loader of their own and are never on this path, so a
13
+ * site theme cannot shadow the login form or the CSRF field inside it
14
+ * (decision-4).
15
+ */
16
+ /**
17
+ * The theme that ships inside the package, resolved from this module rather
18
+ * than from the working directory, so it is found whether the CMS is running
19
+ * from `src/` under tsx or from `dist/` as an installed dependency.
20
+ */
21
+ export declare const PACKAGED_THEME_DIR: string;
22
+ /** The file a directory declares itself a theme with. */
23
+ export declare const THEME_MANIFEST_FILE = "theme.json";
24
+ /**
25
+ * The only kind of theme there is.
26
+ *
27
+ * The field exists so a second kind — the admin, if it is ever made
28
+ * overridable — can slot in without the manifest format changing, and so a
29
+ * manifest that names a kind this CMS does not have is refused rather than
30
+ * loaded as a site theme by accident.
31
+ */
32
+ export declare const SITE_THEME_KIND = "site";
33
+ /** What kinds of theme a manifest may declare. One, today. */
34
+ export type ThemeKind = typeof SITE_THEME_KIND;
35
+ /**
36
+ * One place a theme renders a menu, as its `theme.json` declares it.
37
+ *
38
+ * A theme decides where a menu can go, and the screen that edits menus cannot
39
+ * know what a theme wants (TASK-107). So the theme says: a `name`, which is
40
+ * the key a site stores that menu under in `site.json` and the key the
41
+ * template context carries it as, and a `label` for the person choosing which
42
+ * menu to fill in.
43
+ */
44
+ export interface ThemeArea {
45
+ /** The menu's name: what `menus` is keyed by in `site.json` and in a render. */
46
+ readonly name: string;
47
+ /** What the Navigation screen calls this place, for a person to read. */
48
+ readonly label: string;
49
+ }
50
+ /** One theme directory, read and validated. */
51
+ export interface Theme {
52
+ /** The directory name, which is the theme's id and what a site.json names. */
53
+ readonly id: string;
54
+ /** Absolute path to the directory the manifest was read from. */
55
+ readonly dir: string;
56
+ /** The display name, for the admin's list. */
57
+ readonly name: string;
58
+ /** What the theme themes. Always {@link SITE_THEME_KIND} today. */
59
+ readonly kind: ThemeKind;
60
+ /** One line about the theme, when the manifest wrote one. */
61
+ readonly description?: string | undefined;
62
+ /**
63
+ * Where this theme renders a menu, in the order the manifest names them.
64
+ * Empty for a theme that declares none, which is every theme written before
65
+ * areas existed and every theme that renders no menu at all.
66
+ */
67
+ readonly areas: readonly ThemeArea[];
68
+ }
69
+ /** A theme, or the reason the directory is not one. */
70
+ export type ThemeRead = {
71
+ readonly ok: true;
72
+ readonly theme: Theme;
73
+ } | {
74
+ readonly ok: false;
75
+ readonly reason: string;
76
+ };
77
+ /**
78
+ * Read one directory as a theme.
79
+ *
80
+ * Every way of not being a theme comes back the same way — `ok: false` and a
81
+ * sentence saying why — because every caller has the same job with it: a
82
+ * listing greys the directory out, a chosen theme that stopped being one falls
83
+ * back to the packaged default with the reason logged, and the admin refuses
84
+ * to save it. None of them wants an exception, and a directory that is simply
85
+ * not a theme is not exceptional: a site's `themes/` will have a `.DS_Store`
86
+ * in it soon enough.
87
+ */
88
+ export declare function readTheme(dir: string): ThemeRead;
89
+ /** A directory under the themes directory that turned out not to be a theme. */
90
+ export interface UnreadableTheme {
91
+ /** The directory name, as it sits on disk. */
92
+ readonly id: string;
93
+ /** Absolute path to it, so the screen can say where to go and look. */
94
+ readonly dir: string;
95
+ /** Why it is not a theme: {@link ThemeRead}'s reason. */
96
+ readonly reason: string;
97
+ }
98
+ /** What is in a site's themes directory: the themes, and the near misses. */
99
+ export interface SiteThemes {
100
+ /** Every directory that is a theme, by directory name. */
101
+ readonly themes: readonly Theme[];
102
+ /** Every directory that was meant to be one and is not. */
103
+ readonly unreadable: readonly UnreadableTheme[];
104
+ }
105
+ /**
106
+ * Everything in one site's themes directory.
107
+ *
108
+ * Both halves come back because the Appearance screen draws both: a folder
109
+ * with a typo in its `theme.json` is listed with the reason rather than
110
+ * silently skipped, because a theme that has quietly vanished from the list is
111
+ * the hardest kind of mistake to find. The screen is the only caller —
112
+ * rendering asks {@link chooseTheme} about one name instead, and never reads
113
+ * the directory.
114
+ *
115
+ * Only a subdirectory is a candidate, and a hidden one is not even that: a
116
+ * `themes/` with a `.DS_Store`, a `README.md` or a `.git` in it is a site with
117
+ * no broken themes, not a site with three of them.
118
+ *
119
+ * A themes directory that is not there is an empty one. Nothing scaffolds it
120
+ * (decision-15), so a site that has never written a theme has no directory,
121
+ * and that is the ordinary state rather than a problem to report.
122
+ */
123
+ export declare function listSiteThemes(themesDir: string): SiteThemes;
124
+ /**
125
+ * The theme directories one render reads from, in order: the theme the site
126
+ * has chosen first, the theme that ships in this package second.
127
+ *
128
+ * That is the whole override mechanism. A theme that ships only
129
+ * `layouts/post.njk` replaces the post layout and keeps receiving updates to
130
+ * every other template, and the same order decides a `/theme/` asset and a
131
+ * mail template. The chosen directory need not exist.
132
+ *
133
+ * A site that has chosen nothing passes nothing, and reads the packaged theme
134
+ * alone: an unchosen theme is never on the path, and the packaged one is never
135
+ * on it twice (decision-15).
136
+ */
137
+ export declare function themeSearchPath(chosenThemeDir?: string): string[];
138
+ /**
139
+ * What a `theme` in `site.json` may be: the name of one directory inside the
140
+ * themes directory, and nothing that would reach outside it.
141
+ *
142
+ * The setting is a word somebody picks off a list, so this is about a
143
+ * hand-edited file rather than about an attacker — but the value decides a
144
+ * directory every template is then read out of, so it is checked before it is
145
+ * joined to a path rather than after.
146
+ */
147
+ export declare function themeNameProblem(name: string): string | undefined;
148
+ /** Which theme a render reads from, and why it is that one. */
149
+ export interface ChosenTheme {
150
+ /** The site theme in use, or `undefined` when the packaged one is. */
151
+ readonly theme: Theme | undefined;
152
+ /** The directories to read, in order: {@link themeSearchPath}. */
153
+ readonly dirs: readonly string[];
154
+ /**
155
+ * Why the theme the site named is not the one in use, when it named one that
156
+ * is not there or is not a theme. `undefined` both for a site running the
157
+ * packaged theme on purpose and for one whose choice is working.
158
+ */
159
+ readonly problem: string | undefined;
160
+ }
161
+ /**
162
+ * The theme one site has chosen, resolved against its themes directory.
163
+ *
164
+ * A choice that cannot be honoured is the packaged theme and a sentence saying
165
+ * why, never an exception: a theme deleted from disk, or a `theme.json` broken
166
+ * by a hand edit, has to leave the site up and answering — the alternative is
167
+ * a site that 500s on every page because of a directory rename.
168
+ */
169
+ export declare function chooseTheme(options: {
170
+ themesDir: string;
171
+ name: string;
172
+ }): ChosenTheme;
173
+ /** Where {@link createThemeSource} says what it could not do. */
174
+ export interface ThemeLogger {
175
+ warn(message: string): void;
176
+ }
177
+ /** The theme in use right now, asked afresh whenever anything renders. */
178
+ export interface ThemeSource {
179
+ /**
180
+ * The theme this render reads from.
181
+ *
182
+ * Cheap enough to call per render: it costs one read of the site's choice —
183
+ * which is itself cached against the `stat` of `site.json` — and one `stat`
184
+ * of the chosen theme's manifest.
185
+ */
186
+ current(): ChosenTheme;
187
+ }
188
+ /**
189
+ * The one thing that knows which theme a site is rendering through.
190
+ *
191
+ * It is a source rather than a value because the choice is a setting in
192
+ * `content/_data/site.json` (decision-9, decision-15): the Appearance screen
193
+ * writes that file, a hand edit writes the same file, and both have to reach
194
+ * the next request without a restart. So every consumer — the template
195
+ * environment, the `/theme/` assets, the mail templates — asks here per render
196
+ * instead of being handed a directory at boot.
197
+ *
198
+ * The result is cached against the choice and the `stat` of the chosen theme's
199
+ * manifest, so an unchanged site pays one `stat` per render and a theme
200
+ * edited, replaced or deleted under the running process is noticed on the next
201
+ * one. A choice that cannot be honoured is logged once, when the answer
202
+ * changes, rather than on every render: a site whose theme has been deleted
203
+ * should say so in the log and then serve pages, not fill the log with the
204
+ * same line.
205
+ */
206
+ export declare function createThemeSource(options: {
207
+ /** Where the site's themes are: {@link ResolvedConfig.themesDir}. */
208
+ themesDir: string;
209
+ /** The site's choice, read per call. The empty string is the packaged theme. */
210
+ chosen: () => string;
211
+ /** Where a choice that could not be honoured is reported. Defaults to `console`. */
212
+ logger?: ThemeLogger | undefined;
213
+ }): ThemeSource;
214
+ /**
215
+ * The first theme on the path that ships one file, by absolute path, or
216
+ * `undefined` when none of them does.
217
+ *
218
+ * Nunjucks resolves its own templates through the same order, so this is for
219
+ * the two questions asked outside a render: whether a theme has written the
220
+ * optional front-page or posts-page layout, and which halves of a mail message
221
+ * exist. A path that climbs out of a theme directory finds nothing, so a
222
+ * caller passing a name through from a request cannot reach the file system
223
+ * around it.
224
+ */
225
+ export declare function findThemeFile(themeDirs: readonly string[], relative: string): string | undefined;
226
+ //# sourceMappingURL=themes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../src/web/themes.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAEhC,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,SAAS,CAAC;AAEtC,8DAA8D;AAC9D,MAAM,MAAM,SAAS,GAAG,OAAO,eAAe,CAAC;AAE/C;;;;;;;;GAQG;AACH,MAAM,WAAW,SAAS;IACxB,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,+CAA+C;AAC/C,MAAM,WAAW,KAAK;IACpB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,6DAA6D;IAC7D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;CACtC;AAED,uDAAuD;AACvD,MAAM,MAAM,SAAS,GACnB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjG;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAsDhD;AAwCD,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,6EAA6E;AAC7E,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;IAClC,2DAA2D;IAC3D,QAAQ,CAAC,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;CACjD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAuB5D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOjE;AAED,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAmBrF;AAED,iEAAiE;AACjE,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,OAAO,IAAI,WAAW,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,MAAM,EAAE,MAAM,MAAM,CAAC;IACrB,oFAAoF;IACpF,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAClC,GAAG,WAAW,CAwCd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAYhG"}
@@ -0,0 +1,314 @@
1
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ /**
5
+ * Where a theme is, and what makes a directory one.
6
+ *
7
+ * This module is the only place that knows the packaged theme's path and the
8
+ * order the directories are searched in. The template environment, the
9
+ * `/theme/` asset finder, the mail environment and the per-render probe for
10
+ * the optional front-page and posts-page layouts all ask here, so there is one
11
+ * answer to "which theme is this render reading from" rather than four copies
12
+ * of the same two-element array (decision-15).
13
+ *
14
+ * The admin is deliberately not a theme. Its templates and its static files
15
+ * live at `admin/` with a loader of their own and are never on this path, so a
16
+ * site theme cannot shadow the login form or the CSRF field inside it
17
+ * (decision-4).
18
+ */
19
+ /**
20
+ * The theme that ships inside the package, resolved from this module rather
21
+ * than from the working directory, so it is found whether the CMS is running
22
+ * from `src/` under tsx or from `dist/` as an installed dependency.
23
+ */
24
+ export const PACKAGED_THEME_DIR = fileURLToPath(new URL('../../themes/default/', import.meta.url));
25
+ /** The file a directory declares itself a theme with. */
26
+ export const THEME_MANIFEST_FILE = 'theme.json';
27
+ /**
28
+ * The only kind of theme there is.
29
+ *
30
+ * The field exists so a second kind — the admin, if it is ever made
31
+ * overridable — can slot in without the manifest format changing, and so a
32
+ * manifest that names a kind this CMS does not have is refused rather than
33
+ * loaded as a site theme by accident.
34
+ */
35
+ export const SITE_THEME_KIND = 'site';
36
+ /**
37
+ * Read one directory as a theme.
38
+ *
39
+ * Every way of not being a theme comes back the same way — `ok: false` and a
40
+ * sentence saying why — because every caller has the same job with it: a
41
+ * listing greys the directory out, a chosen theme that stopped being one falls
42
+ * back to the packaged default with the reason logged, and the admin refuses
43
+ * to save it. None of them wants an exception, and a directory that is simply
44
+ * not a theme is not exceptional: a site's `themes/` will have a `.DS_Store`
45
+ * in it soon enough.
46
+ */
47
+ export function readTheme(dir) {
48
+ const directory = path.resolve(dir);
49
+ const manifestFile = path.join(directory, THEME_MANIFEST_FILE);
50
+ let source;
51
+ try {
52
+ source = readFileSync(manifestFile, 'utf8');
53
+ }
54
+ catch {
55
+ return { ok: false, reason: `There is no ${THEME_MANIFEST_FILE} in ${directory}.` };
56
+ }
57
+ let parsed;
58
+ try {
59
+ parsed = JSON.parse(source);
60
+ }
61
+ catch (error) {
62
+ const detail = error instanceof Error ? error.message : String(error);
63
+ return { ok: false, reason: `${manifestFile} is not valid JSON: ${detail}` };
64
+ }
65
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
66
+ return { ok: false, reason: `${manifestFile} is not a JSON object.` };
67
+ }
68
+ const manifest = parsed;
69
+ const name = manifest['name'];
70
+ if (typeof name !== 'string' || name.trim() === '') {
71
+ return { ok: false, reason: `${manifestFile} has no name.` };
72
+ }
73
+ const kind = manifest['kind'];
74
+ if (kind !== SITE_THEME_KIND) {
75
+ const named = typeof kind === 'string' ? `"${kind}"` : 'nothing';
76
+ return {
77
+ ok: false,
78
+ reason: `${manifestFile} declares kind ${named}, and the only theme kind is "${SITE_THEME_KIND}".`,
79
+ };
80
+ }
81
+ const description = manifest['description'];
82
+ return {
83
+ ok: true,
84
+ theme: {
85
+ id: path.basename(directory),
86
+ dir: directory,
87
+ name: name.trim(),
88
+ kind: SITE_THEME_KIND,
89
+ ...(typeof description === 'string' && description.trim() !== ''
90
+ ? { description: description.trim() }
91
+ : {}),
92
+ areas: themeAreasOf(manifest['areas']),
93
+ },
94
+ };
95
+ }
96
+ /**
97
+ * An `areas` value as the areas it declares, ignoring anything that is not
98
+ * one.
99
+ *
100
+ * Tolerant where the name and the kind are strict, and deliberately so: a
101
+ * theme that got its areas wrong still renders a site, whereas one with no
102
+ * name or the wrong kind is not a theme at all. A declaration that cannot be
103
+ * read leaves the theme with no areas — the Navigation screen then offers
104
+ * nowhere to put a menu, which is visibly wrong and fixable, rather than the
105
+ * site 500ing over a typo in a manifest.
106
+ *
107
+ * A label is optional and falls back to the name, because an area with a name
108
+ * and no label is a theme that said where a menu goes and forgot to say it
109
+ * nicely. A name declared twice is one area: the manifest is a list only so
110
+ * that the order is the theme's to choose.
111
+ */
112
+ function themeAreasOf(value) {
113
+ if (!Array.isArray(value))
114
+ return [];
115
+ const areas = [];
116
+ const seen = new Set();
117
+ for (const entry of value) {
118
+ if (typeof entry !== 'object' || entry === null)
119
+ continue;
120
+ const { name, label } = entry;
121
+ if (typeof name !== 'string')
122
+ continue;
123
+ const area = name.trim();
124
+ if (area === '' || seen.has(area))
125
+ continue;
126
+ seen.add(area);
127
+ const words = typeof label === 'string' ? label.trim() : '';
128
+ areas.push({ name: area, label: words === '' ? area : words });
129
+ }
130
+ return areas;
131
+ }
132
+ /**
133
+ * Everything in one site's themes directory.
134
+ *
135
+ * Both halves come back because the Appearance screen draws both: a folder
136
+ * with a typo in its `theme.json` is listed with the reason rather than
137
+ * silently skipped, because a theme that has quietly vanished from the list is
138
+ * the hardest kind of mistake to find. The screen is the only caller —
139
+ * rendering asks {@link chooseTheme} about one name instead, and never reads
140
+ * the directory.
141
+ *
142
+ * Only a subdirectory is a candidate, and a hidden one is not even that: a
143
+ * `themes/` with a `.DS_Store`, a `README.md` or a `.git` in it is a site with
144
+ * no broken themes, not a site with three of them.
145
+ *
146
+ * A themes directory that is not there is an empty one. Nothing scaffolds it
147
+ * (decision-15), so a site that has never written a theme has no directory,
148
+ * and that is the ordinary state rather than a problem to report.
149
+ */
150
+ export function listSiteThemes(themesDir) {
151
+ const root = path.resolve(themesDir);
152
+ let entries;
153
+ try {
154
+ entries = readdirSync(root, { withFileTypes: true });
155
+ }
156
+ catch {
157
+ return { themes: [], unreadable: [] };
158
+ }
159
+ const themes = [];
160
+ const unreadable = [];
161
+ for (const entry of [...entries].sort((left, right) => left.name.localeCompare(right.name))) {
162
+ if (!entry.isDirectory() || entry.name.startsWith('.'))
163
+ continue;
164
+ const dir = path.join(root, entry.name);
165
+ const read = readTheme(dir);
166
+ if (read.ok)
167
+ themes.push(read.theme);
168
+ else
169
+ unreadable.push({ id: entry.name, dir, reason: read.reason });
170
+ }
171
+ return { themes, unreadable };
172
+ }
173
+ /**
174
+ * The theme directories one render reads from, in order: the theme the site
175
+ * has chosen first, the theme that ships in this package second.
176
+ *
177
+ * That is the whole override mechanism. A theme that ships only
178
+ * `layouts/post.njk` replaces the post layout and keeps receiving updates to
179
+ * every other template, and the same order decides a `/theme/` asset and a
180
+ * mail template. The chosen directory need not exist.
181
+ *
182
+ * A site that has chosen nothing passes nothing, and reads the packaged theme
183
+ * alone: an unchosen theme is never on the path, and the packaged one is never
184
+ * on it twice (decision-15).
185
+ */
186
+ export function themeSearchPath(chosenThemeDir) {
187
+ return chosenThemeDir === undefined ? [PACKAGED_THEME_DIR] : [chosenThemeDir, PACKAGED_THEME_DIR];
188
+ }
189
+ /**
190
+ * What a `theme` in `site.json` may be: the name of one directory inside the
191
+ * themes directory, and nothing that would reach outside it.
192
+ *
193
+ * The setting is a word somebody picks off a list, so this is about a
194
+ * hand-edited file rather than about an attacker — but the value decides a
195
+ * directory every template is then read out of, so it is checked before it is
196
+ * joined to a path rather than after.
197
+ */
198
+ export function themeNameProblem(name) {
199
+ const chosen = name.trim();
200
+ if (chosen === '')
201
+ return undefined;
202
+ if (chosen === '.' || chosen === '..' || /[/\\\0]/.test(chosen)) {
203
+ return `"${chosen}" is not a theme name: a theme is one directory inside the themes directory.`;
204
+ }
205
+ return undefined;
206
+ }
207
+ /**
208
+ * The theme one site has chosen, resolved against its themes directory.
209
+ *
210
+ * A choice that cannot be honoured is the packaged theme and a sentence saying
211
+ * why, never an exception: a theme deleted from disk, or a `theme.json` broken
212
+ * by a hand edit, has to leave the site up and answering — the alternative is
213
+ * a site that 500s on every page because of a directory rename.
214
+ */
215
+ export function chooseTheme(options) {
216
+ const name = options.name.trim();
217
+ if (name === '')
218
+ return { theme: undefined, dirs: themeSearchPath(), problem: undefined };
219
+ const badName = themeNameProblem(name);
220
+ if (badName !== undefined) {
221
+ return { theme: undefined, dirs: themeSearchPath(), problem: badName };
222
+ }
223
+ const read = readTheme(path.join(options.themesDir, name));
224
+ if (!read.ok) {
225
+ return {
226
+ theme: undefined,
227
+ dirs: themeSearchPath(),
228
+ problem: `The theme "${name}" is not there: ${read.reason}`,
229
+ };
230
+ }
231
+ return { theme: read.theme, dirs: themeSearchPath(read.theme.dir), problem: undefined };
232
+ }
233
+ /**
234
+ * The one thing that knows which theme a site is rendering through.
235
+ *
236
+ * It is a source rather than a value because the choice is a setting in
237
+ * `content/_data/site.json` (decision-9, decision-15): the Appearance screen
238
+ * writes that file, a hand edit writes the same file, and both have to reach
239
+ * the next request without a restart. So every consumer — the template
240
+ * environment, the `/theme/` assets, the mail templates — asks here per render
241
+ * instead of being handed a directory at boot.
242
+ *
243
+ * The result is cached against the choice and the `stat` of the chosen theme's
244
+ * manifest, so an unchanged site pays one `stat` per render and a theme
245
+ * edited, replaced or deleted under the running process is noticed on the next
246
+ * one. A choice that cannot be honoured is logged once, when the answer
247
+ * changes, rather than on every render: a site whose theme has been deleted
248
+ * should say so in the log and then serve pages, not fill the log with the
249
+ * same line.
250
+ */
251
+ export function createThemeSource(options) {
252
+ const logger = options.logger ?? console;
253
+ let cached;
254
+ let cachedKey;
255
+ let reported;
256
+ /**
257
+ * What would make the answer different: the name chosen, and the state of
258
+ * that theme's manifest. The modification time alone is not enough, for the
259
+ * reason it is not in {@link createSiteDataSource}: a filesystem rounds it,
260
+ * and a theme replaced wholesale changes the inode rather than the time.
261
+ */
262
+ function key(name) {
263
+ if (name === '')
264
+ return '';
265
+ try {
266
+ const stats = statSync(path.join(options.themesDir, name, THEME_MANIFEST_FILE));
267
+ return `${name}:${String(stats.mtimeMs)}:${String(stats.size)}:${String(stats.ino)}`;
268
+ }
269
+ catch {
270
+ return `${name}:missing`;
271
+ }
272
+ }
273
+ return {
274
+ current() {
275
+ const name = options.chosen().trim();
276
+ const current = key(name);
277
+ if (cached !== undefined && current === cachedKey)
278
+ return cached;
279
+ cachedKey = current;
280
+ cached = chooseTheme({ themesDir: options.themesDir, name });
281
+ if (cached.problem !== undefined && cached.problem !== reported) {
282
+ logger.warn(`${cached.problem} The packaged theme is being used instead.`);
283
+ }
284
+ reported = cached.problem;
285
+ return cached;
286
+ },
287
+ };
288
+ }
289
+ /**
290
+ * The first theme on the path that ships one file, by absolute path, or
291
+ * `undefined` when none of them does.
292
+ *
293
+ * Nunjucks resolves its own templates through the same order, so this is for
294
+ * the two questions asked outside a render: whether a theme has written the
295
+ * optional front-page or posts-page layout, and which halves of a mail message
296
+ * exist. A path that climbs out of a theme directory finds nothing, so a
297
+ * caller passing a name through from a request cannot reach the file system
298
+ * around it.
299
+ */
300
+ export function findThemeFile(themeDirs, relative) {
301
+ if (relative === '' || relative.includes('\0'))
302
+ return undefined;
303
+ const segments = relative.split('/').filter((segment) => segment !== '');
304
+ for (const directory of themeDirs) {
305
+ const root = path.resolve(directory);
306
+ const file = path.resolve(root, ...segments);
307
+ if (file !== root && !file.startsWith(root + path.sep))
308
+ continue;
309
+ if (existsSync(file))
310
+ return file;
311
+ }
312
+ return undefined;
313
+ }
314
+ //# sourceMappingURL=themes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themes.js","sourceRoot":"","sources":["../../src/web/themes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Finding out where to send a webmention.
3
+ *
4
+ * The W3C spec fixes the order and it matters, because a page may advertise
5
+ * two: the HTTP `Link` header first, then the first `<link>` **or** `<a>`
6
+ * carrying `rel="webmention"` in document order — one search over both, not
7
+ * one search each. Whatever is found is resolved against the URL the request
8
+ * actually ended at, so a target that redirects to its canonical home
9
+ * advertises that home's endpoint rather than a path under the old one.
10
+ */
11
+ /** How long one discovery request is given before it is abandoned. */
12
+ export declare const DISCOVERY_TIMEOUT_MS = 10000;
13
+ /** How much of a target page is read while looking for its endpoint. */
14
+ export declare const DISCOVERY_MAX_BYTES = 1000000;
15
+ /** What a sender says it is. */
16
+ export declare const WEBMENTION_USER_AGENT = "Geekity/1.0 (+https://github.com/andrewshell/geekity)";
17
+ /**
18
+ * The Webmention endpoint a page advertises, or `undefined` when it advertises
19
+ * none — which is most pages, and is not an error.
20
+ *
21
+ * Nothing throws: a target that times out, refuses the connection or answers
22
+ * an error is a target with no endpoint as far as the sender is concerned, and
23
+ * the caller records that rather than stopping.
24
+ */
25
+ export declare function discoverEndpoint(target: string): Promise<string | undefined>;
26
+ /**
27
+ * The endpoint one or more `Link` headers name, or `undefined`.
28
+ *
29
+ * A header may carry several links separated by commas and each may name
30
+ * several relations, so both are split. Splitting on commas that are not
31
+ * inside angle brackets or quotes is what keeps a URL holding a comma — which
32
+ * is legal — from being torn in half.
33
+ */
34
+ export declare function endpointInHeader(header: string | null, base: string): string | undefined;
35
+ /**
36
+ * The endpoint a page's markup names, or `undefined`.
37
+ *
38
+ * One walk over every element rather than one for `<link>` and another for
39
+ * `<a>`: the spec asks for the first of either in document order, and two
40
+ * walks would answer with whichever kind was searched for first.
41
+ */
42
+ export declare function endpointInHtml(html: string, base: string): string | undefined;
43
+ /**
44
+ * A response body, up to {@link DISCOVERY_MAX_BYTES}.
45
+ *
46
+ * A cap rather than `response.text()`, because the page at the other end is a
47
+ * stranger's and nothing stops it being a gigabyte. What is read is more than
48
+ * enough markup for a `<link>` in the head.
49
+ */
50
+ export declare function readCapped(response: Response): Promise<string>;
51
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/webmention/discovery.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,sEAAsE;AACtE,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAE3C,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,UAAY,CAAC;AAE7C,gCAAgC;AAChC,eAAO,MAAM,qBAAqB,0DAA0D,CAAC;AAE7F;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkClF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAexF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAW7E;AAsCD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BpE"}