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,183 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.UnsafeData = void 0;
7
+ const errors_1 = __importDefault(require("@tryghost/errors"));
8
+ function serializeField(field) {
9
+ if (field.length === 0) {
10
+ return 'data';
11
+ }
12
+ return field.join('.');
13
+ }
14
+ /**
15
+ * NOTE: should be moved to a separate package in case this pattern is found to be useful
16
+ */
17
+ class UnsafeData {
18
+ data;
19
+ context;
20
+ constructor(data, context = {}) {
21
+ this.data = data;
22
+ this.context = context;
23
+ }
24
+ get field() {
25
+ return serializeField(this.context.field ?? []);
26
+ }
27
+ addKeyToField(key) {
28
+ return this.context.field ? [...this.context.field, key] : [key];
29
+ }
30
+ fieldWithKey(key) {
31
+ return serializeField(this.addKeyToField(key));
32
+ }
33
+ /**
34
+ * Returns undefined if the key is not present on the object. Note that this doesn't check for null.
35
+ */
36
+ optionalKey(key) {
37
+ if (typeof this.data !== 'object' || this.data === null) {
38
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be an object` });
39
+ }
40
+ if (!Object.prototype.hasOwnProperty.call(this.data, key)) {
41
+ return undefined;
42
+ }
43
+ return new UnsafeData(this.data[key], {
44
+ field: this.addKeyToField(key)
45
+ });
46
+ }
47
+ key(key) {
48
+ if (typeof this.data !== 'object' || this.data === null) {
49
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be an object` });
50
+ }
51
+ if (!Object.prototype.hasOwnProperty.call(this.data, key)) {
52
+ throw new errors_1.default.ValidationError({ message: `${this.fieldWithKey(key)} is required` });
53
+ }
54
+ return new UnsafeData(this.data[key], {
55
+ field: this.addKeyToField(key)
56
+ });
57
+ }
58
+ /**
59
+ * Use this to get a nullable value:
60
+ * ```
61
+ * const url: string|null = data.key('url').nullable.string
62
+ * ```
63
+ */
64
+ get nullable() {
65
+ if (this.data === null) {
66
+ const d = {
67
+ get string() {
68
+ return null;
69
+ },
70
+ get boolean() {
71
+ return null;
72
+ },
73
+ get number() {
74
+ return null;
75
+ },
76
+ get integer() {
77
+ return null;
78
+ },
79
+ get url() {
80
+ return null;
81
+ },
82
+ enum() {
83
+ return null;
84
+ },
85
+ key() {
86
+ return d;
87
+ },
88
+ optionalKey() {
89
+ return d;
90
+ },
91
+ get array() {
92
+ return null;
93
+ },
94
+ index() {
95
+ return d;
96
+ }
97
+ };
98
+ return d;
99
+ }
100
+ return this;
101
+ }
102
+ get string() {
103
+ if (typeof this.data !== 'string') {
104
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be a string` });
105
+ }
106
+ return this.data;
107
+ }
108
+ get boolean() {
109
+ if (typeof this.data !== 'boolean') {
110
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be a boolean` });
111
+ }
112
+ return this.data;
113
+ }
114
+ get number() {
115
+ if (typeof this.data === 'string') {
116
+ const parsed = parseFloat(this.data);
117
+ if (isNaN(parsed) || parsed.toString() !== this.data) {
118
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be a number, got ${typeof this.data}` });
119
+ }
120
+ return new UnsafeData(parsed, this.context).number;
121
+ }
122
+ if (typeof this.data !== 'number') {
123
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be a number, got ${typeof this.data}` });
124
+ }
125
+ if (Number.isNaN(this.data) || !Number.isFinite(this.data)) {
126
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be a finite number` });
127
+ }
128
+ return this.data;
129
+ }
130
+ get integer() {
131
+ if (typeof this.data === 'string') {
132
+ const parsed = parseInt(this.data);
133
+ if (isNaN(parsed) || parsed.toString() !== this.data) {
134
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be an integer` });
135
+ }
136
+ return new UnsafeData(parseInt(this.data), this.context).integer;
137
+ }
138
+ const number = this.number;
139
+ if (!Number.isSafeInteger(number)) {
140
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be an integer` });
141
+ }
142
+ return number;
143
+ }
144
+ get url() {
145
+ if (this.data instanceof URL) {
146
+ return this.data;
147
+ }
148
+ const string = this.string;
149
+ try {
150
+ const url = new URL(string);
151
+ if (!['http:', 'https:'].includes(url.protocol)) {
152
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be a valid URL` });
153
+ }
154
+ return url;
155
+ }
156
+ catch (e) {
157
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be a valid URL` });
158
+ }
159
+ }
160
+ enum(allowedValues) {
161
+ if (!allowedValues.includes(this.data)) {
162
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be one of ${allowedValues.join(', ')}` });
163
+ }
164
+ return this.data;
165
+ }
166
+ get array() {
167
+ if (!Array.isArray(this.data)) {
168
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be an array` });
169
+ }
170
+ return this.data.map((d, i) => new UnsafeData(d, { field: this.addKeyToField(`${i}`) }));
171
+ }
172
+ index(index) {
173
+ const arr = this.array;
174
+ if (index < 0 || !Number.isSafeInteger(index)) {
175
+ throw new errors_1.default.IncorrectUsageError({ message: `index must be a positive integer` });
176
+ }
177
+ if (index >= arr.length) {
178
+ throw new errors_1.default.ValidationError({ message: `${this.field} must be an array of length ${index + 1}` });
179
+ }
180
+ return arr[index];
181
+ }
182
+ }
183
+ exports.UnsafeData = UnsafeData;
@@ -0,0 +1,217 @@
1
+ import errors from '@tryghost/errors';
2
+
3
+ type UnsafeDataContext = {
4
+ field?: string[]
5
+ }
6
+
7
+ function serializeField(field: string[]) {
8
+ if (field.length === 0) {
9
+ return 'data';
10
+ }
11
+ return field.join('.');
12
+ }
13
+
14
+ type NullData = {
15
+ readonly string: null,
16
+ readonly boolean: null,
17
+ readonly number: null,
18
+ readonly integer: null,
19
+ readonly url: null
20
+ enum(allowedValues: unknown[]): null
21
+ key(key: string): NullData
22
+ optionalKey(key: string): NullData
23
+ readonly array: null
24
+ index(index: number): NullData
25
+ }
26
+
27
+ /**
28
+ * NOTE: should be moved to a separate package in case this pattern is found to be useful
29
+ */
30
+ export class UnsafeData {
31
+ protected data: unknown;
32
+ protected context: UnsafeDataContext;
33
+
34
+ constructor(data: unknown, context: UnsafeDataContext = {}) {
35
+ this.data = data;
36
+ this.context = context;
37
+ }
38
+
39
+ protected get field() {
40
+ return serializeField(this.context.field ?? []);
41
+ }
42
+
43
+ protected addKeyToField(key: string) {
44
+ return this.context.field ? [...this.context.field, key] : [key];
45
+ }
46
+
47
+ protected fieldWithKey(key: string) {
48
+ return serializeField(this.addKeyToField(key));
49
+ }
50
+
51
+ /**
52
+ * Returns undefined if the key is not present on the object. Note that this doesn't check for null.
53
+ */
54
+ optionalKey(key: string): UnsafeData|undefined {
55
+ if (typeof this.data !== 'object' || this.data === null) {
56
+ throw new errors.ValidationError({message: `${this.field} must be an object`});
57
+ }
58
+
59
+ if (!Object.prototype.hasOwnProperty.call(this.data, key)) {
60
+ return undefined;
61
+ }
62
+
63
+ return new UnsafeData((this.data as Record<string, unknown>)[key], {
64
+ field: this.addKeyToField(key)
65
+ });
66
+ }
67
+
68
+ key(key: string): UnsafeData {
69
+ if (typeof this.data !== 'object' || this.data === null) {
70
+ throw new errors.ValidationError({message: `${this.field} must be an object`});
71
+ }
72
+
73
+ if (!Object.prototype.hasOwnProperty.call(this.data, key)) {
74
+ throw new errors.ValidationError({message: `${this.fieldWithKey(key)} is required`});
75
+ }
76
+
77
+ return new UnsafeData((this.data as Record<string, unknown>)[key], {
78
+ field: this.addKeyToField(key)
79
+ });
80
+ }
81
+
82
+ /**
83
+ * Use this to get a nullable value:
84
+ * ```
85
+ * const url: string|null = data.key('url').nullable.string
86
+ * ```
87
+ */
88
+ get nullable(): UnsafeData|NullData {
89
+ if (this.data === null) {
90
+ const d: NullData = {
91
+ get string() {
92
+ return null;
93
+ },
94
+ get boolean() {
95
+ return null;
96
+ },
97
+ get number() {
98
+ return null;
99
+ },
100
+ get integer() {
101
+ return null;
102
+ },
103
+ get url() {
104
+ return null;
105
+ },
106
+ enum() {
107
+ return null;
108
+ },
109
+ key() {
110
+ return d;
111
+ },
112
+ optionalKey() {
113
+ return d;
114
+ },
115
+ get array() {
116
+ return null;
117
+ },
118
+ index() {
119
+ return d;
120
+ }
121
+ };
122
+ return d;
123
+ }
124
+ return this;
125
+ }
126
+
127
+ get string(): string {
128
+ if (typeof this.data !== 'string') {
129
+ throw new errors.ValidationError({message: `${this.field} must be a string`});
130
+ }
131
+ return this.data;
132
+ }
133
+
134
+ get boolean(): boolean {
135
+ if (typeof this.data !== 'boolean') {
136
+ throw new errors.ValidationError({message: `${this.field} must be a boolean`});
137
+ }
138
+ return this.data;
139
+ }
140
+
141
+ get number(): number {
142
+ if (typeof this.data === 'string') {
143
+ const parsed = parseFloat(this.data);
144
+ if (isNaN(parsed) || parsed.toString() !== this.data) {
145
+ throw new errors.ValidationError({message: `${this.field} must be a number, got ${typeof this.data}`});
146
+ }
147
+ return new UnsafeData(parsed, this.context).number;
148
+ }
149
+
150
+ if (typeof this.data !== 'number') {
151
+ throw new errors.ValidationError({message: `${this.field} must be a number, got ${typeof this.data}`});
152
+ }
153
+ if (Number.isNaN(this.data) || !Number.isFinite(this.data)) {
154
+ throw new errors.ValidationError({message: `${this.field} must be a finite number`});
155
+ }
156
+ return this.data;
157
+ }
158
+
159
+ get integer(): number {
160
+ if (typeof this.data === 'string') {
161
+ const parsed = parseInt(this.data);
162
+ if (isNaN(parsed) || parsed.toString() !== this.data) {
163
+ throw new errors.ValidationError({message: `${this.field} must be an integer`});
164
+ }
165
+ return new UnsafeData(parseInt(this.data), this.context).integer;
166
+ }
167
+
168
+ const number = this.number;
169
+ if (!Number.isSafeInteger(number)) {
170
+ throw new errors.ValidationError({message: `${this.field} must be an integer`});
171
+ }
172
+ return number;
173
+ }
174
+
175
+ get url(): URL {
176
+ if (this.data instanceof URL) {
177
+ return this.data;
178
+ }
179
+
180
+ const string = this.string;
181
+ try {
182
+ const url = new URL(string);
183
+
184
+ if (!['http:', 'https:'].includes(url.protocol)) {
185
+ throw new errors.ValidationError({message: `${this.field} must be a valid URL`});
186
+ }
187
+ return url;
188
+ } catch (e) {
189
+ throw new errors.ValidationError({message: `${this.field} must be a valid URL`});
190
+ }
191
+ }
192
+
193
+ enum<T>(allowedValues: T[]): T {
194
+ if (!allowedValues.includes(this.data as T)) {
195
+ throw new errors.ValidationError({message: `${this.field} must be one of ${allowedValues.join(', ')}`});
196
+ }
197
+ return this.data as T;
198
+ }
199
+
200
+ get array(): UnsafeData[] {
201
+ if (!Array.isArray(this.data)) {
202
+ throw new errors.ValidationError({message: `${this.field} must be an array`});
203
+ }
204
+ return this.data.map((d, i) => new UnsafeData(d, {field: this.addKeyToField(`${i}`)}));
205
+ }
206
+
207
+ index(index: number) {
208
+ const arr = this.array;
209
+ if (index < 0 || !Number.isSafeInteger(index)) {
210
+ throw new errors.IncorrectUsageError({message: `index must be a positive integer`});
211
+ }
212
+ if (index >= arr.length) {
213
+ throw new errors.ValidationError({message: `${this.field} must be an array of length ${index + 1}`});
214
+ }
215
+ return arr[index];
216
+ }
217
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.WellknownService = void 0;
7
+ const promises_1 = __importDefault(require("fs/promises"));
8
+ const path_1 = __importDefault(require("path"));
9
+ class WellknownService {
10
+ dir;
11
+ urlUtils;
12
+ constructor({ dir, urlUtils }) {
13
+ this.dir = dir;
14
+ this.urlUtils = urlUtils;
15
+ }
16
+ #formatRecommendation(recommendation) {
17
+ return {
18
+ url: recommendation.url,
19
+ updated_at: (recommendation.updatedAt ?? recommendation.createdAt).toISOString(),
20
+ created_at: (recommendation.createdAt).toISOString()
21
+ };
22
+ }
23
+ getPath() {
24
+ return path_1.default.join(this.dir, '/.well-known/recommendations.json');
25
+ }
26
+ getURL() {
27
+ return new URL(this.urlUtils.relativeToAbsolute('/.well-known/recommendations.json'));
28
+ }
29
+ async set(recommendations) {
30
+ const content = JSON.stringify(recommendations.map(r => this.#formatRecommendation(r)));
31
+ const path = this.getPath();
32
+ await promises_1.default.mkdir(path_1.default.dirname(path), { recursive: true });
33
+ await promises_1.default.writeFile(path, content);
34
+ }
35
+ }
36
+ exports.WellknownService = WellknownService;
@@ -0,0 +1,47 @@
1
+ import {Recommendation} from './Recommendation';
2
+ import fs from 'fs/promises';
3
+ import _path from 'path';
4
+
5
+ type UrlUtils = {
6
+ relativeToAbsolute(url: string): string
7
+ }
8
+ type Options = {
9
+ /**
10
+ * Where to publish the wellknown file
11
+ */
12
+ dir: string,
13
+ urlUtils: UrlUtils
14
+ }
15
+
16
+ export class WellknownService {
17
+ dir: string;
18
+ urlUtils: UrlUtils;
19
+
20
+ constructor({dir, urlUtils}: Options) {
21
+ this.dir = dir;
22
+ this.urlUtils = urlUtils;
23
+ }
24
+
25
+ #formatRecommendation(recommendation: Recommendation) {
26
+ return {
27
+ url: recommendation.url,
28
+ updated_at: (recommendation.updatedAt ?? recommendation.createdAt).toISOString(),
29
+ created_at: (recommendation.createdAt).toISOString()
30
+ };
31
+ }
32
+
33
+ getPath() {
34
+ return _path.join(this.dir, '/.well-known/recommendations.json');
35
+ }
36
+
37
+ getURL(): URL {
38
+ return new URL(this.urlUtils.relativeToAbsolute('/.well-known/recommendations.json'));
39
+ }
40
+
41
+ async set(recommendations: Recommendation[]) {
42
+ const content = JSON.stringify(recommendations.map(r => this.#formatRecommendation(r)));
43
+ const path = this.getPath();
44
+ await fs.mkdir(_path.dirname(path), {recursive: true});
45
+ await fs.writeFile(path, content);
46
+ }
47
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./RecommendationController"), exports);
18
+ __exportStar(require("./RecommendationService"), exports);
19
+ __exportStar(require("./RecommendationRepository"), exports);
20
+ __exportStar(require("./InMemoryRecommendationRepository"), exports);
21
+ __exportStar(require("./Recommendation"), exports);
22
+ __exportStar(require("./WellknownService"), exports);
23
+ __exportStar(require("./BookshelfRecommendationRepository"), exports);
24
+ __exportStar(require("./ClickEvent"), exports);
25
+ __exportStar(require("./BookshelfClickEventRepository"), exports);
26
+ __exportStar(require("./SubscribeEvent"), exports);
27
+ __exportStar(require("./BookshelfSubscribeEventRepository"), exports);
28
+ __exportStar(require("./IncomingRecommendationController"), exports);
29
+ __exportStar(require("./IncomingRecommendationService"), exports);
30
+ __exportStar(require("./IncomingRecommendationEmailRenderer"), exports);
31
+ __exportStar(require("./RecommendationMetadataService"), exports);
@@ -0,0 +1,15 @@
1
+ export * from './RecommendationController';
2
+ export * from './RecommendationService';
3
+ export * from './RecommendationRepository';
4
+ export * from './InMemoryRecommendationRepository';
5
+ export * from './Recommendation';
6
+ export * from './WellknownService';
7
+ export * from './BookshelfRecommendationRepository';
8
+ export * from './ClickEvent';
9
+ export * from './BookshelfClickEventRepository';
10
+ export * from './SubscribeEvent';
11
+ export * from './BookshelfSubscribeEventRepository';
12
+ export * from './IncomingRecommendationController';
13
+ export * from './IncomingRecommendationService';
14
+ export * from './IncomingRecommendationEmailRenderer';
15
+ export * from './RecommendationMetadataService';
@@ -0,0 +1,5 @@
1
+ declare module '@tryghost/errors';
2
+ declare module '@tryghost/tpl';
3
+ declare module '@tryghost/logging';
4
+ declare module '@tryghost/mongo-utils';
5
+ declare module '@tryghost/nql';
@@ -0,0 +1,47 @@
1
+ const path = require('path');
2
+ const tpl = require('@tryghost/tpl');
3
+ const format = require('date-fns/format');
4
+ const {IncorrectUsageError} = require('@tryghost/errors');
5
+
6
+ const messages = {
7
+ incorrectPathsParameter: 'Attempted to setup settings path manager without paths values.'
8
+ };
9
+
10
+ class SettingsPathManager {
11
+ /**
12
+ *
13
+ * @param {Object} options
14
+ * @param {String[]} options.paths - file location paths ordered in priority by where to locate them first
15
+ * @param {String} options.type setting file type, e.g: 'routes' or 'redirects'
16
+ * @param {String[]} [options.extensions] the supported file extensions with 'yaml' and 'json' defaults. Note 'yml' extension is ignored on purpose
17
+ */
18
+ constructor({type, paths, extensions = ['yaml', 'json']}) {
19
+ if (!paths || !paths.length) {
20
+ throw new IncorrectUsageError({
21
+ message: tpl(messages.incorrectPathsParameter)
22
+ });
23
+ }
24
+
25
+ this.type = type;
26
+ this.filename = type;
27
+
28
+ this.paths = paths;
29
+ this.defaultPath = paths[0];
30
+
31
+ this.extensions = extensions;
32
+ this.defaultExtension = extensions[0];
33
+ }
34
+
35
+ getDefaultFilePath() {
36
+ const settingsFolder = this.defaultPath;
37
+ return path.join(settingsFolder, `${this.filename}.${this.defaultExtension}`);
38
+ }
39
+
40
+ getBackupFilePath() {
41
+ const settingsFolder = this.defaultPath;
42
+ const dateStamp = format(new Date(), 'yyyy-MM-dd-HH-mm-ss');
43
+ return path.join(settingsFolder, `${this.filename}-${dateStamp}.${this.defaultExtension}`);
44
+ }
45
+ }
46
+
47
+ module.exports = SettingsPathManager;
@@ -1,6 +1,5 @@
1
1
  const config = require('../../../shared/config');
2
2
  const parseYaml = require('./yaml-parser');
3
- const SettingsPathManager = require('@tryghost/settings-path-manager');
4
3
 
5
4
  let settingsLoader;
6
5
  let routeSettings;
@@ -10,6 +9,7 @@ module.exports = {
10
9
  const RouteSettings = require('./RouteSettings');
11
10
  const SettingsLoader = require('./SettingsLoader');
12
11
  const DefaultSettingsManager = require('./DefaultSettingsManager');
12
+ const SettingsPathManager = require('./SettingsPathManager');
13
13
 
14
14
  const settingsPathManager = new SettingsPathManager({type: 'routes', paths: [config.getContentPath('settings')]});
15
15
  settingsLoader = new SettingsLoader({parseYaml, settingFilePath: settingsPathManager.getDefaultFilePath()});