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
@@ -4,12 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.actingContext = actingContext;
7
- exports.recordCustomFieldAction = recordCustomFieldAction;
7
+ exports.recordMetafieldAction = recordMetafieldAction;
8
8
  const logging_1 = __importDefault(require("@tryghost/logging"));
9
9
  /**
10
10
  * Who is acting, read off an API frame's context.
11
11
  *
12
- * Here rather than in each endpoint, because two resources now record custom field history
12
+ * Here rather than in each endpoint, because two resources now record metafield history
13
13
  * and a second reading of the same shape is a second chance to disagree about it. An
14
14
  * integration and a user are both actors; a request that is neither — a webhook, a job —
15
15
  * has none, and the history says so rather than guessing.
@@ -36,7 +36,7 @@ const COMMANDS = {
36
36
  delete: 'deleted',
37
37
  };
38
38
  // Best-effort action-log write: a failed action must never fail the command that triggered it.
39
- async function recordCustomFieldAction({ Action, context, verb, subject, details, }) {
39
+ async function recordMetafieldAction({ Action, context, verb, subject, details, }) {
40
40
  if (!context.actor) {
41
41
  return;
42
42
  }
@@ -55,12 +55,12 @@ async function recordCustomFieldAction({ Action, context, verb, subject, details
55
55
  }
56
56
  catch (err) {
57
57
  logging_1.default.error({
58
- event: { name: 'members.custom_fields.action_log_failed' },
58
+ event: { name: 'members.metafields.action_log_failed' },
59
59
  err,
60
60
  verb,
61
61
  subject,
62
62
  actorType: context.actor.type,
63
63
  actorId: context.actor.id,
64
- }, 'Failed to record a member custom field action');
64
+ }, 'Failed to record a member metafield action');
65
65
  }
66
66
  }
@@ -0,0 +1,147 @@
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.MetafieldBindingsService = void 0;
7
+ const bson_objectid_1 = __importDefault(require("bson-objectid"));
8
+ const logging_1 = __importDefault(require("@tryghost/logging"));
9
+ const access_1 = require("./access");
10
+ const schema_1 = require("./schema");
11
+ const FIELDS_TABLE = 'members_metafields';
12
+ const { CUSTOM_NAMESPACE } = require('@tryghost/metafield-types/identity');
13
+ const BINDINGS_TABLE = 'members_metafield_bindings';
14
+ /**
15
+ * Where a source sends what it collected: a `port` is the name that source uses for a
16
+ * thing, and the binding resolves it to one of the publisher's fields.
17
+ */
18
+ class MetafieldBindingsService {
19
+ knex;
20
+ values;
21
+ constructor({ knex, values }) {
22
+ this.knex = knex;
23
+ this.values = values;
24
+ }
25
+ async bind(db, productId, port, metafieldKey, now) {
26
+ const existing = await db(BINDINGS_TABLE).where({ product_id: productId, port }).first();
27
+ if (existing?.metafield_key === metafieldKey) {
28
+ await db(BINDINGS_TABLE).where('id', existing.id).update({ updated_at: now });
29
+ return existing.id;
30
+ }
31
+ if (existing) {
32
+ await db(BINDINGS_TABLE).where('id', existing.id).del();
33
+ }
34
+ const bindingId = new bson_objectid_1.default().toHexString();
35
+ await db(BINDINGS_TABLE).insert({
36
+ id: bindingId,
37
+ product_id: productId,
38
+ port,
39
+ metafield_key: metafieldKey,
40
+ created_at: now,
41
+ updated_at: now,
42
+ });
43
+ return bindingId;
44
+ }
45
+ /** Stops the writing. Whatever hangs off the binding cascades with it. */
46
+ async remove(db, productId, port) {
47
+ await db(BINDINGS_TABLE).where({ product_id: productId, port }).del();
48
+ }
49
+ /**
50
+ * Values a processor collected on Ghost's behalf and sent back.
51
+ *
52
+ * Nobody supplied these in a sense the site can name — a payment page asked, and a
53
+ * machine reported the answers — so what is recorded against them is the binding that
54
+ * routed each one. That resolves back to the tier that asked, what it was collected
55
+ * as, and the field it landed in, which is everything worth knowing about how the
56
+ * value arrived.
57
+ */
58
+ async writeCollected(memberId, productId, collected) {
59
+ return this.writeThrough(memberId, productId, collected, (binding) => ({
60
+ type: 'binding',
61
+ id: binding.bindingId,
62
+ }));
63
+ }
64
+ /**
65
+ * Values a member supplied about themselves, through the same ports a checkout uses.
66
+ *
67
+ * A member typing their own address into a form is answerable for it in a way no
68
+ * routing is, and a record saying a binding wrote it would be wrong. The member is the
69
+ * one whose record this is, so there is nobody else it could be.
70
+ */
71
+ async writeSuppliedByMember(memberId, productId, supplied) {
72
+ return this.writeThrough(memberId, productId, supplied, () => ({
73
+ type: 'member',
74
+ id: memberId,
75
+ }));
76
+ }
77
+ /**
78
+ * Values arrive in the order they are to be applied: where two land in one field, the
79
+ * last of them is what the field holds.
80
+ *
81
+ * Every value is attempted, and then the first failure is raised. Attempting them all
82
+ * is this method's business: one refused answer must not cost a publisher the address
83
+ * a courier needs, and the values have nothing to do with each other beyond arriving
84
+ * together. Whether the failure is worth acting on is the caller's, which is why it
85
+ * leaves here rather than being logged and forgotten — a checkout webhook has already
86
+ * taken the money and must never fail, while a member filling in a form is owed the
87
+ * news.
88
+ */
89
+ async writeThrough(memberId, productId, values, attribute) {
90
+ let failure;
91
+ for (const { port, value } of values) {
92
+ try {
93
+ // Inside, because working out where a value goes can fail the same way storing
94
+ // it can, and a value nobody could place is no more reason to abandon the rest
95
+ // than one nobody could store.
96
+ const destination = await this.resolve(productId, port);
97
+ if (!destination) {
98
+ continue;
99
+ }
100
+ await this.writeOne(memberId, destination, value, attribute);
101
+ }
102
+ catch (err) {
103
+ failure = failure ?? err;
104
+ }
105
+ }
106
+ if (failure) {
107
+ throw failure;
108
+ }
109
+ }
110
+ async writeOne(memberId, into, value, attribute) {
111
+ // Internal: what may be set is bounded by the binding rather than by who is
112
+ // looking. A port exists because a publisher pointed it at a field, and that
113
+ // decision is what admits the value, whoever supplied it.
114
+ const planned = await this.values.planWrite({ [`${CUSTOM_NAMESPACE}.${into.key}`]: value }, access_1.INTERNAL);
115
+ await this.values.applyWrite(memberId, planned, { writtenBy: attribute(into) });
116
+ }
117
+ async resolve(productId, port) {
118
+ const row = await this.knex(BINDINGS_TABLE)
119
+ .join(FIELDS_TABLE, `${BINDINGS_TABLE}.metafield_key`, `${FIELDS_TABLE}.key`)
120
+ .where(`${BINDINGS_TABLE}.product_id`, productId)
121
+ .where(`${BINDINGS_TABLE}.port`, port)
122
+ // An archived destination is still where this goes, and still not somewhere a value
123
+ // can land, so the write drops rather than waiting.
124
+ .where(`${FIELDS_TABLE}.status`, schema_1.FIELD_STATUS.active)
125
+ .select(`${BINDINGS_TABLE}.id as binding_id`, `${FIELDS_TABLE}.key`, `${FIELDS_TABLE}.type`)
126
+ .first();
127
+ if (!row) {
128
+ return null;
129
+ }
130
+ // Decoded rather than trusted: a join is a read boundary, and `type` is what decides
131
+ // how the collected value is read. Unreadable counts as unresolved rather than
132
+ // throwing, so one bad row skips its value the way an unbound port does instead of
133
+ // failing everything else the same checkout collected.
134
+ const bound = schema_1.DbBoundField.safeParse(row);
135
+ if (!bound.success) {
136
+ logging_1.default.warn({
137
+ event: { name: 'members.metafields.binding_unreadable' },
138
+ err: bound.error,
139
+ productId,
140
+ port,
141
+ }, 'A binding could not be read');
142
+ return null;
143
+ }
144
+ return { bindingId: bound.data.binding_id, key: bound.data.key, type: bound.data.type };
145
+ }
146
+ }
147
+ exports.MetafieldBindingsService = MetafieldBindingsService;
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.customFieldCodec = void 0;
3
+ exports.metafieldCodec = void 0;
4
4
  const zod_1 = require("zod");
5
- const identity_1 = require("@tryghost/custom-field-types/identity");
5
+ const identity_1 = require("@tryghost/metafield-types/identity");
6
6
  const case_keys_1 = require("../../lib/case-keys");
7
7
  const schema_1 = require("./schema");
8
8
  const models_1 = require("./models");
9
- exports.customFieldCodec = zod_1.z.codec(schema_1.DbCustomField, models_1.CustomField, {
10
- // DbCustomField validates `type` as the field-type enum, so the decoded row
9
+ exports.metafieldCodec = zod_1.z.codec(schema_1.DbMetafield, models_1.Metafield, {
10
+ // DbMetafield validates `type` as the field-type enum, so the decoded row
11
11
  // already carries a FieldType and camelKeys preserves it — no cast needed.
12
12
  decode: (row) => ({ ...(0, case_keys_1.camelKeys)(row), namespace: identity_1.CUSTOM_NAMESPACE }),
13
13
  encode: ({ namespace: _namespace, ...field }) => (0, case_keys_1.snakeKeys)(field),
@@ -22,7 +22,7 @@ const Ceiling = zod_1.z
22
22
  // rather than restated. Parsed eagerly because a missing or malformed value
23
23
  // there is our bug rather than an operator's, and should fail loudly at boot
24
24
  // instead of quietly becoming the fallback for everything below.
25
- const shippedCeiling = Ceiling.parse(require('../../../shared/config/defaults.json').members.customFields.maxDefinitions);
25
+ const shippedCeiling = Ceiling.parse(require('../../../shared/config/defaults.json').members.metafields.maxDefinitions);
26
26
  // A higher layer can override the shipped value with anything. Something
27
27
  // unreadable falls back to the shipped ceiling rather than throwing, because an
28
28
  // operator can correct this live and a bad value must not take the feature down
@@ -3,14 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.CustomFieldDefinitionsService = void 0;
6
+ exports.MetafieldDefinitionsService = 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 custom_field_types_1 = require("@tryghost/custom-field-types");
11
- const identity_1 = require("@tryghost/custom-field-types/identity");
10
+ const metafield_types_1 = require("@tryghost/metafield-types");
11
+ const identity_1 = require("@tryghost/metafield-types/identity");
12
12
  const codec_1 = require("./codec");
13
+ const namespaces_1 = require("./namespaces");
13
14
  const schema_1 = require("./schema");
15
+ const access_1 = require("./access");
14
16
  const queries_1 = require("./queries");
15
17
  const key_1 = require("./key");
16
18
  // The same NQL -> knex bridge Bookshelf's filter plugin uses, applied directly to
@@ -18,7 +20,7 @@ const key_1 = require("./key");
18
20
  // turns that into parametrised WHERE clauses. Neither needs a Bookshelf model.
19
21
  const nql = require('@tryghost/nql');
20
22
  const knexify = require('@tryghost/mongo-knex');
21
- const TABLE = 'members_custom_fields';
23
+ const TABLE = 'members_metafields';
22
24
  // Column limits come from the canonical schema — the same source the migration and
23
25
  // Bookshelf models read — so the service can never drift from the database. The
24
26
  // name cap turns an over-long input into a clean 422 (not a DB error), and the key
@@ -48,7 +50,7 @@ const FieldName = zod_1.z
48
50
  // The backend mints the key from the name, so create takes just a name and type.
49
51
  const AddFieldInput = zod_1.z.object({
50
52
  name: FieldName,
51
- type: custom_field_types_1.FieldTypeSchema,
53
+ type: metafield_types_1.FieldTypeSchema,
52
54
  });
53
55
  // A bound on the work one request can ask for, separate from how many definitions
54
56
  // a site may hold in total. Every definition in a batch costs several queries
@@ -77,9 +79,9 @@ const EditFieldInput = zod_1.z.object({
77
79
  name: FieldName.optional(),
78
80
  status: schema_1.FieldStatusSchema.optional(),
79
81
  key: zod_1.z.string().optional(),
80
- type: custom_field_types_1.FieldTypeSchema.optional(),
82
+ type: metafield_types_1.FieldTypeSchema.optional(),
81
83
  });
82
- class CustomFieldDefinitionsService {
84
+ class MetafieldDefinitionsService {
83
85
  knex;
84
86
  recordAction;
85
87
  getMaxDefinitions;
@@ -104,15 +106,7 @@ class CustomFieldDefinitionsService {
104
106
  isStored(namespace) {
105
107
  return namespace === identity_1.CUSTOM_NAMESPACE;
106
108
  }
107
- assertDefinable(namespace) {
108
- if (!this.isStored(namespace)) {
109
- throw new errors_1.default.ValidationError({
110
- message: `Fields cannot be defined in the "${namespace}" namespace.`,
111
- property: 'namespace',
112
- });
113
- }
114
- }
115
- async browse(options = {}) {
109
+ async browse(options = {}, audience = access_1.ADMIN) {
116
110
  if (options.namespace !== undefined && !this.isStored(options.namespace)) {
117
111
  return [];
118
112
  }
@@ -126,7 +120,7 @@ class CustomFieldDefinitionsService {
126
120
  const query = options.filter
127
121
  ? applyFilter(this.knex(TABLE), options.filter)
128
122
  : (0, queries_1.activeFields)(this.knex);
129
- return this.list(query);
123
+ return (0, access_1.readableFields)(audience, await this.list(query));
130
124
  }
131
125
  /**
132
126
  * Decode a definition query into the domain, in the publisher's order.
@@ -136,7 +130,7 @@ class CustomFieldDefinitionsService {
136
130
  */
137
131
  async list(query) {
138
132
  const rows = await (0, queries_1.inFieldOrder)(query).select('*');
139
- return rows.map((row) => zod_1.z.decode(codec_1.customFieldCodec, row));
133
+ return rows.map((row) => zod_1.z.decode(codec_1.metafieldCodec, row));
140
134
  }
141
135
  async read(namespace, key) {
142
136
  const [field] = this.isStored(namespace) ? await this.list((0, queries_1.fieldByKey)(this.knex, key)) : [];
@@ -156,7 +150,7 @@ class CustomFieldDefinitionsService {
156
150
  * key get distinct ones, exactly as if they had arrived as separate requests.
157
151
  */
158
152
  async add(context, namespace, input) {
159
- this.assertDefinable(namespace);
153
+ (0, namespaces_1.assertDefinable)(namespace);
160
154
  const requestedCount = Array.isArray(input) ? input.length : 0;
161
155
  const parsed = AddFieldsInput.safeParse(input);
162
156
  if (!parsed.success) {
@@ -276,7 +270,7 @@ class CustomFieldDefinitionsService {
276
270
  /** `read` for a caller that is deciding rather than serving: absent is an answer. */
277
271
  async findByKey(key, { executor = this.knex } = {}) {
278
272
  const row = await executor(TABLE).where('key', key).first();
279
- return row ? zod_1.z.decode(codec_1.customFieldCodec, row) : null;
273
+ return row ? zod_1.z.decode(codec_1.metafieldCodec, row) : null;
280
274
  }
281
275
  /** The same entry `add` writes. Only the caller knows its transaction committed. */
282
276
  async recordCreated(context, fields) {
@@ -335,7 +329,7 @@ class CustomFieldDefinitionsService {
335
329
  * Returns every definition, archived included, matching what the request named.
336
330
  */
337
331
  async reorder(context, namespace, input) {
338
- this.assertDefinable(namespace);
332
+ (0, namespaces_1.assertDefinable)(namespace);
339
333
  const parsed = ReorderInput.safeParse(input);
340
334
  if (!parsed.success) {
341
335
  const issue = parsed.error.issues[0];
@@ -399,7 +393,7 @@ class CustomFieldDefinitionsService {
399
393
  async readMany(db, keys) {
400
394
  const rows = await db(TABLE).whereIn('key', keys).select('*');
401
395
  const byKey = new Map(rows.map((row) => [row.key, row]));
402
- return keys.map((key) => zod_1.z.decode(codec_1.customFieldCodec, byKey.get(key)));
396
+ return keys.map((key) => zod_1.z.decode(codec_1.metafieldCodec, byKey.get(key)));
403
397
  }
404
398
  /**
405
399
  * Pick a free key from the name's base: `base`, then `base_2`, `base_3`, ...
@@ -551,7 +545,7 @@ class CustomFieldDefinitionsService {
551
545
  });
552
546
  }
553
547
  }
554
- exports.CustomFieldDefinitionsService = CustomFieldDefinitionsService;
548
+ exports.MetafieldDefinitionsService = MetafieldDefinitionsService;
555
549
  /**
556
550
  * The shape a stated key has to have. Minting derives one that is usable by
557
551
  * construction, so this is the check that path never needed: a caller stating its own
@@ -3,8 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.CUSTOM_FIELDS_RELATION = void 0;
7
- exports.createCustomFieldsFilterTransformer = createCustomFieldsFilterTransformer;
6
+ exports.METAFIELDS_RELATION = void 0;
7
+ exports.createMetafieldsFilterTransformer = createMetafieldsFilterTransformer;
8
8
  // Translates the metafield clauses of a members filter into a query over the
9
9
  // values table. A metafield is a publisher-defined field on a member; it is
10
10
  // addressed as `namespace.key`, and a composite value such as an address names
@@ -15,13 +15,13 @@ exports.createCustomFieldsFilterTransformer = createCustomFieldsFilterTransforme
15
15
  // metafields.key:'custom.company' // has a value
16
16
  // metafields.key:-'custom.shipping_address.country' // that part is not set
17
17
  //
18
- // The values table holds one row per stored value: `custom_field_key`, `path`
18
+ // The values table holds one row per stored value: `metafield_key`, `path`
19
19
  // (empty for a plain field, the part's name for one part of a composite) and
20
20
  // `value_text`. A filter addresses those columns directly, so each one becomes a
21
21
  // single $elemMatch over them — positive asserts a matching row exists, $not
22
22
  // asserts none does — with no lookup against the field definitions.
23
23
  const errors_1 = __importDefault(require("@tryghost/errors"));
24
- const identity_1 = require("@tryghost/custom-field-types/identity");
24
+ const identity_1 = require("@tryghost/metafield-types/identity");
25
25
  const RELATION = 'metafields';
26
26
  const PREFIX = `${RELATION}.`;
27
27
  const KEY_ATTRIBUTE = `${PREFIX}key`;
@@ -78,11 +78,11 @@ function parseLeafAddress(raw) {
78
78
  }
79
79
  return { key: identity.key, path: identity.partPath };
80
80
  }
81
- function createCustomFieldsFilterTransformer() {
81
+ function createMetafieldsFilterTransformer() {
82
82
  // One (maybe-negated) $elemMatch over the leaf columns: positive is "a leaf pinned
83
83
  // by these matches", `$not` is "no leaf does".
84
84
  function buildElemMatch(target, value, negate) {
85
- const match = { custom_field_key: target.key };
85
+ const match = { metafield_key: target.key };
86
86
  if (value !== undefined) {
87
87
  match.path = target.path ?? ROOT_PATH;
88
88
  match.value_text = value;
@@ -167,14 +167,14 @@ function createCustomFieldsFilterTransformer() {
167
167
  return (query) => transform(query);
168
168
  }
169
169
  /**
170
- * The Member filter relation that exposes custom field values. A member has many leaf
170
+ * The Member filter relation that exposes metafield values. A member has many leaf
171
171
  * rows (one per field, or per part of a composite field), and a predicate asks whether
172
172
  * one of them matches, so this joins the values table on member_id and mongo-knex emits
173
173
  * it as a correlated `members.id IN (…)` subquery — composing with every other member
174
174
  * filter.
175
175
  */
176
- exports.CUSTOM_FIELDS_RELATION = {
177
- tableName: 'members_custom_field_values',
176
+ exports.METAFIELDS_RELATION = {
177
+ tableName: 'members_metafield_values',
178
178
  tableNameAs: RELATION,
179
179
  type: 'oneToOne',
180
180
  joinFrom: 'member_id',
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.bindings = exports.values = exports.definitions = exports.actingContext = void 0;
3
+ exports.bindings = exports.values = exports.definitions = exports.readableFields = exports.canWrite = exports.MEMBERS = exports.INTERNAL = exports.ADMIN = exports.actingContext = void 0;
4
4
  exports.init = init;
5
5
  const definitions_service_1 = require("./definitions-service");
6
6
  const values_service_1 = require("./values-service");
@@ -9,6 +9,15 @@ const actions_1 = require("./actions");
9
9
  const config_1 = require("./config");
10
10
  var actions_2 = require("./actions");
11
11
  Object.defineProperty(exports, "actingContext", { enumerable: true, get: function () { return actions_2.actingContext; } });
12
+ // Which door a request came through, which is what decides how much of a member's
13
+ // answers it may see or change. Required wherever that is asked, so a new caller
14
+ // has to name itself rather than inherit an answer by default.
15
+ var access_1 = require("./access");
16
+ Object.defineProperty(exports, "ADMIN", { enumerable: true, get: function () { return access_1.ADMIN; } });
17
+ Object.defineProperty(exports, "INTERNAL", { enumerable: true, get: function () { return access_1.INTERNAL; } });
18
+ Object.defineProperty(exports, "MEMBERS", { enumerable: true, get: function () { return access_1.MEMBERS; } });
19
+ Object.defineProperty(exports, "canWrite", { enumerable: true, get: function () { return access_1.canWrite; } });
20
+ Object.defineProperty(exports, "readableFields", { enumerable: true, get: function () { return access_1.readableFields; } });
12
21
  function init() {
13
22
  // The three are constructed together below, so checking all of them keeps the "all or
14
23
  // none" invariant explicit rather than trusting one to stand in for the rest.
@@ -17,25 +26,25 @@ function init() {
17
26
  }
18
27
  const { knex } = require('../../data/db');
19
28
  const models = require('../../models');
20
- const recordAction = ({ context, verb, subject, details }) => (0, actions_1.recordCustomFieldAction)({ Action: models.Action, context, verb, subject, details });
29
+ const recordAction = ({ context, verb, subject, details }) => (0, actions_1.recordMetafieldAction)({ Action: models.Action, context, verb, subject, details });
21
30
  // Resolved here, not in the service: reading config is this module's job, and
22
31
  // the service is handed a number. A getter rather than a value because the
23
32
  // ceiling is an operator setting that can change between requests, and a Ghost
24
33
  // container holds no state across them.
25
34
  const config = require('../../../shared/config');
26
- exports.definitions = new definitions_service_1.CustomFieldDefinitionsService({
35
+ exports.definitions = new definitions_service_1.MetafieldDefinitionsService({
27
36
  knex,
28
37
  recordAction,
29
- getMaxDefinitions: () => (0, config_1.resolveMaxDefinitions)(config.get('members:customFields:maxDefinitions')),
38
+ getMaxDefinitions: () => (0, config_1.resolveMaxDefinitions)(config.get('members:metafields:maxDefinitions')),
30
39
  });
31
40
  // The values service reads the field definitions straight from the table, so
32
41
  // it needs knex and the same ceiling — no handle on the definitions service.
33
- exports.values = new values_service_1.CustomFieldValuesService({
42
+ exports.values = new values_service_1.MetafieldValuesService({
34
43
  knex,
35
- getMaxDefinitions: () => (0, config_1.resolveMaxDefinitions)(config.get('members:customFields:maxDefinitions')),
44
+ getMaxDefinitions: () => (0, config_1.resolveMaxDefinitions)(config.get('members:metafields:maxDefinitions')),
36
45
  });
37
46
  // Built after the values, which is what a binding routes into. It has no handle on the
38
47
  // definitions: making a field is not part of binding to one, so a caller that needs both
39
48
  // asks for both.
40
- exports.bindings = new bindings_service_1.CustomFieldBindingsService({ knex, values: exports.values });
49
+ exports.bindings = new bindings_service_1.MetafieldBindingsService({ knex, values: exports.values });
41
50
  }
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.KEY_CHARACTERS = void 0;
4
4
  exports.mintableKey = mintableKey;
5
- const identity_1 = require("@tryghost/custom-field-types/identity");
5
+ const identity_1 = require("@tryghost/metafield-types/identity");
6
6
  // Neither package ships types.
7
7
  const { stripInvisibleChars } = require('@tryghost/string');
8
8
  const unidecode = require('unidecode');
@@ -1,15 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CustomField = void 0;
3
+ exports.Metafield = void 0;
4
4
  const zod_1 = require("zod");
5
- const custom_field_types_1 = require("@tryghost/custom-field-types");
5
+ const metafield_types_1 = require("@tryghost/metafield-types");
6
6
  const schema_1 = require("./schema");
7
- exports.CustomField = zod_1.z.object({
7
+ exports.Metafield = zod_1.z.object({
8
8
  id: zod_1.z.string(),
9
9
  namespace: zod_1.z.string(),
10
10
  key: zod_1.z.string(),
11
11
  name: zod_1.z.string(),
12
- type: custom_field_types_1.FieldTypeSchema,
12
+ type: metafield_types_1.FieldTypeSchema,
13
13
  status: schema_1.FieldStatusSchema,
14
14
  createdAt: zod_1.z.date(),
15
15
  updatedAt: zod_1.z.date().nullable(),
@@ -0,0 +1,34 @@
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.definableByPublisher = definableByPublisher;
7
+ exports.assertDefinable = assertDefinable;
8
+ const errors_1 = __importDefault(require("@tryghost/errors"));
9
+ const identity_1 = require("@tryghost/metafield-types/identity");
10
+ /**
11
+ * Who may define fields in a namespace.
12
+ *
13
+ * This is a property of the namespace, not of whoever is asking, so it is settled before
14
+ * any question about the caller. Asking the caller first gets the order wrong in a way
15
+ * that shows: a request to define a field in a namespace nobody owns would be refused for
16
+ * want of a permission, telling the caller to go and get one, when no permission would
17
+ * have helped.
18
+ *
19
+ * The publisher owns `custom` and nothing owns anything else yet. An app owning its own
20
+ * namespace resolves here too, and will not resolve to a permission at all: the caller
21
+ * has to *be* that app rather than hold a role, which is why the staff permission stays
22
+ * named after the publisher's fields rather than after metafields at large.
23
+ */
24
+ function definableByPublisher(namespace) {
25
+ return namespace === identity_1.CUSTOM_NAMESPACE;
26
+ }
27
+ function assertDefinable(namespace) {
28
+ if (!definableByPublisher(namespace)) {
29
+ throw new errors_1.default.ValidationError({
30
+ message: `Fields cannot be defined in the "${namespace}" namespace.`,
31
+ property: 'namespace',
32
+ });
33
+ }
34
+ }
@@ -4,7 +4,7 @@ exports.activeFields = activeFields;
4
4
  exports.fieldByKey = fieldByKey;
5
5
  exports.inFieldOrder = inFieldOrder;
6
6
  const schema_1 = require("./schema");
7
- const FIELDS_TABLE = 'members_custom_fields';
7
+ const FIELDS_TABLE = 'members_metafields';
8
8
  // Archived fields must stay out of every read and write, and nothing in the database
9
9
  // enforces that — no constraint stops a value row referencing an archived field. A query
10
10
  // that forgets the filter is a silent bug, so the filter lives in one place.
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DbBoundField = exports.DbCustomFieldBinding = exports.DbCustomFieldLeaf = exports.DbCustomFieldValue = exports.WrittenBy = exports.DbCustomField = exports.FieldStatusSchema = exports.FIELD_STATUS = void 0;
3
+ exports.DbBoundField = exports.DbMetafieldBinding = exports.DbMetafieldLeaf = exports.DbMetafieldValue = exports.WrittenBy = exports.DbMetafield = exports.FieldStatusSchema = exports.FIELD_STATUS = void 0;
4
4
  const zod_1 = require("zod");
5
- const custom_field_types_1 = require("@tryghost/custom-field-types");
5
+ const metafield_types_1 = require("@tryghost/metafield-types");
6
6
  const date_1 = require("../../lib/db-types/date");
7
7
  // `archived` is soft: the field drops out of the values path but stays in the definition
8
8
  // list so it can be renamed, restored or deleted. Mirrors schema.js's `isIn` on the
@@ -11,11 +11,11 @@ exports.FIELD_STATUS = { active: 'active', archived: 'archived' };
11
11
  exports.FieldStatusSchema = zod_1.z.enum([exports.FIELD_STATUS.active, exports.FIELD_STATUS.archived]);
12
12
  // The single source for the read projection and the knex table type below. `type` parses
13
13
  // as the field-type enum, so the row carries the narrow type and no codec needs a cast.
14
- exports.DbCustomField = zod_1.z.object({
14
+ exports.DbMetafield = zod_1.z.object({
15
15
  id: zod_1.z.string(),
16
16
  key: zod_1.z.string(),
17
17
  name: zod_1.z.string(),
18
- type: custom_field_types_1.FieldTypeSchema,
18
+ type: metafield_types_1.FieldTypeSchema,
19
19
  status: exports.FieldStatusSchema,
20
20
  created_at: date_1.DbDate,
21
21
  updated_at: date_1.DbDate.nullable(),
@@ -23,7 +23,7 @@ exports.DbCustomField = zod_1.z.object({
23
23
  /**
24
24
  * How a value arrived, not who caused it: who edited a member's fields is already an
25
25
  * action, and Stripe is not a person. `type` is the namespace that makes `id` resolvable —
26
- * `users`, `integrations`, `members_custom_field_bindings` — so the one writer that
26
+ * `users`, `integrations`, `members_metafield_bindings` — so the one writer that
27
27
  * resolves in no table is the one with no id to give.
28
28
  */
29
29
  exports.WrittenBy = zod_1.z.discriminatedUnion('type', [
@@ -31,12 +31,16 @@ exports.WrittenBy = zod_1.z.discriminatedUnion('type', [
31
31
  zod_1.z.object({ type: zod_1.z.literal('integration'), id: zod_1.z.string() }),
32
32
  zod_1.z.object({ type: zod_1.z.literal('binding'), id: zod_1.z.string() }),
33
33
  zod_1.z.object({ type: zod_1.z.literal('import'), id: zod_1.z.null() }),
34
+ // A member writing their own answers. Resolvable in `members`, like the others,
35
+ // and the only writer whose changes leave nothing in the staff action log: that
36
+ // log records what staff did.
37
+ zod_1.z.object({ type: zod_1.z.literal('member'), id: zod_1.z.string() }),
34
38
  ]);
35
39
  // One part of a member's value. What a `path` means is storage.ts's business, so the row
36
40
  // carries it as a plain string.
37
- exports.DbCustomFieldValue = zod_1.z.object({
41
+ exports.DbMetafieldValue = zod_1.z.object({
38
42
  id: zod_1.z.string(),
39
- custom_field_key: zod_1.z.string(),
43
+ metafield_key: zod_1.z.string(),
40
44
  member_id: zod_1.z.string(),
41
45
  path: zod_1.z.string(),
42
46
  // Nullable like the column, though nothing here writes a null: a part with no value
@@ -55,18 +59,18 @@ exports.DbCustomFieldValue = zod_1.z.object({
55
59
  // `type` takes no part in the assembly and is here as a gate: a value whose type has left
56
60
  // the catalog is one the definitions list no longer returns either, so failing to parse
57
61
  // is what drops it.
58
- exports.DbCustomFieldLeaf = zod_1.z.object({
62
+ exports.DbMetafieldLeaf = zod_1.z.object({
59
63
  member_id: zod_1.z.string(),
60
64
  key: zod_1.z.string(),
61
- type: custom_field_types_1.FieldTypeSchema,
65
+ type: metafield_types_1.FieldTypeSchema,
62
66
  path: zod_1.z.string(),
63
67
  value_text: zod_1.z.string(),
64
68
  });
65
- exports.DbCustomFieldBinding = zod_1.z.object({
69
+ exports.DbMetafieldBinding = zod_1.z.object({
66
70
  id: zod_1.z.string(),
67
71
  product_id: zod_1.z.string(),
68
72
  port: zod_1.z.string(),
69
- custom_field_key: zod_1.z.string(),
73
+ metafield_key: zod_1.z.string(),
70
74
  created_at: date_1.DbDate,
71
75
  updated_at: date_1.DbDate.nullable(),
72
76
  });
@@ -74,5 +78,5 @@ exports.DbCustomFieldBinding = zod_1.z.object({
74
78
  exports.DbBoundField = zod_1.z.object({
75
79
  binding_id: zod_1.z.string(),
76
80
  key: zod_1.z.string(),
77
- type: custom_field_types_1.FieldTypeSchema,
81
+ type: metafield_types_1.FieldTypeSchema,
78
82
  });
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toCustomFieldsResponse = void 0;
3
+ exports.toMetafieldsResponse = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const case_keys_1 = require("../../lib/case-keys");
6
6
  const models_1 = require("./models");
7
- const CustomFieldResource = zod_1.z.object({
7
+ const MetafieldResource = zod_1.z.object({
8
8
  namespace: zod_1.z.string(),
9
9
  key: zod_1.z.string(),
10
10
  name: zod_1.z.string(),
@@ -13,10 +13,10 @@ const CustomFieldResource = zod_1.z.object({
13
13
  created_at: zod_1.z.date(),
14
14
  updated_at: zod_1.z.date().nullable(),
15
15
  });
16
- const CustomFieldsResponse = zod_1.z.object({ members_metafields: zod_1.z.array(CustomFieldResource) });
17
- exports.toCustomFieldsResponse = zod_1.z
18
- .array(models_1.CustomField)
16
+ const MetafieldsResponse = zod_1.z.object({ members_metafields: zod_1.z.array(MetafieldResource) });
17
+ exports.toMetafieldsResponse = zod_1.z
18
+ .array(models_1.Metafield)
19
19
  .transform((fields) => ({
20
20
  members_metafields: fields.map((field) => (0, case_keys_1.snakeKeys)(field)),
21
21
  }))
22
- .pipe(CustomFieldsResponse);
22
+ .pipe(MetafieldsResponse);