ghost 6.56.0 → 6.57.1
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/validate-adapters.js +74 -0
- package/bin/validate-adapters.ts +87 -0
- package/bin/warm-compile-cache.sh +60 -0
- package/components/tryghost-adapter-base-scheduling-0.2.1.tgz +0 -0
- package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
- package/components/tryghost-kg-converters-1.2.4.tgz +0 -0
- package/components/tryghost-kg-default-cards-10.3.4.tgz +0 -0
- package/components/tryghost-kg-default-nodes-2.1.5.tgz +0 -0
- package/components/tryghost-kg-default-transforms-1.3.3.tgz +0 -0
- package/components/tryghost-kg-html-to-lexical-1.3.3.tgz +0 -0
- package/components/tryghost-kg-lexical-html-renderer-1.4.3.tgz +0 -0
- package/components/tryghost-parse-email-address-0.0.0.tgz +0 -0
- package/core/app.js +1 -1
- package/core/boot.js +21 -25
- package/core/bridge.js +10 -12
- package/core/built/admin/assets/Combination-BDvCdg1t.js +41 -0
- package/core/built/admin/assets/about-BNojRaxf.js +1 -0
- package/core/built/admin/assets/{account-migration-D3O_yVck.js → account-migration-DMS8JsM-.js} +1 -1
- package/core/built/admin/assets/action-list-lGzZLHc8.js +1 -0
- package/core/built/admin/assets/activitypub/{account-migration-D8FbP-Z-.js → account-migration-DHFbePl6.js} +7 -7
- package/core/built/admin/assets/activitypub/activitypub.js +3 -3
- package/core/built/admin/assets/activitypub/{avatar-11EA1VSs.js → avatar-CT4tS2_S.js} +2 -2
- package/core/built/admin/assets/activitypub/{avatar-flipboard-jfbLG-xe.js → avatar-flipboard-ByYWKipo.js} +2 -2
- package/core/built/admin/assets/activitypub/{bluesky-sharing-f1jTQe2P.js → bluesky-sharing-srVnSHDz.js} +8 -8
- package/core/built/admin/assets/activitypub/{content-formatters-nmTOPY9M.js → content-formatters-C2sos5Ht.js} +3 -3
- package/core/built/admin/assets/activitypub/{copy-BCwo9ep3.js → copy-B1UBTOoZ.js} +2 -2
- package/core/built/admin/assets/activitypub/{dist-BEfX-0aW.js → dist-MPsb2WZ1.js} +4 -4
- package/core/built/admin/assets/activitypub/{domain-AaDlZlrA.js → domain-DzcM9Dzo.js} +9 -9
- package/core/built/admin/assets/activitypub/{edit-profile-DPi8Tl5M.js → edit-profile-CsQ_4xAk.js} +5 -5
- package/core/built/admin/assets/activitypub/{explore-CxTzjILQ.js → explore-CJe0DZBK.js} +8 -8
- package/core/built/admin/assets/activitypub/{feed-DPv5x2MX.js → feed-CKV3qWON.js} +9 -9
- package/core/built/admin/assets/activitypub/{field-DbgA8lat.js → field-DckHfDJf.js} +3 -3
- package/core/built/admin/assets/activitypub/{hash-BWuZoYkA.js → hash-Dlp8RM55.js} +2 -2
- package/core/built/admin/assets/activitypub/{inbox-35VDQ2K2.js → inbox-CsPy4R0M.js} +2 -2
- package/core/built/admin/assets/activitypub/{inbox-DSrF_i1O.js → inbox-DAsjzUUe.js} +10 -10
- package/core/built/admin/assets/activitypub/{label-CPjFBbo7.js → label-DWyo9E5T.js} +3 -3
- package/core/built/admin/assets/activitypub/layout-DM_3pqsU.js +1 -0
- package/core/built/admin/assets/activitypub/{moderation-BkDC1XVZ.js → moderation-B0Inc03M.js} +7 -7
- package/core/built/admin/assets/activitypub/{note-xEyH4xT-.js → note-CSE54lER.js} +7 -7
- package/core/built/admin/assets/activitypub/{notifications-DClaL3ui.js → notifications-RSwbKqdh.js} +9 -9
- package/core/built/admin/assets/activitypub/{preferences-DpnOa-4Z.js → preferences-CE231n2_.js} +11 -11
- package/core/built/admin/assets/activitypub/{profile-Dvi9mz-6.js → profile-aaQ1j1Eo.js} +13 -13
- package/core/built/admin/assets/activitypub/{reply-Cs9ySd6Z.js → reply-Cjb0Vs3m.js} +2 -2
- package/core/built/admin/assets/activitypub/{routes-DFBeTnfn.js → routes-Djb0mc9k.js} +26 -26
- package/core/built/admin/assets/activitypub/{separator-C5u_VjzY.js → separator-D8pROI5n.js} +3 -3
- package/core/built/admin/assets/activitypub/{settings-CV2fFu6D.js → settings-DMc32IQl.js} +5 -5
- package/core/built/admin/assets/activitypub/{site-_TgDd_EM.js → site-DVIcsohX.js} +4 -4
- package/core/built/admin/assets/activitypub/{step-1-BfnNL2oF.js → step-1-9Yey9usF.js} +5 -5
- package/core/built/admin/assets/activitypub/{step-2-DLndZkO-.js → step-2-DdYmKRXV.js} +6 -6
- package/core/built/admin/assets/activitypub/{step-3-A-PZTtRE.js → step-3-hdSkcjZU.js} +10 -10
- package/core/built/admin/assets/activitypub/{tabs-BUbz7tea.js → tabs-CUqseYzQ.js} +6 -6
- package/core/built/admin/assets/activitypub/{topic-filter-BdX_xYYT.js → topic-filter-Coni6OXM.js} +3 -3
- package/core/built/admin/assets/activitypub/{use-activity-pub-queries-EwuRemHh.js → use-activity-pub-queries-MeHTPMQv.js} +2 -2
- package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-cy4ACBc4.js → use-navigate-with-base-path-B046AM38.js} +24 -7
- package/core/built/admin/assets/activitypub/{use-reply-chain-data-CyFcGfan.js → use-reply-chain-data-1AO-Xob6.js} +5 -5
- package/core/built/admin/assets/activitypub/{x-7zk8mV2p.js → x-BRfRYd16.js} +2 -2
- package/core/built/admin/assets/add-integration-modal-DU9ghGLS.js +1 -0
- package/core/built/admin/assets/add-newsletter-modal-DFxuQrYu.js +1 -0
- package/core/built/admin/assets/add-recommendation-modal-D-3LOrdd.js +1 -0
- package/core/built/admin/assets/analytics-DTIMRhWw.js +1 -0
- package/core/built/admin/assets/announcement-bar-modal-DGCcezB6.js +1 -0
- package/core/built/admin/assets/api-keys-Dx4NeNpK.js +1 -0
- package/core/built/admin/assets/api-keys-_iCT4dxr.js +1 -0
- package/core/built/admin/assets/{audience-CkBb2LlO.js → audience-DkknNqhZ.js} +1 -1
- package/core/built/admin/assets/automated-emails-PayPCT8L.js +1 -0
- package/core/built/admin/assets/{automations-DhKeS_U5.js → automations-162q5HjL.js} +1 -1
- package/core/built/admin/assets/{automations-cMllU545.js → automations-DvSU7QhW.js} +1 -1
- package/core/built/admin/assets/{bluesky-sharing-DPGpyD-G.js → bluesky-sharing-yZ9A_jL8.js} +1 -1
- package/core/built/admin/assets/brand-icon-09YqFZjV.js +1 -0
- package/core/built/admin/assets/{breadcrumb-DIfcF5ow.js → breadcrumb-CjOH7LCU.js} +1 -1
- package/core/built/admin/assets/{chart-helpers-DV0FkdcD.js → chart-helpers-DGxvWnBT.js} +1 -1
- package/core/built/admin/assets/checkbox-BSUcnNq_.js +1 -0
- package/core/built/admin/assets/{chunk.332.05991a101d67f732dec3.js → chunk.424.4a27628efdade15c2dab.js} +28 -27
- package/core/built/admin/assets/chunk.524.dce1c51e0bc30fb2718e.js +25 -0
- package/core/built/admin/assets/{chunk.211.6f7328d63c41536451b3.js → chunk.571.40f093ed6d883993714e.js} +5 -5
- package/core/built/admin/assets/chunk.582.3a430d5c6a744fd475b6.js +27 -0
- package/core/built/admin/assets/code-editor-view-BcyKABrG.js +1 -0
- package/core/built/admin/assets/color-picker-field-8NoSnhNI.js +1 -0
- package/core/built/admin/assets/color-utils-Dzeeuj1F.js +1 -0
- package/core/built/admin/assets/combobox-5rdgDrDV.js +1 -0
- package/core/built/admin/assets/command-BOYMbZa_.js +1 -0
- package/core/built/admin/assets/comments-BhNM5CYl.js +1 -0
- package/core/built/admin/assets/components-CwL6a6As-B0E0-NBJ.js +1 -0
- package/core/built/admin/assets/confirmation-modal-CYD7x3UQ.js +1 -0
- package/core/built/admin/assets/content-api-modal-BtW4Z1-1.js +1 -0
- package/core/built/admin/assets/copy-field-CEp_XieW.js +1 -0
- package/core/built/admin/assets/currency-Dy4Tc2R2.js +1 -0
- package/core/built/admin/assets/custom-integration-modal-bk3lNEuQ.js +1 -0
- package/core/built/admin/assets/{date-range-select-dXc-GsVe.js → date-range-select-B3Ij1Rqg.js} +1 -1
- package/core/built/admin/assets/debounce-Cx5B_9OI.js +3 -0
- package/core/built/admin/assets/design-and-theme-modal-B2xYKS1I.js +23 -0
- package/core/built/admin/assets/dirty-confirm-dialog-YE9L21gY.js +1 -0
- package/core/built/admin/assets/disabled-sources-indicator-uIzbWL7K.js +1 -0
- package/core/built/admin/assets/{dist-pHiOxyxa.js → dist-ARN6XTcR.js} +1 -1
- package/core/built/admin/assets/dist-B2PvRwLn.js +1 -0
- package/core/built/admin/assets/{dist-DyViJwIy.js → dist-Bg8bSvLA.js} +3 -3
- package/core/built/admin/assets/dist-CsvXCJSe.js +23 -0
- package/core/built/admin/assets/dist-DlCyLrOC.js +1 -0
- package/core/built/admin/assets/dist-j1xxxnY8.js +1 -0
- package/core/built/admin/assets/dist-myQaY0ka.js +1 -0
- package/core/built/admin/assets/{domain-B5ogXUBa.js → domain-DzrOAPY8.js} +1 -1
- package/core/built/admin/assets/{dropzone-BnFG7dDP.js → dropzone-CzhP33wa.js} +1 -1
- package/core/built/admin/assets/{edit-profile-B07jCZy9.js → edit-profile-oufs4R4n.js} +1 -1
- package/core/built/admin/assets/editor-BBKrunMK.js +8 -0
- package/core/built/admin/assets/embed-signup-form-modal-Ch3s6lqA.js +9 -0
- package/core/built/admin/assets/{explore-Ca1y8HW_.js → explore-CA-R01Br.js} +1 -1
- package/core/built/admin/assets/{feed-x4iFMBP4.js → feed-ClC8_Gld.js} +1 -1
- package/core/built/admin/assets/{field-ChCAabZg.js → field-B3OPenbP.js} +1 -1
- package/core/built/admin/assets/{filter-sources-LdtH1e-T.js → filter-sources-CiPLnG9A.js} +1 -1
- package/core/built/admin/assets/filters-Bz0HsRie.js +1 -0
- package/core/built/admin/assets/{filters-CjVKRP8U.js → filters-yFvybRMe.js} +1 -1
- package/core/built/admin/assets/first-promoter-modal-BC0UpYCD.js +1 -0
- package/core/built/admin/assets/format-url-C-t8G6Qd.js +1 -0
- package/core/built/admin/assets/{ghost-7f01131115186d1af84ead76e79646dd.js → ghost-d683fbeb945b13155ea669caa5d8db41.js} +300 -298
- package/core/built/admin/assets/{gift-link-modal-Buqh2vXh.js → gift-link-modal-BKRuqo-k.js} +1 -1
- package/core/built/admin/assets/{gift-links-CsUhefWG.js → gift-links-CVuqLhsZ.js} +1 -1
- package/core/built/admin/assets/global-data-provider-RzW6Bnlf.js +1 -0
- package/core/built/admin/assets/grid-CUciBfjf.js +1 -0
- package/core/built/admin/assets/{growth-DajOBdN0.js → growth-ClNAldfL.js} +1 -1
- package/core/built/admin/assets/{growth-Dy2UOSay.js → growth-Dz8OSG06.js} +2 -2
- package/core/built/admin/assets/history-modal-DIVuQ5Ct.js +1 -0
- package/core/built/admin/assets/{hooks-CixO01lL.js → hooks-D6EE7BIt.js} +2 -2
- package/core/built/admin/assets/html-field-CVZ2sMxw.js +1 -0
- package/core/built/admin/assets/iframe-buffering-e8vH4-Qn.js +1 -0
- package/core/built/admin/assets/images-Ok8FFJ3A.js +1 -0
- package/core/built/admin/assets/{inbox-BUOLDoji.js → inbox-CMUVI6qb.js} +13 -13
- package/core/built/admin/assets/index-DUXM0NlS.js +67 -0
- package/core/built/admin/assets/index-Ds2iUoF6.css +1 -0
- package/core/built/admin/assets/index.es-B9tvf-t4.js +1 -0
- package/core/built/admin/assets/{input-group-uSK3XT7b.js → input-group-2XU-iuh_.js} +1 -1
- package/core/built/admin/assets/integration-header-B4DyXV06.js +1 -0
- package/core/built/admin/assets/integrations-BT6_iJvu.js +1 -0
- package/core/built/admin/assets/invite-user-modal-DrZ7xxrZ.js +1 -0
- package/core/built/admin/assets/isEmail-BOfC647y.js +1 -0
- package/core/built/admin/assets/koenig-editor-base-BPj4S760.js +1 -0
- package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +9254 -9251
- package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +124 -124
- package/core/built/admin/assets/{koenig-lexical-BFc4yFed.js → koenig-lexical-Cdjv-m3_.js} +98 -98
- package/core/built/admin/assets/{kpi-card-CCt-qeWD.js → kpi-card-J8Mj1sDX.js} +1 -1
- package/core/built/admin/assets/{kpi-card-BN-E6WYX.js → kpi-card-awos0BMH.js} +1 -1
- package/core/built/admin/assets/{kpi-helpers-DlxTbTs4.js → kpi-helpers-SEhvH-8E.js} +1 -1
- package/core/built/admin/assets/{kpi-tabs-BlcUttpn.js → kpi-tabs-R6BjsKhd.js} +1 -1
- package/core/built/admin/assets/{label-AVrxwmsz.js → label-BMC3dzLI.js} +1 -1
- package/core/built/admin/assets/label-picker-Bnlru5tO.js +1 -0
- package/core/built/admin/assets/{labels-DAIqKed7.js → labels-DAPjKPy2.js} +1 -1
- package/core/built/admin/assets/layout-yR9rlvEw.js +1 -0
- package/core/built/admin/assets/limit-modal-COmLevuY.js +1 -0
- package/core/built/admin/assets/{link-helpers-D9LsDOkG.js → link-helpers-Bzkk68GD.js} +1 -1
- package/core/built/admin/assets/member-custom-fields-BvFKEpxJ.js +1 -0
- package/core/built/admin/assets/member-detail-CWdPAe3p.js +1 -0
- package/core/built/admin/assets/members-Bnt0ih2R.js +11 -0
- package/core/built/admin/assets/modal-page-BMTzFHVO.js +1 -0
- package/core/built/admin/assets/{moderation-CQ3urTFE.js → moderation-mPjYHgZW.js} +1 -1
- package/core/built/admin/assets/multi-select-combobox-CsoyHAiX.js +1 -0
- package/core/built/admin/assets/navigation-modal-D_c0badj.js +1 -0
- package/core/built/admin/assets/newsletter-DR49NyGS.js +1 -0
- package/core/built/admin/assets/newsletter-detail-modal-B45pL1pb.js +1 -0
- package/core/built/admin/assets/newsletter-emails-B-OLfrvr.js +1 -0
- package/core/built/admin/assets/{newsletters-vt3Ni1Ov.js → newsletters-DGs5BaKH.js} +1 -1
- package/core/built/admin/assets/{newsletters-BXJbJgA-.js → newsletters-Du0lzskS.js} +1 -1
- package/core/built/admin/assets/{note-Dk877BTv.js → note-CSVsUKBm.js} +1 -1
- package/core/built/admin/assets/{notifications-CPlLjPxO.js → notifications-DV9FRtDw.js} +1 -1
- package/core/built/admin/assets/{offers-DEniVRD5.js → offers-Um6ab71O.js} +1 -1
- package/core/built/admin/assets/offers-container-modal-B0hFS8nk.js +1 -0
- package/core/built/admin/assets/{onboarding-route-DdStOtjy.js → onboarding-route--jL5KLPD.js} +1 -1
- package/core/built/admin/assets/overview-B-ZPNqMo.js +1 -0
- package/core/built/admin/assets/overview-D96iwoJi.js +1 -0
- package/core/built/admin/assets/{page-header-pp4dWmOS.js → page-header-DAvDYKO9.js} +1 -1
- package/core/built/admin/assets/{pages-B4goRPUn.js → pages-BVMnpI2O.js} +1 -1
- package/core/built/admin/assets/pintura-modal-jiUCxX0Q.js +1 -0
- package/core/built/admin/assets/portal-frame-D4D4nEO6.js +1 -0
- package/core/built/admin/assets/portal-modal-BLFdYeDH.js +1 -0
- package/core/built/admin/assets/{post-analytics-BMJrI81R.js → post-analytics-BhAtiFJp.js} +1 -1
- package/core/built/admin/assets/post-analytics-header-DK27VjJm.js +1 -0
- package/core/built/admin/assets/{post-analytics-provider-Btml5vJI.js → post-analytics-provider-DGg0FUqs.js} +1 -1
- package/core/built/admin/assets/{post-share-modal-AcUZkbfL.js → post-share-modal-DtFAC132.js} +1 -1
- package/core/built/admin/assets/{posts-DhXE7b6r.js → posts-CxG7v0-M.js} +1 -1
- package/core/built/admin/assets/preferences-CuWLISHa.js +5 -0
- package/core/built/admin/assets/preview-chrome-BOVO6_PE.js +1 -0
- package/core/built/admin/assets/preview-modal-DctYx20m.js +1 -0
- package/core/built/admin/assets/profile-BsKYYtuL.js +1 -0
- package/core/built/admin/assets/radio-group-CI5_Kf_d.js +1 -0
- package/core/built/admin/assets/{referrers-pmJT4k3-.js → referrers-B9QDAfYm.js} +1 -1
- package/core/built/admin/assets/{router-provider-BmEZf6c6.js → router-provider-DSQfprxH.js} +1 -1
- package/core/built/admin/assets/select-CkXqNJDJ.js +1 -0
- package/core/built/admin/assets/settings-B4vM-rgV.js +4 -0
- package/core/built/admin/assets/{settings-BGgk7oCI.js → settings-ZCj-W56o.js} +1 -1
- package/core/built/admin/assets/settings-breadcrumbs-DIq31FwA.js +1 -0
- package/core/built/admin/assets/{share-modal-BeuydaBf.js → share-modal-BNj14g79.js} +1 -1
- package/core/built/admin/assets/slack-modal-C6SpMQ-q.js +1 -0
- package/core/built/admin/assets/social-urls-CHQ9cTAK.js +1 -0
- package/core/built/admin/assets/{sort-button-Df4t2AL8.js → sort-button-B-k54ow2.js} +1 -1
- package/core/built/admin/assets/{source-icon-ajoaKb41.js → source-icon-Cej3sZM6.js} +1 -1
- package/core/built/admin/assets/{stats-C_lfxZAw.js → stats-B2KW8E2y.js} +1 -1
- package/core/built/admin/assets/{stats-view-Cxot1iD8.js → stats-view-CVzU2-p5.js} +1 -1
- package/core/built/admin/assets/{step-1-ogAA4lDr.js → step-1-Dbn1iIMU.js} +1 -1
- package/core/built/admin/assets/{step-2-C5Xini-7.js → step-2-BahnSuN6.js} +1 -1
- package/core/built/admin/assets/{step-3-CZv1FV81.js → step-3-CW04e2ZJ.js} +2 -2
- package/core/built/admin/assets/stripe-button-BkBZqaGG.js +1 -0
- package/core/built/admin/assets/stripe-connect-modal-CYDDrSJm.js +1 -0
- package/core/built/admin/assets/switch-CE2NuMn-.js +1 -0
- package/core/built/admin/assets/{table-DFj1wiYv.js → table-BtLcEi1M.js} +1 -1
- package/core/built/admin/assets/tabs-BaWRfg8j.js +1 -0
- package/core/built/admin/assets/tag-detail-CmqiC32L.js +1 -0
- package/core/built/admin/assets/tags-BbygUvNB.js +1 -0
- package/core/built/admin/assets/tags-BwCgmr5v.js +1 -0
- package/core/built/admin/assets/testimonials-modal--bdzppyh.js +1 -0
- package/core/built/admin/assets/tier-detail-modal-BZmAsIy4.js +1 -0
- package/core/built/admin/assets/{tiers-DYsa4DCo.js → tiers-Da6kxHQP.js} +1 -1
- package/core/built/admin/assets/toggle-group-CVl-Xigr.js +1 -0
- package/core/built/admin/assets/{topic-filter-DGDxDalo.js → topic-filter-BoRHRbL1.js} +1 -1
- package/core/built/admin/assets/transistor-modal-CBPDqEGy.js +1 -0
- package/core/built/admin/assets/unsplash-modal-CixoRAO2.js +1 -0
- package/core/built/admin/assets/{use-analytics-data-C76v4LIp.js → use-analytics-data-BiWvcf1u.js} +1 -1
- package/core/built/admin/assets/use-check-theme-limit-error-B14lZukR.js +2 -0
- package/core/built/admin/assets/use-feature-flag-BmJoc5WN.js +1 -0
- package/core/built/admin/assets/use-filter-params-ChoV72Hw.js +1 -0
- package/core/built/admin/assets/use-filterable-api-iMpDZBxD.js +1 -0
- package/core/built/admin/assets/use-form-vRjI0Kwk.js +1 -0
- package/core/built/admin/assets/{use-growth-stats-aNXJOmQr.js → use-growth-stats-Dom8xVzo.js} +1 -1
- package/core/built/admin/assets/use-hash-link-navigation-guard-B9j6HIrV.js +1 -0
- package/core/built/admin/assets/use-limiter-Dwg8ivgQ.js +2 -0
- package/core/built/admin/assets/use-pintura-config-Bj4QmiVk.js +1 -0
- package/core/built/admin/assets/use-pintura-editor-DvrslmPE.js +1 -0
- package/core/built/admin/assets/{use-post-referrers-CG0SZioj.js → use-post-referrers-pxIHTXFs.js} +1 -1
- package/core/built/admin/assets/use-query-params-DHhhu8wi.js +1 -0
- package/core/built/admin/assets/{use-reply-chain-data-RLdPKRmS.js → use-reply-chain-data-CmFe0N6F.js} +1 -1
- package/core/built/admin/assets/use-setting-group-Cmp_sy-d.js +1 -0
- package/core/built/admin/assets/use-settings-navigation-BmROPrls.js +1 -0
- package/core/built/admin/assets/{use-simple-pagination-DgcF69KI.js → use-simple-pagination-D5rL3YwO.js} +1 -1
- package/core/built/admin/assets/{use-tinybird-query-C1R_Kbmy.js → use-tinybird-query-DP2dMaq7.js} +1 -1
- package/core/built/admin/assets/{use-tinybird-token-C9fPjVM_.js → use-tinybird-token-DrK_skPQ.js} +1 -1
- package/core/built/admin/assets/use-url-input-ChrUZBFf.js +5 -0
- package/core/built/admin/assets/user-detail-modal-XODpOqNC.js +1 -0
- package/core/built/admin/assets/{users-Dkv8NQZe.js → users-B6hIds6n.js} +1 -1
- package/core/built/admin/assets/validator-Cr0sMKuW.js +7 -0
- package/core/built/admin/assets/{virtual-list-BmTUzeoF.js → virtual-list-Dnoafqbk.js} +1 -1
- package/core/built/admin/assets/web-D71mjB2r.js +1 -0
- package/core/built/admin/assets/web-z71lA1Y3.js +2 -0
- package/core/built/admin/assets/zapier-modal-Bp507Um7.js +1 -0
- package/core/built/admin/index.html +16 -14
- package/core/frontend/helpers/authors.js +1 -1
- package/core/frontend/helpers/link.js +3 -8
- package/core/frontend/helpers/tags.js +1 -1
- package/core/frontend/meta/author-url.js +2 -2
- package/core/frontend/meta/url.js +4 -4
- package/core/frontend/services/proxy.js +1 -1
- package/core/frontend/services/routing/events.js +20 -6
- package/core/frontend/services/routing/permalink-adapter.js +0 -13
- package/core/frontend/services/routing/permalink-adapter.ts +0 -13
- package/core/frontend/services/routing/router-manager.js +15 -9
- package/core/frontend/services/sitemap/base-site-map-generator.js +1 -28
- package/core/frontend/services/sitemap/site-map-manager.js +22 -57
- package/core/frontend/web/middleware/admin-toolbar.js +1 -1
- package/core/frontend/web/middleware/serve-indexnow-key.js +1 -7
- package/core/server/adapters/route-settings/utils.js +10 -2
- package/core/server/adapters/route-settings/utils.ts +12 -2
- package/core/server/api/endpoints/email-post.js +1 -1
- package/core/server/api/endpoints/index.js +2 -2
- package/core/server/api/endpoints/previews.js +1 -1
- package/core/server/api/endpoints/search-index-public.js +3 -3
- package/core/server/api/endpoints/search-index.js +4 -4
- package/core/server/api/endpoints/themes.js +6 -1
- package/core/server/api/endpoints/utils/serializers/input/authors.js +2 -2
- package/core/server/api/endpoints/utils/serializers/input/comments.js +1 -1
- package/core/server/api/endpoints/utils/serializers/input/pages.js +3 -3
- package/core/server/api/endpoints/utils/serializers/input/posts.js +3 -3
- package/core/server/api/endpoints/utils/serializers/input/tags.js +1 -1
- package/core/server/api/endpoints/utils/serializers/input/users.js +2 -2
- package/core/server/api/endpoints/utils/serializers/input/utils/url.js +31 -13
- package/core/server/api/endpoints/utils/serializers/output/mappers/posts.js +2 -2
- package/core/server/api/endpoints/utils/serializers/output/mappers/tags.js +2 -2
- package/core/server/api/endpoints/utils/serializers/output/mappers/users.js +8 -0
- package/core/server/api/endpoints/utils/serializers/output/utils/url.js +18 -11
- package/core/server/data/migrations/versions/6.57/2026-08-04-18-00-00-store-custom-field-values-as-leaf-rows.js +74 -0
- package/core/server/data/migrations/versions/6.57/2026-08-04-18-54-14-reset-automation-email-analytics.js +25 -0
- package/core/server/data/schema/commands.js +21 -5
- package/core/server/data/schema/schema.js +24 -5
- package/core/server/lib/common/to-plain.ts +1 -1
- package/core/server/models/base/plugins/overrides.js +7 -5
- package/core/server/models/post.js +2 -2
- package/core/server/services/adapter-manager/adapter-manager.js +1 -45
- package/core/server/services/adapter-manager/adapter-manager.ts +2 -48
- package/core/server/services/adapter-manager/adapter-paths.js +28 -0
- package/core/server/services/adapter-manager/adapter-paths.ts +26 -0
- package/core/server/services/adapter-manager/base-classes.js +22 -0
- package/core/server/services/adapter-manager/base-classes.ts +22 -0
- package/core/server/services/adapter-manager/index.js +4 -27
- package/core/server/services/adapter-manager/index.ts +4 -31
- package/core/server/services/adapter-manager/utils.js +50 -0
- package/core/server/services/adapter-manager/utils.ts +57 -0
- package/core/server/services/audience-feedback/audience-feedback-controller.js +11 -2
- package/core/server/services/audience-feedback/audience-feedback-service.js +2 -2
- package/core/server/services/audience-feedback/feedback-repository.js +4 -1
- package/core/server/services/auth/session/session-service.js +18 -3
- package/core/server/services/automations/database-automations-repository.js +5 -5
- package/core/server/services/automations/database-automations-repository.ts +12 -12
- package/core/server/services/automations/database-date.js +52 -3
- package/core/server/services/automations/database-date.ts +23 -2
- package/core/server/services/automations/service.js +2 -2
- package/core/server/services/automations/service.ts +2 -2
- package/core/server/services/comments/comments-service-emails.js +1 -1
- package/core/server/services/comments/comments-service.js +1 -1
- package/core/server/services/email-analytics/email-analytics-service-wrapper.js +12 -3
- package/core/server/services/email-analytics/email-analytics-service.js +4 -3
- 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/lib/queries.js +91 -124
- package/core/server/services/email-analytics/lib/queries.ts +341 -0
- package/core/server/services/email-service/email-service-wrapper.js +2 -1
- package/core/server/services/email-service/mailgun-email-provider.js +15 -0
- package/core/server/services/indexnow-ping/index.js +0 -2
- package/core/server/services/indexnow-ping/index.ts +0 -2
- package/core/server/services/indexnow-ping/indexnow-ping-service.js +6 -8
- package/core/server/services/indexnow-ping/indexnow-ping-service.ts +9 -17
- package/core/server/services/lib/mailgun-client.js +3 -3
- package/core/server/services/media-inliner/external-media-inliner.js +12 -8
- package/core/server/services/member-attribution/url-translator.js +5 -7
- package/core/server/services/member-welcome-emails/service.js +72 -12
- package/core/server/services/members/api.js +1 -1
- package/core/server/services/members/import-export/import/completion-email.js +8 -4
- package/core/server/services/members/import-export/import/completion-email.ts +9 -4
- package/core/server/services/members/import-export/import/importer.js +25 -4
- package/core/server/services/members/import-export/import/importer.ts +26 -6
- package/core/server/services/members/import-export/import/row.ts +5 -1
- package/core/server/services/members/import-export/index.js +1 -5
- package/core/server/services/members/import-export/index.ts +2 -6
- package/core/server/services/members/members-api/repositories/member-repository.js +51 -0
- package/core/server/services/members-custom-fields/queries.js +4 -13
- package/core/server/services/members-custom-fields/queries.ts +4 -13
- package/core/server/services/members-custom-fields/schema.js +18 -27
- package/core/server/services/members-custom-fields/schema.ts +17 -27
- package/core/server/services/members-custom-fields/storage.js +94 -27
- package/core/server/services/members-custom-fields/storage.ts +114 -39
- package/core/server/services/members-custom-fields/values-service.js +98 -219
- package/core/server/services/members-custom-fields/values-service.ts +110 -238
- package/core/server/services/mentions/resource-service.js +1 -1
- package/core/server/services/mentions/service.js +2 -2
- package/core/server/services/route-settings/dynamic-routing-service.js +9 -59
- package/core/server/services/slack-notifications/slack-notifications.js +2 -2
- package/core/server/services/slack-ping/index.js +1 -1
- package/core/server/services/slack-ping/index.ts +1 -1
- package/core/server/services/slack-ping/slack-ping-service.js +3 -2
- package/core/server/services/slack-ping/slack-ping-service.ts +4 -5
- package/core/server/services/stats/content-stats-service.js +3 -3
- package/core/server/services/stats/members-stats-service.js +0 -7
- package/core/server/services/stats/posts-stats-service.js +2 -2
- package/core/server/services/themes/storage.js +19 -2
- package/core/server/services/url/config.js +90 -135
- package/core/server/services/url/index.js +6 -49
- package/core/server/services/url/lazy-find-resource.js +14 -11
- package/core/server/services/url/lazy-find-resource.ts +14 -11
- package/core/server/services/url/lazy-url-service.js +174 -94
- package/core/server/services/url/lazy-url-service.ts +233 -97
- package/core/server/services/url/routable-resources.js +62 -71
- package/core/server/services/url/router-filter.js +12 -4
- package/core/server/services/url/router-filter.ts +12 -4
- package/core/server/services/webhooks/index.js +1 -1
- package/core/server/services/webhooks/serialize.js +12 -2
- package/core/server/web/api/endpoints/admin/routes.js +2 -2
- package/core/shared/config/env/config.testing-mysql.json +1 -2
- package/core/shared/config/env/config.testing.json +1 -2
- package/core/shared/custom-theme-settings-cache/custom-theme-settings-bread-service.js +4 -0
- package/core/shared/custom-theme-settings-cache/custom-theme-settings-service.js +39 -0
- package/core/shared/events/index.js +1 -2
- package/core/shared/labs.js +4 -4
- package/package.json +10 -11
- package/pnpm-lock.yaml +44 -47
- package/pnpm-workspace.yaml +19 -19
- package/tsconfig.json +1 -0
- package/components/tryghost-adapter-base-scheduling-0.2.0.tgz +0 -0
- package/components/tryghost-kg-converters-1.2.3.tgz +0 -0
- package/components/tryghost-kg-default-cards-10.3.3.tgz +0 -0
- package/components/tryghost-kg-default-nodes-2.1.4.tgz +0 -0
- package/core/built/admin/assets/Combination-BCm9FL4o.js +0 -41
- package/core/built/admin/assets/activitypub/layout-CTgrezN7.js +0 -1
- package/core/built/admin/assets/automated-emails-6t2bIRWf.js +0 -7
- package/core/built/admin/assets/checkbox-BIl077a0.js +0 -1
- package/core/built/admin/assets/chunk.524.87b52f4fada529df2c4c.js +0 -25
- package/core/built/admin/assets/chunk.582.340bcca873e806cbd4bb.js +0 -27
- package/core/built/admin/assets/code-editor-view-C0aWNwdl.js +0 -1
- package/core/built/admin/assets/comments-qwhIjH3c.js +0 -1
- package/core/built/admin/assets/disabled-sources-indicator-DYAXW-6V.js +0 -1
- package/core/built/admin/assets/dist-BUKmD51u.js +0 -1
- package/core/built/admin/assets/dist-CNlMj7ML.js +0 -1
- package/core/built/admin/assets/dist-DDY6GRVz.js +0 -1
- package/core/built/admin/assets/dist-DG78yroX.js +0 -23
- package/core/built/admin/assets/editor-DDYSOXGN.js +0 -8
- package/core/built/admin/assets/esm-CFX93H5M.js +0 -2
- package/core/built/admin/assets/filters-CLehPo_D.js +0 -1
- package/core/built/admin/assets/index-08n05-rc.js +0 -67
- package/core/built/admin/assets/index-DgUzgFvS.css +0 -1
- package/core/built/admin/assets/label-picker-DVnpu_IF.js +0 -1
- package/core/built/admin/assets/layout-B0YLh7R9.js +0 -1
- package/core/built/admin/assets/member-custom-fields-C8NpZYza.js +0 -1
- package/core/built/admin/assets/member-detail-CIVAdKXf.js +0 -1
- package/core/built/admin/assets/members-oLPiSkXD.js +0 -10
- package/core/built/admin/assets/modals-CB7v-k3T.js +0 -31
- package/core/built/admin/assets/newsletter-rbeDX9Wk.js +0 -1
- package/core/built/admin/assets/overview--4V-kx9c.js +0 -1
- package/core/built/admin/assets/overview-DSLv30oz.js +0 -1
- package/core/built/admin/assets/post-analytics-header-pU2m9ZuV.js +0 -1
- package/core/built/admin/assets/preferences-Ru4CRPHC.js +0 -5
- package/core/built/admin/assets/profile-BNb1oj7D.js +0 -1
- package/core/built/admin/assets/select-B0HteHrp.js +0 -1
- package/core/built/admin/assets/settings-B1C9Q3wo.js +0 -4
- package/core/built/admin/assets/social-urls-DA2lXrhW.js +0 -8
- package/core/built/admin/assets/switch-CyQcwMAv.js +0 -1
- package/core/built/admin/assets/tabs-D4y1gqUd.js +0 -1
- package/core/built/admin/assets/tags-Dmft-Y4O.js +0 -1
- package/core/built/admin/assets/toggle-group-R2QMFvXW.js +0 -1
- package/core/built/admin/assets/use-filter-params-WrdhAISv.js +0 -1
- package/core/built/admin/assets/web-BqW0b0_C.js +0 -1
- package/core/built/admin/assets/web-Cy5GKMWM.js +0 -2
- package/core/server/services/email-analytics/jobs/update-member-email-analytics/index.js +0 -14
- package/core/server/services/url/local-file-cache.js +0 -75
- package/core/server/services/url/queue.js +0 -260
- package/core/server/services/url/resource.js +0 -102
- package/core/server/services/url/resources.js +0 -480
- package/core/server/services/url/url-generator.js +0 -276
- package/core/server/services/url/url-service-facade.js +0 -366
- package/core/server/services/url/url-service-facade.ts +0 -519
- package/core/server/services/url/url-service.js +0 -387
- package/core/server/services/url/urls.js +0 -140
- package/core/shared/events/url-resource-updated-event.js +0 -33
- /package/core/built/admin/assets/{chunk.211.6f7328d63c41536451b3.js.LICENSE.txt → chunk.571.40f093ed6d883993714e.js.LICENSE.txt} +0 -0
- /package/core/built/admin/assets/{dist-CqO2lWS0.js → dist-CqO2lWS02.js} +0 -0
- /package/core/server/api/endpoints/{gift-reminders.js → gifts.js} +0 -0
|
@@ -1,105 +1,94 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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.queries = void 0;
|
|
7
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
8
|
+
const debug_1 = __importDefault(require("@tryghost/debug"));
|
|
9
|
+
// @ts-expect-error This module lacks type definitions.
|
|
10
|
+
const db_1 = __importDefault(require("../../../data/db"));
|
|
11
|
+
const logging_1 = __importDefault(require("@tryghost/logging"));
|
|
12
|
+
const bson_objectid_1 = __importDefault(require("bson-objectid"));
|
|
13
|
+
const debug = (0, debug_1.default)('services:email-analytics');
|
|
7
14
|
const MIN_EMAIL_COUNT_FOR_OPEN_RATE = 5;
|
|
8
|
-
|
|
9
|
-
/** @typedef {string} EmailAnalyticsJobName */
|
|
10
|
-
/** @typedef {'delivered'|'opened'|'failed'} EmailAnalyticsEvent */
|
|
11
|
-
/**
|
|
12
|
-
* @typedef {object} CursorSeed
|
|
13
|
-
* @prop {string} tableName
|
|
14
|
-
* @prop {Partial<Record<EmailAnalyticsEvent, string>>} eventColumns
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
15
|
/**
|
|
18
16
|
* Creates a job in the jobs table if it does not already exist.
|
|
19
|
-
* @param
|
|
20
|
-
* @returns {Promise<void>}
|
|
17
|
+
* @param jobName - The name of the job to create.
|
|
21
18
|
*/
|
|
22
19
|
async function createJobIfNotExists(jobName) {
|
|
23
|
-
await
|
|
24
|
-
id: new
|
|
20
|
+
await db_1.default.knex('jobs').insert({
|
|
21
|
+
id: new bson_objectid_1.default().toHexString(),
|
|
25
22
|
name: jobName,
|
|
26
23
|
started_at: new Date(),
|
|
27
24
|
created_at: new Date(),
|
|
28
25
|
status: 'started'
|
|
29
26
|
}).onConflict('name').ignore();
|
|
30
27
|
}
|
|
31
|
-
|
|
32
|
-
module.exports = {
|
|
28
|
+
exports.queries = {
|
|
33
29
|
/**
|
|
34
30
|
* Retrieves the timestamp of the last seen event for the specified email analytics events.
|
|
35
|
-
* @param
|
|
36
|
-
* @param
|
|
37
|
-
* @param
|
|
38
|
-
* @returns
|
|
31
|
+
* @param jobName - The name of the job to update.
|
|
32
|
+
* @param events - The email analytics events to consider.
|
|
33
|
+
* @param cursorSeed - Recipient table and timestamp columns to read the initial cursor from. Used when the job has no stored timestamp yet.
|
|
34
|
+
* @returns The timestamp of the last seen event, or null if no events are found.
|
|
39
35
|
*/
|
|
40
36
|
async getLastEventTimestamp(jobName, events, cursorSeed) {
|
|
41
37
|
const startDate = new Date();
|
|
42
|
-
|
|
43
38
|
let timestamps = [];
|
|
44
39
|
const lastJobRunTimestamp = await this.getLastJobRunTimestamp(jobName);
|
|
45
|
-
|
|
46
40
|
if (lastJobRunTimestamp) {
|
|
47
41
|
debug(`Using job data for ${jobName}`);
|
|
48
42
|
timestamps = [lastJobRunTimestamp];
|
|
49
|
-
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
50
45
|
debug(`Job data not found for ${jobName}, using ${cursorSeed.tableName} data`);
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
logging_1.default.info(`Job data not found for ${jobName}, using ${cursorSeed.tableName} data`);
|
|
53
47
|
for (const event of events) {
|
|
54
48
|
const columnName = cursorSeed.eventColumns[event];
|
|
55
49
|
if (!columnName) {
|
|
56
50
|
continue;
|
|
57
51
|
}
|
|
58
|
-
const row = await
|
|
59
|
-
.select(
|
|
52
|
+
const row = await db_1.default.knex(cursorSeed.tableName)
|
|
53
|
+
.select(db_1.default.knex.raw('MAX(??) as maxTimestamp', [columnName]))
|
|
60
54
|
.first();
|
|
61
55
|
timestamps.push(row.maxTimestamp);
|
|
62
56
|
}
|
|
63
|
-
|
|
64
57
|
await createJobIfNotExists(jobName);
|
|
65
58
|
}
|
|
66
|
-
|
|
67
59
|
// Convert string dates to Date objects for SQLite compatibility
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
60
|
+
const normalizedTimestamps = timestamps.map(date => {
|
|
61
|
+
if (!date) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return date instanceof Date ? date : new Date(date);
|
|
65
|
+
});
|
|
66
|
+
const lastSeenEventTimestamp = lodash_1.default.max(normalizedTimestamps) ?? null;
|
|
67
|
+
debug(`getLastEventTimestamp: finished in ${Date.now() - startDate.getTime()}ms`);
|
|
75
68
|
return lastSeenEventTimestamp;
|
|
76
69
|
},
|
|
77
|
-
|
|
78
70
|
/**
|
|
79
71
|
* Retrieves the job data for the specified job name.
|
|
80
|
-
* @param
|
|
81
|
-
* @returns
|
|
72
|
+
* @param jobName - The name of the job to retrieve data for.
|
|
73
|
+
* @returns The job data, or null if no job data is found.
|
|
82
74
|
*/
|
|
83
75
|
async getJobData(jobName) {
|
|
84
|
-
return await
|
|
76
|
+
return await db_1.default.knex('jobs').select('finished_at', 'started_at', 'metadata').where('name', jobName).first();
|
|
85
77
|
},
|
|
86
|
-
|
|
87
78
|
/**
|
|
88
79
|
* Retrieves the timestamp of the last job run for the specified job name.
|
|
89
|
-
* @param
|
|
90
|
-
* @returns
|
|
80
|
+
* @param jobName - The name of the job to retrieve the last run timestamp for.
|
|
81
|
+
* @returns The timestamp of the last job run, or null if no job data is found.
|
|
91
82
|
*/
|
|
92
83
|
async getLastJobRunTimestamp(jobName) {
|
|
93
84
|
const jobData = await this.getJobData(jobName);
|
|
94
85
|
return jobData ? jobData.finished_at || jobData.started_at : null;
|
|
95
86
|
},
|
|
96
|
-
|
|
97
87
|
/**
|
|
98
88
|
* Sets the timestamp of the last seen event for the specified email analytics events.
|
|
99
|
-
* @param
|
|
100
|
-
* @param
|
|
101
|
-
* @param
|
|
102
|
-
* @returns {Promise<void>}
|
|
89
|
+
* @param jobName - The name of the job to update.
|
|
90
|
+
* @param field - The field to update.
|
|
91
|
+
* @param date - The timestamp of the last seen event.
|
|
103
92
|
* @description
|
|
104
93
|
* Updates the `finished_at` or `started_at` column of the specified job in the `jobs` table with the provided timestamp.
|
|
105
94
|
* This is used to keep track of the last time the job was run to avoid expensive queries following reboot.
|
|
@@ -110,52 +99,53 @@ module.exports = {
|
|
|
110
99
|
debug(`Setting ${field} timestamp for job ${jobName} to ${date}`);
|
|
111
100
|
const updateField = field === 'finished' ? 'finished_at' : 'started_at';
|
|
112
101
|
const status = field === 'finished' ? 'finished' : 'started';
|
|
113
|
-
const result = await
|
|
102
|
+
const result = await db_1.default.knex('jobs').update({ [updateField]: date, updated_at: new Date(), status: status }).where('name', jobName);
|
|
114
103
|
if (result === 0) {
|
|
115
|
-
await
|
|
116
|
-
id: new
|
|
104
|
+
await db_1.default.knex('jobs').insert({
|
|
105
|
+
id: new bson_objectid_1.default().toHexString(),
|
|
117
106
|
name: jobName,
|
|
118
107
|
[updateField]: date.toISOString(), // force to iso string for sqlite
|
|
119
108
|
updated_at: date.toISOString(), // force to iso string for sqlite
|
|
120
109
|
status: status
|
|
121
110
|
});
|
|
122
111
|
}
|
|
123
|
-
}
|
|
124
|
-
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
115
|
+
debug(`Error setting ${field} timestamp for job ${jobName}: ${message}`);
|
|
125
116
|
}
|
|
126
117
|
},
|
|
127
|
-
|
|
128
118
|
/**
|
|
129
119
|
* Retrieves and parses the metadata JSON for the specified job.
|
|
130
|
-
* @param
|
|
131
|
-
* @returns
|
|
120
|
+
* @param jobName - The name of the job.
|
|
121
|
+
* @returns The parsed metadata object, or null.
|
|
132
122
|
*/
|
|
133
123
|
async getJobMetadata(jobName) {
|
|
134
124
|
try {
|
|
135
|
-
const row = await
|
|
125
|
+
const row = await db_1.default.knex('jobs').select('metadata').where('name', jobName).first();
|
|
136
126
|
if (row && row.metadata) {
|
|
137
127
|
return JSON.parse(row.metadata);
|
|
138
128
|
}
|
|
139
|
-
}
|
|
140
|
-
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
132
|
+
logging_1.default.error(`Error reading metadata for job ${jobName}: ${message}`);
|
|
141
133
|
}
|
|
142
134
|
return null;
|
|
143
135
|
},
|
|
144
|
-
|
|
145
136
|
/**
|
|
146
137
|
* Writes metadata JSON for the specified job.
|
|
147
|
-
* @param
|
|
148
|
-
* @param
|
|
149
|
-
* @returns {Promise<void>}
|
|
138
|
+
* @param jobName - The name of the job.
|
|
139
|
+
* @param metadata - The metadata to store, or null to clear.
|
|
150
140
|
*/
|
|
151
141
|
async setJobMetadata(jobName, metadata) {
|
|
152
142
|
try {
|
|
153
143
|
const value = metadata ? JSON.stringify(metadata) : null;
|
|
154
|
-
await
|
|
155
|
-
const result = await trx('jobs').update({metadata: value, updated_at: new Date()}).where('name', jobName);
|
|
144
|
+
await db_1.default.knex.transaction(async (trx) => {
|
|
145
|
+
const result = await trx('jobs').update({ metadata: value, updated_at: new Date() }).where('name', jobName);
|
|
156
146
|
if (result === 0 && metadata) {
|
|
157
147
|
await trx('jobs').insert({
|
|
158
|
-
id: new
|
|
148
|
+
id: new bson_objectid_1.default().toHexString(),
|
|
159
149
|
name: jobName,
|
|
160
150
|
metadata: value,
|
|
161
151
|
created_at: new Date(),
|
|
@@ -163,16 +153,16 @@ module.exports = {
|
|
|
163
153
|
});
|
|
164
154
|
}
|
|
165
155
|
});
|
|
166
|
-
}
|
|
167
|
-
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
159
|
+
logging_1.default.error(`Error setting metadata for job ${jobName}: ${message}`);
|
|
168
160
|
}
|
|
169
161
|
},
|
|
170
|
-
|
|
171
162
|
/**
|
|
172
163
|
* Sets the status of the specified email analytics job.
|
|
173
|
-
* @param
|
|
174
|
-
* @param
|
|
175
|
-
* @returns {Promise<void>}
|
|
164
|
+
* @param jobName - The name of the job to update.
|
|
165
|
+
* @param status - The new status of the job.
|
|
176
166
|
* @description
|
|
177
167
|
* Updates the `status` column of the specified job in the `jobs` table with the provided status.
|
|
178
168
|
* This is used to keep track of the current state of the job.
|
|
@@ -180,101 +170,83 @@ module.exports = {
|
|
|
180
170
|
async setJobStatus(jobName, status) {
|
|
181
171
|
debug(`Setting status for job ${jobName} to ${status}`);
|
|
182
172
|
try {
|
|
183
|
-
const result = await
|
|
173
|
+
const result = await db_1.default.knex('jobs')
|
|
184
174
|
.update({
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
175
|
+
status: status,
|
|
176
|
+
updated_at: new Date()
|
|
177
|
+
})
|
|
188
178
|
.where('name', jobName);
|
|
189
|
-
|
|
190
179
|
if (result === 0) {
|
|
191
|
-
await
|
|
192
|
-
id: new
|
|
180
|
+
await db_1.default.knex('jobs').insert({
|
|
181
|
+
id: new bson_objectid_1.default().toHexString(),
|
|
193
182
|
name: jobName,
|
|
194
183
|
status: status,
|
|
195
184
|
created_at: new Date(),
|
|
196
185
|
updated_at: new Date()
|
|
197
186
|
});
|
|
198
187
|
}
|
|
199
|
-
}
|
|
200
|
-
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
191
|
+
debug(`Error setting status for job ${jobName}: ${message}`);
|
|
201
192
|
throw err;
|
|
202
193
|
}
|
|
203
194
|
},
|
|
204
|
-
|
|
205
195
|
async aggregateEmailStats(emailId, updateOpenedCount) {
|
|
206
|
-
const [deliveredCount] = await
|
|
207
|
-
const [failedCount] = await
|
|
208
|
-
|
|
196
|
+
const [deliveredCount] = await db_1.default.knex('email_recipients').count('id as count').whereRaw('email_id = ? AND delivered_at IS NOT NULL', [emailId]);
|
|
197
|
+
const [failedCount] = await db_1.default.knex('email_recipients').count('id as count').whereRaw('email_id = ? AND failed_at IS NOT NULL', [emailId]);
|
|
209
198
|
const updateData = {
|
|
210
199
|
delivered_count: deliveredCount.count,
|
|
211
200
|
failed_count: failedCount.count
|
|
212
201
|
};
|
|
213
|
-
|
|
214
202
|
if (updateOpenedCount) {
|
|
215
|
-
const [openedCount] = await
|
|
203
|
+
const [openedCount] = await db_1.default.knex('email_recipients').count('id as count').whereRaw('email_id = ? AND opened_at IS NOT NULL', [emailId]);
|
|
216
204
|
updateData.opened_count = openedCount.count;
|
|
217
205
|
}
|
|
218
|
-
|
|
219
|
-
await db.knex('emails').update(updateData).where('id', emailId);
|
|
206
|
+
await db_1.default.knex('emails').update(updateData).where('id', emailId);
|
|
220
207
|
},
|
|
221
|
-
|
|
222
208
|
async aggregateMemberStats(memberId) {
|
|
223
|
-
const {trackedEmailCount} = await
|
|
224
|
-
.select(
|
|
209
|
+
const { trackedEmailCount } = await db_1.default.knex('email_recipients')
|
|
210
|
+
.select(db_1.default.knex.raw('COUNT(email_recipients.id) as trackedEmailCount'))
|
|
225
211
|
.leftJoin('emails', 'email_recipients.email_id', 'emails.id')
|
|
226
212
|
.where('email_recipients.member_id', memberId)
|
|
227
213
|
.where('emails.track_opens', true)
|
|
228
214
|
.first() || {};
|
|
229
|
-
|
|
230
|
-
const [
|
|
231
|
-
const [emailOpenedCount] = await db.knex('email_recipients').count('id as count').whereRaw('member_id = ? AND opened_at IS NOT NULL', [memberId]);
|
|
232
|
-
|
|
215
|
+
const [emailCount] = await db_1.default.knex('email_recipients').count('id as count').whereRaw('member_id = ?', [memberId]);
|
|
216
|
+
const [emailOpenedCount] = await db_1.default.knex('email_recipients').count('id as count').whereRaw('member_id = ? AND opened_at IS NOT NULL', [memberId]);
|
|
233
217
|
const updateQuery = {
|
|
234
218
|
email_count: emailCount.count,
|
|
235
219
|
email_opened_count: emailOpenedCount.count
|
|
236
220
|
};
|
|
237
|
-
|
|
238
221
|
if (trackedEmailCount >= MIN_EMAIL_COUNT_FOR_OPEN_RATE) {
|
|
239
222
|
updateQuery.email_open_rate = Math.round(emailOpenedCount.count / trackedEmailCount * 100);
|
|
240
223
|
}
|
|
241
|
-
|
|
242
|
-
await db.knex('members')
|
|
224
|
+
await db_1.default.knex('members')
|
|
243
225
|
.update(updateQuery)
|
|
244
226
|
.where('id', memberId);
|
|
245
227
|
},
|
|
246
|
-
|
|
247
228
|
async aggregateMemberStatsBatch(memberIds) {
|
|
248
229
|
if (!memberIds || memberIds.length === 0) {
|
|
249
230
|
return;
|
|
250
231
|
}
|
|
251
|
-
|
|
252
232
|
// Batch query to get stats for all members at once
|
|
253
|
-
const stats = await
|
|
233
|
+
const stats = await db_1.default.knex('email_recipients')
|
|
254
234
|
.leftJoin('emails', 'emails.id', 'email_recipients.email_id')
|
|
255
|
-
.select(
|
|
256
|
-
'email_recipients.member_id',
|
|
257
|
-
db.knex.raw('COUNT(email_recipients.id) as email_count'),
|
|
258
|
-
db.knex.raw('SUM(CASE WHEN email_recipients.opened_at IS NOT NULL THEN 1 ELSE 0 END) as email_opened_count'),
|
|
259
|
-
db.knex.raw('SUM(CASE WHEN emails.track_opens = 1 THEN 1 ELSE 0 END) as tracked_count')
|
|
260
|
-
)
|
|
235
|
+
.select('email_recipients.member_id', db_1.default.knex.raw('COUNT(email_recipients.id) as email_count'), db_1.default.knex.raw('SUM(CASE WHEN email_recipients.opened_at IS NOT NULL THEN 1 ELSE 0 END) as email_opened_count'), db_1.default.knex.raw('SUM(CASE WHEN emails.track_opens = 1 THEN 1 ELSE 0 END) as tracked_count'))
|
|
261
236
|
.whereIn('email_recipients.member_id', memberIds)
|
|
262
237
|
.groupBy('email_recipients.member_id');
|
|
263
|
-
|
|
264
238
|
// Build update data for each member
|
|
265
239
|
const memberStatsMap = new Map();
|
|
266
240
|
for (const stat of stats) {
|
|
267
241
|
const emailOpenRate = stat.tracked_count >= MIN_EMAIL_COUNT_FOR_OPEN_RATE
|
|
268
242
|
? Math.round((stat.email_opened_count / stat.tracked_count) * 100)
|
|
269
243
|
: null;
|
|
270
|
-
|
|
271
244
|
memberStatsMap.set(stat.member_id, {
|
|
272
245
|
email_count: stat.email_count,
|
|
273
246
|
email_opened_count: stat.email_opened_count,
|
|
274
247
|
email_open_rate: emailOpenRate
|
|
275
248
|
});
|
|
276
249
|
}
|
|
277
|
-
|
|
278
250
|
// Build CASE statements for batch update
|
|
279
251
|
const emailCountCases = [];
|
|
280
252
|
const emailOpenedCountCases = [];
|
|
@@ -282,29 +254,25 @@ module.exports = {
|
|
|
282
254
|
const emailCountBindings = [];
|
|
283
255
|
const emailOpenedCountBindings = [];
|
|
284
256
|
const emailOpenRateBindings = [];
|
|
285
|
-
|
|
286
257
|
for (const memberId of memberIds) {
|
|
287
258
|
const memberStats = memberStatsMap.get(memberId) || {
|
|
288
259
|
email_count: 0,
|
|
289
260
|
email_opened_count: 0,
|
|
290
261
|
email_open_rate: null
|
|
291
262
|
};
|
|
292
|
-
|
|
293
263
|
emailCountCases.push(`WHEN ? THEN ?`);
|
|
294
264
|
emailCountBindings.push(memberId, memberStats.email_count);
|
|
295
|
-
|
|
296
265
|
emailOpenedCountCases.push(`WHEN ? THEN ?`);
|
|
297
266
|
emailOpenedCountBindings.push(memberId, memberStats.email_opened_count);
|
|
298
|
-
|
|
299
267
|
if (memberStats.email_open_rate !== null) {
|
|
300
268
|
emailOpenRateCases.push(`WHEN ? THEN ?`);
|
|
301
269
|
emailOpenRateBindings.push(memberId, memberStats.email_open_rate);
|
|
302
|
-
}
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
303
272
|
emailOpenRateCases.push(`WHEN ? THEN NULL`);
|
|
304
273
|
emailOpenRateBindings.push(memberId);
|
|
305
274
|
}
|
|
306
275
|
}
|
|
307
|
-
|
|
308
276
|
// Combine bindings in the order they appear in the SQL statement:
|
|
309
277
|
// 1. All bindings for email_count CASE statement
|
|
310
278
|
// 2. All bindings for email_opened_count CASE statement
|
|
@@ -316,9 +284,8 @@ module.exports = {
|
|
|
316
284
|
...emailOpenRateBindings,
|
|
317
285
|
...memberIds
|
|
318
286
|
];
|
|
319
|
-
|
|
320
287
|
// Execute batched update with CASE statements
|
|
321
|
-
await
|
|
288
|
+
await db_1.default.knex.raw(`
|
|
322
289
|
UPDATE members
|
|
323
290
|
SET
|
|
324
291
|
email_count = CASE id ${emailCountCases.join(' ')} END,
|