ghost 6.53.0 → 6.54.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/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.2.0.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-BTP1LthE.js +3 -0
- package/core/built/admin/assets/Newsletters-CSEX0myc.js +1 -0
- package/core/built/admin/assets/Overview-BjACEsJF.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-CxxxjCcv.js +2 -0
- package/core/built/admin/assets/account-migration-BklF2I_I.js +1 -0
- package/core/built/admin/assets/activitypub/{account-migration-BPZG37DJ.js → account-migration-CNovr6W-.js} +13 -13
- package/core/built/admin/assets/activitypub/activitypub.js +8 -8
- 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-Ceslb1_M.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-BqkDUQxJ2.js → dist-ByFmDSNP2.js} +64 -63
- package/core/built/admin/assets/activitypub/{dist-B5ira32t.js → dist-DHAjBcV3.js} +5 -5
- package/core/built/admin/assets/activitypub/{domain-iqE4YXwD.js → domain-C1qQvJ8C.js} +33 -33
- package/core/built/admin/assets/activitypub/{edit-profile-B8MFYh28.js → edit-profile-BcH-jEfM.js} +46 -45
- package/core/built/admin/assets/activitypub/{explore-BbdKodp3.js → explore-AxwBh9dI.js} +20 -20
- package/core/built/admin/assets/activitypub/{feed-Cl3A5owG.js → feed-BaOlbh7a.js} +15 -15
- package/core/built/admin/assets/activitypub/{field-DL6WyR-c.js → field-B7mYYQpN.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-vXez-5uJ.js +1221 -0
- package/core/built/admin/assets/activitypub/{label-DGbLjDvE.js → label-Chv5T8bw.js} +6 -6
- package/core/built/admin/assets/activitypub/layout-CziktJXo.js +1 -0
- package/core/built/admin/assets/activitypub/{moderation-qnBtk1zS.js → moderation-DtSM2i1I.js} +32 -31
- package/core/built/admin/assets/activitypub/{note-C7ZRoSJv.js → note-Dckp4S-2.js} +21 -21
- package/core/built/admin/assets/activitypub/{notifications-DiEA4b1o.js → notifications-CG5T22vg.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-D_799jdl.js} +1607 -1606
- package/core/built/admin/assets/activitypub/{profile-D8ZJfYXB.js → profile-D2JfXBQl.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-CCHe2dQp.js} +1317 -1298
- package/core/built/admin/assets/activitypub/{separator-1gNokN5S.js → separator-BI1FLsYM.js} +4 -4
- package/core/built/admin/assets/activitypub/{settings--9Sb0nbl.js → settings-kx-9Enkz.js} +14 -14
- package/core/built/admin/assets/activitypub/{site-fkMmqv0V.js → site-x4_IjVJ0.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-CyPRQQ1N.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-BAB6fNGt.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-X_XsZivI.js} +1 -1
- package/core/built/admin/assets/{automated-emails-UWM02CMr.js → automated-emails-of1MvVsv.js} +1 -1
- package/core/built/admin/assets/automations-B7-y3dXt.js +1 -0
- package/core/built/admin/assets/automations-DRFjW5fw.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-BbbjWdzs.js +1 -0
- package/core/built/admin/assets/box-BWbhXh21.js +1 -0
- package/core/built/admin/assets/breadcrumb-B-M9Ip_2.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-xiSsW8r0.js +1 -0
- package/core/built/admin/assets/checkbox-EhJKHFdZ.js +1 -0
- package/core/built/admin/assets/{chunk.432.c2caa0b20f03e71d1a35.js → chunk.211.6f7328d63c41536451b3.js} +2025 -2819
- package/core/built/admin/assets/{chunk.432.c2caa0b20f03e71d1a35.js.LICENSE.txt → chunk.211.6f7328d63c41536451b3.js.LICENSE.txt} +1 -62
- package/core/built/admin/assets/{chunk.831.0703a12e49f51cec3f3a.js → chunk.361.3cdb584b973959e52ccc.js} +78 -85
- package/core/built/admin/assets/chunk.524.8365cd9280405c0f6216.js +25 -0
- package/core/built/admin/assets/chunk.582.61d078937e6102769f2c.js +27 -0
- package/core/built/admin/assets/code-editor-view-CZtJFGhR.js +1 -0
- package/core/built/admin/assets/comments-CvyXxOyN.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-CTlyo8zW.js +1 -0
- package/core/built/admin/assets/disabled-sources-indicator-qs2GfLvl.js +1 -0
- package/core/built/admin/assets/{dist-DJ6c4_De.js → dist-2Tnz2Yfq.js} +1 -1
- package/core/built/admin/assets/{dist-CsekE4FL.js → dist-CQJY6SVY.js} +1 -1
- package/core/built/admin/assets/dist-CjY-f5Z1.js +1 -0
- package/core/built/admin/assets/dist-DGzPJ_bO.js +4 -0
- package/core/built/admin/assets/dist-DIC8yz5C.js +1 -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-CPNXKVOV.js +1 -0
- package/core/built/admin/assets/dropzone-BmCXnw6J.js +5 -0
- package/core/built/admin/assets/edit-profile-SGrJve5M.js +1 -0
- package/core/built/admin/assets/editor-BOG2YPUm.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-CUYLv9G9.js +1 -0
- package/core/built/admin/assets/feed-CPdJMttL.js +1 -0
- package/core/built/admin/assets/field-D0XISCK2.js +1 -0
- package/core/built/admin/assets/{filter-sources-v39ihhhV.js → filter-sources-Bieps75g.js} +1 -1
- package/core/built/admin/assets/filters-CuB-A7ma.js +1 -0
- package/core/built/admin/assets/filters-bXkkWro8.js +1 -0
- package/core/built/admin/assets/framework-provider-CmtnPXIT.js +4 -0
- package/core/built/admin/assets/{ghost-b57f077997b739a8ae9a70772dc016cb.js → ghost-05f9a7182ed56903dba05878a5b8422b.js} +46 -41
- package/core/built/admin/assets/ghost-dark-c8d0ab7f515b2010c173e23e9b32ea8a.css +1 -0
- package/core/built/admin/assets/gift-link-modal-su8MsRdg.js +1 -0
- package/core/built/admin/assets/{gift-links-CY3GwiVi.js → gift-links-nBxJjZiQ.js} +1 -1
- package/core/built/admin/assets/growth-Ba6S5FQX.js +1 -0
- package/core/built/admin/assets/hooks-BApwwBE0.js +2 -0
- package/core/built/admin/assets/{inbox-TEISAmth.js → inbox-Xx1CdnfO.js} +38 -38
- package/core/built/admin/assets/index-D8PbzuT9.css +1 -0
- package/core/built/admin/assets/index-ukW_0Uie.js +67 -0
- package/core/built/admin/assets/inline-EMAm3okk.js +1 -0
- package/core/built/admin/assets/input-group-CGOXcy4l.js +1 -0
- package/core/built/admin/assets/input-surface-BpAjZXY5.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-B61IALf5.js} +2 -2
- package/core/built/admin/assets/kpi-card-BlZaG1Lo.js +1 -0
- package/core/built/admin/assets/kpi-card-DCdlyaSS.js +1 -0
- package/core/built/admin/assets/kpi-helpers-DpAuS1Nb.js +1 -0
- package/core/built/admin/assets/kpi-tabs-Dme44bQS.js +1 -0
- package/core/built/admin/assets/label-dSs5aepE.js +1 -0
- package/core/built/admin/assets/label-picker-Uq91atex.js +1 -0
- package/core/built/admin/assets/{labels-GbxlXWtf.js → labels-Cyayfd-e.js} +1 -1
- package/core/built/admin/assets/layout-WUcz6tu1.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-NCzrMuba.js +1 -0
- package/core/built/admin/assets/member-detail-DPWDtYnN.js +1 -0
- package/core/built/admin/assets/members-B9rO7qr4.js +10 -0
- package/core/built/admin/assets/modals-CxRaan1J.js +31 -0
- package/core/built/admin/assets/moderation-D8zon60E.js +1 -0
- package/core/built/admin/assets/multi-select-combobox-1wYm3nle.js +1 -0
- package/core/built/admin/assets/newsletter-DbYMRxRS.js +1 -0
- package/core/built/admin/assets/{newsletters-DZm3yLj8.js → newsletters-D1jbtV-h.js} +1 -1
- package/core/built/admin/assets/note-PiWPnnrh.js +1 -0
- package/core/built/admin/assets/notifications-DEgqqB9G.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-BzF6HeVn.js +1 -0
- package/core/built/admin/assets/overview-DixLeIqY.js +1 -0
- package/core/built/admin/assets/page-header-op0eN36I.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-WwRDEnrV.js +1 -0
- package/core/built/admin/assets/post-analytics-header-DsMoLx0R.js +1 -0
- package/core/built/admin/assets/{post-analytics-provider-DSfBCtnj.js → post-analytics-provider-BJCPLMIb.js} +1 -1
- package/core/built/admin/assets/post-share-modal-Dx-MEjhI.js +1 -0
- package/core/built/admin/assets/{posts-CwH8VJvB.js → posts-EWpZIjkr.js} +1 -1
- package/core/built/admin/assets/preferences-D7-j6A4C.js +5 -0
- package/core/built/admin/assets/profile-Dl69QPp0.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-C1qDZnW4.js +1 -0
- package/core/built/admin/assets/settings-BbmC_Iqq.js +4 -0
- package/core/built/admin/assets/settings-H6HxFgfI.js +1 -0
- package/core/built/admin/assets/shade-app-B3heOAfz-CGXQwWeO.js +3 -0
- package/core/built/admin/assets/share-modal-BJCadJyp.js +1 -0
- package/core/built/admin/assets/social-urls-BPL1nADp.js +8 -0
- package/core/built/admin/assets/sort-button-DyYlfYp7.js +1 -0
- package/core/built/admin/assets/source-icon-_ubRDbg_.js +1 -0
- package/core/built/admin/assets/stack-xiN0eQ6Z.js +1 -0
- package/core/built/admin/assets/stats-BQZMGMvn.js +1 -0
- package/core/built/admin/assets/stats-view-Doei-qCX.js +1 -0
- package/core/built/admin/assets/step-1-IKiLBPoC.js +1 -0
- package/core/built/admin/assets/step-2-jJ41PsDN.js +1 -0
- package/core/built/admin/assets/step-3-CaqFAEqf.js +2 -0
- package/core/built/admin/assets/switch-t-WyENU2.js +1 -0
- package/core/built/admin/assets/table-DxUL78jU.js +1 -0
- package/core/built/admin/assets/tabs-BQcJQ1ke.js +1 -0
- package/core/built/admin/assets/tags-CNujGwkT.js +1 -0
- package/core/built/admin/assets/text-DwtjwGkh.js +1 -0
- package/core/built/admin/assets/textarea-Bjccvh_E.js +1 -0
- package/core/built/admin/assets/{tiers-EghDzCKc.js → tiers-BgYLWRJv.js} +1 -1
- package/core/built/admin/assets/toggle-group-BeEpQ69p.js +1 -0
- package/core/built/admin/assets/topic-filter-Bb5MOD-1.js +1 -0
- package/core/built/admin/assets/{use-analytics-data-0l_OHtnR.js → use-analytics-data-Cds6XDjg.js} +1 -1
- package/core/built/admin/assets/use-filter-params-DjXkhO54.js +1 -0
- package/core/built/admin/assets/use-growth-stats-D8uf98-G.js +1 -0
- package/core/built/admin/assets/{use-post-referrers-DwI31Ril.js → use-post-referrers-CRtgyuXB.js} +1 -1
- package/core/built/admin/assets/use-reply-chain-data-DbKYX50v.js +1 -0
- package/core/built/admin/assets/use-simple-pagination-DC01kpo0.js +1 -0
- package/core/built/admin/assets/{use-tinybird-query-DvZBBMG7.js → use-tinybird-query-C7bQRJWw.js} +1 -1
- package/core/built/admin/assets/{use-tinybird-token-CQtebkvU.js → use-tinybird-token-Az4tam7_.js} +1 -1
- package/core/built/admin/assets/{users-Pc8IRjk9.js → users-CcSCQFcQ.js} +1 -1
- package/core/built/admin/assets/virtual-list-Dhuh9fGx.js +1 -0
- package/core/built/admin/assets/web-LtHNiNBV.js +1 -0
- package/core/built/admin/index.html +22 -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 +42 -3
- 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 +13 -11
- package/core/server/adapters/storage/LocalFilesStorage.ts +24 -0
- package/core/server/adapters/storage/LocalImagesStorage.js +14 -12
- package/core/server/adapters/storage/LocalImagesStorage.ts +24 -0
- package/core/server/adapters/storage/LocalMediaStorage.js +13 -11
- package/core/server/adapters/storage/LocalMediaStorage.ts +24 -0
- package/core/server/adapters/storage/LocalStorageBase.js +107 -167
- package/core/server/adapters/storage/LocalStorageBase.ts +342 -0
- 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 +36 -50
- package/core/server/adapters/storage/utils.ts +60 -0
- package/core/server/api/endpoints/authentication.js +1 -1
- package/core/server/api/endpoints/db.js +6 -0
- 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/members.js +25 -28
- package/core/server/api/endpoints/pages.js +6 -1
- package/core/server/api/endpoints/posts.js +28 -3
- 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/mappers/comments.js +4 -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 +27 -106
- 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/exporter/export-filename.js +2 -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/importer/importers/data/revue-subscriber-importer.js +6 -10
- package/core/server/data/importer/importers/json-to-html.js +24 -4
- 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 +7 -23
- package/core/server/lib/image/image-utils.js +16 -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/request-external.js +1 -1
- 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 +47 -71
- 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 +29 -2
- package/core/server/services/automations/automations-api.js +8 -25
- package/core/server/services/automations/automations-api.ts +8 -37
- package/core/server/services/automations/automations-repository.ts +16 -0
- package/core/server/services/automations/database-automations-repository.js +37 -4
- package/core/server/services/automations/database-automations-repository.ts +41 -4
- 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/comments-service-emails.js +4 -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/import-export/config.js +30 -0
- package/core/server/services/members/import-export/config.ts +34 -0
- package/core/server/services/members/import-export/csv/index.js +10 -0
- package/core/server/services/members/import-export/csv/index.ts +2 -0
- package/core/server/services/members/import-export/csv/parse.js +64 -0
- package/core/server/services/members/import-export/csv/parse.ts +69 -0
- package/core/server/services/members/import-export/csv/serialize.js +13 -0
- package/core/server/services/members/import-export/csv/serialize.ts +18 -0
- package/core/server/services/members/import-export/export/exporter.js +202 -0
- package/core/server/services/members/import-export/export/exporter.ts +325 -0
- package/core/server/services/members/import-export/import/completion-email.js +65 -0
- package/core/server/services/members/import-export/import/completion-email.ts +119 -0
- package/core/server/services/members/import-export/import/importer.js +276 -0
- package/core/server/services/members/import-export/import/importer.ts +430 -0
- package/core/server/services/members/import-export/import/reader.js +32 -0
- package/core/server/services/members/import-export/import/reader.ts +33 -0
- package/core/server/services/members/import-export/import/row.js +33 -0
- package/core/server/services/members/import-export/import/row.ts +52 -0
- package/core/server/services/members/import-export/import/spool.js +30 -0
- package/core/server/services/members/import-export/import/spool.ts +38 -0
- package/core/server/services/members/import-export/index.js +90 -0
- package/core/server/services/members/import-export/index.ts +118 -0
- package/core/server/services/members/members-api/controllers/router-controller.js +7 -0
- 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 +28 -17
- 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-exporter.js +6 -4
- package/core/server/services/posts/posts-service-instance.js +1 -1
- package/core/server/services/posts/posts-service.js +4 -4
- 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/storage.js +9 -0
- package/core/server/services/themes/theme-storage.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 +10 -2
- package/core/shared/config/overrides.json +4 -0
- package/core/shared/express.js +6 -1
- package/core/shared/labs.js +2 -1
- package/core/shared/url-utils.js +19 -15
- package/core/shared/url-utils.ts +20 -0
- package/ghost.js +0 -1
- package/package.json +30 -35
- 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-CT46_f_J.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
- package/core/server/services/mail/templates/newsletter.html +0 -876
- package/core/server/services/members/exporter/query.js +0 -206
- package/core/server/services/members/importer/index.js +0 -30
- package/core/server/services/members/importer/labels.js +0 -125
- package/core/server/services/members/importer/members-csv-importer.js +0 -502
- /package/core/server/services/members/{importer → import-export/import}/email-template.js +0 -0
- /package/core/server/services/members/{importer/members-csv-importer-stripe-utils.js → import-export/import/stripe-utils.js} +0 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IndexNow Integration Service
|
|
3
|
+
*
|
|
4
|
+
* IndexNow is a protocol that allows websites to notify search engines about
|
|
5
|
+
* content changes for faster indexing. Instead of waiting for crawlers to
|
|
6
|
+
* discover updates, we proactively ping the IndexNow API when posts are
|
|
7
|
+
* published or updated.
|
|
8
|
+
*
|
|
9
|
+
* Protocol: https://www.indexnow.org/documentation
|
|
10
|
+
*
|
|
11
|
+
* How it works:
|
|
12
|
+
* 1. Ghost generates a unique API key (32-char hex string)
|
|
13
|
+
* 2. The key is stored in settings and served at /{key}.txt for verification
|
|
14
|
+
* 3. When a post is published/updated, we send a GET request to IndexNow:
|
|
15
|
+
* GET https://api.indexnow.org/indexnow?url={post-url}&key={key}&keyLocation={key-file-url}
|
|
16
|
+
* 4. IndexNow distributes the notification to participating search engines
|
|
17
|
+
* (Bing, Yandex, Seznam.cz, Naver, and others)
|
|
18
|
+
*
|
|
19
|
+
* The API key file is served by the middleware in:
|
|
20
|
+
* ghost/core/core/frontend/web/middleware/serve-indexnow-key.js
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import errors from '@tryghost/errors';
|
|
24
|
+
import tpl from '@tryghost/tpl';
|
|
25
|
+
|
|
26
|
+
import {
|
|
27
|
+
messages,
|
|
28
|
+
INDEXNOW_LOG_KEY,
|
|
29
|
+
INDEXNOW_ENDPOINT,
|
|
30
|
+
defaultPostSlugs,
|
|
31
|
+
seoFields
|
|
32
|
+
} from './constants';
|
|
33
|
+
|
|
34
|
+
type SettingsCache = {
|
|
35
|
+
get(key: string): unknown;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type Config = {
|
|
39
|
+
isPrivacyDisabled(key: string): boolean;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
type Labs = {
|
|
43
|
+
isSet(flag: string): boolean;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
type UrlService = {
|
|
47
|
+
facade: {
|
|
48
|
+
getUrlForResource(resource: Record<string, unknown>, options: {absolute: boolean}): string | null;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
type UrlUtils = {
|
|
53
|
+
urlFor(context: string, absolute: boolean): string;
|
|
54
|
+
urlJoin(...parts: string[]): string;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
type Logging = {
|
|
58
|
+
info(...args: unknown[]): void;
|
|
59
|
+
warn(...args: unknown[]): void;
|
|
60
|
+
error(...args: unknown[]): void;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
type RequestFn = (url: string, options: Record<string, unknown>) => Promise<{statusCode: number}>;
|
|
64
|
+
|
|
65
|
+
type PostModel = {
|
|
66
|
+
get(field: string): unknown;
|
|
67
|
+
previous(field: string): unknown;
|
|
68
|
+
related(relation: string): {toJSON(): unknown[]};
|
|
69
|
+
toJSON(): Record<string, unknown>;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type ModelEventListener = (model: PostModel, options?: {importing?: boolean}) => void;
|
|
73
|
+
|
|
74
|
+
type ModelEvents = {
|
|
75
|
+
removeListener(event: string, listener: ModelEventListener): ModelEvents;
|
|
76
|
+
on(event: string, listener: ModelEventListener): ModelEvents;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
type Post = {
|
|
80
|
+
id?: string;
|
|
81
|
+
slug?: string;
|
|
82
|
+
type?: string;
|
|
83
|
+
[key: string]: unknown;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export type IndexNowPingServiceDeps = {
|
|
87
|
+
settingsCache: SettingsCache;
|
|
88
|
+
config: Config;
|
|
89
|
+
labs: Labs;
|
|
90
|
+
urlService: UrlService;
|
|
91
|
+
urlUtils: UrlUtils;
|
|
92
|
+
request: RequestFn;
|
|
93
|
+
logging: Logging;
|
|
94
|
+
events: ModelEvents;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export class IndexNowPingService {
|
|
98
|
+
settingsCache: SettingsCache;
|
|
99
|
+
config: Config;
|
|
100
|
+
labs: Labs;
|
|
101
|
+
urlService: UrlService;
|
|
102
|
+
urlUtils: UrlUtils;
|
|
103
|
+
request: RequestFn;
|
|
104
|
+
logging: Logging;
|
|
105
|
+
events: ModelEvents;
|
|
106
|
+
listener: ModelEventListener;
|
|
107
|
+
|
|
108
|
+
constructor({settingsCache, config, labs, urlService, urlUtils, request, logging, events}: IndexNowPingServiceDeps) {
|
|
109
|
+
this.settingsCache = settingsCache;
|
|
110
|
+
this.config = config;
|
|
111
|
+
this.labs = labs;
|
|
112
|
+
this.urlService = urlService;
|
|
113
|
+
this.urlUtils = urlUtils;
|
|
114
|
+
this.request = request;
|
|
115
|
+
this.logging = logging;
|
|
116
|
+
this.events = events;
|
|
117
|
+
|
|
118
|
+
// Stable reference so removeListener() can de-register it across reboots.
|
|
119
|
+
this.listener = this.handlePostEvent.bind(this);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get existing API key from settings.
|
|
124
|
+
* The key is auto-generated on boot by the settings service.
|
|
125
|
+
*/
|
|
126
|
+
getApiKey(): string | null {
|
|
127
|
+
return (this.settingsCache.get('indexnow_api_key') as string | undefined) || null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Check if any SEO-relevant fields have changed.
|
|
132
|
+
* These are fields that affect how the post appears in search results.
|
|
133
|
+
*/
|
|
134
|
+
hasSeoRelevantChanges(model: PostModel): boolean {
|
|
135
|
+
return seoFields.some(field => model.get(field) !== model.previous(field));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Ping IndexNow with a URL.
|
|
140
|
+
*/
|
|
141
|
+
async ping(post: Post): Promise<void> {
|
|
142
|
+
// Skip pages - only ping for posts
|
|
143
|
+
if (post.type === 'page') {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Skip if site is private
|
|
148
|
+
if (this.settingsCache.get('is_private')) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Skip if IndexNow pings are disabled via privacy config
|
|
153
|
+
if (this.config.isPrivacyDisabled('useIndexNow')) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Skip if IndexNow is not enabled in labs
|
|
158
|
+
if (!this.labs.isSet('indexnow')) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Don't ping for the default posts
|
|
163
|
+
if (post.slug && defaultPostSlugs.indexOf(post.slug) > -1) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Everything from URL resolution onwards sits inside the swallow-and-log
|
|
168
|
+
// envelope: the lazy URL service evaluates collection filters during
|
|
169
|
+
// resolution and can throw, and IndexNow failures must never disrupt
|
|
170
|
+
// publishing.
|
|
171
|
+
let url: string | null = null;
|
|
172
|
+
try {
|
|
173
|
+
url = this.urlService.facade.getUrlForResource({...post, type: 'posts'}, {absolute: true});
|
|
174
|
+
|
|
175
|
+
if (!url || url.endsWith('/404/')) {
|
|
176
|
+
this.logging.warn({
|
|
177
|
+
event: {name: 'indexnow.unresolved_url'},
|
|
178
|
+
post: {id: post.id, slug: post.slug, url}
|
|
179
|
+
}, `${INDEXNOW_LOG_KEY} Skipped ping - post has no resolvable URL`);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Get the API key (auto-generated on boot by settings service)
|
|
184
|
+
const key = this.getApiKey();
|
|
185
|
+
if (!key) {
|
|
186
|
+
this.logging.warn({
|
|
187
|
+
event: {name: 'indexnow.api_key_missing'},
|
|
188
|
+
post: {id: post.id, slug: post.slug}
|
|
189
|
+
}, `${INDEXNOW_LOG_KEY} API key not available`);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Get the site URL for the keyLocation parameter
|
|
194
|
+
const siteUrl = this.urlUtils.urlFor('home', true);
|
|
195
|
+
|
|
196
|
+
// Build the IndexNow request URL
|
|
197
|
+
const indexNowUrl = new URL(INDEXNOW_ENDPOINT);
|
|
198
|
+
indexNowUrl.searchParams.set('url', url);
|
|
199
|
+
indexNowUrl.searchParams.set('key', key);
|
|
200
|
+
indexNowUrl.searchParams.set('keyLocation', this.urlUtils.urlJoin(siteUrl, `${key}.txt`));
|
|
201
|
+
|
|
202
|
+
const response = await this.request(indexNowUrl.toString(), {
|
|
203
|
+
timeout: {
|
|
204
|
+
request: 5 * 1000 // 5 second timeout
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
if (response.statusCode !== 200 && response.statusCode !== 202) {
|
|
209
|
+
throw new errors.InternalServerError({
|
|
210
|
+
message: `IndexNow returned unexpected status: ${response.statusCode}`,
|
|
211
|
+
statusCode: response.statusCode
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
this.logging.info({
|
|
216
|
+
event: {name: 'indexnow.pinged'},
|
|
217
|
+
post: {id: post.id, slug: post.slug, url},
|
|
218
|
+
http: {response: {status_code: response.statusCode}}
|
|
219
|
+
}, `${INDEXNOW_LOG_KEY} Successfully pinged ${url}`);
|
|
220
|
+
} catch (err) {
|
|
221
|
+
// Log errors but don't throw - IndexNow failures shouldn't disrupt publishing
|
|
222
|
+
const errorLike = err as {statusCode?: number; response?: {statusCode?: number}; message?: string};
|
|
223
|
+
const statusCode = errorLike.statusCode ?? errorLike.response?.statusCode ?? null;
|
|
224
|
+
const {eventName, error} = this.#classifyError(statusCode, err as Error);
|
|
225
|
+
|
|
226
|
+
this.logging.warn({
|
|
227
|
+
event: {name: eventName},
|
|
228
|
+
post: {id: post.id, slug: post.slug, url},
|
|
229
|
+
http: {response: {status_code: statusCode}},
|
|
230
|
+
err: error
|
|
231
|
+
}, `${INDEXNOW_LOG_KEY} ${error.message}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Map an IndexNow response status to a log event name and a structured error.
|
|
237
|
+
* IndexNow-protocol-specific interpretation; when this logic is lifted into a
|
|
238
|
+
* shared ping primitive, this becomes the injected `interpret(status)` hook.
|
|
239
|
+
*/
|
|
240
|
+
#classifyError(statusCode: number | null, err: Error): {eventName: string; error: Error} {
|
|
241
|
+
if (statusCode === 429) {
|
|
242
|
+
// Rate limited by IndexNow - we have no retry/backoff, so the ping is dropped
|
|
243
|
+
return {
|
|
244
|
+
eventName: 'indexnow.rate_limited',
|
|
245
|
+
error: new errors.TooManyRequestsError({
|
|
246
|
+
err,
|
|
247
|
+
message: err.message,
|
|
248
|
+
context: tpl(messages.requestFailedError, {service: 'IndexNow'}),
|
|
249
|
+
help: tpl(messages.requestFailedHelp, {url: 'https://ghost.org/docs/'})
|
|
250
|
+
})
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (statusCode === 422 || statusCode === 403) {
|
|
255
|
+
return {
|
|
256
|
+
eventName: 'indexnow.key_validation_failed',
|
|
257
|
+
error: new errors.ValidationError({
|
|
258
|
+
err,
|
|
259
|
+
message: 'IndexNow key validation failed',
|
|
260
|
+
context: tpl(messages.requestFailedError, {service: 'IndexNow'}),
|
|
261
|
+
help: 'Ensure your IndexNow API key file is accessible at the correct URL'
|
|
262
|
+
})
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
eventName: 'indexnow.ping_failed',
|
|
268
|
+
error: new errors.InternalServerError({
|
|
269
|
+
err,
|
|
270
|
+
message: err.message,
|
|
271
|
+
context: tpl(messages.requestFailedError, {service: 'IndexNow'}),
|
|
272
|
+
help: tpl(messages.requestFailedHelp, {url: 'https://ghost.org/docs/'})
|
|
273
|
+
})
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Event listener for post.published / post.published.edited.
|
|
279
|
+
*/
|
|
280
|
+
handlePostEvent(model: PostModel, options?: {importing?: boolean}): void {
|
|
281
|
+
// CASE: do not ping if we import a database
|
|
282
|
+
if (options && options.importing) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Content-based deduplication: skip if no SEO-relevant fields changed
|
|
287
|
+
// This avoids spamming IndexNow when minor non-content edits are made
|
|
288
|
+
if (!this.hasSeoRelevantChanges(model)) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
this.ping({
|
|
293
|
+
...model.toJSON(),
|
|
294
|
+
// tags and authors are needed so the lazy URL service can evaluate
|
|
295
|
+
// collection filters (e.g. `tag:foo`) when resolving the post URL;
|
|
296
|
+
// without them a tag/author-filtered post resolves to /404/
|
|
297
|
+
authors: model.related('authors').toJSON(),
|
|
298
|
+
tags: model.related('tags').toJSON()
|
|
299
|
+
}).catch(() => {
|
|
300
|
+
// Errors are already logged inside ping()
|
|
301
|
+
// This catch is just to prevent unhandled rejection warnings
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Register event listeners for IndexNow.
|
|
307
|
+
*/
|
|
308
|
+
subscribeEvents(): void {
|
|
309
|
+
// Listen for new posts being published
|
|
310
|
+
this.events
|
|
311
|
+
.removeListener('post.published', this.listener)
|
|
312
|
+
.on('post.published', this.listener);
|
|
313
|
+
|
|
314
|
+
// Also listen for published posts being edited
|
|
315
|
+
this.events
|
|
316
|
+
.removeListener('post.published.edited', this.listener)
|
|
317
|
+
.on('post.published.edited', this.listener);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const settingsCache = require('../../../shared/settings-cache');
|
|
2
2
|
const settingsHelpers = require('../settings-helpers');
|
|
3
3
|
const mailService = require('../../services/mail');
|
|
4
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
4
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
5
5
|
const Invites = require('./invites');
|
|
6
6
|
|
|
7
7
|
module.exports = new Invites({
|
|
@@ -4,12 +4,12 @@ const logging = require('@tryghost/logging');
|
|
|
4
4
|
const metrics = require('@tryghost/metrics');
|
|
5
5
|
const errors = require('@tryghost/errors');
|
|
6
6
|
|
|
7
|
+
const DEFAULT_BATCH_SIZE = 1000;
|
|
8
|
+
|
|
7
9
|
module.exports = class MailgunClient {
|
|
8
10
|
#config;
|
|
9
11
|
#settings;
|
|
10
12
|
|
|
11
|
-
static DEFAULT_BATCH_SIZE = 1000;
|
|
12
|
-
|
|
13
13
|
constructor({config, settings}) {
|
|
14
14
|
this.#config = config;
|
|
15
15
|
this.#settings = settings;
|
|
@@ -393,7 +393,7 @@ module.exports = class MailgunClient {
|
|
|
393
393
|
* @returns {number}
|
|
394
394
|
*/
|
|
395
395
|
getBatchSize() {
|
|
396
|
-
return this.#config.get('bulkEmail')?.batchSize ??
|
|
396
|
+
return this.#config.get('bulkEmail')?.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
397
397
|
}
|
|
398
398
|
|
|
399
399
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
1
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
2
2
|
const LinkRedirectRepository = require('./link-redirect-repository');
|
|
3
|
-
const adapterManager = require('../adapter-manager');
|
|
3
|
+
const adapterManager = require('../adapter-manager').default;
|
|
4
4
|
const config = require('../../../shared/config');
|
|
5
5
|
const EventRegistry = require('../../lib/common/events');
|
|
6
6
|
|
|
@@ -1,26 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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.LinkRedirect = void 0;
|
|
7
|
+
const bson_objectid_1 = __importDefault(require("bson-objectid"));
|
|
8
|
+
class LinkRedirect {
|
|
5
9
|
link_id;
|
|
6
|
-
/** @type {URL} */
|
|
7
10
|
from;
|
|
8
|
-
/** @type {URL} */
|
|
9
11
|
to;
|
|
10
|
-
/** @type {boolean} */
|
|
11
12
|
edited;
|
|
12
|
-
|
|
13
13
|
constructor(data) {
|
|
14
14
|
if (!data.id) {
|
|
15
|
-
this.link_id = new
|
|
15
|
+
this.link_id = new bson_objectid_1.default();
|
|
16
16
|
}
|
|
17
|
-
|
|
18
17
|
if (typeof data.id === 'string') {
|
|
19
|
-
this.link_id =
|
|
18
|
+
this.link_id = bson_objectid_1.default.createFromHexString(data.id);
|
|
20
19
|
}
|
|
21
|
-
|
|
22
20
|
this.from = data.from;
|
|
23
21
|
this.to = data.to;
|
|
24
22
|
this.edited = !!data.edited;
|
|
25
23
|
}
|
|
26
|
-
}
|
|
24
|
+
}
|
|
25
|
+
exports.LinkRedirect = LinkRedirect;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import ObjectID from 'bson-objectid';
|
|
2
|
+
|
|
3
|
+
export class LinkRedirect {
|
|
4
|
+
link_id: undefined | ObjectID;
|
|
5
|
+
from: URL;
|
|
6
|
+
to: URL;
|
|
7
|
+
edited: boolean;
|
|
8
|
+
|
|
9
|
+
constructor(data: {id?: string; from: URL; to: URL; edited?: boolean}) {
|
|
10
|
+
if (!data.id) {
|
|
11
|
+
this.link_id = new ObjectID();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (typeof data.id === 'string') {
|
|
15
|
+
this.link_id = ObjectID.createFromHexString(data.id);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
this.from = data.from;
|
|
19
|
+
this.to = data.to;
|
|
20
|
+
this.edited = !!data.edited;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const crypto = require('crypto');
|
|
2
2
|
const DomainEvents = require('@tryghost/domain-events');
|
|
3
3
|
const RedirectEvent = require('./redirect-event');
|
|
4
|
-
const LinkRedirect = require('./link-redirect');
|
|
4
|
+
const {LinkRedirect} = require('./link-redirect');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @typedef {object} ILinkRedirectRepository
|
|
@@ -12,7 +12,7 @@ module.exports = class FullPostLink {
|
|
|
12
12
|
/** @type {ObjectID} */
|
|
13
13
|
post_id;
|
|
14
14
|
|
|
15
|
-
/** @type {import('../link-redirection/link-redirect')} */
|
|
15
|
+
/** @type {import('../link-redirection/link-redirect').LinkRedirect} */
|
|
16
16
|
link;
|
|
17
17
|
|
|
18
18
|
/** @type {FullPostLinkCount} */
|
|
@@ -21,7 +21,7 @@ module.exports = class FullPostLink {
|
|
|
21
21
|
/**
|
|
22
22
|
* @param {object} data
|
|
23
23
|
* @param {string|ObjectID} data.post_id
|
|
24
|
-
* @param {import('../link-redirection/link-redirect')} data.link
|
|
24
|
+
* @param {import('../link-redirection/link-redirect').LinkRedirect} data.link
|
|
25
25
|
* @param {FullPostLinkCount} data.count
|
|
26
26
|
*/
|
|
27
27
|
constructor(data) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const LinkClickRepository = require('./link-click-repository');
|
|
2
2
|
const PostLinkRepository = require('./post-link-repository');
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
4
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
5
5
|
|
|
6
6
|
class LinkTrackingServiceWrapper {
|
|
7
7
|
async init() {
|
|
@@ -6,7 +6,7 @@ const logging = require('@tryghost/logging');
|
|
|
6
6
|
const errors = require('@tryghost/errors');
|
|
7
7
|
const tpl = require('@tryghost/tpl');
|
|
8
8
|
const settingsCache = require('../../../shared/settings-cache');
|
|
9
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
9
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
10
10
|
const metrics = require('@tryghost/metrics');
|
|
11
11
|
const emailAddress = require('../email-address');
|
|
12
12
|
const messages = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
2
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
3
3
|
const settingsCache = require('../../../shared/settings-cache');
|
|
4
4
|
const EmailContentGenerator = require('../lib/email-content-generator');
|
|
5
5
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const mime = require('mime-types');
|
|
2
2
|
const request = require('../../lib/request-external');
|
|
3
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
3
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
4
4
|
const errors = require('@tryghost/errors');
|
|
5
5
|
const logging = require('@tryghost/logging');
|
|
6
6
|
const string = require('@tryghost/string');
|
|
@@ -37,7 +37,7 @@ class ExternalMediaInliner {
|
|
|
37
37
|
* @param {Object} deps.PostMetaModel - PostMeta model
|
|
38
38
|
* @param {Object} deps.TagModel - Tag model
|
|
39
39
|
* @param {Object} deps.UserModel - User model
|
|
40
|
-
* @param {(extension) => import('ghost-storage-base')} deps.getMediaStorage - getMediaStorage
|
|
40
|
+
* @param {(extension) => import('ghost-storage-base').StorageBase} deps.getMediaStorage - getMediaStorage
|
|
41
41
|
*/
|
|
42
42
|
constructor(deps) {
|
|
43
43
|
this.#PostModel = deps.PostModel;
|
|
@@ -4,10 +4,11 @@ module.exports = {
|
|
|
4
4
|
const MediaInliner = require('./external-media-inliner');
|
|
5
5
|
const models = require('../../models');
|
|
6
6
|
const jobsService = require('../jobs');
|
|
7
|
+
const adapterManager = require('../../services/adapter-manager').default;
|
|
7
8
|
|
|
8
|
-
const mediaStorage =
|
|
9
|
-
const imageStorage =
|
|
10
|
-
const fileStorage =
|
|
9
|
+
const mediaStorage = adapterManager.getAdapter('storage:media');
|
|
10
|
+
const imageStorage = adapterManager.getAdapter('storage:images');
|
|
11
|
+
const fileStorage = adapterManager.getAdapter('storage:files');
|
|
11
12
|
|
|
12
13
|
const config = require('../../../shared/config');
|
|
13
14
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const urlService = require('../url');
|
|
2
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
2
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
3
3
|
const settingsCache = require('../../../shared/settings-cache');
|
|
4
4
|
const config = require('../../../shared/config');
|
|
5
5
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const errors = require('@tryghost/errors');
|
|
3
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
3
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
4
4
|
const settingsCache = require('../../../shared/settings-cache');
|
|
5
5
|
const verifyEmailTemplate = require('../newsletters/emails/verify-email');
|
|
6
6
|
const MagicLink = require('../lib/magic-link/magic-link');
|
|
@@ -11,7 +11,8 @@ const signupPaidEmail = require('./emails/signup-paid');
|
|
|
11
11
|
const subscribeEmail = require('./emails/subscribe');
|
|
12
12
|
const updateEmail = require('./emails/update-email');
|
|
13
13
|
const SingleUseTokenProvider = require('./single-use-token-provider');
|
|
14
|
-
const urlUtils = require('../../../shared/url-utils');
|
|
14
|
+
const urlUtils = require('../../../shared/url-utils').default;
|
|
15
|
+
const urlService = require('../url');
|
|
15
16
|
const labsService = require('../../../shared/labs');
|
|
16
17
|
const offersService = require('../offers');
|
|
17
18
|
const tiersService = require('../tiers');
|
|
@@ -53,6 +54,7 @@ function trimLeadingWhitespace(strings, ...values) {
|
|
|
53
54
|
|
|
54
55
|
function createApiInstance(config) {
|
|
55
56
|
const membersApiInstance = MembersApi({
|
|
57
|
+
urlService: urlService.facade,
|
|
56
58
|
tokenConfig: config.getTokenConfig(),
|
|
57
59
|
auth: {
|
|
58
60
|
getSigninURL: config.getSigninURL.bind(config),
|
|
@@ -259,7 +261,11 @@ function createApiInstance(config) {
|
|
|
259
261
|
commentsService,
|
|
260
262
|
emailAddressService: emailAddressService.service,
|
|
261
263
|
giftService,
|
|
262
|
-
|
|
264
|
+
// Resolved here rather than passed as the module: the members service needs
|
|
265
|
+
// the values service itself, and reading it at construction is what ties the
|
|
266
|
+
// two together in boot order. Custom fields is initialised in initCore, the
|
|
267
|
+
// members API is built in initServices, so this is always the live instance.
|
|
268
|
+
customFieldValues: customFieldsService.values
|
|
263
269
|
});
|
|
264
270
|
|
|
265
271
|
return membersApiInstance;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveInlineThreshold = resolveInlineThreshold;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
// Config arrives untyped: defaults.json ships a value, and any higher layer -- an
|
|
6
|
+
// operator's config file, an environment variable, argv -- can replace it with anything.
|
|
7
|
+
// Validating it into a usable number is a config concern, so it happens here at the
|
|
8
|
+
// boundary; the importer is handed a resolved value.
|
|
9
|
+
// The row count at or below which an import is performed while the request is
|
|
10
|
+
// still open. Zero is allowed and means every import is deferred. A numeric
|
|
11
|
+
// string is accepted because a value supplied through an environment variable
|
|
12
|
+
// can arrive as one.
|
|
13
|
+
const Threshold = zod_1.z
|
|
14
|
+
.union([zod_1.z.number(), zod_1.z.string().trim().min(1)])
|
|
15
|
+
.transform(Number)
|
|
16
|
+
.pipe(zod_1.z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER));
|
|
17
|
+
// defaults.json is the single source of the shipped threshold: it is the lowest
|
|
18
|
+
// config layer and the file an operator actually reads and edits, so it is read
|
|
19
|
+
// rather than restated. Parsed eagerly because a missing or malformed value
|
|
20
|
+
// there is our bug rather than an operator's, and should fail loudly at boot
|
|
21
|
+
// instead of quietly becoming the fallback for everything below.
|
|
22
|
+
const shippedThreshold = Threshold.parse(require('../../../../shared/config/defaults.json').members.importer.inlineThreshold);
|
|
23
|
+
// A higher layer can override the shipped value with anything. Something
|
|
24
|
+
// unreadable falls back to the shipped threshold rather than throwing, because
|
|
25
|
+
// an operator can correct this live and a bad value must not take member import
|
|
26
|
+
// down with it.
|
|
27
|
+
const InlineThreshold = Threshold.catch(shippedThreshold);
|
|
28
|
+
function resolveInlineThreshold(configured) {
|
|
29
|
+
return InlineThreshold.parse(configured);
|
|
30
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {z} from 'zod';
|
|
2
|
+
|
|
3
|
+
// Config arrives untyped: defaults.json ships a value, and any higher layer -- an
|
|
4
|
+
// operator's config file, an environment variable, argv -- can replace it with anything.
|
|
5
|
+
// Validating it into a usable number is a config concern, so it happens here at the
|
|
6
|
+
// boundary; the importer is handed a resolved value.
|
|
7
|
+
|
|
8
|
+
// The row count at or below which an import is performed while the request is
|
|
9
|
+
// still open. Zero is allowed and means every import is deferred. A numeric
|
|
10
|
+
// string is accepted because a value supplied through an environment variable
|
|
11
|
+
// can arrive as one.
|
|
12
|
+
const Threshold = z
|
|
13
|
+
.union([z.number(), z.string().trim().min(1)])
|
|
14
|
+
.transform(Number)
|
|
15
|
+
.pipe(z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER));
|
|
16
|
+
|
|
17
|
+
// defaults.json is the single source of the shipped threshold: it is the lowest
|
|
18
|
+
// config layer and the file an operator actually reads and edits, so it is read
|
|
19
|
+
// rather than restated. Parsed eagerly because a missing or malformed value
|
|
20
|
+
// there is our bug rather than an operator's, and should fail loudly at boot
|
|
21
|
+
// instead of quietly becoming the fallback for everything below.
|
|
22
|
+
const shippedThreshold: number = Threshold.parse(
|
|
23
|
+
require('../../../../shared/config/defaults.json').members.importer.inlineThreshold
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
// A higher layer can override the shipped value with anything. Something
|
|
27
|
+
// unreadable falls back to the shipped threshold rather than throwing, because
|
|
28
|
+
// an operator can correct this live and a bad value must not take member import
|
|
29
|
+
// down with it.
|
|
30
|
+
const InlineThreshold = Threshold.catch(shippedThreshold);
|
|
31
|
+
|
|
32
|
+
export function resolveInlineThreshold(configured: unknown): number {
|
|
33
|
+
return InlineThreshold.parse(configured);
|
|
34
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
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.serialize = exports.parse = void 0;
|
|
7
|
+
var parse_1 = require("./parse");
|
|
8
|
+
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return __importDefault(parse_1).default; } });
|
|
9
|
+
var serialize_1 = require("./serialize");
|
|
10
|
+
Object.defineProperty(exports, "serialize", { enumerable: true, get: function () { return __importDefault(serialize_1).default; } });
|