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
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toCheckoutConfigResponse = exports.CheckoutConfigInput = void 0;
4
+ exports.requirementsByTier = requirementsByTier;
4
5
  const zod_1 = require("zod");
5
- const field_ports_1 = require("../stripe/services/checkout/field-ports");
6
- const allowed_countries_1 = require("../stripe/services/checkout/allowed-countries");
6
+ const checkout_1 = require("@tryghost/checkout");
7
7
  const models_1 = require("./models");
8
8
  // Every country Stripe will take, sent at once, was measured as accepted — so the only
9
9
  // ceiling is the list itself, and a request naming more than there are countries is naming
10
- // something twice.
11
- const MAX_ALLOWED_COUNTRIES = allowed_countries_1.STRIPE_ALLOWED_COUNTRIES.length;
10
+ // something twice. A request that means all of them omits the list instead.
11
+ const MAX_ALLOWED_COUNTRIES = checkout_1.STRIPE_ALLOWED_COUNTRIES.length;
12
12
  const QuestionInput = zod_1.z.object({
13
13
  key: zod_1.z.string().min(1, { error: 'Every checkout question needs a custom field key.' }),
14
14
  label: zod_1.z.string().trim().min(1).nullish(),
@@ -21,7 +21,7 @@ const CountryCode = zod_1.z
21
21
  .trim()
22
22
  .regex(/^[A-Za-z]{2}$/, { error: 'Enter a 2-letter country code, like US.' })
23
23
  .toUpperCase()
24
- .refine(allowed_countries_1.isStripeAllowedCountry, {
24
+ .refine(checkout_1.isStripeAllowedCountry, {
25
25
  error: 'Stripe will not ship to that country, so a checkout cannot offer it.',
26
26
  });
27
27
  /**
@@ -37,8 +37,8 @@ const Destination = zod_1.z.strictObject({ custom_field_key: CustomFieldKey }, {
37
37
  exports.CheckoutConfigInput = zod_1.z.strictObject({
38
38
  custom_fields: zod_1.z
39
39
  .array(QuestionInput)
40
- .max(field_ports_1.MAX_CHECKOUT_CUSTOM_FIELDS, {
41
- error: `A checkout can ask at most ${field_ports_1.MAX_CHECKOUT_CUSTOM_FIELDS} questions.`,
40
+ .max(checkout_1.MAX_CHECKOUT_CUSTOM_FIELDS, {
41
+ error: `A checkout can ask at most ${checkout_1.MAX_CHECKOUT_CUSTOM_FIELDS} questions.`,
42
42
  })
43
43
  .refine((questions) => new Set(questions.map((question) => question.key)).size === questions.length, { error: 'This checkout already asks for that field.' })
44
44
  .optional(),
@@ -47,10 +47,14 @@ exports.CheckoutConfigInput = zod_1.z.strictObject({
47
47
  zod_1.z.strictObject({ collect: zod_1.z.literal(false) }),
48
48
  zod_1.z.strictObject({
49
49
  collect: zod_1.z.literal(true),
50
+ // Absent means everywhere the processor ships. Empty is refused rather than
51
+ // read as everywhere: a publisher who cleared the list said something, and it
52
+ // was not "deliver worldwide".
50
53
  allowed_countries: zod_1.z
51
54
  .array(CountryCode, { error: 'Choose at least one country you deliver to.' })
52
55
  .min(1, { error: 'Choose at least one country you deliver to.' })
53
- .max(MAX_ALLOWED_COUNTRIES),
56
+ .max(MAX_ALLOWED_COUNTRIES)
57
+ .optional(),
54
58
  name: Destination,
55
59
  address: Destination,
56
60
  }),
@@ -75,7 +79,8 @@ const CollectionResource = zod_1.z.object({
75
79
  });
76
80
  const ShippingResource = zod_1.z.object({
77
81
  collect: zod_1.z.literal(true),
78
- allowed_countries: zod_1.z.array(zod_1.z.string()),
82
+ /** Absent means everywhere, the same way it does on the way in. */
83
+ allowed_countries: zod_1.z.array(zod_1.z.string()).optional(),
79
84
  name: zod_1.z.object({ custom_field_key: zod_1.z.string() }),
80
85
  address: zod_1.z.object({ custom_field_key: zod_1.z.string() }),
81
86
  });
@@ -102,7 +107,9 @@ exports.toCheckoutConfigResponse = zod_1.z
102
107
  ? {
103
108
  shipping: {
104
109
  collect: true,
105
- allowed_countries: config.shipping.allowedCountries,
110
+ ...(config.shipping.allowedCountries
111
+ ? { allowed_countries: config.shipping.allowedCountries }
112
+ : {}),
106
113
  name: { custom_field_key: config.shipping.nameCustomFieldKey },
107
114
  address: { custom_field_key: config.shipping.addressCustomFieldKey },
108
115
  },
@@ -120,3 +127,59 @@ exports.toCheckoutConfigResponse = zod_1.z
120
127
  })),
121
128
  }))
122
129
  .pipe(CheckoutConfigResponse);
130
+ /**
131
+ * What a tier asks a member for, as the tier payload carries it.
132
+ *
133
+ * The same rows as the publisher's resource above, minus everything about where a value
134
+ * lands. A member supplies a delivery address rather than a value for a named field, and
135
+ * which field holds it is the publisher's business; naming it here would invite a client
136
+ * to write there directly. The tax number goes too, because the processor keeps one
137
+ * against the customer it invoices and Ghost never stores it. So do the checkout
138
+ * questions, which a tier change does not draw.
139
+ *
140
+ * Not named for the collection, deliberately: a collection in this domain is a collected
141
+ * thing together with the field it lands in, and that second half is exactly the part
142
+ * this drops.
143
+ */
144
+ const TierRequirements = zod_1.z.object({
145
+ /**
146
+ * A block appears only when the tier asks for that thing, and says so as well, the same
147
+ * way the publisher's resource does. Presence and the flag agree, so a client may read
148
+ * whichever it finds clearer.
149
+ *
150
+ * Neither says whether a thing may be skipped, because nothing here may be: everything
151
+ * a tier requires is required. Collection a member could decline is the change that
152
+ * would need a field of its own rather than a new reading of these two.
153
+ */
154
+ shipping: zod_1.z
155
+ .object({
156
+ collect: zod_1.z.literal(true),
157
+ /** Absent means everywhere the processor ships, the same as for a publisher. */
158
+ allowed_countries: zod_1.z.array(zod_1.z.string()).optional(),
159
+ })
160
+ .optional(),
161
+ phone: zod_1.z.object({ collect: zod_1.z.literal(true) }).optional(),
162
+ });
163
+ /**
164
+ * Keyed by tier, because the payload this joins onto is a list of tiers and a lookup is
165
+ * the only thing it needs. Tiers a publisher has never set up are absent, and a tier that
166
+ * collects only a tax number resolves to nothing asked.
167
+ */
168
+ function requirementsByTier(configs) {
169
+ return new Map(configs.map((config) => [
170
+ config.tierId,
171
+ TierRequirements.parse({
172
+ ...(config.shipping
173
+ ? {
174
+ shipping: {
175
+ collect: true,
176
+ ...(config.shipping.allowedCountries
177
+ ? { allowed_countries: config.shipping.allowedCountries }
178
+ : {}),
179
+ },
180
+ }
181
+ : {}),
182
+ ...(config.phone ? { phone: { collect: true } } : {}),
183
+ }),
184
+ ]));
185
+ }
@@ -7,12 +7,11 @@ exports.TierCheckoutConfigService = void 0;
7
7
  const bson_objectid_1 = __importDefault(require("bson-objectid"));
8
8
  const errors_1 = __importDefault(require("@tryghost/errors"));
9
9
  const zod_1 = require("zod");
10
- const schema_1 = require("../members-custom-fields/schema");
11
- const field_ports_1 = require("../stripe/services/checkout/field-ports");
10
+ const schema_1 = require("../members-metafields/schema");
11
+ const checkout_1 = require("@tryghost/checkout");
12
12
  const codec_1 = require("./codec");
13
13
  const queries_1 = require("./queries");
14
14
  const models_1 = require("./models");
15
- const destinations_1 = require("./destinations");
16
15
  const serializers_1 = require("./serializers");
17
16
  /**
18
17
  * A request states its settings in named sections: one for shipping, one for phone. Each
@@ -26,8 +25,8 @@ const serializers_1 = require("./serializers");
26
25
  * save that the publisher believes they have turned off.
27
26
  */
28
27
  const BLOCK_PORTS = {
29
- shipping: [field_ports_1.STRIPE_PORT.shippingName, field_ports_1.STRIPE_PORT.shippingAddress],
30
- phone: [field_ports_1.STRIPE_PORT.phone],
28
+ shipping: [checkout_1.STRIPE_PORT.shippingName, checkout_1.STRIPE_PORT.shippingAddress],
29
+ phone: [checkout_1.STRIPE_PORT.phone],
31
30
  };
32
31
  class TierCheckoutConfigService {
33
32
  knex;
@@ -115,10 +114,10 @@ class TierCheckoutConfigService {
115
114
  async planCollection(stated) {
116
115
  const wanted = [];
117
116
  if (stated.shipping?.collect) {
118
- wanted.push({ port: field_ports_1.STRIPE_PORT.shippingName, key: stated.shipping.name.custom_field_key }, { port: field_ports_1.STRIPE_PORT.shippingAddress, key: stated.shipping.address.custom_field_key });
117
+ wanted.push({ port: checkout_1.STRIPE_PORT.shippingName, key: stated.shipping.name.custom_field_key }, { port: checkout_1.STRIPE_PORT.shippingAddress, key: stated.shipping.address.custom_field_key });
119
118
  }
120
119
  if (stated.phone?.collect) {
121
- wanted.push({ port: field_ports_1.STRIPE_PORT.phone, key: stated.phone.custom_field_key });
120
+ wanted.push({ port: checkout_1.STRIPE_PORT.phone, key: stated.phone.custom_field_key });
122
121
  }
123
122
  const bound = new Set(wanted.map(({ port }) => port));
124
123
  const clear = [];
@@ -129,7 +128,7 @@ class TierCheckoutConfigService {
129
128
  }
130
129
  const create = new Map();
131
130
  for (const { port, key } of wanted) {
132
- const wants = destinations_1.PORT_FIELD[port];
131
+ const wants = checkout_1.PORT_FIELD[port];
133
132
  const existing = await this.fields.findByKey(key);
134
133
  if (existing) {
135
134
  assertCollectableInto(port, existing, wants.type);
@@ -240,7 +239,9 @@ function assertCollectableInto(port, field, valueType) {
240
239
  }
241
240
  async function writeOptions(trx, productId, stated, now) {
242
241
  const all = zod_1.z.encode(codec_1.optionsCodec, {
243
- shippingAllowedCountries: stated.shipping?.collect ? stated.shipping.allowed_countries : [],
242
+ shippingAllowedCountries: stated.shipping?.collect
243
+ ? (stated.shipping.allowed_countries ?? null)
244
+ : null,
244
245
  taxNumber: stated.tax_number?.collect ?? false,
245
246
  });
246
247
  // Only the columns this request spoke about are written, so two requests changing
@@ -262,7 +263,7 @@ async function writeOptions(trx, productId, stated, now) {
262
263
  .merge({ ...columns, updated_at: now });
263
264
  }
264
265
  async function assertQuestionsAskable(db, questions) {
265
- const collides = questions.find((question) => (0, field_ports_1.isStripePort)(question.key));
266
+ const collides = questions.find((question) => (0, checkout_1.isStripePort)(question.key));
266
267
  if (collides) {
267
268
  throw new errors_1.default.ValidationError({
268
269
  message: `A field keyed ${collides.key} cannot be asked at checkout, because that is what this checkout calls something it collects for itself.`,
@@ -286,16 +287,16 @@ async function assertQuestionsAskable(db, questions) {
286
287
  property: 'checkout.custom_fields',
287
288
  });
288
289
  }
289
- if (!(0, field_ports_1.isCheckoutEligible)(field.type)) {
290
+ if (!(0, checkout_1.isCheckoutEligible)(field.type)) {
290
291
  throw new errors_1.default.ValidationError({
291
292
  message: `A ${field.type} field cannot be asked for at checkout.`,
292
293
  property: 'checkout.custom_fields',
293
294
  });
294
295
  }
295
296
  const prompt = question.label ?? field.name;
296
- if (prompt.length > field_ports_1.MAX_CHECKOUT_LABEL_LENGTH) {
297
+ if (prompt.length > checkout_1.MAX_CHECKOUT_LABEL_LENGTH) {
297
298
  throw new errors_1.default.ValidationError({
298
- message: `A checkout question can be at most ${field_ports_1.MAX_CHECKOUT_LABEL_LENGTH} characters. Give this one a shorter label.`,
299
+ message: `A checkout question can be at most ${checkout_1.MAX_CHECKOUT_LABEL_LENGTH} characters. Give this one a shorter label.`,
299
300
  property: 'checkout.custom_fields',
300
301
  });
301
302
  }
@@ -32,14 +32,14 @@ class TiersServiceWrapper {
32
32
  });
33
33
 
34
34
  // What a tier's checkout asks, kept beside the tier rather than inside it: these
35
- // rows are read live on every request, because deleting a custom field cascades a
35
+ // rows are read live on every request, because deleting a metafield cascades a
36
36
  // question away without the repository above ever seeing it, and a cached copy
37
37
  // would go on naming a field the site no longer has.
38
38
  //
39
- // Boot builds the custom fields services before this one, so both collaborators
39
+ // Boot builds the metafields services before this one, so both collaborators
40
40
  // are ready by the time this runs.
41
41
  const { TierCheckoutConfigService } = require('../tier-checkout-config');
42
- const { bindings, definitions } = require('../members-custom-fields');
42
+ const { bindings, definitions } = require('../members-metafields');
43
43
  this.checkout = new TierCheckoutConfigService({
44
44
  knex: models.Base.knex,
45
45
  // A binding is where a collected value lands, and the same rows are what a completed
@@ -2,7 +2,7 @@ const api = require('../../api').endpoints;
2
2
  const config = require('../../../shared/config');
3
3
  const logging = require('@tryghost/logging');
4
4
  const urlUtils = require('../../../shared/url-utils').default;
5
- const jobsService = require('../jobs');
5
+ const UpdateCheckJob = require('./jobs/update-check-job').default;
6
6
 
7
7
  const request = require('@tryghost/request');
8
8
  const ghostVersion = require('@tryghost/version');
@@ -66,7 +66,7 @@ module.exports = async ({
66
66
  await updateChecker.check();
67
67
  };
68
68
 
69
- module.exports.scheduleRecurringJobs = () => {
69
+ const scheduleRecurringJob = async (jobsService) => {
70
70
  // use a random seconds/minutes/hours value to avoid spikes to the update service API
71
71
  const s = Math.floor(Math.random() * 60); // 0-59
72
72
  const m = Math.floor(Math.random() * 60); // 0-59
@@ -74,17 +74,17 @@ module.exports.scheduleRecurringJobs = () => {
74
74
 
75
75
  const at = `${s} ${m} ${h} * * *`;
76
76
  logging.info(`[Background Job] update-check scheduled at ${at}`);
77
- jobsService.addJob({
78
- at, // Every day
79
- job: require('path').resolve(__dirname, 'run-update-check.js'),
80
- name: 'update-check',
81
- });
77
+ await jobsService.scheduleRecurring(new UpdateCheckJob(), { cron: at });
82
78
  };
83
79
 
84
- module.exports.scheduleBootJob = () => {
85
- logging.info('[Background Job] update-check-boot queued');
86
- jobsService.addJob({
87
- job: require('path').resolve(__dirname, 'run-update-check.js'),
88
- name: 'update-check-boot',
89
- });
80
+ const scheduleBootJob = async (jobsService) => {
81
+ logging.info('[Background Job] update-check boot run queued');
82
+ await jobsService.dispatch(new UpdateCheckJob());
83
+ };
84
+
85
+ module.exports.scheduleJobs = async (jobsService) => {
86
+ await scheduleRecurringJob(jobsService);
87
+ if (config.get('updateCheck:forceUpdate')) {
88
+ await scheduleBootJob(jobsService);
89
+ }
90
90
  };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const job_1 = require("../../jobs-service/job");
4
+ class UpdateCheckJob extends job_1.Job {
5
+ static type = 'update-check';
6
+ }
7
+ exports.default = UpdateCheckJob;
@@ -99,7 +99,7 @@ class UpdateCheckService {
99
99
  );
100
100
 
101
101
  err.context = tpl(messages.checkingForUpdatesFailedError);
102
- err.help = tpl(messages.checkingForUpdatesFailedHelp, { url: 'https://ghost.org/docs/' });
102
+ err.help = tpl(messages.checkingForUpdatesFailedHelp, { url: 'https://docs.ghost.org/' });
103
103
 
104
104
  this.logging.error(
105
105
  {
@@ -120,7 +120,7 @@ class UpdateCheckService {
120
120
  * Only the Ghost version is sent so the service can return the relevant
121
121
  * release and security notifications. No site data is collected.
122
122
  *
123
- * @see https://ghost.org/docs/concepts/config/#privacy
123
+ * @see https://docs.ghost.org/concepts/config/#privacy
124
124
  * @returns {Promise}
125
125
  */
126
126
  async updateCheckRequest() {
@@ -1,11 +1,14 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.EXPANSIONS = void 0;
4
7
  exports.routerTypeOf = routerTypeOf;
5
8
  exports.buildFilter = buildFilter;
6
9
  exports.filterMatches = filterMatches;
7
- const nql = require('@tryghost/nql');
8
- const logging = require('@tryghost/logging');
10
+ const nql_1 = __importDefault(require("@tryghost/nql"));
11
+ const logging_1 = __importDefault(require("@tryghost/logging"));
9
12
  // NQL evaluation for routes.yaml collection filters, kept in one place so the
10
13
  // forward lookup, ownership check and reverse lookup all decide membership the
11
14
  // same way.
@@ -17,7 +20,7 @@ exports.EXPANSIONS = [
17
20
  { key: 'primary_tag', replacement: 'primary_tag.slug' },
18
21
  { key: 'primary_author', replacement: 'primary_author.slug' },
19
22
  ];
20
- const PAGE_TRANSFORMER = nql.utils.mapKeyValues({
23
+ const PAGE_TRANSFORMER = nql_1.default.utils.mapKeyValues({
21
24
  key: { from: 'page', to: 'type' },
22
25
  values: [
23
26
  { from: false, to: 'post' },
@@ -45,7 +48,7 @@ function buildFilter(filter) {
45
48
  if (!filter) {
46
49
  return null;
47
50
  }
48
- return nql(filter, { expansions: exports.EXPANSIONS, transformer: PAGE_TRANSFORMER });
51
+ return (0, nql_1.default)(filter, { expansions: exports.EXPANSIONS, transformer: PAGE_TRANSFORMER });
49
52
  }
50
53
  // A null filter always matches; anything that throws is a non-match, not an
51
54
  // error.
@@ -65,12 +68,7 @@ function filterMatches(compiledFilter, record) {
65
68
  }
66
69
  catch (err) {
67
70
  const message = err instanceof Error ? err.message : String(err);
68
- logging.warn('NQL match failed', message);
71
+ logging_1.default.warn('NQL match failed', message);
69
72
  return false;
70
73
  }
71
74
  }
72
- module.exports = { EXPANSIONS: exports.EXPANSIONS, routerTypeOf, buildFilter, filterMatches };
73
- module.exports.EXPANSIONS = exports.EXPANSIONS;
74
- module.exports.routerTypeOf = routerTypeOf;
75
- module.exports.buildFilter = buildFilter;
76
- module.exports.filterMatches = filterMatches;
@@ -1,5 +1,4 @@
1
1
  // @ts-check
2
- const path = require('path');
3
2
  const ObjectId = require('bson-objectid').default;
4
3
 
5
4
  /**
@@ -7,11 +6,6 @@ const ObjectId = require('bson-objectid').default;
7
6
  */
8
7
  const DomainEvents = require('@tryghost/domain-events/lib/DomainEvents');
9
8
 
10
- /**
11
- * @typedef {Object} IdbBackup
12
- * @prop {() => Promise<string>} backup
13
- */
14
-
15
9
  /**
16
10
  * @typedef {Object} IModels
17
11
  * @prop {Object} Base
@@ -40,14 +34,12 @@ const DomainEvents = require('@tryghost/domain-events/lib/DomainEvents');
40
34
  class Users {
41
35
  /**
42
36
  * @param {Object} dependencies
43
- * @param {IdbBackup} dependencies.dbBackup
44
37
  * @param {IModels} dependencies.models
45
38
  * @param {IAuth} dependencies.auth
46
39
  * @param {Object} dependencies.apiMail
47
40
  * @param {Object} dependencies.apiSettings
48
41
  */
49
- constructor({ dbBackup, models, auth, apiMail, apiSettings }) {
50
- this.dbBackup = dbBackup;
42
+ constructor({ models, auth, apiMail, apiSettings }) {
51
43
  this.models = models;
52
44
  this.auth = auth;
53
45
  this.apiMail = apiMail;
@@ -183,14 +175,6 @@ class Users {
183
175
  * @returns
184
176
  */
185
177
  async destroyUser(frameOptions) {
186
- let filename = null;
187
- const backupPath = await this.dbBackup.backup();
188
-
189
- if (backupPath) {
190
- const parsedFileName = path.parse(backupPath);
191
- filename = `${parsedFileName.name}${parsedFileName.ext}`;
192
- }
193
-
194
178
  return this.models.Base.transaction(async (t) => {
195
179
  frameOptions.transacting = t;
196
180
 
@@ -234,8 +218,6 @@ class Users {
234
218
  }
235
219
 
236
220
  await this.models.User.destroy(Object.assign({ status: 'all' }, frameOptions));
237
-
238
- return filename;
239
221
  });
240
222
  }
241
223
  }
@@ -46,7 +46,7 @@ module.exports = function adminController(req, res) {
46
46
  throw new errors.IncorrectUsageError({
47
47
  message: tpl(messages.templateError.message, { templatePath }),
48
48
  context: tpl(messages.templateError.context),
49
- help: tpl(messages.templateError.help, { link: 'https://ghost.org/docs/install/source/' }),
49
+ help: tpl(messages.templateError.help, { link: 'https://docs.ghost.org/install/source/' }),
50
50
  err,
51
51
  });
52
52
  }
@@ -161,7 +161,7 @@ module.exports = function apiRoutes() {
161
161
  router.put(
162
162
  '/tiers/:id/checkout_config',
163
163
  mw.authAdminApi,
164
- labs.enabledMiddleware('membersCustomFields'),
164
+ labs.enabledMiddleware('stripeCheckoutCollection'),
165
165
  http(api.tiersCheckoutConfig.edit),
166
166
  );
167
167
 
@@ -195,36 +195,39 @@ module.exports = function apiRoutes() {
195
195
 
196
196
  router.get('/members/stripe_connect', mw.authAdminApi, http(api.membersStripeConnect.auth));
197
197
 
198
- // Member custom field definitions. Reading them is open: a site that has never
199
- // turned the flag on has none, so the answer is an empty list rather than a 404, and
200
- // Admin can ask without first knowing whether it may. Changing them is gated.
201
- // Registered before /members/:id so the literal path isn't captured by :id.
202
- router.get('/members/custom_fields', mw.authAdminApi, http(api.membersCustomFields.browse));
198
+ // Reading definitions is deliberately not behind the feature flag: Admin asks every site
199
+ // for them, and a site without the flag simply has none, so the answer is an empty list
200
+ // rather than a 404. Creating and changing them is flagged. Registered before /members/:id
201
+ // so the literal path is not captured as an id.
202
+ router.get('/members/metafields/:namespace', mw.authAdminApi, http(api.membersMetafields.browse));
203
203
  router.post(
204
- '/members/custom_fields',
204
+ '/members/metafields/:namespace',
205
205
  mw.authAdminApi,
206
206
  labs.enabledMiddleware('membersCustomFields'),
207
- http(api.membersCustomFields.add),
207
+ http(api.membersMetafields.add),
208
208
  );
209
- // A PUT on the collection sets the publisher's order for the whole list.
210
209
  router.put(
211
- '/members/custom_fields',
210
+ '/members/metafields/:namespace',
212
211
  mw.authAdminApi,
213
212
  labs.enabledMiddleware('membersCustomFields'),
214
- http(api.membersCustomFields.reorder),
213
+ http(api.membersMetafields.reorder),
214
+ );
215
+ router.get(
216
+ '/members/metafields/:namespace/:key',
217
+ mw.authAdminApi,
218
+ http(api.membersMetafields.read),
215
219
  );
216
- router.get('/members/custom_fields/:key', mw.authAdminApi, http(api.membersCustomFields.read));
217
220
  router.put(
218
- '/members/custom_fields/:key',
221
+ '/members/metafields/:namespace/:key',
219
222
  mw.authAdminApi,
220
223
  labs.enabledMiddleware('membersCustomFields'),
221
- http(api.membersCustomFields.edit),
224
+ http(api.membersMetafields.edit),
222
225
  );
223
226
  router.delete(
224
- '/members/custom_fields/:key',
227
+ '/members/metafields/:namespace/:key',
225
228
  mw.authAdminApi,
226
229
  labs.enabledMiddleware('membersCustomFields'),
227
- http(api.membersCustomFields.destroy),
230
+ http(api.membersMetafields.destroy),
228
231
  );
229
232
 
230
233
  router.get('/members/:id', mw.authAdminApi, http(api.members.read));
@@ -518,6 +521,7 @@ module.exports = function apiRoutes() {
518
521
  // ## Emails
519
522
  router.get('/emails', mw.authAdminApi, http(api.emails.browse));
520
523
  router.get('/emails/:id', mw.authAdminApi, http(api.emails.read));
524
+ router.get('/emails/:id/status', mw.authAdminApi, http(api.emails.sendingStatus));
521
525
  router.put('/emails/:id/retry', mw.authAdminApi, http(api.emails.retry));
522
526
  router.get('/emails/:id/batches', mw.authAdminApi, http(api.emails.browseBatches));
523
527
  router.get('/emails/:id/recipient-failures', mw.authAdminApi, http(api.emails.browseFailures));
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ module.exports = require('./routes');
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ const express = require('../../../../shared/express');
3
+ const bodyParser = require('body-parser');
4
+ const config = require('../../../../shared/config');
5
+ const { http } = require('@tryghost/api-framework');
6
+ const api = require('../../../api').endpoints;
7
+ const middleware = require('../../../services/members/middleware');
8
+ /**
9
+ * A member's own account, over HTTP.
10
+ *
11
+ * Everything reached by a signed-in member acting on their own record lives here,
12
+ * so how these routes authenticate is a property of the module rather than a line
13
+ * each one repeats. Establishing who is asking happens once; each route then says
14
+ * what it wants done when there is nobody.
15
+ *
16
+ * Endpoints reached by someone who is not signed in stay outside this: the
17
+ * unsubscribe links identify a member by a signed link, and changing an email
18
+ * address by a token in the body, because in both cases the person following them
19
+ * has no session.
20
+ */
21
+ module.exports = function accountRoutes() {
22
+ const router = express.Router('member-account');
23
+ router.use(middleware.loadMemberIdentity);
24
+ // Reading who you are. Answering with nothing when there is no member is the
25
+ // right answer rather than a failure: a themed page asks this on every view.
26
+ if (config.get('cacheMembersContent:enabled')) {
27
+ router.get('/',
28
+ // Not for this route's benefit. This configuration stamps a cookie saying
29
+ // what the reader is entitled to, so a cache can vary on it, and that needs
30
+ // the member's subscriptions rather than only their identity. It rides here
31
+ // because Portal asks this endpoint on every page load.
32
+ middleware.loadMemberSession, middleware.accessInfoSession, middleware.emptyWhenAnonymous, http(api.membersAccount.read));
33
+ }
34
+ else {
35
+ router.get('/', middleware.emptyWhenAnonymous, http(api.membersAccount.read));
36
+ }
37
+ router.put('/', bodyParser.json({ limit: '50mb' }), middleware.rejectWhenAnonymous, http(api.membersAccount.update));
38
+ // The fields a publisher has defined, which a member's client renders inputs
39
+ // from. Under the account because a member reads them to fill in their own, and
40
+ // refused to an unknown caller because what a publisher collects is their
41
+ // configuration rather than something the site announces.
42
+ router.get('/metafields/:namespace', middleware.rejectWhenAnonymous, http(api.memberMetafieldsMembers.browse));
43
+ // Letting Ghost email this member again after it stopped.
44
+ router.delete('/suppression', middleware.rejectWhenAnonymous, http(api.membersAccount.destroySuppression));
45
+ return router;
46
+ };
@@ -8,10 +8,10 @@ const audienceFeedbackService = require('../../services/audience-feedback');
8
8
  const middleware = membersService.middleware;
9
9
  const shared = require('../shared');
10
10
  const errorHandler = require('@tryghost/mw-error-handler');
11
- const config = require('../../../shared/config');
12
11
  const { http } = require('@tryghost/api-framework');
13
12
  const api = require('../../api').endpoints;
14
13
 
14
+ const accountRoutes = require('./account');
15
15
  const commentRouter = require('../comments');
16
16
  const announcementRouter = require('../announcement');
17
17
  const corsMiddleware = require('./middleware/cors');
@@ -57,21 +57,9 @@ module.exports = function setupMembersApp() {
57
57
  middleware.updateMemberNewsletters,
58
58
  );
59
59
 
60
- // Get and update member data
61
- // Caching members content is an experimental feature
62
- const shouldCacheMembersContent = config.get('cacheMembersContent:enabled');
63
- if (shouldCacheMembersContent) {
64
- membersApp.get(
65
- '/api/member',
66
- middleware.loadMemberSession,
67
- middleware.accessInfoSession,
68
- middleware.getMemberData,
69
- );
70
- } else {
71
- membersApp.get('/api/member', middleware.getMemberData);
72
- }
73
-
74
- membersApp.put('/api/member', bodyParser.json({ limit: '50mb' }), middleware.updateMemberData);
60
+ // A member's own account. Its routes and how they authenticate live together.
61
+ membersApp.use('/api/member', accountRoutes());
62
+
75
63
  membersApp.post('/api/member/email', bodyParser.json({ limit: '50mb' }), (req, res, next) =>
76
64
  membersService.api.middleware.updateEmailAddress(req, res, next),
77
65
  );
@@ -86,8 +74,6 @@ module.exports = function setupMembersApp() {
86
74
  );
87
75
 
88
76
  // Remove email from suppression list
89
- membersApp.delete('/api/member/suppression', middleware.deleteSuppression);
90
-
91
77
  // Manage session
92
78
  membersApp.get('/api/session', middleware.getIdentityToken);
93
79
  membersApp.delete('/api/session', bodyParser.json({ limit: '5mb' }), middleware.deleteSession);
@@ -80,7 +80,7 @@
80
80
  "members": {
81
81
  "contentApiAccess": [],
82
82
  "paymentProcessors": [],
83
- "customFields": {
83
+ "metafields": {
84
84
  "maxDefinitions": 100
85
85
  },
86
86
  "importer": {
@@ -11,7 +11,7 @@
11
11
  "connection": {
12
12
  "host": "127.0.0.1",
13
13
  "user": "root",
14
- "password": "",
14
+ "password": "root",
15
15
  "database": "ghost_testing"
16
16
  }
17
17
  },
@@ -27,7 +27,7 @@ const messages = {
27
27
  };
28
28
 
29
29
  // flags in this list always return `true`, allows quick global enable prior to full flag removal
30
- const GA_FEATURES = ['automationAnalytics', 'giftSubCustomization'];
30
+ const GA_FEATURES = ['automationAnalytics', 'tagDetailsReact'];
31
31
 
32
32
  // These features are considered publicly available and can be enabled/disabled by users
33
33
  const PUBLIC_BETA_FEATURES = [
@@ -42,20 +42,25 @@ const PUBLIC_BETA_FEATURES = [
42
42
  const PRIVATE_FEATURES = [
43
43
  'automations',
44
44
  'automationRunAnalytics',
45
+ 'automationsTinybirdSync',
45
46
  'stripeAutomaticTax',
46
47
  'importMemberTier',
47
48
  'csvContentImporter',
48
49
  'adminUIRefresh',
49
50
  'tagsX',
50
51
  'emailUniqueid',
52
+ 'improveSendingUI',
51
53
  'themeTranslation',
52
54
  'pictureImageFormats',
53
55
  'getHelperDeduplication',
54
56
  'membersCustomFields',
57
+ 'stripeCheckoutCollection',
58
+ 'membersImportRedesign',
55
59
  'paywallImprovements',
56
- 'tagDetailsReact',
57
60
  'selfServeArchives',
58
61
  'machinePayments',
62
+ 'postsListReact',
63
+ 'editorReact',
59
64
  ];
60
65
 
61
66
  module.exports.GA_KEYS = [...GA_FEATURES];