@geekity/cms 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (637) hide show
  1. package/README.md +2091 -214
  2. package/admin/components/fields.njk +165 -0
  3. package/admin/layouts/base.njk +1 -1
  4. package/admin/layouts/settings-page.njk +26 -0
  5. package/admin/layouts/shell.njk +17 -3
  6. package/admin/pages/account/forgot.njk +47 -0
  7. package/admin/pages/account/login.njk +26 -0
  8. package/admin/pages/account/reset.njk +38 -0
  9. package/admin/pages/account/setup.njk +28 -0
  10. package/admin/pages/appearance/themes.njk +69 -0
  11. package/admin/pages/comments/all.njk +133 -0
  12. package/admin/{layouts/dashboard.njk → pages/dashboard/home.njk} +8 -15
  13. package/admin/{layouts/document-conflict.njk → pages/documents/conflict.njk} +1 -0
  14. package/admin/pages/documents/editor.njk +196 -0
  15. package/admin/{layouts/document-list.njk → pages/documents/list.njk} +19 -2
  16. package/admin/pages/documents/taxonomy.njk +95 -0
  17. package/admin/pages/federation/followers.njk +238 -0
  18. package/admin/pages/media/library.njk +160 -0
  19. package/admin/pages/messages/all.njk +110 -0
  20. package/admin/{layouts → pages}/placeholder.njk +5 -1
  21. package/admin/pages/settings/discussion.njk +99 -0
  22. package/admin/pages/settings/email.njk +203 -0
  23. package/admin/pages/settings/federation.njk +75 -0
  24. package/admin/pages/settings/general.njk +29 -0
  25. package/admin/pages/settings/permalinks.njk +50 -0
  26. package/admin/pages/settings/reading.njk +72 -0
  27. package/admin/pages/users/edit.njk +239 -0
  28. package/admin/pages/users/list.njk +48 -0
  29. package/admin/pages/users/new.njk +41 -0
  30. package/admin/static/admin.css +498 -3
  31. package/admin/static/copy.js +52 -0
  32. package/admin/static/editor.js +16 -16
  33. package/admin/static/slug.js +61 -0
  34. package/dist/admin/accounts.d.ts +413 -0
  35. package/dist/admin/accounts.d.ts.map +1 -0
  36. package/dist/admin/accounts.js +680 -0
  37. package/dist/admin/accounts.js.map +1 -0
  38. package/dist/admin/appearance.d.ts +80 -0
  39. package/dist/admin/appearance.d.ts.map +1 -0
  40. package/dist/admin/appearance.js +136 -0
  41. package/dist/admin/appearance.js.map +1 -0
  42. package/dist/admin/comments.d.ts +90 -0
  43. package/dist/admin/comments.d.ts.map +1 -0
  44. package/dist/admin/comments.js +244 -0
  45. package/dist/admin/comments.js.map +1 -0
  46. package/dist/admin/credentials.d.ts +26 -2
  47. package/dist/admin/credentials.d.ts.map +1 -1
  48. package/dist/admin/credentials.js +35 -2
  49. package/dist/admin/credentials.js.map +1 -1
  50. package/dist/admin/documents.d.ts +127 -10
  51. package/dist/admin/documents.d.ts.map +1 -1
  52. package/dist/admin/documents.js +360 -41
  53. package/dist/admin/documents.js.map +1 -1
  54. package/dist/admin/federation.d.ts +151 -50
  55. package/dist/admin/federation.d.ts.map +1 -1
  56. package/dist/admin/federation.js +225 -93
  57. package/dist/admin/federation.js.map +1 -1
  58. package/dist/admin/formatting.d.ts +20 -0
  59. package/dist/admin/formatting.d.ts.map +1 -0
  60. package/dist/admin/formatting.js +72 -0
  61. package/dist/admin/formatting.js.map +1 -0
  62. package/dist/admin/headers.d.ts +65 -0
  63. package/dist/admin/headers.d.ts.map +1 -0
  64. package/dist/admin/headers.js +104 -0
  65. package/dist/admin/headers.js.map +1 -0
  66. package/dist/admin/index.d.ts +38 -12
  67. package/dist/admin/index.d.ts.map +1 -1
  68. package/dist/admin/index.js +25 -7
  69. package/dist/admin/index.js.map +1 -1
  70. package/dist/admin/media.d.ts +168 -0
  71. package/dist/admin/media.d.ts.map +1 -0
  72. package/dist/admin/media.js +295 -0
  73. package/dist/admin/media.js.map +1 -0
  74. package/dist/admin/menu.d.ts +79 -0
  75. package/dist/admin/menu.d.ts.map +1 -0
  76. package/dist/admin/menu.js +126 -0
  77. package/dist/admin/menu.js.map +1 -0
  78. package/dist/admin/messages.d.ts +80 -0
  79. package/dist/admin/messages.d.ts.map +1 -0
  80. package/dist/admin/messages.js +152 -0
  81. package/dist/admin/messages.js.map +1 -0
  82. package/dist/admin/preview.d.ts.map +1 -1
  83. package/dist/admin/preview.js +31 -7
  84. package/dist/admin/preview.js.map +1 -1
  85. package/dist/admin/recovery.d.ts +92 -0
  86. package/dist/admin/recovery.d.ts.map +1 -0
  87. package/dist/admin/recovery.js +229 -0
  88. package/dist/admin/recovery.js.map +1 -0
  89. package/dist/admin/routes.d.ts +0 -20
  90. package/dist/admin/routes.d.ts.map +1 -1
  91. package/dist/admin/routes.js +155 -105
  92. package/dist/admin/routes.js.map +1 -1
  93. package/dist/admin/settings-discussion.d.ts +37 -0
  94. package/dist/admin/settings-discussion.d.ts.map +1 -0
  95. package/dist/admin/settings-discussion.js +117 -0
  96. package/dist/admin/settings-discussion.js.map +1 -0
  97. package/dist/admin/settings-email.d.ts +54 -0
  98. package/dist/admin/settings-email.d.ts.map +1 -0
  99. package/dist/admin/settings-email.js +189 -0
  100. package/dist/admin/settings-email.js.map +1 -0
  101. package/dist/admin/settings-federation.d.ts +39 -0
  102. package/dist/admin/settings-federation.d.ts.map +1 -0
  103. package/dist/admin/settings-federation.js +103 -0
  104. package/dist/admin/settings-federation.js.map +1 -0
  105. package/dist/admin/settings-general.d.ts +12 -0
  106. package/dist/admin/settings-general.d.ts.map +1 -0
  107. package/dist/admin/settings-general.js +48 -0
  108. package/dist/admin/settings-general.js.map +1 -0
  109. package/dist/admin/settings-page.d.ts +102 -0
  110. package/dist/admin/settings-page.d.ts.map +1 -0
  111. package/dist/admin/settings-page.js +126 -0
  112. package/dist/admin/settings-page.js.map +1 -0
  113. package/dist/admin/settings-pages.d.ts +19 -0
  114. package/dist/admin/settings-pages.d.ts.map +1 -0
  115. package/dist/admin/settings-pages.js +33 -0
  116. package/dist/admin/settings-pages.js.map +1 -0
  117. package/dist/admin/settings-permalinks.d.ts +16 -0
  118. package/dist/admin/settings-permalinks.d.ts.map +1 -0
  119. package/dist/admin/settings-permalinks.js +32 -0
  120. package/dist/admin/settings-permalinks.js.map +1 -0
  121. package/dist/admin/settings-reading.d.ts +33 -0
  122. package/dist/admin/settings-reading.d.ts.map +1 -0
  123. package/dist/admin/settings-reading.js +48 -0
  124. package/dist/admin/settings-reading.js.map +1 -0
  125. package/dist/admin/settings.d.ts +325 -96
  126. package/dist/admin/settings.d.ts.map +1 -1
  127. package/dist/admin/settings.js +650 -308
  128. package/dist/admin/settings.js.map +1 -1
  129. package/dist/admin/store.d.ts +606 -152
  130. package/dist/admin/store.d.ts.map +1 -1
  131. package/dist/admin/store.js +863 -268
  132. package/dist/admin/store.js.map +1 -1
  133. package/dist/admin/taxonomy.d.ts +114 -0
  134. package/dist/admin/taxonomy.d.ts.map +1 -0
  135. package/dist/admin/taxonomy.js +289 -0
  136. package/dist/admin/taxonomy.js.map +1 -0
  137. package/dist/admin/templates.d.ts +44 -14
  138. package/dist/admin/templates.d.ts.map +1 -1
  139. package/dist/admin/templates.js +44 -14
  140. package/dist/admin/templates.js.map +1 -1
  141. package/dist/admin/throttle.d.ts +84 -0
  142. package/dist/admin/throttle.d.ts.map +1 -0
  143. package/dist/admin/throttle.js +143 -0
  144. package/dist/admin/throttle.js.map +1 -0
  145. package/dist/admin/uploads.d.ts +28 -2
  146. package/dist/admin/uploads.d.ts.map +1 -1
  147. package/dist/admin/uploads.js +43 -4
  148. package/dist/admin/uploads.js.map +1 -1
  149. package/dist/admin/users.d.ts +100 -13
  150. package/dist/admin/users.d.ts.map +1 -1
  151. package/dist/admin/users.js +412 -39
  152. package/dist/admin/users.js.map +1 -1
  153. package/dist/cache.d.ts +141 -0
  154. package/dist/cache.d.ts.map +1 -0
  155. package/dist/cache.js +207 -0
  156. package/dist/cache.js.map +1 -0
  157. package/dist/cli.d.ts +14 -2
  158. package/dist/cli.d.ts.map +1 -1
  159. package/dist/cli.js +424 -21
  160. package/dist/cli.js.map +1 -1
  161. package/dist/comments/akismet.d.ts +130 -0
  162. package/dist/comments/akismet.d.ts.map +1 -0
  163. package/dist/comments/akismet.js +274 -0
  164. package/dist/comments/akismet.js.map +1 -0
  165. package/dist/comments/conversation.d.ts +29 -0
  166. package/dist/comments/conversation.d.ts.map +1 -0
  167. package/dist/comments/conversation.js +60 -0
  168. package/dist/comments/conversation.js.map +1 -0
  169. package/dist/comments/form.d.ts +75 -0
  170. package/dist/comments/form.d.ts.map +1 -0
  171. package/dist/comments/form.js +64 -0
  172. package/dist/comments/form.js.map +1 -0
  173. package/dist/comments/index.d.ts +15 -0
  174. package/dist/comments/index.d.ts.map +1 -0
  175. package/dist/comments/index.js +9 -0
  176. package/dist/comments/index.js.map +1 -0
  177. package/dist/comments/markdown.d.ts +8 -0
  178. package/dist/comments/markdown.d.ts.map +1 -0
  179. package/dist/comments/markdown.js +85 -0
  180. package/dist/comments/markdown.js.map +1 -0
  181. package/dist/comments/moderate.d.ts +71 -0
  182. package/dist/comments/moderate.d.ts.map +1 -0
  183. package/dist/comments/moderate.js +88 -0
  184. package/dist/comments/moderate.js.map +1 -0
  185. package/dist/comments/policy.d.ts +57 -0
  186. package/dist/comments/policy.d.ts.map +1 -0
  187. package/dist/comments/policy.js +80 -0
  188. package/dist/comments/policy.js.map +1 -0
  189. package/dist/comments/records.d.ts +266 -0
  190. package/dist/comments/records.d.ts.map +1 -0
  191. package/dist/comments/records.js +487 -0
  192. package/dist/comments/records.js.map +1 -0
  193. package/dist/comments/routes.d.ts +58 -0
  194. package/dist/comments/routes.d.ts.map +1 -0
  195. package/dist/comments/routes.js +177 -0
  196. package/dist/comments/routes.js.map +1 -0
  197. package/dist/comments/submission.d.ts +263 -0
  198. package/dist/comments/submission.d.ts.map +1 -0
  199. package/dist/comments/submission.js +241 -0
  200. package/dist/comments/submission.js.map +1 -0
  201. package/dist/config.d.ts +190 -5
  202. package/dist/config.d.ts.map +1 -1
  203. package/dist/config.js +118 -6
  204. package/dist/config.js.map +1 -1
  205. package/dist/contact/delivery.d.ts +60 -0
  206. package/dist/contact/delivery.d.ts.map +1 -0
  207. package/dist/contact/delivery.js +87 -0
  208. package/dist/contact/delivery.js.map +1 -0
  209. package/dist/contact/form.d.ts +130 -0
  210. package/dist/contact/form.d.ts.map +1 -0
  211. package/dist/contact/form.js +163 -0
  212. package/dist/contact/form.js.map +1 -0
  213. package/dist/contact/index.d.ts +17 -0
  214. package/dist/contact/index.d.ts.map +1 -0
  215. package/dist/contact/index.js +13 -0
  216. package/dist/contact/index.js.map +1 -0
  217. package/dist/contact/records.d.ts +124 -0
  218. package/dist/contact/records.d.ts.map +1 -0
  219. package/dist/contact/records.js +218 -0
  220. package/dist/contact/records.js.map +1 -0
  221. package/dist/contact/routes.d.ts +17 -0
  222. package/dist/contact/routes.d.ts.map +1 -0
  223. package/dist/contact/routes.js +127 -0
  224. package/dist/contact/routes.js.map +1 -0
  225. package/dist/contact/submission.d.ts +103 -0
  226. package/dist/contact/submission.d.ts.map +1 -0
  227. package/dist/contact/submission.js +166 -0
  228. package/dist/contact/submission.js.map +1 -0
  229. package/dist/content/document.d.ts +7 -2
  230. package/dist/content/document.d.ts.map +1 -1
  231. package/dist/content/document.js +1 -0
  232. package/dist/content/document.js.map +1 -1
  233. package/dist/content/index.d.ts +7 -2
  234. package/dist/content/index.d.ts.map +1 -1
  235. package/dist/content/index.js +4 -1
  236. package/dist/content/index.js.map +1 -1
  237. package/dist/content/markdown.d.ts.map +1 -1
  238. package/dist/content/markdown.js +24 -2
  239. package/dist/content/markdown.js.map +1 -1
  240. package/dist/content/parser.d.ts.map +1 -1
  241. package/dist/content/parser.js +11 -4
  242. package/dist/content/parser.js.map +1 -1
  243. package/dist/content/save.d.ts +5 -0
  244. package/dist/content/save.d.ts.map +1 -1
  245. package/dist/content/save.js +44 -1
  246. package/dist/content/save.js.map +1 -1
  247. package/dist/content/schedule.d.ts +125 -0
  248. package/dist/content/schedule.d.ts.map +1 -0
  249. package/dist/content/schedule.js +207 -0
  250. package/dist/content/schedule.js.map +1 -0
  251. package/dist/content/search.d.ts +64 -0
  252. package/dist/content/search.d.ts.map +1 -0
  253. package/dist/content/search.js +136 -0
  254. package/dist/content/search.js.map +1 -0
  255. package/dist/content/store.d.ts +202 -7
  256. package/dist/content/store.d.ts.map +1 -1
  257. package/dist/content/store.js +374 -67
  258. package/dist/content/store.js.map +1 -1
  259. package/dist/content/sync.d.ts +7 -1
  260. package/dist/content/sync.d.ts.map +1 -1
  261. package/dist/content/sync.js +18 -10
  262. package/dist/content/sync.js.map +1 -1
  263. package/dist/content/time.d.ts +56 -0
  264. package/dist/content/time.d.ts.map +1 -0
  265. package/dist/content/time.js +141 -0
  266. package/dist/content/time.js.map +1 -0
  267. package/dist/content/writer.d.ts.map +1 -1
  268. package/dist/content/writer.js +3 -0
  269. package/dist/content/writer.js.map +1 -1
  270. package/dist/env.d.ts +58 -4
  271. package/dist/env.d.ts.map +1 -1
  272. package/dist/federation/actor.d.ts +95 -41
  273. package/dist/federation/actor.d.ts.map +1 -1
  274. package/dist/federation/actor.js +180 -53
  275. package/dist/federation/actor.js.map +1 -1
  276. package/dist/federation/article.d.ts +44 -17
  277. package/dist/federation/article.d.ts.map +1 -1
  278. package/dist/federation/article.js +98 -46
  279. package/dist/federation/article.js.map +1 -1
  280. package/dist/federation/delivery.d.ts +63 -15
  281. package/dist/federation/delivery.d.ts.map +1 -1
  282. package/dist/federation/delivery.js +154 -80
  283. package/dist/federation/delivery.js.map +1 -1
  284. package/dist/federation/federation.d.ts +22 -17
  285. package/dist/federation/federation.d.ts.map +1 -1
  286. package/dist/federation/federation.js +98 -77
  287. package/dist/federation/federation.js.map +1 -1
  288. package/dist/federation/followers.d.ts +3 -2
  289. package/dist/federation/followers.d.ts.map +1 -1
  290. package/dist/federation/followers.js +6 -5
  291. package/dist/federation/followers.js.map +1 -1
  292. package/dist/federation/import-wordpress.d.ts +128 -0
  293. package/dist/federation/import-wordpress.d.ts.map +1 -0
  294. package/dist/federation/import-wordpress.js +426 -0
  295. package/dist/federation/import-wordpress.js.map +1 -0
  296. package/dist/federation/inbox.d.ts +36 -13
  297. package/dist/federation/inbox.d.ts.map +1 -1
  298. package/dist/federation/inbox.js +120 -49
  299. package/dist/federation/inbox.js.map +1 -1
  300. package/dist/federation/index.d.ts +22 -10
  301. package/dist/federation/index.d.ts.map +1 -1
  302. package/dist/federation/index.js +13 -8
  303. package/dist/federation/index.js.map +1 -1
  304. package/dist/federation/keys.d.ts +98 -20
  305. package/dist/federation/keys.d.ts.map +1 -1
  306. package/dist/federation/keys.js +269 -39
  307. package/dist/federation/keys.js.map +1 -1
  308. package/dist/federation/mount.d.ts +42 -10
  309. package/dist/federation/mount.d.ts.map +1 -1
  310. package/dist/federation/mount.js +266 -26
  311. package/dist/federation/mount.js.map +1 -1
  312. package/dist/federation/paths.d.ts +23 -35
  313. package/dist/federation/paths.d.ts.map +1 -1
  314. package/dist/federation/paths.js +26 -39
  315. package/dist/federation/paths.js.map +1 -1
  316. package/dist/federation/records.d.ts +223 -0
  317. package/dist/federation/records.d.ts.map +1 -0
  318. package/dist/federation/records.js +506 -0
  319. package/dist/federation/records.js.map +1 -0
  320. package/dist/federation/relays.d.ts +114 -0
  321. package/dist/federation/relays.d.ts.map +1 -0
  322. package/dist/federation/relays.js +290 -0
  323. package/dist/federation/relays.js.map +1 -0
  324. package/dist/federation/replies.d.ts +80 -0
  325. package/dist/federation/replies.d.ts.map +1 -0
  326. package/dist/federation/replies.js +166 -0
  327. package/dist/federation/replies.js.map +1 -0
  328. package/dist/federation/wordpress.d.ts +131 -0
  329. package/dist/federation/wordpress.d.ts.map +1 -0
  330. package/dist/federation/wordpress.js +341 -0
  331. package/dist/federation/wordpress.js.map +1 -0
  332. package/dist/files/atomic.d.ts +103 -0
  333. package/dist/files/atomic.d.ts.map +1 -0
  334. package/dist/files/atomic.js +150 -0
  335. package/dist/files/atomic.js.map +1 -0
  336. package/dist/files/index.d.ts +3 -0
  337. package/dist/files/index.d.ts.map +1 -0
  338. package/dist/files/index.js +2 -0
  339. package/dist/files/index.js.map +1 -0
  340. package/dist/forms/protection.d.ts +85 -0
  341. package/dist/forms/protection.d.ts.map +1 -0
  342. package/dist/forms/protection.js +116 -0
  343. package/dist/forms/protection.js.map +1 -0
  344. package/dist/images/icons.d.ts +59 -0
  345. package/dist/images/icons.d.ts.map +1 -0
  346. package/dist/images/icons.js +131 -0
  347. package/dist/images/icons.js.map +1 -0
  348. package/dist/images/index.d.ts +7 -0
  349. package/dist/images/index.d.ts.map +1 -0
  350. package/dist/images/index.js +4 -0
  351. package/dist/images/index.js.map +1 -0
  352. package/dist/images/markup.d.ts +47 -0
  353. package/dist/images/markup.d.ts.map +1 -0
  354. package/dist/images/markup.js +175 -0
  355. package/dist/images/markup.js.map +1 -0
  356. package/dist/images/paths.d.ts +34 -0
  357. package/dist/images/paths.d.ts.map +1 -0
  358. package/dist/images/paths.js +41 -0
  359. package/dist/images/paths.js.map +1 -0
  360. package/dist/images/variants.d.ts +104 -0
  361. package/dist/images/variants.d.ts.map +1 -0
  362. package/dist/images/variants.js +320 -0
  363. package/dist/images/variants.js.map +1 -0
  364. package/dist/index.d.ts +123 -19
  365. package/dist/index.d.ts.map +1 -1
  366. package/dist/index.js +327 -25
  367. package/dist/index.js.map +1 -1
  368. package/dist/init.d.ts +18 -0
  369. package/dist/init.d.ts.map +1 -1
  370. package/dist/init.js +34 -3
  371. package/dist/init.js.map +1 -1
  372. package/dist/mail/brevo.d.ts +35 -0
  373. package/dist/mail/brevo.d.ts.map +1 -0
  374. package/dist/mail/brevo.js +85 -0
  375. package/dist/mail/brevo.js.map +1 -0
  376. package/dist/mail/credentials.d.ts +62 -0
  377. package/dist/mail/credentials.d.ts.map +1 -0
  378. package/dist/mail/credentials.js +86 -0
  379. package/dist/mail/credentials.js.map +1 -0
  380. package/dist/mail/index.d.ts +15 -0
  381. package/dist/mail/index.d.ts.map +1 -0
  382. package/dist/mail/index.js +8 -0
  383. package/dist/mail/index.js.map +1 -0
  384. package/dist/mail/memory.d.ts +35 -0
  385. package/dist/mail/memory.d.ts.map +1 -0
  386. package/dist/mail/memory.js +29 -0
  387. package/dist/mail/memory.js.map +1 -0
  388. package/dist/mail/provider.d.ts +80 -0
  389. package/dist/mail/provider.d.ts.map +1 -0
  390. package/dist/mail/provider.js +23 -0
  391. package/dist/mail/provider.js.map +1 -0
  392. package/dist/mail/service.d.ts +156 -0
  393. package/dist/mail/service.d.ts.map +1 -0
  394. package/dist/mail/service.js +265 -0
  395. package/dist/mail/service.js.map +1 -0
  396. package/dist/mail/smtp.d.ts +39 -0
  397. package/dist/mail/smtp.d.ts.map +1 -0
  398. package/dist/mail/smtp.js +58 -0
  399. package/dist/mail/smtp.js.map +1 -0
  400. package/dist/mail/templates.d.ts +91 -0
  401. package/dist/mail/templates.d.ts.map +1 -0
  402. package/dist/mail/templates.js +69 -0
  403. package/dist/mail/templates.js.map +1 -0
  404. package/dist/notifications/comments.d.ts +66 -0
  405. package/dist/notifications/comments.d.ts.map +1 -0
  406. package/dist/notifications/comments.js +151 -0
  407. package/dist/notifications/comments.js.map +1 -0
  408. package/dist/notifications/digest.d.ts +135 -0
  409. package/dist/notifications/digest.d.ts.map +1 -0
  410. package/dist/notifications/digest.js +287 -0
  411. package/dist/notifications/digest.js.map +1 -0
  412. package/dist/notifications/index.d.ts +13 -0
  413. package/dist/notifications/index.d.ts.map +1 -0
  414. package/dist/notifications/index.js +8 -0
  415. package/dist/notifications/index.js.map +1 -0
  416. package/dist/notifications/links.d.ts +60 -0
  417. package/dist/notifications/links.d.ts.map +1 -0
  418. package/dist/notifications/links.js +63 -0
  419. package/dist/notifications/links.js.map +1 -0
  420. package/dist/notifications/optouts.d.ts +48 -0
  421. package/dist/notifications/optouts.d.ts.map +1 -0
  422. package/dist/notifications/optouts.js +93 -0
  423. package/dist/notifications/optouts.js.map +1 -0
  424. package/dist/notifications/preferences.d.ts +158 -0
  425. package/dist/notifications/preferences.d.ts.map +1 -0
  426. package/dist/notifications/preferences.js +195 -0
  427. package/dist/notifications/preferences.js.map +1 -0
  428. package/dist/notifications/routes.d.ts +28 -0
  429. package/dist/notifications/routes.d.ts.map +1 -0
  430. package/dist/notifications/routes.js +184 -0
  431. package/dist/notifications/routes.js.map +1 -0
  432. package/dist/notifications/tokens.d.ts +60 -0
  433. package/dist/notifications/tokens.d.ts.map +1 -0
  434. package/dist/notifications/tokens.js +125 -0
  435. package/dist/notifications/tokens.js.map +1 -0
  436. package/dist/notify.d.ts +84 -0
  437. package/dist/notify.d.ts.map +1 -0
  438. package/dist/notify.js +149 -0
  439. package/dist/notify.js.map +1 -0
  440. package/dist/web/archive.d.ts +49 -0
  441. package/dist/web/archive.d.ts.map +1 -0
  442. package/dist/web/archive.js +59 -0
  443. package/dist/web/archive.js.map +1 -0
  444. package/dist/web/assets.d.ts +6 -5
  445. package/dist/web/assets.d.ts.map +1 -1
  446. package/dist/web/assets.js +5 -7
  447. package/dist/web/assets.js.map +1 -1
  448. package/dist/web/authors.d.ts +143 -0
  449. package/dist/web/authors.d.ts.map +1 -0
  450. package/dist/web/authors.js +178 -0
  451. package/dist/web/authors.js.map +1 -0
  452. package/dist/web/comments.d.ts +60 -0
  453. package/dist/web/comments.d.ts.map +1 -0
  454. package/dist/web/comments.js +207 -0
  455. package/dist/web/comments.js.map +1 -0
  456. package/dist/web/context.d.ts +162 -28
  457. package/dist/web/context.d.ts.map +1 -1
  458. package/dist/web/context.js +123 -26
  459. package/dist/web/context.js.map +1 -1
  460. package/dist/web/conversation.d.ts +209 -0
  461. package/dist/web/conversation.d.ts.map +1 -0
  462. package/dist/web/conversation.js +557 -0
  463. package/dist/web/conversation.js.map +1 -0
  464. package/dist/web/documents.d.ts +36 -6
  465. package/dist/web/documents.d.ts.map +1 -1
  466. package/dist/web/documents.js +52 -10
  467. package/dist/web/documents.js.map +1 -1
  468. package/dist/web/feed-atom.d.ts +22 -0
  469. package/dist/web/feed-atom.d.ts.map +1 -0
  470. package/dist/web/feed-atom.js +83 -0
  471. package/dist/web/feed-atom.js.map +1 -0
  472. package/dist/web/feed-item.d.ts +145 -0
  473. package/dist/web/feed-item.d.ts.map +1 -0
  474. package/dist/web/feed-item.js +120 -0
  475. package/dist/web/feed-item.js.map +1 -0
  476. package/dist/web/feed-json.d.ts +79 -0
  477. package/dist/web/feed-json.d.ts.map +1 -0
  478. package/dist/web/feed-json.js +53 -0
  479. package/dist/web/feed-json.js.map +1 -0
  480. package/dist/web/feed-rss.d.ts +26 -0
  481. package/dist/web/feed-rss.d.ts.map +1 -0
  482. package/dist/web/feed-rss.js +203 -0
  483. package/dist/web/feed-rss.js.map +1 -0
  484. package/dist/web/feed-source.d.ts +244 -0
  485. package/dist/web/feed-source.d.ts.map +1 -0
  486. package/dist/web/feed-source.js +201 -0
  487. package/dist/web/feed-source.js.map +1 -0
  488. package/dist/web/feed-xml.d.ts +63 -0
  489. package/dist/web/feed-xml.d.ts.map +1 -0
  490. package/dist/web/feed-xml.js +116 -0
  491. package/dist/web/feed-xml.js.map +1 -0
  492. package/dist/web/feeds.d.ts +31 -96
  493. package/dist/web/feeds.d.ts.map +1 -1
  494. package/dist/web/feeds.js +94 -198
  495. package/dist/web/feeds.js.map +1 -1
  496. package/dist/web/health.d.ts +31 -0
  497. package/dist/web/health.d.ts.map +1 -0
  498. package/dist/web/health.js +44 -0
  499. package/dist/web/health.js.map +1 -0
  500. package/dist/web/index.d.ts +30 -10
  501. package/dist/web/index.d.ts.map +1 -1
  502. package/dist/web/index.js +18 -7
  503. package/dist/web/index.js.map +1 -1
  504. package/dist/web/navigation.d.ts +73 -0
  505. package/dist/web/navigation.d.ts.map +1 -0
  506. package/dist/web/navigation.js +110 -0
  507. package/dist/web/navigation.js.map +1 -0
  508. package/dist/web/negotiate.d.ts +9 -0
  509. package/dist/web/negotiate.d.ts.map +1 -1
  510. package/dist/web/negotiate.js +6 -1
  511. package/dist/web/negotiate.js.map +1 -1
  512. package/dist/web/recent.d.ts +43 -0
  513. package/dist/web/recent.d.ts.map +1 -0
  514. package/dist/web/recent.js +37 -0
  515. package/dist/web/recent.js.map +1 -0
  516. package/dist/web/render.d.ts +197 -9
  517. package/dist/web/render.d.ts.map +1 -1
  518. package/dist/web/render.js +334 -17
  519. package/dist/web/render.js.map +1 -1
  520. package/dist/web/routes.d.ts +25 -8
  521. package/dist/web/routes.d.ts.map +1 -1
  522. package/dist/web/routes.js +845 -93
  523. package/dist/web/routes.js.map +1 -1
  524. package/dist/web/sanitize.d.ts +19 -0
  525. package/dist/web/sanitize.d.ts.map +1 -0
  526. package/dist/web/sanitize.js +272 -0
  527. package/dist/web/sanitize.js.map +1 -0
  528. package/dist/web/search.d.ts +79 -0
  529. package/dist/web/search.d.ts.map +1 -0
  530. package/dist/web/search.js +94 -0
  531. package/dist/web/search.js.map +1 -0
  532. package/dist/web/sitemap.d.ts +120 -0
  533. package/dist/web/sitemap.d.ts.map +1 -0
  534. package/dist/web/sitemap.js +199 -0
  535. package/dist/web/sitemap.js.map +1 -0
  536. package/dist/web/taxonomy.d.ts +152 -0
  537. package/dist/web/taxonomy.d.ts.map +1 -0
  538. package/dist/web/taxonomy.js +237 -0
  539. package/dist/web/taxonomy.js.map +1 -0
  540. package/dist/web/templates.d.ts +54 -16
  541. package/dist/web/templates.d.ts.map +1 -1
  542. package/dist/web/templates.js +109 -28
  543. package/dist/web/templates.js.map +1 -1
  544. package/dist/web/themes.d.ts +205 -0
  545. package/dist/web/themes.d.ts.map +1 -0
  546. package/dist/web/themes.js +277 -0
  547. package/dist/web/themes.js.map +1 -0
  548. package/dist/webmention/discovery.d.ts +51 -0
  549. package/dist/webmention/discovery.d.ts.map +1 -0
  550. package/dist/webmention/discovery.js +176 -0
  551. package/dist/webmention/discovery.js.map +1 -0
  552. package/dist/webmention/html.d.ts +71 -0
  553. package/dist/webmention/html.d.ts.map +1 -0
  554. package/dist/webmention/html.js +285 -0
  555. package/dist/webmention/html.js.map +1 -0
  556. package/dist/webmention/index.d.ts +12 -0
  557. package/dist/webmention/index.d.ts.map +1 -0
  558. package/dist/webmention/index.js +8 -0
  559. package/dist/webmention/index.js.map +1 -0
  560. package/dist/webmention/links.d.ts +18 -0
  561. package/dist/webmention/links.d.ts.map +1 -0
  562. package/dist/webmention/links.js +64 -0
  563. package/dist/webmention/links.js.map +1 -0
  564. package/dist/webmention/microformats.d.ts +93 -0
  565. package/dist/webmention/microformats.d.ts.map +1 -0
  566. package/dist/webmention/microformats.js +376 -0
  567. package/dist/webmention/microformats.js.map +1 -0
  568. package/dist/webmention/receive.d.ts +141 -0
  569. package/dist/webmention/receive.d.ts.map +1 -0
  570. package/dist/webmention/receive.js +264 -0
  571. package/dist/webmention/receive.js.map +1 -0
  572. package/dist/webmention/routes.d.ts +37 -0
  573. package/dist/webmention/routes.d.ts.map +1 -0
  574. package/dist/webmention/routes.js +75 -0
  575. package/dist/webmention/routes.js.map +1 -0
  576. package/dist/webmention/service.d.ts +94 -0
  577. package/dist/webmention/service.d.ts.map +1 -0
  578. package/dist/webmention/service.js +207 -0
  579. package/dist/webmention/service.js.map +1 -0
  580. package/package.json +11 -6
  581. package/templates/site/content/_data/site.json +1 -0
  582. package/templates/site/content/posts/2026-01-01-hello-world.md +5 -3
  583. package/templates/site/geekity.config.ts +11 -1
  584. package/templates/site/tsconfig.json +1 -1
  585. package/themes/default/README.md +1096 -50
  586. package/themes/default/layouts/404.njk +2 -3
  587. package/themes/default/layouts/author.njk +37 -0
  588. package/themes/default/layouts/base.njk +172 -31
  589. package/themes/default/layouts/category.njk +27 -0
  590. package/themes/default/layouts/front-page.njk +57 -0
  591. package/themes/default/layouts/home.njk +17 -1
  592. package/themes/default/layouts/page.njk +57 -5
  593. package/themes/default/layouts/post.njk +78 -19
  594. package/themes/default/layouts/search.njk +57 -0
  595. package/themes/default/layouts/tag.njk +3 -6
  596. package/themes/default/mail/comment-digest.html.njk +37 -0
  597. package/themes/default/mail/comment-digest.subject.njk +3 -0
  598. package/themes/default/mail/comment-digest.txt.njk +40 -0
  599. package/themes/default/mail/comment-pending.html.njk +27 -0
  600. package/themes/default/mail/comment-pending.subject.njk +2 -0
  601. package/themes/default/mail/comment-pending.txt.njk +24 -0
  602. package/themes/default/mail/comment-reply.html.njk +21 -0
  603. package/themes/default/mail/comment-reply.subject.njk +2 -0
  604. package/themes/default/mail/comment-reply.txt.njk +22 -0
  605. package/themes/default/mail/contact-message.html.njk +24 -0
  606. package/themes/default/mail/contact-message.subject.njk +5 -0
  607. package/themes/default/mail/contact-message.txt.njk +20 -0
  608. package/themes/default/mail/password-changed.html.njk +18 -0
  609. package/themes/default/mail/password-changed.subject.njk +2 -0
  610. package/themes/default/mail/password-changed.txt.njk +17 -0
  611. package/themes/default/mail/password-reset.html.njk +22 -0
  612. package/themes/default/mail/password-reset.subject.njk +2 -0
  613. package/themes/default/mail/password-reset.txt.njk +18 -0
  614. package/themes/default/mail/test.html.njk +14 -0
  615. package/themes/default/mail/test.subject.njk +2 -0
  616. package/themes/default/mail/test.txt.njk +12 -0
  617. package/themes/default/partials/archive.njk +27 -0
  618. package/themes/default/partials/bio.njk +77 -0
  619. package/themes/default/partials/comment-form.njk +109 -0
  620. package/themes/default/partials/contact-form.njk +88 -0
  621. package/themes/default/partials/conversation.njk +139 -0
  622. package/themes/default/partials/feeds.njk +26 -0
  623. package/themes/default/partials/jsonld.njk +120 -0
  624. package/themes/default/partials/pagination.njk +12 -6
  625. package/themes/default/partials/post-list.njk +51 -18
  626. package/themes/default/partials/search-form.njk +17 -0
  627. package/themes/default/partials/tags.njk +26 -5
  628. package/themes/default/static/highlight.js +4 -0
  629. package/themes/default/static/style.css +1119 -194
  630. package/themes/default/theme.json +5 -0
  631. package/admin/layouts/document-editor.njk +0 -167
  632. package/admin/layouts/federation.njk +0 -145
  633. package/admin/layouts/login.njk +0 -23
  634. package/admin/layouts/settings.njk +0 -116
  635. package/admin/layouts/setup.njk +0 -27
  636. package/admin/layouts/users.njk +0 -91
  637. /package/admin/{layouts/_flash.njk → components/flash.njk} +0 -0
@@ -1,38 +1,114 @@
1
1
  import { respondWithObject } from '@fedify/fedify';
2
2
  import { federation as federationMiddleware } from '@fedify/hono';
3
+ import { listUsers } from '../admin/accounts.js';
4
+ import { readSiteSettings } from '../admin/settings.js';
5
+ import { authorHref, parseAuthorPath } from '../web/authors.js';
3
6
  import { publicDocumentAt } from '../web/documents.js';
4
- import { prefersActivityStreams } from '../web/negotiate.js';
7
+ import { absoluteUrl, prefersActivityStreams } from '../web/negotiate.js';
5
8
  import { requestPath } from '../web/routes.js';
9
+ import { actorAliases, actorId, userActor } from './actor.js';
6
10
  import { isFederatedDocument, postArticle } from './article.js';
11
+ import { federationOrigin, handleHref } from './paths.js';
12
+ import { recordWordPressRequest, userByWordPressActorId, wordPressRequestTarget, } from './wordpress.js';
7
13
  /**
8
14
  * Put Fedify in front of the rest of the app.
9
15
  *
10
16
  * The middleware only answers the paths Fedify registered — the actor, its
11
- * collections, the post objects, WebFinger and NodeInfo; everything else falls
12
- * through to `next()` and reaches the admin and the public site as before.
13
- * That is why it is mounted first: the public site claims every unmatched path
14
- * in its not-found handler, so anything registered after it never sees a
15
- * request.
17
+ * collections, WebFinger and NodeInfo; everything else falls through to
18
+ * `next()` and reaches the admin and the public site as before. That is why it
19
+ * is mounted first: the public site claims every unmatched path in its
20
+ * not-found handler, so anything registered after it never sees a request.
16
21
  *
17
- * A post permalink asked for as ActivityStreams is answered here too, by
18
- * {@link activityStreamsDocument}, because Fedify only knows about the URLs it
19
- * minted and a permalink is not one of them.
22
+ * A post's object is not one of Fedify's paths at all. decision-13 makes a
23
+ * post's ActivityStreams id its permalink, so {@link activityStreamsDocument}
24
+ * is what serves the `Article`: one URL, answering a browser with the page and
25
+ * a peer with the object. The same handler answers at the `activitypub.id` a
26
+ * migrated post's file names, and sends a browser from there to the permalink.
20
27
  *
21
28
  * The dispatchers are handed the stores off the Hono context rather than
22
29
  * closing over them, so one federation object could serve more than one CMS
23
30
  * and so a dispatcher is never reading a store the request did not come with.
24
31
  */
25
- export function mountFederation(app, federation) {
32
+ export function mountFederation(app, federation, options = {}) {
33
+ // WebFinger is ours rather than Fedify's, and so has to be registered before
34
+ // the middleware that would otherwise answer it. Fedify hard-codes the
35
+ // `self` link to the dispatcher path and computes `aliases` from the
36
+ // resource, neither of which can be added to, so an actor served under the
37
+ // id it had elsewhere could never be discovered by it (doc-8). Owning the
38
+ // route is a dozen lines and gives complete control of `subject`, `aliases`
39
+ // and `links`.
40
+ app.get(WEBFINGER_PATH, (c) => {
41
+ const resource = c.req.query('resource') ?? '';
42
+ const user = webFingerSubject(c, resource);
43
+ if (user === undefined)
44
+ return c.notFound();
45
+ const context = federation.createContext(c.req.raw, contextData(c));
46
+ const { baseUrl } = c.var.config;
47
+ const aliases = actorAliases(context, user, baseUrl);
48
+ return c.json({
49
+ subject: acctOf(user.username, c.var.config.baseUrl),
50
+ aliases: aliases.map((alias) => alias.href),
51
+ links: [
52
+ {
53
+ rel: 'self',
54
+ type: 'application/activity+json',
55
+ href: actorId(context, user).href,
56
+ },
57
+ {
58
+ rel: 'http://webfinger.net/rel/profile-page',
59
+ type: 'text/html',
60
+ href: absoluteUrl(authorHref(user.username), baseUrl),
61
+ },
62
+ ],
63
+ }, 200, {
64
+ // The media type RFC 7033 defines, and the header that lets a browser
65
+ // application read the answer, which is what every other WebFinger
66
+ // server sends.
67
+ 'content-type': 'application/jrd+json; charset=utf-8',
68
+ 'access-control-allow-origin': '*',
69
+ });
70
+ });
71
+ // `/@ada`, the short URL WordPress publishes beside the author archive and
72
+ // the one a person is most likely to type. It is an alias rather than a
73
+ // second identity, so it goes where the identity is.
74
+ app.get('/:handle{@.+}', (c) => {
75
+ // The pattern is a regex rather than `/@:username`, because Hono's path
76
+ // parameters are whole segments: the `@` has to be matched inside one.
77
+ const handle = c.req.param('handle') ?? '';
78
+ return c.redirect(authorHref(decodeURIComponent(handle.slice(1))), 301);
79
+ });
26
80
  // `@fedify/hono` types its context as the two properties it actually reads,
27
81
  // which is looser than Hono's own; the cast is what puts `c.var` back.
28
- app.use('*', federationMiddleware(federation, (context) => {
82
+ const fedify = federationMiddleware(federation, (context) => {
29
83
  const c = context;
30
84
  return contextData(c);
31
- }));
85
+ });
86
+ // The one path where Fedify and the public site both have a claim: a user's
87
+ // author archive is their actor id (decision-14), and Fedify answers a bare
88
+ // `Accept: application/json` as an ActivityStreams request while doc-3 gives
89
+ // that spelling the listing's own JSON. The CMS's rule decides, so a peer
90
+ // asking for `activity+json` or `ld+json` gets the actor and everything else
91
+ // — a browser, a reader, a feed tool — reaches the archive it asked for.
92
+ // Every other Fedify path is left exactly as it was.
93
+ const federationGate = async (c, next) => {
94
+ const isArchive = parseAuthorPath(requestPath(c)) !== undefined;
95
+ if (isArchive && !prefersActivityStreams(c.req.header('accept')))
96
+ return await next();
97
+ return await fedify(c, next);
98
+ };
99
+ app.use('*', federationGate);
100
+ // And then WordPress's, if the site is carrying them (TASK-70). It goes
101
+ // after the canonical middleware, which has already claimed everything it
102
+ // answers, and before the stored-id middleware below, which claims paths of
103
+ // its own: a `/wp-json/` path is served by whichever of the three wants it,
104
+ // and only this one ever does.
105
+ if (options.wordpress !== undefined) {
106
+ app.use('*', wordPressGate(options.wordpress));
107
+ }
32
108
  // Named, and typed as a middleware, so the Hono context arrives with its
33
109
  // path parameters resolved rather than as `any`.
34
110
  const activityStreams = async (c, next) => {
35
- const response = await activityStreamsDocument(c, federation);
111
+ const response = (await activityStreamsActor(c, federation)) ?? (await activityStreamsDocument(c, federation));
36
112
  if (response !== undefined)
37
113
  return response;
38
114
  await next();
@@ -40,30 +116,194 @@ export function mountFederation(app, federation) {
40
116
  app.use('*', activityStreams);
41
117
  }
42
118
  /**
43
- * The `Article` for the post at this URL, when the request asked for
44
- * ActivityStreams and the URL is a published post's permalink.
119
+ * The middleware that answers the WordPress ActivityPub plugin's paths, when
120
+ * the site is carrying them.
121
+ *
122
+ * The setting is read per request rather than at boot, which is the whole of
123
+ * AC #4: turning the switch off in the settings screen takes the paths away on
124
+ * the very next request, and turning it on puts them back, with nothing
125
+ * restarted. A request for one of those paths with the switch off falls
126
+ * through to the public site, which answers it as the 404 it is.
127
+ *
128
+ * The instant is recorded before Fedify is asked, because the record is of
129
+ * what the site was *asked for*: a peer still holding the old inbox URL is
130
+ * news whether or not the number in it still names anybody.
131
+ */
132
+ function wordPressGate(build) {
133
+ let federation;
134
+ let middleware;
135
+ return async (c, next) => {
136
+ const target = wordPressRequestTarget(requestPath(c));
137
+ if (target === undefined)
138
+ return await next();
139
+ if (!readSiteSettings(c.var.config.contentDir).wordpressActivityPub)
140
+ return await next();
141
+ const user = target.wordpressActorId === undefined
142
+ ? undefined
143
+ : userByWordPressActorId(c.var.config.dataDir, target.wordpressActorId);
144
+ await recordWordPressRequest({
145
+ dataDir: c.var.config.dataDir,
146
+ target,
147
+ username: user?.username,
148
+ at: c.var.config.now(),
149
+ });
150
+ if (middleware === undefined) {
151
+ federation = build();
152
+ middleware = federationMiddleware(federation, (context) => contextData(context));
153
+ }
154
+ return await middleware(c, next);
155
+ };
156
+ }
157
+ /**
158
+ * The person this request is about, when it asks at the id they were published
159
+ * under somewhere else: the `Person` for a peer, a redirect to the author
160
+ * archive for a browser, and `undefined` for everything else.
161
+ *
162
+ * The twin of {@link activityStreamsDocument}, and for the same reason
163
+ * (decision-14): a stored actor id is identity. A follower's server keys the
164
+ * account by the URL it first saw, so that URL has to keep answering with this
165
+ * person's actor for as long as the account exists, or every follow out there
166
+ * points at nothing.
167
+ *
168
+ * Fedify cannot serve it — its router matches paths, and a stored id is
169
+ * commonly a query string on the site root (doc-8) — so it is served here,
170
+ * ahead of the public site, exactly as a post's stored `activitypub.id` is.
171
+ */
172
+ async function activityStreamsActor(c, federation) {
173
+ const user = storedActorAt(c);
174
+ if (user === undefined)
175
+ return undefined;
176
+ if (!prefersActivityStreams(c.req.header('accept'))) {
177
+ return c.redirect(authorHref(user.username), 301);
178
+ }
179
+ const context = federation.createContext(c.req.raw, contextData(c));
180
+ const actor = await userActor(context, user, { baseUrl: c.var.config.baseUrl });
181
+ return await respondWithObject(actor, { contextLoader: context.contextLoader });
182
+ }
183
+ /**
184
+ * The user whose stored actor id is the URL this request asks for, or
185
+ * `undefined`.
186
+ *
187
+ * Built the way {@link storedObjectAt} builds a post's candidate — the
188
+ * request's path and query on the site's base URL, rather than `request.url`,
189
+ * which behind a proxy is the internal address — and matched on the whole URL,
190
+ * query string and all, which is what decision-14 asks for.
191
+ *
192
+ * A user whose stored id happens to be their author URL is not one of these:
193
+ * the actor dispatcher has already answered for that URL, and answering again
194
+ * here would only redirect a browser to where it already is.
195
+ */
196
+ function storedActorAt(c) {
197
+ const { search } = new URL(c.req.url);
198
+ const candidate = `${absoluteUrl(requestPath(c), c.var.config.baseUrl)}${search}`;
199
+ const user = listUsers(c.var.config.dataDir).find((entry) => entry.actorId === candidate);
200
+ if (user === undefined)
201
+ return undefined;
202
+ if (absoluteUrl(authorHref(user.username), c.var.config.baseUrl) === candidate)
203
+ return undefined;
204
+ return user;
205
+ }
206
+ /**
207
+ * The post this request is about, when it is about one: the `Article` for a
208
+ * peer, a redirect to the permalink for a browser at a stored id, and
209
+ * `undefined` for everything else.
45
210
  *
46
- * doc-4 wants a peer that dereferences a link somebody shared — which is the
47
- * permalink, not the object id — to land on the object rather than on a page
48
- * it cannot read. The article is built through the same
49
- * {@link postArticle} the object dispatcher uses, off a context Fedify makes
50
- * for this request, so the two answers cannot drift apart; its `id` is the
51
- * object URL either way, so a peer stores one object however it arrived.
211
+ * Two URLs can name a post. Its permalink always does — that is the whole of
212
+ * decision-13, and a peer that dereferences a link somebody shared lands on
213
+ * the object rather than on a page it cannot read. The other is the
214
+ * `activitypub.id` a migrated post's file carries: the name its followers,
215
+ * its replies and its RSS subscribers already hold, which has to keep
216
+ * answering or every copy out there points at nothing. A browser that follows
217
+ * one of those old links is sent on to the permalink, because that is the URL
218
+ * a person should end up at.
52
219
  *
53
- * Anything else — a browser, a `.md` or `.json` request, a page, a listing —
54
- * gets `undefined` and falls through to the public site untouched.
220
+ * Anything else — a browser at a permalink, a `.md` or `.json` request, a
221
+ * page, a listing — gets `undefined` and falls through to the public site
222
+ * untouched.
55
223
  */
56
224
  async function activityStreamsDocument(c, federation) {
57
- if (!prefersActivityStreams(c.req.header('accept')))
225
+ const wantsObject = prefersActivityStreams(c.req.header('accept'));
226
+ if (wantsObject) {
227
+ const atPermalink = publicDocumentAt(c.var.store, requestPath(c));
228
+ if (atPermalink !== undefined && isFederatedDocument(atPermalink, c.var.store.now())) {
229
+ return await article(c, federation, atPermalink);
230
+ }
231
+ }
232
+ const stored = storedObjectAt(c);
233
+ if (stored === undefined)
234
+ return undefined;
235
+ if (!wantsObject)
236
+ return c.redirect(stored.permalink, 301);
237
+ return await article(c, federation, stored);
238
+ }
239
+ /**
240
+ * The post whose `activitypub.id` is the URL this request asks for, or
241
+ * `undefined`.
242
+ *
243
+ * The candidate is built the way the ids themselves are — the request's path
244
+ * and query on the site's base URL — rather than taken from `request.url`,
245
+ * which behind a proxy is the internal address. A post whose stored id is its
246
+ * permalink is not one of these: the permalink lookup has already answered for
247
+ * it, and answering again here would only invite a redirect to itself.
248
+ */
249
+ function storedObjectAt(c) {
250
+ const { search } = new URL(c.req.url);
251
+ const candidate = `${absoluteUrl(requestPath(c), c.var.config.baseUrl)}${search}`;
252
+ const document = c.var.store.getByStoredObjectId(candidate);
253
+ if (document === undefined || document.type !== 'post')
58
254
  return undefined;
59
- const document = publicDocumentAt(c.var.store, requestPath(c));
60
- if (document === undefined || !isFederatedDocument(document))
255
+ if (absoluteUrl(document.permalink, c.var.config.baseUrl) === candidate)
61
256
  return undefined;
257
+ return document;
258
+ }
259
+ /**
260
+ * One post as the ActivityStreams response a peer asked for.
261
+ *
262
+ * The article is built through the same {@link postArticle} the outbox uses,
263
+ * off a context Fedify makes for this request, so the object a peer fetches
264
+ * and the one it is delivered cannot drift apart.
265
+ */
266
+ async function article(c, federation, document) {
62
267
  const context = federation.createContext(c.req.raw, contextData(c));
63
268
  return await respondWithObject(postArticle(context, document), {
64
269
  contextLoader: context.contextLoader,
65
270
  });
66
271
  }
272
+ /** Where WebFinger lives, which is defined on the host rather than under a site. */
273
+ export const WEBFINGER_PATH = '/.well-known/webfinger';
274
+ /** `acct:{username}@{host}`, the handle a person types into a search box. */
275
+ export function acctOf(username, baseUrl) {
276
+ return `acct:${username}@${federationOrigin(baseUrl === '' ? 'http://localhost' : baseUrl).handleHost}`;
277
+ }
278
+ /**
279
+ * The user a WebFinger `resource` asks about, or `undefined` for one this site
280
+ * answers for nobody.
281
+ *
282
+ * Every spelling of a person resolves, and they are the ones decision-14 lists
283
+ * as their aliases: the `acct:` handle, the author archive, `/@{username}` and
284
+ * — for somebody who was published elsewhere first — the id they were
285
+ * published under. Matching every one of them is what lets a peer that holds
286
+ * any one URL for this person find the others, which is the whole job of
287
+ * WebFinger, and it is how a server holding only `?author=2` discovers that
288
+ * the account it follows is still here.
289
+ */
290
+ export function webFingerSubject(c, resource) {
291
+ const wanted = resource.trim();
292
+ if (wanted === '')
293
+ return undefined;
294
+ const { baseUrl } = c.var.config;
295
+ return listUsers(c.var.config.dataDir).find((user) => {
296
+ if (wanted === acctOf(user.username, baseUrl))
297
+ return true;
298
+ // A bare `user@host` is not what RFC 7033 asks for, but it is what enough
299
+ // clients send that refusing it would only look like a missing account.
300
+ if (wanted === acctOf(user.username, baseUrl).slice('acct:'.length))
301
+ return true;
302
+ return (wanted === absoluteUrl(authorHref(user.username), baseUrl) ||
303
+ wanted === absoluteUrl(handleHref(user.username), baseUrl) ||
304
+ wanted === user.actorId);
305
+ });
306
+ }
67
307
  /** What the dispatchers are handed, off the Hono context. */
68
308
  function contextData(c) {
69
309
  return { admin: c.var.admin, store: c.var.store, config: c.var.config };
@@ -1 +1 @@
1
- {"version":3,"file":"mount.js","sourceRoot":"","sources":["../../src/federation/mount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAIlE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,eAAe,CAAC,GAAqB,EAAE,UAA0B;IAC/E,4EAA4E;IAC5E,uEAAuE;IACvE,GAAG,CAAC,GAAG,CACL,GAAG,EACH,oBAAoB,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE;QAC3C,MAAM,CAAC,GAAG,OAAyC,CAAC;QACpD,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC,CAAC,CACH,CAAC;IAEF,yEAAyE;IACzE,iDAAiD;IACjD,MAAM,eAAe,GAAkC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvE,MAAM,QAAQ,GAAG,MAAM,uBAAuB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAC9D,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;QAC5C,MAAM,IAAI,EAAE,CAAC;IACf,CAAC,CAAC;IAEF,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,KAAK,UAAU,uBAAuB,CACpC,CAAsB,EACtB,UAA0B;IAE1B,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAEtE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IAE/E,MAAM,OAAO,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,MAAM,iBAAiB,CAAC,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE;QAC7D,aAAa,EAAE,OAAO,CAAC,aAAa;KACrC,CAAC,CAAC;AACL,CAAC;AAED,6DAA6D;AAC7D,SAAS,WAAW,CAAC,CAAsB;IACzC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;AAC1E,CAAC"}
1
+ {"version":3,"file":"mount.js","sourceRoot":"","sources":["../../src/federation/mount.ts"],"names":[],"mappings":"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"}
@@ -1,48 +1,36 @@
1
1
  import type { FederationOrigin } from '@fedify/fedify';
2
2
  /**
3
- * Where the ActivityPub endpoints live, under one prefix so they never
4
- * collide with a permalink. doc-4 puts post objects at `/ap/posts/{slug}`;
5
- * the actor is its sibling.
6
- */
7
- export declare const FEDERATION_PREFIX = "/ap";
8
- /**
9
- * The actor's path template.
3
+ * Where a user's ActivityPub endpoints live: at their author URL, and under it.
4
+ *
5
+ * decision-14 makes every user an actor whose id is their author archive,
6
+ * `{baseUrl}/author/{username}/`, so there is no prefix of its own any more —
7
+ * the actor is a page in a browser and an actor to a peer, exactly as a post
8
+ * is its permalink to both (decision-13). The collections are the archive's
9
+ * children, with the trailing slashes every URL on this site has, and Fedify
10
+ * builds each id from these templates so nothing has to guess the form.
10
11
  *
11
- * The identifier is a template variable because Fedify requires one, but only
12
- * the site actor's sentinel identifier ever answers: a site is one actor.
13
- * Because that identifier is a constant rather than the handle, the actor's id
14
- * is `{baseUrl}/ap/actor` however often the handle is renamed.
12
+ * A GET of `/author/ada` without the slash is a Fedify 404 that falls through
13
+ * to the public site's own canonical redirect, which is where a browser that
14
+ * followed an actor id without its slash lands (doc-8).
15
15
  */
16
- export declare const ACTOR_PATH: "/ap/{identifier}";
16
+ export declare const ACTOR_PATH: "/author/{identifier}/";
17
17
  /** The actor's inbox, its outbox and its two follow collections. */
18
- export declare const INBOX_PATH: "/ap/{identifier}/inbox";
19
- export declare const OUTBOX_PATH: "/ap/{identifier}/outbox";
20
- export declare const FOLLOWERS_PATH: "/ap/{identifier}/followers";
21
- export declare const FOLLOWING_PATH: "/ap/{identifier}/following";
22
- /** The instance-wide inbox, which a peer may use to deliver to every actor at once. */
23
- export declare const SHARED_INBOX_PATH: "/ap/shared-inbox";
18
+ export declare const INBOX_PATH: "/author/{identifier}/inbox/";
19
+ export declare const OUTBOX_PATH: "/author/{identifier}/outbox/";
20
+ export declare const FOLLOWERS_PATH: "/author/{identifier}/followers/";
21
+ export declare const FOLLOWING_PATH: "/author/{identifier}/following/";
24
22
  /**
25
- * A post's object path template.
23
+ * The instance-wide inbox, which a peer may use to deliver to every actor at
24
+ * once.
26
25
  *
27
- * The slug, not the permalink, is what names the object, exactly as doc-4
28
- * asks: a post moved from `/2026/09/hello/` to `/notes/hello/` keeps its
29
- * ActivityStreams id, so the followers who already have the object are not
30
- * handed a second one.
26
+ * A reserved top-level path (decision-14), which is why `inbox` is one of the
27
+ * two names `web/authors.ts` keeps a user from taking.
31
28
  */
32
- export declare const POST_OBJECT_PATH: "/ap/posts/{slug}";
29
+ export declare const SHARED_INBOX_PATH: "/inbox/";
30
+ /** Where a user's mention-style short URL lives: `/@ada`, WordPress's alias. */
31
+ export declare function handleHref(username: string): string;
33
32
  /** Where the NodeInfo 2.1 document lives; `/.well-known/nodeinfo` points at it. */
34
33
  export declare const NODEINFO_PATH = "/nodeinfo/2.1";
35
- /** The path a post's ActivityStreams object is served at. */
36
- export declare function postObjectPath(slug: string): string;
37
- /**
38
- * A post's ActivityStreams id, as an absolute URL.
39
- *
40
- * It is built on the {@link federationOrigin} rather than on the whole base
41
- * URL, because that is where Fedify serves the object from: a site in a
42
- * subdirectory keeps its pages under that directory, but its federation
43
- * endpoints — this one included — are host-rooted.
44
- */
45
- export declare function postObjectId(slug: string, baseUrl: string): string;
46
34
  /**
47
35
  * The id of the `Create` that announced an object.
48
36
  *
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/federation/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAEvC;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,oBAA+C,CAAC;AAEvE,oEAAoE;AACpE,eAAO,MAAM,UAAU,0BAAiC,CAAC;AACzD,eAAO,MAAM,WAAW,2BAAkC,CAAC;AAC3D,eAAO,MAAM,cAAc,8BAAqC,CAAC;AACjE,eAAO,MAAM,cAAc,8BAAqC,CAAC;AACjE,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,oBAA+C,CAAC;AAE9E;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,oBAA+C,CAAC;AAE7E,mFAAmF;AACnF,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,GAAG,GAAG,CAE5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAE9E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAE9E;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAGlE"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/federation/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIvD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU,yBAA2C,CAAC;AAEnE,oEAAoE;AACpE,eAAO,MAAM,UAAU,+BAAiC,CAAC;AACzD,eAAO,MAAM,WAAW,gCAAkC,CAAC;AAC3D,eAAO,MAAM,cAAc,mCAAqC,CAAC;AACjE,eAAO,MAAM,cAAc,mCAAqC,CAAC;AAEjE;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,WAA6B,CAAC;AAE5D,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,mFAAmF;AACnF,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,GAAG,GAAG,CAE5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAE9E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAE9E;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAGlE"}
@@ -1,51 +1,38 @@
1
+ import { AUTHOR_BASE, INBOX_BASE } from '../web/authors.js';
1
2
  /**
2
- * Where the ActivityPub endpoints live, under one prefix so they never
3
- * collide with a permalink. doc-4 puts post objects at `/ap/posts/{slug}`;
4
- * the actor is its sibling.
5
- */
6
- export const FEDERATION_PREFIX = '/ap';
7
- /**
8
- * The actor's path template.
3
+ * Where a user's ActivityPub endpoints live: at their author URL, and under it.
4
+ *
5
+ * decision-14 makes every user an actor whose id is their author archive,
6
+ * `{baseUrl}/author/{username}/`, so there is no prefix of its own any more —
7
+ * the actor is a page in a browser and an actor to a peer, exactly as a post
8
+ * is its permalink to both (decision-13). The collections are the archive's
9
+ * children, with the trailing slashes every URL on this site has, and Fedify
10
+ * builds each id from these templates so nothing has to guess the form.
9
11
  *
10
- * The identifier is a template variable because Fedify requires one, but only
11
- * the site actor's sentinel identifier ever answers: a site is one actor.
12
- * Because that identifier is a constant rather than the handle, the actor's id
13
- * is `{baseUrl}/ap/actor` however often the handle is renamed.
12
+ * A GET of `/author/ada` without the slash is a Fedify 404 that falls through
13
+ * to the public site's own canonical redirect, which is where a browser that
14
+ * followed an actor id without its slash lands (doc-8).
14
15
  */
15
- export const ACTOR_PATH = `${FEDERATION_PREFIX}/{identifier}`;
16
+ export const ACTOR_PATH = `/${AUTHOR_BASE}/{identifier}/`;
16
17
  /** The actor's inbox, its outbox and its two follow collections. */
17
- export const INBOX_PATH = `${ACTOR_PATH}/inbox`;
18
- export const OUTBOX_PATH = `${ACTOR_PATH}/outbox`;
19
- export const FOLLOWERS_PATH = `${ACTOR_PATH}/followers`;
20
- export const FOLLOWING_PATH = `${ACTOR_PATH}/following`;
21
- /** The instance-wide inbox, which a peer may use to deliver to every actor at once. */
22
- export const SHARED_INBOX_PATH = `${FEDERATION_PREFIX}/shared-inbox`;
18
+ export const INBOX_PATH = `${ACTOR_PATH}inbox/`;
19
+ export const OUTBOX_PATH = `${ACTOR_PATH}outbox/`;
20
+ export const FOLLOWERS_PATH = `${ACTOR_PATH}followers/`;
21
+ export const FOLLOWING_PATH = `${ACTOR_PATH}following/`;
23
22
  /**
24
- * A post's object path template.
23
+ * The instance-wide inbox, which a peer may use to deliver to every actor at
24
+ * once.
25
25
  *
26
- * The slug, not the permalink, is what names the object, exactly as doc-4
27
- * asks: a post moved from `/2026/09/hello/` to `/notes/hello/` keeps its
28
- * ActivityStreams id, so the followers who already have the object are not
29
- * handed a second one.
26
+ * A reserved top-level path (decision-14), which is why `inbox` is one of the
27
+ * two names `web/authors.ts` keeps a user from taking.
30
28
  */
31
- export const POST_OBJECT_PATH = `${FEDERATION_PREFIX}/posts/{slug}`;
29
+ export const SHARED_INBOX_PATH = `/${INBOX_BASE}/`;
30
+ /** Where a user's mention-style short URL lives: `/@ada`, WordPress's alias. */
31
+ export function handleHref(username) {
32
+ return `/@${encodeURIComponent(username)}`;
33
+ }
32
34
  /** Where the NodeInfo 2.1 document lives; `/.well-known/nodeinfo` points at it. */
33
35
  export const NODEINFO_PATH = '/nodeinfo/2.1';
34
- /** The path a post's ActivityStreams object is served at. */
35
- export function postObjectPath(slug) {
36
- return `${FEDERATION_PREFIX}/posts/${encodeURIComponent(slug)}`;
37
- }
38
- /**
39
- * A post's ActivityStreams id, as an absolute URL.
40
- *
41
- * It is built on the {@link federationOrigin} rather than on the whole base
42
- * URL, because that is where Fedify serves the object from: a site in a
43
- * subdirectory keeps its pages under that directory, but its federation
44
- * endpoints — this one included — are host-rooted.
45
- */
46
- export function postObjectId(slug, baseUrl) {
47
- return new URL(postObjectPath(slug), federationOrigin(baseUrl).webOrigin).href;
48
- }
49
36
  /**
50
37
  * The id of the `Create` that announced an object.
51
38
  *
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/federation/paths.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAEvC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,iBAAiB,eAAwB,CAAC;AAEvE,oEAAoE;AACpE,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,UAAU,QAAiB,CAAC;AACzD,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,UAAU,SAAkB,CAAC;AAC3D,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,UAAU,YAAqB,CAAC;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,UAAU,YAAqB,CAAC;AACjE,uFAAuF;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,iBAAiB,eAAwB,CAAC;AAE9E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,iBAAiB,eAAwB,CAAC;AAE7E,mFAAmF;AACnF,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAE7C,6DAA6D;AAC7D,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,GAAG,iBAAiB,UAAU,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;AAClE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,OAAe;IACxD,OAAO,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;AACjF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAsB;IACrD,OAAO,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAsB,EAAE,QAAgB;IACvE,OAAO,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,WAAW,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAsB,EAAE,QAAgB;IACvE,OAAO,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,WAAW,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClF,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;AACzD,CAAC"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/federation/paths.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,WAAW,gBAAyB,CAAC;AAEnE,oEAAoE;AACpE,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,UAAU,QAAiB,CAAC;AACzD,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,UAAU,SAAkB,CAAC;AAC3D,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,UAAU,YAAqB,CAAC;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,UAAU,YAAqB,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,UAAU,GAAY,CAAC;AAE5D,gFAAgF;AAChF,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,KAAK,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;AAC7C,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAsB;IACrD,OAAO,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAsB,EAAE,QAAgB;IACvE,OAAO,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,WAAW,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAsB,EAAE,QAAgB;IACvE,OAAO,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,WAAW,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClF,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;AACzD,CAAC"}