ghost 6.62.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 (439) hide show
  1. package/components/tryghost-adapter-base-jobs-0.0.0.tgz +0 -0
  2. package/components/tryghost-adapter-base-scheduling-0.2.3.tgz +0 -0
  3. package/components/tryghost-adapter-base-sso-0.1.3.tgz +0 -0
  4. package/components/tryghost-admin-api-schema-0.0.0.tgz +0 -0
  5. package/components/tryghost-checkout-0.0.0.tgz +0 -0
  6. package/components/tryghost-i18n-0.0.0.tgz +0 -0
  7. package/components/tryghost-kg-card-factory-5.2.4.tgz +0 -0
  8. package/components/tryghost-kg-clean-basic-html-4.3.4.tgz +0 -0
  9. package/components/tryghost-kg-converters-1.2.5.tgz +0 -0
  10. package/components/tryghost-kg-default-cards-10.3.5.tgz +0 -0
  11. package/components/tryghost-kg-default-nodes-2.2.1.tgz +0 -0
  12. package/components/tryghost-kg-default-transforms-1.3.4.tgz +0 -0
  13. package/components/tryghost-kg-html-to-lexical-1.4.0.tgz +0 -0
  14. package/components/tryghost-kg-lexical-html-renderer-1.5.0.tgz +0 -0
  15. package/components/tryghost-kg-markdown-html-renderer-7.2.4.tgz +0 -0
  16. package/components/tryghost-kg-utils-1.1.4.tgz +0 -0
  17. package/components/tryghost-limit-service-0.0.0.tgz +0 -0
  18. package/components/tryghost-metafield-types-0.0.0.tgz +0 -0
  19. package/content/themes/source/package.json +2 -2
  20. package/content/themes/source/partials/post-card.hbs +1 -1
  21. package/core/boot.js +7 -5
  22. package/core/built/admin/assets/{about-Dyae_UT6.js → about-C1C3s5-g.js} +1 -1
  23. package/core/built/admin/assets/accordion-CxGsDKwa.js +1 -0
  24. package/core/built/admin/assets/{account-migration-CESa0mnX.js → account-migration-CbUhW6gk.js} +1 -1
  25. package/core/built/admin/assets/activitypub/{account-migration-By69CgCp.js → account-migration-KA6Jjf9L.js} +7 -7
  26. package/core/built/admin/assets/activitypub/activitypub.js +3 -3
  27. package/core/built/admin/assets/activitypub/{avatar-DLPL3Abs.js → avatar-DVJF5bxP.js} +2 -2
  28. package/core/built/admin/assets/activitypub/{avatar-flipboard-C9iDY-QV.js → avatar-flipboard-csQaNeYK.js} +2 -2
  29. package/core/built/admin/assets/activitypub/{bluesky-sharing-BJcPMrDd.js → bluesky-sharing-C7nTDMvw.js} +9 -9
  30. package/core/built/admin/assets/activitypub/{content-formatters-3rTHg3mp.js → content-formatters-CLcjaBwV.js} +4 -4
  31. package/core/built/admin/assets/activitypub/{copy-DIAOQoCZ.js → copy-DcOh8kXw.js} +2 -2
  32. package/core/built/admin/assets/activitypub/{domain-DUR4xSkV.js → domain-fZ-X8i4-.js} +9 -9
  33. package/core/built/admin/assets/activitypub/{edit-profile-BqtfzxCp.js → edit-profile-BqMLQV88.js} +6 -6
  34. package/core/built/admin/assets/activitypub/{explore-BxuJd-J4.js → explore-B4yPoP8E.js} +10 -10
  35. package/core/built/admin/assets/activitypub/{feed-BM1TcksA.js → feed-BRC_mvAe.js} +9 -9
  36. package/core/built/admin/assets/activitypub/{field-Dn7HHx2-.js → field-COacNgOt.js} +3 -3
  37. package/core/built/admin/assets/activitypub/{hash-Bm3WxYN4.js → hash-C7u-irQQ.js} +2 -2
  38. package/core/built/admin/assets/activitypub/{inbox-CCjkuow2.js → inbox-BW-yvUoN.js} +10 -10
  39. package/core/built/admin/assets/activitypub/{inbox-d8oJRTf4.js → inbox-CbTTdDQ3.js} +2 -2
  40. package/core/built/admin/assets/activitypub/{label-1AA_s9Fa.js → label-kPMmYI7l.js} +3 -3
  41. package/core/built/admin/assets/activitypub/layout-BL4_jtuV.js +1 -0
  42. package/core/built/admin/assets/activitypub/{moderation-CnmxEB8w.js → moderation-CuidJzc0.js} +10 -10
  43. package/core/built/admin/assets/activitypub/{note-ZKc_Bnba.js → note-CAMRRSqD.js} +7 -7
  44. package/core/built/admin/assets/activitypub/{notifications-CB2tJZau.js → notifications-BmNlXGgp.js} +9 -9
  45. package/core/built/admin/assets/activitypub/{onboarding-BsJ9E5qf.js → onboarding-Bqg7fh_L.js} +2 -2
  46. package/core/built/admin/assets/activitypub/{onboarding-CSUJJIlh.js → onboarding-Dmun9jr_.js} +2 -2
  47. package/core/built/admin/assets/activitypub/{preferences-0-JZnUkI.js → preferences--oH19wf9.js} +11 -11
  48. package/core/built/admin/assets/activitypub/{profile-C35cFIhM.js → profile-DH_tQx2D.js} +14 -14
  49. package/core/built/admin/assets/activitypub/{reply-DYK5vVqb.js → reply-Cap9PxSH.js} +2 -2
  50. package/core/built/admin/assets/activitypub/{routes-BD4vscyc.js → routes-DdyY9uFF.js} +30 -30
  51. package/core/built/admin/assets/activitypub/{separator-BbQqTm-p.js → separator-CAxxu8VV.js} +3 -3
  52. package/core/built/admin/assets/activitypub/{settings-BsMROdqh.js → settings-B6EEcVkW.js} +6 -6
  53. package/core/built/admin/assets/activitypub/{site-O0RL9YCN.js → site-BYps63oh.js} +2 -2
  54. package/core/built/admin/assets/activitypub/{step-1-BMSx7c_X.js → step-1-CKjR2KAm.js} +6 -6
  55. package/core/built/admin/assets/activitypub/{step-2-DtPQzlTH.js → step-2-B6PKfOUQ.js} +6 -6
  56. package/core/built/admin/assets/activitypub/{step-3-CLlOZTyt.js → step-3-C-qBbcUo.js} +11 -11
  57. package/core/built/admin/assets/activitypub/{tabs-Dxk-b9M-.js → tabs-DLhZtVde.js} +6 -6
  58. package/core/built/admin/assets/activitypub/{topic-filter-5yZH6tId.js → topic-filter-DsUOuu0k.js} +3 -3
  59. package/core/built/admin/assets/activitypub/{use-activity-pub-queries-CV50qe03.js → use-activity-pub-queries-CX9snsLs.js} +3 -3
  60. package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-Bmk5h4lW.js → use-navigate-with-base-path-DsJTGDSS.js} +988 -959
  61. package/core/built/admin/assets/activitypub/{use-reply-chain-data-Cbvzgjzd.js → use-reply-chain-data-AJi9zkzm.js} +5 -5
  62. package/core/built/admin/assets/activitypub/{users-BjcoP_HC.js → users-inweyKL5.js} +186 -160
  63. package/core/built/admin/assets/activitypub/{x-DbQZOLiI.js → x-DR8AT3-4.js} +2 -2
  64. package/core/built/admin/assets/{add-integration-modal-BlF6rs_f.js → add-integration-modal-BT_onDJy.js} +1 -1
  65. package/core/built/admin/assets/{add-newsletter-modal-CglVQqah.js → add-newsletter-modal-Cx1kQpiY.js} +1 -1
  66. package/core/built/admin/assets/{add-recommendation-modal-wz7BsuaG.js → add-recommendation-modal-B5nvAhvr.js} +1 -1
  67. package/core/built/admin/assets/{analytics-C4HE1gBg.js → analytics-DjoJWPI7.js} +1 -1
  68. package/core/built/admin/assets/{announcement-bar-modal-Ci4zz8jO.js → announcement-bar-modal-Dwd0EGFP.js} +1 -1
  69. package/core/built/admin/assets/{api-keys-3-0vJC3Y.js → api-keys-BGPzLHzA.js} +1 -1
  70. package/core/built/admin/assets/{api-keys-Ck-Yteiv.js → api-keys-BoeacM-s.js} +1 -1
  71. package/core/built/admin/assets/{audience-CtbA54Sn.js → audience-ceV3XVHq.js} +1 -1
  72. package/core/built/admin/assets/automated-emails-BLesE41L.js +1 -0
  73. package/core/built/admin/assets/{automations-sAcJ1334.js → automations-BN4u3GR8.js} +1 -1
  74. package/core/built/admin/assets/automations-C-ZTUwW3.js +1 -0
  75. package/core/built/admin/assets/{bluesky-sharing-BEtJ_gL_.js → bluesky-sharing-vzh-oPXL.js} +1 -1
  76. package/core/built/admin/assets/{breadcrumb-zUrZrBtW.js → breadcrumb-CaLk2b7D.js} +1 -1
  77. package/core/built/admin/assets/{button-eNMKQWXr.js → button-Dvcv1QSR.js} +1 -1
  78. package/core/built/admin/assets/calendar-Bl9RLcZX.js +1 -0
  79. package/core/built/admin/assets/{chart-helpers-CfBKt0vT.js → chart-helpers-FHywU0pj.js} +1 -1
  80. package/core/built/admin/assets/{checkbox-CgOn_tKW.js → checkbox-BtayFtjg.js} +1 -1
  81. package/core/built/admin/assets/chunk.254.035b85ec456ebbd7336b.js +440 -0
  82. package/core/built/admin/assets/{chunk.524.a697dee88db67fdf6021.js → chunk.524.e6975095fccdf22d90f8.js} +5 -5
  83. package/core/built/admin/assets/{chunk.582.5ed5d124cfca9c259b9c.js → chunk.582.98b485f9b2802f540897.js} +6 -6
  84. package/core/built/admin/assets/{chunk.492.f24d855d7e3f3aad261c.js → chunk.901.4ccc639821020230bcca.js} +9949 -7921
  85. package/core/built/admin/assets/{code-editor-view-K2wI-I5f.js → code-editor-view-C3ZfoF1X.js} +1 -1
  86. package/core/built/admin/assets/{code-editor-view-BYNoAoNV.js → code-editor-view-CAyRWy1s.js} +1 -1
  87. package/core/built/admin/assets/{color-picker-Ddw80xX6.js → color-picker-G4kGR7rp.js} +1 -1
  88. package/core/built/admin/assets/{color-picker-field-D9nUhvA7.js → color-picker-field-DQFVTNnT.js} +1 -1
  89. package/core/built/admin/assets/{combobox-w9j8PPQT.js → combobox-BnYzgEB4.js} +1 -1
  90. package/core/built/admin/assets/{command-BfpHORBv.js → command-C_vyTikI.js} +1 -1
  91. package/core/built/admin/assets/comments-aBrxfnZf.js +1 -0
  92. package/core/built/admin/assets/{config-DOMQDZGZ.js → config-kSHvwdTG.js} +1 -1
  93. package/core/built/admin/assets/{confirmation-context-CBM8G0Vj.js → confirmation-context-DwXX_Y5h.js} +1 -1
  94. package/core/built/admin/assets/{content-api-modal-TXRz3U7S.js → content-api-modal-D2G0nJP6.js} +1 -1
  95. package/core/built/admin/assets/{context-menu-_QMdd3kp.js → context-menu-DOVB6yaz.js} +1 -1
  96. package/core/built/admin/assets/{copy-field-6N01S07E.js → copy-field-DCJwh9qf.js} +1 -1
  97. package/core/built/admin/assets/{create-ghost-browse-value-source-qIBymvvf.js → create-ghost-browse-value-source-5C53jJaX.js} +1 -1
  98. package/core/built/admin/assets/custom-field-type-option-BAuW0F-E.js +1 -0
  99. package/core/built/admin/assets/{custom-integration-modal-DmNquxUV.js → custom-integration-modal-AbJGVyKc.js} +1 -1
  100. package/core/built/admin/assets/{date-range-select-uvz_DtPh.js → date-range-select-BY3K-ukj.js} +1 -1
  101. package/core/built/admin/assets/design-and-theme-modal-BvEy4_pC.js +2 -0
  102. package/core/built/admin/assets/{dirty-confirm-dialog-BZ1iytEd.js → dirty-confirm-dialog-DVPuGz3U.js} +1 -1
  103. package/core/built/admin/assets/{disabled-sources-indicator-DMRrxsiJ.js → disabled-sources-indicator-Cy7Zp4c8.js} +1 -1
  104. package/core/built/admin/assets/{domain-BNYrt0aD.js → domain-Dl61QGuk.js} +1 -1
  105. package/core/built/admin/assets/{dropzone-D7nFdAe5.js → dropzone-Dtz5Rmjt.js} +4 -4
  106. package/core/built/admin/assets/edit-profile-DNJSMDwm.js +1 -0
  107. package/core/built/admin/assets/editor-DbAen9zf.js +8 -0
  108. package/core/built/admin/assets/editor-screen-BFWThIai.js +26 -0
  109. package/core/built/admin/assets/email-sending-status-context-CWDOD1FN.js +1 -0
  110. package/core/built/admin/assets/email-sending-status-provider-DCPkDICt.js +1 -0
  111. package/core/built/admin/assets/emails-vFMk4yYl.js +1 -0
  112. package/core/built/admin/assets/{embed-signup-form-modal-Ds6mPEi5.js → embed-signup-form-modal-DGqsORxS.js} +1 -1
  113. package/core/built/admin/assets/{explore-UY10Egsp.js → explore-nnRr1Fja.js} +1 -1
  114. package/core/built/admin/assets/feature-flag-overrides-context-DQjdJFAk.js +1 -0
  115. package/core/built/admin/assets/{feature-image-placeholder-D1iF_8bc.js → feature-image-placeholder-BrIHmPs8.js} +1 -1
  116. package/core/built/admin/assets/{feed-81C8mJWR.js → feed-BNUcNu-W.js} +1 -1
  117. package/core/built/admin/assets/feedback-DJ4Zb9rZ.js +1 -0
  118. package/core/built/admin/assets/{field-Dihp5p18.js → field-C93_Mg6j.js} +1 -1
  119. package/core/built/admin/assets/filter-sources-CGJb4C5r.js +1 -0
  120. package/core/built/admin/assets/{filters-DirqNXjH.js → filters--kKP-EC8.js} +1 -1
  121. package/core/built/admin/assets/filters-DxA_a4FP.js +1 -0
  122. package/core/built/admin/assets/{first-promoter-modal-CT6MxYZb.js → first-promoter-modal-BYDtrz2S.js} +1 -1
  123. package/core/built/admin/assets/focus-koenig-editor-on-bottom-click-BbSnGOtK.js +1 -0
  124. package/core/built/admin/assets/{ghost-8eabfc1ece81b03cf7b90780d31487e8.css → ghost-8fd5bb799356bbefb254210ba7e1236d.css} +1 -1
  125. package/core/built/admin/assets/{ghost-c2848508292937415f20f5a830eea59e.js → ghost-b4e8a403baba61905cd7560e30b9732d.js} +43 -27
  126. package/core/built/admin/assets/{ghost-dark-a7bebe2c561f55369dcf29f4c820f7ff.css → ghost-dark-cac0cb2d5bb78e9bd14d8d1c2768ed45.css} +1 -1
  127. package/core/built/admin/assets/{gift-link-modal-CQVAye17.js → gift-link-modal-B7u5bD4e.js} +1 -1
  128. package/core/built/admin/assets/{gift-links-DLDS7ljO.js → gift-links-CfLSnst2.js} +1 -1
  129. package/core/built/admin/assets/growth-Cd1uO9d2.js +1 -0
  130. package/core/built/admin/assets/growth-aG32xfdE.js +3 -0
  131. package/core/built/admin/assets/{history-modal-CFd1Hvx6.js → history-modal-Df8lW8h-.js} +1 -1
  132. package/core/built/admin/assets/hooks-Cy_-oZ4o.js +2 -0
  133. package/core/built/admin/assets/{html-field-CJBCLTvv.js → html-field-DA4eU7eq.js} +1 -1
  134. package/core/built/admin/assets/{images-scfkWZiK.js → images-KXmyO3Ss.js} +1 -1
  135. package/core/built/admin/assets/{inbox-Mcp4DXZN.js → inbox-gJHG7_xd.js} +6 -6
  136. package/core/built/admin/assets/index-BHHXtR5C.css +2 -0
  137. package/core/built/admin/assets/index-CgMCwsxN.js +4 -0
  138. package/core/built/admin/assets/index.es-CY6-yuw9.js +1 -0
  139. package/core/built/admin/assets/{input-group-CMhe2DvY.js → input-group-BE8rM2y1.js} +1 -1
  140. package/core/built/admin/assets/{integrations-Bjbu86Z0.js → integrations-B4kuRBFY.js} +1 -1
  141. package/core/built/admin/assets/{invite-user-modal-DfheMXs0.js → invite-user-modal-B4CuNcx4.js} +1 -1
  142. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +2 -2
  143. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +2 -2
  144. package/core/built/admin/assets/{koenig-lexical-DBSqAuiI.js → koenig-lexical-CGXb0F8o.js} +2 -2
  145. package/core/built/admin/assets/koenig-loader-BeM5rFPX.js +2 -0
  146. package/core/built/admin/assets/{kpi-card-DBRMfGOW.js → kpi-card-B21aToe8.js} +1 -1
  147. package/core/built/admin/assets/{kpi-card-DFafD1qq.js → kpi-card-pz6Wv4Ae.js} +1 -1
  148. package/core/built/admin/assets/{kpi-helpers-Cv8i8hns.js → kpi-helpers-Dq5jelmP.js} +1 -1
  149. package/core/built/admin/assets/{kpi-tabs-BJItvLYm.js → kpi-tabs-DEZHpKUt.js} +1 -1
  150. package/core/built/admin/assets/{label-BnSCvffu.js → label-OLCzze8N.js} +1 -1
  151. package/core/built/admin/assets/label-picker-BigOvMPV.js +1 -0
  152. package/core/built/admin/assets/{labels-CH3Kn8RV.js → labels-Dr0SgUQD.js} +1 -1
  153. package/core/built/admin/assets/layout-DUTL8SH5.js +1 -0
  154. package/core/built/admin/assets/lib-7QPTI0FS.js +1 -0
  155. package/core/built/admin/assets/link-helpers-BRAg9SCj.js +1 -0
  156. package/core/built/admin/assets/links-BDHPTlyj.js +1 -0
  157. package/core/built/admin/assets/{member-custom-fields-DDQV6QeG.js → member-custom-fields-TRTHCAz9.js} +1 -1
  158. package/core/built/admin/assets/member-detail-b6dRwc3C.js +1 -0
  159. package/core/built/admin/assets/members-Czt5lJSc.js +4 -0
  160. package/core/built/admin/assets/{moderation-AgCIEso4.js → moderation-ZWefD9uH.js} +1 -1
  161. package/core/built/admin/assets/{multi-select-combobox-BcITkUVr.js → multi-select-combobox-CT13MTo-.js} +1 -1
  162. package/core/built/admin/assets/navigation-modal-C8FEhBK5.js +1 -0
  163. package/core/built/admin/assets/newsletter-5VYW4RyJ.js +1 -0
  164. package/core/built/admin/assets/newsletter-detail-modal-ChjC0ZqH.js +1 -0
  165. package/core/built/admin/assets/{newsletter-emails-DKzwafuh.js → newsletter-emails-DZH6I-PY.js} +1 -1
  166. package/core/built/admin/assets/{newsletters-BRBb_uQC.js → newsletters-DOC9KBcX.js} +1 -1
  167. package/core/built/admin/assets/newsletters-Rq1M3GD-.js +1 -0
  168. package/core/built/admin/assets/{note-DyGHtS9a.js → note-DIV-Pojr.js} +1 -1
  169. package/core/built/admin/assets/{notifications-ZgWniKna.js → notifications-s20-H49V.js} +1 -1
  170. package/core/built/admin/assets/{offers-9J1CSiLy.js → offers--e2nGvkW.js} +1 -1
  171. package/core/built/admin/assets/{offers-container-modal-B-E8TIWr.js → offers-container-modal-BmG5M5Tv.js} +1 -1
  172. package/core/built/admin/assets/onboarding-CUuy9unR.js +1 -0
  173. package/core/built/admin/assets/{onboarding-CzIsre-d.js → onboarding-pXyct0Jm.js} +1 -1
  174. package/core/built/admin/assets/{onboarding-route-CaavZulg.js → onboarding-route-CK4pcXoR.js} +1 -1
  175. package/core/built/admin/assets/overview-CaPsciMs.js +1 -0
  176. package/core/built/admin/assets/overview-a8GfcsKX.js +1 -0
  177. package/core/built/admin/assets/{page-header-De0VzKBi.js → page-header-DM_KyoFI.js} +1 -1
  178. package/core/built/admin/assets/{pagemenu-B5KKCpbA.js → pagemenu-vgZVUVKR.js} +1 -1
  179. package/core/built/admin/assets/pages-CjDY2CBI.js +1 -0
  180. package/core/built/admin/assets/pages-route-BzKZYdV5.js +1 -0
  181. package/core/built/admin/assets/{pintura-modal-BZ2J9w3n.js → pintura-modal-DExCF1ii.js} +1 -1
  182. package/core/built/admin/assets/{portal-frame-B6Hr9wHc.js → portal-frame-Cqanidq4.js} +1 -1
  183. package/core/built/admin/assets/portal-modal-oinBgA27.js +1 -0
  184. package/core/built/admin/assets/post-analytics-C5oJ1dWV.js +1 -0
  185. package/core/built/admin/assets/post-analytics-header-OATo3X_r.js +1 -0
  186. package/core/built/admin/assets/post-analytics-provider-tOpIVGT5.js +1 -0
  187. package/core/built/admin/assets/post-helpers-C88JBa4D.js +1 -0
  188. package/core/built/admin/assets/post-share-modal-DvhC1XgV.js +1 -0
  189. package/core/built/admin/assets/post-utils-DKF4mfuo.js +1 -0
  190. package/core/built/admin/assets/posts-list-screen-o4ZjbgS3.js +2 -0
  191. package/core/built/admin/assets/posts-pCPrhQeR.js +1 -0
  192. package/core/built/admin/assets/posts-route-9F--xdIb.js +1 -0
  193. package/core/built/admin/assets/{preferences-C5YJLp74.js → preferences--vNubsqD.js} +2 -2
  194. package/core/built/admin/assets/{preview-modal-BfeFqi5y.js → preview-modal-YYbzlYdO.js} +1 -1
  195. package/core/built/admin/assets/profile-BllKV3dR.js +1 -0
  196. package/core/built/admin/assets/radio-group-DL8GI8rt.js +1 -0
  197. package/core/built/admin/assets/{referrers-CnhCMWCs.js → referrers-D8oHPmDB.js} +1 -1
  198. package/core/built/admin/assets/router-provider-BSvTXgZY.js +1 -0
  199. package/core/built/admin/assets/schemas-BoYdB6YU.js +64 -0
  200. package/core/built/admin/assets/{select-cb0t_TAJ.js → select-v5YbA3Mw.js} +1 -1
  201. package/core/built/admin/assets/settings-PEsZupw1.js +4 -0
  202. package/core/built/admin/assets/{settings-breadcrumbs-DLzbRRSt.js → settings-breadcrumbs-NwPnCTC7.js} +1 -1
  203. package/core/built/admin/assets/{settings-DZqxR0Da.js → settings-u_s1CRkr.js} +1 -1
  204. package/core/built/admin/assets/{share-modal-D2-Bz1_I.js → share-modal-SskCmVGL.js} +1 -1
  205. package/core/built/admin/assets/{slack-modal-DYDTUria.js → slack-modal-XxSJiYgo.js} +1 -1
  206. package/core/built/admin/assets/{sort-button-VVeQjjbu.js → sort-button-Cx1KtINE.js} +1 -1
  207. package/core/built/admin/assets/{source-icon-Ck5_5Kgq.js → source-icon-Bdp9Im_5.js} +1 -1
  208. package/core/built/admin/assets/stats-D9PDLS3x.js +1 -0
  209. package/core/built/admin/assets/stats-view-W2g6Jsd-.js +1 -0
  210. package/core/built/admin/assets/{step-1-CsaBjeN4.js → step-1-BQYzvBzr.js} +1 -1
  211. package/core/built/admin/assets/{step-2-D2vnxOOM.js → step-2-xES32xJV.js} +1 -1
  212. package/core/built/admin/assets/{step-3-wBoLdGEb.js → step-3-DA_XK5kW.js} +2 -2
  213. package/core/built/admin/assets/{stripe-button-CDgLz0S0.js → stripe-button-CVsLHelt.js} +1 -1
  214. package/core/built/admin/assets/{stripe-connect-modal-CSjMJetP.js → stripe-connect-modal-ClmLOMGS.js} +1 -1
  215. package/core/built/admin/assets/style-Wd9nQubI.css +1 -0
  216. package/core/built/admin/assets/{table-Do6iQ83Q.js → table-BenqVupI.js} +1 -1
  217. package/core/built/admin/assets/{tabs-D2yWLMp_.js → tabs-eBBlxPp8.js} +1 -1
  218. package/core/built/admin/assets/tag-detail-Ce8Se2qd.js +2 -0
  219. package/core/built/admin/assets/tag-picker-C3UR-uJ-.js +1 -0
  220. package/core/built/admin/assets/tags-B-kJxCs7.js +1 -0
  221. package/core/built/admin/assets/{tags-zTFiKRpb.js → tags-ChfdwJyS.js} +1 -1
  222. package/core/built/admin/assets/{testimonials-modal-CtnZBJKl.js → testimonials-modal-9Q6fT06V.js} +1 -1
  223. package/core/built/admin/assets/tier-detail-modal-CDyYdqK7.js +1 -0
  224. package/core/built/admin/assets/tiers-BCpIOGQr.js +1 -0
  225. package/core/built/admin/assets/{toggle-group-ByUJsxwD.js → toggle-group-CviIkyok.js} +1 -1
  226. package/core/built/admin/assets/{topic-filter-BgC3g5_v.js → topic-filter-I2jCBGxm.js} +1 -1
  227. package/core/built/admin/assets/{transistor-modal-Drr0SNfo.js → transistor-modal-p53u3W8y.js} +1 -1
  228. package/core/built/admin/assets/{trend-badge-6ye93YAW.js → trend-badge-CideVzQd.js} +1 -1
  229. package/core/built/admin/assets/{unsplash-modal-p6AoQoWp.js → unsplash-modal-DY8UcKcE.js} +1 -1
  230. package/core/built/admin/assets/{use-analytics-data-CWCMAESo.js → use-analytics-data-DAIGcr2f.js} +1 -1
  231. package/core/built/admin/assets/{use-check-theme-limit-error-Cw3WQHy8.js → use-check-theme-limit-error-DRUjK4YM.js} +1 -1
  232. package/core/built/admin/assets/use-filter-params-JkZhIS8L.js +1 -0
  233. package/core/built/admin/assets/{use-filterable-api-CzXcpUh8.js → use-filterable-api-BVEVMrhZ.js} +1 -1
  234. package/core/built/admin/assets/{use-growth-stats-DCVG3s9w.js → use-growth-stats-937CUj6j.js} +1 -1
  235. package/core/built/admin/assets/use-host-limits-D0Dv3tKA.js +1 -0
  236. package/core/built/admin/assets/{use-limiter-D2WRRx0H.js → use-limiter-CohWfzvK.js} +1 -1
  237. package/core/built/admin/assets/{use-navigate-with-base-path-BHPA228f.js → use-navigate-with-base-path-BkxcPj5l.js} +1 -1
  238. package/core/built/admin/assets/use-pintura-config-xgytjU35.js +1 -0
  239. package/core/built/admin/assets/{use-pintura-editor-BfN1UwzH.js → use-pintura-editor-CaV1mbfO.js} +1 -1
  240. package/core/built/admin/assets/{use-post-referrers-Czg47m8s.js → use-post-referrers-BCQI7fDg.js} +1 -1
  241. package/core/built/admin/assets/{use-reply-chain-data-ns0caK8k.js → use-reply-chain-data-CYRhoaxY.js} +1 -1
  242. package/core/built/admin/assets/{use-router-history-entry-uldn7zJO.js → use-router-history-entry-NOKcd--l.js} +1 -1
  243. package/core/built/admin/assets/{use-setting-group-DpcuCUDg.js → use-setting-group-bLKMwoBT.js} +1 -1
  244. package/core/built/admin/assets/{use-settings-navigation-CZjGrhsp.js → use-settings-navigation-B-qrriKD.js} +1 -1
  245. package/core/built/admin/assets/{use-simple-pagination-DzJWobPR.js → use-simple-pagination-CNPd6Rf6.js} +1 -1
  246. package/core/built/admin/assets/use-staff-users-pRIMIyiW.js +1 -0
  247. package/core/built/admin/assets/{use-tinybird-query-CSnGXzZh.js → use-tinybird-query-CmdbCS9X.js} +1 -1
  248. package/core/built/admin/assets/{use-tinybird-token-DTOKRR7e.js → use-tinybird-token-KLne235s.js} +1 -1
  249. package/core/built/admin/assets/{use-unsaved-changes-guard-CBzs-KPi.js → use-unsaved-changes-guard-7-ug0JdH.js} +1 -1
  250. package/core/built/admin/assets/use-upgrade-route-Dm_qqKr0.js +1 -0
  251. package/core/built/admin/assets/{use-url-input-DFr8lCbS.js → use-url-input-fvp-TpPx.js} +1 -1
  252. package/core/built/admin/assets/user-detail-modal-D3KlGYv-.js +1 -0
  253. package/core/built/admin/assets/{users-Cg-OeGzC.js → users-DVNWrqg9.js} +1 -1
  254. package/core/built/admin/assets/{vendor-5753232c7d6ffb3c44e1eb0a02133953.js → vendor-2dd263291938d407802568d3357ec69e.js} +19 -17
  255. package/core/built/admin/assets/{virtual-list-BW-padMe.js → virtual-list-CZ3RK2Yf.js} +1 -1
  256. package/core/built/admin/assets/{web-C1v33ehA.js → web-ClEJsCAj.js} +2 -2
  257. package/core/built/admin/assets/web-X9rdnrtq.js +1 -0
  258. package/core/built/admin/assets/{zapier-modal-BBFfI6Ml.js → zapier-modal-DfVhV17j.js} +1 -1
  259. package/core/built/admin/index.html +19 -18
  260. package/core/server/adapters/jobs/InMemoryJobsBackend.js +74 -29
  261. package/core/server/api/endpoints/authentication.js +1 -2
  262. package/core/server/api/endpoints/authors-public.js +15 -5
  263. package/core/server/api/endpoints/emails.js +13 -0
  264. package/core/server/api/endpoints/index.js +8 -0
  265. package/core/server/api/endpoints/member-metafields-members.js +23 -0
  266. package/core/server/api/endpoints/member-metafields.js +33 -20
  267. package/core/server/api/endpoints/members-account.js +42 -0
  268. package/core/server/api/endpoints/newsletters-public.js +10 -1
  269. package/core/server/api/endpoints/pages-public.js +15 -5
  270. package/core/server/api/endpoints/posts-public.js +15 -5
  271. package/core/server/api/endpoints/tags-public.js +22 -3
  272. package/core/server/api/endpoints/tiers-checkout-config.js +2 -2
  273. package/core/server/api/endpoints/tiers-public.js +38 -1
  274. package/core/server/api/endpoints/users.js +2 -2
  275. package/core/server/api/endpoints/utils/api-filter-utils.js +170 -3
  276. package/core/server/api/endpoints/utils/public-cache-keys.js +3 -0
  277. package/core/server/api/endpoints/utils/serializers/input/authors.js +2 -0
  278. package/core/server/api/endpoints/utils/serializers/input/members.js +16 -2
  279. package/core/server/api/endpoints/utils/serializers/input/pages.js +2 -0
  280. package/core/server/api/endpoints/utils/serializers/input/posts.js +2 -0
  281. package/core/server/api/endpoints/utils/serializers/input/tags.js +2 -0
  282. package/core/server/api/endpoints/utils/serializers/output/emails.js +7 -0
  283. package/core/server/api/endpoints/utils/serializers/output/index.js +4 -0
  284. package/core/server/api/endpoints/utils/serializers/output/member-metafields.js +3 -3
  285. package/core/server/api/endpoints/utils/serializers/output/members-account.js +19 -0
  286. package/core/server/api/endpoints/utils/serializers/output/members-csv-transform.js +1 -1
  287. package/core/server/api/endpoints/utils/serializers/output/tiers.js +10 -2
  288. package/core/server/api/endpoints/utils/serializers/output/users.js +0 -10
  289. package/core/server/data/exporter/table-lists.js +3 -3
  290. package/core/server/data/migrations/versions/6.53/2026-07-15-20-22-53-add-members-custom-field-values.js +1 -1
  291. package/core/server/data/migrations/versions/6.57/2026-08-04-18-00-00-store-custom-field-values-as-leaf-rows.js +10 -1
  292. package/core/server/data/migrations/versions/6.63/2026-09-03-10-07-03-rename-custom-field-tables-to-metafields.js +169 -0
  293. package/core/server/data/migrations/versions/6.63/2026-09-03-11-03-31-remove-member-custom-field-read-permissions.js +30 -0
  294. package/core/server/data/schema/fixtures/fixtures.json +0 -11
  295. package/core/server/data/schema/lib/default-index-name.js +8 -11
  296. package/core/server/data/schema/schema.js +18 -18
  297. package/core/server/data/seeders/README.md +48 -0
  298. package/core/server/data/tinybird/pipes/mv_hits.pipe +86 -50
  299. package/core/server/lib/db-types/count.js +16 -0
  300. package/core/server/lib/validate-password.js +81 -120
  301. package/core/server/models/action.js +4 -4
  302. package/core/server/models/base/plugins/filtered-collection.js +16 -0
  303. package/core/server/models/member.js +6 -6
  304. package/core/server/models/user.js +1 -1
  305. package/core/server/services/automations/automations-api.js +1 -1
  306. package/core/server/services/automations/database-automations-repository.js +11 -4
  307. package/core/server/services/email-service/CONTEXT.md +37 -0
  308. package/core/server/services/email-service/README.md +42 -0
  309. package/core/server/services/email-service/batch-sending-service.js +2 -0
  310. package/core/server/services/email-service/email-controller.js +18 -2
  311. package/core/server/services/email-service/email-service-wrapper.js +3 -0
  312. package/core/server/services/email-service/sending-status-schema.js +21 -0
  313. package/core/server/services/email-service/sending-status-serializers.js +33 -0
  314. package/core/server/services/email-service/sending-status-service.js +47 -0
  315. package/core/server/services/email-service/sending-status.js +111 -0
  316. package/core/server/services/email-suppression-list/email-suppression-list.js +0 -33
  317. package/core/server/services/email-suppression-list/mailgun-email-suppression-list.js +6 -7
  318. package/core/server/services/gifts/README.md +2 -2
  319. package/core/server/services/gifts/constants.js +1 -1
  320. package/core/server/services/gifts/gift-service.js +19 -57
  321. package/core/server/services/gifts/index.js +0 -2
  322. package/core/server/services/jobs-service/index.js +8 -0
  323. package/core/server/services/jobs-service/jobs-service.js +52 -3
  324. package/core/server/services/jobs-service/register-job-handlers.js +13 -2
  325. package/core/server/services/members/account-service.js +98 -0
  326. package/core/server/services/members/api.js +4 -4
  327. package/core/server/services/members/import-export/export/exporter.js +20 -20
  328. package/core/server/services/members/import-export/import/completion-email.js +6 -6
  329. package/core/server/services/members/import-export/import/importer.js +13 -13
  330. package/core/server/services/members/import-export/index.js +7 -7
  331. package/core/server/services/members/members-api/members-api.js +26 -6
  332. package/core/server/services/members/members-api/repositories/member-repository.js +4 -4
  333. package/core/server/services/members/members-api/services/member-bread-service.js +45 -39
  334. package/core/server/services/members/members-ssr.js +18 -0
  335. package/core/server/services/members/middleware.js +95 -81
  336. package/core/server/services/members/service.js +70 -42
  337. package/core/server/services/members/utils.js +9 -0
  338. package/core/server/services/members-metafields/access.js +28 -0
  339. package/core/server/services/{members-custom-fields → members-metafields}/actions.js +5 -5
  340. package/core/server/services/members-metafields/bindings-service.js +147 -0
  341. package/core/server/services/{members-custom-fields → members-metafields}/codec.js +4 -4
  342. package/core/server/services/{members-custom-fields → members-metafields}/config.js +1 -1
  343. package/core/server/services/{members-custom-fields → members-metafields}/definitions-service.js +17 -23
  344. package/core/server/services/{members-custom-fields → members-metafields}/filter.js +9 -9
  345. package/core/server/services/{members-custom-fields → members-metafields}/index.js +16 -7
  346. package/core/server/services/{members-custom-fields → members-metafields}/key.js +1 -1
  347. package/core/server/services/{members-custom-fields → members-metafields}/models.js +4 -4
  348. package/core/server/services/members-metafields/namespaces.js +34 -0
  349. package/core/server/services/{members-custom-fields → members-metafields}/queries.js +1 -1
  350. package/core/server/services/{members-custom-fields → members-metafields}/schema.js +16 -12
  351. package/core/server/services/{members-custom-fields → members-metafields}/serializers.js +6 -6
  352. package/core/server/services/{members-custom-fields → members-metafields}/values-service.js +32 -22
  353. package/core/server/services/mentions/mention-sending-service.js +26 -9
  354. package/core/server/services/mentions/send-webmentions-job.js +18 -0
  355. package/core/server/services/mentions/service.js +1 -31
  356. package/core/server/services/stripe/services/webhook/checkout-session-event-service.js +2 -2
  357. package/core/server/services/stripe/stripe-service.js +4 -4
  358. package/core/server/services/tier-checkout-config/codec.js +2 -2
  359. package/core/server/services/tier-checkout-config/index.js +2 -1
  360. package/core/server/services/tier-checkout-config/models.js +2 -2
  361. package/core/server/services/tier-checkout-config/queries.js +8 -8
  362. package/core/server/services/tier-checkout-config/serializers.js +57 -0
  363. package/core/server/services/tier-checkout-config/service.js +1 -1
  364. package/core/server/services/tiers/service.js +3 -3
  365. package/core/server/services/url/router-filter.js +8 -10
  366. package/core/server/services/users.js +1 -19
  367. package/core/server/web/api/endpoints/admin/routes.js +1 -0
  368. package/core/server/web/members/account/index.js +2 -0
  369. package/core/server/web/members/account/routes.js +46 -0
  370. package/core/server/web/members/app.js +4 -18
  371. package/core/shared/config/defaults.json +1 -1
  372. package/core/shared/labs.js +4 -2
  373. package/package.json +22 -22
  374. package/pnpm-lock.yaml +513 -571
  375. package/pnpm-workspace.yaml +12 -12
  376. package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
  377. package/core/built/admin/assets/activitypub/layout-2-0bw6HN.js +0 -1
  378. package/core/built/admin/assets/automated-emails-D5VVMND9.js +0 -1
  379. package/core/built/admin/assets/automations-CzKt5fb8.js +0 -1
  380. package/core/built/admin/assets/chunk.598.7e056fabb47ce7dbd73f.js +0 -366
  381. package/core/built/admin/assets/comments-BLmCmyCs.js +0 -1
  382. package/core/built/admin/assets/custom-field-type-option-BddFlJFa.js +0 -1
  383. package/core/built/admin/assets/design-and-theme-modal-BSmo12Op.js +0 -2
  384. package/core/built/admin/assets/edit-profile-C5Asm4LA.js +0 -1
  385. package/core/built/admin/assets/editor-REokrzci.js +0 -8
  386. package/core/built/admin/assets/filter-sources-BO9xUPj7.js +0 -1
  387. package/core/built/admin/assets/filters-CRUWecfY.js +0 -1
  388. package/core/built/admin/assets/growth-BWIu-6xj.js +0 -3
  389. package/core/built/admin/assets/growth-DU29oxeA.js +0 -1
  390. package/core/built/admin/assets/hooks-CuEZV2-q.js +0 -2
  391. package/core/built/admin/assets/index-6MkPdCtr.js +0 -4
  392. package/core/built/admin/assets/index-Bn7QhcZu.css +0 -2
  393. package/core/built/admin/assets/index.es-CNnuNH0d.js +0 -1
  394. package/core/built/admin/assets/koenig-loader-aFQNlJlD.js +0 -2
  395. package/core/built/admin/assets/label-picker-KVoo91sh.js +0 -1
  396. package/core/built/admin/assets/layout-Bjv2Ll-5.js +0 -1
  397. package/core/built/admin/assets/link-helpers-MVDdnFCY.js +0 -1
  398. package/core/built/admin/assets/member-detail-CdJF6Agw.js +0 -1
  399. package/core/built/admin/assets/members-DjQbq9Z2.js +0 -4
  400. package/core/built/admin/assets/navigation-modal-BkT7b1M2.js +0 -1
  401. package/core/built/admin/assets/newsletter-BMMAuvgq.js +0 -1
  402. package/core/built/admin/assets/newsletter-detail-modal-0SCJ7Zpm.js +0 -1
  403. package/core/built/admin/assets/newsletters-DhNigJUh.js +0 -1
  404. package/core/built/admin/assets/onboarding-qg8Akovm.js +0 -1
  405. package/core/built/admin/assets/overview-BW8GLeYi.js +0 -1
  406. package/core/built/admin/assets/overview-BkXZNzaZ.js +0 -1
  407. package/core/built/admin/assets/pages-jgaFm69d.js +0 -1
  408. package/core/built/admin/assets/pages-route-CIUAQxtY.js +0 -1
  409. package/core/built/admin/assets/portal-modal-D4ceei3t.js +0 -1
  410. package/core/built/admin/assets/post-analytics-header-BYCsT0GP.js +0 -1
  411. package/core/built/admin/assets/post-analytics-ot7f6pih.js +0 -1
  412. package/core/built/admin/assets/post-analytics-provider-Bo1gmYaP.js +0 -1
  413. package/core/built/admin/assets/post-helpers-C5OQMBoi.js +0 -1
  414. package/core/built/admin/assets/post-share-modal-C-PaYZ_e.js +0 -1
  415. package/core/built/admin/assets/posts-DuGazgTb.js +0 -1
  416. package/core/built/admin/assets/posts-list-screen-CBGGgjjj.js +0 -2
  417. package/core/built/admin/assets/posts-route-D6xmS7Vf.js +0 -1
  418. package/core/built/admin/assets/profile-B8mx2yAu.js +0 -1
  419. package/core/built/admin/assets/radio-group-DczlLKOn.js +0 -1
  420. package/core/built/admin/assets/router-provider-B0gZyiGJ.js +0 -1
  421. package/core/built/admin/assets/schemas-DppqmpeJ.js +0 -64
  422. package/core/built/admin/assets/settings-DvfTNdHQ.js +0 -4
  423. package/core/built/admin/assets/stats-Rjmk5owg.js +0 -1
  424. package/core/built/admin/assets/stats-view-BGGmkmgv.js +0 -1
  425. package/core/built/admin/assets/tag-detail-BhXlOsCa.js +0 -2
  426. package/core/built/admin/assets/tags-ldukRApe.js +0 -1
  427. package/core/built/admin/assets/tier-detail-modal-BOs8e_G8.js +0 -1
  428. package/core/built/admin/assets/tiers-Nd_z4BZY.js +0 -1
  429. package/core/built/admin/assets/use-filter-params-BIni9taJ.js +0 -1
  430. package/core/built/admin/assets/use-host-limits-DZtR08oa.js +0 -1
  431. package/core/built/admin/assets/use-pintura-config-h-J0Lvta.js +0 -1
  432. package/core/built/admin/assets/use-staff-users-Csipb-O0.js +0 -1
  433. package/core/built/admin/assets/use-upgrade-route-DhRSo7at.js +0 -1
  434. package/core/built/admin/assets/user-detail-modal-B_iUClI6.js +0 -1
  435. package/core/built/admin/assets/web-C4BKzn2T.js +0 -1
  436. package/core/server/services/email-suppression-list/in-memory-email-suppression-list.js +0 -39
  437. package/core/server/services/members-custom-fields/bindings-service.js +0 -120
  438. /package/core/built/admin/assets/{chunk.492.f24d855d7e3f3aad261c.js.LICENSE.txt → chunk.901.4ccc639821020230bcca.js.LICENSE.txt} +0 -0
  439. /package/core/server/services/{members-custom-fields → members-metafields}/storage.js +0 -0
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MemberAccountService = void 0;
7
+ const lodash_1 = __importDefault(require("lodash"));
8
+ const members_metafields_1 = require("../members-metafields");
9
+ /**
10
+ * A member's own account: what they are shown about themselves, and what they may
11
+ * change.
12
+ *
13
+ * Separate from the request handlers that used to hold this, because none of it is
14
+ * a question about HTTP. Which fields a member may set is a fact about members, and
15
+ * the answer is the same whoever is asking.
16
+ *
17
+ * Takes a member id rather than a member. Everything here either writes or reads
18
+ * afresh, and a record loaded before a write is stale by the time the answer is
19
+ * built, so there is nothing a caller could usefully hand over.
20
+ */
21
+ /** What a member is allowed to change about themselves. */
22
+ const WRITABLE_FIELDS = [
23
+ 'name',
24
+ 'expertise',
25
+ 'subscribed',
26
+ 'newsletters',
27
+ 'enable_comment_notifications',
28
+ 'enable_updates_and_announcements',
29
+ ];
30
+ /**
31
+ * The relations a write needs loaded to work out what it is changing.
32
+ *
33
+ * Newsletters because the older `subscribed` flag is stored as a list of them, and
34
+ * the subscription chain because changing what a member is entitled to has to
35
+ * reconcile against what they are paying for.
36
+ */
37
+ const WRITE_RELATIONS = [
38
+ 'stripeSubscriptions',
39
+ 'stripeSubscriptions.customer',
40
+ 'stripeSubscriptions.stripePrice',
41
+ 'newsletters',
42
+ ];
43
+ class MemberAccountService {
44
+ #memberBREADService;
45
+ #members;
46
+ #emailSuppressionList;
47
+ #metafieldValues;
48
+ constructor({ memberBREADService, members, emailSuppressionList, metafieldValues, }) {
49
+ this.#memberBREADService = memberBREADService;
50
+ this.#members = members;
51
+ this.#emailSuppressionList = emailSuppressionList;
52
+ this.#metafieldValues = metafieldValues;
53
+ }
54
+ /** Everything a member is shown about themselves. */
55
+ async read(memberId) {
56
+ // As the member rather than as staff: how much of the extra fields a publisher
57
+ // defines is answered depends on which side of Ghost is asking.
58
+ return this.#memberBREADService.read({ id: memberId }, { metafieldsFor: members_metafields_1.MEMBERS });
59
+ }
60
+ /** Apply what a member asked to change about themselves, and say what they now hold. */
61
+ async edit(data, memberId) {
62
+ // Worked out before the member is touched, so a value the catalog refuses fails
63
+ // the whole request rather than leaving a member renamed with their answers
64
+ // rejected. The write below reconciles subscriptions with Stripe and sends
65
+ // events, none of which giving up halfway could undo.
66
+ const plannedMetafields = data.metafields === undefined
67
+ ? null
68
+ : await this.#metafieldValues.planWrite(this.#metafieldValues.unwrapWire(data.metafields), members_metafields_1.MEMBERS);
69
+ await this.#members.update(lodash_1.default.pick(data, WRITABLE_FIELDS), {
70
+ id: memberId,
71
+ withRelated: WRITE_RELATIONS,
72
+ });
73
+ if (plannedMetafields) {
74
+ // A member is recorded as the author of their own answers, and is the one
75
+ // writer whose changes leave nothing in the staff action log: that log
76
+ // records what staff did.
77
+ await this.#metafieldValues.applyWrite(memberId, plannedMetafields, {
78
+ writtenBy: { type: 'member', id: memberId },
79
+ });
80
+ }
81
+ // Read back rather than returning what was written: a member is told what
82
+ // Ghost now holds, which is not always what they sent. Setting the older
83
+ // `subscribed` flag, for one, is stored as a list of newsletters.
84
+ return this.read(memberId);
85
+ }
86
+ /**
87
+ * Let Ghost email this member again.
88
+ *
89
+ * Two records rather than one: the address is on a list the email provider also
90
+ * writes to, and the member carries a flag of their own. A member asking to hear
91
+ * from a site again means both.
92
+ */
93
+ async allowEmail(memberId, email) {
94
+ await this.#emailSuppressionList.removeEmail(email);
95
+ await this.#members.update({ email_disabled: false }, { id: memberId });
96
+ }
97
+ }
98
+ exports.MemberAccountService = MemberAccountService;
@@ -22,7 +22,7 @@ const emailSuppressionList = require('../email-suppression-list');
22
22
  const commentsService = require('../comments');
23
23
  const emailAddressService = require('../email-address');
24
24
  const giftService = require('../gifts');
25
- const customFieldsService = require('../members-custom-fields');
25
+ const metafieldsService = require('../members-metafields');
26
26
  const { t } = require('../i18n');
27
27
  const sentry = require('../../../shared/sentry');
28
28
 
@@ -271,10 +271,10 @@ function createApiInstance(config) {
271
271
  giftService,
272
272
  // Resolved here rather than passed as the module: the members service needs
273
273
  // the values service itself, and reading it at construction is what ties the
274
- // two together in boot order. Custom fields is initialised in initCore, the
274
+ // two together in boot order. Metafields is initialised in initCore, the
275
275
  // members API is built in initServices, so this is always the live instance.
276
- customFieldValues: customFieldsService.values,
277
- customFieldDefinitions: customFieldsService.definitions,
276
+ metafieldValues: metafieldsService.values,
277
+ metafieldDefinitions: metafieldsService.definitions,
278
278
  });
279
279
 
280
280
  return membersApiInstance;
@@ -8,7 +8,7 @@ const moment_1 = __importDefault(require("moment"));
8
8
  const node_stream_1 = require("node:stream");
9
9
  const logging = require('@tryghost/logging');
10
10
  const errors = require('@tryghost/errors');
11
- const { csvCellsForFields } = require('@tryghost/custom-field-types/csv');
11
+ const { csvCellsForFields } = require('@tryghost/metafield-types/csv');
12
12
  // The columns the export reads off the members table, checked against MemberDbRow so the
13
13
  // query cannot select a column the row type does not declare.
14
14
  const MEMBER_COLUMNS = ['id', 'email', 'name', 'note', 'status', 'created_at'];
@@ -32,22 +32,22 @@ function toExportCsvRow(row) {
32
32
  labels: namesToCsv(row.labels),
33
33
  tiers: namesToCsv(row.tiers),
34
34
  gift_id: row.gift_id || '',
35
- ...row.custom_field_cells,
35
+ ...row.metafield_cells,
36
36
  };
37
37
  }
38
38
  const BATCH_SIZE = 1000;
39
39
  // Streams the matching members as flat rows, each carrying its related data (tiers,
40
- // labels, subscription, gift, Stripe customer, custom fields) for the output serializer
41
- // to turn into CSV lines. The members aggregate and custom fields are reached only
40
+ // labels, subscription, gift, Stripe customer, metafields) for the output serializer
41
+ // to turn into CSV lines. The members aggregate and metafields are reached only
42
42
  // through the ports above, so nothing Bookshelf- or flag-shaped leaks into the export.
43
43
  class MembersCSVExporter {
44
44
  _knex;
45
45
  _members;
46
- _customFields;
47
- constructor({ knex, members, customFields }) {
46
+ _metafields;
47
+ constructor({ knex, members, metafields }) {
48
48
  this._knex = knex;
49
49
  this._members = members;
50
- this._customFields = customFields;
50
+ this._metafields = metafields;
51
51
  }
52
52
  async export(options = {}) {
53
53
  const start = Date.now();
@@ -75,7 +75,7 @@ class MembersCSVExporter {
75
75
  return processingTransform;
76
76
  }
77
77
  // products and labels are small, stable tables, read once up front as id->name
78
- // maps. Custom field definitions are read once too, which fixes the column set for
78
+ // maps. Metafield definitions are read once too, which fixes the column set for
79
79
  // the whole file: archiving a field mid-export cannot leave the header ragged. It
80
80
  // can still leave that field's cells empty from the batch after the archive
81
81
  // onwards, because the per-batch value read applies its own active filter.
@@ -94,8 +94,8 @@ class MembersCSVExporter {
94
94
  return acc;
95
95
  }, {}));
96
96
  logging.info({ event: { name: 'members-export.reference_data_read' }, durationMs: Date.now() - start }, 'Read the products and labels an export names');
97
- const activeCustomFields = await this._customFields.activeDefinitions();
98
- return { allProducts, allLabels, activeCustomFields };
97
+ const activeMetafields = await this._metafields.activeDefinitions();
98
+ return { allProducts, allLabels, activeMetafields };
99
99
  }
100
100
  // Group the member stream into batches so the related-data reads are one query per
101
101
  // batch rather than one per member.
@@ -121,7 +121,7 @@ class MembersCSVExporter {
121
121
  }
122
122
  // Each flattened row is pushed individually so a batch's rows do not pile up in memory.
123
123
  createProcessingTransform(reference) {
124
- const assembleRelatedData = (memberIds) => this.assembleRelatedData(memberIds, reference.activeCustomFields);
124
+ const assembleRelatedData = (memberIds) => this.assembleRelatedData(memberIds, reference.activeMetafields);
125
125
  const flattenBatch = (members, related) => this.flattenBatch(members, related, reference);
126
126
  return new node_stream_1.Transform({
127
127
  objectMode: true,
@@ -140,11 +140,11 @@ class MembersCSVExporter {
140
140
  },
141
141
  });
142
142
  }
143
- // One query per related table for the whole batch, not one per member. Custom field
143
+ // One query per related table for the whole batch, not one per member. Metafield
144
144
  // values are read only when there are columns to fill.
145
- async assembleRelatedData(memberIds, activeCustomFields) {
145
+ async assembleRelatedData(memberIds, activeMetafields) {
146
146
  const knex = this._knex;
147
- const [tiers, labels, stripeCustomers, subscriptions, gifts, customFieldValuesMap] = await Promise.all([
147
+ const [tiers, labels, stripeCustomers, subscriptions, gifts, metafieldValuesMap] = await Promise.all([
148
148
  knex('members_products')
149
149
  .select('member_id', knex.raw('GROUP_CONCAT(product_id) as tiers'))
150
150
  .whereIn('member_id', memberIds)
@@ -162,8 +162,8 @@ class MembersCSVExporter {
162
162
  .select('id', 'redeemer_member_id')
163
163
  .where('status', 'redeemed')
164
164
  .whereIn('redeemer_member_id', memberIds),
165
- activeCustomFields.length > 0
166
- ? this._customFields.valuesForMembers(memberIds)
165
+ activeMetafields.length > 0
166
+ ? this._metafields.valuesForMembers(memberIds)
167
167
  : new Map(),
168
168
  ]);
169
169
  return {
@@ -178,12 +178,12 @@ class MembersCSVExporter {
178
178
  row.redeemer_member_id,
179
179
  row.id,
180
180
  ])),
181
- customFieldValuesMap,
181
+ metafieldValuesMap,
182
182
  };
183
183
  }
184
184
  flattenBatch(members, related, reference) {
185
- const { tiersMap, labelsMap, stripeCustomerMap, subscribedSet, giftIdMap, customFieldValuesMap, } = related;
186
- const { allProducts, allLabels, activeCustomFields } = reference;
185
+ const { tiersMap, labelsMap, stripeCustomerMap, subscribedSet, giftIdMap, metafieldValuesMap } = related;
186
+ const { allProducts, allLabels, activeMetafields } = reference;
187
187
  return members.map((row) => {
188
188
  const tierConcat = tiersMap.get(row.id);
189
189
  const tierIds = tierConcat ? tierConcat.split(',') : [];
@@ -202,7 +202,7 @@ class MembersCSVExporter {
202
202
  // only knowable from the database. Every member carries a cell for every
203
203
  // active field's column, so a member with no values still contributes the
204
204
  // full set -- the CSV header is taken from whichever row streams first.
205
- custom_field_cells: csvCellsForFields(activeCustomFields, customFieldValuesMap.get(row.id) || {}),
205
+ metafield_cells: csvCellsForFields(activeMetafields, metafieldValuesMap.get(row.id) || {}),
206
206
  };
207
207
  });
208
208
  }
@@ -36,7 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.default = buildImportEmail;
37
37
  const csv_1 = require("../csv");
38
38
  const email_template_1 = __importStar(require("./email-template"));
39
- const csv_2 = require("@tryghost/custom-field-types/csv");
39
+ const csv_2 = require("@tryghost/metafield-types/csv");
40
40
  // Turn an ORM validation error into copy a member manager can act on. Presentation
41
41
  // only: the API response keeps the raw messages, and just the emailed report is
42
42
  // rewritten. Takes one reason at a time, so a rewrite matching to the end of its input
@@ -55,11 +55,11 @@ function humaniseError(row) {
55
55
  function stringifyLabels(labels) {
56
56
  return labels.map((label) => (typeof label === 'string' ? label : label.name)).join(',');
57
57
  }
58
- function customFieldCells(row) {
59
- return Object.fromEntries(Object.entries(row).filter(([column]) => (0, csv_2.isCustomFieldColumn)(column)));
58
+ function metafieldCells(row) {
59
+ return Object.fromEntries(Object.entries(row).filter(([column]) => (0, csv_2.isMetafieldColumn)(column)));
60
60
  }
61
61
  // Shape a failed import row into its fixed error-report cells, with the raw ORM message
62
- // rewritten into copy the member manager can act on. Custom field cells are merged on by
62
+ // rewritten into copy the member manager can act on. Metafield cells are merged on by
63
63
  // buildErrorReport, which owns the dynamic column set.
64
64
  function toErrorReportRow(row) {
65
65
  return {
@@ -84,9 +84,9 @@ function toErrorReportRow(row) {
84
84
  // come from the shaper's keys, so the type stays the single source.
85
85
  function buildErrorReport(errors) {
86
86
  const memberColumns = Object.keys(toErrorReportRow(errors[0])).filter((column) => column !== 'error');
87
- const customColumns = [...new Set(errors.flatMap((row) => Object.keys(customFieldCells(row))))];
87
+ const customColumns = [...new Set(errors.flatMap((row) => Object.keys(metafieldCells(row))))];
88
88
  const columns = [...memberColumns, ...customColumns, 'error'];
89
- const rows = errors.map((row) => ({ ...toErrorReportRow(row), ...customFieldCells(row) }));
89
+ const rows = errors.map((row) => ({ ...toErrorReportRow(row), ...metafieldCells(row) }));
90
90
  return (0, csv_1.serialize)(rows, { columns });
91
91
  }
92
92
  // The one email an import sends, whatever became of it. What the publisher is told and
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const moment_timezone_1 = __importDefault(require("moment-timezone"));
7
7
  const completion_email_1 = __importDefault(require("./completion-email"));
8
8
  const csv_1 = require("../csv");
9
- const csv_2 = require("@tryghost/custom-field-types/csv");
9
+ const csv_2 = require("@tryghost/metafield-types/csv");
10
10
  const metrics = require('@tryghost/metrics');
11
11
  const errors = require('@tryghost/errors');
12
12
  const logging = require('@tryghost/logging');
@@ -17,7 +17,7 @@ const messages = {
17
17
  giftCannotCombineWithImportTier: 'Cannot specify both gift_id and import_tier.',
18
18
  giftCannotCombineWithComplimentary: 'Cannot specify both gift_id and complimentary_plan.',
19
19
  giftReassignFailed: 'Failed to reassign gift to member.',
20
- customFieldWriteFailed: 'Failed to save the custom field values for this member.',
20
+ metafieldWriteFailed: 'Failed to save the custom field values for this member.',
21
21
  };
22
22
  // Columns whose presence makes a row slow to import (they reach out to Stripe), so
23
23
  // a file carrying any of them is deferred regardless of size. The routing decision
@@ -50,13 +50,13 @@ class MembersCSVImporter {
50
50
  _tiers;
51
51
  _stripe;
52
52
  _gifts;
53
- _customFields;
53
+ _metafields;
54
54
  _email;
55
55
  _report;
56
56
  _addJob;
57
57
  _getTimezone;
58
58
  _getInlineThreshold;
59
- constructor({ knex, readRows, spool, members, tiers, stripe, gifts, customFields, email, report, addJob, getTimezone, getInlineThreshold, }) {
59
+ constructor({ knex, readRows, spool, members, tiers, stripe, gifts, metafields, email, report, addJob, getTimezone, getInlineThreshold, }) {
60
60
  this._knex = knex;
61
61
  this._readRows = readRows;
62
62
  this._spool = spool;
@@ -64,7 +64,7 @@ class MembersCSVImporter {
64
64
  this._tiers = tiers;
65
65
  this._stripe = stripe;
66
66
  this._gifts = gifts;
67
- this._customFields = customFields;
67
+ this._metafields = metafields;
68
68
  this._email = email;
69
69
  this._report = report;
70
70
  this._addJob = addJob;
@@ -166,14 +166,14 @@ class MembersCSVImporter {
166
166
  return {
167
167
  defaultTier: await this._tiers.getDefault(),
168
168
  // Empty when the feature is off, so a carried-through column is dropped.
169
- activeCustomFields: await this._customFields.activeFields(),
169
+ activeMetafields: await this._metafields.activeFields(),
170
170
  globalLabels: [{ name: labelName }, ...extraLabels],
171
171
  };
172
172
  }
173
173
  // Must not throw: once a row has committed, an import that failed halfway is not one
174
174
  // that never ran.
175
175
  async writeRows(rows, prepared) {
176
- const { defaultTier, activeCustomFields } = prepared;
176
+ const { defaultTier, activeMetafields } = prepared;
177
177
  const tierIdCache = new Map();
178
178
  const archivableStripePriceIds = [];
179
179
  // Copied per row: the member model stamps ids and trims names onto these in
@@ -199,12 +199,12 @@ class MembersCSVImporter {
199
199
  }));
200
200
  }
201
201
  }
202
- // Validate the row's custom field values before the transaction opens.
202
+ // Validate the row's metafield values before the transaction opens.
203
203
  // planWrite only reads, and it throws on an invalid value to fail the row
204
204
  // before any member write -- so there is no reason to hold a transaction
205
205
  // across it, and doing so would deadlock the single-connection SQLite pool.
206
- const customFieldPlan = activeCustomFields.length > 0
207
- ? await namingTheColumn(() => this._customFields.planWrite((0, csv_2.fieldValuesFromCsvRow)(activeCustomFields, row, csv_1.stripFormulaGuard)))
206
+ const metafieldPlan = activeMetafields.length > 0
207
+ ? await namingTheColumn(() => this._metafields.planWrite((0, csv_2.fieldValuesFromCsvRow)(activeMetafields, row, csv_1.stripFormulaGuard)))
208
208
  : [];
209
209
  trx = await this._knex.transaction(undefined, { doNotRejectOnRollback: false });
210
210
  const options = { transacting: trx, context: IMPORT_CONTEXT };
@@ -307,7 +307,7 @@ class MembersCSVImporter {
307
307
  }
308
308
  // On the row's transaction, so the values commit or roll back with the member.
309
309
  try {
310
- await this._customFields.applyWrite(member.id, customFieldPlan, trx);
310
+ await this._metafields.applyWrite(member.id, metafieldPlan, trx);
311
311
  }
312
312
  catch (writeError) {
313
313
  // planWrite passed every value before the transaction opened, so a failure
@@ -315,7 +315,7 @@ class MembersCSVImporter {
315
315
  // will have written a query into; the publisher gets a sentence instead, in a
316
316
  // file they open next to a spreadsheet.
317
317
  this._report(writeError);
318
- throw new errors.DataImportError({ message: tpl(messages.customFieldWriteFailed) });
318
+ throw new errors.DataImportError({ message: tpl(messages.metafieldWriteFailed) });
319
319
  }
320
320
  await trx.commit();
321
321
  imported += 1;
@@ -327,7 +327,7 @@ class MembersCSVImporter {
327
327
  .filter((message) => typeof message === 'string');
328
328
  const errorMessage = reasons.join('\n');
329
329
  // trx is unset if the row failed before the transaction opened (a bad
330
- // custom field value or gift combination). A rejected rollback must not
330
+ // metafield value or gift combination). A rejected rollback must not
331
331
  // escape: rows before this one are already committed, and a throw leaving
332
332
  // here would be read as an import that never wrote anything.
333
333
  if (trx) {
@@ -56,12 +56,12 @@ function makeImporter(deps) {
56
56
  transacting: options.transacting,
57
57
  }),
58
58
  };
59
- const customFields = {
60
- activeFields: async () => deps.customFields.definitions.browse(),
61
- planWrite: (values) => deps.customFields.values.planWrite(values),
59
+ const metafields = {
60
+ activeFields: async () => deps.metafields.definitions.browse(),
61
+ planWrite: (values) => deps.metafields.values.planWrite(values),
62
62
  // Every value the import writes came out of the file, whichever column carried it.
63
63
  // An import has no id to give until runs are tracked, so it names its kind only.
64
- applyWrite: (memberId, plan, executor) => deps.customFields.values.applyWrite(memberId, plan, {
64
+ applyWrite: (memberId, plan, executor) => deps.metafields.values.applyWrite(memberId, plan, {
65
65
  writtenBy: { type: 'import', id: null },
66
66
  executor,
67
67
  }),
@@ -91,7 +91,7 @@ function makeImporter(deps) {
91
91
  productRepository: deps.productRepository,
92
92
  }),
93
93
  gifts,
94
- customFields,
94
+ metafields,
95
95
  email,
96
96
  report,
97
97
  addJob: deps.addJob,
@@ -100,7 +100,7 @@ function makeImporter(deps) {
100
100
  });
101
101
  }
102
102
  // Build the members CSV exporter. The same composition root from the other direction:
103
- // knex and the members id lookup are wired here, and the custom fields definitions and
103
+ // knex and the members id lookup are wired here, and the metafields definitions and
104
104
  // values services are injected (boot builds them before this one).
105
105
  function makeExporter({ definitions, values, }) {
106
106
  const exporter = new exporter_1.default({
@@ -118,7 +118,7 @@ function makeExporter({ definitions, values, }) {
118
118
  return page.data.map((member) => member.id);
119
119
  },
120
120
  },
121
- customFields: {
121
+ metafields: {
122
122
  // Boot builds the definitions and values services before this one, so they
123
123
  // are always present -- no not-initialised state to guard.
124
124
  activeDefinitions: async () => definitions.browse(),
@@ -7,6 +7,8 @@ const PaymentsService = require('./services/payments-service');
7
7
  const TokenService = require('./services/token-service');
8
8
  const GeolocationService = require('./services/geolocation-service');
9
9
  const MemberBREADService = require('./services/member-bread-service');
10
+ const metafields = require('../../members-metafields');
11
+ const { MemberAccountService } = require('../account-service');
10
12
  const MemberRepository = require('./repositories/member-repository');
11
13
  const NextPaymentCalculator = require('./services/next-payment-calculator');
12
14
 
@@ -70,8 +72,8 @@ module.exports = function MembersAPI({
70
72
  commentsService,
71
73
  emailAddressService,
72
74
  giftService,
73
- customFieldValues,
74
- customFieldDefinitions,
75
+ metafieldValues,
76
+ metafieldDefinitions,
75
77
  }) {
76
78
  const tokenService = new TokenService({
77
79
  privateKey,
@@ -153,8 +155,8 @@ module.exports = function MembersAPI({
153
155
  nextPaymentCalculator,
154
156
  commentsService,
155
157
  giftService,
156
- customFieldValues,
157
- customFieldDefinitions,
158
+ metafieldValues,
159
+ metafieldDefinitions,
158
160
  });
159
161
 
160
162
  const geolocationService = new GeolocationService();
@@ -356,11 +358,27 @@ module.exports = function MembersAPI({
356
358
  }
357
359
 
358
360
  async function getMemberIdentityData(email) {
359
- return memberBREADService.read({ email }, { withCustomFields: false });
361
+ return memberBREADService.read({ email }, { metafieldsFor: null });
362
+ }
363
+
364
+ const account = new MemberAccountService({
365
+ memberBREADService,
366
+ members: users,
367
+ emailSuppressionList,
368
+ metafieldValues: metafields.values,
369
+ });
370
+
371
+ async function getMemberIdentity(transientId) {
372
+ if (!transientId) {
373
+ return null;
374
+ }
375
+
376
+ const member = await users.get({ transient_id: transientId });
377
+ return member ? { id: member.id, email: member.get('email') } : null;
360
378
  }
361
379
 
362
380
  async function getMemberIdentityDataFromTransientId(transientId) {
363
- return memberBREADService.read({ transient_id: transientId }, { withCustomFields: false });
381
+ return memberBREADService.read({ transient_id: transientId }, { metafieldsFor: null });
364
382
  }
365
383
 
366
384
  async function cycleTransientId(memberId) {
@@ -500,6 +518,7 @@ module.exports = function MembersAPI({
500
518
  getMemberIdentityToken,
501
519
  getMemberEntitlementToken,
502
520
  getMemberIdentityDataFromTransientId,
521
+ getMemberIdentity,
503
522
  getMemberIdentityData,
504
523
  cycleTransientId,
505
524
  setMemberGeolocationFromIp,
@@ -508,6 +527,7 @@ module.exports = function MembersAPI({
508
527
  sendEmailWithMagicLink,
509
528
  getMagicLink,
510
529
  members: users,
530
+ account,
511
531
  memberBREADService,
512
532
  events: eventRepository,
513
533
  productRepository,
@@ -878,10 +878,10 @@ module.exports = class MemberRepository {
878
878
  (n) => n.attributes.status === 'archived',
879
879
  );
880
880
 
881
- if (archivedNewsletters.length > 0) {
882
- // if (!memberData.newsletters) {
883
- // memberData.newsletters = [];
884
- // }
881
+ // bookshelf-relations only touches the join table when the key is present,
882
+ // so an update that does not set newsletters leaves them all attached and
883
+ // has nothing to preserve.
884
+ if (memberData.newsletters && archivedNewsletters.length > 0) {
885
885
  archivedNewsletters.forEach((n) => memberData.newsletters.push(n));
886
886
  }
887
887
  }