ghost 4.27.1 → 4.30.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 (76) hide show
  1. package/content/themes/casper/assets/built/screen.css +1 -1
  2. package/content/themes/casper/assets/built/screen.css.map +1 -1
  3. package/content/themes/casper/assets/css/screen.css +1 -17
  4. package/content/themes/casper/package.json +1 -1
  5. package/content/themes/casper/partials/post-card.hbs +1 -1
  6. package/core/boot.js +3 -5
  7. package/core/built/assets/{ghost-dark-ae67fe157509b6e82c607ba560fc52e9.css → ghost-dark-1594d07a0716e0253a78234c8e42d765.css} +1 -1
  8. package/core/built/assets/{ghost.min-2d534cce15c43c646814b26f4beefb78.js → ghost.min-884660873d56fcc3d2a3b9fe94c9f022.js} +79 -79
  9. package/core/built/assets/{ghost.min-b1e58e098721e467388682a85a7c187d.css → ghost.min-c21fea11c3f431994a8ee7c47a8ed145.css} +1 -1
  10. package/core/built/assets/icons/audio-file.svg +5 -0
  11. package/core/built/assets/icons/file-download.svg +1 -0
  12. package/core/built/assets/icons/file-upload.svg +1 -0
  13. package/core/built/assets/icons/film-camera.svg +4 -0
  14. package/core/built/assets/icons/mute.svg +3 -0
  15. package/core/built/assets/icons/pause.svg +4 -0
  16. package/core/built/assets/icons/play.svg +3 -0
  17. package/core/built/assets/icons/unmute.svg +3 -0
  18. package/core/built/assets/{vendor.min-e433aa7d5620e7837f30e170cd43f84e.js → vendor.min-a2fd1e62ce6da8911fee8e812d8c6ceb.js} +240 -128
  19. package/core/frontend/apps/amp/lib/views/amp.hbs +94 -2
  20. package/core/frontend/services/theme-engine/i18n/i18n.js +11 -12
  21. package/core/frontend/services/theme-engine/i18n/index.js +1 -2
  22. package/core/frontend/services/theme-engine/i18n/theme-i18n.js +5 -4
  23. package/core/frontend/src/cards/css/audio.css +95 -30
  24. package/core/frontend/src/cards/css/before-after.css +47 -0
  25. package/core/frontend/src/cards/css/bookmark.css +6 -5
  26. package/core/frontend/src/cards/css/button.css +8 -7
  27. package/core/frontend/src/cards/css/callout.css +4 -4
  28. package/core/frontend/src/cards/css/file.css +126 -0
  29. package/core/frontend/src/cards/css/nft.css +9 -13
  30. package/core/frontend/src/cards/css/product.css +81 -52
  31. package/core/frontend/src/cards/css/toggle.css +31 -22
  32. package/core/frontend/src/cards/css/video.css +340 -0
  33. package/core/frontend/src/cards/js/audio.js +127 -128
  34. package/core/frontend/src/cards/js/before-after.js +41 -0
  35. package/core/frontend/src/cards/js/gallery.js +10 -8
  36. package/core/frontend/src/cards/js/toggle.js +16 -14
  37. package/core/frontend/src/cards/js/video.js +232 -0
  38. package/core/frontend/web/middleware/error-handler.js +2 -2
  39. package/core/frontend/web/site.js +2 -1
  40. package/core/server/api/canary/oembed.js +1 -2
  41. package/core/server/data/db/state-manager.js +5 -8
  42. package/core/server/lib/image/cached-image-size-from-url.js +3 -4
  43. package/core/server/lib/image/image-utils.js +2 -2
  44. package/core/server/lib/image/index.js +1 -2
  45. package/core/server/run-update-check.js +1 -13
  46. package/core/server/services/email-analytics/index.js +2 -4
  47. package/core/server/services/email-analytics/jobs/fetch-latest.js +2 -21
  48. package/core/server/services/integrations/integrations-service.js +2 -2
  49. package/core/server/services/invites/index.js +0 -2
  50. package/core/server/services/invites/invites.js +3 -3
  51. package/core/server/services/jobs/job-service.js +1 -1
  52. package/core/server/services/mega/post-email-serializer.js +3 -1
  53. package/core/server/services/mega/template.js +15 -11
  54. package/core/server/services/members/api.js +0 -1
  55. package/core/server/services/members/config.js +4 -7
  56. package/core/server/services/members/service.js +1 -4
  57. package/core/server/services/notifications/index.js +0 -2
  58. package/core/server/services/notifications/notifications.js +4 -5
  59. package/core/server/services/stripe/index.js +0 -2
  60. package/core/server/services/twitter-embed.js +2 -1
  61. package/core/server/web/admin/app.js +4 -2
  62. package/core/server/web/admin/views/default-prod.html +4 -4
  63. package/core/server/web/admin/views/default.html +4 -4
  64. package/core/server/web/api/app.js +3 -2
  65. package/core/server/web/api/canary/admin/app.js +4 -2
  66. package/core/server/web/api/canary/content/app.js +4 -2
  67. package/core/server/web/api/v2/admin/app.js +4 -2
  68. package/core/server/web/api/v2/content/app.js +4 -2
  69. package/core/server/web/api/v3/admin/app.js +4 -2
  70. package/core/server/web/api/v3/content/app.js +4 -2
  71. package/core/server/web/members/app.js +6 -4
  72. package/core/server/web/shared/middleware/index.js +0 -4
  73. package/core/shared/labs.js +9 -8
  74. package/package.json +28 -23
  75. package/yarn.lock +2589 -1988
  76. package/core/server/web/shared/middleware/error-handler.js +0 -224
@@ -1,16 +1,18 @@
1
- const toggleHeadingElements = document.getElementsByClassName("kg-toggle-heading");
1
+ (function() {
2
+ const toggleHeadingElements = document.getElementsByClassName("kg-toggle-heading");
2
3
 
3
- const toggleFn = function(event) {
4
- const targetElement = event.target;
5
- const parentElement = targetElement.closest('.kg-toggle-card');
6
- var toggleState = parentElement.getAttribute("data-kg-toggle-state");
7
- if (toggleState === 'close') {
8
- parentElement.setAttribute('data-kg-toggle-state', 'open');
9
- } else {
10
- parentElement.setAttribute('data-kg-toggle-state', 'close');
11
- }
12
- };
4
+ const toggleFn = function(event) {
5
+ const targetElement = event.target;
6
+ const parentElement = targetElement.closest('.kg-toggle-card');
7
+ var toggleState = parentElement.getAttribute("data-kg-toggle-state");
8
+ if (toggleState === 'close') {
9
+ parentElement.setAttribute('data-kg-toggle-state', 'open');
10
+ } else {
11
+ parentElement.setAttribute('data-kg-toggle-state', 'close');
12
+ }
13
+ };
13
14
 
14
- for (let i = 0; i < toggleHeadingElements.length; i++) {
15
- toggleHeadingElements[i].addEventListener('click', toggleFn, false);
16
- }
15
+ for (let i = 0; i < toggleHeadingElements.length; i++) {
16
+ toggleHeadingElements[i].addEventListener('click', toggleFn, false);
17
+ }
18
+ })();
@@ -0,0 +1,232 @@
1
+ (function() {
2
+ const handleVideoPlayer = function (videoElementContainer) {
3
+ const videoPlayer = videoElementContainer.querySelector('.kg-video-player');
4
+ const videoPlayerContainer = videoElementContainer.querySelector('.kg-video-player-container');
5
+ const playIconContainer = videoElementContainer.querySelector('.kg-video-play-icon');
6
+ const pauseIconContainer = videoElementContainer.querySelector('.kg-video-pause-icon');
7
+ const seekSlider = videoElementContainer.querySelector('.kg-video-seek-slider');
8
+ const playbackRateContainer = videoElementContainer.querySelector('.kg-video-playback-rate');
9
+ const muteIconContainer = videoElementContainer.querySelector('.kg-video-mute-icon');
10
+ const unmuteIconContainer = videoElementContainer.querySelector('.kg-video-unmute-icon');
11
+ const volumeSlider = videoElementContainer.querySelector('.kg-video-volume-slider');
12
+ const videoEl = videoElementContainer.querySelector('video');
13
+ const durationContainer = videoElementContainer.querySelector('.kg-video-duration');
14
+ const currentTimeContainer = videoElementContainer.querySelector('.kg-video-current-time');
15
+ const largePlayIcon = videoElementContainer.querySelector('.kg-video-large-play-icon');
16
+ const videoOverlay = videoElementContainer.querySelector('.kg-video-overlay');
17
+ let playbackRates = [{
18
+ rate: 0.75,
19
+ label: '0.7×'
20
+ }, {
21
+ rate: 1.0,
22
+ label: '1×'
23
+ }, {
24
+ rate: 1.25,
25
+ label: '1.2×'
26
+ }, {
27
+ rate: 1.75,
28
+ label: '1.7×'
29
+ }, {
30
+ rate: 2.0,
31
+ label: '2×'
32
+ }];
33
+
34
+ let raf = null;
35
+ let currentPlaybackRateIdx = 1;
36
+ if (!!videoEl.loop) {
37
+ largePlayIcon.classList.add("kg-video-hide-animated");
38
+ videoOverlay.classList.add("kg-video-hide-animated");
39
+ }
40
+ const whilePlaying = () => {
41
+ seekSlider.value = Math.floor(videoEl.currentTime);
42
+ currentTimeContainer.textContent = calculateTime(seekSlider.value);
43
+ videoPlayer.style.setProperty('--seek-before-width', `${seekSlider.value / seekSlider.max * 100}%`);
44
+ raf = requestAnimationFrame(whilePlaying);
45
+ }
46
+
47
+ const showRangeProgress = (rangeInput) => {
48
+ if (rangeInput === seekSlider) {
49
+ videoPlayer.style.setProperty('--seek-before-width', rangeInput.value / rangeInput.max * 100 + '%');
50
+ }
51
+ else {
52
+ videoPlayer.style.setProperty('--volume-before-width', rangeInput.value / rangeInput.max * 100 + '%');
53
+ }
54
+ }
55
+
56
+ const calculateTime = (secs) => {
57
+ const minutes = Math.floor(secs / 60);
58
+ const seconds = Math.floor(secs % 60);
59
+ const returnedSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;
60
+ return `${minutes}:${returnedSeconds}`;
61
+ }
62
+
63
+ const displayDuration = () => {
64
+ durationContainer.textContent = calculateTime(videoEl.duration);
65
+ }
66
+
67
+ const setSliderMax = () => {
68
+ seekSlider.max = Math.floor(videoEl.duration);
69
+ }
70
+
71
+ const displayBufferedAmount = () => {
72
+ if (videoEl.buffered.length > 0) {
73
+ const bufferedAmount = Math.floor(videoEl.buffered.end(videoEl.buffered.length - 1));
74
+ videoPlayer.style.setProperty('--buffered-width', `${(bufferedAmount / seekSlider.max) * 100}%`);
75
+ }
76
+ }
77
+
78
+ if (videoEl.readyState > 0) {
79
+ displayDuration();
80
+ setSliderMax();
81
+ displayBufferedAmount();
82
+ if (videoEl.autoplay) {
83
+ raf = requestAnimationFrame(whilePlaying);
84
+ playIconContainer.classList.add("kg-video-hide");
85
+ pauseIconContainer.classList.remove("kg-video-hide");
86
+ }
87
+ if (videoEl.muted) {
88
+ unmuteIconContainer.classList.add("kg-video-hide");
89
+ muteIconContainer.classList.remove("kg-video-hide");
90
+ }
91
+ } else {
92
+ videoEl.addEventListener('loadedmetadata', () => {
93
+ displayDuration();
94
+ setSliderMax();
95
+ displayBufferedAmount();
96
+ if (videoEl.autoplay) {
97
+ raf = requestAnimationFrame(whilePlaying);
98
+ playIconContainer.classList.add("kg-video-hide");
99
+ pauseIconContainer.classList.remove("kg-video-hide");
100
+ }
101
+ if (videoEl.muted) {
102
+ unmuteIconContainer.classList.add("kg-video-hide");
103
+ muteIconContainer.classList.remove("kg-video-hide");
104
+ }
105
+ });
106
+ }
107
+
108
+ videoElementContainer.onmouseover = () => {
109
+ if (!videoEl.loop) {
110
+ videoPlayerContainer.classList.remove("kg-video-hide-animated");
111
+ }
112
+ }
113
+
114
+ videoElementContainer.onmouseleave = () => {
115
+ const isPlaying = !!(videoEl.currentTime > 0 && !videoEl.paused && !videoEl.ended && videoEl.readyState > 2);
116
+ if (isPlaying) {
117
+ videoPlayerContainer.classList.add("kg-video-hide-animated");
118
+ }
119
+ }
120
+
121
+ videoElementContainer.addEventListener('click', () => {
122
+ if (!videoEl.loop) {
123
+ const isPlaying = !!(videoEl.currentTime > 0 && !videoEl.paused && !videoEl.ended && videoEl.readyState > 2);
124
+ if (isPlaying) {
125
+ handleOnPause();
126
+ } else {
127
+ handleOnPlay();
128
+ }
129
+ }
130
+ });
131
+
132
+ videoEl.onplay = () => {
133
+ largePlayIcon.classList.add("kg-video-hide-animated");
134
+ videoOverlay.classList.add("kg-video-hide-animated");
135
+ playIconContainer.classList.add("kg-video-hide");
136
+ pauseIconContainer.classList.remove("kg-video-hide");
137
+ };
138
+
139
+ const handleOnPlay = () => {
140
+ largePlayIcon.classList.add("kg-video-hide-animated");
141
+ videoOverlay.classList.add("kg-video-hide-animated");
142
+ playIconContainer.classList.add("kg-video-hide");
143
+ pauseIconContainer.classList.remove("kg-video-hide");
144
+ videoEl.play();
145
+ raf = requestAnimationFrame(whilePlaying);
146
+ }
147
+
148
+ const handleOnPause = () => {
149
+ pauseIconContainer.classList.add("kg-video-hide");
150
+ playIconContainer.classList.remove("kg-video-hide");
151
+ videoEl.pause();
152
+ cancelAnimationFrame(raf);
153
+ }
154
+
155
+ largePlayIcon.addEventListener('click', (event) => {
156
+ event.stopPropagation();
157
+ handleOnPlay();
158
+ });
159
+
160
+ playIconContainer.addEventListener('click', (event) => {
161
+ event.stopPropagation();
162
+ handleOnPlay();
163
+ });
164
+
165
+ pauseIconContainer.addEventListener('click', (event) => {
166
+ event.stopPropagation();
167
+ handleOnPause();
168
+ });
169
+
170
+ muteIconContainer.addEventListener('click', (event) => {
171
+ event.stopPropagation();
172
+ muteIconContainer.classList.add("kg-video-hide");
173
+ unmuteIconContainer.classList.remove("kg-video-hide");
174
+ videoEl.muted = false;
175
+ });
176
+
177
+ unmuteIconContainer.addEventListener('click', (event) => {
178
+ event.stopPropagation();
179
+ unmuteIconContainer.classList.add("kg-video-hide");
180
+ muteIconContainer.classList.remove("kg-video-hide");
181
+ videoEl.muted = true;
182
+ });
183
+
184
+ playbackRateContainer.addEventListener('click', (event) => {
185
+ event.stopPropagation();
186
+ let nextPlaybackRate = playbackRates[(currentPlaybackRateIdx + 1) % 5];
187
+ currentPlaybackRateIdx = currentPlaybackRateIdx + 1;
188
+ videoEl.playbackRate = nextPlaybackRate.rate;
189
+ playbackRateContainer.textContent = nextPlaybackRate.label;
190
+ });
191
+
192
+ videoEl.addEventListener('progress', displayBufferedAmount);
193
+
194
+ seekSlider.addEventListener('input', (e) => {
195
+ e.stopPropagation();
196
+ showRangeProgress(e.target);
197
+ currentTimeContainer.textContent = calculateTime(seekSlider.value);
198
+ if (!videoEl.paused) {
199
+ cancelAnimationFrame(raf);
200
+ }
201
+ });
202
+
203
+ seekSlider.addEventListener('change', (event) => {
204
+ event.stopPropagation();
205
+ videoEl.currentTime = seekSlider.value;
206
+ if (!videoEl.paused) {
207
+ requestAnimationFrame(whilePlaying);
208
+ }
209
+ });
210
+
211
+ volumeSlider.addEventListener('click', (event) => {
212
+ event.stopPropagation();
213
+ });
214
+
215
+ seekSlider.addEventListener('click', (event) => {
216
+ event.stopPropagation();
217
+ });
218
+
219
+ volumeSlider.addEventListener('input', (e) => {
220
+ e.stopPropagation();
221
+ const value = e.target.value;
222
+ showRangeProgress(e.target);
223
+ videoEl.volume = value / 100;
224
+ });
225
+ }
226
+
227
+ const videoCardElements = document.querySelectorAll('.kg-video-card');
228
+
229
+ for (let i = 0; i < videoCardElements.length; i++) {
230
+ handleVideoPlayer(videoCardElements[i]);
231
+ }
232
+ })();
@@ -7,7 +7,7 @@ const config = require('../../../shared/config');
7
7
  const helpers = require('../../services/routing/helpers');
8
8
 
9
9
  // @TODO: make this properly shared code
10
- const shared = require('../../../server/web/shared/middleware/error-handler');
10
+ const {prepareError} = require('@tryghost/mw-error-handler');
11
11
 
12
12
  const messages = {
13
13
  oopsErrorTemplateHasError: 'Oops, seems there is an error in the error template.',
@@ -85,7 +85,7 @@ const themeErrorRenderer = (err, req, res, next) => {
85
85
 
86
86
  module.exports.handleThemeResponse = [
87
87
  // Make sure the error can be served
88
- shared.prepareError,
88
+ prepareError,
89
89
  // Handle the error in Sentry
90
90
  sentry.errorHandler,
91
91
  // Render the error using theme template
@@ -20,6 +20,7 @@ const offersService = require('../../server/services/offers');
20
20
  const customRedirects = require('../../server/services/redirects');
21
21
  const siteRoutes = require('./routes');
22
22
  const shared = require('../../server/web/shared');
23
+ const errorHandler = require('@tryghost/mw-error-handler');
23
24
  const mw = require('./middleware');
24
25
  const labs = require('../../shared/labs');
25
26
 
@@ -176,7 +177,7 @@ module.exports = function setupSiteApp(options = {}) {
176
177
  siteApp.use(SiteRouter);
177
178
 
178
179
  // ### Error handlers
179
- siteApp.use(shared.middleware.errorHandler.pageNotFound);
180
+ siteApp.use(errorHandler.pageNotFound);
180
181
  config.get('apps:internal').forEach((appName) => {
181
182
  const app = require(path.join(config.get('paths').internalAppPath, appName));
182
183
 
@@ -15,8 +15,7 @@ const Twitter = require('../../services/twitter-embed');
15
15
  const twitter = new Twitter({
16
16
  config: {
17
17
  bearerToken: config.get('twitter').privateReadOnlyToken
18
- },
19
- logging: require('@tryghost/logging')
18
+ }
20
19
  });
21
20
 
22
21
  oembed.registerProvider(nft);
@@ -1,5 +1,6 @@
1
1
  const KnexMigrator = require('knex-migrator');
2
2
  const errors = require('@tryghost/errors');
3
+ const logging = require('@tryghost/logging');
3
4
 
4
5
  const states = {
5
6
  READY: 0,
@@ -8,7 +9,7 @@ const states = {
8
9
  ERROR: 3
9
10
  };
10
11
 
11
- const printState = ({state, logging}) => {
12
+ const printState = ({state}) => {
12
13
  if (state === states.READY) {
13
14
  logging.info('Database is in a ready state.');
14
15
  }
@@ -67,13 +68,11 @@ class DatabaseStateManager {
67
68
  }
68
69
  }
69
70
 
70
- async makeReady({logging}) {
71
+ async makeReady() {
71
72
  try {
72
73
  let state = await this.getState();
73
74
 
74
- if (logging) {
75
- printState({state, logging});
76
- }
75
+ printState({state});
77
76
 
78
77
  if (state === states.READY) {
79
78
  return;
@@ -89,9 +88,7 @@ class DatabaseStateManager {
89
88
 
90
89
  state = await this.getState();
91
90
 
92
- if (logging) {
93
- printState({state, logging});
94
- }
91
+ printState({state});
95
92
  } catch (error) {
96
93
  let errorToThrow = error;
97
94
  if (!errors.utils.isGhostError(error)) {
@@ -1,9 +1,8 @@
1
1
  const debug = require('@tryghost/debug')('utils:image-size-cache');
2
2
  const errors = require('@tryghost/errors');
3
-
3
+ const logging = require('@tryghost/logging');
4
4
  class CachedImageSizeFromUrl {
5
- constructor({logging, imageSize}) {
6
- this.logging = logging;
5
+ constructor({imageSize}) {
7
6
  this.imageSize = imageSize;
8
7
  this.cache = new Map();
9
8
  }
@@ -37,7 +36,7 @@ class CachedImageSizeFromUrl {
37
36
  return this.cache.get(url);
38
37
  }).catch((err) => {
39
38
  debug('Cached image (error):', url);
40
- this.logging.error(err);
39
+ logging.error(err);
41
40
 
42
41
  // in case of error we just attach the url
43
42
  this.cache.set(url, url);
@@ -4,10 +4,10 @@ const Gravatar = require('./gravatar');
4
4
  const ImageSize = require('./image-size');
5
5
 
6
6
  class ImageUtils {
7
- constructor({config, logging, urlUtils, settingsCache, storageUtils, storage, validator, request}) {
7
+ constructor({config, urlUtils, settingsCache, storageUtils, storage, validator, request}) {
8
8
  this.blogIcon = new BlogIcon({config, urlUtils, settingsCache, storageUtils});
9
9
  this.imageSize = new ImageSize({config, storage, storageUtils, validator, urlUtils, request});
10
- this.cachedImageSizeFromUrl = new CachedImageSizeFromUrl({logging, imageSize: this.imageSize});
10
+ this.cachedImageSizeFromUrl = new CachedImageSizeFromUrl({imageSize: this.imageSize});
11
11
  this.gravatar = new Gravatar({config, request});
12
12
  }
13
13
  }
@@ -4,8 +4,7 @@ const storage = require('../../adapters/storage');
4
4
  const storageUtils = require('../../adapters/storage/utils');
5
5
  const validator = require('@tryghost/validator');
6
6
  const config = require('../../../shared/config');
7
- const logging = require('@tryghost/logging');
8
7
  const settingsCache = require('../../../shared/settings-cache');
9
8
  const ImageUtils = require('./image-utils');
10
9
 
11
- module.exports = new ImageUtils({config, logging, urlUtils, settingsCache, storageUtils, storage, validator, request});
10
+ module.exports = new ImageUtils({config, urlUtils, settingsCache, storageUtils, storage, validator, request});
@@ -31,18 +31,6 @@ if (parentPort) {
31
31
  (async () => {
32
32
  const updateCheck = require('./update-check');
33
33
 
34
- const logging = {
35
- info(message) {
36
- postParentPortMessage(message);
37
- },
38
- warn(message) {
39
- postParentPortMessage(message);
40
- },
41
- error(message) {
42
- postParentPortMessage(message);
43
- }
44
- };
45
-
46
34
  // INIT required services
47
35
  const models = require('./models');
48
36
  models.init();
@@ -54,7 +42,7 @@ if (parentPort) {
54
42
  await settings.init();
55
43
  // Finished INIT
56
44
 
57
- await updateCheck({logging});
45
+ await updateCheck();
58
46
 
59
47
  postParentPortMessage(`Ran update check`);
60
48
 
@@ -1,5 +1,4 @@
1
1
  const config = require('../../../shared/config');
2
- const logging = require('@tryghost/logging');
3
2
  const db = require('../../data/db');
4
3
  const settings = require('../../../shared/settings-cache');
5
4
  const {EmailAnalyticsService} = require('@tryghost/email-analytics-service');
@@ -9,11 +8,10 @@ const queries = require('./lib/queries');
9
8
 
10
9
  module.exports = new EmailAnalyticsService({
11
10
  config,
12
- logging,
13
11
  settings,
14
- eventProcessor: new EventProcessor({db, logging}),
12
+ eventProcessor: new EventProcessor({db}),
15
13
  providers: [
16
- new MailgunProvider({config, settings, logging})
14
+ new MailgunProvider({config, settings})
17
15
  ],
18
16
  queries
19
17
  });
@@ -28,24 +28,6 @@ if (parentPort) {
28
28
  const config = require('../../../../shared/config');
29
29
  const db = require('../../../data/db');
30
30
 
31
- const logging = {
32
- info(message) {
33
- if (parentPort) {
34
- parentPort.postMessage(message);
35
- }
36
- },
37
- warn(message) {
38
- if (parentPort) {
39
- parentPort.postMessage(message);
40
- }
41
- },
42
- error(message) {
43
- if (parentPort) {
44
- parentPort.postMessage(message);
45
- }
46
- }
47
- };
48
-
49
31
  const settingsRows = await db.knex('settings')
50
32
  .whereIn('key', ['mailgun_api_key', 'mailgun_domain', 'mailgun_base_url']);
51
33
 
@@ -69,10 +51,9 @@ if (parentPort) {
69
51
  const emailAnalyticsService = new EmailAnalyticsService({
70
52
  config,
71
53
  settings,
72
- logging,
73
- eventProcessor: new EventProcessor({db, logging}),
54
+ eventProcessor: new EventProcessor({db}),
74
55
  providers: [
75
- new MailgunProvider({config, settings, logging})
56
+ new MailgunProvider({config, settings})
76
57
  ],
77
58
  queries
78
59
  });
@@ -1,4 +1,4 @@
1
- const {NotFoundError, GhostError} = require('@tryghost/errors');
1
+ const {NotFoundError, InternalServerError} = require('@tryghost/errors');
2
2
  const tpl = require('@tryghost/tpl');
3
3
 
4
4
  const messages = {
@@ -29,7 +29,7 @@ class IntegrationsService {
29
29
  withRelated: ['api_keys', 'webhooks']
30
30
  });
31
31
  } catch (err) {
32
- throw new GhostError({
32
+ throw new InternalServerError({
33
33
  err: err
34
34
  });
35
35
  }
@@ -1,12 +1,10 @@
1
1
  const settingsCache = require('../../../shared/settings-cache');
2
2
  const mailService = require('../../services/mail');
3
- const logging = require('@tryghost/logging');
4
3
  const urlUtils = require('../../../shared/url-utils');
5
4
  const Invites = require('./invites');
6
5
 
7
6
  module.exports = new Invites({
8
7
  settingsCache,
9
- logging,
10
8
  mailService,
11
9
  urlUtils
12
10
  });
@@ -1,5 +1,6 @@
1
1
  const security = require('@tryghost/security');
2
2
  const tpl = require('@tryghost/tpl');
3
+ const logging = require('@tryghost/logging');
3
4
 
4
5
  const messages = {
5
6
  invitedByName: '{invitedByName} has invited you to join {blogName}',
@@ -10,9 +11,8 @@ const messages = {
10
11
  };
11
12
 
12
13
  class Invites {
13
- constructor({settingsCache, logging, mailService, urlUtils}) {
14
+ constructor({settingsCache, mailService, urlUtils}) {
14
15
  this.settingsCache = settingsCache;
15
- this.logging = logging;
16
16
  this.mailService = mailService;
17
17
  this.urlUtils = urlUtils;
18
18
  }
@@ -80,7 +80,7 @@ class Invites {
80
80
  });
81
81
  const helpText = tpl(messages.errorSendingEmail.help);
82
82
  err.message = `${errorMessage} ${helpText}`;
83
- this.logging.warn(err.message);
83
+ logging.warn(err.message);
84
84
  }
85
85
 
86
86
  return Promise.reject(err);
@@ -17,6 +17,6 @@ const workerMessageHandler = ({name, message}) => {
17
17
  logging.info(`Worker for job ${name} sent a message: ${message}`);
18
18
  };
19
19
 
20
- const jobManager = new JobManager({logging, errorHandler, workerMessageHandler});
20
+ const jobManager = new JobManager({errorHandler, workerMessageHandler});
21
21
 
22
22
  module.exports = jobManager;
@@ -240,7 +240,9 @@ const serialize = async (postModel, options = {isBrowserPreview: false, apiVersi
240
240
  post.excerpt = post.excerpt.replace(/\s\[http(.*?)\]/g, '');
241
241
  }
242
242
 
243
- post.html = mobiledocLib.mobiledocHtmlRenderer.render(JSON.parse(post.mobiledoc), {target: 'email'});
243
+ post.html = mobiledocLib.mobiledocHtmlRenderer.render(
244
+ JSON.parse(post.mobiledoc), {target: 'email', postUrl: post.url}
245
+ );
244
246
 
245
247
  // perform any email specific adjustments to the mobiledoc->HTML render output
246
248
  // body wrapper is required so we can get proper top-level selections
@@ -74,8 +74,8 @@ table td {
74
74
  max-width: 600px;
75
75
  }
76
76
 
77
- .content a {
78
- overflow-wrap: anywhere;
77
+ .content a {
78
+ overflow-wrap: anywhere;
79
79
  }
80
80
 
81
81
  /* -------------------------------------
@@ -554,28 +554,32 @@ figure blockquote p {
554
554
  }
555
555
 
556
556
  .kg-nft-link {
557
- display: block;
558
- text-decoration: none !important;
559
- color: #15212A !important;
557
+ display: block;
558
+ text-decoration: none !important;
559
+ color: #15212A !important;
560
560
  font-family: inherit !important;
561
561
  font-size: 14px;
562
562
  line-height: 1.3em;
563
- padding-top: 4px;
564
- padding-right: 20px;
565
- padding-left: 20px;
563
+ padding-top: 4px;
564
+ padding-right: 20px;
565
+ padding-left: 20px;
566
566
  padding-bottom: 4px;
567
567
  }
568
568
 
569
569
  .kg-twitter-link {
570
- display: block;
571
- text-decoration: none !important;
572
- color: #15212A !important;
570
+ display: block;
571
+ text-decoration: none !important;
572
+ color: #15212A !important;
573
573
  font-family: inherit !important;
574
574
  font-size: 15px;
575
575
  padding: 8px;
576
576
  line-height: 1.3em;
577
577
  }
578
578
 
579
+ .kg-audio-thumbnail.placeholder {
580
+ background: ${templateSettings.accentColor || '#15212A'} !important;
581
+ }
582
+
579
583
  .kg-callout-card {
580
584
  display: flex;
581
585
  margin: 0 0 1.5em 0;
@@ -207,7 +207,6 @@ function createApiInstance(config) {
207
207
  Settings: models.Settings
208
208
  },
209
209
  stripeAPIService: stripeService.api,
210
- logger: logging,
211
210
  offersAPI: offersService.api,
212
211
  labsService: labsService
213
212
  });