@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,195 @@
1
+ import type { SiteData } from './context.ts';
2
+ /**
3
+ * The menu a theme renders when nothing says which one it means: the menu that
4
+ * was the whole of `navigation` before menus had names (TASK-107).
5
+ */
6
+ export declare const DEFAULT_MENU_NAME = "primary";
7
+ /**
8
+ * The flags one menu item may carry, as `site.json` spells them and as the
9
+ * settings screen writes them at the end of a line.
10
+ *
11
+ * A flag is a word rather than a value, and the list is here rather than
12
+ * spread through the parsers so that a second one — `nofollow`, say, or a flag
13
+ * that opens a link in its own tab — is one entry and its handling in the
14
+ * theme, not a new shape for an item.
15
+ */
16
+ export declare const MENU_ITEM_FLAGS: readonly ['me'];
17
+ /** One of {@link MENU_ITEM_FLAGS}. */
18
+ export type MenuItemFlag = (typeof MENU_ITEM_FLAGS)[number];
19
+ /**
20
+ * What a menu name may be spelled with.
21
+ *
22
+ * A menu name is the word a theme writes after the dot in
23
+ * `{% for item in menus.footer %}`, and the key `site.json` stores that menu
24
+ * under. So it is an identifier before it is a slug: in a template
25
+ * `menus.top-bar` is `menus.top` minus `bar`, which renders nothing, raises
26
+ * nothing and leaves somebody looking at an empty page wondering which half is
27
+ * broken. A hyphen is refused here so that cannot happen.
28
+ *
29
+ * Lower case is the other half of the rule, and it is what refuses the
30
+ * spellings that would be confused with each other: `footer` and `Footer`
31
+ * would be two menus on the Navigation screen, one of them rendered nowhere,
32
+ * and no way to see the difference between them at a glance.
33
+ */
34
+ export declare const MENU_NAME_PATTERN: RegExp;
35
+ /** The longest a menu name may be. Long enough for a phrase, short enough to read. */
36
+ export declare const MENU_NAME_MAX_LENGTH = 32;
37
+ /**
38
+ * What is wrong with a proposed menu name, or `undefined` when nothing is.
39
+ *
40
+ * The rule governs a name somebody types on the Navigation screen (TASK-108).
41
+ * A name a `theme.json` declares is a menu name by declaration and is shown as
42
+ * the theme spells it: the theme decides where its own menus go, and a screen
43
+ * that hid a declared area because it disliked the spelling would leave
44
+ * somebody unable to fill in a menu their site renders.
45
+ */
46
+ export declare function menuNameProblem(name: string): string | undefined;
47
+ /** One entry of a menu, as `site.json` and the settings screen spell it. */
48
+ export interface NavigationItem {
49
+ /** The words on the link. */
50
+ label: string;
51
+ /** Where it goes: a site-root path, or an absolute URL for somewhere else. */
52
+ url: string;
53
+ /**
54
+ * Whether the link carries `rel="me"`, which is how Mastodon and the rest of
55
+ * the IndieWeb verify that the site and the profile it links are the same
56
+ * person.
57
+ *
58
+ * Present only when it is set. An unmarked item is spelled exactly as every
59
+ * item was before flags existed, so a `site.json` holding a plain
60
+ * `{ label, url }` is a complete item rather than one missing a key, and a
61
+ * flag added later never has to be written across a file to mean nothing.
62
+ */
63
+ me?: true;
64
+ }
65
+ /** Every menu one site stores, by name. */
66
+ export type NavigationMenus = Record<string, NavigationItem[]>;
67
+ /** One entry of the menu a theme renders. */
68
+ export interface MenuItem extends NavigationItem {
69
+ /** Whether this is the page being looked at, for `aria-current`. */
70
+ current: boolean;
71
+ }
72
+ /** Every menu a theme renders, by name, marked for the page being rendered. */
73
+ export type MenuList = Record<string, MenuItem[]>;
74
+ /** What {@link navigationMenu} builds a menu out of. */
75
+ export interface NavigationMenuOptions {
76
+ /** The site data, whose `menus` hold every menu it has. */
77
+ site: SiteData;
78
+ /** The path being rendered, which is what marks an item current. */
79
+ url: string;
80
+ /** Which menu. {@link DEFAULT_MENU_NAME} when nothing says. */
81
+ name?: string | undefined;
82
+ }
83
+ /**
84
+ * One named menu for one request: the items the site stores under that name,
85
+ * with the one the request is on marked.
86
+ *
87
+ * The setting is the only source of a menu (TASK-106). A page cannot put
88
+ * itself in one, so there is one screen to edit a menu on, one order — the
89
+ * order the lines were typed in — and no way for one link to appear twice. A
90
+ * page that should be linked is linked by typing a line for it, including the
91
+ * page a site serves as its front page: that one is typed `Home | /`, the URL
92
+ * a reader lands on, rather than the permalink that redirects there.
93
+ *
94
+ * A name the site has stored nothing under is an empty menu rather than an
95
+ * error: a theme declaring an area the site has not filled in yet renders
96
+ * nothing there, which is what an unfilled area should look like.
97
+ */
98
+ export declare function navigationMenu(options: NavigationMenuOptions): MenuItem[];
99
+ /** What {@link navigationMenus} builds every menu out of. */
100
+ export interface NavigationMenusOptions {
101
+ /** The site data, whose `menus` hold every menu it has. */
102
+ site: SiteData;
103
+ /** The path being rendered, which is what marks an item current. */
104
+ url: string;
105
+ }
106
+ /**
107
+ * Every menu one site stores, by name, marked for this request: what the
108
+ * template context carries as `menus`.
109
+ *
110
+ * Every stored menu is here, not only the ones the theme in use declares an
111
+ * area for. The declaration in `theme.json` is what the Navigation screen
112
+ * reads to say where a menu can go (TASK-108); it is not a filter on the
113
+ * render, because a theme that renders a menu it forgot to declare should look
114
+ * wrong on the screen that lists areas rather than silently render nothing.
115
+ * A menu no template loops over is simply rendered nowhere, and kept.
116
+ */
117
+ export declare function navigationMenus(options: NavigationMenusOptions): MenuList;
118
+ /**
119
+ * The items of one named menu, ignoring anything that is not one.
120
+ *
121
+ * Tolerant on the way out, the way `taxonomyBasesOrDefault` is: the settings
122
+ * screen refuses a malformed item, so anything unreadable here came from a
123
+ * hand-edited `site.json`, and a menu that quietly loses a line is a better
124
+ * answer than a site that will not render.
125
+ */
126
+ export declare function navigationItems(site: SiteData, name?: string): NavigationItem[];
127
+ /**
128
+ * Every menu the site data stores, by name.
129
+ *
130
+ * The one place `site.menus` is read on the render side, the way
131
+ * {@link navigationItems} was the one place `site.navigation` was read before
132
+ * menus had names. The old key is not read at all: a site.json still carrying
133
+ * `navigation` has a key nothing looks at, which is what a rename means.
134
+ */
135
+ export declare function siteMenus(site: SiteData): NavigationMenus;
136
+ /**
137
+ * A `menus` value as the menus it names, ignoring anything that is not one.
138
+ *
139
+ * One spelling for the site data a render reads and the `menus` the settings
140
+ * screen writes, so a menu means the same thing to the theme and to the form
141
+ * that edits it. Anything but a plain object — a list, a string, nothing at
142
+ * all — is a site with no menus; a name holding something that is not a list
143
+ * is a menu with nothing in it, because the name is still a menu this site
144
+ * holds and the Navigation screen has to be able to show it.
145
+ */
146
+ export declare function menusOf(value: unknown): NavigationMenus;
147
+ /**
148
+ * One menu's stored value as the items it names, ignoring anything that is not
149
+ * one.
150
+ *
151
+ * A flag is read only when it is spelled exactly `true`: `"yes"`, `1` and
152
+ * `false` all leave the item unmarked, so a flag is either set or it is not
153
+ * and a theme writes `{% if item.me %}` without wondering what else the file
154
+ * might have put there.
155
+ */
156
+ export declare function navigationItemsOf(value: unknown): NavigationItem[];
157
+ /**
158
+ * One `Label | URL` line as a menu item, or `undefined` when it is not one.
159
+ *
160
+ * The URL is either a site-root path or an absolute http(s) URL: a bare
161
+ * `about/` would be resolved against whatever page it was printed on, which is
162
+ * never what a menu means.
163
+ *
164
+ * A line may end in the flags the item carries, one per bar — `Mastodon |
165
+ * https://example.social/@me | me` — and those are taken off the end first,
166
+ * from the right, and only while the last part is the name of a flag this CMS
167
+ * actually has ({@link MENU_ITEM_FLAGS}). That is what lets a URL still hold a
168
+ * bar, a query string say: a trailing `| elsewhere` is not a flag, so it stays
169
+ * part of the URL and the line is refused for not naming one, rather than
170
+ * being quietly read as a flag nobody asked for.
171
+ *
172
+ * What is left splits at its first bar, so a label still cannot hold one.
173
+ */
174
+ export declare function menuItemOf(line: string): NavigationItem | undefined;
175
+ /**
176
+ * A menu box as the ordered items it names, dropping the lines that are not
177
+ * items.
178
+ *
179
+ * Call {@link menuItemLineProblem} first where a person is waiting to be told:
180
+ * this is the tolerant read, which is what the old settings table's rows and a
181
+ * validated box both go through. `site.json` is read by {@link menusOf}
182
+ * instead, because the file holds objects rather than lines.
183
+ */
184
+ export declare function menuItemsFromText(value: string): NavigationItem[];
185
+ /** The items as a box shows them: one line each, in order. */
186
+ export declare function menuItemsText(items: readonly NavigationItem[]): string;
187
+ /**
188
+ * What is wrong with a typed menu, or `undefined` when nothing is.
189
+ *
190
+ * One message naming the first bad line rather than a count of how many there
191
+ * are: a box is fixed a line at a time, and the line to fix is the useful
192
+ * half of the sentence.
193
+ */
194
+ export declare function menuItemLineProblem(value: string): string | undefined;
195
+ //# sourceMappingURL=navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/web/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAE3C;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,YAAI,IAAI,CAAU,CAAC;AAE/C,sCAAsC;AACtC,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,QAAsB,CAAC;AAErD,sFAAsF;AACtF,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAmBhE;AAED,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;;OASG;IACH,EAAE,CAAC,EAAE,IAAI,CAAC;CACX;AAED,2CAA2C;AAC3C,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;AAE/D,6CAA6C;AAC7C,MAAM,WAAW,QAAS,SAAQ,cAAc;IAC9C,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;AAElD,wDAAwD;AACxD,MAAM,WAAW,qBAAqB;IACpC,2DAA2D;IAC3D,IAAI,EAAE,QAAQ,CAAC;IACf,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC;IACZ,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,QAAQ,EAAE,CAEzE;AAED,6DAA6D;AAC7D,MAAM,WAAW,sBAAsB;IACrC,2DAA2D;IAC3D,IAAI,EAAE,QAAQ,CAAC;IACf,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,QAAQ,CAMzE;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EACd,IAAI,GAAE,MAA0B,GAC/B,cAAc,EAAE,CAElB;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,eAAe,CAEzD;AAED;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CASvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,EAAE,CAYlE;AAeD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAyBnE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAOjE;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,CAItE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOrE"}
@@ -0,0 +1,300 @@
1
+ /**
2
+ * The menu a theme renders when nothing says which one it means: the menu that
3
+ * was the whole of `navigation` before menus had names (TASK-107).
4
+ */
5
+ export const DEFAULT_MENU_NAME = 'primary';
6
+ /**
7
+ * The flags one menu item may carry, as `site.json` spells them and as the
8
+ * settings screen writes them at the end of a line.
9
+ *
10
+ * A flag is a word rather than a value, and the list is here rather than
11
+ * spread through the parsers so that a second one — `nofollow`, say, or a flag
12
+ * that opens a link in its own tab — is one entry and its handling in the
13
+ * theme, not a new shape for an item.
14
+ */
15
+ export const MENU_ITEM_FLAGS = ['me'];
16
+ /**
17
+ * What a menu name may be spelled with.
18
+ *
19
+ * A menu name is the word a theme writes after the dot in
20
+ * `{% for item in menus.footer %}`, and the key `site.json` stores that menu
21
+ * under. So it is an identifier before it is a slug: in a template
22
+ * `menus.top-bar` is `menus.top` minus `bar`, which renders nothing, raises
23
+ * nothing and leaves somebody looking at an empty page wondering which half is
24
+ * broken. A hyphen is refused here so that cannot happen.
25
+ *
26
+ * Lower case is the other half of the rule, and it is what refuses the
27
+ * spellings that would be confused with each other: `footer` and `Footer`
28
+ * would be two menus on the Navigation screen, one of them rendered nowhere,
29
+ * and no way to see the difference between them at a glance.
30
+ */
31
+ export const MENU_NAME_PATTERN = /^[a-z][a-z0-9_]*$/;
32
+ /** The longest a menu name may be. Long enough for a phrase, short enough to read. */
33
+ export const MENU_NAME_MAX_LENGTH = 32;
34
+ /**
35
+ * What is wrong with a proposed menu name, or `undefined` when nothing is.
36
+ *
37
+ * The rule governs a name somebody types on the Navigation screen (TASK-108).
38
+ * A name a `theme.json` declares is a menu name by declaration and is shown as
39
+ * the theme spells it: the theme decides where its own menus go, and a screen
40
+ * that hid a declared area because it disliked the spelling would leave
41
+ * somebody unable to fill in a menu their site renders.
42
+ */
43
+ export function menuNameProblem(name) {
44
+ const proposed = name.trim();
45
+ if (proposed === '')
46
+ return 'A menu needs a name: it is what a theme asks for the menu by.';
47
+ if (proposed.length > MENU_NAME_MAX_LENGTH) {
48
+ return `A menu name is at most ${String(MENU_NAME_MAX_LENGTH)} characters, and "${proposed}" is longer.`;
49
+ }
50
+ if (proposed !== proposed.toLowerCase()) {
51
+ return `A menu name is lower case, so "${proposed}" would be a second menu beside "${proposed.toLowerCase()}" that nothing could tell apart. Try "${proposed.toLowerCase()}".`;
52
+ }
53
+ if (!MENU_NAME_PATTERN.test(proposed)) {
54
+ return (`"${proposed}" is not a menu name. A name is lower-case letters, digits and ` +
55
+ `underscores and has to start with a letter, because a theme writes it after ` +
56
+ `the dot — menus.footer — where a dash would be a minus sign.`);
57
+ }
58
+ return undefined;
59
+ }
60
+ /**
61
+ * One named menu for one request: the items the site stores under that name,
62
+ * with the one the request is on marked.
63
+ *
64
+ * The setting is the only source of a menu (TASK-106). A page cannot put
65
+ * itself in one, so there is one screen to edit a menu on, one order — the
66
+ * order the lines were typed in — and no way for one link to appear twice. A
67
+ * page that should be linked is linked by typing a line for it, including the
68
+ * page a site serves as its front page: that one is typed `Home | /`, the URL
69
+ * a reader lands on, rather than the permalink that redirects there.
70
+ *
71
+ * A name the site has stored nothing under is an empty menu rather than an
72
+ * error: a theme declaring an area the site has not filled in yet renders
73
+ * nothing there, which is what an unfilled area should look like.
74
+ */
75
+ export function navigationMenu(options) {
76
+ return markCurrent(navigationItems(options.site, options.name), options.url);
77
+ }
78
+ /**
79
+ * Every menu one site stores, by name, marked for this request: what the
80
+ * template context carries as `menus`.
81
+ *
82
+ * Every stored menu is here, not only the ones the theme in use declares an
83
+ * area for. The declaration in `theme.json` is what the Navigation screen
84
+ * reads to say where a menu can go (TASK-108); it is not a filter on the
85
+ * render, because a theme that renders a menu it forgot to declare should look
86
+ * wrong on the screen that lists areas rather than silently render nothing.
87
+ * A menu no template loops over is simply rendered nowhere, and kept.
88
+ */
89
+ export function navigationMenus(options) {
90
+ const menus = {};
91
+ for (const [name, items] of Object.entries(siteMenus(options.site))) {
92
+ menus[name] = markCurrent(items, options.url);
93
+ }
94
+ return menus;
95
+ }
96
+ /**
97
+ * The items of one named menu, ignoring anything that is not one.
98
+ *
99
+ * Tolerant on the way out, the way `taxonomyBasesOrDefault` is: the settings
100
+ * screen refuses a malformed item, so anything unreadable here came from a
101
+ * hand-edited `site.json`, and a menu that quietly loses a line is a better
102
+ * answer than a site that will not render.
103
+ */
104
+ export function navigationItems(site, name = DEFAULT_MENU_NAME) {
105
+ return navigationItemsOf(menusOf(site['menus'])[name]);
106
+ }
107
+ /**
108
+ * Every menu the site data stores, by name.
109
+ *
110
+ * The one place `site.menus` is read on the render side, the way
111
+ * {@link navigationItems} was the one place `site.navigation` was read before
112
+ * menus had names. The old key is not read at all: a site.json still carrying
113
+ * `navigation` has a key nothing looks at, which is what a rename means.
114
+ */
115
+ export function siteMenus(site) {
116
+ return menusOf(site['menus']);
117
+ }
118
+ /**
119
+ * A `menus` value as the menus it names, ignoring anything that is not one.
120
+ *
121
+ * One spelling for the site data a render reads and the `menus` the settings
122
+ * screen writes, so a menu means the same thing to the theme and to the form
123
+ * that edits it. Anything but a plain object — a list, a string, nothing at
124
+ * all — is a site with no menus; a name holding something that is not a list
125
+ * is a menu with nothing in it, because the name is still a menu this site
126
+ * holds and the Navigation screen has to be able to show it.
127
+ */
128
+ export function menusOf(value) {
129
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
130
+ return {};
131
+ const menus = {};
132
+ for (const [name, items] of Object.entries(value)) {
133
+ if (name === '')
134
+ continue;
135
+ menus[name] = navigationItemsOf(items);
136
+ }
137
+ return menus;
138
+ }
139
+ /**
140
+ * One menu's stored value as the items it names, ignoring anything that is not
141
+ * one.
142
+ *
143
+ * A flag is read only when it is spelled exactly `true`: `"yes"`, `1` and
144
+ * `false` all leave the item unmarked, so a flag is either set or it is not
145
+ * and a theme writes `{% if item.me %}` without wondering what else the file
146
+ * might have put there.
147
+ */
148
+ export function navigationItemsOf(value) {
149
+ if (!Array.isArray(value))
150
+ return [];
151
+ const items = [];
152
+ for (const entry of value) {
153
+ if (typeof entry !== 'object' || entry === null)
154
+ continue;
155
+ const { label, url, me } = entry;
156
+ if (typeof label !== 'string' || label === '')
157
+ continue;
158
+ if (typeof url !== 'string' || url === '')
159
+ continue;
160
+ items.push({ label, url, ...(me === true ? { me: true } : {}) });
161
+ }
162
+ return items;
163
+ }
164
+ /**
165
+ * The non-empty lines of a menu box, trimmed.
166
+ *
167
+ * A blank line is not an error, exactly as it is not in the relay list: a
168
+ * pasted menu leaves them, and a blank line asks for nothing.
169
+ */
170
+ function menuLines(value) {
171
+ return value
172
+ .split('\n')
173
+ .map((line) => line.trim())
174
+ .filter((line) => line !== '');
175
+ }
176
+ /**
177
+ * One `Label | URL` line as a menu item, or `undefined` when it is not one.
178
+ *
179
+ * The URL is either a site-root path or an absolute http(s) URL: a bare
180
+ * `about/` would be resolved against whatever page it was printed on, which is
181
+ * never what a menu means.
182
+ *
183
+ * A line may end in the flags the item carries, one per bar — `Mastodon |
184
+ * https://example.social/@me | me` — and those are taken off the end first,
185
+ * from the right, and only while the last part is the name of a flag this CMS
186
+ * actually has ({@link MENU_ITEM_FLAGS}). That is what lets a URL still hold a
187
+ * bar, a query string say: a trailing `| elsewhere` is not a flag, so it stays
188
+ * part of the URL and the line is refused for not naming one, rather than
189
+ * being quietly read as a flag nobody asked for.
190
+ *
191
+ * What is left splits at its first bar, so a label still cannot hold one.
192
+ */
193
+ export function menuItemOf(line) {
194
+ const flags = new Set();
195
+ let rest = line;
196
+ for (;;) {
197
+ const bar = rest.lastIndexOf('|');
198
+ if (bar === -1)
199
+ break;
200
+ const flag = rest
201
+ .slice(bar + 1)
202
+ .trim()
203
+ .toLowerCase();
204
+ if (!MENU_ITEM_FLAGS.includes(flag))
205
+ break;
206
+ flags.add(flag);
207
+ rest = rest.slice(0, bar);
208
+ }
209
+ const bar = rest.indexOf('|');
210
+ if (bar === -1)
211
+ return undefined;
212
+ const label = rest.slice(0, bar).trim();
213
+ const url = rest.slice(bar + 1).trim();
214
+ if (label === '' || url === '')
215
+ return undefined;
216
+ if (!url.startsWith('/') && !isAbsoluteHttpUrl(url))
217
+ return undefined;
218
+ return { label, url, ...(flags.has('me') ? { me: true } : {}) };
219
+ }
220
+ /**
221
+ * A menu box as the ordered items it names, dropping the lines that are not
222
+ * items.
223
+ *
224
+ * Call {@link menuItemLineProblem} first where a person is waiting to be told:
225
+ * this is the tolerant read, which is what the old settings table's rows and a
226
+ * validated box both go through. `site.json` is read by {@link menusOf}
227
+ * instead, because the file holds objects rather than lines.
228
+ */
229
+ export function menuItemsFromText(value) {
230
+ const items = [];
231
+ for (const line of menuLines(value)) {
232
+ const item = menuItemOf(line);
233
+ if (item !== undefined)
234
+ items.push(item);
235
+ }
236
+ return items;
237
+ }
238
+ /** The items as a box shows them: one line each, in order. */
239
+ export function menuItemsText(items) {
240
+ return items
241
+ .map((item) => `${item.label} | ${item.url}${item.me === true ? ' | me' : ''}`)
242
+ .join('\n');
243
+ }
244
+ /**
245
+ * What is wrong with a typed menu, or `undefined` when nothing is.
246
+ *
247
+ * One message naming the first bad line rather than a count of how many there
248
+ * are: a box is fixed a line at a time, and the line to fix is the useful
249
+ * half of the sentence.
250
+ */
251
+ export function menuItemLineProblem(value) {
252
+ const bad = menuLines(value).find((line) => menuItemOf(line) === undefined);
253
+ return bad === undefined
254
+ ? undefined
255
+ : `A menu item is "Label | URL", one per line, where the URL is a path ` +
256
+ `like /about/ or an absolute http:// or https:// URL, and ends ` +
257
+ `"| me" for a link that should carry rel="me". "${bad}" is not one.`;
258
+ }
259
+ /**
260
+ * Whether a menu URL is an absolute http(s) one.
261
+ *
262
+ * Deliberately a test rather than a normaliser: a menu keeps the URL as it was
263
+ * typed, so `https://example.social/@me` is what the link says and what the
264
+ * box shows it back as.
265
+ */
266
+ function isAbsoluteHttpUrl(url) {
267
+ let parsed;
268
+ try {
269
+ parsed = new URL(url);
270
+ }
271
+ catch {
272
+ return false;
273
+ }
274
+ return parsed.protocol === 'http:' || parsed.protocol === 'https:';
275
+ }
276
+ /** One menu's items, with the one the request is on marked. */
277
+ function markCurrent(items, url) {
278
+ const here = comparablePath(url);
279
+ return items.map((item) => ({
280
+ ...item,
281
+ current: here !== undefined && comparablePath(item.url) === here,
282
+ }));
283
+ }
284
+ /**
285
+ * A menu URL as the string two of them are compared by: its path without the
286
+ * trailing slash that is canonical here, or `undefined` when it is not a path
287
+ * on this site at all.
288
+ *
289
+ * An item pointing somewhere else is never the page being looked at, even when
290
+ * its URL happens to name this origin: it is a link off the site as far as the
291
+ * menu is concerned, and the request path it would be compared against is
292
+ * never absolute.
293
+ */
294
+ function comparablePath(url) {
295
+ if (!url.startsWith('/'))
296
+ return undefined;
297
+ const path = url.split(/[?#]/)[0] ?? url;
298
+ return path.length > 1 && path.endsWith('/') ? path.slice(0, -1) : path;
299
+ }
300
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/web/navigation.ts"],"names":[],"mappings":"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"}
@@ -141,6 +141,28 @@ export interface RepresentationResponseOptions {
141
141
  href: string;
142
142
  /** Which representations this resource offers, for the `Link` alternates. */
143
143
  available: readonly Representation[];
144
+ /**
145
+ * Whole `Link` header values to advertise alongside the alternates — the
146
+ * webmention endpoint is the one that uses it (TASK-51).
147
+ *
148
+ * Spelled by the caller rather than built here, because they are not
149
+ * representations of this resource and nothing about them is this module's
150
+ * business beyond joining them to the header.
151
+ */
152
+ links?: readonly string[] | undefined;
153
+ /**
154
+ * Whether this response was drawn for one named reader rather than for
155
+ * everybody (TASK-103).
156
+ *
157
+ * A post page is the same for every reader, which is what lets a CDN or a
158
+ * reverse proxy — the Docker deployment documents one — hold it and hand it
159
+ * out. The moment it says "Commenting as ada" it is one person's page, and
160
+ * anything in front of the site holding it would hand her name to the next
161
+ * reader. Such a response says so, and carries no validator either: a
162
+ * browser revalidating its own copy would otherwise be told a page drawn for
163
+ * somebody signed in is still fresh after they signed out.
164
+ */
165
+ private?: boolean | undefined;
144
166
  /** Validator for this representation. Omit when one cannot be trusted. */
145
167
  etag?: string | undefined;
146
168
  /** When the resource last changed. */
@@ -158,6 +180,15 @@ export interface RepresentationResponseOptions {
158
180
  * one exit means one place where the headers are decided.
159
181
  */
160
182
  export declare function representationResponse(options: RepresentationResponseOptions): Response;
183
+ /**
184
+ * What a response drawn for one named reader says about itself.
185
+ *
186
+ * `private` is the part that matters: it tells a shared cache this belongs to
187
+ * one reader and must not be handed to another. `no-store` is the belt to its
188
+ * braces, and keeps the page off the disk of a browser somebody else uses
189
+ * after them.
190
+ */
191
+ export declare const PRIVATE_CACHE_CONTROL = "private, no-store";
161
192
  /**
162
193
  * The 406 a request earns when it accepts none of the representations on
163
194
  * offer, with the options in the body so a client can pick one and retry.
@@ -1 +1 @@
1
- {"version":3,"file":"negotiate.d.ts","sourceRoot":"","sources":["../../src/web/negotiate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"negotiate.d.ts","sourceRoot":"","sources":["../../src/web/negotiate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAIvD;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAE1D,uDAAuD;AACvD,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAIhE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,cAAc,EAAiC,CAAC;AAEhG,mFAAmF;AACnF,eAAO,MAAM,uBAAuB,EAAE,SAAS,cAAc,EAAqB,CAAC;AAEnF;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,SAAS,EAAE,SAAS,cAAc,EAAE,GACnC,cAAc,GAAG,SAAS,CAsB5B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,EAAE,SAAS,MAAM,EAGzD,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAmB1E;AAwBD;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAGvF,CAAC;AAEF,mFAAmF;AACnF,MAAM,WAAW,uBAAuB;IACtC,kDAAkD;IAClD,cAAc,EAAE,cAAc,CAAC;IAC/B,gEAAgE;IAChE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,GACf,uBAAuB,GAAG,SAAS,CAkBrC;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,cAAc,GAAG,MAAM,CAIvF;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,mFAAmF;AACnF,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,2CAA2C;AAC3C,MAAM,WAAW,mBAAmB;IAClC,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAa3F;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKrE;AASD,mDAAmD;AACnD,MAAM,WAAW,kBAAkB;IACjC,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,2BAA2B;IAC3B,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,gDAAgD;AAChD,MAAM,WAAW,6BAA6B;IAC5C,sEAAsE;IACtE,IAAI,EAAE,OAAO,CAAC;IACd,sCAAsC;IACtC,cAAc,EAAE,cAAc,CAAC;IAC/B,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IACrC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IACtC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,sCAAsC;IACtC,YAAY,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAChC,sDAAsD;IACtD,WAAW,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;CAC9C;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,QAAQ,CA2CvF;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAEzD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,SAAS,cAAc,EAAE,GACnC,QAAQ,CAuBV;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,SAAS,EAAE,SAAS,cAAc,EAAE,GACnC,MAAM,CAQR;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAE9F;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAGrE;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,CAOnE;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAAG,IAAI,GAAG,SAAS,CAQ/E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,kBAAkB,GAAG,SAAS,EAC3C,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,YAAY,EAAE,IAAI,GAAG,SAAS,GAC7B,OAAO,CAcT;AAED,+CAA+C;AAC/C,MAAM,WAAW,WAAW;IAC1B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CAmBzD"}
@@ -204,20 +204,31 @@ const CONTENT_TYPES = {
204
204
  export function representationResponse(options) {
205
205
  const headers = new Headers({
206
206
  vary: 'Accept',
207
- link: alternateLinks(options.href, options.representation, options.available),
207
+ link: [
208
+ alternateLinks(options.href, options.representation, options.available),
209
+ ...(options.links ?? []),
210
+ ]
211
+ .filter((value) => value !== '')
212
+ .join(', '),
208
213
  });
209
- if (options.etag !== undefined)
210
- headers.set('etag', options.etag);
211
- if (options.lastModified !== undefined) {
212
- headers.set('last-modified', options.lastModified.toUTCString());
214
+ const personal = options.private === true;
215
+ if (!personal) {
216
+ if (options.etag !== undefined)
217
+ headers.set('etag', options.etag);
218
+ if (options.lastModified !== undefined) {
219
+ headers.set('last-modified', options.lastModified.toUTCString());
220
+ }
221
+ // A validator without a directive leaves the browser to guess how long the
222
+ // response stays fresh. `no-cache` keeps the validator's value — a cheap
223
+ // 304 — without ever letting a stale page through.
224
+ if (options.etag !== undefined || options.lastModified !== undefined) {
225
+ headers.set('cache-control', 'no-cache');
226
+ }
213
227
  }
214
- // A validator without a directive leaves the browser to guess how long the
215
- // response stays fresh. `no-cache` keeps the validator's value — a cheap 304
216
- // — without ever letting a stale page through.
217
- if (options.etag !== undefined || options.lastModified !== undefined) {
218
- headers.set('cache-control', 'no-cache');
228
+ else {
229
+ headers.set('cache-control', PRIVATE_CACHE_CONTROL);
219
230
  }
220
- if (isNotModified(options.conditional, options.etag, options.lastModified)) {
231
+ if (!personal && isNotModified(options.conditional, options.etag, options.lastModified)) {
221
232
  return new Response(null, { status: 304, headers });
222
233
  }
223
234
  headers.set('content-type', CONTENT_TYPES[options.representation]);
@@ -230,6 +241,15 @@ export function representationResponse(options) {
230
241
  : String(options.body);
231
242
  return new Response(body, { headers });
232
243
  }
244
+ /**
245
+ * What a response drawn for one named reader says about itself.
246
+ *
247
+ * `private` is the part that matters: it tells a shared cache this belongs to
248
+ * one reader and must not be handed to another. `no-store` is the belt to its
249
+ * braces, and keeps the page off the disk of a browser somebody else uses
250
+ * after them.
251
+ */
252
+ export const PRIVATE_CACHE_CONTROL = 'private, no-store';
233
253
  /**
234
254
  * The 406 a request earns when it accepts none of the representations on
235
255
  * offer, with the options in the body so a client can pick one and retry.