ghost 6.64.0 → 6.65.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/bin/create-migration.js +15 -0
- package/components/tryghost-adapter-base-scheduling-0.2.4.tgz +0 -0
- package/components/tryghost-api-framework-0.0.0.tgz +0 -0
- package/components/tryghost-i18n-0.0.0.tgz +0 -0
- package/components/tryghost-kg-default-cards-10.3.6.tgz +0 -0
- package/components/tryghost-kg-lexical-html-renderer-1.5.1.tgz +0 -0
- package/components/tryghost-metafield-types-0.0.0.tgz +0 -0
- package/content/themes/casper/assets/built/casper.js +1 -1
- package/content/themes/casper/assets/built/screen.css +1 -1
- package/content/themes/casper/assets/css/screen.css +15 -2
- package/content/themes/casper/assets/js/init.js +37 -9
- package/content/themes/casper/package.json +8 -8
- package/content/themes/source/assets/built/screen.css +1 -1
- package/content/themes/source/assets/built/source.js +1 -1
- package/content/themes/source/assets/css/screen.css +14 -1
- package/content/themes/source/assets/js/main.js +24 -4
- package/content/themes/source/package.json +7 -7
- package/core/boot.js +22 -16
- package/core/bridge.js +1 -1
- package/core/built/admin/assets/Combination-DQ6f9A5P.js +41 -0
- package/core/built/admin/assets/{PolarAngleAxis-a81ieQUO.js → PolarAngleAxis-BBaU7PRV.js} +1 -1
- package/core/built/admin/assets/RadialBarChart-Bp20JPnA.js +1 -0
- package/core/built/admin/assets/{about-39CAfroa.js → about-Dp43j18M.js} +1 -1
- package/core/built/admin/assets/accordion-h62UzFhj.js +1 -0
- package/core/built/admin/assets/account-migration-CBTbtX6Q.js +1 -0
- package/core/built/admin/assets/action-list-DC9QpX-l.js +1 -0
- package/core/built/admin/assets/activitypub/{account-migration-KA6Jjf9L.js → account-migration-B1DUZS4Q.js} +8 -8
- package/core/built/admin/assets/activitypub/activitypub.js +24 -11
- package/core/built/admin/assets/activitypub/avatar-CRGud8yf.js +153 -0
- package/core/built/admin/assets/activitypub/{avatar-flipboard-csQaNeYK.js → avatar-flipboard-BZNFAXfm.js} +3 -3
- package/core/built/admin/assets/activitypub/{bluesky-sharing-C7nTDMvw.js → bluesky-sharing-Cg_v-LwS.js} +30 -31
- package/core/built/admin/assets/activitypub/{chunk-KS7C4IRE-Ck3O4oo2.js → chunk-KS7C4IRE-CTUL98Lc.js} +2498 -1885
- package/core/built/admin/assets/activitypub/{content-formatters-CLcjaBwV.js → content-formatters-D7GWP7nH.js} +23 -24
- package/core/built/admin/assets/activitypub/{copy-DcOh8kXw.js → copy-CgzTvoeR.js} +2 -2
- package/core/built/admin/assets/activitypub/{domain-fZ-X8i4-.js → domain-C3G_nkHU.js} +46 -46
- package/core/built/admin/assets/activitypub/{edit-profile-BqMLQV88.js → edit-profile-C8cCY-AK.js} +927 -928
- package/core/built/admin/assets/activitypub/{explore-B4yPoP8E.js → explore-NlDT4inq.js} +11 -11
- package/core/built/admin/assets/activitypub/{feed-BRC_mvAe.js → feed-DF22jCTV.js} +10 -10
- package/core/built/admin/assets/activitypub/{field-COacNgOt.js → field-95-iuTte.js} +4 -4
- package/core/built/admin/assets/activitypub/{hash-C7u-irQQ.js → hash-R7LMLnhY.js} +2 -2
- package/core/built/admin/assets/activitypub/{inbox-CbTTdDQ3.js → inbox-DUJUiV6x.js} +2 -2
- package/core/built/admin/assets/activitypub/{inbox-BW-yvUoN.js → inbox-DerExBzA.js} +416 -414
- package/core/built/admin/assets/activitypub/{label-kPMmYI7l.js → label-EwCn1QYc.js} +4 -4
- package/core/built/admin/assets/activitypub/layout-Dy6NnW1G.js +1 -0
- package/core/built/admin/assets/activitypub/{moderation-CuidJzc0.js → moderation-BSkfiVYo.js} +73 -75
- package/core/built/admin/assets/activitypub/{note-CAMRRSqD.js → note-DOnAJTXK.js} +9 -9
- package/core/built/admin/assets/activitypub/{notifications-BmNlXGgp.js → notifications-DZc6XTjG.js} +27 -27
- package/core/built/admin/assets/activitypub/{onboarding-Dmun9jr_.js → onboarding-8vEIwYTH.js} +3 -3
- package/core/built/admin/assets/activitypub/{onboarding-Bqg7fh_L.js → onboarding-DYVqbNmp.js} +2 -2
- package/core/built/admin/assets/activitypub/{preferences--oH19wf9.js → preferences-DDok6F2N.js} +1418 -1390
- package/core/built/admin/assets/activitypub/{profile-DH_tQx2D.js → profile-DjVa2hUk.js} +254 -255
- package/core/built/admin/assets/activitypub/{reply-Cap9PxSH.js → reply-DtXBpHxu.js} +2 -2
- package/core/built/admin/assets/activitypub/routes-Cw302e1c.js +4946 -0
- package/core/built/admin/assets/activitypub/{separator-CAxxu8VV.js → separator-FpRpVDd3.js} +8 -9
- package/core/built/admin/assets/activitypub/settings-yK-puALn.js +314 -0
- package/core/built/admin/assets/activitypub/{site-BYps63oh.js → site-CHw0R2PA.js} +2 -2
- package/core/built/admin/assets/activitypub/{step-1-CKjR2KAm.js → step-1-737bnvxk.js} +7 -7
- package/core/built/admin/assets/activitypub/{step-2-B6PKfOUQ.js → step-2-DBaIsAsM.js} +7 -7
- package/core/built/admin/assets/activitypub/{step-3-C-qBbcUo.js → step-3-BBmy9m9V.js} +23 -23
- package/core/built/admin/assets/activitypub/tabs-LQ2xirdm.js +1101 -0
- package/core/built/admin/assets/activitypub/{topic-filter-DsUOuu0k.js → topic-filter-75Nu0CKj.js} +4 -4
- package/core/built/admin/assets/activitypub/{use-activity-pub-queries-CX9snsLs.js → use-activity-pub-queries-CYI2QJMs.js} +58 -58
- package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-DsJTGDSS.js → use-navigate-with-base-path-B4jZ8hyg.js} +3924 -1403
- package/core/built/admin/assets/activitypub/{use-reply-chain-data-AJi9zkzm.js → use-reply-chain-data-BHmFxc3U.js} +6 -6
- package/core/built/admin/assets/activitypub/users-CSjOwpT9.js +886 -0
- package/core/built/admin/assets/activitypub/{x-DR8AT3-4.js → x-B9ptWCds.js} +2 -2
- package/core/built/admin/assets/{add-integration-modal-B12oRifD.js → add-integration-modal-BwePhq95.js} +1 -1
- package/core/built/admin/assets/add-newsletter-modal-Zv0I7Msm.js +1 -0
- package/core/built/admin/assets/{add-recommendation-modal-CJf92edY.js → add-recommendation-modal-cdLv0wHy.js} +1 -1
- package/core/built/admin/assets/analytics-DY8_SaP7.js +1 -0
- package/core/built/admin/assets/announcement-bar-modal-C-2yWwag.js +1 -0
- package/core/built/admin/assets/api-keys-BHKATUqQ.js +1 -0
- package/core/built/admin/assets/{audience-6GXevic-.js → audience-wRcSN0jV.js} +1 -1
- package/core/built/admin/assets/{automated-emails-DJQ4uNZo.js → automated-emails-CzUa3v4d.js} +1 -1
- package/core/built/admin/assets/automations-DupSsSOr.js +1 -0
- package/core/built/admin/assets/badge-CI1Z0xyG.js +1 -0
- package/core/built/admin/assets/bluesky-sharing-B8PC1SBj.js +1 -0
- package/core/built/admin/assets/box-LUuYRT-1.js +1 -0
- package/core/built/admin/assets/brand-icon-CrmbX86T.js +1 -0
- package/core/built/admin/assets/breadcrumb-DDDpzLyo.js +1 -0
- package/core/built/admin/assets/button-D414TI3B.js +1 -0
- package/core/built/admin/assets/calendar-Cp_opo3i.js +1 -0
- package/core/built/admin/assets/card-C2dfd5u0.js +1 -0
- package/core/built/admin/assets/chart-B_UNLXse.js +63 -0
- package/core/built/admin/assets/chart-helpers-Czu_9QpJ.js +1 -0
- package/core/built/admin/assets/checkbox-CFFqf0Nh.js +1 -0
- package/core/built/admin/assets/{chunk.368.22ce1b732c0b40abd3f1.js → chunk.201.6961b57ed7a281ac193e.js} +23 -19
- package/core/built/admin/assets/chunk.524.0b850e72ec49a0fa3882.js +25 -0
- package/core/built/admin/assets/chunk.582.db2ae9e968256e8d58ac.js +27 -0
- package/core/built/admin/assets/code-editor-view-Bd_nnHKk.js +1 -0
- package/core/built/admin/assets/code-editor-view-BeU3Yf9M.js +1 -0
- package/core/built/admin/assets/color-picker-Bzm1V7qg.js +3 -0
- package/core/built/admin/assets/color-picker-field-DP0moHz9.js +1 -0
- package/core/built/admin/assets/combobox-6_ruuTuj.js +1 -0
- package/core/built/admin/assets/command-B5wfm6pd.js +1 -0
- package/core/built/admin/assets/comments-BB26dUSl.js +1 -0
- package/core/built/admin/assets/confirmation-context-znVJD4pX.js +1 -0
- package/core/built/admin/assets/container-CHHif8km.js +1 -0
- package/core/built/admin/assets/{content-api-modal-0ZjuLcQ8.js → content-api-modal-DOHwl0yZ.js} +1 -1
- package/core/built/admin/assets/context-menu-BpY46Dlb.js +1 -0
- package/core/built/admin/assets/copy-field-DRBx6Ady.js +1 -0
- package/core/built/admin/assets/create-ghost-browse-value-source-eIXo5Qws.js +1 -0
- package/core/built/admin/assets/custom-field-type-option-DrSlETOI.js +1 -0
- package/core/built/admin/assets/custom-integration-modal-Dgo425Ec.js +1 -0
- package/core/built/admin/assets/data-list-DM8yqpXi.js +1 -0
- package/core/built/admin/assets/date-range-select-DdC23c13.js +1 -0
- package/core/built/admin/assets/design-and-theme-modal-CbSu9IT4.js +2 -0
- package/core/built/admin/assets/detail-page-CN4NdhpV.js +1 -0
- package/core/built/admin/assets/dirty-confirm-dialog-BT_Vq9TD.js +1 -0
- package/core/built/admin/assets/{disabled-sources-indicator-CLZhMv8J.js → disabled-sources-indicator-C5xtW0Q2.js} +1 -1
- package/core/built/admin/assets/dist-B40T-RCQ.js +1 -0
- package/core/built/admin/assets/dist-CrlaEoaK.js +1 -0
- package/core/built/admin/assets/domain-BPReCZa8.js +1 -0
- package/core/built/admin/assets/dropzone-B2auMkf2.js +5 -0
- package/core/built/admin/assets/edit-profile-B7XTBzKe.js +1 -0
- package/core/built/admin/assets/editor-BcaC9dqm.js +8 -0
- package/core/built/admin/assets/editor-screen-FuMpItC8.js +27 -0
- package/core/built/admin/assets/email-sending-status-provider-9d81o1C2.js +1 -0
- package/core/built/admin/assets/embed-signup-form-modal-CbVbMsxl.js +8 -0
- package/core/built/admin/assets/empty-indicator-CSQts7GV.js +1 -0
- package/core/built/admin/assets/explore-DbSXFTJN.js +1 -0
- package/core/built/admin/assets/feature-image-placeholder-DFXA4vfJ.js +1 -0
- package/core/built/admin/assets/feed-W7RlF-Gp.js +1 -0
- package/core/built/admin/assets/field-BXEh3ptU.js +1 -0
- package/core/built/admin/assets/filter-sources-DHK2IoCk.js +1 -0
- package/core/built/admin/assets/filters-0SYNTqyQ.js +1 -0
- package/core/built/admin/assets/filters-DTtZKQyq.js +1 -0
- package/core/built/admin/assets/{first-promoter-modal-wr73Dldc.js → first-promoter-modal-DcoN_OXu.js} +1 -1
- package/core/built/admin/assets/{ghost-a1e6e172c6917e8ef8fa6b0007756d9b.js → ghost-25495154132af7305cb7b646fd83f48f.js} +562 -514
- package/core/built/admin/assets/gift-link-modal-BX-Q1TOk.js +1 -0
- package/core/built/admin/assets/grid-BEUIDQX7.js +1 -0
- package/core/built/admin/assets/growth-G6PLO4aF.js +1 -0
- package/core/built/admin/assets/growth-tkD-fBOY.js +3 -0
- package/core/built/admin/assets/heading-ih-fOVqF.js +1 -0
- package/core/built/admin/assets/history-modal-Ca-gStoq.js +1 -0
- package/core/built/admin/assets/html-field-B3CrKV9Y.js +1 -0
- package/core/built/admin/assets/images-H-BIm8OQ.js +1 -0
- package/core/built/admin/assets/{inbox-DgSZ6w2p.js → inbox-DBbDVMPz.js} +14 -14
- package/core/built/admin/assets/index-DOF2jDq0.js +4 -0
- package/core/built/admin/assets/index-JrrNchW1.css +2 -0
- package/core/built/admin/assets/input-group-CvH-3d3F.js +1 -0
- package/core/built/admin/assets/input-surface-CL23Mlh8.js +1 -0
- package/core/built/admin/assets/integration-header-C7GXGis_.js +1 -0
- package/core/built/admin/assets/invite-user-modal-EJ2_6RpV.js +1 -0
- package/core/built/admin/assets/isPlainObject-BzzgUf1E.js +1 -0
- package/core/built/admin/assets/{koenig-lexical-CXVgQFUk.js → koenig-lexical-Dkwee5FG.js} +1 -1
- package/core/built/admin/assets/koenig-loader-BzXCXHoA.js +2 -0
- package/core/built/admin/assets/kpi-card-iCDUTgOR.js +1 -0
- package/core/built/admin/assets/kpi-card-jTnpLKGr.js +1 -0
- package/core/built/admin/assets/kpi-helpers-Criu0YAf.js +1 -0
- package/core/built/admin/assets/kpi-tabs-DbOmmyOo.js +1 -0
- package/core/built/admin/assets/label-Du0yqMqL.js +1 -0
- package/core/built/admin/assets/label-picker-Bq1XXr1D.js +1 -0
- package/core/built/admin/assets/{labels-KMkFoRG6.js → labels-0x2NfLtC.js} +1 -1
- package/core/built/admin/assets/layout-Ckwzsnsu.js +1 -0
- package/core/built/admin/assets/lib-CCz2mjm8.js +2 -0
- package/core/built/admin/assets/link-helpers-o9GgBTni.js +1 -0
- package/core/built/admin/assets/{links-FwNCVyVe.js → links-Ctujreuh.js} +1 -1
- package/core/built/admin/assets/list-page-CH_wnDC3.js +1 -0
- package/core/built/admin/assets/member-activity-CsAh6MxK.js +1 -0
- package/core/built/admin/assets/member-activity-feed-0ytsQbtY.js +1 -0
- package/core/built/admin/assets/member-custom-fields-CTFGnnYv.js +1 -0
- package/core/built/admin/assets/member-detail-QU3vB1ML.js +1 -0
- package/core/built/admin/assets/members-CtMVO_AB.js +4 -0
- package/core/built/admin/assets/modal-page-8Ipfl51B.js +1 -0
- package/core/built/admin/assets/moderation-B8VtA-W0.js +1 -0
- package/core/built/admin/assets/multi-select-combobox-_9wEYmGv.js +1 -0
- package/core/built/admin/assets/navigation-modal-CGcjJvkc.js +1 -0
- package/core/built/admin/assets/newsletter-BpHjjqmq.js +1 -0
- package/core/built/admin/assets/newsletter-detail-modal-DzTbGOyo.js +1 -0
- package/core/built/admin/assets/newsletter-emails-BMKH4Osp.js +1 -0
- package/core/built/admin/assets/newsletters-BxC84_cL.js +1 -0
- package/core/built/admin/assets/note-BPtEzzZS.js +1 -0
- package/core/built/admin/assets/notifications-ng3ulEdp.js +1 -0
- package/core/built/admin/assets/offers-container-modal-CwqnRa3T.js +1 -0
- package/core/built/admin/assets/onboarding-route-CplZzd7F.js +1 -0
- package/core/built/admin/assets/overview-B0yD9OoX.js +1 -0
- package/core/built/admin/assets/overview-C4eJzQqi.js +1 -0
- package/core/built/admin/assets/page-header-CdCpekG9.js +1 -0
- package/core/built/admin/assets/pagemenu-CKQD9hoP.js +1 -0
- package/core/built/admin/assets/pages-route-CKsnxIvw.js +1 -0
- package/core/built/admin/assets/{pintura-modal-BljM7hf8.js → pintura-modal-C5jzeyGk.js} +1 -1
- package/core/built/admin/assets/portal-frame-DYo0bh0E.js +1 -0
- package/core/built/admin/assets/portal-modal-C0d8xjKa.js +1 -0
- package/core/built/admin/assets/post-analytics-C5C7IyAm.js +1 -0
- package/core/built/admin/assets/post-analytics-header-DKWHwoK2.js +1 -0
- package/core/built/admin/assets/{post-analytics-provider-CgreZDjS.js → post-analytics-provider-BqCPPxmW.js} +1 -1
- package/core/built/admin/assets/post-share-modal-wxmqbAv_.js +1 -0
- package/core/built/admin/assets/posts-list-screen-B978ZO0R.js +2 -0
- package/core/built/admin/assets/posts-route-CDqxKazl.js +1 -0
- package/core/built/admin/assets/preferences-CnejTRc4.js +5 -0
- package/core/built/admin/assets/preview-chrome-C7yZWVLZ.js +1 -0
- package/core/built/admin/assets/preview-modal-CFUxUGHp.js +1 -0
- package/core/built/admin/assets/profile-ClRGiOqA.js +1 -0
- package/core/built/admin/assets/radio-group-CTmLo0h9.js +1 -0
- package/core/built/admin/assets/router-provider-DDZvgS3V.js +1 -0
- package/core/built/admin/assets/select-D_4xWFYv.js +1 -0
- package/core/built/admin/assets/settings-BRl7-7a9.js +1 -0
- package/core/built/admin/assets/settings-BoQcPa-y.js +4 -0
- package/core/built/admin/assets/settings-breadcrumbs-C9Yxl81q.js +1 -0
- package/core/built/admin/assets/{dist-BXHrDV19.js → shade-scope-Cccj-c7I-D0XwkdKQ.js} +5 -3
- package/core/built/admin/assets/share-modal-DBqZobuR.js +1 -0
- package/core/built/admin/assets/simple-pagination-D5t_ox6x.js +1 -0
- package/core/built/admin/assets/skeleton-CPcTiTSX.js +1 -0
- package/core/built/admin/assets/{slack-modal-D7W_fNON.js → slack-modal-BF9ex8cd.js} +1 -1
- package/core/built/admin/assets/sort-button-C0EXGjnS.js +1 -0
- package/core/built/admin/assets/{source-icon-CQboPZQ3.js → source-icon-BzzftCQ2.js} +1 -1
- package/core/built/admin/assets/stats-view-CzpGoHzF.js +1 -0
- package/core/built/admin/assets/{step-1-BKhjy0PV.js → step-1-CBUYUPPF.js} +1 -1
- package/core/built/admin/assets/{step-2-PxA1OM7R.js → step-2-CEIXUwQa.js} +1 -1
- package/core/built/admin/assets/{step-3-BJbAiq16.js → step-3-C1HA5i1N.js} +2 -2
- package/core/built/admin/assets/stripe-button-DMFsLs80.js +1 -0
- package/core/built/admin/assets/stripe-connect-modal-CEvxCUTv.js +1 -0
- package/core/built/admin/assets/switch-DoOJF2yg.js +1 -0
- package/core/built/admin/assets/table-BDYbUHJz.js +1 -0
- package/core/built/admin/assets/tabs-BZyz4ZCH.js +1 -0
- package/core/built/admin/assets/tag-detail-CFzaz_9E.js +2 -0
- package/core/built/admin/assets/tag-picker-BKUCZuRc.js +1 -0
- package/core/built/admin/assets/tags-Bs1FiD7m.js +1 -0
- package/core/built/admin/assets/{testimonials-modal-Dkt6ODLW.js → testimonials-modal-CVm0_7E-.js} +1 -1
- package/core/built/admin/assets/text-BLI0C8Mc.js +1 -0
- package/core/built/admin/assets/textarea-C5qolByg.js +1 -0
- package/core/built/admin/assets/tier-detail-modal-Cmwzi-e7.js +1 -0
- package/core/built/admin/assets/toggle-group-BTL1QsWY.js +1 -0
- package/core/built/admin/assets/{topic-filter-DVOe3D-b.js → topic-filter-BMjhquv7.js} +1 -1
- package/core/built/admin/assets/transistor-modal-hMv53jF8.js +1 -0
- package/core/built/admin/assets/trend-badge-1w_HEzkG.js +1 -0
- package/core/built/admin/assets/{unsplash-modal-DXt7Brum.js → unsplash-modal-jzC8lEB2.js} +1 -1
- package/core/built/admin/assets/use-analytics-data-B3lGOxsC.js +1 -0
- package/core/built/admin/assets/use-availability-DnKqOyqd.js +1 -0
- package/core/built/admin/assets/{use-check-theme-limit-error-JD-J5aaZ.js → use-check-theme-limit-error-C1tc2P4N.js} +2 -2
- package/core/built/admin/assets/use-filter-params-DU-aiaTb.js +1 -0
- package/core/built/admin/assets/{use-filterable-api-CEMSAYPg.js → use-filterable-api-CxCrnPxG.js} +1 -1
- package/core/built/admin/assets/use-growth-stats-E13rMQUE.js +1 -0
- package/core/built/admin/assets/use-limiter-DlL7au90.js +19 -0
- package/core/built/admin/assets/{use-navigate-with-base-path-88EQpw2k.js → use-navigate-with-base-path-BzgNwMAx.js} +1 -1
- package/core/built/admin/assets/{use-pintura-config-BmU45Ruy.js → use-pintura-config-CtEV1JQY.js} +1 -1
- package/core/built/admin/assets/{use-pintura-editor-Bz2bZ4iT.js → use-pintura-editor-CaxE64kD.js} +1 -1
- package/core/built/admin/assets/use-reply-chain-data-BST2OgCM.js +1 -0
- package/core/built/admin/assets/use-sending-eta-DR9ueMH8.js +1 -0
- package/core/built/admin/assets/use-setting-group-ldtX1Vsk.js +1 -0
- package/core/built/admin/assets/use-settings-navigation-CzGU4sus.js +1 -0
- package/core/built/admin/assets/use-staff-users-DoeXaPsb.js +1 -0
- package/core/built/admin/assets/use-tinybird-query-BaBNCaj0.js +1 -0
- package/core/built/admin/assets/{use-tinybird-token-Lk1RSn0t.js → use-tinybird-token-CnZ19NDf.js} +1 -1
- package/core/built/admin/assets/{use-url-input-DpmbDppC.js → use-url-input-C5KHJw79.js} +1 -1
- package/core/built/admin/assets/user-detail-modal-Dm0KfPeR.js +1 -0
- package/core/built/admin/assets/{vendor-2dd263291938d407802568d3357ec69e.js → vendor-97e91ff8dd1457c668f9ef103ee1a77b.js} +2748 -2977
- package/core/built/admin/assets/virtual-list-tAuPUICw.js +1 -0
- package/core/built/admin/assets/web-BQlKcW2x.js +2 -0
- package/core/built/admin/assets/web-NTT5DkEz.js +1 -0
- package/core/built/admin/assets/{zapier-modal-BafLUO4R.js → zapier-modal-DsHG9Oev.js} +1 -1
- package/core/built/admin/index.html +22 -24
- package/core/frontend/apps/private-blogging/index.js +2 -2
- package/core/frontend/apps/private-blogging/lib/middleware.js +1 -1
- package/core/frontend/apps/private-blogging/lib/router.js +1 -1
- package/core/frontend/helpers/cancel_link.js +3 -3
- package/core/frontend/helpers/content.js +2 -2
- package/core/frontend/helpers/content_api_url.js +1 -1
- package/core/frontend/helpers/date.js +1 -1
- package/core/frontend/helpers/foreach.js +5 -5
- package/core/frontend/helpers/get.js +7 -4
- package/core/frontend/helpers/ghost_head.js +2 -2
- package/core/frontend/helpers/has.js +1 -3
- package/core/frontend/helpers/link.js +7 -7
- package/core/frontend/helpers/link_class.js +2 -2
- package/core/frontend/helpers/navigation.js +1 -2
- package/core/frontend/helpers/recommendations.js +5 -6
- package/core/frontend/helpers/tiers.js +1 -1
- package/core/frontend/helpers/total_members.js +1 -1
- package/core/frontend/helpers/total_paid_members.js +1 -1
- package/core/frontend/meta/author-url.js +1 -1
- package/core/frontend/meta/modified-date.js +1 -1
- package/core/frontend/meta/published-date.js +1 -1
- package/core/frontend/meta/schema.js +3 -8
- package/core/frontend/meta/structured-data.js +1 -2
- package/core/frontend/services/assets-minification/minifier.js +1 -1
- package/core/frontend/services/data/entry-lookup.js +1 -1
- package/core/frontend/services/data/fetch-data.js +2 -2
- package/core/frontend/services/rendering/format-response.js +1 -1
- package/core/frontend/services/rendering/renderer.js +3 -0
- package/core/frontend/services/rendering/templates.js +1 -1
- package/core/frontend/services/routing/controllers/static.js +1 -1
- package/core/frontend/services/routing/parent-router.js +1 -1
- package/core/frontend/services/routing/registry.js +1 -1
- package/core/frontend/services/sitemap/base-site-map-generator.js +68 -97
- package/core/frontend/services/sitemap/site-map-index-generator.js +16 -21
- package/core/frontend/services/sitemap/site-map-manager.js +82 -43
- package/core/frontend/services/sitemap/sitemap-xml.js +72 -0
- package/core/frontend/services/theme-engine/handlebars/utils.js +8 -8
- package/core/frontend/services/theme-engine/i18n/i18n.js +4 -5
- package/core/frontend/services/theme-engine/middleware/update-global-template-options.js +1 -1
- package/core/frontend/services/theme-engine/preview.js +1 -1
- package/core/frontend/utils/member-count.js +2 -2
- package/core/frontend/web/routers/serve-public-file.js +1 -1
- package/core/server/adapters/scheduling/README.md +4 -0
- package/core/server/adapters/scheduling/get-scheduler-idempotency-key.js +21 -0
- package/core/server/adapters/storage/LocalStorageBase.js +2 -1
- package/core/server/api/endpoints/automated-emails.js +8 -2
- package/core/server/api/endpoints/db.js +1 -1
- package/core/server/api/endpoints/emails.js +3 -3
- package/core/server/api/endpoints/mail.js +1 -1
- package/core/server/api/endpoints/member-signin-urls.js +1 -1
- package/core/server/api/endpoints/members.js +3 -3
- package/core/server/api/endpoints/oembed.js +1 -1
- package/core/server/api/endpoints/posts.js +1 -1
- package/core/server/api/endpoints/settings.js +2 -2
- package/core/server/api/endpoints/themes.js +5 -5
- package/core/server/api/endpoints/utils/serializers/input/pages.js +2 -2
- package/core/server/api/endpoints/utils/serializers/input/posts.js +2 -2
- package/core/server/api/endpoints/utils/serializers/input/tags.js +1 -1
- package/core/server/api/endpoints/utils/serializers/input/utils/slug-filter-order.js +4 -4
- package/core/server/api/endpoints/utils/serializers/output/mappers/comments.js +8 -5
- package/core/server/api/endpoints/utils/serializers/output/mappers/posts.js +1 -1
- package/core/server/api/endpoints/utils/serializers/output/pages.js +4 -4
- package/core/server/api/endpoints/utils/serializers/output/posts.js +4 -4
- package/core/server/api/endpoints/utils/serializers/output/search-index.js +11 -11
- package/core/server/api/endpoints/utils/serializers/output/settings.js +1 -1
- package/core/server/api/endpoints/utils/serializers/output/utils/extra-attrs.js +3 -3
- package/core/server/api/endpoints/utils/validators/input/automated_emails.js +23 -33
- package/core/server/api/endpoints/utils/validators/input/settings.js +3 -3
- package/core/server/data/exporter/exporter.js +1 -2
- package/core/server/data/exporter/table-lists.js +1 -0
- package/core/server/data/importer/handlers/image.js +1 -2
- package/core/server/data/importer/handlers/json.js +1 -3
- package/core/server/data/importer/handlers/markdown.js +4 -8
- package/core/server/data/importer/import-manager.js +1 -1
- package/core/server/data/importer/importers/content-file-importer.js +4 -8
- package/core/server/data/importer/importers/data/base.js +10 -10
- package/core/server/data/importer/importers/data/custom-theme-settings-importer.js +1 -1
- package/core/server/data/importer/importers/data/data-importer.js +3 -4
- package/core/server/data/importer/importers/data/posts-importer.js +10 -10
- package/core/server/data/importer/importers/data/products-importer.js +3 -3
- package/core/server/data/importer/importers/data/settings-importer.js +2 -2
- package/core/server/data/importer/importers/data/stripe-prices-importer.js +1 -1
- package/core/server/data/importer/importers/data/stripe-products-importer.js +1 -1
- package/core/server/data/importer/importers/data/tags-importer.js +1 -1
- package/core/server/data/importer/importers/data/users-importer.js +2 -2
- package/core/server/data/importer/importers/json-to-html.js +12 -9
- package/core/server/data/migrations/versions/5.0/2022-05-11-13-12-rename-settings.js +1 -1
- package/core/server/data/migrations/versions/6.65/2026-09-16-15-35-26-add-members-metafield-change-events.js +17 -0
- package/core/server/data/schema/fixtures/fixture-manager.js +3 -3
- package/core/server/data/schema/index.js +1 -1
- package/core/server/data/schema/schema.js +26 -0
- package/core/server/data/schema/validator.js +96 -123
- package/core/server/data/seeders/importers/email-recipients-importer.js +2 -2
- package/core/server/data/seeders/importers/members-login-events-importer.js +1 -1
- package/core/server/data/seeders/importers/members-newsletters-importer.js +1 -1
- package/core/server/data/seeders/importers/members-paid-subscription-events-importer.js +1 -1
- package/core/server/data/seeders/importers/members-status-events-importer.js +1 -1
- package/core/server/data/seeders/importers/members-stripe-customers-importer.js +1 -1
- package/core/server/data/seeders/importers/members-stripe-customers-subscriptions-importer.js +1 -1
- package/core/server/data/seeders/importers/members-subscribe-events-importer.js +2 -2
- package/core/server/data/seeders/importers/members-subscription-created-events-importer.js +1 -1
- package/core/server/data/tinybird/pipes/mv_hits.pipe +25 -20
- package/core/server/data/tinybird/scripts/docker-analytics-manager.js +2 -2
- package/core/server/ghost-server.js +1 -19
- package/core/server/lib/image/image-size.js +1 -3
- package/core/server/lib/request-external.js +53 -117
- package/core/server/models/base/plugins/actions.js +2 -3
- package/core/server/models/base/plugins/crud.js +1 -2
- package/core/server/models/base/plugins/events.js +4 -4
- package/core/server/models/base/plugins/raw-knex.js +3 -3
- package/core/server/models/base/plugins/sanitize.js +1 -1
- package/core/server/models/benefit.js +1 -1
- package/core/server/models/collection.js +1 -1
- package/core/server/models/comment.js +3 -3
- package/core/server/models/invite.js +2 -5
- package/core/server/models/label.js +3 -6
- package/core/server/models/member.js +7 -10
- package/core/server/models/newsletter.js +1 -1
- package/core/server/models/permission.js +3 -6
- package/core/server/models/post.js +20 -23
- package/core/server/models/product.js +4 -1
- package/core/server/models/relations/authors.js +9 -12
- package/core/server/models/role.js +2 -5
- package/core/server/models/settings.js +3 -3
- package/core/server/models/tag.js +2 -5
- package/core/server/models/user.js +8 -10
- package/core/server/models/webhook.js +2 -4
- package/core/server/notify.js +2 -2
- package/core/server/services/adapter-manager/utils.js +6 -1
- package/core/server/services/api-version-compatibility/legacy-api-path-match.js +2 -2
- package/core/server/services/auth/api-key/admin.js +2 -2
- package/core/server/services/auth/api-key/content.js +1 -1
- package/core/server/services/auth/passwordreset.js +1 -1
- package/core/server/services/auth/setup.js +1 -3
- package/core/server/services/automations/README.md +19 -0
- package/core/server/services/automations/poll.js +3 -1
- package/core/server/services/automations/service.js +2 -2
- package/core/server/services/automations/welcome-email-automation-poll.js +199 -293
- package/core/server/services/comments/comments-controller.js +9 -30
- package/core/server/services/comments/comments-service-email-renderer.js +1 -1
- package/core/server/services/comments/comments-service-emails.js +1 -1
- package/core/server/services/comments/comments-service.js +27 -58
- package/core/server/services/comments/comments-stats-service.js +1 -1
- package/core/server/services/content-import/import/staged-file.js +9 -9
- package/core/server/services/content-import/index.js +1 -1
- package/core/server/services/custom-redirects/validation.js +1 -1
- package/core/server/services/email-analytics/email-analytics-service-wrapper.js +23 -55
- package/core/server/services/email-analytics/index.js +35 -19
- package/core/server/services/email-analytics/jobs/email-analytics-job-scheduler.js +31 -60
- package/core/server/services/email-service/README.md +35 -0
- package/core/server/services/email-service/batch-sending-service.js +13 -14
- package/core/server/services/email-service/email-renderer.js +50 -14
- package/core/server/services/email-service/email-service-wrapper.js +3 -2
- package/core/server/services/email-service/email-service.js +33 -8
- package/core/server/services/email-service/email-templates/partials/feedback-button.hbs +2 -1
- package/core/server/services/email-service/email-templates/partials/styles.hbs +0 -6
- package/core/server/services/email-service/email-templates/template.hbs +1 -1
- package/core/server/services/email-service/jobs/send-email-job.js +12 -0
- package/core/server/services/email-service/mailgun-email-provider.js +7 -2
- package/core/server/services/email-service/sending-service.js +1 -1
- package/core/server/services/gifts/gift-service.js +12 -3
- package/core/server/services/gifts/index.js +0 -2
- package/core/server/services/gifts/jobs/index.js +12 -24
- package/core/server/services/gifts/jobs/send-gift-reminders-job.js +6 -46
- package/core/server/services/invitations/accept.js +2 -2
- package/core/server/services/jobs/job-service.js +0 -28
- package/core/server/services/jobs-service/jobs-service.js +5 -0
- package/core/server/services/jobs-service/register-job-handlers.js +17 -1
- package/core/server/services/lib/mailgun-client.js +16 -1
- package/core/server/services/lib/mailgun-recipient-message-id.js +49 -0
- package/core/server/services/limits.js +1 -1
- package/core/server/services/mail/ghost-mailer.js +1 -1
- package/core/server/services/member-attribution/member-attribution-service.js +1 -1
- package/core/server/services/member-attribution/referrer-translator.js +1 -1
- package/core/server/services/members/account-service.js +3 -3
- package/core/server/services/members/api.js +1 -1
- package/core/server/services/members/import-export/import/importer.js +25 -16
- package/core/server/services/members/import-export/import/spool.js +11 -15
- package/core/server/services/members/import-export/index.js +6 -4
- package/core/server/services/members/jobs/index.js +1 -1
- package/core/server/services/members/jobs/members-import-job.js +18 -0
- package/core/server/services/members/member-avatar.js +18 -0
- package/core/server/services/members/members-api/controllers/member-controller.js +2 -2
- package/core/server/services/members/members-api/members-api.js +4 -4
- package/core/server/services/members/members-api/repositories/event-repository.js +36 -1
- package/core/server/services/members/members-api/repositories/member-repository.js +55 -17
- package/core/server/services/members/members-api/repositories/product-repository.js +1 -1
- package/core/server/services/members/members-api/services/member-bread-service.js +4 -7
- package/core/server/services/members/service.js +7 -2
- package/core/server/services/members/stats/members-stats.js +2 -2
- package/core/server/services/members-events/event-storage.js +2 -2
- package/core/server/services/members-metafields/actions.js +23 -2
- package/core/server/services/members-metafields/bindings-service.js +5 -5
- package/core/server/services/members-metafields/definitions-service.js +2 -7
- package/core/server/services/members-metafields/index.js +2 -1
- package/core/server/services/members-metafields/queries.js +7 -1
- package/core/server/services/members-metafields/schema.js +49 -1
- package/core/server/services/members-metafields/values-service.js +112 -10
- package/core/server/services/mentions/mention-sending-service.js +2 -2
- package/core/server/services/mentions/mention.js +3 -4
- package/core/server/services/mentions/mentions-api.js +4 -1
- package/core/server/services/mentions-jobs/job-service.js +0 -28
- package/core/server/services/milestones/milestones-service.js +1 -1
- package/core/server/services/newsletters/newsletters-service.js +1 -1
- package/core/server/services/notifications/notifications.js +3 -3
- package/core/server/services/oembed/oembed-service.js +79 -3
- package/core/server/services/permissions/can-this.js +1 -2
- package/core/server/services/post-scheduling/post-scheduling.js +8 -1
- package/core/server/services/posts/post-scheduling.js +7 -0
- package/core/server/services/settings/settings-bread-service.js +3 -3
- package/core/server/services/settings/settings-utils.js +1 -1
- package/core/server/services/settings-helpers/settings-helpers.js +1 -1
- package/core/server/services/staff/staff-service-emails.js +9 -9
- package/core/server/services/stats/posts-stats-service.js +10 -10
- package/core/server/services/stats/referrers-stats-service.js +1 -1
- package/core/server/services/stats/subscription-stats-service.js +3 -3
- package/core/server/services/stats/utils/tinybird.js +8 -1
- package/core/server/services/stripe/stripe-api.js +3 -3
- package/core/server/services/stripe/stripe-migrations.js +6 -6
- package/core/server/services/themes/storage.js +21 -26
- package/core/server/services/themes/theme-storage.js +2 -2
- package/core/server/services/tiers/tier.js +15 -15
- package/core/server/services/tinybird-sync/index.js +3 -0
- package/core/server/services/tinybird-sync/tinybird-sync-service.js +7 -2
- package/core/server/services/update-check/update-check-service.js +3 -3
- package/core/server/services/webhooks/serialize.js +1 -1
- package/core/server/web/api/app.js +0 -5
- package/core/server/web/api/middleware/upload.js +29 -2
- package/core/server/web/parent/middleware/index.js +1 -1
- package/core/server/web/parent/middleware/log-request.js +5 -0
- package/core/server/web/parent/middleware/queue-request.js +104 -59
- package/core/server/web/shared/middleware/api/spam-prevention.js +2 -2
- package/core/shared/config/defaults.json +6 -1
- package/core/shared/custom-theme-settings-cache/custom-theme-settings-service.js +1 -1
- package/core/shared/labs.js +3 -2
- package/core/shared/settings-cache/cache-manager.js +1 -1
- package/nodemon.json +1 -1
- package/package.json +6 -7
- package/pnpm-lock.yaml +126 -728
- package/pnpm-workspace.yaml +4 -7
- package/tsconfig.json +1 -1
- package/components/tryghost-adapter-base-scheduling-0.2.3.tgz +0 -0
- package/core/built/admin/assets/Combination-DWfJPcz9.js +0 -41
- package/core/built/admin/assets/RadialBarChart-CHRBhiBN.js +0 -1
- package/core/built/admin/assets/_baseAssignValue-DcPokYW8.js +0 -1
- package/core/built/admin/assets/accordion-CJmRaqK7.js +0 -1
- package/core/built/admin/assets/account-migration-DYf7skbb.js +0 -1
- package/core/built/admin/assets/action-list-Crnh-_UI.js +0 -1
- package/core/built/admin/assets/activitypub/avatar-DVJF5bxP.js +0 -261
- package/core/built/admin/assets/activitypub/layout-BL4_jtuV.js +0 -1
- package/core/built/admin/assets/activitypub/routes-DdyY9uFF.js +0 -7181
- package/core/built/admin/assets/activitypub/settings-B6EEcVkW.js +0 -315
- package/core/built/admin/assets/activitypub/tabs-DLhZtVde.js +0 -1083
- package/core/built/admin/assets/activitypub/users-inweyKL5.js +0 -1499
- package/core/built/admin/assets/add-newsletter-modal-CTvXiIqY.js +0 -1
- package/core/built/admin/assets/analytics-PHR1Fggi.js +0 -1
- package/core/built/admin/assets/announcement-bar-modal-Bql0CXdp.js +0 -1
- package/core/built/admin/assets/api-keys-CubH-7_H.js +0 -1
- package/core/built/admin/assets/automations-DcZSLFDU.js +0 -1
- package/core/built/admin/assets/badge-qP06OT7C.js +0 -1
- package/core/built/admin/assets/bluesky-sharing-CJw4d4Mf.js +0 -1
- package/core/built/admin/assets/box-CZ_LSVSy.js +0 -1
- package/core/built/admin/assets/brand-icon-D3ffDYaC.js +0 -1
- package/core/built/admin/assets/breadcrumb-Chn1Ip_q.js +0 -1
- package/core/built/admin/assets/button-DvIh2Bq-.js +0 -1
- package/core/built/admin/assets/calendar-1QGoStFM.js +0 -1
- package/core/built/admin/assets/card-FHQ4D10L.js +0 -1
- package/core/built/admin/assets/chart-helpers-CNpA7re_.js +0 -1
- package/core/built/admin/assets/chart-jVz9Nf9t.js +0 -63
- package/core/built/admin/assets/checkbox-DKht9xMl.js +0 -1
- package/core/built/admin/assets/chunk.524.cc9be98e44890cedc8c8.js +0 -25
- package/core/built/admin/assets/chunk.582.e6fe742b3217207b11a6.js +0 -27
- package/core/built/admin/assets/code-editor-view-BLQIV85-.js +0 -1
- package/core/built/admin/assets/code-editor-view-Cg5eJxcr.js +0 -1
- package/core/built/admin/assets/color-picker-DQoghc0t.js +0 -3
- package/core/built/admin/assets/color-picker-field-BbeK5RRs.js +0 -1
- package/core/built/admin/assets/combobox-weO4FBbv.js +0 -1
- package/core/built/admin/assets/command-DlLrCm9V.js +0 -1
- package/core/built/admin/assets/comments-BjTitLmP.js +0 -1
- package/core/built/admin/assets/confirmation-context-IyqoXVk-.js +0 -1
- package/core/built/admin/assets/container-DAimjOF_.js +0 -1
- package/core/built/admin/assets/context-menu-BtioYFrg.js +0 -1
- package/core/built/admin/assets/copy-field-C6ujqJlP.js +0 -1
- package/core/built/admin/assets/create-ghost-browse-value-source-DAZMWZNq.js +0 -1
- package/core/built/admin/assets/custom-integration-modal-Dm8QI_J4.js +0 -1
- package/core/built/admin/assets/data-list-C0CKkeWW.js +0 -1
- package/core/built/admin/assets/date-range-select-DrjHQdgz.js +0 -1
- package/core/built/admin/assets/design-and-theme-modal-CXVOzBWu.js +0 -2
- package/core/built/admin/assets/detail-page-QpLIL-EO.js +0 -1
- package/core/built/admin/assets/dirty-confirm-dialog-DWwxREGh.js +0 -1
- package/core/built/admin/assets/dist-Bf-HQtVL.js +0 -1
- package/core/built/admin/assets/dist-CUwte9v_.js +0 -1
- package/core/built/admin/assets/dist-FEQQAwTe.js +0 -1
- package/core/built/admin/assets/domain-DBrBic6q.js +0 -1
- package/core/built/admin/assets/dropzone-D61QVcEY.js +0 -5
- package/core/built/admin/assets/edit-profile-jCqJBxqw.js +0 -1
- package/core/built/admin/assets/editor-8Fm4UBEd.js +0 -8
- package/core/built/admin/assets/editor-screen-BSX_uC2B.js +0 -27
- package/core/built/admin/assets/email-sending-status-provider-DnNhlIvt.js +0 -1
- package/core/built/admin/assets/embed-signup-form-modal-DqtBs1WE.js +0 -8
- package/core/built/admin/assets/empty-indicator-L4Ql5Db7.js +0 -1
- package/core/built/admin/assets/en-Cx75dJv5.js +0 -1
- package/core/built/admin/assets/explore-DXhDCtKw.js +0 -1
- package/core/built/admin/assets/feature-image-placeholder-e2q6TcH6.js +0 -1
- package/core/built/admin/assets/feed-mmt4noNL.js +0 -1
- package/core/built/admin/assets/field-p7KnP98B.js +0 -1
- package/core/built/admin/assets/filter-bar-CiIKBg3D.js +0 -1
- package/core/built/admin/assets/filter-sources-I-dRaQxl.js +0 -1
- package/core/built/admin/assets/filters-1injvyxJ.js +0 -1
- package/core/built/admin/assets/filters-DnpO6GWX.js +0 -1
- package/core/built/admin/assets/gift-link-modal-C3H7YFXO.js +0 -1
- package/core/built/admin/assets/grid-5vplBYri.js +0 -1
- package/core/built/admin/assets/growth-B1og1kQp.js +0 -1
- package/core/built/admin/assets/growth-Bf6OHZlK.js +0 -3
- package/core/built/admin/assets/heading-BB21QAbb.js +0 -1
- package/core/built/admin/assets/history-modal-t_qEnxPx.js +0 -1
- package/core/built/admin/assets/html-field-COLQbV4r.js +0 -1
- package/core/built/admin/assets/images-4mvoc3lB.js +0 -1
- package/core/built/admin/assets/index-B3HZU2i8.css +0 -2
- package/core/built/admin/assets/index-DDd-zhNL.js +0 -4
- package/core/built/admin/assets/inline-B8H6NzIw.js +0 -1
- package/core/built/admin/assets/input-group-CLIN2ykI.js +0 -1
- package/core/built/admin/assets/input-surface-wSO5CRy5.js +0 -1
- package/core/built/admin/assets/integration-header-CKGrXNVP.js +0 -1
- package/core/built/admin/assets/invite-user-modal-BaN2mdhI.js +0 -1
- package/core/built/admin/assets/koenig-loader-B1XPPY5C.js +0 -2
- package/core/built/admin/assets/kpi-card-CRLPVlFW.js +0 -1
- package/core/built/admin/assets/kpi-card-CRPbW8NZ.js +0 -1
- package/core/built/admin/assets/kpi-helpers-D7zT96bp.js +0 -1
- package/core/built/admin/assets/kpi-tabs-DE_yh9Go.js +0 -1
- package/core/built/admin/assets/label-CgeBxy4o.js +0 -1
- package/core/built/admin/assets/label-picker-DGDp4Vwr.js +0 -1
- package/core/built/admin/assets/layout-DWnOMly4.js +0 -1
- package/core/built/admin/assets/lib-_QYaUU89.js +0 -2
- package/core/built/admin/assets/link-helpers-8J7ixADV.js +0 -1
- package/core/built/admin/assets/list-page-DLMP0PxC.js +0 -1
- package/core/built/admin/assets/member-activity-ClMWFyvN.js +0 -1
- package/core/built/admin/assets/member-activity-feed-BQY5Rwaj.js +0 -1
- package/core/built/admin/assets/member-custom-fields-Dd_ie1zG.js +0 -1
- package/core/built/admin/assets/member-detail-DjwkGVne.js +0 -1
- package/core/built/admin/assets/members--N9lhk1N.js +0 -4
- package/core/built/admin/assets/modal-page-Dz-9TP4E.js +0 -1
- package/core/built/admin/assets/moderation-DfYBKq9s.js +0 -1
- package/core/built/admin/assets/multi-select-combobox-BcBEzUW_.js +0 -1
- package/core/built/admin/assets/navigation-modal-Cd-scywg.js +0 -1
- package/core/built/admin/assets/newsletter-detail-modal-CFRY6vg_.js +0 -1
- package/core/built/admin/assets/newsletter-emails-4ntck1AC.js +0 -1
- package/core/built/admin/assets/newsletter-o6eCJtab.js +0 -1
- package/core/built/admin/assets/newsletters-Bmlv0edG.js +0 -1
- package/core/built/admin/assets/note-CWs3LF-0.js +0 -1
- package/core/built/admin/assets/notifications-BjSvTJqh.js +0 -1
- package/core/built/admin/assets/offers-container-modal-Bc9A196w.js +0 -1
- package/core/built/admin/assets/onboarding-route-Di1LJYEE.js +0 -1
- package/core/built/admin/assets/overview-DE7NHZQN.js +0 -1
- package/core/built/admin/assets/overview-DEF-ZY6x.js +0 -1
- package/core/built/admin/assets/page-header-B-G_g42C.js +0 -1
- package/core/built/admin/assets/pagemenu-CnkTDO71.js +0 -1
- package/core/built/admin/assets/pages-route-VT7r7YhG.js +0 -1
- package/core/built/admin/assets/portal-frame-D9V8iq5x.js +0 -1
- package/core/built/admin/assets/portal-modal-B5OOR9ZD.js +0 -1
- package/core/built/admin/assets/post-analytics-header-J0WciLx6.js +0 -1
- package/core/built/admin/assets/post-analytics-rGb-PgD-.js +0 -1
- package/core/built/admin/assets/post-share-modal-D0BbTo4W.js +0 -1
- package/core/built/admin/assets/posts-list-screen-CO5jAWoU.js +0 -2
- package/core/built/admin/assets/posts-route-DV-CXWK9.js +0 -1
- package/core/built/admin/assets/preferences-Tac29oG6.js +0 -5
- package/core/built/admin/assets/preview-chrome-C2lQgZBZ.js +0 -1
- package/core/built/admin/assets/preview-modal-CjRbBr8U.js +0 -1
- package/core/built/admin/assets/profile-yiM1f_Og.js +0 -1
- package/core/built/admin/assets/radio-group-CKROWsw4.js +0 -1
- package/core/built/admin/assets/router-provider-CU87qxXw.js +0 -1
- package/core/built/admin/assets/select-CKaC4ggu.js +0 -1
- package/core/built/admin/assets/settings-81kxUa28.js +0 -1
- package/core/built/admin/assets/settings-BVXFqBVK.js +0 -4
- package/core/built/admin/assets/settings-breadcrumbs-czGRx-iu.js +0 -1
- package/core/built/admin/assets/shade-app-CcS3f8MZ-D5BnfHck.js +0 -3
- package/core/built/admin/assets/share-modal-BL-16PiB.js +0 -1
- package/core/built/admin/assets/skeleton-DwCva0-b.js +0 -1
- package/core/built/admin/assets/sort-button-Dquc83jY.js +0 -1
- package/core/built/admin/assets/stack-BURz77VS.js +0 -1
- package/core/built/admin/assets/stats-view-NDja_g96.js +0 -1
- package/core/built/admin/assets/stripe-button-C3cfCAou.js +0 -1
- package/core/built/admin/assets/stripe-connect-modal-FyE3Ey2c.js +0 -1
- package/core/built/admin/assets/switch-zfUUy9Jh.js +0 -1
- package/core/built/admin/assets/table-dE4GTIRT.js +0 -1
- package/core/built/admin/assets/tabs-B3XK93sR.js +0 -1
- package/core/built/admin/assets/tag-detail-D4P-tZdM.js +0 -2
- package/core/built/admin/assets/tag-picker-BNSZ6Qxw.js +0 -1
- package/core/built/admin/assets/tags-BsZcaJ6h.js +0 -1
- package/core/built/admin/assets/text-DC-ot6u2.js +0 -1
- package/core/built/admin/assets/textarea-B4FffFmE.js +0 -1
- package/core/built/admin/assets/tier-detail-modal-a77Z2VMH.js +0 -1
- package/core/built/admin/assets/toggle-group-D2p4okmJ.js +0 -1
- package/core/built/admin/assets/transistor-modal-C8RMkhOD.js +0 -1
- package/core/built/admin/assets/trend-badge-B9v7kMF8.js +0 -1
- package/core/built/admin/assets/types-uYQ1HgqL.js +0 -1
- package/core/built/admin/assets/use-analytics-data-ChHqiZXv.js +0 -1
- package/core/built/admin/assets/use-availability-hPdeG76y.js +0 -1
- package/core/built/admin/assets/use-filter-params-BSFigDIn.js +0 -1
- package/core/built/admin/assets/use-growth-stats-CqqdnESN.js +0 -1
- package/core/built/admin/assets/use-limiter-DBGjYqu7.js +0 -19
- package/core/built/admin/assets/use-reply-chain-data-DmD2yX5D.js +0 -1
- package/core/built/admin/assets/use-sending-eta-CQeG6OP_.js +0 -1
- package/core/built/admin/assets/use-setting-group-Dza6bQ7W.js +0 -1
- package/core/built/admin/assets/use-settings-navigation-BIjI5mL3.js +0 -1
- package/core/built/admin/assets/use-simple-pagination-DwVxe-Lo.js +0 -1
- package/core/built/admin/assets/use-staff-users-i_Mq9OGR.js +0 -1
- package/core/built/admin/assets/use-tinybird-query-DXoF74NM.js +0 -1
- package/core/built/admin/assets/user-detail-modal-BU4QCHE7.js +0 -1
- package/core/built/admin/assets/virtual-list-DScLNuU8.js +0 -1
- package/core/built/admin/assets/web-BZS-t4H0.js +0 -1
- package/core/built/admin/assets/web-DxAUxnK3.js +0 -2
- package/core/frontend/services/sitemap/utils.js +0 -17
- package/core/server/services/automations/get-scheduler-idempotency-key.js +0 -13
- package/core/server/web/api/testmode/index.js +0 -1
- package/core/server/web/api/testmode/jobs/cpu-hog.js +0 -15
- package/core/server/web/api/testmode/jobs/graceful-job.js +0 -50
- package/core/server/web/api/testmode/jobs/say-hello.js +0 -17
- package/core/server/web/api/testmode/routes.js +0 -120
|
@@ -3,6 +3,11 @@ const debug = require('@tryghost/debug');
|
|
|
3
3
|
const logging = require('@tryghost/logging');
|
|
4
4
|
const metrics = require('@tryghost/metrics');
|
|
5
5
|
const errors = require('@tryghost/errors');
|
|
6
|
+
const {
|
|
7
|
+
addRecipientMessageIds,
|
|
8
|
+
isTemplatedRecipientMessageId,
|
|
9
|
+
RECIPIENT_MESSAGE_ID_VARIABLE,
|
|
10
|
+
} = require('./mailgun-recipient-message-id');
|
|
6
11
|
|
|
7
12
|
const DEFAULT_BATCH_SIZE = 1000;
|
|
8
13
|
|
|
@@ -19,6 +24,7 @@ module.exports = class MailgunClient {
|
|
|
19
24
|
* Creates the data payload and sends to Mailgun
|
|
20
25
|
*
|
|
21
26
|
* @param {Object} message
|
|
27
|
+
* @param {boolean} [message.perRecipientMessageId] Give every recipient its own Message-Id header
|
|
22
28
|
* @param {Object} recipientData
|
|
23
29
|
* @param {Array<Object>} replacements
|
|
24
30
|
*
|
|
@@ -118,6 +124,14 @@ module.exports = class MailgunClient {
|
|
|
118
124
|
// Use overriden domain if specified in message
|
|
119
125
|
const mailDomain = message.domainOverride ? message.domainOverride : mailgunConfig.domain;
|
|
120
126
|
|
|
127
|
+
if (message.perRecipientMessageId === true) {
|
|
128
|
+
// one Message-Id per recipient, referenced from a recipient variable like List-Unsubscribe above
|
|
129
|
+
messageData['recipient-variables'] = JSON.stringify(
|
|
130
|
+
addRecipientMessageIds(recipientData, { emailId: message.id, domain: mailDomain }),
|
|
131
|
+
);
|
|
132
|
+
messageData['h:Message-Id'] = `<%recipient.${RECIPIENT_MESSAGE_ID_VARIABLE}%>`;
|
|
133
|
+
}
|
|
134
|
+
|
|
121
135
|
const response = await mailgunInstance.messages.create(mailDomain, messageData);
|
|
122
136
|
metrics.metric('mailgun-send-mail', {
|
|
123
137
|
value: Date.now() - startTime,
|
|
@@ -125,7 +139,8 @@ module.exports = class MailgunClient {
|
|
|
125
139
|
});
|
|
126
140
|
|
|
127
141
|
return {
|
|
128
|
-
|
|
142
|
+
// a batch of per-recipient Message-Ids has no single provider id
|
|
143
|
+
id: isTemplatedRecipientMessageId(response.id) ? null : response.id,
|
|
129
144
|
};
|
|
130
145
|
} catch (error) {
|
|
131
146
|
logging.error(error);
|
|
@@ -0,0 +1,49 @@
|
|
|
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.RECIPIENT_MESSAGE_ID_VARIABLE = void 0;
|
|
7
|
+
exports.buildRecipientMessageId = buildRecipientMessageId;
|
|
8
|
+
exports.isTemplatedRecipientMessageId = isTemplatedRecipientMessageId;
|
|
9
|
+
exports.addRecipientMessageIds = addRecipientMessageIds;
|
|
10
|
+
/**
|
|
11
|
+
* Per-recipient Message-Id values for Mailgun batch sends. Mailgun mints one Message-Id per
|
|
12
|
+
* API call, so without these every recipient shares it and readers' replies thread together.
|
|
13
|
+
* Not to be confused with `./mailgun-message-id`, which normalizes the id Mailgun returns.
|
|
14
|
+
*/
|
|
15
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
16
|
+
exports.RECIPIENT_MESSAGE_ID_VARIABLE = 'message_id';
|
|
17
|
+
/**
|
|
18
|
+
* Deterministic per (email, recipient) so a resubmitted batch reuses the same ids; the address
|
|
19
|
+
* is hashed rather than exposed. Test emails have no email id and get a random prefix instead.
|
|
20
|
+
* No angle brackets: the header template adds them.
|
|
21
|
+
*/
|
|
22
|
+
function buildRecipientMessageId({ emailId, recipientEmail, domain, }) {
|
|
23
|
+
const prefix = emailId || node_crypto_1.default.randomUUID();
|
|
24
|
+
const digest = node_crypto_1.default
|
|
25
|
+
.createHash('sha256')
|
|
26
|
+
.update(`${prefix}:${recipientEmail}`)
|
|
27
|
+
.digest('hex')
|
|
28
|
+
.slice(0, 32);
|
|
29
|
+
return `${prefix}.${digest}@${domain}`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Mailgun returns the Message-Id it was given, so when the header is a per-recipient template it
|
|
33
|
+
* comes back unsubstituted and identifies nothing.
|
|
34
|
+
*/
|
|
35
|
+
function isTemplatedRecipientMessageId(messageId) {
|
|
36
|
+
return (typeof messageId === 'string' &&
|
|
37
|
+
messageId.includes(`%recipient.${exports.RECIPIENT_MESSAGE_ID_VARIABLE}%`));
|
|
38
|
+
}
|
|
39
|
+
/** Returns a new recipient-variables map with a `message_id` per recipient; the input is not mutated */
|
|
40
|
+
function addRecipientMessageIds(recipientData, { emailId, domain }) {
|
|
41
|
+
const result = {};
|
|
42
|
+
for (const [recipientEmail, variables] of Object.entries(recipientData)) {
|
|
43
|
+
result[recipientEmail] = {
|
|
44
|
+
...variables,
|
|
45
|
+
[exports.RECIPIENT_MESSAGE_ID_VARIABLE]: buildRecipientMessageId({ emailId, recipientEmail, domain }),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
@@ -3,7 +3,7 @@ const config = require('../../shared/config');
|
|
|
3
3
|
const db = require('../data/db');
|
|
4
4
|
const logging = require('@tryghost/logging');
|
|
5
5
|
const { LimitService } = require('@tryghost/limit-service');
|
|
6
|
-
|
|
6
|
+
const limitService = new LimitService();
|
|
7
7
|
|
|
8
8
|
const init = () => {
|
|
9
9
|
let helpLink;
|
|
@@ -105,7 +105,7 @@ function createMailError({ message, err, ignoreDefaultMessage } = { message: ''
|
|
|
105
105
|
const defaultErrorMessage = tpl(messages.failedSendingEmailError);
|
|
106
106
|
|
|
107
107
|
const fullErrorMessage = defaultErrorMessage + message;
|
|
108
|
-
|
|
108
|
+
const statusCode = err && err.name === 'RecipientError' ? 400 : 500;
|
|
109
109
|
return new errors.EmailError({
|
|
110
110
|
message: ignoreDefaultMessage ? message : fullErrorMessage,
|
|
111
111
|
err: err,
|
|
@@ -76,7 +76,7 @@ class ReferrerTranslator {
|
|
|
76
76
|
|
|
77
77
|
// In finding the 'content' that got the user to sign up, we want the latest entry with referrer data
|
|
78
78
|
for (const item of history) {
|
|
79
|
-
|
|
79
|
+
const refUrl = this.getUrlFromStr(item.referrerUrl);
|
|
80
80
|
if (refUrl?.hostname === 'checkout.stripe.com') {
|
|
81
81
|
// Ignore stripe, because second try payments should not be attributed to Stripe
|
|
82
82
|
continue;
|
|
@@ -71,11 +71,11 @@ class MemberAccountService {
|
|
|
71
71
|
withRelated: WRITE_RELATIONS,
|
|
72
72
|
});
|
|
73
73
|
if (plannedMetafields) {
|
|
74
|
-
// A member is recorded as the author of their own answers,
|
|
75
|
-
//
|
|
76
|
-
// records what staff did.
|
|
74
|
+
// A member is recorded as the author of their own answers, made from their
|
|
75
|
+
// account, which is Portal's.
|
|
77
76
|
await this.#metafieldValues.applyWrite(memberId, plannedMetafields, {
|
|
78
77
|
writtenBy: { type: 'member', id: memberId },
|
|
78
|
+
source: 'portal',
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
// Read back rather than returning what was written: a member is told what
|
|
@@ -7,6 +7,7 @@ const moment_timezone_1 = __importDefault(require("moment-timezone"));
|
|
|
7
7
|
const completion_email_1 = __importDefault(require("./completion-email"));
|
|
8
8
|
const csv_1 = require("../csv");
|
|
9
9
|
const csv_2 = require("@tryghost/metafield-types/csv");
|
|
10
|
+
const members_import_job_1 = __importDefault(require("../../jobs/members-import-job"));
|
|
10
11
|
const metrics = require('@tryghost/metrics');
|
|
11
12
|
const errors = require('@tryghost/errors');
|
|
12
13
|
const logging = require('@tryghost/logging');
|
|
@@ -53,10 +54,10 @@ class MembersCSVImporter {
|
|
|
53
54
|
_metafields;
|
|
54
55
|
_email;
|
|
55
56
|
_report;
|
|
56
|
-
|
|
57
|
+
_dispatchJob;
|
|
57
58
|
_getTimezone;
|
|
58
59
|
_getInlineThreshold;
|
|
59
|
-
constructor({ knex, readRows, spool, members, tiers, stripe, gifts, metafields, email, report,
|
|
60
|
+
constructor({ knex, readRows, spool, members, tiers, stripe, gifts, metafields, email, report, dispatchJob, getTimezone, getInlineThreshold, }) {
|
|
60
61
|
this._knex = knex;
|
|
61
62
|
this._readRows = readRows;
|
|
62
63
|
this._spool = spool;
|
|
@@ -67,7 +68,7 @@ class MembersCSVImporter {
|
|
|
67
68
|
this._metafields = metafields;
|
|
68
69
|
this._email = email;
|
|
69
70
|
this._report = report;
|
|
70
|
-
this.
|
|
71
|
+
this._dispatchJob = dispatchJob;
|
|
71
72
|
this._getTimezone = getTimezone;
|
|
72
73
|
this._getInlineThreshold = getInlineThreshold;
|
|
73
74
|
}
|
|
@@ -79,35 +80,43 @@ class MembersCSVImporter {
|
|
|
79
80
|
const result = await this.importRows(rows, labelName, extraLabels, verificationTrigger);
|
|
80
81
|
return { deferred: false, originalImportSize: rows.length, result };
|
|
81
82
|
}
|
|
82
|
-
await this.deferImport(rows, {
|
|
83
|
+
await this.deferImport(rows, {
|
|
84
|
+
labelName,
|
|
85
|
+
extraLabels,
|
|
86
|
+
requestUserEmail: request.requestUserEmail,
|
|
87
|
+
});
|
|
83
88
|
return { deferred: true, originalImportSize: rows.length };
|
|
84
89
|
}
|
|
85
90
|
async importInline(request, verificationTrigger) {
|
|
86
91
|
const rows = await this._readRows(request.filePath, request.mapping);
|
|
87
92
|
return this.importRows(rows, buildImportLabelName(this._getTimezone()), request.extraLabels ?? [], verificationTrigger);
|
|
88
93
|
}
|
|
89
|
-
async deferImport(rows, { labelName, extraLabels, requestUserEmail, }
|
|
94
|
+
async deferImport(rows, { labelName, extraLabels, requestUserEmail, }) {
|
|
90
95
|
// Resolved here, not at the API boundary, so the owner lookup only runs when
|
|
91
96
|
// a request without a user actually reaches the deferred path.
|
|
92
97
|
const emailRecipient = requestUserEmail ?? (await this._email.getDefaultRecipient());
|
|
93
|
-
const
|
|
98
|
+
const spoolKey = await this._spool.write(rows);
|
|
94
99
|
logging.info({ event: { name: 'members.import.queued' }, rows: rows.length }, 'Members import queued');
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
+
try {
|
|
101
|
+
await this._dispatchJob(new members_import_job_1.default({ spoolKey, labelName, extraLabels, emailRecipient }));
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
// No job will ever read the rows, so they are not left behind for one.
|
|
105
|
+
await this.settle(() => this._spool.remove(spoolKey));
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
100
108
|
}
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
|
|
109
|
+
// The members-import job handler. Resolves in every case, as the legacy inline job did:
|
|
110
|
+
// everything that can fail is already reported here, so a rejection would only make the
|
|
111
|
+
// jobs service report it again, and there is no retry behind it.
|
|
112
|
+
async handle({ spoolKey, labelName, extraLabels, emailRecipient }, verificationTrigger) {
|
|
104
113
|
const startedAt = Date.now();
|
|
105
114
|
logging.info({ event: { name: 'members.import.started' } }, 'Members import started');
|
|
106
115
|
// Null until the import produces one: parsing and mapping already happened inside
|
|
107
116
|
// the request, so anything failing from here is ours rather than the file's.
|
|
108
117
|
let result = null;
|
|
109
118
|
try {
|
|
110
|
-
const spooledRows = await
|
|
119
|
+
const spooledRows = await this._spool.read(spoolKey);
|
|
111
120
|
result = await this.importRows(spooledRows, labelName, extraLabels, verificationTrigger);
|
|
112
121
|
}
|
|
113
122
|
catch (error) {
|
|
@@ -115,7 +124,7 @@ class MembersCSVImporter {
|
|
|
115
124
|
this._report(error);
|
|
116
125
|
}
|
|
117
126
|
finally {
|
|
118
|
-
await this.settle(() =>
|
|
127
|
+
await this.settle(() => this._spool.remove(spoolKey));
|
|
119
128
|
}
|
|
120
129
|
// Whatever became of it, the publisher hears exactly once. If this is what fails,
|
|
121
130
|
// there is nobody left to tell but us.
|
|
@@ -4,27 +4,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.createRowSpool = createRowSpool;
|
|
7
|
-
const node_os_1 = __importDefault(require("node:os"));
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
7
|
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
10
|
-
|
|
11
|
-
// Spools import rows to a private JSON file under the OS temp dir, so a deferred
|
|
8
|
+
// Spools import rows to a JSON file in the imports storage adapter, so a deferred
|
|
12
9
|
// import can hand them to a background job and read them back after the request has
|
|
13
10
|
// already returned. The rows go in and come out as MemberImportRow, so nothing but
|
|
14
11
|
// the import's own row shape crosses this boundary.
|
|
15
|
-
function createRowSpool() {
|
|
12
|
+
function createRowSpool(storage) {
|
|
16
13
|
return {
|
|
17
14
|
async write(rows) {
|
|
18
|
-
const
|
|
19
|
-
await
|
|
20
|
-
return
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
};
|
|
15
|
+
const key = `members-import-${node_crypto_1.default.randomUUID()}.json`;
|
|
16
|
+
await storage.saveRaw(Buffer.from(JSON.stringify(rows)), key);
|
|
17
|
+
return key;
|
|
18
|
+
},
|
|
19
|
+
async read(key) {
|
|
20
|
+
return JSON.parse((await storage.read({ path: key })).toString('utf8'));
|
|
21
|
+
},
|
|
22
|
+
async remove(key) {
|
|
23
|
+
await storage.delete(key);
|
|
28
24
|
},
|
|
29
25
|
};
|
|
30
26
|
}
|
|
@@ -64,11 +64,13 @@ function makeImporter(deps) {
|
|
|
64
64
|
// An import has no id to give until runs are tracked, so it names its kind only.
|
|
65
65
|
applyWrite: (memberId, plan, executor) => deps.metafields.values.applyWrite(memberId, plan, {
|
|
66
66
|
writtenBy: { type: 'import', id: null },
|
|
67
|
+
source: 'import',
|
|
67
68
|
executor,
|
|
68
69
|
}),
|
|
69
70
|
};
|
|
70
|
-
//
|
|
71
|
-
//
|
|
71
|
+
// The import job never rejects, so the jobs service never sees its failures, and the
|
|
72
|
+
// inline path's bookkeeping failures never reach the request: a throw here would be
|
|
73
|
+
// seen by nobody.
|
|
72
74
|
const report = (error) => {
|
|
73
75
|
try {
|
|
74
76
|
logging.error({ event: { name: 'members.import.error' }, err: error }, '[Background Job] members-import error');
|
|
@@ -81,7 +83,7 @@ function makeImporter(deps) {
|
|
|
81
83
|
return new importer_1.default({
|
|
82
84
|
knex: deps.knex,
|
|
83
85
|
readRows: reader_1.default,
|
|
84
|
-
spool: (0, spool_1.createRowSpool)(),
|
|
86
|
+
spool: (0, spool_1.createRowSpool)(require('../../adapter-manager').default.getAdapter('storage:imports')),
|
|
85
87
|
members,
|
|
86
88
|
tiers: {
|
|
87
89
|
getDefault: deps.getDefaultTier,
|
|
@@ -95,7 +97,7 @@ function makeImporter(deps) {
|
|
|
95
97
|
metafields,
|
|
96
98
|
email,
|
|
97
99
|
report,
|
|
98
|
-
|
|
100
|
+
dispatchJob: deps.dispatchJob,
|
|
99
101
|
getTimezone: deps.getTimezone,
|
|
100
102
|
getInlineThreshold: deps.getInlineThreshold,
|
|
101
103
|
});
|
|
@@ -5,7 +5,7 @@ const CleanExpiredCompedJob = require('./clean-expired-comped-job').default;
|
|
|
5
5
|
const cleanTokensTask = require('./clean-tokens-task').default;
|
|
6
6
|
const cleanExpiredCompedTask = require('./clean-expired-comped-task').default;
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
const hasScheduled = {
|
|
9
9
|
expiredComped: false,
|
|
10
10
|
tokens: false,
|
|
11
11
|
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const job_1 = require("../../jobs-service/job");
|
|
4
|
+
class MembersImportJob extends job_1.Job {
|
|
5
|
+
static type = 'members-import';
|
|
6
|
+
spoolKey;
|
|
7
|
+
labelName;
|
|
8
|
+
extraLabels;
|
|
9
|
+
emailRecipient;
|
|
10
|
+
constructor(data) {
|
|
11
|
+
super();
|
|
12
|
+
this.spoolKey = data.spoolKey;
|
|
13
|
+
this.labelName = data.labelName;
|
|
14
|
+
this.extraLabels = data.extraLabels;
|
|
15
|
+
this.emailRecipient = data.emailRecipient;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.default = MembersImportJob;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.memberAvatarImage = memberAvatarImage;
|
|
4
|
+
const config = require('../../../shared/config');
|
|
5
|
+
/**
|
|
6
|
+
* The avatar shown for a member: their Gravatar, served blank when they have none, unless
|
|
7
|
+
* the site has turned Gravatar off. Nothing is stored, so every place that shows a member
|
|
8
|
+
* works it out from their email the same way.
|
|
9
|
+
*/
|
|
10
|
+
function memberAvatarImage(email) {
|
|
11
|
+
if (!email || config.isPrivacyDisabled('useGravatar')) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
// Required on first use, as the member model did. The image library is untyped JS, so
|
|
15
|
+
// `gravatar` is not checked here.
|
|
16
|
+
const { gravatar } = require('../../lib/image');
|
|
17
|
+
return gravatar.url(email, { size: 250, default: 'blank' });
|
|
18
|
+
}
|
|
@@ -57,7 +57,7 @@ module.exports = class MemberController {
|
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
const tokenData = {};
|
|
61
61
|
try {
|
|
62
62
|
const member = await this._memberRepository.getByToken(identity);
|
|
63
63
|
tokenData.oldEmail = member.get('email');
|
|
@@ -88,7 +88,7 @@ module.exports = class MemberController {
|
|
|
88
88
|
const cancelAtPeriodEnd = req.body.cancel_at_period_end;
|
|
89
89
|
const smartCancel = req.body.smart_cancel;
|
|
90
90
|
const cancellationReason = req.body.cancellation_reason;
|
|
91
|
-
|
|
91
|
+
const ghostPriceId = req.body.priceId;
|
|
92
92
|
const tierId = req.body.tierId;
|
|
93
93
|
const cadence = req.body.cadence;
|
|
94
94
|
|
|
@@ -7,7 +7,6 @@ const PaymentsService = require('./services/payments-service');
|
|
|
7
7
|
const TokenService = require('./services/token-service');
|
|
8
8
|
const GeolocationService = require('./services/geolocation-service');
|
|
9
9
|
const MemberBREADService = require('./services/member-bread-service');
|
|
10
|
-
const metafields = require('../../members-metafields');
|
|
11
10
|
const { MemberAccountService } = require('../account-service');
|
|
12
11
|
const MemberRepository = require('./repositories/member-repository');
|
|
13
12
|
const NextPaymentCalculator = require('./services/next-payment-calculator');
|
|
@@ -128,6 +127,7 @@ module.exports = function MembersAPI({
|
|
|
128
127
|
labsService,
|
|
129
128
|
memberAttributionService,
|
|
130
129
|
MemberEmailChangeEvent,
|
|
130
|
+
metafieldValues,
|
|
131
131
|
AutomatedEmailRecipient,
|
|
132
132
|
giftSubscriptions: giftService,
|
|
133
133
|
});
|
|
@@ -285,7 +285,7 @@ module.exports = function MembersAPI({
|
|
|
285
285
|
return null;
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
-
|
|
288
|
+
const member = oldEmail
|
|
289
289
|
? await getMemberIdentityData(oldEmail)
|
|
290
290
|
: await getMemberIdentityData(email);
|
|
291
291
|
|
|
@@ -365,7 +365,7 @@ module.exports = function MembersAPI({
|
|
|
365
365
|
memberBREADService,
|
|
366
366
|
members: users,
|
|
367
367
|
emailSuppressionList,
|
|
368
|
-
metafieldValues
|
|
368
|
+
metafieldValues,
|
|
369
369
|
});
|
|
370
370
|
|
|
371
371
|
async function getMemberIdentity(transientId) {
|
|
@@ -434,7 +434,7 @@ module.exports = function MembersAPI({
|
|
|
434
434
|
}
|
|
435
435
|
|
|
436
436
|
// max request time is 500ms so shouldn't slow requests down too much
|
|
437
|
-
|
|
437
|
+
const geolocation = JSON.stringify(await geolocationService.getGeolocationFromIP(ip));
|
|
438
438
|
if (geolocation) {
|
|
439
439
|
await users.update({ geolocation }, { id: member.id });
|
|
440
440
|
}
|
|
@@ -12,6 +12,7 @@ const {
|
|
|
12
12
|
} = require('@tryghost/mongo-utils');
|
|
13
13
|
const { default: ObjectID } = require('bson-objectid');
|
|
14
14
|
const db = require('../../../../data/db');
|
|
15
|
+
const { memberAvatarImage } = require('../../member-avatar');
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* This mongo transformer ignores the provided filter option and replaces the filter with a custom filter that was provided to the transformer. Allowing us to set a mongo filter instead of a string based NQL filter.
|
|
@@ -42,6 +43,7 @@ module.exports = class EventRepository {
|
|
|
42
43
|
memberAttributionService,
|
|
43
44
|
urlService,
|
|
44
45
|
MemberEmailChangeEvent,
|
|
46
|
+
metafieldValues,
|
|
45
47
|
AutomatedEmailRecipient,
|
|
46
48
|
giftSubscriptions,
|
|
47
49
|
}) {
|
|
@@ -60,6 +62,7 @@ module.exports = class EventRepository {
|
|
|
60
62
|
this._EmailSpamComplaintEvent = EmailSpamComplaintEvent;
|
|
61
63
|
this._memberAttributionService = memberAttributionService;
|
|
62
64
|
this._MemberEmailChangeEvent = MemberEmailChangeEvent;
|
|
65
|
+
this._metafieldValues = metafieldValues;
|
|
63
66
|
this._AutomatedEmailRecipient = AutomatedEmailRecipient;
|
|
64
67
|
this._giftSubscriptions = giftSubscriptions;
|
|
65
68
|
this._knex = db.knex;
|
|
@@ -99,6 +102,7 @@ module.exports = class EventRepository {
|
|
|
99
102
|
{ type: 'login_event', action: 'getLoginEvents' },
|
|
100
103
|
{ type: 'payment_event', action: 'getPaymentEvents' },
|
|
101
104
|
{ type: 'email_change_event', action: 'getEmailChangeEvent' },
|
|
105
|
+
{ type: 'metafield_change_event', action: 'getMetafieldChangeEvents' },
|
|
102
106
|
{ type: 'gift_purchase_event', action: 'getGiftPurchaseEvents' },
|
|
103
107
|
{ type: 'gift_redemption_event', action: 'getGiftRedemptionEvents' },
|
|
104
108
|
{ type: 'gift_ended_event', action: 'getGiftEndedEvents' },
|
|
@@ -652,7 +656,7 @@ module.exports = class EventRepository {
|
|
|
652
656
|
|
|
653
657
|
filter = this.removePostIdFilter(otherFilter); //Remove post_id filter as we don't need it in the query
|
|
654
658
|
|
|
655
|
-
|
|
659
|
+
const postClicksQuery = postId
|
|
656
660
|
? `SELECT
|
|
657
661
|
mce.id,
|
|
658
662
|
mce.member_id,
|
|
@@ -1012,6 +1016,37 @@ module.exports = class EventRepository {
|
|
|
1012
1016
|
};
|
|
1013
1017
|
}
|
|
1014
1018
|
|
|
1019
|
+
async getMetafieldChangeEvents(options = {}, filter) {
|
|
1020
|
+
// The entries belong to the metafields domain, which reads them without a model; the
|
|
1021
|
+
// feed maps its own filter names onto the table's columns and adds each member's avatar.
|
|
1022
|
+
const columnFilter = filter
|
|
1023
|
+
? chainTransformers(
|
|
1024
|
+
...mapKeys({
|
|
1025
|
+
'data.created_at': 'created_at',
|
|
1026
|
+
'data.member_id': 'member_id',
|
|
1027
|
+
}),
|
|
1028
|
+
)(filter)
|
|
1029
|
+
: undefined;
|
|
1030
|
+
|
|
1031
|
+
const { events, total } = await this._metafieldValues.browseChangeEvents({
|
|
1032
|
+
// The feed's limit arrives as the request sent it, which can be a numeric string
|
|
1033
|
+
// or `all`; the service takes a number, or nothing for every entry.
|
|
1034
|
+
limit: options.limit === 'all' ? undefined : Number(options.limit),
|
|
1035
|
+
filter: columnFilter,
|
|
1036
|
+
});
|
|
1037
|
+
|
|
1038
|
+
return {
|
|
1039
|
+
data: events.map((event) => ({
|
|
1040
|
+
type: 'metafield_change_event',
|
|
1041
|
+
data: {
|
|
1042
|
+
...event,
|
|
1043
|
+
member: { ...event.member, avatar_image: memberAvatarImage(event.member.email) },
|
|
1044
|
+
},
|
|
1045
|
+
})),
|
|
1046
|
+
meta: { pagination: { total } },
|
|
1047
|
+
};
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1015
1050
|
async getAutomatedEmailSentEvents(options = {}, filter) {
|
|
1016
1051
|
options = {
|
|
1017
1052
|
...options,
|