ghost 6.53.0 → 6.54.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/ghost-storage-base-3.0.0.tgz +0 -0
- package/components/tryghost-adapter-base-cache-0.2.0.tgz +0 -0
- package/components/tryghost-adapter-base-scheduling-0.1.1.tgz +0 -0
- package/components/tryghost-adapter-base-sso-0.1.1.tgz +0 -0
- package/components/tryghost-admin-api-schema-0.0.0.tgz +0 -0
- package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
- package/components/tryghost-i18n-0.0.0.tgz +0 -0
- package/components/tryghost-kg-converters-1.2.3.tgz +0 -0
- package/components/tryghost-kg-default-nodes-2.1.3.tgz +0 -0
- package/components/tryghost-kg-lexical-html-renderer-1.4.3.tgz +0 -0
- package/core/boot.js +9 -6
- package/core/built/admin/assets/Combination-CJG7Flp-.js +41 -0
- package/core/built/admin/assets/Growth-CSaHoSVD.js +3 -0
- package/core/built/admin/assets/Newsletters-C5cs6FGo.js +1 -0
- package/core/built/admin/assets/Overview-j4NaeUNm.js +1 -0
- package/core/built/admin/assets/{PolarAngleAxis-pciQ0MOy.js → PolarAngleAxis-BGjf7sBu.js} +1 -1
- package/core/built/admin/assets/{RadialBarChart-DWmw2PcX.js → RadialBarChart-zeFf9mBz.js} +1 -1
- package/core/built/admin/assets/Web-_fD935OX.js +2 -0
- package/core/built/admin/assets/account-migration-DLvVA5yq.js +1 -0
- package/core/built/admin/assets/activitypub/{account-migration-BPZG37DJ.js → account-migration-DHbZcxGM.js} +13 -13
- package/core/built/admin/assets/activitypub/activitypub.js +7 -7
- package/core/built/admin/assets/activitypub/{avatar-ZYco0ITb.js → avatar-B3DEDB1l.js} +10 -10
- package/core/built/admin/assets/activitypub/{avatar-flipboard-D541lc4F.js → avatar-flipboard-Cqrg0XMx.js} +3 -3
- package/core/built/admin/assets/activitypub/{bluesky-sharing-NOHUtHjl.js → bluesky-sharing-zfxUey_L.js} +38 -37
- package/core/built/admin/assets/activitypub/{chunk-KS7C4IRE-B-GOFDPZ.js → chunk-KS7C4IRE-D4HEcEwi.js} +716 -710
- package/core/built/admin/assets/activitypub/{content-formatters-bwrp4iEO.js → content-formatters-BpQARh28.js} +229 -181
- package/core/built/admin/assets/activitypub/{copy-C7m7ovHw.js → copy-D9UWIAan.js} +2 -2
- package/core/built/admin/assets/activitypub/{dist-B5ira32t.js → dist-Ba_QxHHl.js} +5 -5
- package/core/built/admin/assets/activitypub/{domain-iqE4YXwD.js → domain-CmwSZLHK.js} +33 -33
- package/core/built/admin/assets/activitypub/{edit-profile-B8MFYh28.js → edit-profile-CXdwNmVG.js} +46 -45
- package/core/built/admin/assets/activitypub/{explore-BbdKodp3.js → explore-DfbjzGM1.js} +20 -20
- package/core/built/admin/assets/activitypub/{feed-Cl3A5owG.js → feed-DSEBJOqf.js} +15 -15
- package/core/built/admin/assets/activitypub/{field-DL6WyR-c.js → field-CY7XVcx6.js} +13 -13
- package/core/built/admin/assets/activitypub/{hash-6G3DzwL9.js → hash-BC9Q0N4c.js} +2 -2
- package/core/built/admin/assets/activitypub/{inbox-YmhuBice.js → inbox-DQ4ZnC1m.js} +2 -2
- package/core/built/admin/assets/activitypub/inbox-DtQ0kytT.js +1221 -0
- package/core/built/admin/assets/activitypub/{label-DGbLjDvE.js → label-Dw96GQ7u.js} +6 -6
- package/core/built/admin/assets/activitypub/layout-IdVq3lRy.js +1 -0
- package/core/built/admin/assets/activitypub/{moderation-qnBtk1zS.js → moderation-Dg_-I-8C.js} +32 -31
- package/core/built/admin/assets/activitypub/{note-C7ZRoSJv.js → note-Cy1-uKMY.js} +21 -21
- package/core/built/admin/assets/activitypub/{notifications-DiEA4b1o.js → notifications-B_fvoLIM.js} +17 -17
- package/core/built/admin/assets/activitypub/{onboarding-_JVgEwgV.js → onboarding-BFDkzeR2.js} +2 -2
- package/core/built/admin/assets/activitypub/{onboarding-DG4zu3qM.js → onboarding-D6rcBdPe.js} +5 -5
- package/core/built/admin/assets/activitypub/{preferences-B3FtocnP.js → preferences-ByJseZp6.js} +1607 -1606
- package/core/built/admin/assets/activitypub/{profile-D8ZJfYXB.js → profile-BFtbnIjz.js} +264 -263
- package/core/built/admin/assets/activitypub/{reply-C1vggenw.js → reply-CpdMeAO5.js} +2 -2
- package/core/built/admin/assets/activitypub/{routes-BOii-V9n.js → routes-Dh3xXfce.js} +1311 -1295
- package/core/built/admin/assets/activitypub/{separator-1gNokN5S.js → separator-BI1FLsYM.js} +4 -4
- package/core/built/admin/assets/activitypub/{settings--9Sb0nbl.js → settings-DTgqJPxM.js} +14 -14
- package/core/built/admin/assets/activitypub/{site-fkMmqv0V.js → site-CdL9ZLqm.js} +10 -10
- package/core/built/admin/assets/activitypub/{step-1-QhivSMw2.js → step-1-DIDg4aHb.js} +15 -15
- package/core/built/admin/assets/activitypub/{step-2-pMk9YwqD.js → step-2-BfGe8BYt.js} +7 -7
- package/core/built/admin/assets/activitypub/{step-3-DvmVC1fo.js → step-3-mE9spAqw.js} +12 -12
- package/core/built/admin/assets/activitypub/{tabs-Dc0FEEYD.js → tabs-ogqwoBlb.js} +241 -237
- package/core/built/admin/assets/activitypub/{topic-filter-CuDyM5bD.js → topic-filter-DLHBZT93.js} +4 -4
- package/core/built/admin/assets/activitypub/use-activity-pub-queries-VzbN99u_.js +1957 -0
- package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-Drx1kdAK.js → use-navigate-with-base-path-CAwXTmqH.js} +165 -175
- package/core/built/admin/assets/activitypub/{use-reply-chain-data-BHkCHcW5.js → use-reply-chain-data-CxonteFD.js} +8 -8
- package/core/built/admin/assets/activitypub/users-BLeiOTHc.js +1464 -0
- package/core/built/admin/assets/activitypub/{x-BHCEe-c2.js → x-C8tAnXly.js} +2 -2
- package/core/built/admin/assets/{audience-adiFehTD.js → audience-BKRdsFmy.js} +1 -1
- package/core/built/admin/assets/{automated-emails-UWM02CMr.js → automated-emails-Cn87L5Md.js} +1 -1
- package/core/built/admin/assets/automations-B7-y3dXt.js +1 -0
- package/core/built/admin/assets/automations-BP_aHamJ.js +1 -0
- package/core/built/admin/assets/{avatar-flipboard-Lz3F9fNT.js → avatar-flipboard-C6Kj3Awu.js} +1 -1
- package/core/built/admin/assets/bluesky-sharing-Bh36XPh4.js +1 -0
- package/core/built/admin/assets/box-BWbhXh21.js +1 -0
- package/core/built/admin/assets/breadcrumb-D34YWnaw.js +1 -0
- package/core/built/admin/assets/card-DGoDJzrn.js +1 -0
- package/core/built/admin/assets/{chart-ChpW-NzQ.js → chart-BuRT2Y6p.js} +14 -14
- package/core/built/admin/assets/chart-helpers-DbklaJw9.js +1 -0
- package/core/built/admin/assets/checkbox-DA4-1UiI.js +1 -0
- package/core/built/admin/assets/chunk.524.45e0875f41b71e46e849.js +25 -0
- package/core/built/admin/assets/chunk.582.51defd4b009f0de8d4d5.js +27 -0
- package/core/built/admin/assets/{chunk.831.0703a12e49f51cec3f3a.js → chunk.589.096f4d0bb775e5229aa9.js} +78 -85
- package/core/built/admin/assets/{chunk.432.c2caa0b20f03e71d1a35.js → chunk.962.b73442b07be930bb5d85.js} +2216 -3188
- package/core/built/admin/assets/{chunk.432.c2caa0b20f03e71d1a35.js.LICENSE.txt → chunk.962.b73442b07be930bb5d85.js.LICENSE.txt} +0 -63
- package/core/built/admin/assets/code-editor-view-BKBrkffZ.js +1 -0
- package/core/built/admin/assets/comments-CzVNIT8b.js +1 -0
- package/core/built/admin/assets/container-BYz2Ed39.js +1 -0
- package/core/built/admin/assets/data-list-16rkJYYi.js +1 -0
- package/core/built/admin/assets/date-range-select-B5vSsrpx.js +1 -0
- package/core/built/admin/assets/disabled-sources-indicator-NkOIoMue.js +1 -0
- package/core/built/admin/assets/{dist-CsekE4FL.js → dist-CQJY6SVY.js} +1 -1
- package/core/built/admin/assets/dist-DGzPJ_bO.js +4 -0
- package/core/built/admin/assets/{dist-BbGrW05X.js → dist-DyViJwIy.js} +1 -1
- package/core/built/admin/assets/dist-Ndy-PuGN.js +1 -0
- package/core/built/admin/assets/dist-P_ohUlTi.js +1 -0
- package/core/built/admin/assets/domain-B7_n5nfx.js +1 -0
- package/core/built/admin/assets/dropzone-DcuJEEUf.js +5 -0
- package/core/built/admin/assets/edit-profile-rvDGrS8J.js +1 -0
- package/core/built/admin/assets/editor-BCiIyFjm.js +8 -0
- package/core/built/admin/assets/empty-indicator-oX1u1Pkn.js +1 -0
- package/core/built/admin/assets/esm-CFX93H5M.js +2 -0
- package/core/built/admin/assets/explore-BZAZOg5X.js +1 -0
- package/core/built/admin/assets/feed-CFV8xDw9.js +1 -0
- package/core/built/admin/assets/field-BW-M2Zwp.js +1 -0
- package/core/built/admin/assets/{filter-sources-v39ihhhV.js → filter-sources-Fx8wiYYw.js} +1 -1
- package/core/built/admin/assets/filters-CGX_pf2N.js +1 -0
- package/core/built/admin/assets/filters-DtcXMZDU.js +1 -0
- package/core/built/admin/assets/framework-provider-CmtnPXIT.js +4 -0
- package/core/built/admin/assets/{ghost-b57f077997b739a8ae9a70772dc016cb.js → ghost-b1dce91ad3232cc259ee5fbbf9526243.js} +294 -290
- package/core/built/admin/assets/ghost-dark-c8d0ab7f515b2010c173e23e9b32ea8a.css +1 -0
- package/core/built/admin/assets/gift-link-modal-Bk8qpnMw.js +1 -0
- package/core/built/admin/assets/{gift-links-CY3GwiVi.js → gift-links-nBxJjZiQ.js} +1 -1
- package/core/built/admin/assets/growth-Ck2s3JjR.js +1 -0
- package/core/built/admin/assets/hooks-BApwwBE0.js +2 -0
- package/core/built/admin/assets/{inbox-TEISAmth.js → inbox-BRp1_aaC.js} +35 -35
- package/core/built/admin/assets/index-BBf502Wg.js +69 -0
- package/core/built/admin/assets/index-BCCZKxP2.css +1 -0
- package/core/built/admin/assets/inline-EMAm3okk.js +1 -0
- package/core/built/admin/assets/input-group-DjuYnNCd.js +1 -0
- package/core/built/admin/assets/{react-dom-C6aoWSfl.js → jsx-runtime-DX3WBWVO.js} +1 -1
- package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +5 -2
- package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +2 -2
- package/core/built/admin/assets/{koenig-lexical-Di7b48ED.js → koenig-lexical-CM7UFNdL.js} +2 -2
- package/core/built/admin/assets/kpi-card-BrGH6FsT.js +1 -0
- package/core/built/admin/assets/kpi-card-CIGyijjx.js +1 -0
- package/core/built/admin/assets/kpi-helpers-_HRRsklE.js +1 -0
- package/core/built/admin/assets/kpi-tabs-BSvh9eoq.js +1 -0
- package/core/built/admin/assets/label-BOR9XdKl.js +1 -0
- package/core/built/admin/assets/label-picker-BdNAWuUX.js +1 -0
- package/core/built/admin/assets/{labels-GbxlXWtf.js → labels-Cyayfd-e.js} +1 -1
- package/core/built/admin/assets/layout-Bw4GnxXp.js +1 -0
- package/core/built/admin/assets/limit-service-9fwD33lU.js +20 -0
- package/core/built/admin/assets/link-helpers-tOlxmuH5.js +1 -0
- package/core/built/admin/assets/list-page-B6ANtzkd.js +1 -0
- package/core/built/admin/assets/mailchimp-Ds_NQ04w.svg +9 -0
- package/core/built/admin/assets/member-custom-fields-DvFyamLu.js +1 -0
- package/core/built/admin/assets/member-detail-Cg2vTqvJ.js +1 -0
- package/core/built/admin/assets/members-DsPxYAVm.js +10 -0
- package/core/built/admin/assets/modals-Bf_fyvHZ.js +31 -0
- package/core/built/admin/assets/moderation-Dlp7M5sa.js +1 -0
- package/core/built/admin/assets/multi-select-combobox-CH1o8XXQ.js +1 -0
- package/core/built/admin/assets/newsletter-CQ5CAYUI.js +1 -0
- package/core/built/admin/assets/{newsletters-DZm3yLj8.js → newsletters-D1jbtV-h.js} +1 -1
- package/core/built/admin/assets/note-BrAZ7Z0o.js +1 -0
- package/core/built/admin/assets/notifications-BnbHLOPC.js +1 -0
- package/core/built/admin/assets/nql-lang-B7faUf8D.js +19 -0
- package/core/built/admin/assets/{offers-D11QtPXX.js → offers-CrY6nSRR.js} +1 -1
- package/core/built/admin/assets/onboarding-route-eU146kuA.js +1 -0
- package/core/built/admin/assets/overview-BpbaK-xu.js +1 -0
- package/core/built/admin/assets/page-header-C0jVxtS8.js +1 -0
- package/core/built/admin/assets/{pages-BnObVRrf.js → pages-BbNWFcGj.js} +1 -1
- package/core/built/admin/assets/pintura-CXOmq-5H.svg +15 -0
- package/core/built/admin/assets/post-analytics-Iw7dk1mT.js +1 -0
- package/core/built/admin/assets/post-analytics-header-D9pJ4iNm.js +1 -0
- package/core/built/admin/assets/{post-analytics-provider-DSfBCtnj.js → post-analytics-provider-BDqcfBor.js} +1 -1
- package/core/built/admin/assets/post-share-modal-DBfKl2GZ.js +1 -0
- package/core/built/admin/assets/{posts-CwH8VJvB.js → posts-EWpZIjkr.js} +1 -1
- package/core/built/admin/assets/preferences-D4EANGoc.js +5 -0
- package/core/built/admin/assets/profile-dJ44Bn_W.js +1 -0
- package/core/built/admin/assets/{referrers-nxR52jPI.js → referrers-BCfFYSHc.js} +1 -1
- package/core/built/admin/assets/router-provider-C1R4AZ2o.js +1 -0
- package/core/built/admin/assets/select--2uVN9_-.js +1 -0
- package/core/built/admin/assets/settings-Bz3RZRmE.js +1 -0
- package/core/built/admin/assets/settings-SD9bxIpt.js +4 -0
- package/core/built/admin/assets/share-modal-CkdTTMJd.js +1 -0
- package/core/built/admin/assets/social-urls-BvFZwYcE.js +8 -0
- package/core/built/admin/assets/sort-button-DZp9Y2r1.js +1 -0
- package/core/built/admin/assets/source-icon-CHr9qJ2Y.js +1 -0
- package/core/built/admin/assets/stack-xiN0eQ6Z.js +1 -0
- package/core/built/admin/assets/stats-DGoXZxWE.js +1 -0
- package/core/built/admin/assets/stats-view-D2-1L0ms.js +1 -0
- package/core/built/admin/assets/step-1-RdahbwyG.js +1 -0
- package/core/built/admin/assets/step-2-D83PeRwd.js +1 -0
- package/core/built/admin/assets/step-3-p_Op4wv4.js +2 -0
- package/core/built/admin/assets/switch-qp518gFQ.js +1 -0
- package/core/built/admin/assets/table-B8LgTQJZ.js +1 -0
- package/core/built/admin/assets/tabs-D3ZOYkM7.js +1 -0
- package/core/built/admin/assets/tags-B4l891z2.js +1 -0
- package/core/built/admin/assets/text-DwtjwGkh.js +1 -0
- package/core/built/admin/assets/textarea-CTlb3Uu6.js +1 -0
- package/core/built/admin/assets/{tiers-EghDzCKc.js → tiers-BgYLWRJv.js} +1 -1
- package/core/built/admin/assets/toggle-group-DNXDkAwf.js +1 -0
- package/core/built/admin/assets/topic-filter-DZGjEcz3.js +1 -0
- package/core/built/admin/assets/{use-analytics-data-0l_OHtnR.js → use-analytics-data-CaT8RirX.js} +1 -1
- package/core/built/admin/assets/use-filter-params-DeQ8sX4N.js +1 -0
- package/core/built/admin/assets/use-growth-stats-9Db2CuJe.js +1 -0
- package/core/built/admin/assets/{use-post-referrers-DwI31Ril.js → use-post-referrers-BV54YcQS.js} +1 -1
- package/core/built/admin/assets/use-reply-chain-data-DuYZGDan.js +1 -0
- package/core/built/admin/assets/use-simple-pagination-8fTua9Nt.js +1 -0
- package/core/built/admin/assets/{use-tinybird-query-DvZBBMG7.js → use-tinybird-query-Dz156HvZ.js} +1 -1
- package/core/built/admin/assets/{use-tinybird-token-CQtebkvU.js → use-tinybird-token-C9RUdL_n.js} +1 -1
- package/core/built/admin/assets/{users-Pc8IRjk9.js → users-CcSCQFcQ.js} +1 -1
- package/core/built/admin/assets/virtual-list-BCvP0YF-.js +1 -0
- package/core/built/admin/assets/web-DTZnnUGr.js +1 -0
- package/core/built/admin/index.html +18 -22
- package/core/frontend/apps/private-blogging/index.js +1 -1
- package/core/frontend/apps/private-blogging/lib/middleware.js +1 -1
- package/core/frontend/helpers/split.js +2 -1
- package/core/frontend/meta/asset-url.js +1 -1
- package/core/frontend/meta/author-image.js +1 -1
- package/core/frontend/meta/blog-logo.js +1 -1
- package/core/frontend/meta/canonical-url.js +1 -1
- package/core/frontend/meta/cover-image.js +1 -1
- package/core/frontend/meta/get-meta.js +1 -1
- package/core/frontend/meta/og-image.js +1 -1
- package/core/frontend/meta/paginated-url.js +1 -1
- package/core/frontend/meta/twitter-image.js +1 -1
- package/core/frontend/meta/url.js +1 -1
- package/core/frontend/services/assets-minification/admin-auth-assets.js +1 -1
- package/core/frontend/services/llms/handler.js +1 -1
- package/core/frontend/services/proxy.js +31 -2
- package/core/frontend/services/routing/collection-router.js +1 -1
- package/core/frontend/services/routing/controllers/email-post.js +1 -1
- package/core/frontend/services/routing/controllers/entry/markdown.js +1 -1
- package/core/frontend/services/routing/controllers/entry/markdown.ts +1 -1
- package/core/frontend/services/routing/controllers/entry.js +1 -1
- package/core/frontend/services/routing/controllers/entry.ts +1 -1
- package/core/frontend/services/routing/controllers/previews.js +6 -7
- package/core/frontend/services/routing/controllers/unsubscribe.js +7 -3
- package/core/frontend/services/routing/email-router.js +1 -1
- package/core/frontend/services/routing/events.js +12 -0
- package/core/frontend/services/routing/middleware/page-param.js +1 -1
- package/core/frontend/services/routing/parent-router.js +1 -1
- package/core/frontend/services/routing/preview-router.js +1 -1
- package/core/frontend/services/routing/router-manager.js +4 -8
- package/core/frontend/services/routing/rss-router.js +1 -1
- package/core/frontend/services/routing/static-pages-router.js +1 -1
- package/core/frontend/services/routing/static-routes-router.js +1 -1
- package/core/frontend/services/routing/taxonomy-router.js +1 -1
- package/core/frontend/services/rss/generate-feed.js +1 -1
- package/core/frontend/services/sitemap/base-site-map-generator.js +23 -4
- package/core/frontend/services/sitemap/site-map-index-generator.js +1 -1
- package/core/frontend/services/sitemap/site-map-manager.js +14 -8
- package/core/frontend/services/sitemap/utils.js +1 -1
- package/core/frontend/services/theme-engine/middleware/update-global-template-options.js +1 -1
- package/core/frontend/services/theme-engine/middleware/update-local-template-options.js +1 -1
- package/core/frontend/utils/images.js +1 -1
- package/core/frontend/web/middleware/admin-toolbar.js +1 -1
- package/core/frontend/web/middleware/handle-image-sizes.js +2 -2
- package/core/frontend/web/middleware/redirect-ghost-to-admin.js +1 -1
- package/core/frontend/web/routers/serve-favicon.js +1 -1
- package/core/frontend/web/routers/serve-public-file.js +1 -1
- package/core/frontend/web/site.js +5 -5
- package/core/server/adapters/cache/AdapterCacheMemoryTTL.js +2 -2
- package/core/server/adapters/cache/MemoryCache.js +2 -2
- package/core/server/adapters/cache/Redis.js +1 -1
- package/core/server/adapters/cache/index.js +1 -1
- package/core/server/adapters/lib/redis/AdapterCacheRedis.js +2 -2
- package/core/server/adapters/route-settings/FileStore.js +2 -8
- package/core/server/adapters/route-settings/FileStore.ts +1 -6
- package/core/server/adapters/route-settings/S3RouteSettingsStore.js +206 -0
- package/core/server/adapters/route-settings/S3RouteSettingsStore.ts +199 -0
- package/core/server/adapters/route-settings/utils.js +13 -0
- package/core/server/adapters/route-settings/utils.ts +7 -0
- package/core/server/adapters/scheduling/deps.d.ts +0 -2
- package/core/server/adapters/scheduling/error-capture.js +76 -0
- package/core/server/adapters/scheduling/error-capture.ts +91 -0
- package/core/server/adapters/scheduling/utils.js +18 -34
- package/core/server/adapters/scheduling/utils.ts +36 -0
- package/core/server/adapters/storage/LocalFilesStorage.js +1 -1
- package/core/server/adapters/storage/LocalImagesStorage.js +1 -1
- package/core/server/adapters/storage/LocalMediaStorage.js +1 -1
- package/core/server/adapters/storage/LocalStorageBase.js +3 -3
- package/core/server/adapters/storage/S3Storage.js +2 -2
- package/core/server/adapters/storage/S3Storage.ts +1 -1
- package/core/server/adapters/storage/utils.js +1 -1
- package/core/server/api/endpoints/authentication.js +1 -1
- package/core/server/api/endpoints/featurebase.js +1 -1
- package/core/server/api/endpoints/files.js +2 -2
- package/core/server/api/endpoints/images.js +2 -2
- package/core/server/api/endpoints/libraries.d.ts +0 -1
- package/core/server/api/endpoints/media.js +8 -5
- package/core/server/api/endpoints/member-custom-fields.js +4 -1
- package/core/server/api/endpoints/member-custom-fields.ts +4 -1
- package/core/server/api/endpoints/posts.js +17 -1
- package/core/server/api/endpoints/search-index-public.js +4 -3
- package/core/server/api/endpoints/search-index.js +5 -4
- package/core/server/api/endpoints/settings-public.js +1 -1
- package/core/server/api/endpoints/settings.js +3 -1
- package/core/server/api/endpoints/utils/serializers/input/utils/url.js +9 -1
- package/core/server/api/endpoints/utils/serializers/output/default.js +7 -0
- package/core/server/api/endpoints/utils/serializers/output/files.js +1 -1
- package/core/server/api/endpoints/utils/serializers/output/media.js +1 -1
- package/core/server/api/endpoints/utils/serializers/output/member-custom-fields.js +7 -4
- package/core/server/api/endpoints/utils/serializers/output/member-custom-fields.ts +8 -4
- package/core/server/api/endpoints/utils/serializers/output/members.js +16 -26
- package/core/server/api/endpoints/utils/serializers/output/pages.js +7 -0
- package/core/server/api/endpoints/utils/serializers/output/posts.js +13 -0
- package/core/server/api/endpoints/utils/serializers/output/utils/url.js +1 -1
- package/core/server/api/endpoints/utils/validators/input/members.js +2 -52
- package/core/server/data/db/backup.js +1 -1
- package/core/server/data/importer/handlers/image.js +3 -3
- package/core/server/data/importer/import-manager.js +6 -4
- package/core/server/data/importer/importers/content-file-importer.js +2 -2
- package/core/server/data/migrations/utils/schema.js +4 -2
- package/core/server/data/migrations/versions/6.54/2026-07-19-16-59-00-add-content-import-permission.js +10 -0
- package/core/server/data/migrations/versions/6.54/2026-07-20-13-59-21-drop-email-tracked-sent-count-from-automation-action-revisions.js +7 -0
- package/core/server/data/migrations/versions/6.54/2026-07-21-01-58-20-add-automation-run-steps-poller-index.js +3 -0
- package/core/server/data/migrations/versions/6.54/2026-07-21-21-08-15-add-automated-email-recipients-mailgun-message-id-index.js +3 -0
- package/core/server/data/migrations/versions/6.54/2026-07-22-10-41-08-add-click-tracking-to-automated-email-recipients.js +13 -0
- package/core/server/data/migrations/versions/6.54/2026-07-22-15-10-30-add-email-clicked-count-to-automation-action-revisions.js +7 -0
- package/core/server/data/migrations/versions/6.54/2026-07-23-10-24-18-add-automation-action-revision-to-redirects.js +9 -0
- package/core/server/data/schema/commands.js +37 -3
- package/core/server/data/schema/fixtures/fixtures.json +7 -0
- package/core/server/data/schema/lib/default-index-name.js +20 -0
- package/core/server/data/schema/schema.js +40 -17
- package/core/server/data/seeders/data-generator.js +4 -2
- package/core/server/lib/image/image-size.js +5 -7
- package/core/server/lib/image/image-utils.js +2 -2
- package/core/server/lib/image/index.js +4 -4
- package/core/server/lib/lexical.js +3 -3
- package/core/server/lib/mobiledoc.js +2 -2
- package/core/server/lib/validate-password.js +1 -1
- package/core/server/models/action.js +9 -0
- package/core/server/models/base/plugins/generate-slug.js +1 -1
- package/core/server/models/collection.js +1 -1
- package/core/server/models/custom-theme-setting.js +1 -1
- package/core/server/models/member.js +73 -0
- package/core/server/models/newsletter.js +1 -1
- package/core/server/models/post.js +19 -5
- package/core/server/models/posts-meta.js +1 -1
- package/core/server/models/redirect.js +1 -1
- package/core/server/models/settings.js +1 -1
- package/core/server/models/snippet.js +1 -1
- package/core/server/models/tag.js +1 -1
- package/core/server/models/user.js +1 -1
- package/core/server/models/welcome-email-automated-email.js +1 -1
- package/core/server/services/activitypub/activity-pub-service-wrapper.js +1 -1
- package/core/server/services/adapter-manager/adapter-manager.js +5 -1
- package/core/server/services/adapter-manager/adapter-manager.ts +7 -2
- package/core/server/services/adapter-manager/index.js +18 -15
- package/core/server/services/adapter-manager/index.ts +23 -17
- package/core/server/services/adapter-manager/utils.js +124 -14
- package/core/server/services/adapter-manager/utils.ts +130 -14
- package/core/server/services/api-version-compatibility/mw-version-rewrites.js +1 -1
- package/core/server/services/audience-feedback/index.js +1 -1
- package/core/server/services/auth/passwordreset.js +1 -1
- package/core/server/services/auth/session/express-session.js +1 -1
- package/core/server/services/auth/session/index.js +2 -2
- package/core/server/services/auth/session/session-service.js +1 -1
- package/core/server/services/automations/automations-api.js +2 -19
- package/core/server/services/automations/automations-api.ts +2 -31
- package/core/server/services/automations/automations-repository.ts +15 -0
- package/core/server/services/automations/database-automations-repository.js +30 -2
- package/core/server/services/automations/database-automations-repository.ts +33 -2
- package/core/server/services/automations/poll.js +16 -12
- package/core/server/services/automations/poll.ts +17 -15
- package/core/server/services/automations/service.js +1 -1
- package/core/server/services/automations/service.ts +3 -13
- package/core/server/services/automations/welcome-email-automation-poll.js +2 -1
- package/core/server/services/comments/index.js +1 -1
- package/core/server/services/custom-redirects/index.js +2 -2
- package/core/server/services/email-analytics/email-analytics-service-wrapper.js +14 -13
- package/core/server/services/email-analytics/email-analytics-service.js +1 -1
- package/core/server/services/email-analytics/events/start-email-analytics-job-event.js +11 -15
- package/core/server/services/email-analytics/events/start-email-analytics-job-event.ts +15 -0
- package/core/server/services/email-analytics/index.js +2 -3
- package/core/server/services/email-analytics/index.ts +1 -2
- package/core/server/services/email-analytics/jobs/email-analytics-job-scheduler.js +1 -6
- package/core/server/services/email-analytics/jobs/email-analytics-job-scheduler.ts +0 -9
- package/core/server/services/email-analytics/jobs/fetch-latest/index.js +1 -1
- package/core/server/services/email-analytics/jobs/index.js +0 -2
- package/core/server/services/email-service/email-service-wrapper.js +1 -1
- package/core/server/services/email-service/email-service.js +20 -4
- package/core/server/services/explore-ping/explore-ping-service.js +24 -39
- package/core/server/services/explore-ping/explore-ping-service.ts +198 -0
- package/core/server/services/explore-ping/index.js +11 -11
- package/core/server/services/explore-ping/index.ts +42 -0
- package/core/server/services/gifts/gift-reminder-scheduler.js +1 -1
- package/core/server/services/gifts/gift-reminder-scheduler.ts +1 -1
- package/core/server/services/gifts/gift-service-wrapper.js +1 -1
- package/core/server/services/identity-tokens/identity-token-service-wrapper.js +1 -1
- package/core/server/services/indexnow-ping/constants.js +30 -0
- package/core/server/services/indexnow-ping/constants.ts +32 -0
- package/core/server/services/indexnow-ping/index.js +29 -253
- package/core/server/services/indexnow-ping/index.ts +37 -0
- package/core/server/services/indexnow-ping/indexnow-ping-service.js +229 -0
- package/core/server/services/indexnow-ping/indexnow-ping-service.ts +319 -0
- package/core/server/services/invites/index.js +1 -1
- package/core/server/services/lib/mailgun-client.js +3 -3
- package/core/server/services/link-redirection/index.js +2 -2
- package/core/server/services/link-redirection/link-redirect-repository.js +1 -1
- package/core/server/services/link-redirection/link-redirect.js +12 -13
- package/core/server/services/link-redirection/link-redirect.ts +22 -0
- package/core/server/services/link-redirection/link-redirects-service.js +1 -1
- package/core/server/services/link-tracking/full-post-link.js +2 -2
- package/core/server/services/link-tracking/index.js +1 -1
- package/core/server/services/mail/ghost-mailer.js +1 -1
- package/core/server/services/mail/index.js +1 -1
- package/core/server/services/media-inliner/external-media-inliner.js +2 -2
- package/core/server/services/media-inliner/service.js +4 -3
- package/core/server/services/member-attribution/index.js +1 -1
- package/core/server/services/member-welcome-emails/service.js +1 -1
- package/core/server/services/members/api.js +8 -2
- package/core/server/services/members/csv/index.js +10 -0
- package/core/server/services/members/csv/index.ts +3 -0
- package/core/server/services/members/csv/parse.js +94 -0
- package/core/server/services/members/csv/parse.ts +111 -0
- package/core/server/services/members/csv/types.js +2 -0
- package/core/server/services/members/csv/types.ts +39 -0
- package/core/server/services/members/csv/unparse.js +69 -0
- package/core/server/services/members/csv/unparse.ts +79 -0
- package/core/server/services/members/exporter/query.js +35 -8
- package/core/server/services/members/importer/config.js +35 -0
- package/core/server/services/members/importer/config.ts +39 -0
- package/core/server/services/members/importer/members-csv-importer.js +31 -13
- package/core/server/services/members/members-api/members-api.js +4 -2
- package/core/server/services/members/members-api/repositories/event-repository.js +13 -2
- package/core/server/services/members/members-api/services/member-bread-service.js +42 -19
- package/core/server/services/members/middleware.js +1 -1
- package/core/server/services/members/service.js +15 -2
- package/core/server/services/members/stripe-connect.js +1 -1
- package/core/server/services/members-custom-fields/actions.js +3 -0
- package/core/server/services/members-custom-fields/actions.ts +6 -2
- package/core/server/services/members-custom-fields/config.js +34 -0
- package/core/server/services/members-custom-fields/config.ts +38 -0
- package/core/server/services/members-custom-fields/definitions-service.js +156 -21
- package/core/server/services/members-custom-fields/definitions-service.ts +170 -25
- package/core/server/services/members-custom-fields/index.js +16 -3
- package/core/server/services/members-custom-fields/index.ts +17 -3
- package/core/server/services/members-custom-fields/values-service.js +56 -10
- package/core/server/services/members-custom-fields/values-service.ts +62 -10
- package/core/server/services/mentions/mention-sending-service.js +22 -2
- package/core/server/services/mentions/service.js +21 -5
- package/core/server/services/newsletters/index.js +1 -1
- package/core/server/services/oembed/oembed-service.js +122 -33
- package/core/server/services/oembed/service.js +4 -2
- package/core/server/services/offers/service.js +1 -1
- package/core/server/services/post-scheduling/index.js +4 -3
- package/core/server/services/post-scheduling/index.ts +4 -3
- package/core/server/services/post-scheduling/post-scheduling.js +1 -1
- package/core/server/services/post-scheduling/post-scheduling.ts +1 -1
- package/core/server/services/posts/post-email-handler.js +13 -6
- package/core/server/services/posts/post-scheduling.js +1 -1
- package/core/server/services/posts/posts-service-instance.js +1 -1
- package/core/server/services/posts/posts-service.js +2 -2
- package/core/server/services/posts-public/service.js +1 -1
- package/core/server/services/public-config/site.js +1 -1
- package/core/server/services/recommendations/recommendation-service-wrapper.js +1 -1
- package/core/server/services/recommendations/service/libraries.d.ts +0 -2
- package/core/server/services/route-settings/dynamic-routing-service.js +2 -3
- package/core/server/services/route-settings/index.js +1 -1
- package/core/server/services/route-settings/route-settings-parser.js +134 -124
- package/core/server/services/route-settings/route-settings-parser.ts +160 -125
- package/core/server/services/route-settings/validation-errors.js +178 -0
- package/core/server/services/route-settings/validation-errors.ts +196 -0
- package/core/server/services/settings/settings-service.js +2 -2
- package/core/server/services/settings-helpers/index.js +1 -1
- package/core/server/services/slack-notifications/service.js +1 -1
- package/core/server/services/slack-ping/constants.js +16 -0
- package/core/server/services/slack-ping/constants.ts +15 -0
- package/core/server/services/slack-ping/index.js +26 -204
- package/core/server/services/slack-ping/index.ts +35 -0
- package/core/server/services/slack-ping/slack-ping-service.js +214 -0
- package/core/server/services/slack-ping/slack-ping-service.ts +296 -0
- package/core/server/services/staff/index.js +1 -1
- package/core/server/services/stats/posts-stats-service.js +1 -1
- package/core/server/services/stats/service.js +1 -1
- package/core/server/services/stripe/service.js +1 -1
- package/core/server/services/tags-public/service.js +1 -1
- package/core/server/services/themes/validate.js +1 -1
- package/core/server/services/update-check/index.js +1 -1
- package/core/server/services/url/lazy-url-service.js +66 -6
- package/core/server/services/url/lazy-url-service.ts +73 -6
- package/core/server/services/url/url-generator.js +1 -1
- package/core/server/services/url/url-service-facade.js +68 -3
- package/core/server/services/url/url-service-facade.ts +79 -4
- package/core/server/services/url/url-service.js +1 -1
- package/core/server/services/url/urls.js +1 -1
- package/core/server/services/webhooks/index.js +19 -2
- package/core/server/services/webhooks/listen.js +6 -11
- package/core/server/services/webhooks/payload.js +1 -3
- package/core/server/services/webhooks/serialize.js +16 -1
- package/core/server/web/admin/app.js +1 -1
- package/core/server/web/admin/middleware/redirect-admin-urls.js +1 -1
- package/core/server/web/api/endpoints/admin/routes.js +1 -0
- package/core/server/web/api/middleware/cors.js +1 -1
- package/core/server/web/api/middleware/upload.js +4 -0
- package/core/server/web/gift-preview/controller.js +1 -1
- package/core/server/web/shared/middleware/redirect-amp-urls.js +1 -1
- package/core/server/web/shared/middleware/uncapitalise.js +2 -2
- package/core/server/web/shared/middleware/url-redirects.js +1 -1
- package/core/shared/config/defaults.json +8 -1
- package/core/shared/config/overrides.json +4 -0
- package/core/shared/url-utils.js +19 -15
- package/core/shared/url-utils.ts +20 -0
- package/ghost.js +0 -1
- package/package.json +26 -31
- package/pnpm-lock.yaml +681 -2789
- package/pnpm-workspace.yaml +31 -17
- package/components/tryghost-adapter-base-scheduling-0.0.0.tgz +0 -0
- package/components/tryghost-adapter-base-sso-0.0.0.tgz +0 -0
- package/core/built/admin/assets/Combination--5EZGaDs.js +0 -43
- package/core/built/admin/assets/Growth-C0NoKcHQ.js +0 -3
- package/core/built/admin/assets/Newsletters-Ed8kDjdy.js +0 -1
- package/core/built/admin/assets/Overview-CArPgRZt.js +0 -1
- package/core/built/admin/assets/Web-CjjYoVM3.js +0 -2
- package/core/built/admin/assets/account-migration-mfa5mNI9.js +0 -1
- package/core/built/admin/assets/activitypub/inbox-B3rjKMTv.js +0 -1221
- package/core/built/admin/assets/activitypub/layout-jcurg3rU.js +0 -1
- package/core/built/admin/assets/activitypub/use-activity-pub-queries-yqGRcnLn.js +0 -2569
- package/core/built/admin/assets/activitypub/users-CfyHIsTG.js +0 -1316
- package/core/built/admin/assets/automations-DkUnxNdv.js +0 -1
- package/core/built/admin/assets/automations-vjXofmV_.js +0 -1
- package/core/built/admin/assets/bluesky-sharing-T-pO3RcP.js +0 -1
- package/core/built/admin/assets/breadcrumb-CekPYTCn.js +0 -1
- package/core/built/admin/assets/button--i2uMDDn.js +0 -4
- package/core/built/admin/assets/card-CSWz_BXq.js +0 -1
- package/core/built/admin/assets/chart-helpers-C_4Ka_vT.js +0 -1
- package/core/built/admin/assets/chunk.524.8ce2c741473e2f0929dc.js +0 -25
- package/core/built/admin/assets/chunk.582.453459d6228d2955408b.js +0 -27
- package/core/built/admin/assets/code-editor-view-BfkwQto2.js +0 -1
- package/core/built/admin/assets/command-K75Jzs0G.js +0 -1
- package/core/built/admin/assets/comments-BEIi1DH-.js +0 -1
- package/core/built/admin/assets/container-BNXvlcjA.js +0 -1
- package/core/built/admin/assets/data-list-BmK5QMab.js +0 -1
- package/core/built/admin/assets/date-range-select-5sKzwbt7.js +0 -1
- package/core/built/admin/assets/disabled-sources-indicator-L_ssJTNr.js +0 -1
- package/core/built/admin/assets/dist-BBIJuyPg.js +0 -1
- package/core/built/admin/assets/dist-BHE0dp6o.js +0 -1
- package/core/built/admin/assets/dist-DJ6c4_De.js +0 -1
- package/core/built/admin/assets/dist-DW0QXQO3.js +0 -1
- package/core/built/admin/assets/dist-DxFLceO5.js +0 -1
- package/core/built/admin/assets/dist-QcACAOAD.js +0 -1
- package/core/built/admin/assets/dist-duxRDcQu.js +0 -177
- package/core/built/admin/assets/domain-CLaPZ9Rc.js +0 -1
- package/core/built/admin/assets/dropzone-E0bSX4_a.js +0 -5
- package/core/built/admin/assets/edit-profile-DqNPKaA4.js +0 -1
- package/core/built/admin/assets/editor-CkLXQDRp.js +0 -8
- package/core/built/admin/assets/empty-indicator-BTtOlgIo.js +0 -1
- package/core/built/admin/assets/esm-TSfGW7nz.js +0 -2
- package/core/built/admin/assets/explore-BEstLxKr.js +0 -1
- package/core/built/admin/assets/feed-C58p2voG.js +0 -1
- package/core/built/admin/assets/field-BSbDUHPv.js +0 -1
- package/core/built/admin/assets/filters-BgYv8Gt7.js +0 -1
- package/core/built/admin/assets/filters-DvenFkmK.js +0 -1
- package/core/built/admin/assets/framework-provider-jQktxm9P.js +0 -4
- package/core/built/admin/assets/ghost-dark-8590dea6cd695ff90f27d262c4464538.css +0 -1
- package/core/built/admin/assets/gift-link-modal-BPjXkEFt.js +0 -1
- package/core/built/admin/assets/growth-D4JNiVTe.js +0 -1
- package/core/built/admin/assets/hooks-Cjxexi_I.js +0 -2
- package/core/built/admin/assets/index-BacwlcOy.js +0 -67
- package/core/built/admin/assets/index-DxRNHH0o.css +0 -1
- package/core/built/admin/assets/inline-C22rnPro.js +0 -1
- package/core/built/admin/assets/input-group-CKfrILLP.js +0 -1
- package/core/built/admin/assets/jsx-runtime-CtMZ-PAS.js +0 -1
- package/core/built/admin/assets/kpi-card-DZxQKAIb.js +0 -1
- package/core/built/admin/assets/kpi-card-FidQ5zg3.js +0 -1
- package/core/built/admin/assets/kpi-helpers-C5T8Vaf1.js +0 -1
- package/core/built/admin/assets/kpi-tabs-_VRK6hGV.js +0 -1
- package/core/built/admin/assets/label-Cza7hPgn.js +0 -1
- package/core/built/admin/assets/label-picker-DgC_zLaw.js +0 -1
- package/core/built/admin/assets/layout-BxsXnKFX.js +0 -1
- package/core/built/admin/assets/limit-service-CTurluJQ.js +0 -20
- package/core/built/admin/assets/link-helpers-C3Gqy2cz.js +0 -1
- package/core/built/admin/assets/list-page-BtqCnow_.js +0 -1
- package/core/built/admin/assets/member-custom-fields-9uXFBqSt.js +0 -1
- package/core/built/admin/assets/member-detail-Dq6ZDIxo.js +0 -1
- package/core/built/admin/assets/members-CUWD9jal.js +0 -10
- package/core/built/admin/assets/modals-CIdwHVga.js +0 -31
- package/core/built/admin/assets/moderation-DTt04UDA.js +0 -1
- package/core/built/admin/assets/newsletter-cC8vcc9h.js +0 -1
- package/core/built/admin/assets/note-DZU0IY9e.js +0 -1
- package/core/built/admin/assets/notifications-NoHpBHJ4.js +0 -1
- package/core/built/admin/assets/nql-lang-CvCSOQG3.js +0 -19
- package/core/built/admin/assets/onboarding-route-Deg2hNm8.js +0 -1
- package/core/built/admin/assets/overview-BQPt_9w3.js +0 -1
- package/core/built/admin/assets/page-header-D6bEqPo2.js +0 -1
- package/core/built/admin/assets/post-analytics-header-BPw_B2_D.js +0 -1
- package/core/built/admin/assets/post-analytics-kp2_--XO.js +0 -1
- package/core/built/admin/assets/post-share-modal-Cave3Z4W.js +0 -1
- package/core/built/admin/assets/preferences-C7h3j_uy.js +0 -5
- package/core/built/admin/assets/profile-B2x4q2oB.js +0 -1
- package/core/built/admin/assets/router-provider-5fsX1CYn.js +0 -1
- package/core/built/admin/assets/select-PhPjIBBT.js +0 -1
- package/core/built/admin/assets/settings-D5P9Gwgo.js +0 -6
- package/core/built/admin/assets/settings-zUOzQV5I.js +0 -1
- package/core/built/admin/assets/share-modal-EfpfbuWF.js +0 -1
- package/core/built/admin/assets/social-urls-DgAF08Xc.js +0 -18
- package/core/built/admin/assets/sort-button-WOQYJm2H.js +0 -1
- package/core/built/admin/assets/source-icon-hm8Cj-Gx.js +0 -1
- package/core/built/admin/assets/stats-CnQDb62m.js +0 -1
- package/core/built/admin/assets/stats-view-CCfTJgSe.js +0 -1
- package/core/built/admin/assets/step-1-BGlhY4DS.js +0 -1
- package/core/built/admin/assets/step-2-D3sDEyFH.js +0 -1
- package/core/built/admin/assets/step-3-CvZoUdsc.js +0 -2
- package/core/built/admin/assets/switch-CNjkOmwz.js +0 -1
- package/core/built/admin/assets/table-C5nZYPnW.js +0 -1
- package/core/built/admin/assets/tabs-dtOcExye.js +0 -1
- package/core/built/admin/assets/tags-Dhm0FB_g.js +0 -1
- package/core/built/admin/assets/textarea-CeKw3wmV.js +0 -1
- package/core/built/admin/assets/toggle-group-DfhZIMTW.js +0 -1
- package/core/built/admin/assets/topic-filter-Cxe1Il41.js +0 -1
- package/core/built/admin/assets/typeof-Ca-duI-z.js +0 -1
- package/core/built/admin/assets/use-filter-params-Bub6BqNy.js +0 -1
- package/core/built/admin/assets/use-growth-stats-BJORomv0.js +0 -1
- package/core/built/admin/assets/use-reply-chain-data-B89YjVoo.js +0 -1
- package/core/built/admin/assets/use-simple-pagination-BL2SYXKi.js +0 -1
- package/core/built/admin/assets/virtual-list-DNJOSK9I.js +0 -1
- package/core/built/admin/assets/web-BHUE3YQc.js +0 -1
- package/core/server/adapters/scheduling/scheduling-base.js +0 -5
- package/core/server/adapters/sso/SSOBase.js +0 -5
- package/core/server/adapters/storage/index.js +0 -17
|
@@ -81,6 +81,17 @@ export type AutomatedEmailEvents = {
|
|
|
81
81
|
automationActionRevisionId: string;
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
+
export type RecordEmailSentOptions = Readonly<{
|
|
85
|
+
automationActionRevisionId: string;
|
|
86
|
+
mailgunMessageId?: string;
|
|
87
|
+
memberEmail: string;
|
|
88
|
+
memberId: string;
|
|
89
|
+
memberName: string | null;
|
|
90
|
+
memberUuid: string;
|
|
91
|
+
trackClicks: boolean;
|
|
92
|
+
trackOpens: boolean;
|
|
93
|
+
}>;
|
|
94
|
+
|
|
84
95
|
type AutomationStepBase = {
|
|
85
96
|
id: string;
|
|
86
97
|
locked_by: string;
|
|
@@ -167,6 +178,10 @@ export interface AutomationsRepository {
|
|
|
167
178
|
step: Pick<AutomationStepToRun, 'id' | 'locked_by'>,
|
|
168
179
|
retryAt: Readonly<Date>
|
|
169
180
|
): Promise<boolean>;
|
|
181
|
+
/**
|
|
182
|
+
* Record a sent email and increment its action revision's sent count.
|
|
183
|
+
*/
|
|
184
|
+
recordEmailSent(options: RecordEmailSentOptions): Promise<void>;
|
|
170
185
|
/**
|
|
171
186
|
* Fetch sent emails by their Mailgun IDs.
|
|
172
187
|
*/
|
|
@@ -94,6 +94,29 @@ function createDatabaseAutomationsRepository({ knex, fakeWaitHoursMultiplier })
|
|
|
94
94
|
async retryStep(step, retryAt) {
|
|
95
95
|
return await knex.transaction(trx => retryStep(trx, step, retryAt));
|
|
96
96
|
},
|
|
97
|
+
async recordEmailSent(options) {
|
|
98
|
+
await knex.transaction(async (trx) => {
|
|
99
|
+
await trx('automation_action_revisions')
|
|
100
|
+
.where('id', options.automationActionRevisionId)
|
|
101
|
+
.update({
|
|
102
|
+
email_sent_count: trx.raw('COALESCE(??, 0) + ?', ['email_sent_count', 1])
|
|
103
|
+
});
|
|
104
|
+
const now = toDatabaseDate(new Date());
|
|
105
|
+
await trx('automated_email_recipients').insert({
|
|
106
|
+
id: (0, bson_objectid_1.default)().toHexString(),
|
|
107
|
+
member_id: options.memberId,
|
|
108
|
+
member_uuid: options.memberUuid,
|
|
109
|
+
member_email: options.memberEmail,
|
|
110
|
+
member_name: options.memberName,
|
|
111
|
+
automation_action_revision_id: options.automationActionRevisionId,
|
|
112
|
+
...(options.mailgunMessageId ? { mailgun_message_id: options.mailgunMessageId } : {}),
|
|
113
|
+
track_clicks: options.trackClicks,
|
|
114
|
+
track_opens: options.trackOpens,
|
|
115
|
+
created_at: now,
|
|
116
|
+
updated_at: now
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
},
|
|
97
120
|
async getAutomatedEmailRecipientsByMailgunIds(mailgunMessageIds) {
|
|
98
121
|
if (mailgunMessageIds.length === 0) {
|
|
99
122
|
return [];
|
|
@@ -128,7 +151,10 @@ function createDatabaseAutomationsRepository({ knex, fakeWaitHoursMultiplier })
|
|
|
128
151
|
newOpensPerRevision.set(automationActionRevisionId, (newOpensPerRevision.get(automationActionRevisionId) ?? 0) + 1);
|
|
129
152
|
}
|
|
130
153
|
}
|
|
131
|
-
|
|
154
|
+
// Keep lock acquisition order consistent across concurrent transactions to avoid deadlocks.
|
|
155
|
+
const revisions = [...newOpensPerRevision.entries()]
|
|
156
|
+
.sort(([left], [right]) => left.localeCompare(right));
|
|
157
|
+
for (const [id, opens] of revisions) {
|
|
132
158
|
await trx('automation_action_revisions')
|
|
133
159
|
.where({ id })
|
|
134
160
|
.update({
|
|
@@ -329,6 +355,7 @@ async function fetchAndLockSteps(trx, limit) {
|
|
|
329
355
|
.innerJoin('automations as automation', 'automation.id', 'run.automation_id')
|
|
330
356
|
.innerJoin('automation_action_revisions as revision', 'revision.id', 'step.automation_action_revision_id')
|
|
331
357
|
.innerJoin('automation_actions as action', 'action.id', 'revision.action_id')
|
|
358
|
+
.whereIn('step.id', candidateIds)
|
|
332
359
|
.where('step.locked_by', lockId)
|
|
333
360
|
.orderBy([
|
|
334
361
|
'step.ready_at',
|
|
@@ -342,13 +369,14 @@ async function fetchAndLockSteps(trx, limit) {
|
|
|
342
369
|
}
|
|
343
370
|
async function findNextPendingReadyAt(trx, staleLockCutoff) {
|
|
344
371
|
const row = await trx('automation_run_steps')
|
|
345
|
-
.
|
|
372
|
+
.select({ next_ready_at: 'ready_at' })
|
|
346
373
|
.where('status', 'pending')
|
|
347
374
|
.where((builder) => {
|
|
348
375
|
builder
|
|
349
376
|
.whereNull('locked_by')
|
|
350
377
|
.orWhere('locked_at', '<', toDatabaseDate(staleLockCutoff));
|
|
351
378
|
})
|
|
379
|
+
.orderBy('ready_at')
|
|
352
380
|
.first();
|
|
353
381
|
return row?.next_ready_at ? new Date(row.next_ready_at) : null;
|
|
354
382
|
}
|
|
@@ -224,6 +224,31 @@ export function createDatabaseAutomationsRepository({
|
|
|
224
224
|
return await knex.transaction(trx => retryStep(trx, step, retryAt));
|
|
225
225
|
},
|
|
226
226
|
|
|
227
|
+
async recordEmailSent(options): Promise<void> {
|
|
228
|
+
await knex.transaction(async (trx) => {
|
|
229
|
+
await trx('automation_action_revisions')
|
|
230
|
+
.where('id', options.automationActionRevisionId)
|
|
231
|
+
.update({
|
|
232
|
+
email_sent_count: trx.raw('COALESCE(??, 0) + ?', ['email_sent_count', 1])
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const now = toDatabaseDate(new Date());
|
|
236
|
+
await trx('automated_email_recipients').insert({
|
|
237
|
+
id: ObjectId().toHexString(),
|
|
238
|
+
member_id: options.memberId,
|
|
239
|
+
member_uuid: options.memberUuid,
|
|
240
|
+
member_email: options.memberEmail,
|
|
241
|
+
member_name: options.memberName,
|
|
242
|
+
automation_action_revision_id: options.automationActionRevisionId,
|
|
243
|
+
...(options.mailgunMessageId ? {mailgun_message_id: options.mailgunMessageId} : {}),
|
|
244
|
+
track_clicks: options.trackClicks,
|
|
245
|
+
track_opens: options.trackOpens,
|
|
246
|
+
created_at: now,
|
|
247
|
+
updated_at: now
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
},
|
|
251
|
+
|
|
227
252
|
async getAutomatedEmailRecipientsByMailgunIds(mailgunMessageIds) {
|
|
228
253
|
if (mailgunMessageIds.length === 0) {
|
|
229
254
|
return [];
|
|
@@ -266,7 +291,11 @@ export function createDatabaseAutomationsRepository({
|
|
|
266
291
|
}
|
|
267
292
|
}
|
|
268
293
|
|
|
269
|
-
|
|
294
|
+
// Keep lock acquisition order consistent across concurrent transactions to avoid deadlocks.
|
|
295
|
+
const revisions = [...newOpensPerRevision.entries()]
|
|
296
|
+
.sort(([left], [right]) => left.localeCompare(right));
|
|
297
|
+
|
|
298
|
+
for (const [id, opens] of revisions) {
|
|
270
299
|
await trx('automation_action_revisions')
|
|
271
300
|
.where({id})
|
|
272
301
|
.update({
|
|
@@ -542,6 +571,7 @@ async function fetchAndLockSteps(trx: Knex.Transaction, limit: number): Promise<
|
|
|
542
571
|
.innerJoin('automations as automation', 'automation.id', 'run.automation_id')
|
|
543
572
|
.innerJoin('automation_action_revisions as revision', 'revision.id', 'step.automation_action_revision_id')
|
|
544
573
|
.innerJoin('automation_actions as action', 'action.id', 'revision.action_id')
|
|
574
|
+
.whereIn('step.id', candidateIds)
|
|
545
575
|
.where('step.locked_by', lockId)
|
|
546
576
|
.orderBy([
|
|
547
577
|
'step.ready_at',
|
|
@@ -557,13 +587,14 @@ async function fetchAndLockSteps(trx: Knex.Transaction, limit: number): Promise<
|
|
|
557
587
|
|
|
558
588
|
async function findNextPendingReadyAt(trx: Knex.Transaction, staleLockCutoff: Readonly<Date>): Promise<Date | null> {
|
|
559
589
|
const row = await trx('automation_run_steps')
|
|
560
|
-
.
|
|
590
|
+
.select({next_ready_at: 'ready_at'})
|
|
561
591
|
.where('status', 'pending')
|
|
562
592
|
.where((builder) => {
|
|
563
593
|
builder
|
|
564
594
|
.whereNull('locked_by')
|
|
565
595
|
.orWhere('locked_at', '<', toDatabaseDate(staleLockCutoff));
|
|
566
596
|
})
|
|
597
|
+
.orderBy('ready_at')
|
|
567
598
|
.first();
|
|
568
599
|
return row?.next_ready_at ? new Date(row.next_ready_at) : null;
|
|
569
600
|
}
|
|
@@ -112,6 +112,7 @@ const processStep = async ({ automationsApi, memberWelcomeEmailService, schedule
|
|
|
112
112
|
break;
|
|
113
113
|
}
|
|
114
114
|
memberWelcomeEmailService.init();
|
|
115
|
+
const trackClicks = Boolean(settingsCache.get('email_track_clicks'));
|
|
115
116
|
const trackOpens = Boolean(settingsCache.get('email_track_opens'));
|
|
116
117
|
const sendResult = await memberWelcomeEmailService.api.sendAutomationEmail({
|
|
117
118
|
email: {
|
|
@@ -138,6 +139,7 @@ const processStep = async ({ automationsApi, memberWelcomeEmailService, schedule
|
|
|
138
139
|
memberId: step.member_id,
|
|
139
140
|
memberName: member.get('name'),
|
|
140
141
|
memberUuid: member.get('uuid'),
|
|
142
|
+
trackClicks,
|
|
141
143
|
trackOpens: trackOpensForRecipient
|
|
142
144
|
});
|
|
143
145
|
}
|
|
@@ -151,18 +153,20 @@ const processStep = async ({ automationsApi, memberWelcomeEmailService, schedule
|
|
|
151
153
|
}
|
|
152
154
|
}, `[AUTOMATIONS] Failed to record automated email recipient for step ${step.id}`);
|
|
153
155
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
156
|
+
if (mailgunMessageId) {
|
|
157
|
+
try {
|
|
158
|
+
await scheduleAutomationEmailAnalyticsJob();
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
logging_1.default.error({
|
|
162
|
+
err,
|
|
163
|
+
system: {
|
|
164
|
+
event: 'automations.poll.analytics_scheduling_failed',
|
|
165
|
+
member_id: step.member_id,
|
|
166
|
+
step_id: step.id
|
|
167
|
+
}
|
|
168
|
+
}, `[AUTOMATIONS] Failed to schedule email analytics job for step ${step.id}`);
|
|
169
|
+
}
|
|
166
170
|
}
|
|
167
171
|
break;
|
|
168
172
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type {AutomationStepToRun, AutomationsRepository} from './automations-repository';
|
|
2
|
-
import type {RecordEmailSentOptions} from './automations-api';
|
|
3
2
|
import {getMailgunMessageId} from './mailgun-message-id';
|
|
4
3
|
import logging from '@tryghost/logging';
|
|
5
4
|
import errors from '@tryghost/errors';
|
|
@@ -44,10 +43,9 @@ type PollOptions = {
|
|
|
44
43
|
'fetchAndLockSteps' |
|
|
45
44
|
'finishStepAndEnqueueNext' |
|
|
46
45
|
'markStepTerminal' |
|
|
46
|
+
'recordEmailSent' |
|
|
47
47
|
'retryStep'
|
|
48
|
-
|
|
49
|
-
recordEmailSent(options: RecordEmailSentOptions): Promise<void>;
|
|
50
|
-
};
|
|
48
|
+
>;
|
|
51
49
|
enqueueAnotherPollAt: (date: Readonly<Date>) => unknown;
|
|
52
50
|
scheduleAutomationEmailAnalyticsJob: () => Promise<void>;
|
|
53
51
|
memberWelcomeEmailService: MemberWelcomeEmailService;
|
|
@@ -185,6 +183,7 @@ const processStep = async ({
|
|
|
185
183
|
break;
|
|
186
184
|
}
|
|
187
185
|
memberWelcomeEmailService.init();
|
|
186
|
+
const trackClicks = Boolean(settingsCache.get('email_track_clicks'));
|
|
188
187
|
const trackOpens = Boolean(settingsCache.get('email_track_opens'));
|
|
189
188
|
const sendResult = await memberWelcomeEmailService.api.sendAutomationEmail({
|
|
190
189
|
email: {
|
|
@@ -211,6 +210,7 @@ const processStep = async ({
|
|
|
211
210
|
memberId: step.member_id,
|
|
212
211
|
memberName: member.get('name'),
|
|
213
212
|
memberUuid: member.get('uuid'),
|
|
213
|
+
trackClicks,
|
|
214
214
|
trackOpens: trackOpensForRecipient
|
|
215
215
|
});
|
|
216
216
|
} catch (err) {
|
|
@@ -223,17 +223,19 @@ const processStep = async ({
|
|
|
223
223
|
}
|
|
224
224
|
}, `[AUTOMATIONS] Failed to record automated email recipient for step ${step.id}`);
|
|
225
225
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
226
|
+
if (mailgunMessageId) {
|
|
227
|
+
try {
|
|
228
|
+
await scheduleAutomationEmailAnalyticsJob();
|
|
229
|
+
} catch (err) {
|
|
230
|
+
logging.error({
|
|
231
|
+
err,
|
|
232
|
+
system: {
|
|
233
|
+
event: 'automations.poll.analytics_scheduling_failed',
|
|
234
|
+
member_id: step.member_id,
|
|
235
|
+
step_id: step.id
|
|
236
|
+
}
|
|
237
|
+
}, `[AUTOMATIONS] Failed to schedule email analytics job for step ${step.id}`);
|
|
238
|
+
}
|
|
237
239
|
}
|
|
238
240
|
break;
|
|
239
241
|
}
|
|
@@ -45,7 +45,7 @@ const promises_1 = require("node:timers/promises");
|
|
|
45
45
|
const soonest_timer_1 = require("../../lib/soonest-timer");
|
|
46
46
|
// @ts-expect-error This module currently lacks type definitions.
|
|
47
47
|
const jobs_1 = __importDefault(require("../email-analytics/jobs"));
|
|
48
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
48
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
49
49
|
const logging = require('@tryghost/logging');
|
|
50
50
|
const { getSignedAdminToken } = require('../../adapters/scheduling/utils');
|
|
51
51
|
const StartAutomationsPollEvent = require('./events/start-automations-poll-event');
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
|
+
import type {SchedulerAdapter} from '@tryghost/adapter-base-scheduling';
|
|
2
3
|
import type {InternalKeys} from '../internal-keys';
|
|
3
4
|
// @ts-expect-error @tryghost/domain-events currently lacks type declarations.
|
|
4
5
|
import type DomainEvents from '@tryghost/domain-events';
|
|
@@ -10,29 +11,18 @@ import {SoonestTimer} from '../../lib/soonest-timer';
|
|
|
10
11
|
// @ts-expect-error This module currently lacks type definitions.
|
|
11
12
|
import emailAnalyticsJobs from '../email-analytics/jobs';
|
|
12
13
|
|
|
13
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
14
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
14
15
|
const logging = require('@tryghost/logging');
|
|
15
16
|
const {getSignedAdminToken} = require('../../adapters/scheduling/utils');
|
|
16
17
|
const StartAutomationsPollEvent = require('./events/start-automations-poll-event');
|
|
17
18
|
const {welcomeEmailAutomationPoll} = require('./welcome-email-automation-poll');
|
|
18
19
|
const memberWelcomeEmailService = require('../member-welcome-emails/service');
|
|
19
20
|
|
|
20
|
-
type SchedulerAdapter = {
|
|
21
|
-
schedule(job: {
|
|
22
|
-
extra: {
|
|
23
|
-
httpMethod: string;
|
|
24
|
-
};
|
|
25
|
-
time: number;
|
|
26
|
-
url: string;
|
|
27
|
-
}): void;
|
|
28
|
-
register(rescheduler: {rescheduleAll: () => unknown}): void;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
21
|
type AutomationsServiceOptions = {
|
|
32
22
|
apiUrl: string;
|
|
33
23
|
domainEvents: Pick<DomainEvents, 'dispatch' | 'subscribe'>;
|
|
34
24
|
internalKeys: InternalKeys;
|
|
35
|
-
schedulerAdapter: SchedulerAdapter
|
|
25
|
+
schedulerAdapter: Pick<SchedulerAdapter, 'schedule' | 'register'>;
|
|
36
26
|
};
|
|
37
27
|
|
|
38
28
|
const scheduleAutomationEmailAnalyticsJob = () => (
|
|
@@ -235,7 +235,8 @@ async function processRun({
|
|
|
235
235
|
member_uuid: member.get('uuid'),
|
|
236
236
|
member_email: member.get('email'),
|
|
237
237
|
member_name: member.get('name'),
|
|
238
|
-
track_opens: false
|
|
238
|
+
track_opens: false,
|
|
239
|
+
track_clicks: false
|
|
239
240
|
}, {transacting});
|
|
240
241
|
|
|
241
242
|
await markExited(run.id, 'finished', transacting);
|
|
@@ -11,7 +11,7 @@ class CommentsServiceWrapper {
|
|
|
11
11
|
const mailer = new GhostMailer();
|
|
12
12
|
const settingsCache = require('../../../shared/settings-cache');
|
|
13
13
|
const urlService = require('../url');
|
|
14
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
14
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
15
15
|
const membersService = require('../members');
|
|
16
16
|
const db = require('../../data/db');
|
|
17
17
|
const settingsHelpers = require('../settings-helpers');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const config = require('../../../shared/config');
|
|
2
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
3
|
-
const adapterManager = require('../adapter-manager');
|
|
2
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
3
|
+
const adapterManager = require('../adapter-manager').default;
|
|
4
4
|
|
|
5
5
|
const DynamicRedirectManager = require('../lib/dynamic-redirect-manager');
|
|
6
6
|
const {RedirectsService} = require('./redirects-service');
|
|
@@ -8,6 +8,7 @@ const domainEvents = require('@tryghost/domain-events');
|
|
|
8
8
|
|
|
9
9
|
class EmailAnalyticsServiceWrapper {
|
|
10
10
|
/** @type {string} */ #logName;
|
|
11
|
+
#fetching = false;
|
|
11
12
|
#restoredSchedule = false;
|
|
12
13
|
|
|
13
14
|
get #logPrefix() {
|
|
@@ -128,9 +129,9 @@ class EmailAnalyticsServiceWrapper {
|
|
|
128
129
|
logging.warn(`${this.#logPrefix} Opened events processing is ${lagMinutes.toFixed(1)} minutes behind (threshold: ${lagThreshold})`);
|
|
129
130
|
}
|
|
130
131
|
|
|
131
|
-
const
|
|
132
|
+
const fetchStartedAt = Date.now();
|
|
132
133
|
const fetchResult = await this.service.fetchLatestOpenedEvents({maxEvents});
|
|
133
|
-
const totalDuration = Date.now() -
|
|
134
|
+
const totalDuration = Date.now() - fetchStartedAt;
|
|
134
135
|
|
|
135
136
|
this._logJobCompletion('latest-opened', fetchResult, totalDuration);
|
|
136
137
|
|
|
@@ -138,9 +139,9 @@ class EmailAnalyticsServiceWrapper {
|
|
|
138
139
|
}
|
|
139
140
|
|
|
140
141
|
async fetchLatestNonOpenedEvents({maxEvents} = {maxEvents: Infinity}) {
|
|
141
|
-
const
|
|
142
|
+
const fetchStartedAt = Date.now();
|
|
142
143
|
const fetchResult = await this.service.fetchLatestNonOpenedEvents({maxEvents});
|
|
143
|
-
const totalDuration = Date.now() -
|
|
144
|
+
const totalDuration = Date.now() - fetchStartedAt;
|
|
144
145
|
|
|
145
146
|
this._logJobCompletion('latest', fetchResult, totalDuration);
|
|
146
147
|
|
|
@@ -148,9 +149,9 @@ class EmailAnalyticsServiceWrapper {
|
|
|
148
149
|
}
|
|
149
150
|
|
|
150
151
|
async fetchMissing({maxEvents} = {maxEvents: Infinity}) {
|
|
151
|
-
const
|
|
152
|
+
const fetchStartedAt = Date.now();
|
|
152
153
|
const fetchResult = await this.service.fetchMissing({maxEvents});
|
|
153
|
-
const totalDuration = Date.now() -
|
|
154
|
+
const totalDuration = Date.now() - fetchStartedAt;
|
|
154
155
|
|
|
155
156
|
this._logJobCompletion('missing', fetchResult, totalDuration);
|
|
156
157
|
|
|
@@ -162,9 +163,9 @@ class EmailAnalyticsServiceWrapper {
|
|
|
162
163
|
return 0;
|
|
163
164
|
}
|
|
164
165
|
|
|
165
|
-
const
|
|
166
|
+
const fetchStartedAt = Date.now();
|
|
166
167
|
const fetchResult = await this.service.fetchScheduled({maxEvents});
|
|
167
|
-
const totalDuration = Date.now() -
|
|
168
|
+
const totalDuration = Date.now() - fetchStartedAt;
|
|
168
169
|
|
|
169
170
|
this._logJobCompletion('scheduled', fetchResult, totalDuration);
|
|
170
171
|
|
|
@@ -177,11 +178,11 @@ class EmailAnalyticsServiceWrapper {
|
|
|
177
178
|
await this.service.restoreScheduled();
|
|
178
179
|
}
|
|
179
180
|
|
|
180
|
-
if (this
|
|
181
|
+
if (this.#fetching) {
|
|
181
182
|
logging.info(`Email analytics fetch for ${this.#logName} already running, skipping`);
|
|
182
183
|
return;
|
|
183
184
|
}
|
|
184
|
-
this
|
|
185
|
+
this.#fetching = true;
|
|
185
186
|
|
|
186
187
|
// NOTE: Data shows we can process ~2500 events per minute on Pro for a large-ish db (150k members).
|
|
187
188
|
// This can vary locally, but we should be conservative with the number of events we fetch.
|
|
@@ -216,18 +217,18 @@ class EmailAnalyticsServiceWrapper {
|
|
|
216
217
|
logging.info(`${this.#logPrefix} Job complete - No events`);
|
|
217
218
|
}
|
|
218
219
|
|
|
219
|
-
this
|
|
220
|
+
this.#fetching = false;
|
|
220
221
|
} catch (e) {
|
|
221
222
|
logging.error(e, `Error while fetching email analytics for ${this.#logName}`);
|
|
222
223
|
|
|
223
224
|
// Log again only the error, otherwise we lose the stack trace
|
|
224
225
|
logging.error(e);
|
|
225
226
|
}
|
|
226
|
-
this
|
|
227
|
+
this.#fetching = false;
|
|
227
228
|
}
|
|
228
229
|
|
|
229
230
|
_restartFetch(reason) {
|
|
230
|
-
this
|
|
231
|
+
this.#fetching = false;
|
|
231
232
|
logging.info(`${this.#logPrefix} Restarting fetch due to ${reason}`);
|
|
232
233
|
this.startFetch();
|
|
233
234
|
}
|
|
@@ -105,7 +105,7 @@ module.exports = class EmailAnalyticsService {
|
|
|
105
105
|
* @param {object} dependencies
|
|
106
106
|
* @param {object} dependencies.queries
|
|
107
107
|
* @param {object} dependencies.provider
|
|
108
|
-
* @param {PrometheusClient} dependencies.prometheusClient
|
|
108
|
+
* @param {PrometheusClient} [dependencies.prometheusClient]
|
|
109
109
|
* @param {() => BatchEventProcessor} dependencies.createEventProcessor
|
|
110
110
|
* @param {JobNames} dependencies.jobNames
|
|
111
111
|
* @param {CursorSeed} dependencies.cursorSeed
|
|
@@ -1,22 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StartEmailAnalyticsJobEvent = void 0;
|
|
1
4
|
/**
|
|
2
5
|
* This is an event that is used to circumvent the job manager that currently isn't able to run scheduled jobs on the main thread (not offloaded).
|
|
3
6
|
* We simply emit this event in the job manager and listen for it on the main thread.
|
|
4
7
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* @param {Date} timestamp
|
|
9
|
-
*/
|
|
10
|
-
constructor(data, timestamp) {
|
|
11
|
-
this.data = data;
|
|
8
|
+
class StartEmailAnalyticsJobEvent {
|
|
9
|
+
timestamp;
|
|
10
|
+
constructor(timestamp) {
|
|
12
11
|
this.timestamp = timestamp;
|
|
13
12
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
* @param {any} [data]
|
|
17
|
-
* @param {Date} [timestamp]
|
|
18
|
-
*/
|
|
19
|
-
static create(data, timestamp) {
|
|
20
|
-
return new StartEmailAnalyticsJobEvent(data, timestamp ?? new Date);
|
|
13
|
+
static create(timestamp = new Date()) {
|
|
14
|
+
return new StartEmailAnalyticsJobEvent(timestamp);
|
|
21
15
|
}
|
|
22
|
-
}
|
|
16
|
+
}
|
|
17
|
+
exports.StartEmailAnalyticsJobEvent = StartEmailAnalyticsJobEvent;
|
|
18
|
+
;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is an event that is used to circumvent the job manager that currently isn't able to run scheduled jobs on the main thread (not offloaded).
|
|
3
|
+
* We simply emit this event in the job manager and listen for it on the main thread.
|
|
4
|
+
*/
|
|
5
|
+
export class StartEmailAnalyticsJobEvent {
|
|
6
|
+
readonly timestamp: Date;
|
|
7
|
+
|
|
8
|
+
constructor(timestamp: Date) {
|
|
9
|
+
this.timestamp = timestamp;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static create(timestamp = new Date()) {
|
|
13
|
+
return new StartEmailAnalyticsJobEvent(timestamp);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
@@ -59,8 +59,7 @@ const domain_events_1 = __importDefault(require("@tryghost/domain-events"));
|
|
|
59
59
|
const prometheus_client_1 = __importDefault(require("../../../shared/prometheus-client"));
|
|
60
60
|
// @ts-expect-error This module lacks type definitions.
|
|
61
61
|
const queries_1 = __importDefault(require("./lib/queries"));
|
|
62
|
-
|
|
63
|
-
const start_email_analytics_job_event_1 = __importDefault(require("./events/start-email-analytics-job-event"));
|
|
62
|
+
const start_email_analytics_job_event_1 = require("./events/start-email-analytics-job-event");
|
|
64
63
|
const start_automation_email_analytics_job_event_1 = require("./events/start-automation-email-analytics-job-event");
|
|
65
64
|
const constants_1 = require("../member-welcome-emails/constants");
|
|
66
65
|
const automationsApi = __importStar(require("../automations/automations-api"));
|
|
@@ -93,7 +92,7 @@ const init = () => {
|
|
|
93
92
|
newsletterMailgunTags.push(config_1.default.get('bulkEmail:mailgun:tag'));
|
|
94
93
|
}
|
|
95
94
|
exports.newsletters.init({
|
|
96
|
-
event: start_email_analytics_job_event_1.
|
|
95
|
+
event: start_email_analytics_job_event_1.StartEmailAnalyticsJobEvent,
|
|
97
96
|
mailgunTags: newsletterMailgunTags,
|
|
98
97
|
jobNames: {
|
|
99
98
|
latestNonOpened: 'email-analytics-latest-others',
|
|
@@ -20,8 +20,7 @@ import domainEvents from '@tryghost/domain-events';
|
|
|
20
20
|
import prometheusClient from '../../../shared/prometheus-client';
|
|
21
21
|
// @ts-expect-error This module lacks type definitions.
|
|
22
22
|
import queries from './lib/queries';
|
|
23
|
-
|
|
24
|
-
import StartEmailAnalyticsJobEvent from './events/start-email-analytics-job-event';
|
|
23
|
+
import {StartEmailAnalyticsJobEvent} from './events/start-email-analytics-job-event';
|
|
25
24
|
import {StartAutomationEmailAnalyticsJobEvent} from './events/start-automation-email-analytics-job-event';
|
|
26
25
|
import {AUTOMATION_EMAIL_TAG} from '../member-welcome-emails/constants';
|
|
27
26
|
import * as automationsApi from '../automations/automations-api';
|
|
@@ -51,12 +51,10 @@ class EmailAnalyticsJobScheduler {
|
|
|
51
51
|
#hasScheduledAutomationsJob = false;
|
|
52
52
|
#models;
|
|
53
53
|
#config;
|
|
54
|
-
#labs;
|
|
55
54
|
#jobManager;
|
|
56
|
-
constructor({ models, config,
|
|
55
|
+
constructor({ models, config, jobManager }) {
|
|
57
56
|
this.#models = models;
|
|
58
57
|
this.#config = config;
|
|
59
|
-
this.#labs = labs;
|
|
60
58
|
this.#jobManager = jobManager;
|
|
61
59
|
}
|
|
62
60
|
#isConfigured() {
|
|
@@ -94,9 +92,6 @@ class EmailAnalyticsJobScheduler {
|
|
|
94
92
|
if (!this.#isConfigured()) {
|
|
95
93
|
return;
|
|
96
94
|
}
|
|
97
|
-
if (!this.#labs.isSet('automationAnalytics')) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
95
|
const hasAutomatedEmailRecipient = (skipAutomationEmailCheck ||
|
|
101
96
|
Boolean(await this.#models.AutomatedEmailRecipient
|
|
102
97
|
.query()
|
|
@@ -19,7 +19,6 @@ type Models = {
|
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
21
|
type Config = {get(key: string): unknown};
|
|
22
|
-
type Labs = {isSet(flag: string): boolean};
|
|
23
22
|
type JobManager = {
|
|
24
23
|
addJob(options: {
|
|
25
24
|
job: string;
|
|
@@ -42,23 +41,19 @@ export class EmailAnalyticsJobScheduler {
|
|
|
42
41
|
#hasScheduledAutomationsJob = false;
|
|
43
42
|
readonly #models: Models;
|
|
44
43
|
readonly #config: Config;
|
|
45
|
-
readonly #labs: Labs;
|
|
46
44
|
readonly #jobManager: JobManager;
|
|
47
45
|
|
|
48
46
|
constructor({
|
|
49
47
|
models,
|
|
50
48
|
config,
|
|
51
|
-
labs,
|
|
52
49
|
jobManager
|
|
53
50
|
}: {
|
|
54
51
|
models: Models,
|
|
55
52
|
config: Config,
|
|
56
|
-
labs: Labs,
|
|
57
53
|
jobManager: JobManager
|
|
58
54
|
}) {
|
|
59
55
|
this.#models = models;
|
|
60
56
|
this.#config = config;
|
|
61
|
-
this.#labs = labs;
|
|
62
57
|
this.#jobManager = jobManager;
|
|
63
58
|
}
|
|
64
59
|
|
|
@@ -106,10 +101,6 @@ export class EmailAnalyticsJobScheduler {
|
|
|
106
101
|
return;
|
|
107
102
|
}
|
|
108
103
|
|
|
109
|
-
if (!this.#labs.isSet('automationAnalytics')) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
104
|
const hasAutomatedEmailRecipient = (
|
|
114
105
|
skipAutomationEmailCheck ||
|
|
115
106
|
Boolean(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const {run} = require('../fetch-latest-job');
|
|
2
|
-
const StartEmailAnalyticsJobEvent = require('../../events/start-email-analytics-job-event');
|
|
2
|
+
const {StartEmailAnalyticsJobEvent} = require('../../events/start-email-analytics-job-event');
|
|
3
3
|
|
|
4
4
|
run({
|
|
5
5
|
event: StartEmailAnalyticsJobEvent,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const config = require('../../../../shared/config');
|
|
2
|
-
const labs = require('../../../../shared/labs');
|
|
3
2
|
const models = require('../../../models');
|
|
4
3
|
const jobsService = require('../../jobs');
|
|
5
4
|
const {EmailAnalyticsJobScheduler} = require('./email-analytics-job-scheduler');
|
|
@@ -7,7 +6,6 @@ const {EmailAnalyticsJobScheduler} = require('./email-analytics-job-scheduler');
|
|
|
7
6
|
const emailAnalyticsJobScheduler = new EmailAnalyticsJobScheduler({
|
|
8
7
|
models,
|
|
9
8
|
config,
|
|
10
|
-
labs,
|
|
11
9
|
jobManager: jobsService
|
|
12
10
|
});
|
|
13
11
|
|
|
@@ -41,7 +41,7 @@ class EmailServiceWrapper {
|
|
|
41
41
|
const emailAddressService = require('../email-address');
|
|
42
42
|
const i18nLib = require('@tryghost/i18n');
|
|
43
43
|
const lexicalLib = require('../../lib/lexical');
|
|
44
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
44
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
45
45
|
const memberAttribution = require('../member-attribution');
|
|
46
46
|
const linkReplacer = require('../lib/link-replacer');
|
|
47
47
|
const linkTracking = require('../link-tracking');
|