ghost 5.115.0 → 5.116.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.
Files changed (341) hide show
  1. package/components/{tryghost-api-framework-5.115.0.tgz → tryghost-api-framework-5.116.0.tgz} +0 -0
  2. package/components/tryghost-constants-5.116.0.tgz +0 -0
  3. package/components/tryghost-custom-fonts-5.116.0.tgz +0 -0
  4. package/components/{tryghost-custom-theme-settings-service-5.115.0.tgz → tryghost-custom-theme-settings-service-5.116.0.tgz} +0 -0
  5. package/components/tryghost-domain-events-5.116.0.tgz +0 -0
  6. package/components/{tryghost-donations-5.115.0.tgz → tryghost-donations-5.116.0.tgz} +0 -0
  7. package/components/tryghost-email-addresses-5.116.0.tgz +0 -0
  8. package/components/tryghost-email-service-5.116.0.tgz +0 -0
  9. package/components/tryghost-email-suppression-list-5.116.0.tgz +0 -0
  10. package/components/tryghost-html-to-plaintext-5.116.0.tgz +0 -0
  11. package/components/tryghost-i18n-5.116.0.tgz +0 -0
  12. package/components/tryghost-job-manager-5.116.0.tgz +0 -0
  13. package/components/tryghost-link-replacer-5.116.0.tgz +0 -0
  14. package/components/tryghost-magic-link-5.116.0.tgz +0 -0
  15. package/components/tryghost-member-attribution-5.116.0.tgz +0 -0
  16. package/components/tryghost-member-events-5.116.0.tgz +0 -0
  17. package/components/tryghost-members-api-5.116.0.tgz +0 -0
  18. package/components/tryghost-members-csv-5.116.0.tgz +0 -0
  19. package/components/{tryghost-members-offers-5.115.0.tgz → tryghost-members-offers-5.116.0.tgz} +0 -0
  20. package/components/{tryghost-milestones-5.115.0.tgz → tryghost-milestones-5.116.0.tgz} +0 -0
  21. package/components/{tryghost-mw-error-handler-5.115.0.tgz → tryghost-mw-error-handler-5.116.0.tgz} +0 -0
  22. package/components/tryghost-mw-vhost-5.116.0.tgz +0 -0
  23. package/components/{tryghost-post-events-5.115.0.tgz → tryghost-post-events-5.116.0.tgz} +0 -0
  24. package/components/{tryghost-post-revisions-5.115.0.tgz → tryghost-post-revisions-5.116.0.tgz} +0 -0
  25. package/components/tryghost-posts-service-5.116.0.tgz +0 -0
  26. package/components/{tryghost-prometheus-metrics-5.115.0.tgz → tryghost-prometheus-metrics-5.116.0.tgz} +0 -0
  27. package/components/tryghost-security-5.116.0.tgz +0 -0
  28. package/components/{tryghost-tiers-5.115.0.tgz → tryghost-tiers-5.116.0.tgz} +0 -0
  29. package/components/tryghost-webmentions-5.116.0.tgz +0 -0
  30. package/content/themes/casper/LICENSE +1 -1
  31. package/content/themes/casper/README.md +1 -1
  32. package/content/themes/source/LICENSE +1 -1
  33. package/content/themes/source/README.md +1 -1
  34. package/content/themes/source/assets/built/screen.css +1 -1
  35. package/content/themes/source/assets/built/screen.css.map +1 -1
  36. package/content/themes/source/assets/css/screen.css +11 -6
  37. package/content/themes/source/partials/feature-image.hbs +2 -2
  38. package/core/boot.js +3 -43
  39. package/core/built/admin/assets/admin-x-activitypub/admin-x-activitypub.js +30494 -29403
  40. package/core/built/admin/assets/admin-x-demo/admin-x-demo.js +1 -1
  41. package/core/built/admin/assets/admin-x-demo/{index-0040480a.mjs → index-a9601514.mjs} +5 -4
  42. package/core/built/admin/assets/admin-x-demo/{modals-fb35c86c.mjs → modals-c1789d04.mjs} +67 -65
  43. package/core/built/admin/assets/admin-x-settings/{CodeEditorView-806ef39c.mjs → CodeEditorView-e9c9deb8.mjs} +2 -2
  44. package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +2 -2
  45. package/core/built/admin/assets/admin-x-settings/{index-376f847c.mjs → index-84580c3a.mjs} +2 -2
  46. package/core/built/admin/assets/admin-x-settings/{index-8fa19303.mjs → index-f744cab7.mjs} +3147 -3123
  47. package/core/built/admin/assets/admin-x-settings/{modals-36775d71.mjs → modals-d9ca60c5.mjs} +1198 -1192
  48. package/core/built/admin/assets/chunk.524.8371443ef8f60db429d0.js +35 -0
  49. package/core/built/admin/assets/chunk.582.f90151775f2e53dd21d9.js +37 -0
  50. package/core/built/admin/assets/{chunk.874.461cb3cf5b6b36915f8c.js → chunk.713.e9027c0cc3c56110f5da.js} +125 -98
  51. package/core/built/admin/assets/{ghost-938b3d9c29e3564a53a22f8c8f82d351.js → ghost-03b64c086f3c60cabc85fe7a7e2b640a.js} +272 -251
  52. package/core/built/admin/assets/ghost-ba58e9822f7384461e926c7e23f04a75.css +1 -0
  53. package/core/built/admin/assets/ghost-dark-f1f29683b14ffa11615b3bba8b6ab92c.css +1 -0
  54. package/core/built/admin/assets/koenig-lexical/index.css +1 -1
  55. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +20563 -20891
  56. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +139 -139
  57. package/core/built/admin/assets/posts/posts.js +5732 -5667
  58. package/core/built/admin/assets/stats/stats.js +75373 -0
  59. package/core/built/admin/assets/{vendor-68a4aa424a179a90f5bbc2b750def576.js → vendor-72026232b36d97babc6320917c16c321.js} +36 -34
  60. package/core/built/admin/index.html +6 -6
  61. package/core/cli/generate-data.js +1 -1
  62. package/core/frontend/helpers/ghost_head.js +8 -1
  63. package/core/frontend/public/ghost-stats.js +55 -2
  64. package/core/frontend/services/assets-minification/AdminAuthAssets.js +2 -1
  65. package/core/frontend/services/assets-minification/CardAssets.js +1 -1
  66. package/core/frontend/services/assets-minification/CommentCountsAssets.js +1 -1
  67. package/core/frontend/services/assets-minification/MemberAttributionAssets.js +1 -1
  68. package/core/frontend/services/assets-minification/Minifier.js +191 -0
  69. package/core/frontend/services/routing/controllers/previews.js +2 -1
  70. package/core/frontend/src/cards/css/cta.css +1 -1
  71. package/core/server/adapters/cache/Redis.js +1 -1
  72. package/core/server/adapters/lib/redis/AdapterCacheRedis.js +287 -0
  73. package/core/server/adapters/lib/redis/redis-store-factory.js +22 -0
  74. package/core/server/api/endpoints/posts.js +9 -3
  75. package/core/server/api/endpoints/previews.js +35 -1
  76. package/core/server/api/endpoints/slugs.js +6 -2
  77. package/core/server/api/endpoints/utils/serializers/output/utils/post-gating.js +6 -9
  78. package/core/server/api/endpoints/utils/validators/input/settings.js +1 -1
  79. package/core/server/data/db/connection.js +2 -0
  80. package/core/server/data/db/index.js +1 -0
  81. package/core/server/data/importer/handlers/ImporterContentFileHandler.js +90 -0
  82. package/core/server/data/importer/import-manager.js +3 -3
  83. package/core/server/data/importer/importers/importer-revue.js +128 -0
  84. package/core/server/data/importer/importers/json-to-html.js +107 -0
  85. package/core/server/data/migrations/utils/tables.js +2 -4
  86. package/core/server/data/seeders/DataGenerator.js +288 -0
  87. package/core/server/data/seeders/importers/BenefitsImporter.js +28 -0
  88. package/core/server/data/seeders/importers/CommentsImporter.js +73 -0
  89. package/core/server/data/seeders/importers/EmailBatchesImporter.js +38 -0
  90. package/core/server/data/seeders/importers/EmailRecipientFailuresImporter.js +67 -0
  91. package/core/server/data/seeders/importers/EmailRecipientsImporter.js +212 -0
  92. package/core/server/data/seeders/importers/EmailsImporter.js +99 -0
  93. package/core/server/data/seeders/importers/LabelsImporter.js +41 -0
  94. package/core/server/data/seeders/importers/MembersClickEventsImporter.js +69 -0
  95. package/core/server/data/seeders/importers/MembersCreatedEventsImporter.js +103 -0
  96. package/core/server/data/seeders/importers/MembersFeedbackImporter.js +45 -0
  97. package/core/server/data/seeders/importers/MembersImporter.js +111 -0
  98. package/core/server/data/seeders/importers/MembersLabelsImporter.js +39 -0
  99. package/core/server/data/seeders/importers/MembersLoginEventsImporter.js +69 -0
  100. package/core/server/data/seeders/importers/MembersNewslettersImporter.js +38 -0
  101. package/core/server/data/seeders/importers/MembersPaidSubscriptionEventsImporter.js +99 -0
  102. package/core/server/data/seeders/importers/MembersProductsImporter.js +42 -0
  103. package/core/server/data/seeders/importers/MembersStatusEventsImporter.js +58 -0
  104. package/core/server/data/seeders/importers/MembersStripeCustomersImporter.js +60 -0
  105. package/core/server/data/seeders/importers/MembersStripeCustomersSubscriptionsImporter.js +259 -0
  106. package/core/server/data/seeders/importers/MembersSubscribeEventsImporter.js +69 -0
  107. package/core/server/data/seeders/importers/MembersSubscriptionCreatedEventsImporter.js +95 -0
  108. package/core/server/data/seeders/importers/NewslettersImporter.js +40 -0
  109. package/core/server/data/seeders/importers/OffersImporter.js +70 -0
  110. package/core/server/data/seeders/importers/PostsAuthorsImporter.js +32 -0
  111. package/core/server/data/seeders/importers/PostsImporter.js +102 -0
  112. package/core/server/data/seeders/importers/PostsProductsImporter.js +35 -0
  113. package/core/server/data/seeders/importers/PostsTagsImporter.js +46 -0
  114. package/core/server/data/seeders/importers/ProductsBenefitsImporter.js +54 -0
  115. package/core/server/data/seeders/importers/ProductsImporter.js +90 -0
  116. package/core/server/data/seeders/importers/RecommendationClickEventsImporter.js +32 -0
  117. package/core/server/data/seeders/importers/RecommendationSubscribeEventsImporter.js +32 -0
  118. package/core/server/data/seeders/importers/RecommendationsImporter.js +34 -0
  119. package/core/server/data/seeders/importers/RedirectsImporter.js +49 -0
  120. package/core/server/data/seeders/importers/RolesUsersImporter.js +42 -0
  121. package/core/server/data/seeders/importers/StripePricesImporter.js +69 -0
  122. package/core/server/data/seeders/importers/StripeProductsImporter.js +34 -0
  123. package/core/server/data/seeders/importers/TableImporter.js +187 -0
  124. package/core/server/data/seeders/importers/TagsImporter.js +41 -0
  125. package/core/server/data/seeders/importers/UsersImporter.js +31 -0
  126. package/core/server/data/seeders/importers/WebMentionsImporter.js +42 -0
  127. package/core/server/data/seeders/importers/index.js +41 -0
  128. package/core/server/data/seeders/utils/JsonImporter.js +39 -0
  129. package/core/server/data/seeders/utils/blog-info.js +3 -0
  130. package/core/server/data/seeders/utils/database-date.js +7 -0
  131. package/core/server/data/seeders/utils/event-generator.js +48 -0
  132. package/core/server/data/seeders/utils/random.js +13 -0
  133. package/core/server/data/seeders/utils/topological-sort.js +33 -0
  134. package/core/server/lib/bootstrap-socket.js +87 -0
  135. package/core/server/lib/package-json/index.js +1 -0
  136. package/core/server/lib/package-json/package-json.js +160 -0
  137. package/core/server/lib/package-json/parse.js +57 -0
  138. package/core/server/models/base/plugins/actions.js +44 -31
  139. package/core/server/models/base/plugins/generate-slug.js +6 -0
  140. package/core/server/notify.js +1 -1
  141. package/core/server/services/activitypub/ActivityPubService.ts +1 -1
  142. package/core/server/services/adapter-manager/AdapterManager.js +161 -0
  143. package/core/server/services/adapter-manager/index.js +1 -1
  144. package/core/server/services/announcement-bar-service/AnnouncementBarSettings.js +54 -0
  145. package/core/server/services/announcement-bar-service/AnnouncementVisibilityValues.js +11 -0
  146. package/core/server/services/announcement-bar-service/index.js +1 -1
  147. package/core/server/services/api-version-compatibility/APIVersionCompatibilityService.js +99 -0
  148. package/core/server/services/api-version-compatibility/VersionNotificationsDataService.js +80 -0
  149. package/core/server/services/api-version-compatibility/extract-api-key.js +57 -0
  150. package/core/server/services/api-version-compatibility/index.js +2 -2
  151. package/core/server/services/api-version-compatibility/mw-api-version-mismatch.js +31 -0
  152. package/core/server/services/audience-feedback/AudienceFeedbackController.js +85 -0
  153. package/core/server/services/audience-feedback/AudienceFeedbackService.js +34 -0
  154. package/core/server/services/audience-feedback/Feedback.js +35 -0
  155. package/core/server/services/audience-feedback/index.js +4 -2
  156. package/core/server/services/auth/session/emails/signin.js +168 -0
  157. package/core/server/services/auth/session/index.js +2 -2
  158. package/core/server/services/auth/session/session-from-token.js +69 -0
  159. package/core/server/services/auth/session/session-service.js +374 -0
  160. package/core/server/services/custom-redirects/index.js +1 -1
  161. package/core/server/services/email-analytics/EmailAnalyticsProviderMailgun.js +62 -0
  162. package/core/server/services/email-analytics/EmailAnalyticsService.js +552 -0
  163. package/core/server/services/email-analytics/EmailAnalyticsServiceWrapper.js +3 -3
  164. package/core/server/services/email-analytics/EventProcessingResult.js +66 -0
  165. package/core/server/services/email-service/EmailServiceWrapper.js +4 -4
  166. package/core/server/services/email-suppression-list/MailgunEmailSuppressionList.js +1 -1
  167. package/core/server/services/email-suppression-list/service.js +1 -1
  168. package/core/server/services/explore-ping/ExplorePingService.js +106 -0
  169. package/core/server/services/explore-ping/index.js +31 -0
  170. package/core/server/services/identity-tokens/IdentityTokenService.js +30 -0
  171. package/core/server/services/identity-tokens/IdentityTokenService.ts +28 -0
  172. package/core/server/services/identity-tokens/IdentityTokenServiceWrapper.js +1 -1
  173. package/core/server/services/invitations/accept.js +5 -2
  174. package/core/server/services/lib/DynamicRedirectManager.js +156 -0
  175. package/core/server/services/lib/EmailContentGenerator.js +54 -0
  176. package/core/server/services/lib/InMemoryRepository.js +62 -0
  177. package/core/server/services/lib/InMemoryRepository.ts +80 -0
  178. package/core/server/services/lib/MailgunClient.js +364 -0
  179. package/core/server/services/link-redirection/LinkRedirect.js +26 -0
  180. package/core/server/services/link-redirection/LinkRedirectRepository.js +7 -7
  181. package/core/server/services/link-redirection/LinkRedirectsService.js +123 -0
  182. package/core/server/services/link-redirection/README.md +151 -0
  183. package/core/server/services/link-redirection/RedirectEvent.js +24 -0
  184. package/core/server/services/link-redirection/index.js +1 -1
  185. package/core/server/services/link-tracking/LinkClickTrackingService.js +1 -1
  186. package/core/server/services/mail/index.js +1 -1
  187. package/core/server/services/mail-events/BookshelfMailEventRepository.js +2 -2
  188. package/core/server/services/mail-events/InMemoryMailEventRepository.js +10 -0
  189. package/core/server/services/mail-events/InMemoryMailEventRepository.ts +8 -0
  190. package/core/server/services/mail-events/MailEvent.js +20 -0
  191. package/core/server/services/mail-events/MailEvent.ts +10 -0
  192. package/core/server/services/mail-events/MailEventRepository.js +2 -0
  193. package/core/server/services/mail-events/MailEventRepository.ts +5 -0
  194. package/core/server/services/mail-events/MailEventService.js +124 -0
  195. package/core/server/services/mail-events/MailEventService.ts +169 -0
  196. package/core/server/services/mail-events/index.js +1 -1
  197. package/core/server/services/mail-events/libraries.d.ts +2 -0
  198. package/core/server/services/members/CaptchaService.js +80 -0
  199. package/core/server/services/members/api.js +1 -1
  200. package/core/server/services/members/importer/MembersCSVImporter.js +464 -0
  201. package/core/server/services/members/importer/MembersCSVImporterStripeUtils.js +194 -0
  202. package/core/server/services/members/importer/email-template.js +182 -0
  203. package/core/server/services/members/importer/index.js +30 -0
  204. package/core/server/services/members/members-ssr.js +333 -0
  205. package/core/server/services/members/service.js +2 -2
  206. package/core/server/services/members-events/LastSeenAtUpdater.js +1 -1
  207. package/core/server/services/offers/service.js +1 -1
  208. package/core/server/services/posts/stats/PostStats.js +13 -0
  209. package/core/server/services/recommendations/RecommendationServiceWrapper.js +8 -8
  210. package/core/server/services/recommendations/service/BookshelfClickEventRepository.js +48 -0
  211. package/core/server/services/recommendations/service/BookshelfClickEventRepository.ts +49 -0
  212. package/core/server/services/recommendations/service/BookshelfRecommendationRepository.js +98 -0
  213. package/core/server/services/recommendations/service/BookshelfRecommendationRepository.ts +117 -0
  214. package/core/server/services/recommendations/service/BookshelfRepository.js +134 -0
  215. package/core/server/services/recommendations/service/BookshelfRepository.ts +196 -0
  216. package/core/server/services/recommendations/service/BookshelfSubscribeEventRepository.js +48 -0
  217. package/core/server/services/recommendations/service/BookshelfSubscribeEventRepository.ts +49 -0
  218. package/core/server/services/recommendations/service/ClickEvent.js +33 -0
  219. package/core/server/services/recommendations/service/ClickEvent.ts +32 -0
  220. package/core/server/services/recommendations/service/InMemoryRecommendationRepository.js +19 -0
  221. package/core/server/services/recommendations/service/InMemoryRecommendationRepository.ts +20 -0
  222. package/core/server/services/recommendations/service/IncomingRecommendationController.js +34 -0
  223. package/core/server/services/recommendations/service/IncomingRecommendationController.ts +51 -0
  224. package/core/server/services/recommendations/service/IncomingRecommendationEmailRenderer.js +25 -0
  225. package/core/server/services/recommendations/service/IncomingRecommendationEmailRenderer.ts +37 -0
  226. package/core/server/services/recommendations/service/IncomingRecommendationService.js +93 -0
  227. package/core/server/services/recommendations/service/IncomingRecommendationService.ts +160 -0
  228. package/core/server/services/recommendations/service/Recommendation.js +140 -0
  229. package/core/server/services/recommendations/service/Recommendation.ts +201 -0
  230. package/core/server/services/recommendations/service/RecommendationController.js +208 -0
  231. package/core/server/services/recommendations/service/RecommendationController.ts +258 -0
  232. package/core/server/services/recommendations/service/RecommendationMetadataService.js +86 -0
  233. package/core/server/services/recommendations/service/RecommendationMetadataService.ts +128 -0
  234. package/core/server/services/recommendations/service/RecommendationRepository.js +2 -0
  235. package/core/server/services/recommendations/service/RecommendationRepository.ts +13 -0
  236. package/core/server/services/recommendations/service/RecommendationService.js +228 -0
  237. package/core/server/services/recommendations/service/RecommendationService.ts +281 -0
  238. package/core/server/services/recommendations/service/SubscribeEvent.js +33 -0
  239. package/core/server/services/recommendations/service/SubscribeEvent.ts +32 -0
  240. package/core/server/services/recommendations/service/UnsafeData.js +183 -0
  241. package/core/server/services/recommendations/service/UnsafeData.ts +217 -0
  242. package/core/server/services/recommendations/service/WellknownService.js +36 -0
  243. package/core/server/services/recommendations/service/WellknownService.ts +47 -0
  244. package/core/server/services/recommendations/service/index.js +31 -0
  245. package/core/server/services/recommendations/service/index.ts +15 -0
  246. package/core/server/services/recommendations/service/libraries.d.ts +5 -0
  247. package/core/server/services/route-settings/SettingsPathManager.js +47 -0
  248. package/core/server/services/route-settings/index.js +1 -1
  249. package/core/server/services/slack-notifications/SlackNotifications.js +211 -0
  250. package/core/server/services/slack-notifications/SlackNotificationsService.js +90 -0
  251. package/core/server/services/slack-notifications/service.js +4 -6
  252. package/core/server/services/stripe/README.md +63 -0
  253. package/core/server/services/stripe/StripeAPI.js +931 -0
  254. package/core/server/services/stripe/StripeMigrations.js +613 -0
  255. package/core/server/services/stripe/StripeService.js +175 -0
  256. package/core/server/services/stripe/WebhookController.js +100 -0
  257. package/core/server/services/stripe/WebhookManager.js +175 -0
  258. package/core/server/services/stripe/events/StripeLiveDisabledEvent.js +23 -0
  259. package/core/server/services/stripe/events/StripeLiveEnabledEvent.js +23 -0
  260. package/core/server/services/stripe/events/index.js +4 -0
  261. package/core/server/services/stripe/service.js +1 -1
  262. package/core/server/services/stripe/services/webhook/CheckoutSessionEventService.js +255 -0
  263. package/core/server/services/stripe/services/webhook/InvoiceEventService.js +70 -0
  264. package/core/server/services/stripe/services/webhook/SubscriptionEventService.js +54 -0
  265. package/core/server/services/themes/loader.js +1 -1
  266. package/core/server/services/themes/to-json.js +1 -1
  267. package/core/server/web/api/endpoints/admin/app.js +1 -21
  268. package/core/server/web/api/endpoints/admin/routes.js +1 -0
  269. package/core/server/web/api/middleware/version-match.js +41 -0
  270. package/core/server/web/shared/middleware/cache-control.js +51 -0
  271. package/core/server/web/shared/middleware/index.js +1 -1
  272. package/core/server/web/well-known.js +1 -1
  273. package/core/shared/labs.js +5 -3
  274. package/core/shared/settings-cache/CacheManager.js +64 -6
  275. package/package.json +98 -146
  276. package/tsconfig.tsbuildinfo +1 -1
  277. package/yarn.lock +1478 -1634
  278. package/components/tryghost-adapter-cache-redis-5.115.0.tgz +0 -0
  279. package/components/tryghost-adapter-manager-5.115.0.tgz +0 -0
  280. package/components/tryghost-announcement-bar-settings-5.115.0.tgz +0 -0
  281. package/components/tryghost-api-version-compatibility-service-5.115.0.tgz +0 -0
  282. package/components/tryghost-audience-feedback-5.115.0.tgz +0 -0
  283. package/components/tryghost-bookshelf-repository-5.115.0.tgz +0 -0
  284. package/components/tryghost-bootstrap-socket-5.115.0.tgz +0 -0
  285. package/components/tryghost-captcha-service-5.115.0.tgz +0 -0
  286. package/components/tryghost-constants-5.115.0.tgz +0 -0
  287. package/components/tryghost-custom-fonts-5.115.0.tgz +0 -0
  288. package/components/tryghost-data-generator-5.115.0.tgz +0 -0
  289. package/components/tryghost-domain-events-5.115.0.tgz +0 -0
  290. package/components/tryghost-email-addresses-5.115.0.tgz +0 -0
  291. package/components/tryghost-email-analytics-provider-mailgun-5.115.0.tgz +0 -0
  292. package/components/tryghost-email-analytics-service-5.115.0.tgz +0 -0
  293. package/components/tryghost-email-content-generator-5.115.0.tgz +0 -0
  294. package/components/tryghost-email-events-5.115.0.tgz +0 -0
  295. package/components/tryghost-email-service-5.115.0.tgz +0 -0
  296. package/components/tryghost-email-suppression-list-5.115.0.tgz +0 -0
  297. package/components/tryghost-express-dynamic-redirects-5.115.0.tgz +0 -0
  298. package/components/tryghost-extract-api-key-5.115.0.tgz +0 -0
  299. package/components/tryghost-ghost-5.115.0.tgz +0 -0
  300. package/components/tryghost-html-to-plaintext-5.115.0.tgz +0 -0
  301. package/components/tryghost-i18n-5.115.0.tgz +0 -0
  302. package/components/tryghost-identity-token-service-5.115.0.tgz +0 -0
  303. package/components/tryghost-importer-handler-content-files-5.115.0.tgz +0 -0
  304. package/components/tryghost-importer-revue-5.115.0.tgz +0 -0
  305. package/components/tryghost-in-memory-repository-5.115.0.tgz +0 -0
  306. package/components/tryghost-job-manager-5.115.0.tgz +0 -0
  307. package/components/tryghost-link-redirects-5.115.0.tgz +0 -0
  308. package/components/tryghost-link-replacer-5.115.0.tgz +0 -0
  309. package/components/tryghost-magic-link-5.115.0.tgz +0 -0
  310. package/components/tryghost-mail-events-5.115.0.tgz +0 -0
  311. package/components/tryghost-mailgun-client-5.115.0.tgz +0 -0
  312. package/components/tryghost-member-attribution-5.115.0.tgz +0 -0
  313. package/components/tryghost-member-events-5.115.0.tgz +0 -0
  314. package/components/tryghost-members-api-5.115.0.tgz +0 -0
  315. package/components/tryghost-members-csv-5.115.0.tgz +0 -0
  316. package/components/tryghost-members-importer-5.115.0.tgz +0 -0
  317. package/components/tryghost-members-payments-5.115.0.tgz +0 -0
  318. package/components/tryghost-members-ssr-5.115.0.tgz +0 -0
  319. package/components/tryghost-members-stripe-service-5.115.0.tgz +0 -0
  320. package/components/tryghost-minifier-5.115.0.tgz +0 -0
  321. package/components/tryghost-mw-api-version-mismatch-5.115.0.tgz +0 -0
  322. package/components/tryghost-mw-cache-control-5.115.0.tgz +0 -0
  323. package/components/tryghost-mw-session-from-token-5.115.0.tgz +0 -0
  324. package/components/tryghost-mw-update-user-last-seen-5.115.0.tgz +0 -0
  325. package/components/tryghost-mw-version-match-5.115.0.tgz +0 -0
  326. package/components/tryghost-mw-vhost-5.115.0.tgz +0 -0
  327. package/components/tryghost-package-json-5.115.0.tgz +0 -0
  328. package/components/tryghost-posts-service-5.115.0.tgz +0 -0
  329. package/components/tryghost-recommendations-5.115.0.tgz +0 -0
  330. package/components/tryghost-referrers-5.115.0.tgz +0 -0
  331. package/components/tryghost-security-5.115.0.tgz +0 -0
  332. package/components/tryghost-session-service-5.115.0.tgz +0 -0
  333. package/components/tryghost-settings-path-manager-5.115.0.tgz +0 -0
  334. package/components/tryghost-slack-notifications-5.115.0.tgz +0 -0
  335. package/components/tryghost-version-notifications-data-service-5.115.0.tgz +0 -0
  336. package/components/tryghost-webmentions-5.115.0.tgz +0 -0
  337. package/core/built/admin/assets/chunk.524.31419fdf6fb3859ecc1e.js +0 -35
  338. package/core/built/admin/assets/chunk.582.08c816d5e4ab766486a7.js +0 -37
  339. package/core/built/admin/assets/ghost-c2a7c4a1b76550c4219adb2ed4124ce0.css +0 -1
  340. package/core/built/admin/assets/ghost-dark-f91e4a479c6d38d94d5d1b14727871dc.css +0 -1
  341. /package/core/built/admin/assets/{chunk.874.461cb3cf5b6b36915f8c.js.LICENSE.txt → chunk.713.e9027c0cc3c56110f5da.js.LICENSE.txt} +0 -0
@@ -0,0 +1,160 @@
1
+ /*
2
+ * # Package Utils
3
+ *
4
+ * Ghost has support for several different types of sub-packages:
5
+ * - Themes: have always been packages, but we're going to lean more heavily on npm & package.json in future
6
+ * - Adapters: replace fundamental pieces like storage, will become npm modules
7
+ *
8
+ * These utils facilitate loading, reading, managing etc, packages from the file system.
9
+ *
10
+ */
11
+ const _ = require('lodash');
12
+ const fs = require('fs-extra');
13
+ const join = require('path').join;
14
+ const errors = require('@tryghost/errors');
15
+ const parse = require('./parse');
16
+
17
+ const notAPackageRegex = /^\.|_messages|README.md|node_modules|bower_components/i;
18
+ const packageJSONPath = 'package.json';
19
+
20
+ /**
21
+ * @typedef {object} PackageList
22
+ * @typedef {object} Package
23
+ */
24
+
25
+ /**
26
+ * Recursively read directory and find the packages in it
27
+ *
28
+ * @param {string} absolutePath
29
+ * @param {string} packageName
30
+ * @returns {Promise<Package>}
31
+ */
32
+ async function processPackage(absolutePath, packageName) {
33
+ const pkg = {
34
+ name: packageName,
35
+ path: absolutePath
36
+ };
37
+
38
+ try {
39
+ const packageJSON = await parse(join(absolutePath, packageJSONPath));
40
+ pkg['package.json'] = packageJSON;
41
+ } catch (err) {
42
+ // ignore invalid package.json for now,
43
+ // because Ghost does not rely/use them at the moment
44
+ // in the future, this .catch() will need to be removed,
45
+ // so that error is thrown on invalid json syntax
46
+ pkg['package.json'] = null;
47
+ }
48
+
49
+ return pkg;
50
+ }
51
+
52
+ /**
53
+ * ### Filter Packages
54
+ * Normalizes packages read by readPackages so that the themes module can use them.
55
+ * Iterates over each package and return an array of objects which are simplified representations of the package
56
+ * with 3 properties:
57
+ *
58
+ * @typedef {object} SimplePackage
59
+ * @prop {string} name - the package name
60
+ * @prop {object|boolean} package - contents of the package.json or false if there isn't one
61
+ * @prop {boolean} active - set to true if this package is active
62
+ *
63
+ * This data structure is used for listings of packages provided over the API and as such
64
+ * deliberately combines multiple sources of information in order to be efficient.
65
+ *
66
+ * TODO: simplify the package.json representation to contain only fields we use
67
+ *
68
+ * @param {PackageList} packages object made up of packages keyed by name as returned by readPackages
69
+ * @param {array|string} [active] optional set of names of packages that are active
70
+ * @returns {Array<SimplePackage>} array of objects with useful info about themes
71
+ */
72
+ function filter(packages, active) {
73
+ // turn active into an array if it isn't one, so this function can deal with lists and one-offs
74
+ if (!Array.isArray(active)) {
75
+ active = [active];
76
+ }
77
+
78
+ return _.reduce(packages, function (result, pkg, key) {
79
+ let item = {};
80
+ if (!key.match(notAPackageRegex)) {
81
+ item = {
82
+ name: key,
83
+ package: pkg['package.json'] || false,
84
+ active: _.indexOf(active, key) !== -1
85
+ };
86
+
87
+ result.push(item);
88
+ }
89
+
90
+ return result;
91
+ }, []);
92
+ }
93
+
94
+ /**
95
+ * @param {string} packagePath
96
+ * @param {string} packageName
97
+ * @returns {Promise<Package>}
98
+ */
99
+ async function readPackage(packagePath, packageName) {
100
+ const absolutePath = join(packagePath, packageName);
101
+
102
+ try {
103
+ const stat = await fs.stat(absolutePath);
104
+ if (!stat.isDirectory()) {
105
+ return {};
106
+ }
107
+
108
+ const pkg = await processPackage(absolutePath, packageName);
109
+ const res = {};
110
+ res[packageName] = pkg;
111
+ return res;
112
+ } catch (err) {
113
+ return Promise.reject(new errors.NotFoundError({
114
+ message: 'Package not found',
115
+ err: err,
116
+ help: 'path: ' + packagePath,
117
+ context: 'name: ' + packageName
118
+ }));
119
+ }
120
+ }
121
+
122
+ /**
123
+ * @param {string} packagePath
124
+ * @returns {Promise<PackageList>}
125
+ */
126
+ async function readPackages(packagePath) {
127
+ const files = await fs.promises.readdir(packagePath, {withFileTypes: true});
128
+ const packages = await Promise.all(files.map(async (file) => {
129
+ // Filter out things which are not packages by regex
130
+ if (file.name.match(notAPackageRegex)) {
131
+ return false;
132
+ }
133
+
134
+ if (file.isSymbolicLink()) {
135
+ try {
136
+ const packageFileOrig = await fs.stat(join(packagePath, file.name));
137
+ return packageFileOrig.isDirectory();
138
+ } catch (err) {
139
+ // if there's an error reading the symlink, we should just return false
140
+ return false;
141
+ }
142
+ }
143
+
144
+ // Check the remaining items to ensure they are a directory
145
+ return file.isDirectory();
146
+ }))
147
+ .then(results => files.filter((_v, index) => results[index]))
148
+ .then(packageFiles => Promise.all(packageFiles.map((packageFile) => {
149
+ const absolutePath = join(packagePath, packageFile.name);
150
+ return processPackage(absolutePath, packageFile.name);
151
+ })));
152
+
153
+ return _.keyBy(packages, 'name');
154
+ }
155
+
156
+ module.exports = {
157
+ filter,
158
+ readPackage,
159
+ readPackages
160
+ };
@@ -0,0 +1,57 @@
1
+ const fs = require('fs-extra');
2
+ const errors = require('@tryghost/errors');
3
+ const tpl = require('@tryghost/tpl');
4
+
5
+ const messages = {
6
+ couldNotReadPackage: 'Could not read package.json file',
7
+ nameOrVersionMissing: '"name" or "version" is missing from theme package.json file.',
8
+ willBeRequired: 'This will be required in future. Please see {url}',
9
+ themeFileIsMalformed: 'Theme package.json file is malformed'
10
+ };
11
+
12
+ /**
13
+ * Parse package.json and validate it has
14
+ * all the required fields
15
+ *
16
+ * @param {string} path
17
+ * @returns {Promise<object>}
18
+ */
19
+ async function parse(path) {
20
+ let source;
21
+ let json;
22
+
23
+ try {
24
+ source = await fs.readFile(path, {encoding: 'utf8'});
25
+ } catch (readError) {
26
+ throw new errors.IncorrectUsageError({
27
+ message: tpl(messages.couldNotReadPackage),
28
+ context: path,
29
+ err: readError
30
+ });
31
+ }
32
+
33
+ try {
34
+ json = JSON.parse(source);
35
+ } catch (parseError) {
36
+ throw new errors.IncorrectUsageError({
37
+ message: tpl(messages.themeFileIsMalformed),
38
+ context: path,
39
+ err: parseError,
40
+ help: tpl(messages.willBeRequired, {url: 'https://ghost.org/docs/themes/'})
41
+ });
42
+ }
43
+
44
+ const hasRequiredKeys = json.name && json.version;
45
+
46
+ if (!hasRequiredKeys) {
47
+ throw new errors.IncorrectUsageError({
48
+ message: tpl(messages.nameOrVersionMissing),
49
+ context: path,
50
+ help: tpl(messages.willBeRequired, {url: 'https://ghost.org/docs/themes/'})
51
+ });
52
+ }
53
+
54
+ return json;
55
+ }
56
+
57
+ module.exports = parse;
@@ -3,9 +3,20 @@ const errors = require('@tryghost/errors');
3
3
  const logging = require('@tryghost/logging');
4
4
 
5
5
  /**
6
+ * This plugin is used to add actions to the database. It backs the "audit log" feature we have in Ghost.
7
+ *
8
+ * The functions here are triggered by the `onCreated`, `onUpdated`, `onDeleted` functions in the `events`
9
+ * plugin, with some extra ones for niche other events.
10
+ *
6
11
  * @param {import('bookshelf')} Bookshelf
7
12
  */
8
13
  module.exports = function (Bookshelf) {
14
+ /**
15
+ * Insert an action into the database
16
+ *
17
+ * @param {Object} data - The data to insert
18
+ * @param {Object} options - The options object
19
+ */
9
20
  const insertAction = (data, options) => {
10
21
  // CASE: model does not support action for target event
11
22
  if (!data) {
@@ -39,7 +50,13 @@ module.exports = function (Bookshelf) {
39
50
  }
40
51
  };
41
52
 
42
- // We need this addAction accessible from the static model and instances
53
+ /**
54
+ * Add an action to the database
55
+ *
56
+ * @param {import('bookshelf').Model} model - The model to add the action to
57
+ * @param {string} event - The event that triggered the action
58
+ * @param {Object} options - The options object
59
+ */
43
60
  const addAction = (model, event, options) => {
44
61
  if (!model.wasChanged()) {
45
62
  return;
@@ -58,11 +75,14 @@ module.exports = function (Bookshelf) {
58
75
  /**
59
76
  * Constructs data to be stored in the database with info
60
77
  * on particular actions
78
+ *
79
+ * @param {string} event - The event that triggered the action
80
+ * @param {Object} options - The options object
81
+ * @returns {Object} The data to be stored in the database
61
82
  */
62
83
  getAction(event, options) {
84
+ // Ignore internal updates (`options.context.internal`) for now
63
85
  const actor = this.getActor(options);
64
-
65
- // @NOTE: we ignore internal updates (`options.context.internal`) for now
66
86
  if (!actor) {
67
87
  return;
68
88
  }
@@ -71,12 +91,7 @@ module.exports = function (Bookshelf) {
71
91
  return;
72
92
  }
73
93
 
74
- let resourceType = this.actionsResourceType;
75
-
76
- if (typeof resourceType === 'function') {
77
- resourceType = resourceType.bind(this)();
78
- }
79
-
94
+ const resourceType = this.actionsResourceType;
80
95
  if (!resourceType) {
81
96
  return;
82
97
  }
@@ -85,12 +100,14 @@ module.exports = function (Bookshelf) {
85
100
  action_name: options.actionName
86
101
  };
87
102
 
103
+ // Used to attach extra content to the action (ie. the key + group for settings changes)
88
104
  if (this.actionsExtraContext && Array.isArray(this.actionsExtraContext)) {
89
105
  for (const c of this.actionsExtraContext) {
90
106
  context[c] = this.get(c) || this.previous(c);
91
107
  }
92
108
  }
93
109
 
110
+ // Attach the primary name to the action (ie. the title or name of the model)
94
111
  if (event === 'deleted') {
95
112
  context.primary_name = (this.previous('title') || this.previous('name'));
96
113
  } else if (['added', 'edited'].includes(event)) {
@@ -112,21 +129,17 @@ module.exports = function (Bookshelf) {
112
129
  return data;
113
130
  },
114
131
 
115
- /**
116
- * @NOTE:
117
- *
118
- * We add actions step by step and define how they should look like.
119
- * Each post update triggers a couple of events, which we don't want to add actions for.
120
- *
121
- * e.g. transform post to page triggers a handful of events including `post.deleted` and `page.added`
122
- *
123
- * We protect adding too many and uncontrolled events.
124
- *
125
- * We could embed adding actions more nicely in the future e.g. plugin.
126
- */
127
132
  addAction
128
133
  }, {
129
134
  addAction,
135
+
136
+ /**
137
+ * Add actions for bulk actions
138
+ *
139
+ * @param {string} event - The event that triggered the action
140
+ * @param {number[]} ids - The ids of the models that were affected
141
+ * @param {Object} options - The options object
142
+ */
130
143
  async addActions(event, ids, options) {
131
144
  if (ids.length === 1) {
132
145
  // We want to store an event for a single model in the actions table
@@ -141,27 +154,27 @@ module.exports = function (Bookshelf) {
141
154
  },
142
155
 
143
156
  /**
144
- * Constructs data to be stored in the database with info
145
- * on particular actions
157
+ * Constructs data for bulk actions to be stored in the database
158
+ *
159
+ * @param {string} event - The event that triggered the action
160
+ * @param {number} count - The number of models that were affected
161
+ * @param {Object} options - The options object
162
+ * @returns {Object} The data to be stored in the database
146
163
  */
147
164
  getBulkAction(event, count, options) {
165
+ // Ignore internal updates (`options.context.internal`) for now
148
166
  const actor = this.prototype.getActor(options);
149
-
150
- // @NOTE: we ignore internal updates (`options.context.internal`) for now
151
167
  if (!actor) {
152
168
  return;
153
169
  }
154
170
 
171
+ // Models can opt-in to their CRUD actions being collected (we do this so we don't
172
+ // log every single action)
155
173
  if (!this.prototype.actionsCollectCRUD) {
156
174
  return;
157
175
  }
158
176
 
159
- let resourceType = this.prototype.actionsResourceType;
160
-
161
- if (typeof resourceType === 'function') {
162
- resourceType = resourceType.bind(this)();
163
- }
164
-
177
+ const resourceType = this.prototype.actionsResourceType;
165
178
  if (!resourceType) {
166
179
  return;
167
180
  }
@@ -39,6 +39,12 @@ module.exports = function (Bookshelf) {
39
39
  return slugToFind;
40
40
  }
41
41
 
42
+ if (options.modelId) {
43
+ if (found.id === options.modelId) {
44
+ return slugToFind;
45
+ }
46
+ }
47
+
42
48
  slugTryCount += 1;
43
49
 
44
50
  // If we shortened, go back to the full version and try again
@@ -51,7 +51,7 @@ async function notify(type, error = null) {
51
51
  // CASE: use bootstrap socket to communicate with CLI for systemd
52
52
  let socketAddress = config.get('bootstrap-socket');
53
53
  if (socketAddress) {
54
- const bootstrapSocket = require('@tryghost/bootstrap-socket');
54
+ const bootstrapSocket = require('./lib/bootstrap-socket');
55
55
  return bootstrapSocket.connectAndSend(socketAddress, message);
56
56
  }
57
57
 
@@ -1,6 +1,6 @@
1
1
  import ObjectID from 'bson-objectid';
2
2
  import {Knex} from 'knex';
3
- import {IdentityTokenService} from '@tryghost/identity-token-service';
3
+ import {IdentityTokenService} from '../identity-tokens/IdentityTokenService';
4
4
  import fetch from 'node-fetch';
5
5
 
6
6
  type ExpectedWebhook = {
@@ -0,0 +1,161 @@
1
+ const path = require('path');
2
+ const errors = require('@tryghost/errors');
3
+
4
+ /**
5
+ * @typedef { function(new: Adapter, object) } AdapterConstructor
6
+ */
7
+
8
+ /**
9
+ * @typedef {object} Adapter
10
+ * @prop {string[]} requiredFns
11
+ */
12
+
13
+ module.exports = class AdapterManager {
14
+ /**
15
+ * @param {object} config
16
+ * @param {string[]} config.pathsToAdapters The paths to check, e.g. ['content/adapters', 'core/server/adapters']
17
+ * @param {(path: string) => AdapterConstructor} config.loadAdapterFromPath A function to load adapters, e.g. global.require
18
+ */
19
+ constructor({pathsToAdapters, loadAdapterFromPath}) {
20
+ /**
21
+ * @private
22
+ * @type {Object.<string, AdapterConstructor>}
23
+ */
24
+ this.baseClasses = {};
25
+
26
+ /**
27
+ * @private
28
+ * @type {Object.<string, Object.<string, Adapter>>}
29
+ */
30
+ this.instanceCache = {};
31
+
32
+ /**
33
+ * @private
34
+ * @type {string[]}
35
+ */
36
+ this.pathsToAdapters = pathsToAdapters;
37
+
38
+ /**
39
+ * @private
40
+ * @type {(path: string) => AdapterConstructor}
41
+ */
42
+ this.loadAdapterFromPath = loadAdapterFromPath;
43
+ }
44
+
45
+ /**
46
+ * Register an adapter type and the corresponding base class. Must be called before requesting adapters of that type
47
+ *
48
+ * @param {string} type The name for the type of adapter
49
+ * @param {AdapterConstructor} BaseClass The class from which all adapters of this type must extend
50
+ */
51
+ registerAdapter(type, BaseClass) {
52
+ this.instanceCache[type] = {};
53
+ this.baseClasses[type] = BaseClass;
54
+ }
55
+
56
+ /**
57
+ * Force recreation of all instances instead of reusing cached instances. Use when editing config file during tests.
58
+ */
59
+ clearInstanceCache() {
60
+ for (const key of Object.keys(this.instanceCache)) {
61
+ this.instanceCache[key] = {};
62
+ }
63
+ }
64
+
65
+ /**
66
+ * getAdapter
67
+ *
68
+ * @param {string} adapterName The name of the type of adapter, e.g. "storage" or "scheduling", optionally including the feature, e.g. "storage:files"
69
+ * @param {string} adapterClassName The active adapter instance class name e.g. "LocalFileStorage"
70
+ * @param {object} [config] The config the adapter could be instantiated with
71
+ *
72
+ * @returns {Adapter} The resolved and instantiated adapter
73
+ */
74
+ getAdapter(adapterName, adapterClassName, config) {
75
+ if (!adapterName || !adapterClassName) {
76
+ throw new errors.IncorrectUsageError({
77
+ message: 'getAdapter must be called with a adapterName and a adapterClassName.'
78
+ });
79
+ }
80
+
81
+ let adapterType;
82
+ if (adapterName.includes(':')) {
83
+ [adapterType] = adapterName.split(':');
84
+ } else {
85
+ adapterType = adapterName;
86
+ }
87
+
88
+ const adapterCache = this.instanceCache[adapterType];
89
+
90
+ if (!adapterCache) {
91
+ throw new errors.NotFoundError({
92
+ message: `Unknown adapter type ${adapterType}. Please register adapter.`
93
+ });
94
+ }
95
+
96
+ // @NOTE: example cache key value 'email:newsletters:custom-newsletter-adapter'
97
+ const adapterCacheKey = `${adapterName}:${adapterClassName}`;
98
+ if (adapterCache[adapterCacheKey]) {
99
+ return adapterCache[adapterCacheKey];
100
+ }
101
+
102
+ /** @type AdapterConstructor */
103
+ let Adapter;
104
+ for (const pathToAdapters of this.pathsToAdapters) {
105
+ const pathToAdapter = path.join(pathToAdapters, adapterType, adapterClassName);
106
+ try {
107
+ Adapter = this.loadAdapterFromPath(pathToAdapter);
108
+ if (Adapter) {
109
+ break;
110
+ }
111
+ } catch (err) {
112
+ // Catch runtime errors
113
+ if (err.code !== 'MODULE_NOT_FOUND') {
114
+ throw new errors.IncorrectUsageError({err});
115
+ }
116
+
117
+ // Catch missing dependencies BUT NOT missing adapter
118
+ if (!err.message.includes(pathToAdapter)) {
119
+ throw new errors.IncorrectUsageError({
120
+ message: `You are missing dependencies in your adapter ${pathToAdapter}`,
121
+ err
122
+ });
123
+ }
124
+ }
125
+ }
126
+
127
+ if (!Adapter) {
128
+ throw new errors.IncorrectUsageError({
129
+ message: `Unable to find ${adapterType} adapter ${adapterClassName} in ${this.pathsToAdapters}.`
130
+ });
131
+ }
132
+
133
+ const adapter = new Adapter(config);
134
+
135
+ if (!(adapter instanceof this.baseClasses[adapterType])) {
136
+ if (Object.getPrototypeOf(Adapter).name !== this.baseClasses[adapterType].name) {
137
+ throw new errors.IncorrectUsageError({
138
+ message: `${adapterType} adapter ${adapterClassName} does not inherit from the base class.`
139
+ });
140
+ }
141
+ }
142
+
143
+ if (!adapter.requiredFns) {
144
+ throw new errors.IncorrectUsageError({
145
+ message: `${adapterType} adapter ${adapterClassName} does not have the requiredFns.`
146
+ });
147
+ }
148
+
149
+ for (const requiredFn of adapter.requiredFns) {
150
+ if (typeof adapter[requiredFn] !== 'function') {
151
+ throw new errors.IncorrectUsageError({
152
+ message: `${adapterType} adapter ${adapterClassName} is missing the ${requiredFn} method.`
153
+ });
154
+ }
155
+ }
156
+
157
+ adapterCache[adapterCacheKey] = adapter;
158
+
159
+ return adapter;
160
+ }
161
+ };
@@ -1,4 +1,4 @@
1
- const AdapterManager = require('@tryghost/adapter-manager');
1
+ const AdapterManager = require('./AdapterManager');
2
2
  const getAdapterServiceConfig = require('./config');
3
3
  const resolveAdapterOptions = require('./options-resolver');
4
4
  const config = require('../../../shared/config');
@@ -0,0 +1,54 @@
1
+ const AnnouncementVisibilityValues = require('./AnnouncementVisibilityValues');
2
+
3
+ class AnnouncementBarSettings {
4
+ #getAnnouncementSettings;
5
+
6
+ static VisibilityValues = AnnouncementVisibilityValues;
7
+
8
+ /**
9
+ *
10
+ * @param {Object} deps
11
+ * @param {() => {announcement: string, announcement_visibility: string[], announcement_background: string}} deps.getAnnouncementSettings
12
+ */
13
+ constructor(deps) {
14
+ this.#getAnnouncementSettings = deps.getAnnouncementSettings;
15
+ }
16
+
17
+ /**
18
+ * @param {Object} [member]
19
+ * @param {string} member.status
20
+ * @returns {{announcement: string, announcement_background: string}}
21
+ */
22
+ getAnnouncementSettings(member) {
23
+ let announcement = undefined;
24
+
25
+ // NOTE: combination of 'free_members' & 'paid_members' makes just a 'members' filter
26
+ const announcementSettings = this.#getAnnouncementSettings();
27
+
28
+ if (announcementSettings.announcement) {
29
+ const visibilities = announcementSettings.announcement_visibility;
30
+ const announcementContent = announcementSettings.announcement;
31
+
32
+ if (visibilities.length === 0) {
33
+ announcement = undefined;
34
+ } else {
35
+ if (visibilities.includes(AnnouncementVisibilityValues.VISITORS) && !member) {
36
+ announcement = announcementContent;
37
+ } else if (visibilities.includes(AnnouncementVisibilityValues.FREE_MEMBERS) && (member?.status === 'free')) {
38
+ announcement = announcementContent;
39
+ } else if (visibilities.includes(AnnouncementVisibilityValues.PAID_MEMBERS) && (member && member.status !== 'free')) {
40
+ announcement = announcementContent;
41
+ }
42
+ }
43
+ }
44
+
45
+ if (announcement !== undefined) {
46
+ return {
47
+ announcement,
48
+ announcement_background: announcementSettings.announcement_background
49
+ };
50
+ }
51
+ }
52
+ }
53
+
54
+ module.exports = AnnouncementBarSettings;
@@ -0,0 +1,11 @@
1
+ // Available visibilities:
2
+ // 'visitors' - anonymous visitors
3
+ // 'free_members' - free members
4
+ // 'paid_members' - paid members (aka non-free members)
5
+ class AnnouncementVisibilityValues {
6
+ static VISITORS = 'visitors';
7
+ static FREE_MEMBERS = 'free_members';
8
+ static PAID_MEMBERS = 'paid_members';
9
+ }
10
+
11
+ module.exports = AnnouncementVisibilityValues;
@@ -1,5 +1,5 @@
1
1
  const settingsCache = require('../../../shared/settings-cache');
2
- const AnnouncementBarSettings = require('@tryghost/announcement-bar-settings');
2
+ const AnnouncementBarSettings = require('./AnnouncementBarSettings');
3
3
 
4
4
  const announcementBarService = new AnnouncementBarSettings({
5
5
  getAnnouncementSettings: () => ({