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.
- package/components/tryghost-adapter-base-jobs-0.0.0.tgz +0 -0
- package/components/tryghost-adapter-base-scheduling-0.2.3.tgz +0 -0
- package/components/tryghost-adapter-base-sso-0.1.3.tgz +0 -0
- package/components/tryghost-admin-api-schema-0.0.0.tgz +0 -0
- package/components/tryghost-checkout-0.0.0.tgz +0 -0
- package/components/tryghost-i18n-0.0.0.tgz +0 -0
- package/components/tryghost-kg-card-factory-5.2.4.tgz +0 -0
- package/components/tryghost-kg-clean-basic-html-4.3.4.tgz +0 -0
- package/components/tryghost-kg-converters-1.2.5.tgz +0 -0
- package/components/tryghost-kg-default-cards-10.3.5.tgz +0 -0
- package/components/tryghost-kg-default-nodes-2.2.1.tgz +0 -0
- package/components/tryghost-kg-default-transforms-1.3.4.tgz +0 -0
- package/components/tryghost-kg-html-to-lexical-1.4.0.tgz +0 -0
- package/components/tryghost-kg-lexical-html-renderer-1.5.0.tgz +0 -0
- package/components/tryghost-kg-markdown-html-renderer-7.2.4.tgz +0 -0
- package/components/tryghost-kg-utils-1.1.4.tgz +0 -0
- package/components/tryghost-limit-service-0.0.0.tgz +0 -0
- package/components/tryghost-metafield-types-0.0.0.tgz +0 -0
- package/content/themes/source/package.json +2 -2
- package/content/themes/source/partials/post-card.hbs +1 -1
- package/core/boot.js +7 -5
- package/core/built/admin/assets/{about-Dyae_UT6.js → about-C1C3s5-g.js} +1 -1
- package/core/built/admin/assets/accordion-CxGsDKwa.js +1 -0
- package/core/built/admin/assets/{account-migration-CESa0mnX.js → account-migration-CbUhW6gk.js} +1 -1
- package/core/built/admin/assets/activitypub/{account-migration-By69CgCp.js → account-migration-KA6Jjf9L.js} +7 -7
- package/core/built/admin/assets/activitypub/activitypub.js +3 -3
- package/core/built/admin/assets/activitypub/{avatar-DLPL3Abs.js → avatar-DVJF5bxP.js} +2 -2
- package/core/built/admin/assets/activitypub/{avatar-flipboard-C9iDY-QV.js → avatar-flipboard-csQaNeYK.js} +2 -2
- package/core/built/admin/assets/activitypub/{bluesky-sharing-BJcPMrDd.js → bluesky-sharing-C7nTDMvw.js} +9 -9
- package/core/built/admin/assets/activitypub/{content-formatters-3rTHg3mp.js → content-formatters-CLcjaBwV.js} +4 -4
- package/core/built/admin/assets/activitypub/{copy-DIAOQoCZ.js → copy-DcOh8kXw.js} +2 -2
- package/core/built/admin/assets/activitypub/{domain-DUR4xSkV.js → domain-fZ-X8i4-.js} +9 -9
- package/core/built/admin/assets/activitypub/{edit-profile-BqtfzxCp.js → edit-profile-BqMLQV88.js} +6 -6
- package/core/built/admin/assets/activitypub/{explore-BxuJd-J4.js → explore-B4yPoP8E.js} +10 -10
- package/core/built/admin/assets/activitypub/{feed-BM1TcksA.js → feed-BRC_mvAe.js} +9 -9
- package/core/built/admin/assets/activitypub/{field-Dn7HHx2-.js → field-COacNgOt.js} +3 -3
- package/core/built/admin/assets/activitypub/{hash-Bm3WxYN4.js → hash-C7u-irQQ.js} +2 -2
- package/core/built/admin/assets/activitypub/{inbox-CCjkuow2.js → inbox-BW-yvUoN.js} +10 -10
- package/core/built/admin/assets/activitypub/{inbox-d8oJRTf4.js → inbox-CbTTdDQ3.js} +2 -2
- package/core/built/admin/assets/activitypub/{label-1AA_s9Fa.js → label-kPMmYI7l.js} +3 -3
- package/core/built/admin/assets/activitypub/layout-BL4_jtuV.js +1 -0
- package/core/built/admin/assets/activitypub/{moderation-CnmxEB8w.js → moderation-CuidJzc0.js} +10 -10
- package/core/built/admin/assets/activitypub/{note-ZKc_Bnba.js → note-CAMRRSqD.js} +7 -7
- package/core/built/admin/assets/activitypub/{notifications-CB2tJZau.js → notifications-BmNlXGgp.js} +9 -9
- package/core/built/admin/assets/activitypub/{onboarding-BsJ9E5qf.js → onboarding-Bqg7fh_L.js} +2 -2
- package/core/built/admin/assets/activitypub/{onboarding-CSUJJIlh.js → onboarding-Dmun9jr_.js} +2 -2
- package/core/built/admin/assets/activitypub/{preferences-0-JZnUkI.js → preferences--oH19wf9.js} +11 -11
- package/core/built/admin/assets/activitypub/{profile-C35cFIhM.js → profile-DH_tQx2D.js} +14 -14
- package/core/built/admin/assets/activitypub/{reply-DYK5vVqb.js → reply-Cap9PxSH.js} +2 -2
- package/core/built/admin/assets/activitypub/{routes-BD4vscyc.js → routes-DdyY9uFF.js} +30 -30
- package/core/built/admin/assets/activitypub/{separator-BbQqTm-p.js → separator-CAxxu8VV.js} +3 -3
- package/core/built/admin/assets/activitypub/{settings-BsMROdqh.js → settings-B6EEcVkW.js} +6 -6
- package/core/built/admin/assets/activitypub/{site-O0RL9YCN.js → site-BYps63oh.js} +2 -2
- package/core/built/admin/assets/activitypub/{step-1-BMSx7c_X.js → step-1-CKjR2KAm.js} +6 -6
- package/core/built/admin/assets/activitypub/{step-2-DtPQzlTH.js → step-2-B6PKfOUQ.js} +6 -6
- package/core/built/admin/assets/activitypub/{step-3-CLlOZTyt.js → step-3-C-qBbcUo.js} +11 -11
- package/core/built/admin/assets/activitypub/{tabs-Dxk-b9M-.js → tabs-DLhZtVde.js} +6 -6
- package/core/built/admin/assets/activitypub/{topic-filter-5yZH6tId.js → topic-filter-DsUOuu0k.js} +3 -3
- package/core/built/admin/assets/activitypub/{use-activity-pub-queries-CV50qe03.js → use-activity-pub-queries-CX9snsLs.js} +3 -3
- package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-Bmk5h4lW.js → use-navigate-with-base-path-DsJTGDSS.js} +988 -959
- package/core/built/admin/assets/activitypub/{use-reply-chain-data-Cbvzgjzd.js → use-reply-chain-data-AJi9zkzm.js} +5 -5
- package/core/built/admin/assets/activitypub/{users-BjcoP_HC.js → users-inweyKL5.js} +186 -160
- package/core/built/admin/assets/activitypub/{x-DbQZOLiI.js → x-DR8AT3-4.js} +2 -2
- package/core/built/admin/assets/{add-integration-modal-BlF6rs_f.js → add-integration-modal-BT_onDJy.js} +1 -1
- package/core/built/admin/assets/{add-newsletter-modal-CglVQqah.js → add-newsletter-modal-Cx1kQpiY.js} +1 -1
- package/core/built/admin/assets/{add-recommendation-modal-wz7BsuaG.js → add-recommendation-modal-B5nvAhvr.js} +1 -1
- package/core/built/admin/assets/{analytics-C4HE1gBg.js → analytics-DjoJWPI7.js} +1 -1
- package/core/built/admin/assets/{announcement-bar-modal-Ci4zz8jO.js → announcement-bar-modal-Dwd0EGFP.js} +1 -1
- package/core/built/admin/assets/{api-keys-3-0vJC3Y.js → api-keys-BGPzLHzA.js} +1 -1
- package/core/built/admin/assets/{api-keys-Ck-Yteiv.js → api-keys-BoeacM-s.js} +1 -1
- package/core/built/admin/assets/{audience-CtbA54Sn.js → audience-ceV3XVHq.js} +1 -1
- package/core/built/admin/assets/automated-emails-BLesE41L.js +1 -0
- package/core/built/admin/assets/{automations-sAcJ1334.js → automations-BN4u3GR8.js} +1 -1
- package/core/built/admin/assets/automations-C-ZTUwW3.js +1 -0
- package/core/built/admin/assets/{bluesky-sharing-BEtJ_gL_.js → bluesky-sharing-vzh-oPXL.js} +1 -1
- package/core/built/admin/assets/{breadcrumb-zUrZrBtW.js → breadcrumb-CaLk2b7D.js} +1 -1
- package/core/built/admin/assets/{button-eNMKQWXr.js → button-Dvcv1QSR.js} +1 -1
- package/core/built/admin/assets/calendar-Bl9RLcZX.js +1 -0
- package/core/built/admin/assets/{chart-helpers-CfBKt0vT.js → chart-helpers-FHywU0pj.js} +1 -1
- package/core/built/admin/assets/{checkbox-CgOn_tKW.js → checkbox-BtayFtjg.js} +1 -1
- package/core/built/admin/assets/chunk.254.035b85ec456ebbd7336b.js +440 -0
- package/core/built/admin/assets/{chunk.524.a697dee88db67fdf6021.js → chunk.524.e6975095fccdf22d90f8.js} +5 -5
- package/core/built/admin/assets/{chunk.582.5ed5d124cfca9c259b9c.js → chunk.582.98b485f9b2802f540897.js} +6 -6
- package/core/built/admin/assets/{chunk.492.f24d855d7e3f3aad261c.js → chunk.901.4ccc639821020230bcca.js} +9949 -7921
- package/core/built/admin/assets/{code-editor-view-K2wI-I5f.js → code-editor-view-C3ZfoF1X.js} +1 -1
- package/core/built/admin/assets/{code-editor-view-BYNoAoNV.js → code-editor-view-CAyRWy1s.js} +1 -1
- package/core/built/admin/assets/{color-picker-Ddw80xX6.js → color-picker-G4kGR7rp.js} +1 -1
- package/core/built/admin/assets/{color-picker-field-D9nUhvA7.js → color-picker-field-DQFVTNnT.js} +1 -1
- package/core/built/admin/assets/{combobox-w9j8PPQT.js → combobox-BnYzgEB4.js} +1 -1
- package/core/built/admin/assets/{command-BfpHORBv.js → command-C_vyTikI.js} +1 -1
- package/core/built/admin/assets/comments-aBrxfnZf.js +1 -0
- package/core/built/admin/assets/{config-DOMQDZGZ.js → config-kSHvwdTG.js} +1 -1
- package/core/built/admin/assets/{confirmation-context-CBM8G0Vj.js → confirmation-context-DwXX_Y5h.js} +1 -1
- package/core/built/admin/assets/{content-api-modal-TXRz3U7S.js → content-api-modal-D2G0nJP6.js} +1 -1
- package/core/built/admin/assets/{context-menu-_QMdd3kp.js → context-menu-DOVB6yaz.js} +1 -1
- package/core/built/admin/assets/{copy-field-6N01S07E.js → copy-field-DCJwh9qf.js} +1 -1
- package/core/built/admin/assets/{create-ghost-browse-value-source-qIBymvvf.js → create-ghost-browse-value-source-5C53jJaX.js} +1 -1
- package/core/built/admin/assets/custom-field-type-option-BAuW0F-E.js +1 -0
- package/core/built/admin/assets/{custom-integration-modal-DmNquxUV.js → custom-integration-modal-AbJGVyKc.js} +1 -1
- package/core/built/admin/assets/{date-range-select-uvz_DtPh.js → date-range-select-BY3K-ukj.js} +1 -1
- package/core/built/admin/assets/design-and-theme-modal-BvEy4_pC.js +2 -0
- package/core/built/admin/assets/{dirty-confirm-dialog-BZ1iytEd.js → dirty-confirm-dialog-DVPuGz3U.js} +1 -1
- package/core/built/admin/assets/{disabled-sources-indicator-DMRrxsiJ.js → disabled-sources-indicator-Cy7Zp4c8.js} +1 -1
- package/core/built/admin/assets/{domain-BNYrt0aD.js → domain-Dl61QGuk.js} +1 -1
- package/core/built/admin/assets/{dropzone-D7nFdAe5.js → dropzone-Dtz5Rmjt.js} +4 -4
- package/core/built/admin/assets/edit-profile-DNJSMDwm.js +1 -0
- package/core/built/admin/assets/editor-DbAen9zf.js +8 -0
- package/core/built/admin/assets/editor-screen-BFWThIai.js +26 -0
- package/core/built/admin/assets/email-sending-status-context-CWDOD1FN.js +1 -0
- package/core/built/admin/assets/email-sending-status-provider-DCPkDICt.js +1 -0
- package/core/built/admin/assets/emails-vFMk4yYl.js +1 -0
- package/core/built/admin/assets/{embed-signup-form-modal-Ds6mPEi5.js → embed-signup-form-modal-DGqsORxS.js} +1 -1
- package/core/built/admin/assets/{explore-UY10Egsp.js → explore-nnRr1Fja.js} +1 -1
- package/core/built/admin/assets/feature-flag-overrides-context-DQjdJFAk.js +1 -0
- package/core/built/admin/assets/{feature-image-placeholder-D1iF_8bc.js → feature-image-placeholder-BrIHmPs8.js} +1 -1
- package/core/built/admin/assets/{feed-81C8mJWR.js → feed-BNUcNu-W.js} +1 -1
- package/core/built/admin/assets/feedback-DJ4Zb9rZ.js +1 -0
- package/core/built/admin/assets/{field-Dihp5p18.js → field-C93_Mg6j.js} +1 -1
- package/core/built/admin/assets/filter-sources-CGJb4C5r.js +1 -0
- package/core/built/admin/assets/{filters-DirqNXjH.js → filters--kKP-EC8.js} +1 -1
- package/core/built/admin/assets/filters-DxA_a4FP.js +1 -0
- package/core/built/admin/assets/{first-promoter-modal-CT6MxYZb.js → first-promoter-modal-BYDtrz2S.js} +1 -1
- package/core/built/admin/assets/focus-koenig-editor-on-bottom-click-BbSnGOtK.js +1 -0
- package/core/built/admin/assets/{ghost-8eabfc1ece81b03cf7b90780d31487e8.css → ghost-8fd5bb799356bbefb254210ba7e1236d.css} +1 -1
- package/core/built/admin/assets/{ghost-c2848508292937415f20f5a830eea59e.js → ghost-b4e8a403baba61905cd7560e30b9732d.js} +43 -27
- package/core/built/admin/assets/{ghost-dark-a7bebe2c561f55369dcf29f4c820f7ff.css → ghost-dark-cac0cb2d5bb78e9bd14d8d1c2768ed45.css} +1 -1
- package/core/built/admin/assets/{gift-link-modal-CQVAye17.js → gift-link-modal-B7u5bD4e.js} +1 -1
- package/core/built/admin/assets/{gift-links-DLDS7ljO.js → gift-links-CfLSnst2.js} +1 -1
- package/core/built/admin/assets/growth-Cd1uO9d2.js +1 -0
- package/core/built/admin/assets/growth-aG32xfdE.js +3 -0
- package/core/built/admin/assets/{history-modal-CFd1Hvx6.js → history-modal-Df8lW8h-.js} +1 -1
- package/core/built/admin/assets/hooks-Cy_-oZ4o.js +2 -0
- package/core/built/admin/assets/{html-field-CJBCLTvv.js → html-field-DA4eU7eq.js} +1 -1
- package/core/built/admin/assets/{images-scfkWZiK.js → images-KXmyO3Ss.js} +1 -1
- package/core/built/admin/assets/{inbox-Mcp4DXZN.js → inbox-gJHG7_xd.js} +6 -6
- package/core/built/admin/assets/index-BHHXtR5C.css +2 -0
- package/core/built/admin/assets/index-CgMCwsxN.js +4 -0
- package/core/built/admin/assets/index.es-CY6-yuw9.js +1 -0
- package/core/built/admin/assets/{input-group-CMhe2DvY.js → input-group-BE8rM2y1.js} +1 -1
- package/core/built/admin/assets/{integrations-Bjbu86Z0.js → integrations-B4kuRBFY.js} +1 -1
- package/core/built/admin/assets/{invite-user-modal-DfheMXs0.js → invite-user-modal-B4CuNcx4.js} +1 -1
- package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +2 -2
- package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +2 -2
- package/core/built/admin/assets/{koenig-lexical-DBSqAuiI.js → koenig-lexical-CGXb0F8o.js} +2 -2
- package/core/built/admin/assets/koenig-loader-BeM5rFPX.js +2 -0
- package/core/built/admin/assets/{kpi-card-DBRMfGOW.js → kpi-card-B21aToe8.js} +1 -1
- package/core/built/admin/assets/{kpi-card-DFafD1qq.js → kpi-card-pz6Wv4Ae.js} +1 -1
- package/core/built/admin/assets/{kpi-helpers-Cv8i8hns.js → kpi-helpers-Dq5jelmP.js} +1 -1
- package/core/built/admin/assets/{kpi-tabs-BJItvLYm.js → kpi-tabs-DEZHpKUt.js} +1 -1
- package/core/built/admin/assets/{label-BnSCvffu.js → label-OLCzze8N.js} +1 -1
- package/core/built/admin/assets/label-picker-BigOvMPV.js +1 -0
- package/core/built/admin/assets/{labels-CH3Kn8RV.js → labels-Dr0SgUQD.js} +1 -1
- package/core/built/admin/assets/layout-DUTL8SH5.js +1 -0
- package/core/built/admin/assets/lib-7QPTI0FS.js +1 -0
- package/core/built/admin/assets/link-helpers-BRAg9SCj.js +1 -0
- package/core/built/admin/assets/links-BDHPTlyj.js +1 -0
- package/core/built/admin/assets/{member-custom-fields-DDQV6QeG.js → member-custom-fields-TRTHCAz9.js} +1 -1
- package/core/built/admin/assets/member-detail-b6dRwc3C.js +1 -0
- package/core/built/admin/assets/members-Czt5lJSc.js +4 -0
- package/core/built/admin/assets/{moderation-AgCIEso4.js → moderation-ZWefD9uH.js} +1 -1
- package/core/built/admin/assets/{multi-select-combobox-BcITkUVr.js → multi-select-combobox-CT13MTo-.js} +1 -1
- package/core/built/admin/assets/navigation-modal-C8FEhBK5.js +1 -0
- package/core/built/admin/assets/newsletter-5VYW4RyJ.js +1 -0
- package/core/built/admin/assets/newsletter-detail-modal-ChjC0ZqH.js +1 -0
- package/core/built/admin/assets/{newsletter-emails-DKzwafuh.js → newsletter-emails-DZH6I-PY.js} +1 -1
- package/core/built/admin/assets/{newsletters-BRBb_uQC.js → newsletters-DOC9KBcX.js} +1 -1
- package/core/built/admin/assets/newsletters-Rq1M3GD-.js +1 -0
- package/core/built/admin/assets/{note-DyGHtS9a.js → note-DIV-Pojr.js} +1 -1
- package/core/built/admin/assets/{notifications-ZgWniKna.js → notifications-s20-H49V.js} +1 -1
- package/core/built/admin/assets/{offers-9J1CSiLy.js → offers--e2nGvkW.js} +1 -1
- package/core/built/admin/assets/{offers-container-modal-B-E8TIWr.js → offers-container-modal-BmG5M5Tv.js} +1 -1
- package/core/built/admin/assets/onboarding-CUuy9unR.js +1 -0
- package/core/built/admin/assets/{onboarding-CzIsre-d.js → onboarding-pXyct0Jm.js} +1 -1
- package/core/built/admin/assets/{onboarding-route-CaavZulg.js → onboarding-route-CK4pcXoR.js} +1 -1
- package/core/built/admin/assets/overview-CaPsciMs.js +1 -0
- package/core/built/admin/assets/overview-a8GfcsKX.js +1 -0
- package/core/built/admin/assets/{page-header-De0VzKBi.js → page-header-DM_KyoFI.js} +1 -1
- package/core/built/admin/assets/{pagemenu-B5KKCpbA.js → pagemenu-vgZVUVKR.js} +1 -1
- package/core/built/admin/assets/pages-CjDY2CBI.js +1 -0
- package/core/built/admin/assets/pages-route-BzKZYdV5.js +1 -0
- package/core/built/admin/assets/{pintura-modal-BZ2J9w3n.js → pintura-modal-DExCF1ii.js} +1 -1
- package/core/built/admin/assets/{portal-frame-B6Hr9wHc.js → portal-frame-Cqanidq4.js} +1 -1
- package/core/built/admin/assets/portal-modal-oinBgA27.js +1 -0
- package/core/built/admin/assets/post-analytics-C5oJ1dWV.js +1 -0
- package/core/built/admin/assets/post-analytics-header-OATo3X_r.js +1 -0
- package/core/built/admin/assets/post-analytics-provider-tOpIVGT5.js +1 -0
- package/core/built/admin/assets/post-helpers-C88JBa4D.js +1 -0
- package/core/built/admin/assets/post-share-modal-DvhC1XgV.js +1 -0
- package/core/built/admin/assets/post-utils-DKF4mfuo.js +1 -0
- package/core/built/admin/assets/posts-list-screen-o4ZjbgS3.js +2 -0
- package/core/built/admin/assets/posts-pCPrhQeR.js +1 -0
- package/core/built/admin/assets/posts-route-9F--xdIb.js +1 -0
- package/core/built/admin/assets/{preferences-C5YJLp74.js → preferences--vNubsqD.js} +2 -2
- package/core/built/admin/assets/{preview-modal-BfeFqi5y.js → preview-modal-YYbzlYdO.js} +1 -1
- package/core/built/admin/assets/profile-BllKV3dR.js +1 -0
- package/core/built/admin/assets/radio-group-DL8GI8rt.js +1 -0
- package/core/built/admin/assets/{referrers-CnhCMWCs.js → referrers-D8oHPmDB.js} +1 -1
- package/core/built/admin/assets/router-provider-BSvTXgZY.js +1 -0
- package/core/built/admin/assets/schemas-BoYdB6YU.js +64 -0
- package/core/built/admin/assets/{select-cb0t_TAJ.js → select-v5YbA3Mw.js} +1 -1
- package/core/built/admin/assets/settings-PEsZupw1.js +4 -0
- package/core/built/admin/assets/{settings-breadcrumbs-DLzbRRSt.js → settings-breadcrumbs-NwPnCTC7.js} +1 -1
- package/core/built/admin/assets/{settings-DZqxR0Da.js → settings-u_s1CRkr.js} +1 -1
- package/core/built/admin/assets/{share-modal-D2-Bz1_I.js → share-modal-SskCmVGL.js} +1 -1
- package/core/built/admin/assets/{slack-modal-DYDTUria.js → slack-modal-XxSJiYgo.js} +1 -1
- package/core/built/admin/assets/{sort-button-VVeQjjbu.js → sort-button-Cx1KtINE.js} +1 -1
- package/core/built/admin/assets/{source-icon-Ck5_5Kgq.js → source-icon-Bdp9Im_5.js} +1 -1
- package/core/built/admin/assets/stats-D9PDLS3x.js +1 -0
- package/core/built/admin/assets/stats-view-W2g6Jsd-.js +1 -0
- package/core/built/admin/assets/{step-1-CsaBjeN4.js → step-1-BQYzvBzr.js} +1 -1
- package/core/built/admin/assets/{step-2-D2vnxOOM.js → step-2-xES32xJV.js} +1 -1
- package/core/built/admin/assets/{step-3-wBoLdGEb.js → step-3-DA_XK5kW.js} +2 -2
- package/core/built/admin/assets/{stripe-button-CDgLz0S0.js → stripe-button-CVsLHelt.js} +1 -1
- package/core/built/admin/assets/{stripe-connect-modal-CSjMJetP.js → stripe-connect-modal-ClmLOMGS.js} +1 -1
- package/core/built/admin/assets/style-Wd9nQubI.css +1 -0
- package/core/built/admin/assets/{table-Do6iQ83Q.js → table-BenqVupI.js} +1 -1
- package/core/built/admin/assets/{tabs-D2yWLMp_.js → tabs-eBBlxPp8.js} +1 -1
- package/core/built/admin/assets/tag-detail-Ce8Se2qd.js +2 -0
- package/core/built/admin/assets/tag-picker-C3UR-uJ-.js +1 -0
- package/core/built/admin/assets/tags-B-kJxCs7.js +1 -0
- package/core/built/admin/assets/{tags-zTFiKRpb.js → tags-ChfdwJyS.js} +1 -1
- package/core/built/admin/assets/{testimonials-modal-CtnZBJKl.js → testimonials-modal-9Q6fT06V.js} +1 -1
- package/core/built/admin/assets/tier-detail-modal-CDyYdqK7.js +1 -0
- package/core/built/admin/assets/tiers-BCpIOGQr.js +1 -0
- package/core/built/admin/assets/{toggle-group-ByUJsxwD.js → toggle-group-CviIkyok.js} +1 -1
- package/core/built/admin/assets/{topic-filter-BgC3g5_v.js → topic-filter-I2jCBGxm.js} +1 -1
- package/core/built/admin/assets/{transistor-modal-Drr0SNfo.js → transistor-modal-p53u3W8y.js} +1 -1
- package/core/built/admin/assets/{trend-badge-6ye93YAW.js → trend-badge-CideVzQd.js} +1 -1
- package/core/built/admin/assets/{unsplash-modal-p6AoQoWp.js → unsplash-modal-DY8UcKcE.js} +1 -1
- package/core/built/admin/assets/{use-analytics-data-CWCMAESo.js → use-analytics-data-DAIGcr2f.js} +1 -1
- package/core/built/admin/assets/{use-check-theme-limit-error-Cw3WQHy8.js → use-check-theme-limit-error-DRUjK4YM.js} +1 -1
- package/core/built/admin/assets/use-filter-params-JkZhIS8L.js +1 -0
- package/core/built/admin/assets/{use-filterable-api-CzXcpUh8.js → use-filterable-api-BVEVMrhZ.js} +1 -1
- package/core/built/admin/assets/{use-growth-stats-DCVG3s9w.js → use-growth-stats-937CUj6j.js} +1 -1
- package/core/built/admin/assets/use-host-limits-D0Dv3tKA.js +1 -0
- package/core/built/admin/assets/{use-limiter-D2WRRx0H.js → use-limiter-CohWfzvK.js} +1 -1
- package/core/built/admin/assets/{use-navigate-with-base-path-BHPA228f.js → use-navigate-with-base-path-BkxcPj5l.js} +1 -1
- package/core/built/admin/assets/use-pintura-config-xgytjU35.js +1 -0
- package/core/built/admin/assets/{use-pintura-editor-BfN1UwzH.js → use-pintura-editor-CaV1mbfO.js} +1 -1
- package/core/built/admin/assets/{use-post-referrers-Czg47m8s.js → use-post-referrers-BCQI7fDg.js} +1 -1
- package/core/built/admin/assets/{use-reply-chain-data-ns0caK8k.js → use-reply-chain-data-CYRhoaxY.js} +1 -1
- package/core/built/admin/assets/{use-router-history-entry-uldn7zJO.js → use-router-history-entry-NOKcd--l.js} +1 -1
- package/core/built/admin/assets/{use-setting-group-DpcuCUDg.js → use-setting-group-bLKMwoBT.js} +1 -1
- package/core/built/admin/assets/{use-settings-navigation-CZjGrhsp.js → use-settings-navigation-B-qrriKD.js} +1 -1
- package/core/built/admin/assets/{use-simple-pagination-DzJWobPR.js → use-simple-pagination-CNPd6Rf6.js} +1 -1
- package/core/built/admin/assets/use-staff-users-pRIMIyiW.js +1 -0
- package/core/built/admin/assets/{use-tinybird-query-CSnGXzZh.js → use-tinybird-query-CmdbCS9X.js} +1 -1
- package/core/built/admin/assets/{use-tinybird-token-DTOKRR7e.js → use-tinybird-token-KLne235s.js} +1 -1
- package/core/built/admin/assets/{use-unsaved-changes-guard-CBzs-KPi.js → use-unsaved-changes-guard-7-ug0JdH.js} +1 -1
- package/core/built/admin/assets/use-upgrade-route-Dm_qqKr0.js +1 -0
- package/core/built/admin/assets/{use-url-input-DFr8lCbS.js → use-url-input-fvp-TpPx.js} +1 -1
- package/core/built/admin/assets/user-detail-modal-D3KlGYv-.js +1 -0
- package/core/built/admin/assets/{users-Cg-OeGzC.js → users-DVNWrqg9.js} +1 -1
- package/core/built/admin/assets/{vendor-5753232c7d6ffb3c44e1eb0a02133953.js → vendor-2dd263291938d407802568d3357ec69e.js} +19 -17
- package/core/built/admin/assets/{virtual-list-BW-padMe.js → virtual-list-CZ3RK2Yf.js} +1 -1
- package/core/built/admin/assets/{web-C1v33ehA.js → web-ClEJsCAj.js} +2 -2
- package/core/built/admin/assets/web-X9rdnrtq.js +1 -0
- package/core/built/admin/assets/{zapier-modal-BBFfI6Ml.js → zapier-modal-DfVhV17j.js} +1 -1
- package/core/built/admin/index.html +19 -18
- package/core/server/adapters/jobs/InMemoryJobsBackend.js +74 -29
- package/core/server/api/endpoints/authentication.js +1 -2
- package/core/server/api/endpoints/authors-public.js +15 -5
- package/core/server/api/endpoints/emails.js +13 -0
- package/core/server/api/endpoints/index.js +8 -0
- package/core/server/api/endpoints/member-metafields-members.js +23 -0
- package/core/server/api/endpoints/member-metafields.js +33 -20
- package/core/server/api/endpoints/members-account.js +42 -0
- package/core/server/api/endpoints/newsletters-public.js +10 -1
- package/core/server/api/endpoints/pages-public.js +15 -5
- package/core/server/api/endpoints/posts-public.js +15 -5
- package/core/server/api/endpoints/tags-public.js +22 -3
- package/core/server/api/endpoints/tiers-checkout-config.js +2 -2
- package/core/server/api/endpoints/tiers-public.js +38 -1
- package/core/server/api/endpoints/users.js +2 -2
- package/core/server/api/endpoints/utils/api-filter-utils.js +170 -3
- package/core/server/api/endpoints/utils/public-cache-keys.js +3 -0
- package/core/server/api/endpoints/utils/serializers/input/authors.js +2 -0
- package/core/server/api/endpoints/utils/serializers/input/members.js +16 -2
- package/core/server/api/endpoints/utils/serializers/input/pages.js +2 -0
- package/core/server/api/endpoints/utils/serializers/input/posts.js +2 -0
- package/core/server/api/endpoints/utils/serializers/input/tags.js +2 -0
- package/core/server/api/endpoints/utils/serializers/output/emails.js +7 -0
- package/core/server/api/endpoints/utils/serializers/output/index.js +4 -0
- package/core/server/api/endpoints/utils/serializers/output/member-metafields.js +3 -3
- package/core/server/api/endpoints/utils/serializers/output/members-account.js +19 -0
- package/core/server/api/endpoints/utils/serializers/output/members-csv-transform.js +1 -1
- package/core/server/api/endpoints/utils/serializers/output/tiers.js +10 -2
- package/core/server/api/endpoints/utils/serializers/output/users.js +0 -10
- package/core/server/data/exporter/table-lists.js +3 -3
- package/core/server/data/migrations/versions/6.53/2026-07-15-20-22-53-add-members-custom-field-values.js +1 -1
- package/core/server/data/migrations/versions/6.57/2026-08-04-18-00-00-store-custom-field-values-as-leaf-rows.js +10 -1
- package/core/server/data/migrations/versions/6.63/2026-09-03-10-07-03-rename-custom-field-tables-to-metafields.js +169 -0
- package/core/server/data/migrations/versions/6.63/2026-09-03-11-03-31-remove-member-custom-field-read-permissions.js +30 -0
- package/core/server/data/schema/fixtures/fixtures.json +0 -11
- package/core/server/data/schema/lib/default-index-name.js +8 -11
- package/core/server/data/schema/schema.js +18 -18
- package/core/server/data/seeders/README.md +48 -0
- package/core/server/data/tinybird/pipes/mv_hits.pipe +86 -50
- package/core/server/lib/db-types/count.js +16 -0
- package/core/server/lib/validate-password.js +81 -120
- package/core/server/models/action.js +4 -4
- package/core/server/models/base/plugins/filtered-collection.js +16 -0
- package/core/server/models/member.js +6 -6
- package/core/server/models/user.js +1 -1
- package/core/server/services/automations/automations-api.js +1 -1
- package/core/server/services/automations/database-automations-repository.js +11 -4
- package/core/server/services/email-service/CONTEXT.md +37 -0
- package/core/server/services/email-service/README.md +42 -0
- package/core/server/services/email-service/batch-sending-service.js +2 -0
- package/core/server/services/email-service/email-controller.js +18 -2
- package/core/server/services/email-service/email-service-wrapper.js +3 -0
- package/core/server/services/email-service/sending-status-schema.js +21 -0
- package/core/server/services/email-service/sending-status-serializers.js +33 -0
- package/core/server/services/email-service/sending-status-service.js +47 -0
- package/core/server/services/email-service/sending-status.js +111 -0
- package/core/server/services/email-suppression-list/email-suppression-list.js +0 -33
- package/core/server/services/email-suppression-list/mailgun-email-suppression-list.js +6 -7
- package/core/server/services/gifts/README.md +2 -2
- package/core/server/services/gifts/constants.js +1 -1
- package/core/server/services/gifts/gift-service.js +19 -57
- package/core/server/services/gifts/index.js +0 -2
- package/core/server/services/jobs-service/index.js +8 -0
- package/core/server/services/jobs-service/jobs-service.js +52 -3
- package/core/server/services/jobs-service/register-job-handlers.js +13 -2
- package/core/server/services/members/account-service.js +98 -0
- package/core/server/services/members/api.js +4 -4
- package/core/server/services/members/import-export/export/exporter.js +20 -20
- package/core/server/services/members/import-export/import/completion-email.js +6 -6
- package/core/server/services/members/import-export/import/importer.js +13 -13
- package/core/server/services/members/import-export/index.js +7 -7
- package/core/server/services/members/members-api/members-api.js +26 -6
- package/core/server/services/members/members-api/repositories/member-repository.js +4 -4
- package/core/server/services/members/members-api/services/member-bread-service.js +45 -39
- package/core/server/services/members/members-ssr.js +18 -0
- package/core/server/services/members/middleware.js +95 -81
- package/core/server/services/members/service.js +70 -42
- package/core/server/services/members/utils.js +9 -0
- package/core/server/services/members-metafields/access.js +28 -0
- package/core/server/services/{members-custom-fields → members-metafields}/actions.js +5 -5
- package/core/server/services/members-metafields/bindings-service.js +147 -0
- package/core/server/services/{members-custom-fields → members-metafields}/codec.js +4 -4
- package/core/server/services/{members-custom-fields → members-metafields}/config.js +1 -1
- package/core/server/services/{members-custom-fields → members-metafields}/definitions-service.js +17 -23
- package/core/server/services/{members-custom-fields → members-metafields}/filter.js +9 -9
- package/core/server/services/{members-custom-fields → members-metafields}/index.js +16 -7
- package/core/server/services/{members-custom-fields → members-metafields}/key.js +1 -1
- package/core/server/services/{members-custom-fields → members-metafields}/models.js +4 -4
- package/core/server/services/members-metafields/namespaces.js +34 -0
- package/core/server/services/{members-custom-fields → members-metafields}/queries.js +1 -1
- package/core/server/services/{members-custom-fields → members-metafields}/schema.js +16 -12
- package/core/server/services/{members-custom-fields → members-metafields}/serializers.js +6 -6
- package/core/server/services/{members-custom-fields → members-metafields}/values-service.js +32 -22
- package/core/server/services/mentions/mention-sending-service.js +26 -9
- package/core/server/services/mentions/send-webmentions-job.js +18 -0
- package/core/server/services/mentions/service.js +1 -31
- package/core/server/services/stripe/services/webhook/checkout-session-event-service.js +2 -2
- package/core/server/services/stripe/stripe-service.js +4 -4
- package/core/server/services/tier-checkout-config/codec.js +2 -2
- package/core/server/services/tier-checkout-config/index.js +2 -1
- package/core/server/services/tier-checkout-config/models.js +2 -2
- package/core/server/services/tier-checkout-config/queries.js +8 -8
- package/core/server/services/tier-checkout-config/serializers.js +57 -0
- package/core/server/services/tier-checkout-config/service.js +1 -1
- package/core/server/services/tiers/service.js +3 -3
- package/core/server/services/url/router-filter.js +8 -10
- package/core/server/services/users.js +1 -19
- package/core/server/web/api/endpoints/admin/routes.js +1 -0
- package/core/server/web/members/account/index.js +2 -0
- package/core/server/web/members/account/routes.js +46 -0
- package/core/server/web/members/app.js +4 -18
- package/core/shared/config/defaults.json +1 -1
- package/core/shared/labs.js +4 -2
- package/package.json +22 -22
- package/pnpm-lock.yaml +513 -571
- package/pnpm-workspace.yaml +12 -12
- package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
- package/core/built/admin/assets/activitypub/layout-2-0bw6HN.js +0 -1
- package/core/built/admin/assets/automated-emails-D5VVMND9.js +0 -1
- package/core/built/admin/assets/automations-CzKt5fb8.js +0 -1
- package/core/built/admin/assets/chunk.598.7e056fabb47ce7dbd73f.js +0 -366
- package/core/built/admin/assets/comments-BLmCmyCs.js +0 -1
- package/core/built/admin/assets/custom-field-type-option-BddFlJFa.js +0 -1
- package/core/built/admin/assets/design-and-theme-modal-BSmo12Op.js +0 -2
- package/core/built/admin/assets/edit-profile-C5Asm4LA.js +0 -1
- package/core/built/admin/assets/editor-REokrzci.js +0 -8
- package/core/built/admin/assets/filter-sources-BO9xUPj7.js +0 -1
- package/core/built/admin/assets/filters-CRUWecfY.js +0 -1
- package/core/built/admin/assets/growth-BWIu-6xj.js +0 -3
- package/core/built/admin/assets/growth-DU29oxeA.js +0 -1
- package/core/built/admin/assets/hooks-CuEZV2-q.js +0 -2
- package/core/built/admin/assets/index-6MkPdCtr.js +0 -4
- package/core/built/admin/assets/index-Bn7QhcZu.css +0 -2
- package/core/built/admin/assets/index.es-CNnuNH0d.js +0 -1
- package/core/built/admin/assets/koenig-loader-aFQNlJlD.js +0 -2
- package/core/built/admin/assets/label-picker-KVoo91sh.js +0 -1
- package/core/built/admin/assets/layout-Bjv2Ll-5.js +0 -1
- package/core/built/admin/assets/link-helpers-MVDdnFCY.js +0 -1
- package/core/built/admin/assets/member-detail-CdJF6Agw.js +0 -1
- package/core/built/admin/assets/members-DjQbq9Z2.js +0 -4
- package/core/built/admin/assets/navigation-modal-BkT7b1M2.js +0 -1
- package/core/built/admin/assets/newsletter-BMMAuvgq.js +0 -1
- package/core/built/admin/assets/newsletter-detail-modal-0SCJ7Zpm.js +0 -1
- package/core/built/admin/assets/newsletters-DhNigJUh.js +0 -1
- package/core/built/admin/assets/onboarding-qg8Akovm.js +0 -1
- package/core/built/admin/assets/overview-BW8GLeYi.js +0 -1
- package/core/built/admin/assets/overview-BkXZNzaZ.js +0 -1
- package/core/built/admin/assets/pages-jgaFm69d.js +0 -1
- package/core/built/admin/assets/pages-route-CIUAQxtY.js +0 -1
- package/core/built/admin/assets/portal-modal-D4ceei3t.js +0 -1
- package/core/built/admin/assets/post-analytics-header-BYCsT0GP.js +0 -1
- package/core/built/admin/assets/post-analytics-ot7f6pih.js +0 -1
- package/core/built/admin/assets/post-analytics-provider-Bo1gmYaP.js +0 -1
- package/core/built/admin/assets/post-helpers-C5OQMBoi.js +0 -1
- package/core/built/admin/assets/post-share-modal-C-PaYZ_e.js +0 -1
- package/core/built/admin/assets/posts-DuGazgTb.js +0 -1
- package/core/built/admin/assets/posts-list-screen-CBGGgjjj.js +0 -2
- package/core/built/admin/assets/posts-route-D6xmS7Vf.js +0 -1
- package/core/built/admin/assets/profile-B8mx2yAu.js +0 -1
- package/core/built/admin/assets/radio-group-DczlLKOn.js +0 -1
- package/core/built/admin/assets/router-provider-B0gZyiGJ.js +0 -1
- package/core/built/admin/assets/schemas-DppqmpeJ.js +0 -64
- package/core/built/admin/assets/settings-DvfTNdHQ.js +0 -4
- package/core/built/admin/assets/stats-Rjmk5owg.js +0 -1
- package/core/built/admin/assets/stats-view-BGGmkmgv.js +0 -1
- package/core/built/admin/assets/tag-detail-BhXlOsCa.js +0 -2
- package/core/built/admin/assets/tags-ldukRApe.js +0 -1
- package/core/built/admin/assets/tier-detail-modal-BOs8e_G8.js +0 -1
- package/core/built/admin/assets/tiers-Nd_z4BZY.js +0 -1
- package/core/built/admin/assets/use-filter-params-BIni9taJ.js +0 -1
- package/core/built/admin/assets/use-host-limits-DZtR08oa.js +0 -1
- package/core/built/admin/assets/use-pintura-config-h-J0Lvta.js +0 -1
- package/core/built/admin/assets/use-staff-users-Csipb-O0.js +0 -1
- package/core/built/admin/assets/use-upgrade-route-DhRSo7at.js +0 -1
- package/core/built/admin/assets/user-detail-modal-B_iUClI6.js +0 -1
- package/core/built/admin/assets/web-C4BKzn2T.js +0 -1
- package/core/server/services/email-suppression-list/in-memory-email-suppression-list.js +0 -39
- package/core/server/services/members-custom-fields/bindings-service.js +0 -120
- /package/core/built/admin/assets/{chunk.492.f24d855d7e3f3aad261c.js.LICENSE.txt → chunk.901.4ccc639821020230bcca.js.LICENSE.txt} +0 -0
- /package/core/server/services/{members-custom-fields → members-metafields}/storage.js +0 -0
|
@@ -3,21 +3,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.MetafieldValuesService = void 0;
|
|
7
7
|
const bson_objectid_1 = __importDefault(require("bson-objectid"));
|
|
8
8
|
const errors_1 = __importDefault(require("@tryghost/errors"));
|
|
9
9
|
const logging_1 = __importDefault(require("@tryghost/logging"));
|
|
10
10
|
const zod_1 = require("zod");
|
|
11
|
-
const
|
|
12
|
-
const identity_1 = require("@tryghost/
|
|
11
|
+
const metafield_types_1 = require("@tryghost/metafield-types");
|
|
12
|
+
const identity_1 = require("@tryghost/metafield-types/identity");
|
|
13
13
|
const schema_1 = require("./schema");
|
|
14
14
|
const queries_1 = require("./queries");
|
|
15
|
+
const access_1 = require("./access");
|
|
15
16
|
const storage_1 = require("./storage");
|
|
16
|
-
const FIELDS_TABLE = '
|
|
17
|
-
const VALUES_TABLE = '
|
|
17
|
+
const FIELDS_TABLE = 'members_metafields';
|
|
18
|
+
const VALUES_TABLE = 'members_metafield_values';
|
|
18
19
|
/**
|
|
19
20
|
* From the canonical schema, the same source definitions-service reads, so no key a site
|
|
20
|
-
* could hold is refused and this cannot drift from the `
|
|
21
|
+
* could hold is refused and this cannot drift from the `members_metafields.key` column.
|
|
21
22
|
*/
|
|
22
23
|
const MAX_KEY_LENGTH = require('../../data/schema').tables[FIELDS_TABLE].key.maxlength;
|
|
23
24
|
/**
|
|
@@ -38,7 +39,7 @@ const wireProperty = (identity) => [identity_1.QUALIFIER, identity].join('.');
|
|
|
38
39
|
* because a value belongs to the member and a definition belongs to the site's settings,
|
|
39
40
|
* which are different aggregates rather than different layers.
|
|
40
41
|
*/
|
|
41
|
-
class
|
|
42
|
+
class MetafieldValuesService {
|
|
42
43
|
knex;
|
|
43
44
|
/** A getter, not a number: the ceiling is an operator setting that changes between requests. */
|
|
44
45
|
getMaxDefinitions;
|
|
@@ -62,7 +63,7 @@ class CustomFieldValuesService {
|
|
|
62
63
|
{ ...field, namespace: identity_1.CUSTOM_NAMESPACE },
|
|
63
64
|
]));
|
|
64
65
|
}
|
|
65
|
-
async getValuesForMembers(memberIds) {
|
|
66
|
+
async getValuesForMembers(memberIds, audience) {
|
|
66
67
|
if (memberIds.length === 0) {
|
|
67
68
|
return new Map();
|
|
68
69
|
}
|
|
@@ -70,7 +71,7 @@ class CustomFieldValuesService {
|
|
|
70
71
|
// cannot carry an order. `path` is ordered so composite parts assemble the same
|
|
71
72
|
// way every time.
|
|
72
73
|
const rows = await this.knex(VALUES_TABLE)
|
|
73
|
-
.join(FIELDS_TABLE, `${VALUES_TABLE}.
|
|
74
|
+
.join(FIELDS_TABLE, `${VALUES_TABLE}.metafield_key`, `${FIELDS_TABLE}.key`)
|
|
74
75
|
.whereIn(`${VALUES_TABLE}.member_id`, memberIds)
|
|
75
76
|
.where(`${FIELDS_TABLE}.status`, schema_1.FIELD_STATUS.active)
|
|
76
77
|
.orderBy(`${VALUES_TABLE}.path`, 'asc')
|
|
@@ -78,18 +79,21 @@ class CustomFieldValuesService {
|
|
|
78
79
|
const leaves = [];
|
|
79
80
|
for (const row of rows) {
|
|
80
81
|
try {
|
|
81
|
-
leaves.push(schema_1.
|
|
82
|
+
leaves.push(schema_1.DbMetafieldLeaf.parse(row));
|
|
82
83
|
}
|
|
83
84
|
catch (err) {
|
|
84
85
|
logging_1.default.warn({
|
|
85
|
-
event: { name: 'members.
|
|
86
|
+
event: { name: 'members.metafields.value_unreadable' },
|
|
86
87
|
err,
|
|
87
|
-
|
|
88
|
+
metafieldKey: row.key,
|
|
88
89
|
path: row.path,
|
|
89
|
-
}, 'Skipping an unreadable
|
|
90
|
+
}, 'Skipping an unreadable metafield value');
|
|
90
91
|
}
|
|
91
92
|
}
|
|
92
|
-
|
|
93
|
+
// Narrowed before assembly, not after: a composite is one value spread across
|
|
94
|
+
// several rows, and dropping some of its parts later would hand back half an
|
|
95
|
+
// address rather than no address.
|
|
96
|
+
const flat = (0, storage_1.valuesFromLeaves)((0, access_1.readableFields)(audience, leaves));
|
|
93
97
|
return new Map(memberIds.map((memberId) => [memberId, { [identity_1.CUSTOM_NAMESPACE]: flat.get(memberId) ?? {} }]));
|
|
94
98
|
}
|
|
95
99
|
parseValues(input) {
|
|
@@ -141,7 +145,7 @@ class CustomFieldValuesService {
|
|
|
141
145
|
* validate before opening a transaction it would otherwise have to unwind, then apply
|
|
142
146
|
* the same plan without re-resolving it.
|
|
143
147
|
*/
|
|
144
|
-
async planWrite(input) {
|
|
148
|
+
async planWrite(input, audience) {
|
|
145
149
|
const values = this.parseValues(input);
|
|
146
150
|
const identities = Object.keys(values);
|
|
147
151
|
// Bounded by the definitions ceiling, which also holds the lookup below inside
|
|
@@ -163,10 +167,16 @@ class CustomFieldValuesService {
|
|
|
163
167
|
property: wireProperty(identity),
|
|
164
168
|
});
|
|
165
169
|
}
|
|
170
|
+
if (!(0, access_1.canWrite)(audience, field)) {
|
|
171
|
+
throw new errors_1.default.ValidationError({
|
|
172
|
+
message: `Cannot set custom field: ${identity}`,
|
|
173
|
+
property: wireProperty(identity),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
166
176
|
// `null` clears any field, and `''` clears one with no parts. For a value
|
|
167
177
|
// with parts `''` names nothing, so it is left to fail validation rather than
|
|
168
178
|
// being read as a silent delete.
|
|
169
|
-
if (raw === null || (raw === '' && (0,
|
|
179
|
+
if (raw === null || (raw === '' && (0, metafield_types_1.subFieldsOf)(field.type) === null)) {
|
|
170
180
|
writes.push({ field });
|
|
171
181
|
continue;
|
|
172
182
|
}
|
|
@@ -174,7 +184,7 @@ class CustomFieldValuesService {
|
|
|
174
184
|
// `context` when `context` is empty and prepends it when it is not, so
|
|
175
185
|
// anything added here reaches the client glued to the front of the reason.
|
|
176
186
|
// Which field failed rides in `property`.
|
|
177
|
-
const value =
|
|
187
|
+
const value = metafield_types_1.FIELD_TYPES[field.type].value.safeParse(raw);
|
|
178
188
|
if (!value.success) {
|
|
179
189
|
const issue = value.error.issues[0];
|
|
180
190
|
throw new errors_1.default.ValidationError({
|
|
@@ -224,7 +234,7 @@ class CustomFieldValuesService {
|
|
|
224
234
|
rows.push(...set.map((leaf) => ({
|
|
225
235
|
id: new bson_objectid_1.default().toHexString(),
|
|
226
236
|
member_id: memberId,
|
|
227
|
-
|
|
237
|
+
metafield_key: field.key,
|
|
228
238
|
path: leaf.path,
|
|
229
239
|
value_text: leaf.value_text,
|
|
230
240
|
written_by_type: writtenBy.type,
|
|
@@ -236,7 +246,7 @@ class CustomFieldValuesService {
|
|
|
236
246
|
if (clearedKeys.length > 0) {
|
|
237
247
|
await trx(VALUES_TABLE)
|
|
238
248
|
.where('member_id', memberId)
|
|
239
|
-
.whereIn('
|
|
249
|
+
.whereIn('metafield_key', clearedKeys)
|
|
240
250
|
.del();
|
|
241
251
|
}
|
|
242
252
|
if (clearedPaths.length > 0) {
|
|
@@ -245,7 +255,7 @@ class CustomFieldValuesService {
|
|
|
245
255
|
.where('member_id', memberId)
|
|
246
256
|
.where((builder) => {
|
|
247
257
|
for (const { fieldKey, paths } of clearedPaths) {
|
|
248
|
-
builder.orWhere((pair) => pair.where('
|
|
258
|
+
builder.orWhere((pair) => pair.where('metafield_key', fieldKey).whereIn('path', paths));
|
|
249
259
|
}
|
|
250
260
|
})
|
|
251
261
|
.del();
|
|
@@ -258,7 +268,7 @@ class CustomFieldValuesService {
|
|
|
258
268
|
.insert(rows.slice(from, from + UPSERT_CHUNK))
|
|
259
269
|
// Naming the columns rather than giving values takes each from the row
|
|
260
270
|
// that lost the conflict, so every part updates to its own value.
|
|
261
|
-
.onConflict(['member_id', '
|
|
271
|
+
.onConflict(['member_id', 'metafield_key', 'path'])
|
|
262
272
|
// The writer is merged with the value, so a leaf names who wrote what
|
|
263
273
|
// it currently holds rather than who wrote its first value.
|
|
264
274
|
.merge(['value_text', 'written_by_type', 'written_by_id', 'updated_at']);
|
|
@@ -273,4 +283,4 @@ class CustomFieldValuesService {
|
|
|
273
283
|
}
|
|
274
284
|
}
|
|
275
285
|
}
|
|
276
|
-
exports.
|
|
286
|
+
exports.MetafieldValuesService = MetafieldValuesService;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const errors = require('@tryghost/errors');
|
|
2
2
|
const logging = require('@tryghost/logging');
|
|
3
|
+
const SendWebmentionsJob = require('./send-webmentions-job').default;
|
|
3
4
|
|
|
4
5
|
module.exports = class MentionSendingService {
|
|
5
6
|
#discoveryService;
|
|
@@ -8,8 +9,12 @@ module.exports = class MentionSendingService {
|
|
|
8
9
|
#getPostData;
|
|
9
10
|
#getPostUrl;
|
|
10
11
|
#isEnabled;
|
|
11
|
-
#
|
|
12
|
+
#jobsService;
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* @param {object} deps
|
|
16
|
+
* @param {import('../jobs-service/jobs-service').JobsService} deps.jobsService
|
|
17
|
+
*/
|
|
13
18
|
constructor({
|
|
14
19
|
discoveryService,
|
|
15
20
|
externalRequest,
|
|
@@ -17,7 +22,7 @@ module.exports = class MentionSendingService {
|
|
|
17
22
|
getPostData,
|
|
18
23
|
getPostUrl,
|
|
19
24
|
isEnabled,
|
|
20
|
-
|
|
25
|
+
jobsService,
|
|
21
26
|
}) {
|
|
22
27
|
this.#discoveryService = discoveryService;
|
|
23
28
|
this.#externalRequest = externalRequest;
|
|
@@ -25,7 +30,7 @@ module.exports = class MentionSendingService {
|
|
|
25
30
|
this.#getPostData = getPostData;
|
|
26
31
|
this.#getPostUrl = getPostUrl;
|
|
27
32
|
this.#isEnabled = isEnabled;
|
|
28
|
-
this.#
|
|
33
|
+
this.#jobsService = jobsService;
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
get siteUrl() {
|
|
@@ -82,13 +87,13 @@ module.exports = class MentionSendingService {
|
|
|
82
87
|
// Capture the source URL now, from the event's data, rather than
|
|
83
88
|
// deferring the model into the job.
|
|
84
89
|
const url = new URL(await this.#resolvePostUrl(post));
|
|
85
|
-
await this.#
|
|
86
|
-
|
|
87
|
-
url,
|
|
90
|
+
await this.#jobsService.dispatch(
|
|
91
|
+
new SendWebmentionsJob({
|
|
92
|
+
sourceUrl: url.href,
|
|
88
93
|
html: html,
|
|
89
94
|
previousHtml: previousHtml,
|
|
90
|
-
})
|
|
91
|
-
|
|
95
|
+
}),
|
|
96
|
+
);
|
|
92
97
|
}
|
|
93
98
|
} catch (e) {
|
|
94
99
|
logging.error('Error in webmention sending service post update event handler:');
|
|
@@ -157,11 +162,23 @@ module.exports = class MentionSendingService {
|
|
|
157
162
|
});
|
|
158
163
|
}
|
|
159
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Send the webmentions for a delivered job.
|
|
167
|
+
* @param {import('./send-webmentions-job').default} job
|
|
168
|
+
*/
|
|
169
|
+
async sendWebmentions(job) {
|
|
170
|
+
await this.sendForHTMLResource({
|
|
171
|
+
url: new URL(job.sourceUrl),
|
|
172
|
+
html: job.html,
|
|
173
|
+
previousHtml: job.previousHtml,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
160
177
|
/**
|
|
161
178
|
* Send a webmention call for the links in a resource.
|
|
162
179
|
* @param {object} resource
|
|
163
180
|
* @param {URL} resource.url
|
|
164
|
-
* @param {string} resource.html
|
|
181
|
+
* @param {string|null} resource.html
|
|
165
182
|
* @param {string|null} [resource.previousHtml]
|
|
166
183
|
*/
|
|
167
184
|
async sendForHTMLResource(resource) {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const job_1 = require("../jobs-service/job");
|
|
4
|
+
// Carries the post's full html twice - the largest job payload in the system;
|
|
5
|
+
// revisit if a durable backend puts size limits on envelopes.
|
|
6
|
+
class SendWebmentionsJob extends job_1.Job {
|
|
7
|
+
static type = 'send-webmentions';
|
|
8
|
+
sourceUrl;
|
|
9
|
+
html;
|
|
10
|
+
previousHtml;
|
|
11
|
+
constructor({ sourceUrl, html, previousHtml, }) {
|
|
12
|
+
super();
|
|
13
|
+
this.sourceUrl = sourceUrl;
|
|
14
|
+
this.html = html ?? null;
|
|
15
|
+
this.previousHtml = previousHtml ?? null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.default = SendWebmentionsJob;
|
|
@@ -14,8 +14,6 @@ const outputSerializerUrlUtil = require('../../../server/api/endpoints/utils/ser
|
|
|
14
14
|
const urlService = require('../url');
|
|
15
15
|
const settingsCache = require('../../../shared/settings-cache');
|
|
16
16
|
const DomainEvents = require('@tryghost/domain-events');
|
|
17
|
-
const logging = require('@tryghost/logging');
|
|
18
|
-
const mentionsJobService = require('../mentions-jobs');
|
|
19
17
|
|
|
20
18
|
// Serializes a post model to the data the URL service needs, loading the
|
|
21
19
|
// relations it reads for filtered collections (event-emitted models don't
|
|
@@ -38,33 +36,6 @@ function getPostUrl(id, postData) {
|
|
|
38
36
|
return jsonModel.url;
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
// Reports the same queued/started/finished/failed lifecycle for every mentions
|
|
42
|
-
// background job. The wrapped callback's result and errors pass through unchanged,
|
|
43
|
-
// so job manager outcomes and retries are unaffected.
|
|
44
|
-
function makeLoggingJobService() {
|
|
45
|
-
return {
|
|
46
|
-
async addJob(name, fn) {
|
|
47
|
-
logging.info(`[Background Job] ${name} queued`);
|
|
48
|
-
mentionsJobService.addJob({
|
|
49
|
-
name,
|
|
50
|
-
job: async () => {
|
|
51
|
-
const startedAt = Date.now();
|
|
52
|
-
logging.info(`[Background Job] ${name} started`);
|
|
53
|
-
try {
|
|
54
|
-
const result = await fn();
|
|
55
|
-
logging.info(`[Background Job] ${name} completed in ${Date.now() - startedAt}ms`);
|
|
56
|
-
return result;
|
|
57
|
-
} catch (err) {
|
|
58
|
-
logging.error(err, `[Background Job] ${name} failed after ${Date.now() - startedAt}ms`);
|
|
59
|
-
throw err;
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
offloaded: false,
|
|
63
|
-
});
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
39
|
module.exports = {
|
|
69
40
|
/** @type {import('./mentions-api')} */
|
|
70
41
|
api: null,
|
|
@@ -141,7 +112,7 @@ module.exports = {
|
|
|
141
112
|
getPostData: (post) => getPostData(post),
|
|
142
113
|
getPostUrl: (id, data) => getPostUrl(id, data),
|
|
143
114
|
isEnabled: () => !settingsCache.get('is_private'),
|
|
144
|
-
|
|
115
|
+
jobsService,
|
|
145
116
|
});
|
|
146
117
|
sendingService.listen(events);
|
|
147
118
|
|
|
@@ -152,4 +123,3 @@ module.exports = {
|
|
|
152
123
|
// exposed for testing
|
|
153
124
|
module.exports.getPostData = getPostData;
|
|
154
125
|
module.exports.getPostUrl = getPostUrl;
|
|
155
|
-
module.exports.makeLoggingJobService = makeLoggingJobService;
|
|
@@ -453,7 +453,7 @@ module.exports = class CheckoutSessionEventService {
|
|
|
453
453
|
|
|
454
454
|
/**
|
|
455
455
|
* This service knows how to read a completed Stripe session. It does not know, and must
|
|
456
|
-
* not know, which
|
|
456
|
+
* not know, which metafield any of those values belongs in — that is what a binding
|
|
457
457
|
* decides, so no field key appears anywhere in this code.
|
|
458
458
|
*
|
|
459
459
|
* Nothing here may be fatal: a throw fails the webhook, which makes Stripe retry it and
|
|
@@ -493,7 +493,7 @@ module.exports = class CheckoutSessionEventService {
|
|
|
493
493
|
return;
|
|
494
494
|
}
|
|
495
495
|
|
|
496
|
-
await this.deps.
|
|
496
|
+
await this.deps.metafieldBindings.writeCollected(
|
|
497
497
|
memberId,
|
|
498
498
|
tierId,
|
|
499
499
|
collectedByPort.parse(session),
|
|
@@ -10,7 +10,7 @@ const InvoiceEventService = require('./services/webhook/invoice-event-service');
|
|
|
10
10
|
const CheckoutSessionEventService = require('./services/webhook/checkout-session-event-service');
|
|
11
11
|
const ChargeRefundedEventService = require('./services/webhook/charge-refunded-event-service');
|
|
12
12
|
const memberWelcomeEmailService = require('../member-welcome-emails/service');
|
|
13
|
-
const
|
|
13
|
+
const metafields = require('../members-metafields');
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* @typedef {object} IStripeServiceConfig
|
|
@@ -135,10 +135,10 @@ module.exports = class StripeService {
|
|
|
135
135
|
memberWelcomeEmailService.init();
|
|
136
136
|
return memberWelcomeEmailService.api.isMemberWelcomeEmailActive('paid');
|
|
137
137
|
},
|
|
138
|
-
// A getter because the
|
|
138
|
+
// A getter because the metafields services are built during boot: reading the
|
|
139
139
|
// binding at construction would capture the empty value it had beforehand.
|
|
140
|
-
get
|
|
141
|
-
return
|
|
140
|
+
get metafieldBindings() {
|
|
141
|
+
return metafields.bindings;
|
|
142
142
|
},
|
|
143
143
|
});
|
|
144
144
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.questionRowCodec = exports.QuestionRow = exports.collectionRowCodec = exports.CollectionRow = exports.optionsCodec = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
|
-
const
|
|
5
|
+
const metafield_types_1 = require("@tryghost/metafield-types");
|
|
6
6
|
const boolean_1 = require("../../lib/db-types/boolean");
|
|
7
7
|
const schema_1 = require("./schema");
|
|
8
8
|
const models_1 = require("./models");
|
|
@@ -67,7 +67,7 @@ exports.QuestionRow = zod_1.z.object({
|
|
|
67
67
|
label: schema_1.DbCheckoutQuestion.shape.label,
|
|
68
68
|
optional: schema_1.DbCheckoutQuestion.shape.optional,
|
|
69
69
|
question_name: zod_1.z.string().nullable(),
|
|
70
|
-
question_type:
|
|
70
|
+
question_type: metafield_types_1.FieldTypeSchema.nullable(),
|
|
71
71
|
});
|
|
72
72
|
exports.questionRowCodec = exports.QuestionRow.transform((row) => ({
|
|
73
73
|
tierId: row.product_id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toCheckoutConfigResponse = exports.TierCheckoutConfig = exports.ShippingCollection = exports.ResolvedQuestion = exports.ResolvedCheckout = exports.PhoneCollection = exports.emptyCheckoutConfig = exports.CheckoutQuestion = exports.TierCheckoutConfigService = void 0;
|
|
3
|
+
exports.requirementsByTier = exports.toCheckoutConfigResponse = exports.TierCheckoutConfig = exports.ShippingCollection = exports.ResolvedQuestion = exports.ResolvedCheckout = exports.PhoneCollection = exports.emptyCheckoutConfig = exports.CheckoutQuestion = exports.TierCheckoutConfigService = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* What a tier's checkout asks and collects.
|
|
6
6
|
*
|
|
@@ -24,3 +24,4 @@ Object.defineProperty(exports, "ShippingCollection", { enumerable: true, get: fu
|
|
|
24
24
|
Object.defineProperty(exports, "TierCheckoutConfig", { enumerable: true, get: function () { return models_1.TierCheckoutConfig; } });
|
|
25
25
|
var serializers_1 = require("./serializers");
|
|
26
26
|
Object.defineProperty(exports, "toCheckoutConfigResponse", { enumerable: true, get: function () { return serializers_1.toCheckoutConfigResponse; } });
|
|
27
|
+
Object.defineProperty(exports, "requirementsByTier", { enumerable: true, get: function () { return serializers_1.requirementsByTier; } });
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ResolvedCheckout = exports.ResolvedQuestion = exports.CheckoutOptions = exports.emptyCheckoutConfig = exports.emptyCollection = exports.TierCheckoutConfig = exports.PhoneCollection = exports.ShippingCollection = exports.CheckoutQuestion = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
|
-
const
|
|
5
|
+
const metafield_types_1 = require("@tryghost/metafield-types");
|
|
6
6
|
exports.CheckoutQuestion = zod_1.z.object({
|
|
7
7
|
key: zod_1.z.string(),
|
|
8
8
|
label: zod_1.z.string().nullable(),
|
|
@@ -53,7 +53,7 @@ exports.CheckoutOptions = zod_1.z.object({
|
|
|
53
53
|
});
|
|
54
54
|
exports.ResolvedQuestion = exports.CheckoutQuestion.extend({
|
|
55
55
|
prompt: zod_1.z.string(),
|
|
56
|
-
type:
|
|
56
|
+
type: metafield_types_1.FieldTypeSchema,
|
|
57
57
|
});
|
|
58
58
|
exports.ResolvedCheckout = zod_1.z.object({
|
|
59
59
|
customFields: zod_1.z.array(exports.ResolvedQuestion),
|
|
@@ -4,13 +4,13 @@ exports.FIELDS_TABLE = exports.BINDINGS_TABLE = exports.CONFIG_TABLE = exports.Q
|
|
|
4
4
|
exports.collectionRowsForTier = collectionRowsForTier;
|
|
5
5
|
exports.configuredCollectionRows = configuredCollectionRows;
|
|
6
6
|
exports.questionRows = questionRows;
|
|
7
|
-
const schema_1 = require("../members-
|
|
7
|
+
const schema_1 = require("../members-metafields/schema");
|
|
8
8
|
const checkout_1 = require("@tryghost/checkout");
|
|
9
9
|
const schema_2 = require("./schema");
|
|
10
10
|
exports.QUESTIONS_TABLE = 'products_checkout_fields';
|
|
11
11
|
exports.CONFIG_TABLE = 'products_checkout_config';
|
|
12
|
-
exports.BINDINGS_TABLE = '
|
|
13
|
-
exports.FIELDS_TABLE = '
|
|
12
|
+
exports.BINDINGS_TABLE = 'members_metafield_bindings';
|
|
13
|
+
exports.FIELDS_TABLE = 'members_metafields';
|
|
14
14
|
const ACTIVE = schema_1.FIELD_STATUS.active;
|
|
15
15
|
const optionColumns = Object.keys(schema_2.DbCheckoutOptions.shape).map((column) => `${exports.CONFIG_TABLE}.${column}`);
|
|
16
16
|
function collectionQuery(db) {
|
|
@@ -18,7 +18,7 @@ function collectionQuery(db) {
|
|
|
18
18
|
this.on(`${alias}.product_id`, 'products.id').andOn(db.raw(`${alias}.port = ?`, [port]));
|
|
19
19
|
};
|
|
20
20
|
const landsIn = (alias, binding) => function () {
|
|
21
|
-
this.on(`${alias}.key`, `${binding}.
|
|
21
|
+
this.on(`${alias}.key`, `${binding}.metafield_key`).andOn(db.raw(`${alias}.status = ?`, [ACTIVE]));
|
|
22
22
|
};
|
|
23
23
|
const query = db('products')
|
|
24
24
|
.leftJoin(exports.CONFIG_TABLE, `${exports.CONFIG_TABLE}.product_id`, 'products.id')
|
|
@@ -33,11 +33,11 @@ function collectionQuery(db) {
|
|
|
33
33
|
'products.id as product_id',
|
|
34
34
|
`${exports.CONFIG_TABLE}.id as config_id`,
|
|
35
35
|
...optionColumns,
|
|
36
|
-
'name_binding.
|
|
36
|
+
'name_binding.metafield_key as shipping_name_key',
|
|
37
37
|
'name_field.key as shipping_name_collectable',
|
|
38
|
-
'shipping_binding.
|
|
38
|
+
'shipping_binding.metafield_key as shipping_address_key',
|
|
39
39
|
'shipping_field.key as shipping_address_collectable',
|
|
40
|
-
'phone_binding.
|
|
40
|
+
'phone_binding.metafield_key as phone_key',
|
|
41
41
|
'phone_field.key as phone_collectable',
|
|
42
42
|
]);
|
|
43
43
|
return query;
|
|
@@ -60,7 +60,7 @@ function questionRows(db, productId) {
|
|
|
60
60
|
const query = db(exports.QUESTIONS_TABLE)
|
|
61
61
|
.join(exports.BINDINGS_TABLE, `${exports.BINDINGS_TABLE}.id`, `${exports.QUESTIONS_TABLE}.binding_id`)
|
|
62
62
|
.leftJoin({ question_field: exports.FIELDS_TABLE }, function () {
|
|
63
|
-
this.on('question_field.key', `${exports.BINDINGS_TABLE}.
|
|
63
|
+
this.on('question_field.key', `${exports.BINDINGS_TABLE}.metafield_key`).andOn(db.raw('question_field.status = ?', [ACTIVE]));
|
|
64
64
|
})
|
|
65
65
|
.orderBy(`${exports.BINDINGS_TABLE}.product_id`, 'asc')
|
|
66
66
|
.orderBy(`${exports.QUESTIONS_TABLE}.sort_order`, 'asc')
|
|
@@ -1,6 +1,7 @@
|
|
|
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
6
|
const checkout_1 = require("@tryghost/checkout");
|
|
6
7
|
const models_1 = require("./models");
|
|
@@ -126,3 +127,59 @@ exports.toCheckoutConfigResponse = zod_1.z
|
|
|
126
127
|
})),
|
|
127
128
|
}))
|
|
128
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,7 +7,7 @@ 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-
|
|
10
|
+
const schema_1 = require("../members-metafields/schema");
|
|
11
11
|
const checkout_1 = require("@tryghost/checkout");
|
|
12
12
|
const codec_1 = require("./codec");
|
|
13
13
|
const queries_1 = require("./queries");
|
|
@@ -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
|
|
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
|
|
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-
|
|
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
|
|
@@ -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
|
|
8
|
-
const
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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({
|
|
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
|
}
|