ghost 6.61.0 → 6.63.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 (619) hide show
  1. package/components/ghost-storage-base-3.0.0.tgz +0 -0
  2. package/components/tryghost-adapter-base-cache-0.2.0.tgz +0 -0
  3. package/components/tryghost-adapter-base-jobs-0.0.0.tgz +0 -0
  4. package/components/tryghost-adapter-base-redirects-0.0.0.tgz +0 -0
  5. package/components/tryghost-adapter-base-route-settings-0.0.0.tgz +0 -0
  6. package/components/tryghost-adapter-base-scheduling-0.2.3.tgz +0 -0
  7. package/components/tryghost-adapter-base-sso-0.1.3.tgz +0 -0
  8. package/components/tryghost-admin-api-schema-0.0.0.tgz +0 -0
  9. package/components/tryghost-checkout-0.0.0.tgz +0 -0
  10. package/components/tryghost-i18n-0.0.0.tgz +0 -0
  11. package/components/tryghost-kg-card-factory-5.2.4.tgz +0 -0
  12. package/components/tryghost-kg-clean-basic-html-4.3.4.tgz +0 -0
  13. package/components/tryghost-kg-converters-1.2.5.tgz +0 -0
  14. package/components/tryghost-kg-default-cards-10.3.5.tgz +0 -0
  15. package/components/tryghost-kg-default-nodes-2.2.1.tgz +0 -0
  16. package/components/tryghost-kg-default-transforms-1.3.4.tgz +0 -0
  17. package/components/tryghost-kg-html-to-lexical-1.4.0.tgz +0 -0
  18. package/components/tryghost-kg-lexical-html-renderer-1.5.0.tgz +0 -0
  19. package/components/tryghost-kg-markdown-html-renderer-7.2.4.tgz +0 -0
  20. package/components/tryghost-kg-utils-1.1.4.tgz +0 -0
  21. package/components/tryghost-limit-service-0.0.0.tgz +0 -0
  22. package/components/tryghost-metafield-types-0.0.0.tgz +0 -0
  23. package/components/tryghost-nql-string-0.0.0.tgz +0 -0
  24. package/components/tryghost-parse-email-address-0.0.0.tgz +0 -0
  25. package/content/settings/README.md +1 -1
  26. package/content/themes/casper/.gitignore +28 -0
  27. package/content/themes/casper/assets/built/casper.js +1 -1
  28. package/content/themes/casper/assets/built/screen.css +1 -1
  29. package/content/themes/casper/assets/css/screen.css +2 -1
  30. package/content/themes/casper/assets/js/lightbox.js +63 -46
  31. package/content/themes/casper/package.json +6 -6
  32. package/content/themes/casper/page.hbs +1 -0
  33. package/content/themes/casper/post.hbs +1 -0
  34. package/content/themes/source/.gitignore +28 -0
  35. package/content/themes/source/assets/built/screen.css +1 -1
  36. package/content/themes/source/assets/built/source.js +1 -1
  37. package/content/themes/source/assets/css/screen.css +2 -1
  38. package/content/themes/source/assets/js/lightbox.js +62 -45
  39. package/content/themes/source/assets/js/main.js +2 -2
  40. package/content/themes/source/package.json +4 -4
  41. package/content/themes/source/partials/feature-image.hbs +1 -0
  42. package/content/themes/source/partials/post-card.hbs +1 -1
  43. package/core/boot.js +61 -27
  44. package/core/built/admin/assets/Combination-B0l4MKVh.js +41 -0
  45. package/core/built/admin/assets/InterVariable-DiVDrmQJ.woff2 +0 -0
  46. package/core/built/admin/assets/InterVariable-Italic-FCBEiFp6.woff2 +0 -0
  47. package/core/built/admin/assets/{about-Bve7IJS2.js → about-C1C3s5-g.js} +1 -1
  48. package/core/built/admin/assets/accordion-CxGsDKwa.js +1 -0
  49. package/core/built/admin/assets/account-migration-CbUhW6gk.js +1 -0
  50. package/core/built/admin/assets/activitypub/{account-migration-C-aej4x_.js → account-migration-KA6Jjf9L.js} +16 -16
  51. package/core/built/admin/assets/activitypub/activitypub.js +9 -9
  52. package/core/built/admin/assets/activitypub/{avatar-DLPL3Abs.js → avatar-DVJF5bxP.js} +2 -2
  53. package/core/built/admin/assets/activitypub/{avatar-flipboard-C9iDY-QV.js → avatar-flipboard-csQaNeYK.js} +2 -2
  54. package/core/built/admin/assets/activitypub/{bluesky-sharing-BXkA5mqV.js → bluesky-sharing-C7nTDMvw.js} +37 -37
  55. package/core/built/admin/assets/activitypub/{content-formatters-CHcyMFk4.js → content-formatters-CLcjaBwV.js} +4 -4
  56. package/core/built/admin/assets/activitypub/{copy-DIAOQoCZ.js → copy-DcOh8kXw.js} +2 -2
  57. package/core/built/admin/assets/activitypub/{domain-B3ihkPde.js → domain-fZ-X8i4-.js} +121 -121
  58. package/core/built/admin/assets/activitypub/{edit-profile-DsZM3rTX.js → edit-profile-BqMLQV88.js} +40 -40
  59. package/core/built/admin/assets/activitypub/{explore-BodNrZgR.js → explore-B4yPoP8E.js} +27 -27
  60. package/core/built/admin/assets/activitypub/{feed-PwH1iJ84.js → feed-BRC_mvAe.js} +51 -51
  61. package/core/built/admin/assets/activitypub/{field-D06-kmOJ.js → field-COacNgOt.js} +3 -3
  62. package/core/built/admin/assets/activitypub/{hash-Bm3WxYN4.js → hash-C7u-irQQ.js} +2 -2
  63. package/core/built/admin/assets/activitypub/inbox-BW-yvUoN.js +1284 -0
  64. package/core/built/admin/assets/activitypub/{inbox-d8oJRTf4.js → inbox-CbTTdDQ3.js} +2 -2
  65. package/core/built/admin/assets/activitypub/label-kPMmYI7l.js +16 -0
  66. package/core/built/admin/assets/activitypub/layout-BL4_jtuV.js +1 -0
  67. package/core/built/admin/assets/activitypub/{moderation-D1Yapsod.js → moderation-CuidJzc0.js} +91 -91
  68. package/core/built/admin/assets/activitypub/{note-C5zjqq5C.js → note-CAMRRSqD.js} +24 -24
  69. package/core/built/admin/assets/activitypub/{notifications-B9p8eCHD.js → notifications-BmNlXGgp.js} +51 -51
  70. package/core/built/admin/assets/activitypub/{onboarding-CNelD_uF.js → onboarding-Bqg7fh_L.js} +2 -2
  71. package/core/built/admin/assets/activitypub/{onboarding-mat5Hrl0.js → onboarding-Dmun9jr_.js} +2 -2
  72. package/core/built/admin/assets/activitypub/{preferences-BCqUdC3v.js → preferences--oH19wf9.js} +1519 -1519
  73. package/core/built/admin/assets/activitypub/{profile-BRCWoFem.js → profile-DH_tQx2D.js} +185 -185
  74. package/core/built/admin/assets/activitypub/{reply-DYK5vVqb.js → reply-Cap9PxSH.js} +2 -2
  75. package/core/built/admin/assets/activitypub/{routes-BSXT992i.js → routes-DdyY9uFF.js} +744 -735
  76. package/core/built/admin/assets/activitypub/{separator-BbQqTm-p.js → separator-CAxxu8VV.js} +3 -3
  77. package/core/built/admin/assets/activitypub/settings-B6EEcVkW.js +315 -0
  78. package/core/built/admin/assets/activitypub/{site-DHoMupSB.js → site-BYps63oh.js} +2 -2
  79. package/core/built/admin/assets/activitypub/{step-1-B-YfsVeO.js → step-1-CKjR2KAm.js} +6 -6
  80. package/core/built/admin/assets/activitypub/{step-2-DtPQzlTH.js → step-2-B6PKfOUQ.js} +6 -6
  81. package/core/built/admin/assets/activitypub/{step-3-D6BFMXL_.js → step-3-C-qBbcUo.js} +11 -11
  82. package/core/built/admin/assets/activitypub/{tabs-GpNecvfB.js → tabs-DLhZtVde.js} +306 -306
  83. package/core/built/admin/assets/activitypub/{topic-filter-BPDeQQys.js → topic-filter-DsUOuu0k.js} +3 -3
  84. package/core/built/admin/assets/activitypub/{use-activity-pub-queries-BoVOxXkV.js → use-activity-pub-queries-CX9snsLs.js} +3 -3
  85. package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-Bmk5h4lW.js → use-navigate-with-base-path-DsJTGDSS.js} +988 -959
  86. package/core/built/admin/assets/activitypub/{use-reply-chain-data-wVBX7swM.js → use-reply-chain-data-AJi9zkzm.js} +30 -30
  87. package/core/built/admin/assets/activitypub/{users-CoX6FT_K.js → users-inweyKL5.js} +192 -164
  88. package/core/built/admin/assets/activitypub/{x-DbQZOLiI.js → x-DR8AT3-4.js} +2 -2
  89. package/core/built/admin/assets/add-integration-modal-BT_onDJy.js +1 -0
  90. package/core/built/admin/assets/add-newsletter-modal-Cx1kQpiY.js +1 -0
  91. package/core/built/admin/assets/add-recommendation-modal-B5nvAhvr.js +1 -0
  92. package/core/built/admin/assets/analytics-DjoJWPI7.js +1 -0
  93. package/core/built/admin/assets/{announcement-bar-modal-DM3cYOpo.js → announcement-bar-modal-Dwd0EGFP.js} +1 -1
  94. package/core/built/admin/assets/{api-keys-3-0vJC3Y.js → api-keys-BGPzLHzA.js} +1 -1
  95. package/core/built/admin/assets/{api-keys-BLm2NDBh.js → api-keys-BoeacM-s.js} +1 -1
  96. package/core/built/admin/assets/{audience-9mwU5TW6.js → audience-ceV3XVHq.js} +1 -1
  97. package/core/built/admin/assets/automated-emails-BLesE41L.js +1 -0
  98. package/core/built/admin/assets/{automations-sAcJ1334.js → automations-BN4u3GR8.js} +1 -1
  99. package/core/built/admin/assets/automations-C-ZTUwW3.js +1 -0
  100. package/core/built/admin/assets/bluesky-sharing-vzh-oPXL.js +1 -0
  101. package/core/built/admin/assets/{breadcrumb-DLiqCyFc.js → breadcrumb-CaLk2b7D.js} +1 -1
  102. package/core/built/admin/assets/{button-B2jcu6bk.js → button-Dvcv1QSR.js} +1 -1
  103. package/core/built/admin/assets/calendar-Bl9RLcZX.js +1 -0
  104. package/core/built/admin/assets/{chart-helpers-Fo3bUL3K.js → chart-helpers-FHywU0pj.js} +1 -1
  105. package/core/built/admin/assets/{checkbox-BfKktMph.js → checkbox-BtayFtjg.js} +1 -1
  106. package/core/built/admin/assets/chunk.254.035b85ec456ebbd7336b.js +440 -0
  107. package/core/built/admin/assets/{chunk.524.60ca4692d91c6022042f.js → chunk.524.e6975095fccdf22d90f8.js} +5 -5
  108. package/core/built/admin/assets/{chunk.582.525c7617c2d9e94c940a.js → chunk.582.98b485f9b2802f540897.js} +6 -6
  109. package/core/built/admin/assets/{chunk.492.f24d855d7e3f3aad261c.js → chunk.901.4ccc639821020230bcca.js} +9949 -7921
  110. package/core/built/admin/assets/{code-editor-view-DCQJxsfU.js → code-editor-view-C3ZfoF1X.js} +1 -1
  111. package/core/built/admin/assets/{code-editor-view-CYVu4EW6.js → code-editor-view-CAyRWy1s.js} +1 -1
  112. package/core/built/admin/assets/color-picker-G4kGR7rp.js +3 -0
  113. package/core/built/admin/assets/color-picker-field-DQFVTNnT.js +1 -0
  114. package/core/built/admin/assets/combobox-BnYzgEB4.js +1 -0
  115. package/core/built/admin/assets/command-C_vyTikI.js +1 -0
  116. package/core/built/admin/assets/comments-aBrxfnZf.js +1 -0
  117. package/core/built/admin/assets/{config-DOMQDZGZ.js → config-kSHvwdTG.js} +1 -1
  118. package/core/built/admin/assets/confirmation-context-DwXX_Y5h.js +1 -0
  119. package/core/built/admin/assets/{content-api-modal-CyQEC3fr.js → content-api-modal-D2G0nJP6.js} +1 -1
  120. package/core/built/admin/assets/context-menu-DOVB6yaz.js +1 -0
  121. package/core/built/admin/assets/{copy-field-B3M1s78L.js → copy-field-DCJwh9qf.js} +1 -1
  122. package/core/built/admin/assets/create-ghost-browse-value-source-5C53jJaX.js +1 -0
  123. package/core/built/admin/assets/custom-field-type-option-BAuW0F-E.js +1 -0
  124. package/core/built/admin/assets/custom-integration-modal-AbJGVyKc.js +1 -0
  125. package/core/built/admin/assets/{date-range-select-DD2RKkgB.js → date-range-select-BY3K-ukj.js} +1 -1
  126. package/core/built/admin/assets/design-and-theme-modal-BvEy4_pC.js +2 -0
  127. package/core/built/admin/assets/dirty-confirm-dialog-DVPuGz3U.js +1 -0
  128. package/core/built/admin/assets/{disabled-sources-indicator-Cvy47bE2.js → disabled-sources-indicator-Cy7Zp4c8.js} +1 -1
  129. package/core/built/admin/assets/dist-Dcsslyo72.js +1 -0
  130. package/core/built/admin/assets/domain-Dl61QGuk.js +1 -0
  131. package/core/built/admin/assets/dropzone-Dtz5Rmjt.js +5 -0
  132. package/core/built/admin/assets/edit-profile-DNJSMDwm.js +1 -0
  133. package/core/built/admin/assets/editor-DbAen9zf.js +8 -0
  134. package/core/built/admin/assets/editor-screen-BFWThIai.js +26 -0
  135. package/core/built/admin/assets/email-sending-status-context-CWDOD1FN.js +1 -0
  136. package/core/built/admin/assets/email-sending-status-provider-DCPkDICt.js +1 -0
  137. package/core/built/admin/assets/emails-vFMk4yYl.js +1 -0
  138. package/core/built/admin/assets/{embed-signup-form-modal-DeBMLxlL.js → embed-signup-form-modal-DGqsORxS.js} +1 -1
  139. package/core/built/admin/assets/en-B1jX3WMs.js +1 -0
  140. package/core/built/admin/assets/explore-nnRr1Fja.js +1 -0
  141. package/core/built/admin/assets/feature-flag-overrides-context-DQjdJFAk.js +1 -0
  142. package/core/built/admin/assets/feature-image-placeholder-BrIHmPs8.js +1 -0
  143. package/core/built/admin/assets/feed-BNUcNu-W.js +1 -0
  144. package/core/built/admin/assets/feedback-DJ4Zb9rZ.js +1 -0
  145. package/core/built/admin/assets/{field-Cj8lmDOo.js → field-C93_Mg6j.js} +1 -1
  146. package/core/built/admin/assets/filter-bar-Da1qxybu.js +1 -0
  147. package/core/built/admin/assets/filter-sources-CGJb4C5r.js +1 -0
  148. package/core/built/admin/assets/filters--kKP-EC8.js +1 -0
  149. package/core/built/admin/assets/filters-DxA_a4FP.js +1 -0
  150. package/core/built/admin/assets/first-promoter-modal-BYDtrz2S.js +1 -0
  151. package/core/built/admin/assets/focus-koenig-editor-on-bottom-click-BbSnGOtK.js +1 -0
  152. package/core/built/admin/assets/{ghost-c8807202a07c20030acb719ee0114815.css → ghost-8fd5bb799356bbefb254210ba7e1236d.css} +1 -1
  153. package/core/built/admin/assets/{ghost-3894eedcc6968f658578c0abfe942aab.js → ghost-b4e8a403baba61905cd7560e30b9732d.js} +63 -44
  154. package/core/built/admin/assets/{ghost-dark-fbf1e384aaef3ae315e540f0eb7373a7.css → ghost-dark-cac0cb2d5bb78e9bd14d8d1c2768ed45.css} +1 -1
  155. package/core/built/admin/assets/gift-link-modal-B7u5bD4e.js +1 -0
  156. package/core/built/admin/assets/{gift-links-DLDS7ljO.js → gift-links-CfLSnst2.js} +1 -1
  157. package/core/built/admin/assets/{growth-D6mhcx3q.js → growth-Cd1uO9d2.js} +1 -1
  158. package/core/built/admin/assets/growth-aG32xfdE.js +3 -0
  159. package/core/built/admin/assets/history-modal-Df8lW8h-.js +1 -0
  160. package/core/built/admin/assets/hooks-Cy_-oZ4o.js +2 -0
  161. package/core/built/admin/assets/{html-field-C8qVGGC1.js → html-field-DA4eU7eq.js} +1 -1
  162. package/core/built/admin/assets/{images-h8VZEQ9k.js → images-KXmyO3Ss.js} +1 -1
  163. package/core/built/admin/assets/{inbox-BYd1M06Q.js → inbox-gJHG7_xd.js} +14 -14
  164. package/core/built/admin/assets/index-BHHXtR5C.css +2 -0
  165. package/core/built/admin/assets/index-CgMCwsxN.js +4 -0
  166. package/core/built/admin/assets/index.es-CY6-yuw9.js +1 -0
  167. package/core/built/admin/assets/{input-group-D8sCXRF5.js → input-group-BE8rM2y1.js} +1 -1
  168. package/core/built/admin/assets/{integrations-Bjbu86Z0.js → integrations-B4kuRBFY.js} +1 -1
  169. package/core/built/admin/assets/invite-user-modal-B4CuNcx4.js +1 -0
  170. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +14 -14
  171. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +3 -3
  172. package/core/built/admin/assets/koenig-lexical/style.css +1 -1
  173. package/core/built/admin/assets/{koenig-lexical-_-IsVI7E.js → koenig-lexical-CGXb0F8o.js} +3 -3
  174. package/core/built/admin/assets/koenig-loader-BeM5rFPX.js +2 -0
  175. package/core/built/admin/assets/{kpi-card-DZQk_0W8.js → kpi-card-B21aToe8.js} +1 -1
  176. package/core/built/admin/assets/{kpi-card-DW_2y3ug.js → kpi-card-pz6Wv4Ae.js} +1 -1
  177. package/core/built/admin/assets/{kpi-helpers-PueTKuA6.js → kpi-helpers-Dq5jelmP.js} +1 -1
  178. package/core/built/admin/assets/{kpi-tabs-CojDs-Qz.js → kpi-tabs-DEZHpKUt.js} +1 -1
  179. package/core/built/admin/assets/{label-DjbT91GM.js → label-OLCzze8N.js} +1 -1
  180. package/core/built/admin/assets/label-picker-BigOvMPV.js +1 -0
  181. package/core/built/admin/assets/{labels-CH3Kn8RV.js → labels-Dr0SgUQD.js} +1 -1
  182. package/core/built/admin/assets/layout-DUTL8SH5.js +1 -0
  183. package/core/built/admin/assets/lib-7QPTI0FS.js +1 -0
  184. package/core/built/admin/assets/link-helpers-BRAg9SCj.js +1 -0
  185. package/core/built/admin/assets/links-BDHPTlyj.js +1 -0
  186. package/core/built/admin/assets/member-custom-fields-TRTHCAz9.js +1 -0
  187. package/core/built/admin/assets/member-detail-b6dRwc3C.js +1 -0
  188. package/core/built/admin/assets/members-Czt5lJSc.js +4 -0
  189. package/core/built/admin/assets/moderation-ZWefD9uH.js +1 -0
  190. package/core/built/admin/assets/{multi-select-combobox-B6LiRzDO.js → multi-select-combobox-CT13MTo-.js} +1 -1
  191. package/core/built/admin/assets/navigation-modal-C8FEhBK5.js +1 -0
  192. package/core/built/admin/assets/newsletter-5VYW4RyJ.js +1 -0
  193. package/core/built/admin/assets/newsletter-detail-modal-ChjC0ZqH.js +1 -0
  194. package/core/built/admin/assets/{newsletter-emails-CFeLlt4z.js → newsletter-emails-DZH6I-PY.js} +1 -1
  195. package/core/built/admin/assets/newsletters-DOC9KBcX.js +1 -0
  196. package/core/built/admin/assets/newsletters-Rq1M3GD-.js +1 -0
  197. package/core/built/admin/assets/note-DIV-Pojr.js +1 -0
  198. package/core/built/admin/assets/notifications-s20-H49V.js +1 -0
  199. package/core/built/admin/assets/nql-BLpCn7qX.js +21 -0
  200. package/core/built/admin/assets/{offers-9J1CSiLy.js → offers--e2nGvkW.js} +1 -1
  201. package/core/built/admin/assets/offers-container-modal-BmG5M5Tv.js +1 -0
  202. package/core/built/admin/assets/onboarding-CUuy9unR.js +1 -0
  203. package/core/built/admin/assets/{onboarding-B4YhlZ0i.js → onboarding-pXyct0Jm.js} +1 -1
  204. package/core/built/admin/assets/{onboarding-route-Dmc4IPm3.js → onboarding-route-CK4pcXoR.js} +1 -1
  205. package/core/built/admin/assets/overview-CaPsciMs.js +1 -0
  206. package/core/built/admin/assets/overview-a8GfcsKX.js +1 -0
  207. package/core/built/admin/assets/{page-header-BR_nbIPp.js → page-header-DM_KyoFI.js} +1 -1
  208. package/core/built/admin/assets/pagemenu-vgZVUVKR.js +1 -0
  209. package/core/built/admin/assets/pages-CjDY2CBI.js +1 -0
  210. package/core/built/admin/assets/pages-route-BzKZYdV5.js +1 -0
  211. package/core/built/admin/assets/papaparse.min-cQwnxGCG.js +10 -0
  212. package/core/built/admin/assets/{pintura-modal-BR9hEvS8.js → pintura-modal-DExCF1ii.js} +1 -1
  213. package/core/built/admin/assets/portal-frame-Cqanidq4.js +1 -0
  214. package/core/built/admin/assets/portal-modal-oinBgA27.js +1 -0
  215. package/core/built/admin/assets/post-analytics-C5oJ1dWV.js +1 -0
  216. package/core/built/admin/assets/post-analytics-header-OATo3X_r.js +1 -0
  217. package/core/built/admin/assets/post-analytics-provider-tOpIVGT5.js +1 -0
  218. package/core/built/admin/assets/post-helpers-C88JBa4D.js +1 -0
  219. package/core/built/admin/assets/post-share-modal-DvhC1XgV.js +1 -0
  220. package/core/built/admin/assets/post-utils-DKF4mfuo.js +1 -0
  221. package/core/built/admin/assets/posts-list-screen-o4ZjbgS3.js +2 -0
  222. package/core/built/admin/assets/posts-pCPrhQeR.js +1 -0
  223. package/core/built/admin/assets/posts-route-9F--xdIb.js +1 -0
  224. package/core/built/admin/assets/preferences--vNubsqD.js +5 -0
  225. package/core/built/admin/assets/{preview-modal-C-BL-F9k.js → preview-modal-YYbzlYdO.js} +1 -1
  226. package/core/built/admin/assets/profile-BllKV3dR.js +1 -0
  227. package/core/built/admin/assets/{radio-group-Bgz60i81.js → radio-group-DL8GI8rt.js} +1 -1
  228. package/core/built/admin/assets/{referrers-CnhCMWCs.js → referrers-D8oHPmDB.js} +1 -1
  229. package/core/built/admin/assets/router-provider-BSvTXgZY.js +1 -0
  230. package/core/built/admin/assets/schemas-BoYdB6YU.js +64 -0
  231. package/core/built/admin/assets/select-v5YbA3Mw.js +1 -0
  232. package/core/built/admin/assets/settings-PEsZupw1.js +4 -0
  233. package/core/built/admin/assets/{settings-breadcrumbs-CyP_9zTo.js → settings-breadcrumbs-NwPnCTC7.js} +1 -1
  234. package/core/built/admin/assets/settings-u_s1CRkr.js +1 -0
  235. package/core/built/admin/assets/share-modal-SskCmVGL.js +1 -0
  236. package/core/built/admin/assets/slack-modal-XxSJiYgo.js +1 -0
  237. package/core/built/admin/assets/{sort-button-Cc-Z96sA.js → sort-button-Cx1KtINE.js} +1 -1
  238. package/core/built/admin/assets/{source-icon-v6PUnmyM.js → source-icon-Bdp9Im_5.js} +1 -1
  239. package/core/built/admin/assets/stats-D9PDLS3x.js +1 -0
  240. package/core/built/admin/assets/stats-view-W2g6Jsd-.js +1 -0
  241. package/core/built/admin/assets/{step-1-DSRp2vBj.js → step-1-BQYzvBzr.js} +1 -1
  242. package/core/built/admin/assets/{step-2-COqv2g0u.js → step-2-xES32xJV.js} +1 -1
  243. package/core/built/admin/assets/{step-3-6W1NMVQc.js → step-3-DA_XK5kW.js} +2 -2
  244. package/core/built/admin/assets/{stripe-button-D2K42Uty.js → stripe-button-CVsLHelt.js} +1 -1
  245. package/core/built/admin/assets/stripe-connect-modal-ClmLOMGS.js +1 -0
  246. package/core/built/admin/assets/style-Wd9nQubI.css +1 -0
  247. package/core/built/admin/assets/{table-B2pIKjVh.js → table-BenqVupI.js} +1 -1
  248. package/core/built/admin/assets/{tabs-SaW_UT-Q.js → tabs-eBBlxPp8.js} +1 -1
  249. package/core/built/admin/assets/tag-detail-Ce8Se2qd.js +2 -0
  250. package/core/built/admin/assets/tag-picker-C3UR-uJ-.js +1 -0
  251. package/core/built/admin/assets/tags-B-kJxCs7.js +1 -0
  252. package/core/built/admin/assets/{tags-zTFiKRpb.js → tags-ChfdwJyS.js} +1 -1
  253. package/core/built/admin/assets/testimonials-modal-9Q6fT06V.js +1 -0
  254. package/core/built/admin/assets/tier-detail-modal-CDyYdqK7.js +1 -0
  255. package/core/built/admin/assets/tiers-BCpIOGQr.js +1 -0
  256. package/core/built/admin/assets/{toggle-group-EM9WpESu.js → toggle-group-CviIkyok.js} +1 -1
  257. package/core/built/admin/assets/{topic-filter-DY4gNHn2.js → topic-filter-I2jCBGxm.js} +1 -1
  258. package/core/built/admin/assets/{transistor-modal-CpyPG-MH.js → transistor-modal-p53u3W8y.js} +1 -1
  259. package/core/built/admin/assets/{trend-badge-ByMkuAuH.js → trend-badge-CideVzQd.js} +1 -1
  260. package/core/built/admin/assets/{unsplash-modal-Cv2Q6GtY.js → unsplash-modal-DY8UcKcE.js} +1 -1
  261. package/core/built/admin/assets/{use-analytics-data-CHvjMYuT.js → use-analytics-data-DAIGcr2f.js} +1 -1
  262. package/core/built/admin/assets/use-check-theme-limit-error-B8bjF-gO.css +1 -0
  263. package/core/built/admin/assets/{use-check-theme-limit-error-Qv4SVXqw.js → use-check-theme-limit-error-DRUjK4YM.js} +1 -1
  264. package/core/built/admin/assets/use-filter-params-JkZhIS8L.js +1 -0
  265. package/core/built/admin/assets/{use-filterable-api-CzXcpUh8.js → use-filterable-api-BVEVMrhZ.js} +1 -1
  266. package/core/built/admin/assets/use-growth-stats-937CUj6j.js +1 -0
  267. package/core/built/admin/assets/use-host-limits-D0Dv3tKA.js +1 -0
  268. package/core/built/admin/assets/{use-limiter-cwJvsNBo.js → use-limiter-CohWfzvK.js} +1 -1
  269. package/core/built/admin/assets/{use-navigate-with-base-path-BHPA228f.js → use-navigate-with-base-path-BkxcPj5l.js} +1 -1
  270. package/core/built/admin/assets/use-pintura-config-xgytjU35.js +1 -0
  271. package/core/built/admin/assets/{use-pintura-editor-BDBXWUYq.js → use-pintura-editor-CaV1mbfO.js} +1 -1
  272. package/core/built/admin/assets/{use-post-referrers-DbY-mzci.js → use-post-referrers-BCQI7fDg.js} +1 -1
  273. package/core/built/admin/assets/use-reply-chain-data-CYRhoaxY.js +1 -0
  274. package/core/built/admin/assets/{use-router-history-entry-Bg6BhBQQ.js → use-router-history-entry-NOKcd--l.js} +1 -1
  275. package/core/built/admin/assets/{use-setting-group-VM7FQwMY.js → use-setting-group-bLKMwoBT.js} +1 -1
  276. package/core/built/admin/assets/use-settings-navigation-B-qrriKD.js +1 -0
  277. package/core/built/admin/assets/{use-simple-pagination-Dum6Irbs.js → use-simple-pagination-CNPd6Rf6.js} +1 -1
  278. package/core/built/admin/assets/use-staff-users-pRIMIyiW.js +1 -0
  279. package/core/built/admin/assets/use-tinybird-query-CmdbCS9X.js +1 -0
  280. package/core/built/admin/assets/use-tinybird-token-KLne235s.js +1 -0
  281. package/core/built/admin/assets/{use-unsaved-changes-guard-BAy0RANR.js → use-unsaved-changes-guard-7-ug0JdH.js} +1 -1
  282. package/core/built/admin/assets/use-upgrade-route-Dm_qqKr0.js +1 -0
  283. package/core/built/admin/assets/{use-url-input-Df5QzNa7.js → use-url-input-fvp-TpPx.js} +1 -1
  284. package/core/built/admin/assets/user-detail-modal-D3KlGYv-.js +1 -0
  285. package/core/built/admin/assets/users-DVNWrqg9.js +1 -0
  286. package/core/built/admin/assets/{vendor-5753232c7d6ffb3c44e1eb0a02133953.js → vendor-2dd263291938d407802568d3357ec69e.js} +19 -17
  287. package/core/built/admin/assets/{virtual-list-DEx8WgiO.js → virtual-list-CZ3RK2Yf.js} +1 -1
  288. package/core/built/admin/assets/web-ClEJsCAj.js +2 -0
  289. package/core/built/admin/assets/web-X9rdnrtq.js +1 -0
  290. package/core/built/admin/assets/{zapier-modal-Cw3BTBUu.js → zapier-modal-DfVhV17j.js} +1 -1
  291. package/core/built/admin/index.html +23 -27
  292. package/core/frontend/apps/private-blogging/lib/views/private.hbs +44 -43
  293. package/core/frontend/helpers/cancel_link.js +2 -2
  294. package/core/frontend/helpers/pagination.js +2 -2
  295. package/core/frontend/helpers/social_accounts.js +2 -2
  296. package/core/frontend/public/ghost.css +1 -1
  297. package/core/frontend/public/ghost.min.css +1 -1
  298. package/core/frontend/services/sitemap/user-map-generator.js +9 -2
  299. package/core/server/adapters/jobs/InMemoryJobsBackend.js +74 -29
  300. package/core/server/api/endpoints/authentication.js +1 -2
  301. package/core/server/api/endpoints/authors-public.js +15 -5
  302. package/core/server/api/endpoints/emails.js +13 -0
  303. package/core/server/api/endpoints/index.js +10 -2
  304. package/core/server/api/endpoints/mail.js +1 -1
  305. package/core/server/api/endpoints/member-metafields-members.js +23 -0
  306. package/core/server/api/endpoints/member-metafields.js +102 -0
  307. package/core/server/api/endpoints/members-account.js +42 -0
  308. package/core/server/api/endpoints/members.js +4 -4
  309. package/core/server/api/endpoints/newsletters-public.js +10 -1
  310. package/core/server/api/endpoints/pages-public.js +15 -5
  311. package/core/server/api/endpoints/posts-public.js +15 -5
  312. package/core/server/api/endpoints/posts.js +3 -3
  313. package/core/server/api/endpoints/tags-public.js +22 -3
  314. package/core/server/api/endpoints/tiers-checkout-config.js +2 -2
  315. package/core/server/api/endpoints/tiers-public.js +38 -1
  316. package/core/server/api/endpoints/users.js +2 -2
  317. package/core/server/api/endpoints/utils/api-filter-utils.js +170 -3
  318. package/core/server/api/endpoints/utils/public-cache-keys.js +3 -0
  319. package/core/server/api/endpoints/utils/serializers/input/authors.js +2 -0
  320. package/core/server/api/endpoints/utils/serializers/input/members.js +20 -9
  321. package/core/server/api/endpoints/utils/serializers/input/pages.js +2 -0
  322. package/core/server/api/endpoints/utils/serializers/input/posts.js +2 -0
  323. package/core/server/api/endpoints/utils/serializers/input/tags.js +2 -0
  324. package/core/server/api/endpoints/utils/serializers/output/emails.js +7 -0
  325. package/core/server/api/endpoints/utils/serializers/output/index.js +6 -2
  326. package/core/server/api/endpoints/utils/serializers/output/member-metafields.js +18 -0
  327. package/core/server/api/endpoints/utils/serializers/output/members-account.js +19 -0
  328. package/core/server/api/endpoints/utils/serializers/output/members-csv-transform.js +1 -1
  329. package/core/server/api/endpoints/utils/serializers/output/members.js +2 -4
  330. package/core/server/api/endpoints/utils/serializers/output/tiers.js +10 -2
  331. package/core/server/api/endpoints/utils/serializers/output/users.js +0 -10
  332. package/core/server/api/endpoints/utils/validators/input/invitations.js +0 -5
  333. package/core/server/api/endpoints/utils/validators/input/pages.js +1 -1
  334. package/core/server/api/endpoints/utils/validators/input/posts.js +1 -1
  335. package/core/server/data/exporter/table-lists.js +3 -3
  336. package/core/server/data/importer/importers/data/data-importer.js +3 -3
  337. package/core/server/data/migrations/utils/migrations.js +1 -1
  338. package/core/server/data/migrations/versions/6.53/2026-07-15-20-22-53-add-members-custom-field-values.js +1 -1
  339. package/core/server/data/migrations/versions/6.57/2026-08-04-18-00-00-store-custom-field-values-as-leaf-rows.js +10 -1
  340. package/core/server/data/migrations/versions/6.63/2026-09-03-10-07-03-rename-custom-field-tables-to-metafields.js +169 -0
  341. package/core/server/data/migrations/versions/6.63/2026-09-03-11-03-31-remove-member-custom-field-read-permissions.js +30 -0
  342. package/core/server/data/schema/fixtures/fixtures.json +0 -11
  343. package/core/server/data/schema/lib/default-index-name.js +8 -11
  344. package/core/server/data/schema/schema.js +18 -18
  345. package/core/server/data/seeders/README.md +48 -0
  346. package/core/server/data/tinybird/pipes/mv_hits.pipe +86 -50
  347. package/core/server/lib/db-types/count.js +16 -0
  348. package/core/server/lib/image/image-size.js +24 -0
  349. package/core/server/lib/package-json/parse.js +2 -2
  350. package/core/server/lib/validate-password.js +81 -120
  351. package/core/server/models/action.js +4 -4
  352. package/core/server/models/base/plugins/filtered-collection.js +16 -0
  353. package/core/server/models/member.js +10 -21
  354. package/core/server/models/post.js +2 -2
  355. package/core/server/models/relations/authors.js +2 -16
  356. package/core/server/models/user.js +10 -3
  357. package/core/server/services/auth/passwordreset.js +13 -0
  358. package/core/server/services/automations/automations-api.js +1 -1
  359. package/core/server/services/automations/database-automations-repository.js +11 -4
  360. package/core/server/services/comments/comments-controller.js +30 -9
  361. package/core/server/services/comments/comments-service.js +55 -5
  362. package/core/server/services/content-import/csv/formula.js +12 -0
  363. package/core/server/services/content-import/csv/index.js +6 -1
  364. package/core/server/services/content-import/csv/parse.js +27 -6
  365. package/core/server/services/content-import/csv/serialize.js +13 -0
  366. package/core/server/services/content-import/import/completion-email.js +164 -0
  367. package/core/server/services/content-import/import/errors-file.js +36 -0
  368. package/core/server/services/content-import/import/importer.js +160 -53
  369. package/core/server/services/content-import/import/local-media-url.js +63 -0
  370. package/core/server/services/content-import/import/media.js +254 -0
  371. package/core/server/services/content-import/import/post-data.js +0 -1
  372. package/core/server/services/content-import/import/post-link.js +11 -0
  373. package/core/server/services/content-import/import/post-repository.js +25 -3
  374. package/core/server/services/content-import/import/reader.js +9 -2
  375. package/core/server/services/content-import/import/report.js +34 -0
  376. package/core/server/services/content-import/import/row.js +0 -2
  377. package/core/server/services/content-import/import/schema.js +1 -0
  378. package/core/server/services/content-import/import/staged-file.js +29 -0
  379. package/core/server/services/content-import/import/store.js +25 -2
  380. package/core/server/services/content-import/index.js +52 -6
  381. package/core/server/services/content-import/jobs/content-csv-import-job.js +20 -0
  382. package/core/server/services/custom-redirects/redirect-config-parser.js +2 -2
  383. package/core/server/services/custom-redirects/redirects-service.js +1 -1
  384. package/core/server/services/custom-redirects/validation.js +1 -1
  385. package/core/server/services/email-address/email-address-parser.js +30 -38
  386. package/core/server/services/email-address/email-address-service.js +37 -4
  387. package/core/server/services/email-analytics/index.js +2 -7
  388. package/core/server/services/email-service/CONTEXT.md +37 -0
  389. package/core/server/services/email-service/README.md +42 -0
  390. package/core/server/services/email-service/batch-sending-service.js +2 -4
  391. package/core/server/services/email-service/email-controller.js +18 -2
  392. package/core/server/services/email-service/email-renderer.js +14 -4
  393. package/core/server/services/email-service/email-service-wrapper.js +3 -9
  394. package/core/server/services/email-service/mailgun-email-provider.js +20 -9
  395. package/core/server/services/email-service/sending-status-schema.js +21 -0
  396. package/core/server/services/email-service/sending-status-serializers.js +33 -0
  397. package/core/server/services/email-service/sending-status-service.js +47 -0
  398. package/core/server/services/email-service/sending-status.js +111 -0
  399. package/core/server/services/email-suppression-list/email-suppression-list.js +0 -33
  400. package/core/server/services/email-suppression-list/mailgun-email-suppression-list.js +6 -7
  401. package/core/server/services/gifts/README.md +2 -2
  402. package/core/server/services/gifts/constants.js +1 -1
  403. package/core/server/services/gifts/email-templates/gift-delivery.hbs +3 -3
  404. package/core/server/services/gifts/gift-email-service.js +0 -1
  405. package/core/server/services/gifts/gift-service.js +19 -57
  406. package/core/server/services/gifts/index.js +3 -5
  407. package/core/server/services/gifts/jobs/index.js +4 -4
  408. package/core/server/services/indexnow-ping/indexnow-ping-service.js +2 -2
  409. package/core/server/services/invitations/accept.js +4 -2
  410. package/core/server/services/jobs/job-service.js +0 -9
  411. package/core/server/services/jobs-service/index.js +8 -0
  412. package/core/server/services/jobs-service/jobs-service.js +52 -3
  413. package/core/server/services/jobs-service/register-job-handlers.js +32 -11
  414. package/core/server/services/mail/ghost-mailer.js +4 -4
  415. package/core/server/services/member-welcome-emails/service.js +7 -7
  416. package/core/server/services/members/account-service.js +98 -0
  417. package/core/server/services/members/api.js +4 -3
  418. package/core/server/services/members/import-export/csv/parse.js +0 -7
  419. package/core/server/services/members/import-export/export/exporter.js +20 -20
  420. package/core/server/services/members/import-export/import/completion-email.js +8 -11
  421. package/core/server/services/members/import-export/import/importer.js +13 -13
  422. package/core/server/services/members/import-export/import/row.js +0 -3
  423. package/core/server/services/members/import-export/index.js +10 -17
  424. package/core/server/services/members/jobs/clean-expired-comped-job.js +7 -0
  425. package/core/server/services/members/jobs/clean-expired-comped-task.js +145 -0
  426. package/core/server/services/members/jobs/index.js +48 -24
  427. package/core/server/services/members/members-api/controllers/member-controller.js +11 -0
  428. package/core/server/services/members/members-api/controllers/router-controller.js +3 -6
  429. package/core/server/services/members/members-api/members-api.js +26 -8
  430. package/core/server/services/members/members-api/repositories/event-repository.js +0 -4
  431. package/core/server/services/members/members-api/repositories/member-repository.js +4 -4
  432. package/core/server/services/members/members-api/services/member-bread-service.js +62 -84
  433. package/core/server/services/members/members-api/services/payments-service.js +1 -1
  434. package/core/server/services/members/members-ssr.js +18 -0
  435. package/core/server/services/members/middleware.js +95 -81
  436. package/core/server/services/members/service.js +71 -47
  437. package/core/server/services/members/utils.js +9 -0
  438. package/core/server/services/members-metafields/access.js +28 -0
  439. package/core/server/services/{members-custom-fields → members-metafields}/actions.js +5 -5
  440. package/core/server/services/members-metafields/bindings-service.js +147 -0
  441. package/core/server/services/members-metafields/codec.js +14 -0
  442. package/core/server/services/{members-custom-fields → members-metafields}/config.js +1 -1
  443. package/core/server/services/{members-custom-fields → members-metafields}/definitions-service.js +68 -22
  444. package/core/server/services/members-metafields/filter.js +181 -0
  445. package/core/server/services/{members-custom-fields → members-metafields}/index.js +16 -7
  446. package/core/server/services/{members-custom-fields → members-metafields}/key.js +2 -1
  447. package/core/server/services/{members-custom-fields → members-metafields}/models.js +5 -5
  448. package/core/server/services/members-metafields/namespaces.js +34 -0
  449. package/core/server/services/{members-custom-fields → members-metafields}/queries.js +1 -1
  450. package/core/server/services/{members-custom-fields → members-metafields}/schema.js +16 -12
  451. package/core/server/services/members-metafields/serializers.js +22 -0
  452. package/core/server/services/{members-custom-fields → members-metafields}/values-service.js +80 -48
  453. package/core/server/services/mentions/mention-controller.js +23 -21
  454. package/core/server/services/mentions/mention-sending-service.js +26 -9
  455. package/core/server/services/mentions/process-webmention-job.js +16 -0
  456. package/core/server/services/mentions/send-webmentions-job.js +18 -0
  457. package/core/server/services/mentions/service.js +7 -33
  458. package/core/server/services/route-settings/validation-errors.js +1 -1
  459. package/core/server/services/route-settings/yaml-parser.js +1 -1
  460. package/core/server/services/settings/settings-service.js +1 -8
  461. package/core/server/services/settings-helpers/settings-helpers.js +4 -6
  462. package/core/server/services/slack-ping/slack-ping-service.js +1 -1
  463. package/core/server/services/staff/staff-service-emails.js +2 -2
  464. package/core/server/services/stripe/config.js +14 -8
  465. package/core/server/services/stripe/service.js +10 -1
  466. package/core/server/services/stripe/services/checkout/completed-session.js +2 -2
  467. package/core/server/services/stripe/services/checkout/session-options.js +18 -15
  468. package/core/server/services/stripe/services/webhook/checkout-session-event-service.js +28 -7
  469. package/core/server/services/stripe/stripe-api.js +2 -0
  470. package/core/server/services/stripe/stripe-service.js +24 -14
  471. package/core/server/services/stripe/webhook-controller.js +10 -0
  472. package/core/server/services/tier-checkout-config/codec.js +11 -7
  473. package/core/server/services/tier-checkout-config/index.js +2 -1
  474. package/core/server/services/tier-checkout-config/models.js +11 -5
  475. package/core/server/services/tier-checkout-config/queries.js +12 -12
  476. package/core/server/services/tier-checkout-config/serializers.js +73 -10
  477. package/core/server/services/tier-checkout-config/service.js +14 -13
  478. package/core/server/services/tiers/service.js +3 -3
  479. package/core/server/services/update-check/index.js +13 -13
  480. package/core/server/services/update-check/jobs/update-check-job.js +7 -0
  481. package/core/server/services/update-check/update-check-service.js +2 -2
  482. package/core/server/services/url/router-filter.js +8 -10
  483. package/core/server/services/users.js +1 -19
  484. package/core/server/web/admin/controller.js +1 -1
  485. package/core/server/web/api/endpoints/admin/routes.js +20 -16
  486. package/core/server/web/members/account/index.js +2 -0
  487. package/core/server/web/members/account/routes.js +46 -0
  488. package/core/server/web/members/app.js +4 -18
  489. package/core/shared/config/defaults.json +1 -1
  490. package/core/shared/config/env/config.testing-mysql.json +1 -1
  491. package/core/shared/labs.js +7 -2
  492. package/package.json +42 -41
  493. package/pnpm-lock.yaml +1159 -582
  494. package/pnpm-workspace.yaml +18 -15
  495. package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
  496. package/components/tryghost-kg-default-nodes-2.2.0.tgz +0 -0
  497. package/core/built/admin/assets/Combination-5fYEzgbs.js +0 -41
  498. package/core/built/admin/assets/account-migration-DRhAehfw.js +0 -1
  499. package/core/built/admin/assets/activitypub/inbox-BluD2ucT.js +0 -1284
  500. package/core/built/admin/assets/activitypub/label-FHSh6ZAw.js +0 -16
  501. package/core/built/admin/assets/activitypub/layout-Cq4NG0Xr.js +0 -1
  502. package/core/built/admin/assets/activitypub/settings-DQDkr06X.js +0 -315
  503. package/core/built/admin/assets/add-integration-modal-BC0jExDZ.js +0 -1
  504. package/core/built/admin/assets/add-newsletter-modal-DchTkA7l.js +0 -1
  505. package/core/built/admin/assets/add-recommendation-modal-DMvaJZKp.js +0 -1
  506. package/core/built/admin/assets/alert-dialog-QhXzdHfc.js +0 -1
  507. package/core/built/admin/assets/analytics-No1DDY3A.js +0 -1
  508. package/core/built/admin/assets/automated-emails-te1D5kq-.js +0 -1
  509. package/core/built/admin/assets/automations-DpUNUdcZ.js +0 -1
  510. package/core/built/admin/assets/bluesky-sharing-Cjrv_f62.js +0 -1
  511. package/core/built/admin/assets/chunk.896.435fe0637944d4a69810.js +0 -366
  512. package/core/built/admin/assets/color-picker-BTY_NdEm.js +0 -3
  513. package/core/built/admin/assets/color-picker-field-CPlkzOH0.js +0 -1
  514. package/core/built/admin/assets/combobox-DrMtv_4P.js +0 -1
  515. package/core/built/admin/assets/command-ZdgYJpoI.js +0 -1
  516. package/core/built/admin/assets/comments-kidj60-h.js +0 -1
  517. package/core/built/admin/assets/confirmation-context-BhbmQQEl.js +0 -1
  518. package/core/built/admin/assets/custom-field-type-option-CsGIZk1J.js +0 -10
  519. package/core/built/admin/assets/custom-integration-modal-BY37O_9X.js +0 -1
  520. package/core/built/admin/assets/design-and-theme-modal-DUSKM4uC.js +0 -22
  521. package/core/built/admin/assets/dialog-B44iRwlc.js +0 -1
  522. package/core/built/admin/assets/dirty-confirm-dialog-BxgQgQ6H.js +0 -1
  523. package/core/built/admin/assets/dist-Cy8tfrp_.js +0 -1
  524. package/core/built/admin/assets/domain-Ca6KhoQt.js +0 -1
  525. package/core/built/admin/assets/dropzone-Bb-5zQTk.js +0 -5
  526. package/core/built/admin/assets/edit-profile-BdupLlus.js +0 -1
  527. package/core/built/admin/assets/editor-BP883Lpn.js +0 -8
  528. package/core/built/admin/assets/explore-FB-CimXw.js +0 -1
  529. package/core/built/admin/assets/feed-C1GxsmI2.js +0 -1
  530. package/core/built/admin/assets/filter-sources-D5n5bFA2.js +0 -1
  531. package/core/built/admin/assets/filters-DJEzkMUK.js +0 -1
  532. package/core/built/admin/assets/filters-MZXvdH5D.js +0 -1
  533. package/core/built/admin/assets/first-promoter-modal-CGTGLCr5.js +0 -1
  534. package/core/built/admin/assets/gift-link-modal-B6v0tnRN.js +0 -1
  535. package/core/built/admin/assets/growth-BGAJD1rs.js +0 -3
  536. package/core/built/admin/assets/history-modal-iKwUY3XR.js +0 -1
  537. package/core/built/admin/assets/hooks-CuEZV2-q.js +0 -2
  538. package/core/built/admin/assets/index-DjQe-e5s.js +0 -4
  539. package/core/built/admin/assets/index-Dqf2x-ry.css +0 -1
  540. package/core/built/admin/assets/index.es-VihPwfeH.js +0 -1
  541. package/core/built/admin/assets/input--W-rCTrX.js +0 -1
  542. package/core/built/admin/assets/invite-user-modal-MdImLCaJ.js +0 -1
  543. package/core/built/admin/assets/koenig-loader-DYZpm6El.js +0 -2
  544. package/core/built/admin/assets/label-picker-cB51xl1r.js +0 -1
  545. package/core/built/admin/assets/layout-c_B_1hax.js +0 -1
  546. package/core/built/admin/assets/link-helpers-MVDdnFCY.js +0 -1
  547. package/core/built/admin/assets/loading-indicator-BpFWTVgh.js +0 -1
  548. package/core/built/admin/assets/member-custom-fields-qs0dIkxM.js +0 -1
  549. package/core/built/admin/assets/member-detail-B6uec2a6.js +0 -1
  550. package/core/built/admin/assets/members-BQF3CqhI.js +0 -2
  551. package/core/built/admin/assets/moderation-DY4wF1Q3.js +0 -1
  552. package/core/built/admin/assets/navigation-modal-DX-gNF3X.js +0 -1
  553. package/core/built/admin/assets/newsletter-CyQA7m3m.js +0 -1
  554. package/core/built/admin/assets/newsletter-detail-modal-BDrptuxn.js +0 -1
  555. package/core/built/admin/assets/newsletters-DXuNmC42.js +0 -1
  556. package/core/built/admin/assets/newsletters-DhNigJUh.js +0 -1
  557. package/core/built/admin/assets/note-Cgo2LCJ6.js +0 -1
  558. package/core/built/admin/assets/notifications-BC50AMku.js +0 -1
  559. package/core/built/admin/assets/offers-container-modal-DWycIMzT.js +0 -1
  560. package/core/built/admin/assets/onboarding-DGQuV7Ew.js +0 -1
  561. package/core/built/admin/assets/overview-CVbFtn-k.js +0 -1
  562. package/core/built/admin/assets/overview-YKj7SZaK.js +0 -1
  563. package/core/built/admin/assets/pages-B6vr9F_D.js +0 -1
  564. package/core/built/admin/assets/popover-CCy0h5rq.js +0 -1
  565. package/core/built/admin/assets/portal-frame-dc4XKr0e.js +0 -1
  566. package/core/built/admin/assets/portal-modal-BvvdF_B9.js +0 -1
  567. package/core/built/admin/assets/post-analytics-DX470WRG.js +0 -1
  568. package/core/built/admin/assets/post-analytics-header-CXpJmdDv.js +0 -1
  569. package/core/built/admin/assets/post-analytics-provider-CLfKGWZy.js +0 -1
  570. package/core/built/admin/assets/post-helpers-C5OQMBoi.js +0 -1
  571. package/core/built/admin/assets/post-share-modal-Cl0NXRJr.js +0 -1
  572. package/core/built/admin/assets/posts-KY3aUhVV.js +0 -1
  573. package/core/built/admin/assets/preferences-DO0UUWFp.js +0 -5
  574. package/core/built/admin/assets/profile-CxT-0l4d.js +0 -1
  575. package/core/built/admin/assets/router-provider-B0gZyiGJ.js +0 -1
  576. package/core/built/admin/assets/schemas-4UPic-oD.js +0 -64
  577. package/core/built/admin/assets/select-DuDUFdPq.js +0 -1
  578. package/core/built/admin/assets/settings-BjCii7BM.js +0 -1
  579. package/core/built/admin/assets/settings-b8kNzZSQ.js +0 -4
  580. package/core/built/admin/assets/share-modal-BV70mr9k.js +0 -1
  581. package/core/built/admin/assets/shim-ClF_m5ux.js +0 -1
  582. package/core/built/admin/assets/slack-modal-Be2_KK-z.js +0 -1
  583. package/core/built/admin/assets/stats-C4reGh9O.js +0 -1
  584. package/core/built/admin/assets/stats-view-DP9pQ62k.js +0 -1
  585. package/core/built/admin/assets/stripe-connect-modal-Z-UT_BGc.js +0 -1
  586. package/core/built/admin/assets/tag-detail-Dc0nTOtU.js +0 -2
  587. package/core/built/admin/assets/tags-BLaXBwnb.js +0 -1
  588. package/core/built/admin/assets/testimonials-modal-sFwRnNLh.js +0 -1
  589. package/core/built/admin/assets/tier-detail-modal-BCFpWwUS.js +0 -1
  590. package/core/built/admin/assets/tiers-Nd_z4BZY.js +0 -1
  591. package/core/built/admin/assets/use-filter-params-CAvfDvf1.js +0 -1
  592. package/core/built/admin/assets/use-growth-stats-D6mZXGhK.js +0 -1
  593. package/core/built/admin/assets/use-host-limits-DZtR08oa.js +0 -1
  594. package/core/built/admin/assets/use-pintura-config-CzTfnufz.js +0 -1
  595. package/core/built/admin/assets/use-reply-chain-data-BeQwz8oF.js +0 -1
  596. package/core/built/admin/assets/use-settings-navigation-BbrSUVcf.js +0 -1
  597. package/core/built/admin/assets/use-staff-users-cZg4ugOF.js +0 -1
  598. package/core/built/admin/assets/use-tinybird-query-B1IMyAcv.js +0 -39
  599. package/core/built/admin/assets/use-tinybird-token-Bow0Zwn8.js +0 -1
  600. package/core/built/admin/assets/use-upgrade-route-DhRSo7at.js +0 -1
  601. package/core/built/admin/assets/user-detail-modal-yipSoQfv.js +0 -1
  602. package/core/built/admin/assets/users-5msE1WMs.js +0 -1
  603. package/core/built/admin/assets/web-CKcXAu86.js +0 -1
  604. package/core/built/admin/assets/web-DR4TqM3E.js +0 -2
  605. package/core/server/api/endpoints/member-custom-fields.js +0 -90
  606. package/core/server/api/endpoints/utils/serializers/output/member-custom-fields.js +0 -20
  607. package/core/server/services/email-suppression-list/in-memory-email-suppression-list.js +0 -39
  608. package/core/server/services/jobs/worker-model-event-bridge.js +0 -149
  609. package/core/server/services/members/jobs/clean-expired-comped.js +0 -132
  610. package/core/server/services/members-custom-fields/bindings-service.js +0 -119
  611. package/core/server/services/members-custom-fields/codec.js +0 -15
  612. package/core/server/services/members-custom-fields/filter.js +0 -199
  613. package/core/server/services/members-custom-fields/serializers.js +0 -24
  614. package/core/server/services/stripe/services/checkout/allowed-countries.js +0 -267
  615. package/core/server/services/stripe/services/checkout/field-ports.js +0 -34
  616. package/core/server/services/tier-checkout-config/destinations.js +0 -17
  617. package/core/server/services/update-check/run-update-check.js +0 -63
  618. /package/core/built/admin/assets/{chunk.492.f24d855d7e3f3aad261c.js.LICENSE.txt → chunk.901.4ccc639821020230bcca.js.LICENSE.txt} +0 -0
  619. /package/core/server/services/{members-custom-fields → members-metafields}/storage.js +0 -0
@@ -3,20 +3,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.CustomFieldValuesService = void 0;
6
+ exports.MetafieldValuesService = void 0;
7
7
  const bson_objectid_1 = __importDefault(require("bson-objectid"));
8
8
  const errors_1 = __importDefault(require("@tryghost/errors"));
9
9
  const logging_1 = __importDefault(require("@tryghost/logging"));
10
10
  const zod_1 = require("zod");
11
- const custom_field_types_1 = require("@tryghost/custom-field-types");
11
+ const metafield_types_1 = require("@tryghost/metafield-types");
12
+ const identity_1 = require("@tryghost/metafield-types/identity");
12
13
  const schema_1 = require("./schema");
13
14
  const queries_1 = require("./queries");
15
+ const access_1 = require("./access");
14
16
  const storage_1 = require("./storage");
15
- const FIELDS_TABLE = 'members_custom_fields';
16
- const VALUES_TABLE = 'members_custom_field_values';
17
+ const FIELDS_TABLE = 'members_metafields';
18
+ const VALUES_TABLE = 'members_metafield_values';
17
19
  /**
18
20
  * From the canonical schema, the same source definitions-service reads, so no key a site
19
- * could hold is refused and this cannot drift from the `members_custom_fields.key` column.
21
+ * could hold is refused and this cannot drift from the `members_metafields.key` column.
20
22
  */
21
23
  const MAX_KEY_LENGTH = require('../../data/schema').tables[FIELDS_TABLE].key.maxlength;
22
24
  /**
@@ -29,15 +31,15 @@ const MAX_KEY_LENGTH = require('../../data/schema').tables[FIELDS_TABLE].key.max
29
31
  * go when that lands; until then the alternative is hand-written upsert SQL per engine.
30
32
  */
31
33
  const UPSERT_CHUNK = 400;
32
- // Values stay `unknown`: each is validated by its own field type, which is not known
33
- // until the key is resolved to a definition.
34
- const ValuesInput = zod_1.z.record(zod_1.z.string().max(MAX_KEY_LENGTH), zod_1.z.unknown());
34
+ const MAX_IDENTITY_LENGTH = MAX_KEY_LENGTH * 2 + 1;
35
+ const ValuesInput = zod_1.z.record(zod_1.z.string().max(MAX_IDENTITY_LENGTH), zod_1.z.unknown());
36
+ const wireProperty = (identity) => [identity_1.QUALIFIER, identity].join('.');
35
37
  /**
36
38
  * What a member holds for each defined field. Separate from the definitions service
37
39
  * because a value belongs to the member and a definition belongs to the site's settings,
38
40
  * which are different aggregates rather than different layers.
39
41
  */
40
- class CustomFieldValuesService {
42
+ class MetafieldValuesService {
41
43
  knex;
42
44
  /** A getter, not a number: the ceiling is an operator setting that changes between requests. */
43
45
  getMaxDefinitions;
@@ -45,23 +47,23 @@ class CustomFieldValuesService {
45
47
  this.knex = knex;
46
48
  this.getMaxDefinitions = getMaxDefinitions;
47
49
  }
48
- async activeFieldsByKey(keys) {
50
+ async activeFieldsByIdentity(identities) {
51
+ const keys = identities
52
+ .map((identity) => (0, identity_1.parseIdentity)(identity))
53
+ .filter((parsed) => parsed !== null && parsed.namespace === identity_1.CUSTOM_NAMESPACE)
54
+ .map((parsed) => parsed.key);
49
55
  if (keys.length === 0) {
50
56
  return new Map();
51
57
  }
52
58
  const fields = await (0, queries_1.activeFields)(this.knex)
53
59
  .whereIn('key', keys)
54
60
  .select('id', 'key', 'name', 'type');
55
- return new Map(fields.map((field) => [field.key, field]));
61
+ return new Map(fields.map((field) => [
62
+ (0, identity_1.formatIdentity)({ namespace: identity_1.CUSTOM_NAMESPACE, key: field.key, partPath: null }),
63
+ { ...field, namespace: identity_1.CUSTOM_NAMESPACE },
64
+ ]));
56
65
  }
57
- /**
58
- * Members' values, keyed by member id then field key; anything absent is unset.
59
- *
60
- * Archived fields are excluded to match the definitions browse: their values stay in
61
- * the database and stop being addressable. A row that will not parse is dropped and
62
- * logged rather than failing the read, so one stale row cannot take down a member.
63
- */
64
- async getValuesForMembers(memberIds) {
66
+ async getValuesForMembers(memberIds, audience) {
65
67
  if (memberIds.length === 0) {
66
68
  return new Map();
67
69
  }
@@ -69,7 +71,7 @@ class CustomFieldValuesService {
69
71
  // cannot carry an order. `path` is ordered so composite parts assemble the same
70
72
  // way every time.
71
73
  const rows = await this.knex(VALUES_TABLE)
72
- .join(FIELDS_TABLE, `${VALUES_TABLE}.custom_field_key`, `${FIELDS_TABLE}.key`)
74
+ .join(FIELDS_TABLE, `${VALUES_TABLE}.metafield_key`, `${FIELDS_TABLE}.key`)
73
75
  .whereIn(`${VALUES_TABLE}.member_id`, memberIds)
74
76
  .where(`${FIELDS_TABLE}.status`, schema_1.FIELD_STATUS.active)
75
77
  .orderBy(`${VALUES_TABLE}.path`, 'asc')
@@ -77,30 +79,57 @@ class CustomFieldValuesService {
77
79
  const leaves = [];
78
80
  for (const row of rows) {
79
81
  try {
80
- leaves.push(schema_1.DbCustomFieldLeaf.parse(row));
82
+ leaves.push(schema_1.DbMetafieldLeaf.parse(row));
81
83
  }
82
84
  catch (err) {
83
85
  logging_1.default.warn({
84
- event: { name: 'members.custom_fields.value_unreadable' },
86
+ event: { name: 'members.metafields.value_unreadable' },
85
87
  err,
86
- customFieldKey: row.key,
88
+ metafieldKey: row.key,
87
89
  path: row.path,
88
- }, 'Skipping an unreadable custom field value');
90
+ }, 'Skipping an unreadable metafield value');
89
91
  }
90
92
  }
91
- return (0, storage_1.valuesFromLeaves)(leaves);
93
+ // Narrowed before assembly, not after: a composite is one value spread across
94
+ // several rows, and dropping some of its parts later would hand back half an
95
+ // address rather than no address.
96
+ const flat = (0, storage_1.valuesFromLeaves)((0, access_1.readableFields)(audience, leaves));
97
+ return new Map(memberIds.map((memberId) => [memberId, { [identity_1.CUSTOM_NAMESPACE]: flat.get(memberId) ?? {} }]));
92
98
  }
93
- /** Shared by every caller so they cannot disagree on what a values object is. */
94
99
  parseValues(input) {
95
100
  const parsed = ValuesInput.safeParse(input);
96
101
  if (!parsed.success) {
97
102
  throw new errors_1.default.ValidationError({
98
- message: 'Custom field values must be an object keyed by field key.',
99
- property: 'custom_fields',
103
+ message: 'Custom field values must be an object keyed by field identity.',
104
+ property: identity_1.QUALIFIER,
100
105
  });
101
106
  }
102
107
  return parsed.data;
103
108
  }
109
+ unwrapWire(input) {
110
+ if (input === undefined) {
111
+ return undefined;
112
+ }
113
+ if (typeof input !== 'object' || input === null || Array.isArray(input)) {
114
+ throw new errors_1.default.ValidationError({
115
+ message: 'Metafields must be an object keyed by namespace.',
116
+ property: identity_1.QUALIFIER,
117
+ });
118
+ }
119
+ const identified = {};
120
+ for (const [namespace, values] of Object.entries(input)) {
121
+ if (typeof values !== 'object' || values === null || Array.isArray(values)) {
122
+ throw new errors_1.default.ValidationError({
123
+ message: 'Metafield values must be an object keyed by field key.',
124
+ property: [identity_1.QUALIFIER, namespace].join('.'),
125
+ });
126
+ }
127
+ for (const [key, raw] of Object.entries(values)) {
128
+ identified[`${namespace}.${key}`] = raw;
129
+ }
130
+ }
131
+ return identified;
132
+ }
104
133
  /**
105
134
  * Whether input names any values. Asks the shape question alone, with no catalog
106
135
  * lookup, so it can be asked before a write is known to be permitted.
@@ -116,35 +145,38 @@ class CustomFieldValuesService {
116
145
  * validate before opening a transaction it would otherwise have to unwind, then apply
117
146
  * the same plan without re-resolving it.
118
147
  */
119
- async planWrite(input) {
148
+ async planWrite(input, audience) {
120
149
  const values = this.parseValues(input);
121
- const keys = Object.keys(values);
150
+ const identities = Object.keys(values);
122
151
  // Bounded by the definitions ceiling, which also holds the lookup below inside
123
152
  // the driver's bound-parameter limit.
124
153
  const maxKeys = this.getMaxDefinitions();
125
- if (keys.length > maxKeys) {
154
+ if (identities.length > maxKeys) {
126
155
  throw new errors_1.default.ValidationError({
127
156
  message: `Custom field values are limited to ${maxKeys} fields per request.`,
128
- property: 'custom_fields',
157
+ property: identity_1.QUALIFIER,
129
158
  });
130
159
  }
131
- const byKey = await this.activeFieldsByKey(keys);
160
+ const byIdentity = await this.activeFieldsByIdentity(identities);
132
161
  const writes = [];
133
- for (const [key, raw] of Object.entries(values)) {
134
- const field = byKey.get(key);
162
+ for (const [identity, raw] of Object.entries(values)) {
163
+ const field = byIdentity.get(identity);
135
164
  if (!field) {
136
- // Unknown or archived. Refused rather than ignored: a typo that silently
137
- // drops what somebody typed is worse than a save that fails. The catalog
138
- // applies the same rule to the parts of a composite value.
139
165
  throw new errors_1.default.ValidationError({
140
- message: `Unknown custom field: ${key}`,
141
- property: `custom_fields.${key}`,
166
+ message: `Unknown custom field: ${identity}`,
167
+ property: wireProperty(identity),
168
+ });
169
+ }
170
+ if (!(0, access_1.canWrite)(audience, field)) {
171
+ throw new errors_1.default.ValidationError({
172
+ message: `Cannot set custom field: ${identity}`,
173
+ property: wireProperty(identity),
142
174
  });
143
175
  }
144
176
  // `null` clears any field, and `''` clears one with no parts. For a value
145
177
  // with parts `''` names nothing, so it is left to fail validation rather than
146
178
  // being read as a silent delete.
147
- if (raw === null || (raw === '' && (0, custom_field_types_1.subFieldsOf)(field.type) === null)) {
179
+ if (raw === null || (raw === '' && (0, metafield_types_1.subFieldsOf)(field.type) === null)) {
148
180
  writes.push({ field });
149
181
  continue;
150
182
  }
@@ -152,12 +184,12 @@ class CustomFieldValuesService {
152
184
  // `context` when `context` is empty and prepends it when it is not, so
153
185
  // anything added here reaches the client glued to the front of the reason.
154
186
  // Which field failed rides in `property`.
155
- const value = custom_field_types_1.FIELD_TYPES[field.type].value.safeParse(raw);
187
+ const value = metafield_types_1.FIELD_TYPES[field.type].value.safeParse(raw);
156
188
  if (!value.success) {
157
189
  const issue = value.error.issues[0];
158
190
  throw new errors_1.default.ValidationError({
159
191
  message: issue.message,
160
- property: [`custom_fields.${key}`, ...issue.path].join('.'),
192
+ property: [wireProperty(identity), ...issue.path].join('.'),
161
193
  });
162
194
  }
163
195
  writes.push({ field, value: value.data });
@@ -202,7 +234,7 @@ class CustomFieldValuesService {
202
234
  rows.push(...set.map((leaf) => ({
203
235
  id: new bson_objectid_1.default().toHexString(),
204
236
  member_id: memberId,
205
- custom_field_key: field.key,
237
+ metafield_key: field.key,
206
238
  path: leaf.path,
207
239
  value_text: leaf.value_text,
208
240
  written_by_type: writtenBy.type,
@@ -214,7 +246,7 @@ class CustomFieldValuesService {
214
246
  if (clearedKeys.length > 0) {
215
247
  await trx(VALUES_TABLE)
216
248
  .where('member_id', memberId)
217
- .whereIn('custom_field_key', clearedKeys)
249
+ .whereIn('metafield_key', clearedKeys)
218
250
  .del();
219
251
  }
220
252
  if (clearedPaths.length > 0) {
@@ -223,7 +255,7 @@ class CustomFieldValuesService {
223
255
  .where('member_id', memberId)
224
256
  .where((builder) => {
225
257
  for (const { fieldKey, paths } of clearedPaths) {
226
- builder.orWhere((pair) => pair.where('custom_field_key', fieldKey).whereIn('path', paths));
258
+ builder.orWhere((pair) => pair.where('metafield_key', fieldKey).whereIn('path', paths));
227
259
  }
228
260
  })
229
261
  .del();
@@ -236,7 +268,7 @@ class CustomFieldValuesService {
236
268
  .insert(rows.slice(from, from + UPSERT_CHUNK))
237
269
  // Naming the columns rather than giving values takes each from the row
238
270
  // that lost the conflict, so every part updates to its own value.
239
- .onConflict(['member_id', 'custom_field_key', 'path'])
271
+ .onConflict(['member_id', 'metafield_key', 'path'])
240
272
  // The writer is merged with the value, so a leaf names who wrote what
241
273
  // it currently holds rather than who wrote its first value.
242
274
  .merge(['value_text', 'written_by_type', 'written_by_id', 'updated_at']);
@@ -251,4 +283,4 @@ class CustomFieldValuesService {
251
283
  }
252
284
  }
253
285
  }
254
- exports.CustomFieldValuesService = CustomFieldValuesService;
286
+ exports.MetafieldValuesService = MetafieldValuesService;
@@ -1,4 +1,5 @@
1
1
  const logging = require('@tryghost/logging');
2
+ const ProcessWebmentionJob = require('./process-webmention-job').default;
2
3
 
3
4
  /**
4
5
  * @typedef {import('./mentions-api')} MentionsAPI
@@ -22,11 +23,6 @@ const logging = require('@tryghost/logging');
22
23
  * @prop {Resource} resource
23
24
  */
24
25
 
25
- /**
26
- * @typedef {object} IJobService
27
- * @prop {(name: string, fn: Function) => void} addJob
28
- */
29
-
30
26
  /**
31
27
  * @typedef {object} IMentionResourceService
32
28
  * @prop {(id: import('bson-objectid').default) => Promise<MentionResource>} getByID
@@ -36,8 +32,8 @@ module.exports = class MentionController {
36
32
  /** @type {import('./mentions-api')} */
37
33
  #api;
38
34
 
39
- /** @type {IJobService} */
40
- #jobService;
35
+ /** @type {import('../jobs-service/jobs-service').JobsService} */
36
+ #jobsService;
41
37
 
42
38
  /** @type {IMentionResourceService} */
43
39
  #mentionResourceService;
@@ -45,12 +41,12 @@ module.exports = class MentionController {
45
41
  /**
46
42
  * @param {object} deps
47
43
  * @param {import('./mentions-api')} deps.api
48
- * @param {IJobService} deps.jobService
44
+ * @param {import('../jobs-service/jobs-service').JobsService} deps.jobsService
49
45
  * @param {IMentionResourceService} deps.mentionResourceService
50
46
  */
51
47
  async init(deps) {
52
48
  this.#api = deps.api;
53
- this.#jobService = deps.jobService;
49
+ this.#jobsService = deps.jobsService;
54
50
  this.#mentionResourceService = deps.mentionResourceService;
55
51
  }
56
52
 
@@ -127,17 +123,23 @@ module.exports = class MentionController {
127
123
  */
128
124
  async receive(frame) {
129
125
  logging.info('[Webmention] ' + JSON.stringify(frame.data));
130
- this.#jobService.addJob('processWebmention', async () => {
131
- const { source, target, ...payload } = frame.data;
132
- try {
133
- await this.#api.processWebmention({
134
- source: new URL(source),
135
- target: new URL(target),
136
- payload,
137
- });
138
- } catch (err) {
139
- logging.error(err, '[Webmention] Failed processing webmention');
140
- }
141
- });
126
+ const { source, target, ...payload } = frame.data;
127
+ await this.#jobsService.dispatch(new ProcessWebmentionJob({ source, target, payload }));
128
+ }
129
+
130
+ /**
131
+ * @param {import('./process-webmention-job').default} job
132
+ * @returns {Promise<void>}
133
+ */
134
+ async processWebmention({ source, target, payload }) {
135
+ try {
136
+ await this.#api.processWebmention({
137
+ source: new URL(source),
138
+ target: new URL(target),
139
+ payload,
140
+ });
141
+ } catch (err) {
142
+ logging.error(err, '[Webmention] Failed processing webmention');
143
+ }
142
144
  }
143
145
  };
@@ -1,5 +1,6 @@
1
1
  const errors = require('@tryghost/errors');
2
2
  const logging = require('@tryghost/logging');
3
+ const SendWebmentionsJob = require('./send-webmentions-job').default;
3
4
 
4
5
  module.exports = class MentionSendingService {
5
6
  #discoveryService;
@@ -8,8 +9,12 @@ module.exports = class MentionSendingService {
8
9
  #getPostData;
9
10
  #getPostUrl;
10
11
  #isEnabled;
11
- #jobService;
12
+ #jobsService;
12
13
 
14
+ /**
15
+ * @param {object} deps
16
+ * @param {import('../jobs-service/jobs-service').JobsService} deps.jobsService
17
+ */
13
18
  constructor({
14
19
  discoveryService,
15
20
  externalRequest,
@@ -17,7 +22,7 @@ module.exports = class MentionSendingService {
17
22
  getPostData,
18
23
  getPostUrl,
19
24
  isEnabled,
20
- jobService,
25
+ jobsService,
21
26
  }) {
22
27
  this.#discoveryService = discoveryService;
23
28
  this.#externalRequest = externalRequest;
@@ -25,7 +30,7 @@ module.exports = class MentionSendingService {
25
30
  this.#getPostData = getPostData;
26
31
  this.#getPostUrl = getPostUrl;
27
32
  this.#isEnabled = isEnabled;
28
- this.#jobService = jobService;
33
+ this.#jobsService = jobsService;
29
34
  }
30
35
 
31
36
  get siteUrl() {
@@ -82,13 +87,13 @@ module.exports = class MentionSendingService {
82
87
  // Capture the source URL now, from the event's data, rather than
83
88
  // deferring the model into the job.
84
89
  const url = new URL(await this.#resolvePostUrl(post));
85
- await this.#jobService.addJob('sendWebmentions', async () => {
86
- await this.sendForHTMLResource({
87
- url,
90
+ await this.#jobsService.dispatch(
91
+ new SendWebmentionsJob({
92
+ sourceUrl: url.href,
88
93
  html: html,
89
94
  previousHtml: previousHtml,
90
- });
91
- });
95
+ }),
96
+ );
92
97
  }
93
98
  } catch (e) {
94
99
  logging.error('Error in webmention sending service post update event handler:');
@@ -157,11 +162,23 @@ module.exports = class MentionSendingService {
157
162
  });
158
163
  }
159
164
 
165
+ /**
166
+ * Send the webmentions for a delivered job.
167
+ * @param {import('./send-webmentions-job').default} job
168
+ */
169
+ async sendWebmentions(job) {
170
+ await this.sendForHTMLResource({
171
+ url: new URL(job.sourceUrl),
172
+ html: job.html,
173
+ previousHtml: job.previousHtml,
174
+ });
175
+ }
176
+
160
177
  /**
161
178
  * Send a webmention call for the links in a resource.
162
179
  * @param {object} resource
163
180
  * @param {URL} resource.url
164
- * @param {string} resource.html
181
+ * @param {string|null} resource.html
165
182
  * @param {string|null} [resource.previousHtml]
166
183
  */
167
184
  async sendForHTMLResource(resource) {
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const job_1 = require("../jobs-service/job");
4
+ class ProcessWebmentionJob extends job_1.Job {
5
+ static type = 'process-webmention';
6
+ source;
7
+ target;
8
+ payload;
9
+ constructor({ source, target, payload, }) {
10
+ super();
11
+ this.source = source;
12
+ this.target = target;
13
+ this.payload = payload;
14
+ }
15
+ }
16
+ exports.default = ProcessWebmentionJob;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const job_1 = require("../jobs-service/job");
4
+ // Carries the post's full html twice - the largest job payload in the system;
5
+ // revisit if a durable backend puts size limits on envelopes.
6
+ class SendWebmentionsJob extends job_1.Job {
7
+ static type = 'send-webmentions';
8
+ sourceUrl;
9
+ html;
10
+ previousHtml;
11
+ constructor({ sourceUrl, html, previousHtml, }) {
12
+ super();
13
+ this.sourceUrl = sourceUrl;
14
+ this.html = html ?? null;
15
+ this.previousHtml = previousHtml ?? null;
16
+ }
17
+ }
18
+ exports.default = SendWebmentionsJob;
@@ -14,8 +14,6 @@ const outputSerializerUrlUtil = require('../../../server/api/endpoints/utils/ser
14
14
  const urlService = require('../url');
15
15
  const settingsCache = require('../../../shared/settings-cache');
16
16
  const DomainEvents = require('@tryghost/domain-events');
17
- const logging = require('@tryghost/logging');
18
- const jobsService = require('../mentions-jobs');
19
17
 
20
18
  // Serializes a post model to the data the URL service needs, loading the
21
19
  // relations it reads for filtered collections (event-emitted models don't
@@ -38,33 +36,6 @@ function getPostUrl(id, postData) {
38
36
  return jsonModel.url;
39
37
  }
40
38
 
41
- // Reports the same queued/started/finished/failed lifecycle for every mentions
42
- // background job. The wrapped callback's result and errors pass through unchanged,
43
- // so job manager outcomes and retries are unaffected.
44
- function makeLoggingJobService() {
45
- return {
46
- async addJob(name, fn) {
47
- logging.info(`[Background Job] ${name} queued`);
48
- jobsService.addJob({
49
- name,
50
- job: async () => {
51
- const startedAt = Date.now();
52
- logging.info(`[Background Job] ${name} started`);
53
- try {
54
- const result = await fn();
55
- logging.info(`[Background Job] ${name} completed in ${Date.now() - startedAt}ms`);
56
- return result;
57
- } catch (err) {
58
- logging.error(err, `[Background Job] ${name} failed after ${Date.now() - startedAt}ms`);
59
- throw err;
60
- }
61
- },
62
- offloaded: false,
63
- });
64
- },
65
- };
66
- }
67
-
68
39
  module.exports = {
69
40
  /** @type {import('./mentions-api')} */
70
41
  api: null,
@@ -75,7 +46,11 @@ module.exports = {
75
46
  /** @type {import('./mention-sending-service')} */
76
47
  sendingService: null,
77
48
  didInit: false,
78
- async init() {
49
+ /**
50
+ * @param {object} deps
51
+ * @param {import('../jobs-service/jobs-service').JobsService} deps.jobsService
52
+ */
53
+ async init({ jobsService }) {
79
54
  if (this.didInit) {
80
55
  return;
81
56
  }
@@ -110,7 +85,7 @@ module.exports = {
110
85
 
111
86
  this.controller.init({
112
87
  api,
113
- jobService: makeLoggingJobService(),
88
+ jobsService,
114
89
  mentionResourceService: {
115
90
  async getByID(id) {
116
91
  if (!id) {
@@ -137,7 +112,7 @@ module.exports = {
137
112
  getPostData: (post) => getPostData(post),
138
113
  getPostUrl: (id, data) => getPostUrl(id, data),
139
114
  isEnabled: () => !settingsCache.get('is_private'),
140
- jobService: makeLoggingJobService(),
115
+ jobsService,
141
116
  });
142
117
  sendingService.listen(events);
143
118
 
@@ -148,4 +123,3 @@ module.exports = {
148
123
  // exposed for testing
149
124
  module.exports.getPostData = getPostData;
150
125
  module.exports.getPostUrl = getPostUrl;
151
- module.exports.makeLoggingJobService = makeLoggingJobService;
@@ -14,7 +14,7 @@ const tpl_1 = __importDefault(require("@tryghost/tpl"));
14
14
  const messages = {
15
15
  validationError: 'The following definition "{at}" is invalid: {reason}',
16
16
  };
17
- const DOCS_URL = 'https://ghost.org/docs/themes/routing/';
17
+ const DOCS_URL = 'https://docs.ghost.org/themes/routing/';
18
18
  const MAX_SHOWN_LENGTH = 40;
19
19
  /**
20
20
  * Stable, machine-readable codes describing the class of a routes.yaml failure.
@@ -9,7 +9,7 @@ const messages = {
9
9
  },
10
10
  invalidYamlFormat: {
11
11
  message: 'YAML input cannot be a plain string. Check the format of your YAML file.',
12
- help: 'https://ghost.org/docs/themes/routing/',
12
+ help: 'https://docs.ghost.org/themes/routing/',
13
13
  },
14
14
  };
15
15
 
@@ -200,14 +200,7 @@ module.exports = {
200
200
  type: 'boolean',
201
201
  group: 'members',
202
202
  fn: settingsHelpers.allowSelfSignup.bind(settingsHelpers),
203
- dependents: [
204
- 'members_signup_access',
205
- 'portal_plans',
206
- 'stripe_secret_key',
207
- 'stripe_publishable_key',
208
- 'stripe_connect_secret_key',
209
- 'stripe_connect_publishable_key',
210
- ],
203
+ dependents: ['members_signup_access'],
211
204
  }),
212
205
  );
213
206
  fields.push(
@@ -1,7 +1,7 @@
1
1
  const net = require('net');
2
2
  const tpl = require('@tryghost/tpl');
3
3
  const errors = require('@tryghost/errors');
4
- const EmailAddressParser = require('../email-address/email-address-parser');
4
+ const emailAddressParser = require('../email-address/email-address-parser');
5
5
  const logging = require('@tryghost/logging');
6
6
  const crypto = require('crypto');
7
7
  const debug = require('@tryghost/debug')('services:settings-helpers');
@@ -130,11 +130,9 @@ class SettingsHelpers {
130
130
  if (!supportAddress) {
131
131
  // In the new flow, we make a difference between an empty setting (= use default) and a 'noreply' setting (=use noreply @ domain)
132
132
  // Also keep the name of the default email!
133
- return EmailAddressParser.stringify(this.getDefaultEmail());
133
+ return emailAddressParser.stringify(this.getDefaultEmail());
134
134
  }
135
135
 
136
- supportAddress = supportAddress || 'noreply';
137
-
138
136
  // Any fromAddress without domain uses site domain, like default setting `noreply`
139
137
  if (supportAddress.indexOf('@') < 0) {
140
138
  return `${supportAddress}@${this.getDefaultEmailDomain()}`;
@@ -143,7 +141,7 @@ class SettingsHelpers {
143
141
  }
144
142
 
145
143
  /**
146
- * @deprecated Use getDefaultEmail().address (without name) or EmailAddressParser.stringify(this.getDefaultEmail()) (with name) instead
144
+ * @deprecated Use getDefaultEmail().address (without name) or emailAddressParser.stringify(this.getDefaultEmail()) (with name) instead
147
145
  */
148
146
  getNoReplyAddress() {
149
147
  return this.getDefaultEmailAddress();
@@ -157,7 +155,7 @@ class SettingsHelpers {
157
155
  // parse the email here and remove the sender name
158
156
  // E.g. when set to "bar" <from@default.com>
159
157
  const configAddress = this.config.get('mail:from');
160
- const parsed = EmailAddressParser.parse(configAddress);
158
+ const parsed = emailAddressParser.parse(configAddress);
161
159
  if (parsed) {
162
160
  return parsed;
163
161
  }
@@ -173,7 +173,7 @@ class SlackPingService {
173
173
  this.logging.error(new errors_1.default.InternalServerError({
174
174
  err: err,
175
175
  context: (0, tpl_1.default)(constants_1.messages.requestFailedError, { service: 'slack' }),
176
- help: (0, tpl_1.default)(constants_1.messages.requestFailedHelp, { url: 'https://ghost.org/docs/' }),
176
+ help: (0, tpl_1.default)(constants_1.messages.requestFailedHelp, { url: 'https://docs.ghost.org/' }),
177
177
  }));
178
178
  });
179
179
  }
@@ -2,7 +2,7 @@ const { promises: fs, readFileSync } = require('fs');
2
2
  const path = require('path');
3
3
  const moment = require('moment');
4
4
  const { globSync } = require('glob');
5
- const EmailAddressParser = require('../email-address/email-address-parser');
5
+ const emailAddressParser = require('../email-address/email-address-parser');
6
6
 
7
7
  class StaffServiceEmails {
8
8
  constructor({
@@ -593,7 +593,7 @@ class StaffServiceEmails {
593
593
  }
594
594
 
595
595
  get fromEmailAddress() {
596
- return EmailAddressParser.stringify(this.settingsHelpers.getDefaultEmail());
596
+ return emailAddressParser.stringify(this.settingsHelpers.getDefaultEmail());
597
597
  }
598
598
 
599
599
  extractInitials(name = '') {