ghost 5.98.0 → 5.99.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 (178) hide show
  1. package/components/tryghost-adapter-cache-memory-ttl-5.99.0.tgz +0 -0
  2. package/components/tryghost-adapter-cache-redis-5.99.0.tgz +0 -0
  3. package/components/tryghost-adapter-manager-5.99.0.tgz +0 -0
  4. package/components/tryghost-announcement-bar-settings-5.99.0.tgz +0 -0
  5. package/components/tryghost-api-framework-5.99.0.tgz +0 -0
  6. package/components/{tryghost-api-version-compatibility-service-5.98.0.tgz → tryghost-api-version-compatibility-service-5.99.0.tgz} +0 -0
  7. package/components/tryghost-audience-feedback-5.99.0.tgz +0 -0
  8. package/components/tryghost-bookshelf-repository-5.99.0.tgz +0 -0
  9. package/components/tryghost-bootstrap-socket-5.99.0.tgz +0 -0
  10. package/components/tryghost-collections-5.99.0.tgz +0 -0
  11. package/components/tryghost-constants-5.99.0.tgz +0 -0
  12. package/components/tryghost-custom-fonts-5.99.0.tgz +0 -0
  13. package/components/tryghost-custom-theme-settings-service-5.99.0.tgz +0 -0
  14. package/components/{tryghost-data-generator-5.98.0.tgz → tryghost-data-generator-5.99.0.tgz} +0 -0
  15. package/components/tryghost-domain-events-5.99.0.tgz +0 -0
  16. package/components/{tryghost-donations-5.98.0.tgz → tryghost-donations-5.99.0.tgz} +0 -0
  17. package/components/tryghost-dynamic-routing-events-5.99.0.tgz +0 -0
  18. package/components/tryghost-email-addresses-5.99.0.tgz +0 -0
  19. package/components/tryghost-email-analytics-provider-mailgun-5.99.0.tgz +0 -0
  20. package/components/{tryghost-email-analytics-service-5.98.0.tgz → tryghost-email-analytics-service-5.99.0.tgz} +0 -0
  21. package/components/tryghost-email-content-generator-5.99.0.tgz +0 -0
  22. package/components/tryghost-email-events-5.99.0.tgz +0 -0
  23. package/components/tryghost-email-service-5.99.0.tgz +0 -0
  24. package/components/tryghost-email-suppression-list-5.99.0.tgz +0 -0
  25. package/components/tryghost-express-dynamic-redirects-5.99.0.tgz +0 -0
  26. package/components/tryghost-external-media-inliner-5.99.0.tgz +0 -0
  27. package/components/tryghost-extract-api-key-5.99.0.tgz +0 -0
  28. package/components/tryghost-ghost-5.99.0.tgz +0 -0
  29. package/components/tryghost-html-to-plaintext-5.99.0.tgz +0 -0
  30. package/components/tryghost-i18n-5.99.0.tgz +0 -0
  31. package/components/tryghost-importer-handler-content-files-5.99.0.tgz +0 -0
  32. package/components/{tryghost-importer-revue-5.98.0.tgz → tryghost-importer-revue-5.99.0.tgz} +0 -0
  33. package/components/tryghost-in-memory-repository-5.99.0.tgz +0 -0
  34. package/components/{tryghost-job-manager-5.98.0.tgz → tryghost-job-manager-5.99.0.tgz} +0 -0
  35. package/components/{tryghost-link-redirects-5.98.0.tgz → tryghost-link-redirects-5.99.0.tgz} +0 -0
  36. package/components/tryghost-link-replacer-5.99.0.tgz +0 -0
  37. package/components/{tryghost-link-tracking-5.98.0.tgz → tryghost-link-tracking-5.99.0.tgz} +0 -0
  38. package/components/{tryghost-magic-link-5.98.0.tgz → tryghost-magic-link-5.99.0.tgz} +0 -0
  39. package/components/tryghost-mail-events-5.99.0.tgz +0 -0
  40. package/components/{tryghost-mailgun-client-5.98.0.tgz → tryghost-mailgun-client-5.99.0.tgz} +0 -0
  41. package/components/tryghost-member-attribution-5.99.0.tgz +0 -0
  42. package/components/tryghost-member-events-5.99.0.tgz +0 -0
  43. package/components/tryghost-members-api-5.99.0.tgz +0 -0
  44. package/components/tryghost-members-csv-5.99.0.tgz +0 -0
  45. package/components/tryghost-members-events-service-5.99.0.tgz +0 -0
  46. package/components/tryghost-members-importer-5.99.0.tgz +0 -0
  47. package/components/tryghost-members-offers-5.99.0.tgz +0 -0
  48. package/components/tryghost-members-payments-5.99.0.tgz +0 -0
  49. package/components/{tryghost-members-ssr-5.98.0.tgz → tryghost-members-ssr-5.99.0.tgz} +0 -0
  50. package/components/tryghost-members-stripe-service-5.99.0.tgz +0 -0
  51. package/components/tryghost-mentions-email-report-5.99.0.tgz +0 -0
  52. package/components/tryghost-metrics-server-5.99.0.tgz +0 -0
  53. package/components/tryghost-milestones-5.99.0.tgz +0 -0
  54. package/components/tryghost-minifier-5.99.0.tgz +0 -0
  55. package/components/tryghost-model-to-domain-event-interceptor-5.99.0.tgz +0 -0
  56. package/components/tryghost-mw-api-version-mismatch-5.99.0.tgz +0 -0
  57. package/components/tryghost-mw-cache-control-5.99.0.tgz +0 -0
  58. package/components/tryghost-mw-error-handler-5.99.0.tgz +0 -0
  59. package/components/tryghost-mw-session-from-token-5.99.0.tgz +0 -0
  60. package/components/tryghost-mw-update-user-last-seen-5.99.0.tgz +0 -0
  61. package/components/{tryghost-mw-version-match-5.98.0.tgz → tryghost-mw-version-match-5.99.0.tgz} +0 -0
  62. package/components/tryghost-mw-vhost-5.99.0.tgz +0 -0
  63. package/components/{tryghost-nql-filter-expansions-5.98.0.tgz → tryghost-nql-filter-expansions-5.99.0.tgz} +0 -0
  64. package/components/tryghost-oembed-service-5.99.0.tgz +0 -0
  65. package/components/tryghost-package-json-5.99.0.tgz +0 -0
  66. package/components/tryghost-post-events-5.99.0.tgz +0 -0
  67. package/components/tryghost-post-revisions-5.99.0.tgz +0 -0
  68. package/components/tryghost-posts-service-5.99.0.tgz +0 -0
  69. package/components/tryghost-recommendations-5.99.0.tgz +0 -0
  70. package/components/tryghost-referrers-5.99.0.tgz +0 -0
  71. package/components/{tryghost-security-5.98.0.tgz → tryghost-security-5.99.0.tgz} +0 -0
  72. package/components/tryghost-session-service-5.99.0.tgz +0 -0
  73. package/components/tryghost-settings-path-manager-5.99.0.tgz +0 -0
  74. package/components/tryghost-slack-notifications-5.99.0.tgz +0 -0
  75. package/components/{tryghost-staff-service-5.98.0.tgz → tryghost-staff-service-5.99.0.tgz} +0 -0
  76. package/components/{tryghost-stats-service-5.98.0.tgz → tryghost-stats-service-5.99.0.tgz} +0 -0
  77. package/components/{tryghost-tiers-5.98.0.tgz → tryghost-tiers-5.99.0.tgz} +0 -0
  78. package/components/{tryghost-update-check-service-5.98.0.tgz → tryghost-update-check-service-5.99.0.tgz} +0 -0
  79. package/components/tryghost-verification-trigger-5.99.0.tgz +0 -0
  80. package/components/tryghost-version-notifications-data-service-5.99.0.tgz +0 -0
  81. package/components/tryghost-webmentions-5.99.0.tgz +0 -0
  82. package/core/built/admin/assets/admin-x-activitypub/admin-x-activitypub.js +2 -2
  83. package/core/built/admin/assets/admin-x-activitypub/{index-d0087e93.mjs → index-696e3897.mjs} +3695 -3594
  84. package/core/built/admin/assets/admin-x-activitypub/{modals-aaaeb2ed.mjs → modals-dc93ce65.mjs} +2 -2
  85. package/core/built/admin/assets/admin-x-demo/admin-x-demo.js +1 -1
  86. package/core/built/admin/assets/admin-x-demo/{index-ec1c4705.mjs → index-ff63fc71.mjs} +11 -10
  87. package/core/built/admin/assets/admin-x-demo/{modals-3bfb50e8.mjs → modals-c5353ca0.mjs} +2 -2
  88. package/core/built/admin/assets/admin-x-settings/{CodeEditorView-72579105.mjs → CodeEditorView-e6f6e0b3.mjs} +2 -2
  89. package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +2 -2
  90. package/core/built/admin/assets/admin-x-settings/{index-c8b38805.mjs → index-2a9ec06c.mjs} +2 -2
  91. package/core/built/admin/assets/admin-x-settings/{index-253cc6ec.mjs → index-8ede56c6.mjs} +23 -20
  92. package/core/built/admin/assets/admin-x-settings/{modals-e1b17636.mjs → modals-e3497e68.mjs} +7 -8
  93. package/core/built/admin/assets/{chunk.524.3ed488a4afaa8dc49de8.js → chunk.524.85082593cb84282804e5.js} +5 -5
  94. package/core/built/admin/assets/{chunk.582.4832ffb3f13ae2b00734.js → chunk.582.a756882ecb6d421c862c.js} +7 -7
  95. package/core/built/admin/assets/{ghost-84fc705038c0ea946e4e5048ccb1fea5.css → ghost-5be0a663eecbd5db9c3612b90050fa66.css} +1 -1
  96. package/core/built/admin/assets/ghost-dark-562f74b99cec55f89d4c6cc82ab5ad51.css +1 -0
  97. package/core/built/admin/assets/{ghost-7a6db87f125f7ea41beb7a88d500e8dc.js → ghost-fefa2e99b7dc389dfd6579049cdd2066.js} +11 -8
  98. package/core/built/admin/assets/koenig-lexical/index.css +1 -1
  99. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +13236 -13223
  100. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +134 -134
  101. package/core/built/admin/index.html +4 -4
  102. package/core/frontend/helpers/ghost_head.js +60 -52
  103. package/core/frontend/src/cards/css/signup.css +1 -0
  104. package/core/server/api/endpoints/utils/serializers/output/mappers/index.js +1 -0
  105. package/core/server/api/endpoints/utils/serializers/output/mappers/oembed.js +5 -0
  106. package/core/server/api/endpoints/utils/serializers/output/oembed.js +7 -0
  107. package/core/server/services/email-service/EmailServiceWrapper.js +5 -2
  108. package/core/server/services/i18n.js +1 -1
  109. package/core/server/services/oembed/TwitterOEmbedProvider.js +8 -0
  110. package/core/server/services/oembed/service.js +2 -1
  111. package/core/shared/config/defaults.json +2 -2
  112. package/core/shared/settings-cache/CacheManager.js +9 -0
  113. package/package.json +152 -152
  114. package/yarn.lock +98 -87
  115. package/components/tryghost-adapter-cache-memory-ttl-5.98.0.tgz +0 -0
  116. package/components/tryghost-adapter-cache-redis-5.98.0.tgz +0 -0
  117. package/components/tryghost-adapter-manager-5.98.0.tgz +0 -0
  118. package/components/tryghost-announcement-bar-settings-5.98.0.tgz +0 -0
  119. package/components/tryghost-api-framework-5.98.0.tgz +0 -0
  120. package/components/tryghost-audience-feedback-5.98.0.tgz +0 -0
  121. package/components/tryghost-bookshelf-repository-5.98.0.tgz +0 -0
  122. package/components/tryghost-bootstrap-socket-5.98.0.tgz +0 -0
  123. package/components/tryghost-collections-5.98.0.tgz +0 -0
  124. package/components/tryghost-constants-5.98.0.tgz +0 -0
  125. package/components/tryghost-custom-fonts-5.98.0.tgz +0 -0
  126. package/components/tryghost-custom-theme-settings-service-5.98.0.tgz +0 -0
  127. package/components/tryghost-domain-events-5.98.0.tgz +0 -0
  128. package/components/tryghost-dynamic-routing-events-5.98.0.tgz +0 -0
  129. package/components/tryghost-email-addresses-5.98.0.tgz +0 -0
  130. package/components/tryghost-email-analytics-provider-mailgun-5.98.0.tgz +0 -0
  131. package/components/tryghost-email-content-generator-5.98.0.tgz +0 -0
  132. package/components/tryghost-email-events-5.98.0.tgz +0 -0
  133. package/components/tryghost-email-service-5.98.0.tgz +0 -0
  134. package/components/tryghost-email-suppression-list-5.98.0.tgz +0 -0
  135. package/components/tryghost-express-dynamic-redirects-5.98.0.tgz +0 -0
  136. package/components/tryghost-external-media-inliner-5.98.0.tgz +0 -0
  137. package/components/tryghost-extract-api-key-5.98.0.tgz +0 -0
  138. package/components/tryghost-ghost-5.98.0.tgz +0 -0
  139. package/components/tryghost-html-to-plaintext-5.98.0.tgz +0 -0
  140. package/components/tryghost-i18n-5.98.0.tgz +0 -0
  141. package/components/tryghost-importer-handler-content-files-5.98.0.tgz +0 -0
  142. package/components/tryghost-in-memory-repository-5.98.0.tgz +0 -0
  143. package/components/tryghost-link-replacer-5.98.0.tgz +0 -0
  144. package/components/tryghost-mail-events-5.98.0.tgz +0 -0
  145. package/components/tryghost-member-attribution-5.98.0.tgz +0 -0
  146. package/components/tryghost-member-events-5.98.0.tgz +0 -0
  147. package/components/tryghost-members-api-5.98.0.tgz +0 -0
  148. package/components/tryghost-members-csv-5.98.0.tgz +0 -0
  149. package/components/tryghost-members-events-service-5.98.0.tgz +0 -0
  150. package/components/tryghost-members-importer-5.98.0.tgz +0 -0
  151. package/components/tryghost-members-offers-5.98.0.tgz +0 -0
  152. package/components/tryghost-members-payments-5.98.0.tgz +0 -0
  153. package/components/tryghost-members-stripe-service-5.98.0.tgz +0 -0
  154. package/components/tryghost-mentions-email-report-5.98.0.tgz +0 -0
  155. package/components/tryghost-metrics-server-5.98.0.tgz +0 -0
  156. package/components/tryghost-milestones-5.98.0.tgz +0 -0
  157. package/components/tryghost-minifier-5.98.0.tgz +0 -0
  158. package/components/tryghost-model-to-domain-event-interceptor-5.98.0.tgz +0 -0
  159. package/components/tryghost-mw-api-version-mismatch-5.98.0.tgz +0 -0
  160. package/components/tryghost-mw-cache-control-5.98.0.tgz +0 -0
  161. package/components/tryghost-mw-error-handler-5.98.0.tgz +0 -0
  162. package/components/tryghost-mw-session-from-token-5.98.0.tgz +0 -0
  163. package/components/tryghost-mw-update-user-last-seen-5.98.0.tgz +0 -0
  164. package/components/tryghost-mw-vhost-5.98.0.tgz +0 -0
  165. package/components/tryghost-oembed-service-5.98.0.tgz +0 -0
  166. package/components/tryghost-package-json-5.98.0.tgz +0 -0
  167. package/components/tryghost-post-events-5.98.0.tgz +0 -0
  168. package/components/tryghost-post-revisions-5.98.0.tgz +0 -0
  169. package/components/tryghost-posts-service-5.98.0.tgz +0 -0
  170. package/components/tryghost-recommendations-5.98.0.tgz +0 -0
  171. package/components/tryghost-referrers-5.98.0.tgz +0 -0
  172. package/components/tryghost-session-service-5.98.0.tgz +0 -0
  173. package/components/tryghost-settings-path-manager-5.98.0.tgz +0 -0
  174. package/components/tryghost-slack-notifications-5.98.0.tgz +0 -0
  175. package/components/tryghost-verification-trigger-5.98.0.tgz +0 -0
  176. package/components/tryghost-version-notifications-data-service-5.98.0.tgz +0 -0
  177. package/components/tryghost-webmentions-5.98.0.tgz +0 -0
  178. package/core/built/admin/assets/ghost-dark-b00268cf596f7bba8699dce557d65585.css +0 -1
@@ -8,7 +8,7 @@
8
8
  <title>Ghost Admin</title>
9
9
 
10
10
 
11
- <meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.98%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%22ee37f0b9eb%22%2C%22adminXDemoFilename%22%3A%22admin-x-demo.js%22%2C%22adminXDemoHash%22%3A%221b17317b1f%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%22a887193dcd%22%2C%22adminXActivitypubFilename%22%3A%22admin-x-activitypub.js%22%2C%22adminXActivitypubHash%22%3A%22ad0a25d390%22%2C%22adminXActivitypubCustomUrl%22%3A%22https%3A%2F%2Fcdn.jsdelivr.net%2Fghost%2Fadmin-x-activitypub%400%2Fdist%2Fadmin-x-activitypub.js%22%7D" />
11
+ <meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.99%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%22a724a31dfe%22%2C%22adminXDemoFilename%22%3A%22admin-x-demo.js%22%2C%22adminXDemoHash%22%3A%22118f338ce4%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%2224993c916e%22%2C%22adminXActivitypubFilename%22%3A%22admin-x-activitypub.js%22%2C%22adminXActivitypubHash%22%3A%22f172caf7c8%22%2C%22adminXActivitypubCustomUrl%22%3A%22https%3A%2F%2Fcdn.jsdelivr.net%2Fghost%2Fadmin-x-activitypub%400%2Fdist%2Fadmin-x-activitypub.js%22%7D" />
12
12
 
13
13
  <meta name="HandheldFriendly" content="True" />
14
14
  <meta name="MobileOptimized" content="320" />
@@ -37,7 +37,7 @@
37
37
  </style>
38
38
 
39
39
  <link integrity="" rel="stylesheet" href="assets/vendor-0ede59da8efb5e28fa929557f7ff7154.css">
40
- <link integrity="" rel="stylesheet" href="assets/ghost-84fc705038c0ea946e4e5048ccb1fea5.css" title="light">
40
+ <link integrity="" rel="stylesheet" href="assets/ghost-5be0a663eecbd5db9c3612b90050fa66.css" title="light">
41
41
 
42
42
 
43
43
  </head>
@@ -58,7 +58,7 @@
58
58
 
59
59
  <script src="assets/vendor-88cd9f5cf5eba65221e2d2a636531eaa.js"></script>
60
60
  <script src="assets/chunk.874.5eb920d19e75683234c2.js"></script>
61
- <script src="assets/chunk.524.3ed488a4afaa8dc49de8.js"></script>
62
- <script src="assets/ghost-7a6db87f125f7ea41beb7a88d500e8dc.js"></script>
61
+ <script src="assets/chunk.524.85082593cb84282804e5.js"></script>
62
+ <script src="assets/ghost-fefa2e99b7dc389dfd6579049cdd2066.js"></script>
63
63
  </body>
64
64
  </html>
@@ -48,28 +48,31 @@ function finaliseStructuredData(meta) {
48
48
  return head;
49
49
  }
50
50
 
51
- function getMembersHelper(data, frontendKey) {
51
+ function getMembersHelper(data, frontendKey, excludeList) {
52
52
  // Do not load Portal if both Memberships and Tips & Donations and Recommendations are disabled
53
53
  if (!settingsCache.get('members_enabled') && !settingsCache.get('donations_enabled') && !settingsCache.get('recommendations_enabled')) {
54
54
  return '';
55
55
  }
56
-
57
- const {scriptUrl} = getFrontendAppConfig('portal');
58
-
59
- const colorString = (_.has(data, 'site._preview') && data.site.accent_color) ? data.site.accent_color : '';
60
- const attributes = {
61
- i18n: labs.isSet('i18n'),
62
- ghost: urlUtils.getSiteUrl(),
63
- key: frontendKey,
64
- api: urlUtils.urlFor('api', {type: 'content'}, true)
65
- };
66
- if (colorString) {
67
- attributes['accent-color'] = colorString;
56
+ let membersHelper = '';
57
+ if (!excludeList.has('portal')) {
58
+ const {scriptUrl} = getFrontendAppConfig('portal');
59
+
60
+ const colorString = (_.has(data, 'site._preview') && data.site.accent_color) ? data.site.accent_color : '';
61
+ const attributes = {
62
+ i18n: labs.isSet('i18n'),
63
+ ghost: urlUtils.getSiteUrl(),
64
+ key: frontendKey,
65
+ api: urlUtils.urlFor('api', {type: 'content'}, true)
66
+ };
67
+ if (colorString) {
68
+ attributes['accent-color'] = colorString;
69
+ }
70
+ const dataAttributes = getDataAttributes(attributes);
71
+ membersHelper += `<script defer src="${scriptUrl}" ${dataAttributes} crossorigin="anonymous"></script>`;
72
+ }
73
+ if (!excludeList.has('cta_styles')) {
74
+ membersHelper += (`<style id="gh-members-styles">${templateStyles}</style>`);
68
75
  }
69
- const dataAttributes = getDataAttributes(attributes);
70
-
71
- let membersHelper = `<script defer src="${scriptUrl}" ${dataAttributes} crossorigin="anonymous"></script>`;
72
- membersHelper += (`<style id="gh-members-styles">${templateStyles}</style>`);
73
76
  if (settingsCache.get('paid_members_enabled')) {
74
77
  // disable fraud detection for e2e tests to reduce waiting time
75
78
  const isFraudSignalsEnabled = process.env.NODE_ENV === 'testing-browser' ? '?advancedFraudSignals=false' : '';
@@ -91,7 +94,7 @@ function getSearchHelper(frontendKey) {
91
94
  key: frontendKey,
92
95
  styles: stylesUrl,
93
96
  'sodo-search': adminUrl,
94
- locale: settingsCache.get('locale') || 'en'
97
+ locale: labs.isSet('i18n') ? (settingsCache.get('locale') || 'en') : undefined
95
98
  };
96
99
  const dataAttrs = getDataAttributes(attrs);
97
100
  let helper = `<script defer src="${scriptUrl}" ${dataAttrs} crossorigin="anonymous"></script>`;
@@ -198,12 +201,11 @@ function getTinybirdTrackerScript(dataRoot) {
198
201
  // We use the name ghost_head to match the helper for consistency:
199
202
  module.exports = async function ghost_head(options) { // eslint-disable-line camelcase
200
203
  debug('begin');
201
-
202
204
  // if server error page do nothing
203
205
  if (options.data.root.statusCode >= 500) {
204
206
  return;
205
207
  }
206
-
208
+ const excludeList = new Set(options?.hash?.exclude?.split(',') || []);
207
209
  const head = [];
208
210
  const dataRoot = options.data.root;
209
211
  const context = dataRoot._locals.context ? dataRoot._locals.context : null;
@@ -234,25 +236,26 @@ module.exports = async function ghost_head(options) { // eslint-disable-line cam
234
236
  debug('end fetch');
235
237
 
236
238
  if (context) {
237
- // head is our main array that holds our meta data
238
- if (meta.metaDescription && meta.metaDescription.length > 0) {
239
- head.push('<meta name="description" content="' + escapeExpression(meta.metaDescription) + '">');
240
- }
239
+ if (!excludeList.has('metadata')) {
240
+ // head is our main array that holds our meta data
241
+ if (meta.metaDescription && meta.metaDescription.length > 0) {
242
+ head.push('<meta name="description" content="' + escapeExpression(meta.metaDescription) + '">');
243
+ }
241
244
 
242
- // no output in head if a publication icon is not set
243
- if (settingsCache.get('icon')) {
244
- head.push('<link rel="icon" href="' + favicon + '" type="image/' + iconType + '">');
245
- }
245
+ // no output in head if a publication icon is not set
246
+ if (settingsCache.get('icon')) {
247
+ head.push('<link rel="icon" href="' + favicon + '" type="image/' + iconType + '">');
248
+ }
246
249
 
247
- head.push('<link rel="canonical" href="' + escapeExpression(meta.canonicalUrl) + '">');
250
+ head.push('<link rel="canonical" href="' + escapeExpression(meta.canonicalUrl) + '">');
248
251
 
249
- if (_.includes(context, 'preview')) {
250
- head.push(writeMetaTag('robots', 'noindex,nofollow', 'name'));
251
- head.push(writeMetaTag('referrer', 'same-origin', 'name'));
252
- } else {
253
- head.push(writeMetaTag('referrer', referrerPolicy, 'name'));
252
+ if (_.includes(context, 'preview')) {
253
+ head.push(writeMetaTag('robots', 'noindex,nofollow', 'name'));
254
+ head.push(writeMetaTag('referrer', 'same-origin', 'name'));
255
+ } else {
256
+ head.push(writeMetaTag('referrer', referrerPolicy, 'name'));
257
+ }
254
258
  }
255
-
256
259
  // show amp link in post when 1. we are not on the amp page and 2. amp is enabled
257
260
  if (_.includes(context, 'post') && !_.includes(context, 'amp') && settingsCache.get('amp')) {
258
261
  head.push('<link rel="amphtml" href="' +
@@ -270,30 +273,33 @@ module.exports = async function ghost_head(options) { // eslint-disable-line cam
270
273
  }
271
274
 
272
275
  if (!_.includes(context, 'paged') && useStructuredData) {
273
- head.push('');
274
- head.push.apply(head, finaliseStructuredData(meta));
275
- head.push('');
276
+ if (!excludeList.has('social_data')) {
277
+ head.push('');
278
+ head.push.apply(head, finaliseStructuredData(meta));
279
+ head.push('');
280
+ }
276
281
 
277
- if (meta.schema) {
282
+ if (!excludeList.has('schema') && meta.schema) {
278
283
  head.push('<script type="application/ld+json">\n' +
279
284
  JSON.stringify(meta.schema, null, ' ') +
280
285
  '\n </script>\n');
281
286
  }
282
287
  }
283
288
  }
284
-
285
289
  head.push('<meta name="generator" content="Ghost ' +
286
290
  escapeExpression(safeVersion) + '">');
287
-
288
291
  head.push('<link rel="alternate" type="application/rss+xml" title="' +
289
292
  escapeExpression(meta.site.title) + '" href="' +
290
293
  escapeExpression(meta.rssUrl) + '">');
291
-
292
294
  // no code injection for amp context!!!
293
295
  if (!_.includes(context, 'amp')) {
294
- head.push(getMembersHelper(options.data, frontendKey));
295
- head.push(getSearchHelper(frontendKey));
296
- head.push(getAnnouncementBarHelper(options.data));
296
+ head.push(getMembersHelper(options.data, frontendKey, excludeList)); // controlling for excludes within the function
297
+ if (!excludeList.has('search')) {
298
+ head.push(getSearchHelper(frontendKey));
299
+ }
300
+ if (!excludeList.has('announcement')) {
301
+ head.push(getAnnouncementBarHelper(options.data));
302
+ }
297
303
  try {
298
304
  head.push(getWebmentionDiscoveryLink());
299
305
  } catch (err) {
@@ -301,14 +307,17 @@ module.exports = async function ghost_head(options) { // eslint-disable-line cam
301
307
  }
302
308
 
303
309
  // @TODO do this in a more "frameworky" way
304
- if (cardAssets.hasFile('js')) {
305
- head.push(`<script defer src="${getAssetUrl('public/cards.min.js')}"></script>`);
306
- }
307
- if (cardAssets.hasFile('css')) {
308
- head.push(`<link rel="stylesheet" type="text/css" href="${getAssetUrl('public/cards.min.css')}">`);
310
+
311
+ if (!excludeList.has('card_assets')) {
312
+ if (cardAssets.hasFile('js')) {
313
+ head.push(`<script defer src="${getAssetUrl('public/cards.min.js')}"></script>`);
314
+ }
315
+ if (cardAssets.hasFile('css')) {
316
+ head.push(`<link rel="stylesheet" type="text/css" href="${getAssetUrl('public/cards.min.css')}">`);
317
+ }
309
318
  }
310
319
 
311
- if (settingsCache.get('comments_enabled') !== 'off') {
320
+ if (!excludeList.has('comment_counts') && settingsCache.get('comments_enabled') !== 'off') {
312
321
  head.push(`<script defer src="${getAssetUrl('public/comment-counts.min.js')}" data-ghost-comments-counts-api="${urlUtils.getSiteUrl(true)}members/api/comments/counts/"></script>`);
313
322
  }
314
323
 
@@ -327,7 +336,6 @@ module.exports = async function ghost_head(options) { // eslint-disable-line cam
327
336
  head.push(styleTag);
328
337
  }
329
338
  }
330
-
331
339
  if (!_.isEmpty(globalCodeinjection)) {
332
340
  head.push(globalCodeinjection);
333
341
  }
@@ -223,6 +223,7 @@
223
223
  align-items: center;
224
224
  height: 2.9em;
225
225
  min-height: 46px;
226
+ height: 100%;
226
227
  padding: 0 1.2em;
227
228
  outline: none;
228
229
  border: none;
@@ -9,6 +9,7 @@ module.exports = {
9
9
  emailFailures: require('./email-failures'),
10
10
  images: require('./images'),
11
11
  integrations: require('./integrations'),
12
+ oembed: require('./oembed'),
12
13
  pages: require('./pages'),
13
14
  posts: require('./posts'),
14
15
  settings: require('./settings'),
@@ -0,0 +1,5 @@
1
+ const url = require('../utils/url');
2
+
3
+ module.exports = (path) => {
4
+ return url.forImage(path);
5
+ };
@@ -1,8 +1,15 @@
1
1
  const debug = require('@tryghost/debug')('api:endpoints:utils:serializers:output:oembed');
2
+ const mappers = require('./mappers');
2
3
 
3
4
  module.exports = {
4
5
  all(data, apiConfig, frame) {
5
6
  debug('all');
7
+ if (data?.metadata?.thumbnail) {
8
+ data.metadata.thumbnail = mappers.oembed(data.metadata.thumbnail);
9
+ }
10
+ if (data?.metadata?.icon) {
11
+ data.metadata.icon = mappers.oembed(data.metadata.icon);
12
+ }
6
13
  frame.response = data;
7
14
  }
8
15
  };
@@ -27,7 +27,7 @@ class EmailServiceWrapper {
27
27
  const limitService = require('../limits');
28
28
  const labs = require('../../../shared/labs');
29
29
  const emailAddressService = require('../email-address');
30
-
30
+ const i18nLib = require('@tryghost/i18n');
31
31
  const mobiledocLib = require('../../lib/mobiledoc');
32
32
  const lexicalLib = require('../../lib/lexical');
33
33
  const urlUtils = require('../../../shared/url-utils');
@@ -49,6 +49,8 @@ class EmailServiceWrapper {
49
49
  const mailgunClient = new MailgunClient({
50
50
  config: configService, settings: settingsCache
51
51
  });
52
+ const i18nLanguage = settingsCache.get('locale') || 'en';
53
+ const i18n = i18nLib(i18nLanguage, 'newsletter');
52
54
 
53
55
  const mailgunEmailProvider = new MailgunEmailProvider({
54
56
  mailgunClient,
@@ -73,7 +75,8 @@ class EmailServiceWrapper {
73
75
  outboundLinkTagger: memberAttribution.outboundLinkTagger,
74
76
  emailAddressService: emailAddressService.service,
75
77
  labs,
76
- models: {Post}
78
+ models: {Post},
79
+ t: i18n.t
77
80
  });
78
81
 
79
82
  const sendingService = new SendingService({
@@ -33,4 +33,4 @@ module.exports.init = function () {
33
33
  i18nInstance.changeLanguage(model.get('value'));
34
34
  }
35
35
  });
36
- };
36
+ };
@@ -71,6 +71,14 @@ class TwitterOEmbedProvider {
71
71
  oembedData.tweet_data = body.data;
72
72
  oembedData.tweet_data.includes = body.includes;
73
73
  } catch (err) {
74
+ if (err.response?.body) {
75
+ try {
76
+ const parsed = JSON.parse(err.response.body);
77
+ err.context = parsed;
78
+ } catch (e) {
79
+ err.context = err.response.body;
80
+ }
81
+ }
74
82
  logging.error(err);
75
83
  }
76
84
  }
@@ -1,8 +1,9 @@
1
1
  const config = require('../../../shared/config');
2
+ const storage = require('../../adapters/storage');
2
3
  const externalRequest = require('../../lib/request-external');
3
4
 
4
5
  const OEmbed = require('@tryghost/oembed-service');
5
- const oembed = new OEmbed({config, externalRequest});
6
+ const oembed = new OEmbed({config, externalRequest, storage});
6
7
 
7
8
  const NFT = require('./NFTOEmbedProvider');
8
9
  const nft = new NFT({
@@ -197,12 +197,12 @@
197
197
  },
198
198
  "portal": {
199
199
  "url": "https://cdn.jsdelivr.net/ghost/portal@~{version}/umd/portal.min.js",
200
- "version": "2.45"
200
+ "version": "2.46"
201
201
  },
202
202
  "sodoSearch": {
203
203
  "url": "https://cdn.jsdelivr.net/ghost/sodo-search@~{version}/umd/sodo-search.min.js",
204
204
  "styles": "https://cdn.jsdelivr.net/ghost/sodo-search@~{version}/umd/main.css",
205
- "version": "1.4"
205
+ "version": "1.5"
206
206
  },
207
207
  "announcementBar": {
208
208
  "url": "https://cdn.jsdelivr.net/ghost/announcement-bar@~{version}/umd/announcement-bar.min.js",
@@ -64,6 +64,10 @@ class CacheManager {
64
64
  return cacheEntry;
65
65
  }
66
66
 
67
+ // TODO: I think we should be a little smarter here and deserialize the value based on the type
68
+ // rather than trying to parse everything as JSON, which is very slow when we do it hundreds
69
+ // of times per request.
70
+
67
71
  // Default behavior is to try to resolve the value and return that
68
72
  try {
69
73
  // CASE: handle literal false
@@ -71,6 +75,11 @@ class CacheManager {
71
75
  return false;
72
76
  }
73
77
 
78
+ // CASE: hotpath early return for strings which are already strings
79
+ if (cacheEntry.type === 'string' && typeof cacheEntry.value === 'string') {
80
+ return cacheEntry.value || null;
81
+ }
82
+
74
83
  // CASE: if a string contains a number e.g. "1", JSON.parse will auto convert into integer
75
84
  if (!isNaN(Number(cacheEntry.value))) {
76
85
  return cacheEntry.value || null;