ghost 6.11.0 → 6.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/tryghost-i18n-6.12.0.tgz +0 -0
- package/core/boot.js +4 -2
- package/core/built/admin/assets/{_baseAssignValue-BX8EallQ.js → _baseAssignValue-hsL6ItjC.js} +1 -1
- package/core/built/admin/assets/{a-large-small-CKZJgscl.js → a-large-small-BPPu_Iy7.js} +1 -1
- package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +1 -1
- package/core/built/admin/assets/admin-x-settings/{code-editor-view-n8DFeXbv.mjs → code-editor-view-Bq6l5arq.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/{index-v6qQgUXt.mjs → index-CKaxer_o.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/{index-CXL12uvO.mjs → index-CtYEAgeN.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/{index-D4ye6uvI.mjs → index-D4NstoNQ.mjs} +11 -6
- package/core/built/admin/assets/admin-x-settings/{modals-CdsPaTfy.mjs → modals-BzljHVa7.mjs} +2 -2
- package/core/built/admin/assets/{at-sign-CqQzllfI.js → at-sign-CYnGzOFc.js} +1 -1
- package/core/built/admin/assets/{audience-select-DQD7iDOb.js → audience-select-DYoxiiwy.js} +1 -1
- package/core/built/admin/assets/{avatar-flipboard-uq7ptTxT.js → avatar-flipboard-C9-npfmZ.js} +1 -1
- package/core/built/admin/assets/{bluesky-sharing-qyIGv6Ny.js → bluesky-sharing-BGcmGcee.js} +1 -1
- package/core/built/admin/assets/{chart-DGA1MaFs.js → chart-CqJxisVP.js} +1 -1
- package/core/built/admin/assets/{chunk.524.1289543297329587cf8a.js → chunk.524.74a9629dd2ba0d21bbef.js} +7 -7
- package/core/built/admin/assets/{chunk.582.344ea0d0a16d671345cd.js → chunk.582.3846471396b3a7c46e66.js} +8 -8
- package/core/built/admin/assets/{code-editor-view-Bz6kXDiv.js → code-editor-view-C8l3gNnO.js} +1 -1
- package/core/built/admin/assets/{comments-C-lkEDkz.js → comments-CpHDoxov.js} +1 -1
- package/core/built/admin/assets/{copy-BFuV16bY.js → copy-DWiB-781.js} +1 -1
- package/core/built/admin/assets/{data-list-Bw1CQEZ9.js → data-list-yngXNZDF.js} +1 -1
- package/core/built/admin/assets/{deleted-feed-item-CmNbSYiO.js → deleted-feed-item-C0FcyLMN.js} +1 -1
- package/core/built/admin/assets/{edit-profile-DlIPB2km.js → edit-profile-BjtDkDAq.js} +1 -1
- package/core/built/admin/assets/{empty-indicator-DBrIZcFq.js → empty-indicator-BXWniwsl.js} +1 -1
- package/core/built/admin/assets/{en-BBc7b85q.js → en-B8qaJx-T.js} +1 -1
- package/core/built/admin/assets/{feed-B3XQzKZl.js → feed-DsCVb1SA.js} +1 -1
- package/core/built/admin/assets/{filters-DUFXZZnu.js → filters-jAXQSPq6.js} +1 -1
- package/core/built/admin/assets/{gh-chart-BV97-O7c.js → gh-chart-DwTCK8z_.js} +1 -1
- package/core/built/admin/assets/{ghost-9aa1e7c5992f122dba6932af78bf8e56.js → ghost-6367d022df9db9dacbcb9bfa30232ec7.js} +2 -2
- package/core/built/admin/assets/{growth-njR0GqK2.js → growth-DshcRqda.js} +1 -1
- package/core/built/admin/assets/{hash-CdH0ikFp.js → hash-p9dv0yuc.js} +1 -1
- package/core/built/admin/assets/{inbox-Bd0uf1Ez.js → inbox-CRoP9sy5.js} +1 -1
- package/core/built/admin/assets/{index-Kji6JKl7.js → index-6syrC9X1.js} +1 -1
- package/core/built/admin/assets/{index-C7M19LpB.js → index-BKtz3UH0.js} +1 -1
- package/core/built/admin/assets/{index-DWk7hKRR.js → index-BwY94Fb4.js} +1 -1
- package/core/built/admin/assets/{index-BFhECYgc.js → index-C3DF6aFe.js} +1 -1
- package/core/built/admin/assets/index-C6NCNp1B.js +1 -0
- package/core/built/admin/assets/{index-BYawr8p9.js → index-CJU9a2PB.js} +3 -3
- package/core/built/admin/assets/{index-CIE2_z5J.js → index-CUWE7aD1.js} +1 -1
- package/core/built/admin/assets/{index-DgRIbSpg.js → index-CuQ_II0e.js} +1 -1
- package/core/built/admin/assets/{index-Birw80cQ.js → index-DG8f-HuU.js} +1 -1
- package/core/built/admin/assets/{index-DziHC2du.js → index-DItZTRQ4.js} +1 -1
- package/core/built/admin/assets/{index-DG53N3Xt.js → index-eLx96SEn.js} +1 -1
- package/core/built/admin/assets/{index-DCw6JaEl.js → index-j2_Q-_8H.js} +1 -1
- package/core/built/admin/assets/{index-BZ21H0xH.js → index-qWpHJAMP.js} +1 -1
- package/core/built/admin/assets/{index-DXCu9e7c.js → index-sy6xRtoO.js} +1 -1
- package/core/built/admin/assets/{koenig-lexical-BDJVCHtm.js → koenig-lexical-DgAlBHHS.js} +1 -1
- package/core/built/admin/assets/{kpi-card-cv8roErt.js → kpi-card-CHZSLw4p.js} +1 -1
- package/core/built/admin/assets/{kpis-Dt4OFY3L.js → kpis-DzbAHfKK.js} +1 -1
- package/core/built/admin/assets/{links-08beB3Ij.js → links-BQHRbn46.js} +1 -1
- package/core/built/admin/assets/{lucide-react-DKlmxVQI.js → lucide-react-B7UnD_Dp.js} +1 -1
- package/core/built/admin/assets/{main-layout-Cl09wG7F.js → main-layout-9nmU5WlG.js} +1 -1
- package/core/built/admin/assets/{message-square-text-CaMVBVPr.js → message-square-text-CS3iRuPc.js} +1 -1
- package/core/built/admin/assets/{minus-2XwCoFJV.js → minus-emzwh6hq.js} +1 -1
- package/core/built/admin/assets/{modals-CIgzYQgv.js → modals-CumFuZ2d.js} +1 -1
- package/core/built/admin/assets/{moderation-FjlsSym6.js → moderation-DyfFc9m4.js} +1 -1
- package/core/built/admin/assets/{newsletter-BNOwZNlE.js → newsletter-BWul5IFc.js} +1 -1
- package/core/built/admin/assets/{newsletters-DUusEYSg.js → newsletters-N6bwI1OF.js} +1 -1
- package/core/built/admin/assets/{note-BpYwIDK6.js → note-CiBzkHzz.js} +1 -1
- package/core/built/admin/assets/{overview-Y5QYPClr.js → overview-D9gRvn7X.js} +1 -1
- package/core/built/admin/assets/{pagemenu-BMXHDXYy.js → pagemenu-aHubMPwB.js} +1 -1
- package/core/built/admin/assets/{post-analytics-UerFnJse.js → post-analytics-Bm9xH8nA.js} +1 -1
- package/core/built/admin/assets/{post-analytics-context-geHk7rOj.js → post-analytics-context-C7oW3aBz.js} +1 -1
- package/core/built/admin/assets/{post-analytics-header-DXfc4KeX.js → post-analytics-header-BjGFgN6A.js} +1 -1
- package/core/built/admin/assets/{post-share-modal-Dql4fYjR.js → post-share-modal-Su923uIc.js} +1 -1
- package/core/built/admin/assets/{posts-Bsvw11Zo.js → posts-BwP7BNcB.js} +1 -1
- package/core/built/admin/assets/{referrers-B8xJpCcR.js → referrers-n_ln9DqI.js} +1 -1
- package/core/built/admin/assets/{repeat-COP-3g8d.js → repeat-ms5ocvE0.js} +1 -1
- package/core/built/admin/assets/{reply-JE8tmvOn.js → reply-BvO85IDn.js} +1 -1
- package/core/built/admin/assets/{select-BhvNY3I-.js → select-B4QhMW5f.js} +1 -1
- package/core/built/admin/assets/{settings-BJwVfuWG.js → settings-D5rGcWJ7.js} +4 -4
- package/core/built/admin/assets/{settings-C6ZUZQe4.js → settings-QtZ6a2TL.js} +1 -1
- package/core/built/admin/assets/{sort-button-iOtR-vQ1.js → sort-button-84sYUZMN.js} +1 -1
- package/core/built/admin/assets/{source-icon-C2iFWMlV.js → source-icon-Bzw-AU8p.js} +1 -1
- package/core/built/admin/assets/{sprout-BW9HFVU8.js → sprout-C2R5CbXV.js} +1 -1
- package/core/built/admin/assets/{square-BCNGSZhW.js → square-DT1uWkxs.js} +1 -1
- package/core/built/admin/assets/stats/{audience-select-DNAWmT7R.mjs → audience-select-fTCiZ9MT.mjs} +3 -3
- package/core/built/admin/assets/stats/{index-DbGvSTMe.mjs → index-BKgioyC7.mjs} +5 -5
- package/core/built/admin/assets/stats/{index-s19ZmxbX.mjs → index-CR2t5Xd-.mjs} +5 -5
- package/core/built/admin/assets/stats/index-DEkYwR7C.mjs +739 -0
- package/core/built/admin/assets/stats/{index-BS3KMSy9.mjs → index-Djwey97a.mjs} +5 -5
- package/core/built/admin/assets/stats/{index-MOQSSYwT.mjs → index-FiU_XgEe.mjs} +6 -6
- package/core/built/admin/assets/stats/{sort-button-D76rcldr.mjs → sort-button-Bvi1wfa7.mjs} +3 -3
- package/core/built/admin/assets/stats/{stats-CJ7fhUyT.mjs → stats-Bbm6yWZq.mjs} +2 -2
- package/core/built/admin/assets/stats/stats.js +1 -1
- package/core/built/admin/assets/stats/{tabs-CkbxYgOE.mjs → tabs-BKwH5k-q.mjs} +3 -3
- package/core/built/admin/assets/stats/{url-helpers-DICtqCrE.mjs → url-helpers-DmHnUIGc.mjs} +9 -9
- package/core/built/admin/assets/stats/{use-growth-stats-DzO7zEy4.mjs → use-growth-stats-BVj3j1hb.mjs} +3 -3
- package/core/built/admin/assets/{stats-r0Bphuvi.js → stats-B1mhlQSp.js} +1 -1
- package/core/built/admin/assets/{stats-view-DzZxrBDz.js → stats-view-C6MTCwRW.js} +1 -1
- package/core/built/admin/assets/{step-1-CUoUOyMm.js → step-1-CzQmZJ93.js} +1 -1
- package/core/built/admin/assets/{step-2-CpAkPD8D.js → step-2-DXGDWSQo.js} +1 -1
- package/core/built/admin/assets/{step-3-Ci6oJDmK.js → step-3-CYuxXKac.js} +1 -1
- package/core/built/admin/assets/{table-DeBuf80X.js → table-mjAkKNdb.js} +1 -1
- package/core/built/admin/assets/{tabs-C2sFfNcp.js → tabs-BwQ-i6MY.js} +1 -1
- package/core/built/admin/assets/{tags-Bl6G5rvf.js → tags-BkUqCuvX.js} +1 -1
- package/core/built/admin/assets/{tags-BL_N4nn2.js → tags-DXDZbfxp.js} +1 -1
- package/core/built/admin/assets/{toggle-group-B2X-8giI.js → toggle-group-CqDO3Kkx.js} +1 -1
- package/core/built/admin/assets/{topic-filter-DeqMID_s.js → topic-filter-DnuJJBAE.js} +1 -1
- package/core/built/admin/assets/{trash-BglGemAb.js → trash-CZ3EXwTL.js} +1 -1
- package/core/built/admin/assets/{url-helpers-84icqAuE.js → url-helpers-BE3VXr__.js} +1 -1
- package/core/built/admin/assets/{use-growth-stats-DF-7tL8g.js → use-growth-stats-CiuWWM6O.js} +1 -1
- package/core/built/admin/assets/{use-infinite-virtual-scroll-BHH7oscK.js → use-infinite-virtual-scroll-BjATkxBj.js} +1 -1
- package/core/built/admin/assets/{use-simple-pagination-BsvYfixw.js → use-simple-pagination-C9cb7dDz.js} +1 -1
- package/core/built/admin/assets/{user-round-check-BjHbfXKY.js → user-round-check-D3ihrrKL.js} +1 -1
- package/core/built/admin/assets/{wallet-cards-KaTkgqvi.js → wallet-cards-Do7nPf3f.js} +1 -1
- package/core/built/admin/assets/{web-CUWbpFil.js → web-BEwI2Gfy.js} +1 -1
- package/core/built/admin/index-forward.html +4 -4
- package/core/built/admin/index.html +3 -3
- package/core/frontend/web/middleware/index.js +1 -0
- package/core/frontend/web/middleware/serve-indexnow-key.js +66 -0
- package/core/frontend/web/site.js +3 -0
- package/core/server/api/endpoints/authentication.js +1 -1
- package/core/server/api/endpoints/pages.js +1 -1
- package/core/server/api/endpoints/posts-public.js +1 -1
- package/core/server/api/endpoints/posts.js +1 -1
- package/core/server/api/endpoints/search-index-public.js +1 -1
- package/core/server/api/endpoints/search-index.js +1 -1
- package/core/server/api/endpoints/users.js +1 -1
- package/core/server/api/endpoints/utils/serializers/input/settings.js +2 -1
- package/core/server/api/endpoints/utils/serializers/output/mappers/posts.js +1 -1
- package/core/server/api/endpoints/utils/validators/input/settings.js +1 -1
- package/core/server/data/exporter/table-lists.js +2 -1
- package/core/server/data/migrations/versions/6.12/2026-01-08-11-48-16-add-indexnow-api-key-setting.js +9 -0
- package/core/server/data/schema/default-settings/default-settings.json +6 -0
- package/core/server/lib/lexical.js +1 -1
- package/core/server/models/settings.js +2 -1
- package/core/server/services/activitypub/{ActivityPubServiceWrapper.js → activity-pub-service-wrapper.js} +1 -1
- package/core/server/services/activitypub/{ActivityPubService.ts → activity-pub-service.ts} +1 -1
- package/core/server/services/activitypub/index.js +1 -1
- package/core/server/services/adapter-manager/index.js +1 -1
- package/core/server/services/announcement-bar-service/{AnnouncementBarSettings.js → announcement-bar-settings.js} +1 -1
- package/core/server/services/announcement-bar-service/index.js +1 -1
- package/core/server/services/audience-feedback/{AudienceFeedbackController.js → audience-feedback-controller.js} +3 -3
- package/core/server/services/audience-feedback/index.js +4 -4
- package/core/server/services/auth/session/express-session.js +1 -1
- package/core/server/services/comments/{CommentsController.js → comments-controller.js} +2 -2
- package/core/server/services/comments/{CommentsServiceEmails.js → comments-service-emails.js} +1 -1
- package/core/server/services/comments/{CommentsService.js → comments-service.js} +1 -1
- package/core/server/services/comments/index.js +3 -3
- package/core/server/services/custom-redirects/index.js +2 -2
- package/core/server/services/donations/{DonationBookshelfRepository.ts → donation-bookshelf-repository.ts} +1 -1
- package/core/server/services/donations/{DonationServiceWrapper.js → donation-service-wrapper.js} +1 -1
- package/core/server/services/donations/index.js +1 -1
- package/core/server/services/email-address/{EmailAddressServiceWrapper.js → email-address-service-wrapper.js} +2 -2
- package/core/server/services/email-address/{EmailAddressService.js → email-address-service.js} +4 -4
- package/core/server/services/email-address/{EmailAddressService.ts → email-address-service.ts} +1 -1
- package/core/server/services/email-address/index.js +1 -1
- package/core/server/services/email-analytics/{EmailAnalyticsProviderMailgun.js → email-analytics-provider-mailgun.js} +1 -1
- package/core/server/services/email-analytics/{EmailAnalyticsServiceWrapper.js → email-analytics-service-wrapper.js} +5 -5
- package/core/server/services/email-analytics/{EmailAnalyticsService.js → email-analytics-service.js} +2 -2
- package/core/server/services/email-analytics/index.js +1 -1
- package/core/server/services/email-analytics/jobs/fetch-latest/index.js +1 -1
- package/core/server/services/email-service/{BatchSendingService.js → batch-sending-service.js} +8 -8
- package/core/server/services/email-service/{EmailEventProcessor.js → email-event-processor.js} +6 -6
- package/core/server/services/email-service/{EmailEventStorage.js → email-event-storage.js} +1 -1
- package/core/server/services/email-service/{EmailRenderer.js → email-renderer.js} +1 -1
- package/core/server/services/email-service/{EmailServiceWrapper.js → email-service-wrapper.js} +9 -9
- package/core/server/services/email-service/{EmailService.js → email-service.js} +13 -13
- package/core/server/services/email-service/index.js +1 -1
- package/core/server/services/email-service/{MailgunEmailProvider.js → mailgun-email-provider.js} +1 -1
- package/core/server/services/email-service/{SendingService.js → sending-service.js} +6 -6
- package/core/server/services/email-suppression-list/{InMemoryEmailSuppressionList.js → in-memory-email-suppression-list.js} +1 -1
- package/core/server/services/email-suppression-list/{MailgunEmailSuppressionList.js → mailgun-email-suppression-list.js} +3 -3
- package/core/server/services/email-suppression-list/service.js +2 -2
- package/core/server/services/explore/index.js +2 -2
- package/core/server/services/explore-ping/index.js +2 -2
- package/core/server/services/frontend-data-service/index.js +1 -1
- package/core/server/services/identity-tokens/{IdentityTokenServiceWrapper.js → identity-token-service-wrapper.js} +1 -1
- package/core/server/services/identity-tokens/index.js +1 -1
- package/core/server/services/indexnow.js +212 -0
- package/core/server/services/invites/index.js +1 -1
- package/core/server/services/link-redirection/index.js +2 -2
- package/core/server/services/link-redirection/{LinkRedirectRepository.js → link-redirect-repository.js} +1 -1
- package/core/server/services/link-redirection/{LinkRedirectsService.js → link-redirects-service.js} +2 -2
- package/core/server/services/link-redirection/{RedirectEvent.js → redirect-event.js} +1 -1
- package/core/server/services/link-tracking/index.js +3 -3
- package/core/server/services/link-tracking/{LinkClickRepository.js → link-click-repository.js} +1 -1
- package/core/server/services/link-tracking/{LinkClickTrackingService.js → link-click-tracking-service.js} +4 -4
- package/core/server/services/link-tracking/{PostLinkRepository.js → post-link-repository.js} +7 -7
- package/core/server/services/mail/{GhostMailer.js → ghost-mailer.js} +1 -1
- package/core/server/services/mail/index.js +2 -2
- package/core/server/services/media-inliner/service.js +1 -1
- package/core/server/services/member-attribution/README.md +6 -6
- package/core/server/services/member-attribution/{AttributionBuilder.js → attribution-builder.js} +4 -4
- package/core/server/services/member-attribution/index.js +5 -5
- package/core/server/services/member-attribution/{MemberAttributionService.js → member-attribution-service.js} +9 -9
- package/core/server/services/member-attribution/{ReferrerTranslator.js → referrer-translator.js} +1 -1
- package/core/server/services/member-attribution/{UrlTranslator.js → url-translator.js} +1 -1
- package/core/server/services/member-welcome-emails/constants.js +22 -1
- package/core/server/services/member-welcome-emails/service.js +23 -5
- package/core/server/services/members/api.js +1 -1
- package/core/server/services/members/importer/index.js +3 -3
- package/core/server/services/members/importer/{MembersCSVImporter.js → members-csv-importer.js} +2 -2
- package/core/server/services/members/members-api/members-api.js +14 -14
- package/core/server/services/members/members-api/repositories/{MemberRepository.js → member-repository.js} +17 -8
- package/core/server/services/members/members-api/services/{MemberBREADService.js → member-bread-service.js} +1 -1
- package/core/server/services/members/members-api/services/{PaymentsService.js → payments-service.js} +12 -12
- package/core/server/services/members/service.js +4 -4
- package/core/server/services/members-events/index.js +3 -3
- package/core/server/services/members-events/{LastSeenAtUpdater.js → last-seen-at-updater.js} +2 -2
- package/core/server/services/mentions/{BookshelfMentionRepository.js → bookshelf-mention-repository.js} +9 -9
- package/core/server/services/mentions/{InMemoryMentionRepository.js → in-memory-mention-repository.js} +4 -4
- package/core/server/services/mentions/{MentionController.js → mention-controller.js} +5 -5
- package/core/server/services/mentions/{MentionCreatedEvent.js → mention-created-event.js} +1 -1
- package/core/server/services/mentions/{Mention.js → mention.js} +1 -1
- package/core/server/services/mentions/{MentionsAPI.js → mentions-api.js} +1 -1
- package/core/server/services/mentions/{ResourceService.js → resource-service.js} +2 -2
- package/core/server/services/mentions/{RoutingService.js → routing-service.js} +2 -2
- package/core/server/services/mentions/service.js +11 -11
- package/core/server/services/mentions/{WebmentionMetadata.js → webmention-metadata.js} +1 -1
- package/core/server/services/mentions-email-report/job.js +1 -1
- package/core/server/services/mentions-email-report/{MentionEmailReportJob.js → mention-email-report-job.js} +1 -1
- package/core/server/services/mentions-email-report/service.js +2 -2
- package/core/server/services/milestones/{BookshelfMilestoneRepository.js → bookshelf-milestone-repository.js} +2 -2
- package/core/server/services/milestones/{InMemoryMilestoneRepository.js → in-memory-milestone-repository.js} +2 -2
- package/core/server/services/milestones/{Milestone.js → milestone.js} +1 -1
- package/core/server/services/milestones/{MilestonesService.js → milestones-service.js} +1 -1
- package/core/server/services/milestones/service.js +4 -4
- package/core/server/services/newsletters/index.js +2 -2
- package/core/server/services/newsletters/{NewslettersService.js → newsletters-service.js} +1 -1
- package/core/server/services/notifications/index.js +1 -1
- package/core/server/services/oembed/service.js +3 -3
- package/core/server/services/offers/application/{OfferMapper.js → offer-mapper.js} +1 -1
- package/core/server/services/offers/application/{OffersAPI.js → offers-api.js} +9 -9
- package/core/server/services/offers/application/{UniqueChecker.js → unique-checker.js} +2 -2
- package/core/server/services/offers/domain/events/{OfferCodeChangeEvent.js → offer-code-change-event.js} +1 -1
- package/core/server/services/offers/domain/events/{OfferCreatedEvent.js → offer-created-event.js} +1 -1
- package/core/server/services/offers/domain/models/{OfferAmount.js → offer-amount.js} +1 -1
- package/core/server/services/offers/domain/models/{OfferCadence.js → offer-cadence.js} +1 -1
- package/core/server/services/offers/domain/models/{OfferCode.js → offer-code.js} +1 -1
- package/core/server/services/offers/domain/models/{OfferCreatedAt.js → offer-created-at.js} +1 -1
- package/core/server/services/offers/domain/models/{OfferCurrency.js → offer-currency.js} +1 -1
- package/core/server/services/offers/domain/models/{OfferDescription.js → offer-description.js} +1 -1
- package/core/server/services/offers/domain/models/{OfferDuration.js → offer-duration.js} +1 -1
- package/core/server/services/offers/domain/models/{OfferName.js → offer-name.js} +1 -1
- package/core/server/services/offers/domain/models/{OfferStatus.js → offer-status.js} +1 -1
- package/core/server/services/offers/domain/models/{OfferTitle.js → offer-title.js} +1 -1
- package/core/server/services/offers/domain/models/{OfferType.js → offer-type.js} +1 -1
- package/core/server/services/offers/domain/models/{Offer.js → offer.js} +14 -14
- package/core/server/services/offers/domain/models/{StripeCoupon.js → stripe-coupon.js} +1 -1
- package/core/server/services/offers/{OfferBookshelfRepository.js → offer-bookshelf-repository.js} +6 -6
- package/core/server/services/offers/{OffersModule.js → offers-module.js} +4 -4
- package/core/server/services/offers/service.js +3 -3
- package/core/server/services/outbox/index.js +2 -2
- package/core/server/services/outbox/jobs/outbox-job.js +2 -2
- package/core/server/services/posts/posts-service-instance.js +47 -0
- package/core/server/services/posts/posts-service.js +572 -45
- package/core/server/services/recommendations/index.js +1 -1
- package/core/server/services/recommendations/{RecommendationEnablerService.js → recommendation-enabler-service.js} +2 -2
- package/core/server/services/recommendations/{RecommendationServiceWrapper.js → recommendation-service-wrapper.js} +2 -2
- package/core/server/services/recommendations/service/{BookshelfClickEventRepository.js → bookshelf-click-event-repository.js} +4 -4
- package/core/server/services/recommendations/service/{BookshelfClickEventRepository.ts → bookshelf-click-event-repository.ts} +2 -2
- package/core/server/services/recommendations/service/{BookshelfRecommendationRepository.js → bookshelf-recommendation-repository.js} +4 -4
- package/core/server/services/recommendations/service/{BookshelfRecommendationRepository.ts → bookshelf-recommendation-repository.ts} +3 -3
- package/core/server/services/recommendations/service/{BookshelfSubscribeEventRepository.js → bookshelf-subscribe-event-repository.js} +4 -4
- package/core/server/services/recommendations/service/{BookshelfSubscribeEventRepository.ts → bookshelf-subscribe-event-repository.ts} +2 -2
- package/core/server/services/recommendations/service/{InMemoryRecommendationRepository.js → in-memory-recommendation-repository.js} +2 -2
- package/core/server/services/recommendations/service/{InMemoryRecommendationRepository.ts → in-memory-recommendation-repository.ts} +3 -3
- package/core/server/services/recommendations/service/{IncomingRecommendationController.js → incoming-recommendation-controller.js} +2 -2
- package/core/server/services/recommendations/service/{IncomingRecommendationController.ts → incoming-recommendation-controller.ts} +3 -3
- package/core/server/services/recommendations/service/{IncomingRecommendationEmailRenderer.ts → incoming-recommendation-email-renderer.ts} +2 -2
- package/core/server/services/recommendations/service/{IncomingRecommendationService.ts → incoming-recommendation-service.ts} +2 -2
- package/core/server/services/recommendations/service/index.js +15 -15
- package/core/server/services/recommendations/service/index.ts +15 -15
- package/core/server/services/recommendations/service/{RecommendationController.js → recommendation-controller.js} +13 -13
- package/core/server/services/recommendations/service/{RecommendationController.ts → recommendation-controller.ts} +4 -4
- package/core/server/services/recommendations/service/{RecommendationRepository.ts → recommendation-repository.ts} +3 -3
- package/core/server/services/recommendations/service/{RecommendationService.js → recommendation-service.js} +6 -6
- package/core/server/services/recommendations/service/{RecommendationService.ts → recommendation-service.ts} +8 -8
- package/core/server/services/recommendations/service/{Recommendation.js → recommendation.js} +4 -4
- package/core/server/services/recommendations/service/{Recommendation.ts → recommendation.ts} +1 -1
- package/core/server/services/recommendations/service/{WellknownService.ts → well-known-service.ts} +1 -1
- package/core/server/services/route-settings/index.js +4 -4
- package/core/server/services/settings/{SettingsBREADService.js → settings-bread-service.js} +1 -1
- package/core/server/services/settings/settings-service.js +2 -2
- package/core/server/services/settings-helpers/index.js +1 -1
- package/core/server/services/settings-helpers/{SettingsHelpers.js → settings-helpers.js} +5 -5
- package/core/server/services/slack-notifications/service.js +4 -4
- package/core/server/services/slack-notifications/{SlackNotificationsService.js → slack-notifications-service.js} +2 -2
- package/core/server/services/slack-notifications/{SlackNotifications.js → slack-notifications.js} +2 -2
- package/core/server/services/staff/index.js +1 -1
- package/core/server/services/staff/{StaffServiceEmails.js → staff-service-emails.js} +2 -2
- package/core/server/services/staff/{StaffService.js → staff-service.js} +2 -2
- package/core/server/services/stats/{PostsStatsService.js → posts-stats-service.js} +25 -25
- package/core/server/services/stats/{ReferrersStatsService.js → referrers-stats-service.js} +3 -3
- package/core/server/services/stats/service.js +1 -1
- package/core/server/services/stats/{StatsService.js → stats-service.js} +23 -23
- package/core/server/services/stripe/events/index.js +2 -2
- package/core/server/services/stripe/service.js +1 -1
- package/core/server/services/stripe/services/webhook/{CheckoutSessionEventService.js → checkout-session-event-service.js} +2 -2
- package/core/server/services/stripe/{StripeMigrations.js → stripe-migrations.js} +1 -1
- package/core/server/services/stripe/{StripeService.js → stripe-service.js} +8 -8
- package/core/server/services/stripe/{WebhookController.js → webhook-controller.js} +4 -4
- package/core/server/services/stripe/{WebhookManager.js → webhook-manager.js} +5 -5
- package/core/server/services/themes/storage.js +1 -1
- package/core/server/services/tiers/{InMemoryTierRepository.js → in-memory-tier-repository.js} +1 -1
- package/core/server/services/tiers/service.js +2 -2
- package/core/server/services/tiers/{TierActivatedEvent.js → tier-activated-event.js} +1 -1
- package/core/server/services/tiers/{TierArchivedEvent.js → tier-archived-event.js} +1 -1
- package/core/server/services/tiers/{TierCreatedEvent.js → tier-created-event.js} +1 -1
- package/core/server/services/tiers/{TierNameChangeEvent.js → tier-name-change-event.js} +1 -1
- package/core/server/services/tiers/{TierPriceChangeEvent.js → tier-price-change-event.js} +1 -1
- package/core/server/services/tiers/{TierRepository.js → tier-repository.js} +7 -7
- package/core/server/services/tiers/{Tier.js → tier.js} +5 -5
- package/core/server/services/tiers/{TiersAPI.js → tiers-api.js} +1 -1
- package/core/server/services/tinybird/index.js +1 -1
- package/core/server/services/tinybird/{TinybirdServiceWrapper.js → tinybird-service-wrapper.js} +2 -2
- package/core/server/services/update-check/index.js +1 -1
- package/core/server/services/url/index.js +2 -2
- package/core/server/services/url/{Resources.js → resources.js} +1 -1
- package/core/server/services/url/{UrlGenerator.js → url-generator.js} +1 -1
- package/core/server/services/url/{UrlService.js → url-service.js} +4 -4
- package/core/server/services/url/{Urls.js → urls.js} +1 -1
- package/core/server/services/webhooks/listen.js +1 -1
- package/core/shared/labs.js +2 -1
- package/package.json +3 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/components/tryghost-i18n-6.11.0.tgz +0 -0
- package/core/built/admin/assets/index-Cr_YX9yU.js +0 -1
- package/core/built/admin/assets/stats/index-BBCJ2EZo.mjs +0 -733
- package/core/server/services/posts/PostsService.js +0 -574
- /package/core/server/{GhostServer.js → ghost-server.js} +0 -0
- /package/core/server/services/activitypub/{ActivityPubService.js → activity-pub-service.js} +0 -0
- /package/core/server/services/adapter-manager/{AdapterManager.js → adapter-manager.js} +0 -0
- /package/core/server/services/announcement-bar-service/{AnnouncementVisibilityValues.js → announcement-visibility-values.js} +0 -0
- /package/core/server/services/audience-feedback/{AudienceFeedbackService.js → audience-feedback-service.js} +0 -0
- /package/core/server/services/audience-feedback/{FeedbackRepository.js → feedback-repository.js} +0 -0
- /package/core/server/services/audience-feedback/{Feedback.js → feedback.js} +0 -0
- /package/core/server/services/auth/session/{SessionStore.js → session-store.js} +0 -0
- /package/core/server/services/comments/{CommentsServiceEmailRenderer.js → comments-service-email-renderer.js} +0 -0
- /package/core/server/services/comments/{CommentsStatsService.js → comments-stats-service.js} +0 -0
- /package/core/server/services/custom-redirects/{CustomRedirectsAPI.js → custom-redirects-api.js} +0 -0
- /package/core/server/services/donations/{DonationBookshelfRepository.js → donation-bookshelf-repository.js} +0 -0
- /package/core/server/services/donations/{DonationPaymentEvent.js → donation-payment-event.js} +0 -0
- /package/core/server/services/donations/{DonationPaymentEvent.ts → donation-payment-event.ts} +0 -0
- /package/core/server/services/email-address/{EmailAddressParser.js → email-address-parser.js} +0 -0
- /package/core/server/services/email-address/{EmailAddressParser.js.d.ts → email-address-parser.js.d.ts} +0 -0
- /package/core/server/services/email-analytics/{EventProcessingResult.js → event-processing-result.js} +0 -0
- /package/core/server/services/email-analytics/events/{StartEmailAnalyticsJobEvent.js → start-email-analytics-job-event.js} +0 -0
- /package/core/server/services/email-service/{DomainWarmingService.js → domain-warming-service.js} +0 -0
- /package/core/server/services/email-service/{DomainWarmingService.ts → domain-warming-service.ts} +0 -0
- /package/core/server/services/email-service/{EmailBodyCache.js → email-body-cache.js} +0 -0
- /package/core/server/services/email-service/{EmailController.js → email-controller.js} +0 -0
- /package/core/server/services/email-service/{EmailSegmenter.js → email-segmenter.js} +0 -0
- /package/core/server/services/email-service/events/{EmailBouncedEvent.js → email-bounced-event.js} +0 -0
- /package/core/server/services/email-service/events/{EmailDeliveredEvent.js → email-delivered-event.js} +0 -0
- /package/core/server/services/email-service/events/{EmailOpenedEvent.js → email-opened-event.js} +0 -0
- /package/core/server/services/email-service/events/{EmailTemporaryBouncedEvent.js → email-temporary-bounced-event.js} +0 -0
- /package/core/server/services/email-service/events/{EmailUnsubscribedEvent.js → email-unsubscribed-event.js} +0 -0
- /package/core/server/services/email-service/events/{SpamComplaintEvent.js → spam-complaint-event.js} +0 -0
- /package/core/server/services/email-suppression-list/{EmailSuppressionList.js → email-suppression-list.js} +0 -0
- /package/core/server/services/explore/{ExploreService.js → explore-service.js} +0 -0
- /package/core/server/services/explore-ping/{ExplorePingService.js → explore-ping-service.js} +0 -0
- /package/core/server/services/frontend-data-service/{FrontendDataService.js → front-end-data-service.js} +0 -0
- /package/core/server/services/identity-tokens/{IdentityTokenService.js → identity-token-service.js} +0 -0
- /package/core/server/services/identity-tokens/{IdentityTokenService.ts → identity-token-service.ts} +0 -0
- /package/core/server/services/invites/{Invites.js → invites.js} +0 -0
- /package/core/server/services/lib/{DynamicRedirectManager.js → dynamic-redirect-manager.js} +0 -0
- /package/core/server/services/lib/{EmailContentGenerator.js → email-content-generator.js} +0 -0
- /package/core/server/services/lib/{InMemoryRepository.js → in-memory-repository.js} +0 -0
- /package/core/server/services/lib/{InMemoryRepository.ts → in-memory-repository.ts} +0 -0
- /package/core/server/services/lib/magic-link/{MagicLink.js → magic-link.js} +0 -0
- /package/core/server/services/lib/{MailgunClient.js → mailgun-client.js} +0 -0
- /package/core/server/services/link-redirection/{LinkRedirect.js → link-redirect.js} +0 -0
- /package/core/server/services/link-tracking/{ClickEvent.js → click-event.js} +0 -0
- /package/core/server/services/link-tracking/{FullPostLink.js → full-post-link.js} +0 -0
- /package/core/server/services/link-tracking/{PostLink.js → post-link.js} +0 -0
- /package/core/server/services/media-inliner/{ExternalMediaInliner.js → external-media-inliner.js} +0 -0
- /package/core/server/services/member-attribution/{OutboundLinkTagger.js → outbound-link-tagger.js} +0 -0
- /package/core/server/services/member-attribution/{UrlHistory.js → url-history.js} +0 -0
- /package/core/server/services/member-welcome-emails/{MemberWelcomeEmailRenderer.js → member-welcome-email-renderer.js} +0 -0
- /package/core/server/services/members/importer/{MembersCSVImporterStripeUtils.js → members-csv-importer-stripe-utils.js} +0 -0
- /package/core/server/services/members/members-api/controllers/{MemberController.js → member-controller.js} +0 -0
- /package/core/server/services/members/members-api/controllers/{RouterController.js → router-controller.js} +0 -0
- /package/core/server/services/members/members-api/controllers/{WellKnownController.js → well-known-controller.js} +0 -0
- /package/core/server/services/members/members-api/repositories/{EventRepository.js → event-repository.js} +0 -0
- /package/core/server/services/members/members-api/repositories/{ProductRepository.js → product-repository.js} +0 -0
- /package/core/server/services/members/members-api/services/{GeolocationService.js → geolocation-service.js} +0 -0
- /package/core/server/services/members/members-api/services/{TokenService.js → token-service.js} +0 -0
- /package/core/server/services/members/{MembersConfigProvider.js → members-config-provider.js} +0 -0
- /package/core/server/services/members/{RequestIntegrityTokenProvider.js → request-integrity-token-provider.js} +0 -0
- /package/core/server/services/members/{SingleUseTokenProvider.js → single-use-token-provider.js} +0 -0
- /package/core/server/services/members/stats/{MembersStats.js → members-stats.js} +0 -0
- /package/core/server/services/members-events/{EventStorage.js → event-storage.js} +0 -0
- /package/core/server/services/members-events/{LastSeenAtCache.js → last-seen-at-cache.js} +0 -0
- /package/core/server/services/mentions/{MentionDiscoveryService.js → mention-discovery-service.js} +0 -0
- /package/core/server/services/mentions/{MentionSendingService.js → mention-sending-service.js} +0 -0
- /package/core/server/services/mentions-email-report/{StartMentionEmailReportJob.js → start-mention-email-report-job.js} +0 -0
- /package/core/server/services/milestones/{MilestoneCreatedEvent.js → milestone-created-event.js} +0 -0
- /package/core/server/services/milestones/{MilestoneQueries.js → milestone-queries.js} +0 -0
- /package/core/server/services/notifications/{Notifications.js → notifications.js} +0 -0
- /package/core/server/services/oembed/{NFTOEmbedProvider.js → nft-oembed-provider.js} +0 -0
- /package/core/server/services/oembed/{OEmbedService.js → oembed-service.js} +0 -0
- /package/core/server/services/oembed/{TwitterOEmbedProvider.js → twitter-oembed-provider.js} +0 -0
- /package/core/server/services/offers/domain/models/shared/{ValueObject.js → value-object.js} +0 -0
- /package/core/server/services/outbox/events/{StartOutboxProcessingEvent.js → start-outbox-processing-event.js} +0 -0
- /package/core/server/services/posts/{PostsExporter.js → posts-exporter.js} +0 -0
- /package/core/server/services/posts/stats/{PostStats.js → post-stats.js} +0 -0
- /package/core/server/services/recommendations/service/{BookshelfRepository.js → bookshelf-repository.js} +0 -0
- /package/core/server/services/recommendations/service/{BookshelfRepository.ts → bookshelf-repository.ts} +0 -0
- /package/core/server/services/recommendations/service/{ClickEvent.js → click-event.js} +0 -0
- /package/core/server/services/recommendations/service/{ClickEvent.ts → click-event.ts} +0 -0
- /package/core/server/services/recommendations/service/{IncomingRecommendationEmailRenderer.js → incoming-recommendation-email-renderer.js} +0 -0
- /package/core/server/services/recommendations/service/{IncomingRecommendationService.js → incoming-recommendation-service.js} +0 -0
- /package/core/server/services/recommendations/service/{RecommendationMetadataService.js → recommendation-metadata-service.js} +0 -0
- /package/core/server/services/recommendations/service/{RecommendationMetadataService.ts → recommendation-metadata-service.ts} +0 -0
- /package/core/server/services/recommendations/service/{RecommendationRepository.js → recommendation-repository.js} +0 -0
- /package/core/server/services/recommendations/service/{SubscribeEvent.js → subscribe-event.js} +0 -0
- /package/core/server/services/recommendations/service/{SubscribeEvent.ts → subscribe-event.ts} +0 -0
- /package/core/server/services/recommendations/service/{UnsafeData.js → unsafe-data.js} +0 -0
- /package/core/server/services/recommendations/service/{UnsafeData.ts → unsafe-data.ts} +0 -0
- /package/core/server/services/recommendations/service/{WellknownService.js → well-known-service.js} +0 -0
- /package/core/server/services/route-settings/{DefaultSettingsManager.js → default-settings-manager.js} +0 -0
- /package/core/server/services/route-settings/{RouteSettings.js → route-settings.js} +0 -0
- /package/core/server/services/route-settings/{SettingsLoader.js → settings-loader.js} +0 -0
- /package/core/server/services/route-settings/{SettingsPathManager.js → settings-path-manager.js} +0 -0
- /package/core/server/services/stats/{ContentStatsService.js → content-stats-service.js} +0 -0
- /package/core/server/services/stats/{MembersStatsService.js → members-stats-service.js} +0 -0
- /package/core/server/services/stats/{MrrStatsService.js → mrr-stats-service.js} +0 -0
- /package/core/server/services/stats/{SubscriptionStatsService.js → subscription-stats-service.js} +0 -0
- /package/core/server/services/stripe/events/{StripeLiveDisabledEvent.js → stripe-live-disabled-event.js} +0 -0
- /package/core/server/services/stripe/events/{StripeLiveEnabledEvent.js → stripe-live-enabled-event.js} +0 -0
- /package/core/server/services/stripe/services/webhook/{InvoiceEventService.js → invoice-event-service.js} +0 -0
- /package/core/server/services/stripe/services/webhook/{SubscriptionEventService.js → subscription-event-service.js} +0 -0
- /package/core/server/services/stripe/{StripeAPI.js → stripe-api.js} +0 -0
- /package/core/server/services/themes/{ThemeStorage.js → theme-storage.js} +0 -0
- /package/core/server/services/tinybird/{TinybirdService.js → tinybird-service.js} +0 -0
- /package/core/server/services/update-check/{UpdateCheckService.js → update-check-service.js} +0 -0
- /package/core/server/services/url/{LocalFileCache.js → local-file-cache.js} +0 -0
- /package/core/server/services/url/{Queue.js → queue.js} +0 -0
- /package/core/server/services/url/{Resource.js → resource.js} +0 -0
- /package/core/server/services/{Users.js → users.js} +0 -0
- /package/core/server/services/{VerificationTrigger.js → verification-trigger.js} +0 -0
- /package/core/server/services/webhooks/{WebhookTrigger.js → webhook-trigger.js} +0 -0
|
@@ -40,26 +40,26 @@ graph TD
|
|
|
40
40
|
|
|
41
41
|
### Components
|
|
42
42
|
|
|
43
|
-
#### 1. **MemberAttributionService** (`
|
|
43
|
+
#### 1. **MemberAttributionService** (`member-attribution-service.js`)
|
|
44
44
|
Main service interface that coordinates all attribution logic.
|
|
45
45
|
|
|
46
|
-
#### 2. **AttributionBuilder** (`
|
|
46
|
+
#### 2. **AttributionBuilder** (`attribution-builder.js`)
|
|
47
47
|
Converts URL history into attribution resources using the "Last Post Algorithm™️".
|
|
48
48
|
|
|
49
49
|
**Key Classes:**
|
|
50
50
|
- `Attribution`: Represents attribution data with methods to fetch and enrich resources
|
|
51
51
|
- `AttributionBuilder`: Factory for creating `Attribution` instances
|
|
52
52
|
|
|
53
|
-
#### 3. **UrlHistory** (`
|
|
53
|
+
#### 3. **UrlHistory** (`url-history.js`)
|
|
54
54
|
Validated container for URL history arrays from the frontend.
|
|
55
55
|
|
|
56
|
-
#### 4. **UrlTranslator** (`
|
|
56
|
+
#### 4. **UrlTranslator** (`url-translator.js`)
|
|
57
57
|
Translates between URLs and Ghost resources.
|
|
58
58
|
|
|
59
|
-
#### 5. **ReferrerTranslator** (`
|
|
59
|
+
#### 5. **ReferrerTranslator** (`referrer-translator.js`)
|
|
60
60
|
Parses referrer information into source and medium classifications.
|
|
61
61
|
|
|
62
|
-
#### 6. **OutboundLinkTagger** (`
|
|
62
|
+
#### 6. **OutboundLinkTagger** (`outbound-link-tagger.js`)
|
|
63
63
|
Adds `?ref=` parameters to external links in newsletters.
|
|
64
64
|
|
|
65
65
|
#### 7. **Frontend Script** (`member-attribution.js`)
|
package/core/server/services/member-attribution/{AttributionBuilder.js → attribution-builder.js}
RENAMED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
class Attribution {
|
|
18
|
-
/** @type {import('./
|
|
18
|
+
/** @type {import('./url-translator')} */
|
|
19
19
|
#urlTranslator;
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -133,9 +133,9 @@ class Attribution {
|
|
|
133
133
|
* Convert a UrlHistory to an attribution object
|
|
134
134
|
*/
|
|
135
135
|
class AttributionBuilder {
|
|
136
|
-
/** @type {import('./
|
|
136
|
+
/** @type {import('./url-translator')} */
|
|
137
137
|
urlTranslator;
|
|
138
|
-
/** @type {import('./
|
|
138
|
+
/** @type {import('./referrer-translator')} */
|
|
139
139
|
referrerTranslator;
|
|
140
140
|
|
|
141
141
|
/**
|
|
@@ -166,7 +166,7 @@ class AttributionBuilder {
|
|
|
166
166
|
|
|
167
167
|
/**
|
|
168
168
|
* Last Post Algorithm™️
|
|
169
|
-
* @param {import('./
|
|
169
|
+
* @param {import('./url-history').UrlHistoryArray} history
|
|
170
170
|
* @returns {Promise<Attribution>}
|
|
171
171
|
*/
|
|
172
172
|
async getAttribution(history) {
|
|
@@ -11,11 +11,11 @@ class MemberAttributionServiceWrapper {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
// Wire up all the dependencies
|
|
14
|
-
const MemberAttributionService = require('./
|
|
15
|
-
const UrlTranslator = require('./
|
|
16
|
-
const ReferrerTranslator = require('./
|
|
17
|
-
const AttributionBuilder = require('./
|
|
18
|
-
const OutboundLinkTagger = require('./
|
|
14
|
+
const MemberAttributionService = require('./member-attribution-service');
|
|
15
|
+
const UrlTranslator = require('./url-translator');
|
|
16
|
+
const ReferrerTranslator = require('./referrer-translator');
|
|
17
|
+
const AttributionBuilder = require('./attribution-builder');
|
|
18
|
+
const OutboundLinkTagger = require('./outbound-link-tagger');
|
|
19
19
|
const models = require('../../models');
|
|
20
20
|
|
|
21
21
|
const urlTranslator = new UrlTranslator({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const UrlHistory = require('./
|
|
1
|
+
const UrlHistory = require('./url-history');
|
|
2
2
|
|
|
3
3
|
class MemberAttributionService {
|
|
4
4
|
/**
|
|
@@ -23,7 +23,7 @@ class MemberAttributionService {
|
|
|
23
23
|
/**
|
|
24
24
|
*
|
|
25
25
|
* @param {Object} context instance of ghost framework context object
|
|
26
|
-
* @returns {Promise<import('./
|
|
26
|
+
* @returns {Promise<import('./attribution-builder').AttributionResource|null>}
|
|
27
27
|
*/
|
|
28
28
|
async getAttributionFromContext(context) {
|
|
29
29
|
if (!context || !this.isTrackingEnabled) {
|
|
@@ -70,8 +70,8 @@ class MemberAttributionService {
|
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
72
|
*
|
|
73
|
-
* @param {import('./
|
|
74
|
-
* @returns {Promise<import('./
|
|
73
|
+
* @param {import('./url-history').UrlHistoryArray} historyArray
|
|
74
|
+
* @returns {Promise<import('./attribution-builder').Attribution>}
|
|
75
75
|
*/
|
|
76
76
|
async getAttribution(historyArray) {
|
|
77
77
|
let history = UrlHistory.create(historyArray);
|
|
@@ -107,7 +107,7 @@ class MemberAttributionService {
|
|
|
107
107
|
* Returns the attribution resource for a given event model (MemberCreatedEvent / SubscriptionCreatedEvent), where the model has the required relations already loaded
|
|
108
108
|
* You need to already load the 'postAttribution', 'userAttribution', and 'tagAttribution' relations
|
|
109
109
|
* @param {Object} eventModel MemberCreatedEvent or SubscriptionCreatedEvent
|
|
110
|
-
* @returns {import('./
|
|
110
|
+
* @returns {import('./attribution-builder').AttributionResource|null}
|
|
111
111
|
*/
|
|
112
112
|
getEventAttribution(eventModel) {
|
|
113
113
|
const _attribution = this.attributionBuilder.build({
|
|
@@ -139,7 +139,7 @@ class MemberAttributionService {
|
|
|
139
139
|
/**
|
|
140
140
|
* Returns the parsed attribution for a member creation event
|
|
141
141
|
* @param {string} memberId
|
|
142
|
-
* @returns {Promise<import('./
|
|
142
|
+
* @returns {Promise<import('./attribution-builder').AttributionResource|null>}
|
|
143
143
|
*/
|
|
144
144
|
async getMemberCreatedAttribution(memberId) {
|
|
145
145
|
const memberCreatedEvent = await this.models.MemberCreatedEvent.findOne({member_id: memberId}, {require: false, withRelated: []});
|
|
@@ -160,7 +160,7 @@ class MemberAttributionService {
|
|
|
160
160
|
/**
|
|
161
161
|
* Returns the last attribution for a given subscription ID
|
|
162
162
|
* @param {string} subscriptionId
|
|
163
|
-
* @returns {Promise<import('./
|
|
163
|
+
* @returns {Promise<import('./attribution-builder').AttributionResource|null>}
|
|
164
164
|
*/
|
|
165
165
|
async getSubscriptionCreatedAttribution(subscriptionId) {
|
|
166
166
|
const subscriptionCreatedEvent = await this.models.SubscriptionCreatedEvent.findOne({subscription_id: subscriptionId}, {require: false, withRelated: []});
|
|
@@ -180,8 +180,8 @@ class MemberAttributionService {
|
|
|
180
180
|
|
|
181
181
|
/**
|
|
182
182
|
* Fetches the resource for a given attribution without the use of an event model
|
|
183
|
-
* @param {Object} attribution
|
|
184
|
-
* @returns {Promise<import('./
|
|
183
|
+
* @param {Object} attribution
|
|
184
|
+
* @returns {Promise<import('./attribution-builder').AttributionResource|null>}
|
|
185
185
|
*/
|
|
186
186
|
async fetchResource(attribution) {
|
|
187
187
|
if (!attribution) {
|
package/core/server/services/member-attribution/{ReferrerTranslator.js → referrer-translator.js}
RENAMED
|
@@ -32,7 +32,7 @@ class ReferrerTranslator {
|
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Calculate referrer details from history
|
|
35
|
-
* @param {import('./
|
|
35
|
+
* @param {import('./url-history').UrlHistoryArray} history
|
|
36
36
|
* @returns {ReferrerData|null}
|
|
37
37
|
*/
|
|
38
38
|
getReferrerDetails(history) {
|
|
@@ -54,7 +54,7 @@ class UrlTranslator {
|
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* Get the resource type and ID from a URLHistory item that was added by the frontend attribution script
|
|
57
|
-
* @param {import('./
|
|
57
|
+
* @param {import('./url-history').UrlHistoryItem} item
|
|
58
58
|
* @returns {Promise<{type: string, id: string | null, url: string}|null>} Returns null if the item is invalid
|
|
59
59
|
*/
|
|
60
60
|
async getResourceDetails(item) {
|
|
@@ -14,8 +14,29 @@ const MESSAGES = {
|
|
|
14
14
|
memberWelcomeEmailInactive: memberStatus => `Member welcome email for "${memberStatus}" members is inactive`
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
// Default welcome email content in Lexical JSON format
|
|
18
|
+
// Uses __GHOST_URL__ placeholder which Ghost replaces with the actual site URL
|
|
19
|
+
// These match the defaults used in the admin UI (apps/admin-x-settings/src/components/settings/membership/member-emails.tsx)
|
|
20
|
+
const DEFAULT_FREE_LEXICAL_CONTENT = '{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Welcome! Thanks for subscribing — it\'s great to have you here.","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"You\'ll now receive new posts straight to your inbox. You can also log in any time to read the ","type":"extended-text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"full archive","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":"noreferrer","target":null,"title":null,"url":"__GHOST_URL__/"},{"detail":0,"format":0,"mode":"normal","style":"","text":" or catch up on new posts as they go live.","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"A little housekeeping: If this email landed in spam or promotions, try moving it to your primary inbox and adding this address to your contacts. Small signals like that help your inbox recognize that these messages matter to you.","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Have questions or just want to say hi? Feel free to reply directly to this email or any newsletter in the future.","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}';
|
|
21
|
+
|
|
22
|
+
const DEFAULT_PAID_LEXICAL_CONTENT = '{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Welcome, and thank you for your support — it means a lot.","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"As a paid member, you now have full access to everything: the complete archive, and any paid-only content going forward. New posts will land straight to your inbox, and you can log in any time to ","type":"extended-text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"catch up","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":"noreferrer","target":null,"title":null,"url":"__GHOST_URL__/"},{"detail":0,"format":0,"mode":"normal","style":"","text":" on anything you\'ve missed.","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"A little housekeeping: If this email landed in spam or promotions, try moving it to your primary inbox and adding this address to your contacts. Small signals like that help your inbox recognize that these messages matter to you.","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Have questions or just want to say hi? Feel free to reply directly to this email or any newsletter in the future.","type":"extended-text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}';
|
|
23
|
+
|
|
24
|
+
const DEFAULT_WELCOME_EMAILS = {
|
|
25
|
+
free: {
|
|
26
|
+
lexical: DEFAULT_FREE_LEXICAL_CONTENT,
|
|
27
|
+
subject: 'Welcome to {{site.title}}',
|
|
28
|
+
status: 'active'
|
|
29
|
+
},
|
|
30
|
+
paid: {
|
|
31
|
+
lexical: DEFAULT_PAID_LEXICAL_CONTENT,
|
|
32
|
+
subject: 'Welcome to your paid subscription',
|
|
33
|
+
status: 'active'
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
17
37
|
module.exports = {
|
|
18
38
|
MEMBER_WELCOME_EMAIL_LOG_KEY,
|
|
19
39
|
MEMBER_WELCOME_EMAIL_SLUGS,
|
|
20
|
-
MESSAGES
|
|
40
|
+
MESSAGES,
|
|
41
|
+
DEFAULT_WELCOME_EMAILS
|
|
21
42
|
};
|
|
@@ -7,8 +7,8 @@ const emailAddressService = require('../email-address');
|
|
|
7
7
|
const mail = require('../mail');
|
|
8
8
|
// @ts-expect-error type checker has trouble with the dynamic exporting in models
|
|
9
9
|
const {AutomatedEmail} = require('../../models');
|
|
10
|
-
const MemberWelcomeEmailRenderer = require('./
|
|
11
|
-
const {MEMBER_WELCOME_EMAIL_LOG_KEY, MEMBER_WELCOME_EMAIL_SLUGS, MESSAGES} = require('./constants');
|
|
10
|
+
const MemberWelcomeEmailRenderer = require('./member-welcome-email-renderer');
|
|
11
|
+
const {MEMBER_WELCOME_EMAIL_LOG_KEY, MEMBER_WELCOME_EMAIL_SLUGS, MESSAGES, DEFAULT_WELCOME_EMAILS} = require('./constants');
|
|
12
12
|
|
|
13
13
|
class MemberWelcomeEmailService {
|
|
14
14
|
#mailer;
|
|
@@ -30,14 +30,32 @@ class MemberWelcomeEmailService {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
async loadMemberWelcomeEmails() {
|
|
33
|
+
const useDefaults = Boolean(config.get('memberWelcomeEmailTestInbox'));
|
|
34
|
+
|
|
33
35
|
for (const [memberStatus, slug] of Object.entries(MEMBER_WELCOME_EMAIL_SLUGS)) {
|
|
34
36
|
const row = await AutomatedEmail.findOne({slug});
|
|
35
37
|
|
|
36
|
-
if (!row
|
|
38
|
+
if (!row) {
|
|
39
|
+
// No row - use default template when test inbox is configured
|
|
40
|
+
if (useDefaults) {
|
|
41
|
+
const defaultEmail = DEFAULT_WELCOME_EMAILS[memberStatus];
|
|
42
|
+
this.#memberWelcomeEmails[memberStatus] = {
|
|
43
|
+
...defaultEmail,
|
|
44
|
+
lexical: urlUtils.transformReadyToAbsolute(defaultEmail.lexical)
|
|
45
|
+
};
|
|
46
|
+
} else {
|
|
47
|
+
this.#memberWelcomeEmails[memberStatus] = null;
|
|
48
|
+
}
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Row exists - check if it has content
|
|
53
|
+
if (!row.get('lexical')) {
|
|
37
54
|
this.#memberWelcomeEmails[memberStatus] = null;
|
|
38
55
|
continue;
|
|
39
56
|
}
|
|
40
57
|
|
|
58
|
+
// Use DB template (status check happens in send())
|
|
41
59
|
this.#memberWelcomeEmails[memberStatus] = {
|
|
42
60
|
lexical: row.get('lexical'),
|
|
43
61
|
subject: row.get('subject'),
|
|
@@ -99,7 +117,7 @@ class MemberWelcomeEmailService {
|
|
|
99
117
|
if (!slug) {
|
|
100
118
|
return false;
|
|
101
119
|
}
|
|
102
|
-
|
|
120
|
+
|
|
103
121
|
const row = await AutomatedEmail.findOne({slug});
|
|
104
122
|
return Boolean(row && row.get('lexical') && row.get('status') === 'active');
|
|
105
123
|
}
|
|
@@ -119,7 +137,7 @@ class MemberWelcomeEmailService {
|
|
|
119
137
|
message: MESSAGES.MISSING_EMAIL_CONTENT
|
|
120
138
|
});
|
|
121
139
|
}
|
|
122
|
-
|
|
140
|
+
|
|
123
141
|
if (!subject) {
|
|
124
142
|
throw new errors.ValidationError({
|
|
125
143
|
message: MESSAGES.MISSING_EMAIL_SUBJECT
|
|
@@ -10,7 +10,7 @@ const signupEmail = require('./emails/signup');
|
|
|
10
10
|
const signupPaidEmail = require('./emails/signup-paid');
|
|
11
11
|
const subscribeEmail = require('./emails/subscribe');
|
|
12
12
|
const updateEmail = require('./emails/update-email');
|
|
13
|
-
const SingleUseTokenProvider = require('./
|
|
13
|
+
const SingleUseTokenProvider = require('./single-use-token-provider');
|
|
14
14
|
const urlUtils = require('../../../shared/url-utils');
|
|
15
15
|
const labsService = require('../../../shared/labs');
|
|
16
16
|
const offersService = require('../offers');
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const MembersCSVImporter = require('./
|
|
2
|
-
const MembersCSVImporterStripeUtils = require('./
|
|
1
|
+
const MembersCSVImporter = require('./members-csv-importer');
|
|
2
|
+
const MembersCSVImporterStripeUtils = require('./members-csv-importer-stripe-utils');
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @typedef {import('./
|
|
5
|
+
* @typedef {import('./members-csv-importer').MembersCSVImporterOptions} MembersCSVImporterOptions
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
/**
|
package/core/server/services/members/importer/{MembersCSVImporter.js → members-csv-importer.js}
RENAMED
|
@@ -33,8 +33,8 @@ const DEFAULT_CSV_HEADER_MAPPING = {
|
|
|
33
33
|
* @property {string} storagePath - The path to store CSV's in before importing
|
|
34
34
|
* @property {Function} getTimezone - function returning currently configured timezone
|
|
35
35
|
* @property {() => Object} getMembersRepository - member model access instance for data access and manipulation
|
|
36
|
-
* @property {() => Promise<import('../../tiers/
|
|
37
|
-
* @property {(string) => Promise<import('../../tiers/
|
|
36
|
+
* @property {() => Promise<import('../../tiers/tier')>} getDefaultTier - async function returning default Member Tier
|
|
37
|
+
* @property {(string) => Promise<import('../../tiers/tier')>} getTierByName - async function returning Member Tier by name
|
|
38
38
|
* @property {Function} sendEmail - function sending an email
|
|
39
39
|
* @property {(string) => boolean} isSet - Method checking if specific feature is enabled
|
|
40
40
|
* @property {({job, offloaded, name}) => void} addJob - Method registering an async job
|
|
@@ -3,20 +3,20 @@ const body = require('body-parser');
|
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
4
|
const logging = require('@tryghost/logging');
|
|
5
5
|
|
|
6
|
-
const PaymentsService = require('./services/
|
|
7
|
-
const TokenService = require('./services/
|
|
8
|
-
const GeolocationService = require('./services/
|
|
9
|
-
const MemberBREADService = require('./services/
|
|
10
|
-
const MemberRepository = require('./repositories/
|
|
11
|
-
|
|
12
|
-
const EventRepository = require('./repositories/
|
|
13
|
-
const ProductRepository = require('./repositories/
|
|
14
|
-
const RouterController = require('./controllers/
|
|
15
|
-
const MemberController = require('./controllers/
|
|
16
|
-
const WellKnownController = require('./controllers/
|
|
17
|
-
|
|
18
|
-
const {EmailSuppressedEvent} = require('../../email-suppression-list/
|
|
19
|
-
const MagicLink = require('../../lib/magic-link/
|
|
6
|
+
const PaymentsService = require('./services/payments-service');
|
|
7
|
+
const TokenService = require('./services/token-service');
|
|
8
|
+
const GeolocationService = require('./services/geolocation-service');
|
|
9
|
+
const MemberBREADService = require('./services/member-bread-service');
|
|
10
|
+
const MemberRepository = require('./repositories/member-repository');
|
|
11
|
+
|
|
12
|
+
const EventRepository = require('./repositories/event-repository');
|
|
13
|
+
const ProductRepository = require('./repositories/product-repository');
|
|
14
|
+
const RouterController = require('./controllers/router-controller');
|
|
15
|
+
const MemberController = require('./controllers/member-controller');
|
|
16
|
+
const WellKnownController = require('./controllers/well-known-controller');
|
|
17
|
+
|
|
18
|
+
const {EmailSuppressedEvent} = require('../../email-suppression-list/email-suppression-list');
|
|
19
|
+
const MagicLink = require('../../lib/magic-link/magic-link');
|
|
20
20
|
const DomainEvents = require('@tryghost/domain-events');
|
|
21
21
|
|
|
22
22
|
module.exports = function MembersAPI({
|
|
@@ -9,7 +9,7 @@ const {NotFoundError} = require('@tryghost/errors');
|
|
|
9
9
|
const validator = require('@tryghost/validator');
|
|
10
10
|
const crypto = require('crypto');
|
|
11
11
|
const config = require('../../../../../shared/config');
|
|
12
|
-
const StartOutboxProcessingEvent = require('../../../outbox/events/
|
|
12
|
+
const StartOutboxProcessingEvent = require('../../../outbox/events/start-outbox-processing-event');
|
|
13
13
|
const {MEMBER_WELCOME_EMAIL_SLUGS} = require('../../../member-welcome-emails/constants');
|
|
14
14
|
const messages = {
|
|
15
15
|
noStripeConnection: 'Cannot {action} without a Stripe Connection',
|
|
@@ -343,10 +343,13 @@ module.exports = class MemberRepository {
|
|
|
343
343
|
const memberAddOptions = {...(options || {}), withRelated};
|
|
344
344
|
let member;
|
|
345
345
|
|
|
346
|
-
|
|
346
|
+
const hasTestInbox = Boolean(config.get('memberWelcomeEmailTestInbox'));
|
|
347
|
+
if (hasTestInbox && WELCOME_EMAIL_SOURCES.includes(source)) {
|
|
347
348
|
const freeWelcomeEmail = this._AutomatedEmail ? await this._AutomatedEmail.findOne({slug: MEMBER_WELCOME_EMAIL_SLUGS.free}) : null;
|
|
348
349
|
const isFreeWelcomeEmailActive = freeWelcomeEmail && freeWelcomeEmail.get('lexical') && freeWelcomeEmail.get('status') === 'active';
|
|
349
350
|
const isFreeSignup = !stripeCustomer;
|
|
351
|
+
// Use default template only when no DB row exists (not when inactive - respect explicit user choice)
|
|
352
|
+
const useDefaultFreeTemplate = !freeWelcomeEmail && hasTestInbox;
|
|
350
353
|
|
|
351
354
|
const runMemberCreation = async (transacting) => {
|
|
352
355
|
const newMember = await this._Member.add({
|
|
@@ -355,10 +358,10 @@ module.exports = class MemberRepository {
|
|
|
355
358
|
labels
|
|
356
359
|
}, {...memberAddOptions, transacting});
|
|
357
360
|
|
|
358
|
-
//
|
|
359
|
-
// 1. The free welcome email is active
|
|
361
|
+
// Send the free welcome email if:
|
|
362
|
+
// 1. The free welcome email is active OR no DB row exists and test inbox is configured (uses default template)
|
|
360
363
|
// 2. The member is not signing up for a paid subscription (no stripeCustomer)
|
|
361
|
-
if (isFreeWelcomeEmailActive && isFreeSignup) {
|
|
364
|
+
if ((isFreeWelcomeEmailActive || useDefaultFreeTemplate) && isFreeSignup) {
|
|
362
365
|
const timestamp = eventData.created_at || newMember.get('created_at');
|
|
363
366
|
|
|
364
367
|
await this._Outbox.add({
|
|
@@ -384,7 +387,7 @@ module.exports = class MemberRepository {
|
|
|
384
387
|
member = await this._Member.transaction(runMemberCreation);
|
|
385
388
|
}
|
|
386
389
|
|
|
387
|
-
if (isFreeWelcomeEmailActive && isFreeSignup) {
|
|
390
|
+
if ((isFreeWelcomeEmailActive || useDefaultFreeTemplate) && isFreeSignup) {
|
|
388
391
|
this.dispatchEvent(StartOutboxProcessingEvent.create({memberId: member.id}), memberAddOptions);
|
|
389
392
|
}
|
|
390
393
|
} else {
|
|
@@ -1425,11 +1428,17 @@ module.exports = class MemberRepository {
|
|
|
1425
1428
|
const source = this._resolveContextSource(context);
|
|
1426
1429
|
const shouldSendPaidWelcomeEmail = config.get('memberWelcomeEmailTestInbox') && WELCOME_EMAIL_SOURCES.includes(source);
|
|
1427
1430
|
let isPaidWelcomeEmailActive = false;
|
|
1431
|
+
let paidWelcomeEmail = null;
|
|
1428
1432
|
if (shouldSendPaidWelcomeEmail && this._AutomatedEmail) {
|
|
1429
|
-
|
|
1433
|
+
paidWelcomeEmail = await this._AutomatedEmail.findOne({slug: MEMBER_WELCOME_EMAIL_SLUGS.paid}, options);
|
|
1430
1434
|
isPaidWelcomeEmailActive = paidWelcomeEmail && paidWelcomeEmail.get('lexical') && paidWelcomeEmail.get('status') === 'active';
|
|
1431
1435
|
}
|
|
1432
|
-
|
|
1436
|
+
// Use default template only when no DB row exists (not when inactive - respect explicit user choice)
|
|
1437
|
+
const useDefaultPaidTemplate = !paidWelcomeEmail && shouldSendPaidWelcomeEmail;
|
|
1438
|
+
// Send paid welcome email if:
|
|
1439
|
+
// 1. The paid welcome email is active OR no DB row exists and test inbox is configured (uses default template)
|
|
1440
|
+
// 2. The member status changed to 'paid'
|
|
1441
|
+
if (updatedMember.get('status') === 'paid' && (isPaidWelcomeEmailActive || useDefaultPaidTemplate)) {
|
|
1433
1442
|
await this._Outbox.add({
|
|
1434
1443
|
id: ObjectId().toHexString(),
|
|
1435
1444
|
event_type: MemberCreatedEvent.name,
|
|
@@ -30,7 +30,7 @@ const messages = {
|
|
|
30
30
|
module.exports = class MemberBREADService {
|
|
31
31
|
/**
|
|
32
32
|
* @param {object} deps
|
|
33
|
-
* @param {import('../repositories/
|
|
33
|
+
* @param {import('../repositories/member-repository')} deps.memberRepository
|
|
34
34
|
* @param {import('@tryghost/members-offers/lib/application/OffersAPI')} deps.offersAPI
|
|
35
35
|
* @param {ILabsService} deps.labsService
|
|
36
36
|
* @param {IEmailService} deps.emailService
|
package/core/server/services/members/members-api/services/{PaymentsService.js → payments-service.js}
RENAMED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const DomainEvents = require('@tryghost/domain-events');
|
|
3
|
-
const TierCreatedEvent = require('
|
|
4
|
-
const TierPriceChangeEvent = require('
|
|
5
|
-
const TierNameChangeEvent = require('
|
|
6
|
-
const OfferCreatedEvent = require('
|
|
3
|
+
const TierCreatedEvent = require('../../../tiers/tier-created-event');
|
|
4
|
+
const TierPriceChangeEvent = require('../../../tiers/tier-price-change-event');
|
|
5
|
+
const TierNameChangeEvent = require('../../../tiers/tier-name-change-event');
|
|
6
|
+
const OfferCreatedEvent = require('../../../offers/domain/events/offer-created-event');
|
|
7
7
|
const {BadRequestError} = require('@tryghost/errors');
|
|
8
8
|
|
|
9
9
|
class PaymentsService {
|
|
10
10
|
/**
|
|
11
11
|
* @param {object} deps
|
|
12
12
|
* @param {import('bookshelf').Model} deps.Offer
|
|
13
|
-
* @param {import('../../../offers/application/
|
|
14
|
-
* @param {import('../../../stripe/
|
|
13
|
+
* @param {import('../../../offers/application/offers-api')} deps.offersAPI
|
|
14
|
+
* @param {import('../../../stripe/stripe-api')} deps.stripeAPIService
|
|
15
15
|
* @param {{get(key: string): any}} deps.settingsCache
|
|
16
16
|
*/
|
|
17
17
|
constructor(deps) {
|
|
@@ -57,7 +57,7 @@ class PaymentsService {
|
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* @param {object} params
|
|
60
|
-
* @param {import('../../../tiers/
|
|
60
|
+
* @param {import('../../../tiers/tier')} params.tier
|
|
61
61
|
* @param {Tier.Cadence} params.cadence
|
|
62
62
|
* @param {Offer} [params.offer]
|
|
63
63
|
* @param {Member} [params.member]
|
|
@@ -183,7 +183,7 @@ class PaymentsService {
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
/**
|
|
186
|
-
* @param {import('../../../tiers/
|
|
186
|
+
* @param {import('../../../tiers/tier')} tier
|
|
187
187
|
* @returns {Promise<{id: string}>}
|
|
188
188
|
*/
|
|
189
189
|
async getProductForTier(tier) {
|
|
@@ -211,7 +211,7 @@ class PaymentsService {
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
/**
|
|
214
|
-
* @param {import('../../../tiers/
|
|
214
|
+
* @param {import('../../../tiers/tier')} tier
|
|
215
215
|
* @returns {Promise<import('stripe').default.Product>}
|
|
216
216
|
*/
|
|
217
217
|
async createProductForTier(tier) {
|
|
@@ -224,7 +224,7 @@ class PaymentsService {
|
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
/**
|
|
227
|
-
* @param {import('../../../tiers/
|
|
227
|
+
* @param {import('../../../tiers/tier')} tier
|
|
228
228
|
* @returns {Promise<void>}
|
|
229
229
|
*/
|
|
230
230
|
async updateNameForTierProducts(tier) {
|
|
@@ -398,7 +398,7 @@ class PaymentsService {
|
|
|
398
398
|
}
|
|
399
399
|
|
|
400
400
|
/**
|
|
401
|
-
* @param {import('../../../tiers/
|
|
401
|
+
* @param {import('../../../tiers/tier')} tier
|
|
402
402
|
* @param {'month'|'year'} cadence
|
|
403
403
|
* @returns {Promise<{id: string}>}
|
|
404
404
|
*/
|
|
@@ -442,7 +442,7 @@ class PaymentsService {
|
|
|
442
442
|
}
|
|
443
443
|
|
|
444
444
|
/**
|
|
445
|
-
* @param {import('../../../tiers/
|
|
445
|
+
* @param {import('../../../tiers/tier')} tier
|
|
446
446
|
* @param {'month'|'year'} cadence
|
|
447
447
|
* @returns {Promise<import('stripe').default.Price>}
|
|
448
448
|
*/
|
|
@@ -3,9 +3,9 @@ const errors = require('@tryghost/errors');
|
|
|
3
3
|
const tpl = require('@tryghost/tpl');
|
|
4
4
|
const MembersSSR = require('./members-ssr');
|
|
5
5
|
const db = require('../../data/db');
|
|
6
|
-
const MembersConfigProvider = require('./
|
|
6
|
+
const MembersConfigProvider = require('./members-config-provider');
|
|
7
7
|
const makeMembersCSVImporter = require('./importer');
|
|
8
|
-
const MembersStats = require('./stats/
|
|
8
|
+
const MembersStats = require('./stats/members-stats');
|
|
9
9
|
const memberJobs = require('./jobs');
|
|
10
10
|
const logging = require('@tryghost/logging');
|
|
11
11
|
const urlUtils = require('../../../shared/url-utils');
|
|
@@ -16,10 +16,10 @@ const models = require('../../models');
|
|
|
16
16
|
const {GhostMailer} = require('../mail');
|
|
17
17
|
const jobsService = require('../jobs');
|
|
18
18
|
const tiersService = require('../tiers');
|
|
19
|
-
const VerificationTrigger = require('../
|
|
19
|
+
const VerificationTrigger = require('../verification-trigger');
|
|
20
20
|
const DatabaseInfo = require('@tryghost/database-info');
|
|
21
21
|
const settingsHelpers = require('../settings-helpers');
|
|
22
|
-
const RequestIntegrityTokenProvider = require('./
|
|
22
|
+
const RequestIntegrityTokenProvider = require('./request-integrity-token-provider');
|
|
23
23
|
|
|
24
24
|
const messages = {
|
|
25
25
|
noLiveKeysInDevelopment: 'Cannot use live stripe keys in development. Please restart in production mode.',
|
|
@@ -13,9 +13,9 @@ class MembersEventsServiceWrapper {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
// Wire up all the dependencies
|
|
16
|
-
const EventStorage = require('./
|
|
17
|
-
const LastSeenAtUpdater = require('./
|
|
18
|
-
const LastSeenAtCache = require('./
|
|
16
|
+
const EventStorage = require('./event-storage');
|
|
17
|
+
const LastSeenAtUpdater = require('./last-seen-at-updater');
|
|
18
|
+
const LastSeenAtCache = require('./last-seen-at-cache');
|
|
19
19
|
const models = require('../../models');
|
|
20
20
|
|
|
21
21
|
// Listen for events and store them in the database
|
package/core/server/services/members-events/{LastSeenAtUpdater.js → last-seen-at-updater.js}
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const {MemberPageViewEvent, MemberCommentEvent, MemberLinkClickEvent} = require('../../../shared/events');
|
|
2
2
|
const moment = require('moment-timezone');
|
|
3
3
|
const {IncorrectUsageError} = require('@tryghost/errors');
|
|
4
|
-
const EmailOpenedEvent = require('
|
|
4
|
+
const EmailOpenedEvent = require('../email-service/events/email-opened-event');
|
|
5
5
|
const logging = require('@tryghost/logging');
|
|
6
|
-
const LastSeenAtCache = require('./
|
|
6
|
+
const LastSeenAtCache = require('./last-seen-at-cache');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Listen for `MemberViewEvent` to update the `member.last_seen_at` timestamp
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
const Mention = require('./
|
|
1
|
+
const Mention = require('./mention');
|
|
2
2
|
const logging = require('@tryghost/logging');
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @typedef {import('./
|
|
5
|
+
* @typedef {import('./mentions-api').IMentionRepository} IMentionRepository
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @template Model
|
|
10
|
-
* @typedef {import('./
|
|
10
|
+
* @typedef {import('./mentions-api').Page<Model>} Page
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* @typedef {import('./
|
|
15
|
-
* @typedef {import('./
|
|
14
|
+
* @typedef {import('./mentions-api').GetPageOptions} GetPageOptions
|
|
15
|
+
* @typedef {import('./mentions-api').GetAllOptions} GetAllOptions
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -64,7 +64,7 @@ module.exports = class BookshelfMentionRepository {
|
|
|
64
64
|
|
|
65
65
|
/**
|
|
66
66
|
* @param {GetPageOptions} options
|
|
67
|
-
* @returns {Promise<Page<import('./
|
|
67
|
+
* @returns {Promise<Page<import('./mention')>>}
|
|
68
68
|
*/
|
|
69
69
|
async getPage(options) {
|
|
70
70
|
/**
|
|
@@ -88,7 +88,7 @@ module.exports = class BookshelfMentionRepository {
|
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
90
|
* @param {GetAllOptions} options
|
|
91
|
-
* @returns {Promise<import('./
|
|
91
|
+
* @returns {Promise<import('./mention')[]>}
|
|
92
92
|
*/
|
|
93
93
|
async getAll(options) {
|
|
94
94
|
const models = await this.#MentionModel.findAll(options);
|
|
@@ -99,7 +99,7 @@ module.exports = class BookshelfMentionRepository {
|
|
|
99
99
|
/**
|
|
100
100
|
* @param {URL} source
|
|
101
101
|
* @param {URL} target
|
|
102
|
-
* @returns {Promise<import('./
|
|
102
|
+
* @returns {Promise<import('./mention')|null>}
|
|
103
103
|
*/
|
|
104
104
|
async getBySourceAndTarget(source, target) {
|
|
105
105
|
const model = await this.#MentionModel.findOne({
|
|
@@ -115,7 +115,7 @@ module.exports = class BookshelfMentionRepository {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
/**
|
|
118
|
-
* @param {import('./
|
|
118
|
+
* @param {import('./mention')} mention
|
|
119
119
|
* @returns {Promise<void>}
|
|
120
120
|
*/
|
|
121
121
|
async save(mention) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
const nql = require('@tryghost/nql');
|
|
2
|
-
const Mention = require('./
|
|
2
|
+
const Mention = require('./mention');
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @typedef {import('./
|
|
6
|
-
* @typedef {import('./
|
|
5
|
+
* @typedef {import('./mentions-api').GetPageOptions} GetPageOptions
|
|
6
|
+
* @typedef {import('./mentions-api').IMentionRepository} IMentionRepository
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @template Model
|
|
11
|
-
* @typedef {import('./
|
|
11
|
+
* @typedef {import('./mentions-api').Page<Model>} Page<Model>
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
/**
|