ghost 5.24.2 → 5.25.1

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 (140) hide show
  1. package/components/{tryghost-adapter-manager-5.24.2.tgz → tryghost-adapter-manager-5.25.1.tgz} +0 -0
  2. package/components/{tryghost-api-framework-5.24.2.tgz → tryghost-api-framework-5.25.1.tgz} +0 -0
  3. package/components/{tryghost-api-version-compatibility-service-5.24.2.tgz → tryghost-api-version-compatibility-service-5.25.1.tgz} +0 -0
  4. package/components/{tryghost-audience-feedback-5.24.2.tgz → tryghost-audience-feedback-5.25.1.tgz} +0 -0
  5. package/components/{tryghost-bootstrap-socket-5.24.2.tgz → tryghost-bootstrap-socket-5.25.1.tgz} +0 -0
  6. package/components/tryghost-constants-5.25.1.tgz +0 -0
  7. package/components/tryghost-custom-theme-settings-service-5.25.1.tgz +0 -0
  8. package/components/{tryghost-data-generator-5.24.2.tgz → tryghost-data-generator-5.25.1.tgz} +0 -0
  9. package/components/tryghost-domain-events-5.25.1.tgz +0 -0
  10. package/components/tryghost-email-analytics-provider-mailgun-5.25.1.tgz +0 -0
  11. package/components/tryghost-email-analytics-service-5.25.1.tgz +0 -0
  12. package/components/tryghost-email-content-generator-5.25.1.tgz +0 -0
  13. package/components/tryghost-email-events-5.25.1.tgz +0 -0
  14. package/components/tryghost-email-service-5.25.1.tgz +0 -0
  15. package/components/tryghost-email-suppression-list-5.25.1.tgz +0 -0
  16. package/components/{tryghost-express-dynamic-redirects-5.24.2.tgz → tryghost-express-dynamic-redirects-5.25.1.tgz} +0 -0
  17. package/components/tryghost-extract-api-key-5.25.1.tgz +0 -0
  18. package/components/tryghost-html-to-plaintext-5.25.1.tgz +0 -0
  19. package/components/tryghost-job-manager-5.25.1.tgz +0 -0
  20. package/components/{tryghost-link-redirects-5.24.2.tgz → tryghost-link-redirects-5.25.1.tgz} +0 -0
  21. package/components/tryghost-link-replacer-5.25.1.tgz +0 -0
  22. package/components/{tryghost-link-tracking-5.24.2.tgz → tryghost-link-tracking-5.25.1.tgz} +0 -0
  23. package/components/tryghost-magic-link-5.25.1.tgz +0 -0
  24. package/components/tryghost-mailgun-client-5.25.1.tgz +0 -0
  25. package/components/{tryghost-member-attribution-5.24.2.tgz → tryghost-member-attribution-5.25.1.tgz} +0 -0
  26. package/components/tryghost-member-events-5.25.1.tgz +0 -0
  27. package/components/tryghost-members-api-5.25.1.tgz +0 -0
  28. package/components/{tryghost-members-csv-5.24.2.tgz → tryghost-members-csv-5.25.1.tgz} +0 -0
  29. package/components/tryghost-members-events-service-5.25.1.tgz +0 -0
  30. package/components/{tryghost-members-importer-5.24.2.tgz → tryghost-members-importer-5.25.1.tgz} +0 -0
  31. package/components/{tryghost-members-offers-5.24.2.tgz → tryghost-members-offers-5.25.1.tgz} +0 -0
  32. package/components/{tryghost-members-payments-5.24.2.tgz → tryghost-members-payments-5.25.1.tgz} +0 -0
  33. package/components/tryghost-members-ssr-5.25.1.tgz +0 -0
  34. package/components/{tryghost-members-stripe-service-5.24.2.tgz → tryghost-members-stripe-service-5.25.1.tgz} +0 -0
  35. package/components/tryghost-minifier-5.25.1.tgz +0 -0
  36. package/components/tryghost-mw-api-version-mismatch-5.25.1.tgz +0 -0
  37. package/components/tryghost-mw-cache-control-5.25.1.tgz +0 -0
  38. package/components/{tryghost-mw-error-handler-5.24.2.tgz → tryghost-mw-error-handler-5.25.1.tgz} +0 -0
  39. package/components/tryghost-mw-session-from-token-5.25.1.tgz +0 -0
  40. package/components/{tryghost-mw-update-user-last-seen-5.24.2.tgz → tryghost-mw-update-user-last-seen-5.25.1.tgz} +0 -0
  41. package/components/tryghost-mw-vhost-5.25.1.tgz +0 -0
  42. package/components/{tryghost-oembed-service-5.24.2.tgz → tryghost-oembed-service-5.25.1.tgz} +0 -0
  43. package/components/{tryghost-package-json-5.24.2.tgz → tryghost-package-json-5.25.1.tgz} +0 -0
  44. package/components/tryghost-referrers-5.25.1.tgz +0 -0
  45. package/components/tryghost-security-5.25.1.tgz +0 -0
  46. package/components/{tryghost-session-service-5.24.2.tgz → tryghost-session-service-5.25.1.tgz} +0 -0
  47. package/components/tryghost-settings-path-manager-5.25.1.tgz +0 -0
  48. package/components/{tryghost-staff-service-5.24.2.tgz → tryghost-staff-service-5.25.1.tgz} +0 -0
  49. package/components/tryghost-stats-service-5.25.1.tgz +0 -0
  50. package/components/{tryghost-tiers-5.24.2.tgz → tryghost-tiers-5.25.1.tgz} +0 -0
  51. package/components/tryghost-update-check-service-5.25.1.tgz +0 -0
  52. package/components/tryghost-verification-trigger-5.25.1.tgz +0 -0
  53. package/components/{tryghost-version-notifications-data-service-5.24.2.tgz → tryghost-version-notifications-data-service-5.25.1.tgz} +0 -0
  54. package/core/boot.js +1 -1
  55. package/core/built/admin/assets/{chunk.143.ec6fc400326aebf73801.js → chunk.143.0dc2fb34377630cd95b4.js} +23 -23
  56. package/core/built/admin/assets/{chunk.178.1c3441f4acec543cf937.js → chunk.178.fee48b8b52dc3ad83ba1.js} +4 -4
  57. package/core/built/admin/assets/{chunk.507.71dd4bfc4ccb354cc629.js → chunk.507.37279ad3a2f6aeb82302.js} +13 -13
  58. package/core/built/admin/assets/{chunk.613.6bbcc18224567657fc2e.js → chunk.613.a29fe5699dd5f7fb05f1.js} +162 -160
  59. package/core/built/admin/assets/{chunk.613.6bbcc18224567657fc2e.js.LICENSE.txt → chunk.613.a29fe5699dd5f7fb05f1.js.LICENSE.txt} +0 -0
  60. package/core/built/admin/assets/ghost-16dd31e7747e2dce6313f4362842b7b7.css +1 -0
  61. package/core/built/admin/assets/{ghost-34bc21923675def87aa2516f72ca15d7.js → ghost-a66ff073d219101414fa7b344095c1ca.js} +1084 -1051
  62. package/core/built/admin/assets/ghost-dark-1117e1c672c39d594cdd1dfdf3d1c1ac.css +1 -0
  63. package/core/built/admin/assets/{vendor-04415b2b8a59aa9567dfa5d819ada71c.js → vendor-a767da2d0322ba6e801e0d719ccf5a26.js} +40 -38
  64. package/core/built/admin/index.html +6 -6
  65. package/core/server/api/endpoints/emails.js +59 -0
  66. package/core/server/api/endpoints/utils/serializers/input/emails.js +15 -0
  67. package/core/server/api/endpoints/utils/serializers/input/index.js +4 -0
  68. package/core/server/api/endpoints/utils/serializers/output/emails.js +32 -0
  69. package/core/server/api/endpoints/utils/serializers/output/index.js +4 -0
  70. package/core/server/api/endpoints/utils/serializers/output/mappers/email-batches.js +31 -0
  71. package/core/server/api/endpoints/utils/serializers/output/mappers/email-failures.js +53 -0
  72. package/core/server/data/exporter/table-lists.js +4 -1
  73. package/core/server/data/importer/import-manager.js +1 -3
  74. package/core/server/data/migrations/versions/5.25/2022-11-24-10-36-add-suppressions-table.js +9 -0
  75. package/core/server/data/migrations/versions/5.25/2022-11-24-10-37-add-email-spam-complaint-events-table.js +12 -0
  76. package/core/server/data/migrations/versions/5.25/2022-11-29-08-30-add-error-recipient-failures-table.js +20 -0
  77. package/core/server/data/schema/schema.js +45 -0
  78. package/core/server/lib/lexical.js +37 -0
  79. package/core/server/models/email-batch.js +13 -0
  80. package/core/server/models/email-recipient-failure.js +29 -0
  81. package/core/server/models/email-spam-complaint-event.js +44 -0
  82. package/core/server/models/post.js +7 -1
  83. package/core/server/models/suppression.js +9 -0
  84. package/core/server/services/email-analytics/index.js +8 -2
  85. package/core/server/services/email-analytics/jobs/fetch-latest/index.js +50 -0
  86. package/core/server/services/email-analytics/jobs/{fetch-latest.js → fetch-latest/run.js} +16 -41
  87. package/core/server/services/email-analytics/jobs/index.js +1 -1
  88. package/core/server/services/email-service/wrapper.js +73 -12
  89. package/core/server/services/email-suppression-list/InMemoryEmailSuppressionList.js +36 -0
  90. package/core/server/services/email-suppression-list/MailgunEmailSuppressionList.js +117 -0
  91. package/core/server/services/email-suppression-list/service.js +15 -38
  92. package/core/server/services/jobs/job-service.js +5 -2
  93. package/core/server/services/mail/GhostMailer.js +1 -0
  94. package/core/server/services/mega/feedback-buttons.js +6 -0
  95. package/core/server/services/mega/mega.js +11 -7
  96. package/core/server/services/mega/template.js +12 -0
  97. package/core/server/services/members/api.js +2 -1
  98. package/core/server/services/members/config.js +11 -2
  99. package/core/server/services/members/service.js +1 -10
  100. package/core/server/services/members-events/index.js +2 -2
  101. package/core/server/services/settings-helpers/settings-helpers.js +4 -0
  102. package/core/server/web/api/endpoints/admin/routes.js +2 -0
  103. package/package.json +109 -107
  104. package/yarn.lock +185 -163
  105. package/.c8rc.e2e.json +0 -21
  106. package/components/tryghost-constants-5.24.2.tgz +0 -0
  107. package/components/tryghost-custom-theme-settings-service-5.24.2.tgz +0 -0
  108. package/components/tryghost-domain-events-5.24.2.tgz +0 -0
  109. package/components/tryghost-email-analytics-provider-mailgun-5.24.2.tgz +0 -0
  110. package/components/tryghost-email-analytics-service-5.24.2.tgz +0 -0
  111. package/components/tryghost-email-content-generator-5.24.2.tgz +0 -0
  112. package/components/tryghost-email-events-5.24.2.tgz +0 -0
  113. package/components/tryghost-email-service-5.24.2.tgz +0 -0
  114. package/components/tryghost-email-suppression-list-5.24.2.tgz +0 -0
  115. package/components/tryghost-extract-api-key-5.24.2.tgz +0 -0
  116. package/components/tryghost-html-to-plaintext-5.24.2.tgz +0 -0
  117. package/components/tryghost-job-manager-5.24.2.tgz +0 -0
  118. package/components/tryghost-link-replacer-5.24.2.tgz +0 -0
  119. package/components/tryghost-magic-link-5.24.2.tgz +0 -0
  120. package/components/tryghost-mailgun-client-5.24.2.tgz +0 -0
  121. package/components/tryghost-member-events-5.24.2.tgz +0 -0
  122. package/components/tryghost-members-api-5.24.2.tgz +0 -0
  123. package/components/tryghost-members-events-service-5.24.2.tgz +0 -0
  124. package/components/tryghost-members-ssr-5.24.2.tgz +0 -0
  125. package/components/tryghost-minifier-5.24.2.tgz +0 -0
  126. package/components/tryghost-mw-api-version-mismatch-5.24.2.tgz +0 -0
  127. package/components/tryghost-mw-cache-control-5.24.2.tgz +0 -0
  128. package/components/tryghost-mw-session-from-token-5.24.2.tgz +0 -0
  129. package/components/tryghost-mw-vhost-5.24.2.tgz +0 -0
  130. package/components/tryghost-referrers-5.24.2.tgz +0 -0
  131. package/components/tryghost-security-5.24.2.tgz +0 -0
  132. package/components/tryghost-settings-path-manager-5.24.2.tgz +0 -0
  133. package/components/tryghost-stats-service-5.24.2.tgz +0 -0
  134. package/components/tryghost-update-check-service-5.24.2.tgz +0 -0
  135. package/components/tryghost-verification-trigger-5.24.2.tgz +0 -0
  136. package/core/built/admin/assets/ghost-dark-a2076b08f23a9e6340072bc7b06ec9e7.css +0 -1
  137. package/core/built/admin/assets/ghost-f428683b68c0eea9042acc7c021641e0.css +0 -1
  138. package/core/server/services/email-analytics/lib/event-processor.js +0 -178
  139. package/core/server/services/members/settings.js +0 -30
  140. package/playwright.config.js +0 -26
@@ -1,38 +1,15 @@
1
- const {AbstractEmailSuppressionList, EmailSuppressionData} = require('@tryghost/email-suppression-list');
2
-
3
- class InMemoryEmailSuppressionList extends AbstractEmailSuppressionList {
4
- store = ['spam@member.test', 'fail@member.test'];
5
-
6
- async removeEmail(email) {
7
- if ((email === 'fail@member.test' || email === 'spam@member.test') && this.store.includes(email)) {
8
- this.store = this.store.filter(el => el !== email);
9
-
10
- setTimeout(() => this.store.push(email), 3000);
11
- return true;
12
- }
13
-
14
- return false;
15
- }
16
-
17
- async getSuppressionData(email) {
18
- if (email === 'spam@member.test' && this.store.includes(email)) {
19
- return new EmailSuppressionData(true, {
20
- timestamp: new Date(),
21
- reason: 'spam'
22
- });
23
- }
24
- if (email === 'fail@member.test' && this.store.includes(email)) {
25
- return new EmailSuppressionData(true, {
26
- timestamp: new Date(),
27
- reason: 'fail'
28
- });
29
- }
30
- return new EmailSuppressionData(false);
31
- }
32
-
33
- async init() {
34
- return;
35
- }
36
- }
37
-
38
- module.exports = new InMemoryEmailSuppressionList();
1
+ const MailgunClient = require('@tryghost/mailgun-client');
2
+ const models = require('../../models');
3
+ const configService = require('../../../shared/config');
4
+ const settingsCache = require('../../../shared/settings-cache');
5
+ const MailgunEmailSuppressionList = require('./MailgunEmailSuppressionList');
6
+
7
+ const mailgunClient = new MailgunClient({
8
+ config: configService,
9
+ settings: settingsCache
10
+ });
11
+
12
+ module.exports = new MailgunEmailSuppressionList({
13
+ Suppression: models.Suppression,
14
+ apiClient: mailgunClient
15
+ });
@@ -7,6 +7,7 @@ const JobManager = require('@tryghost/job-manager');
7
7
  const logging = require('@tryghost/logging');
8
8
  const models = require('../../models');
9
9
  const sentry = require('../../../shared/sentry');
10
+ const domainEvents = require('@tryghost/domain-events');
10
11
 
11
12
  const errorHandler = (error, workerMeta) => {
12
13
  logging.info(`Capturing error for worker during execution of job: ${workerMeta.name}`);
@@ -15,7 +16,9 @@ const errorHandler = (error, workerMeta) => {
15
16
  };
16
17
 
17
18
  const workerMessageHandler = ({name, message}) => {
18
- logging.info(`Worker for job ${name} sent a message: ${message}`);
19
+ if (typeof message === 'string') {
20
+ logging.info(`Worker for job ${name} sent a message: ${message}`);
21
+ }
19
22
  };
20
23
 
21
24
  const initTestMode = () => {
@@ -39,7 +42,7 @@ const initTestMode = () => {
39
42
  }, 5000);
40
43
  };
41
44
 
42
- const jobManager = new JobManager({errorHandler, workerMessageHandler, JobModel: models.Job});
45
+ const jobManager = new JobManager({errorHandler, workerMessageHandler, JobModel: models.Job, domainEvents});
43
46
 
44
47
  module.exports = jobManager;
45
48
  module.exports.initTestMode = initTestMode;
@@ -96,6 +96,7 @@ module.exports = class GhostMailer {
96
96
  * @param {string} message.subject - email subject
97
97
  * @param {string} message.html - email content
98
98
  * @param {string} message.to - email recipient address
99
+ * @param {string} [message.replyTo]
99
100
  * @param {string} [message.from] - sender email address
100
101
  * @param {string} [message.text] - text version of this message
101
102
  * @param {boolean} [message.forceTextContent] - maps to generateTextFromHTML nodemailer option
@@ -125,7 +125,13 @@ function getButtonLightTheme(accentColor) {
125
125
  };
126
126
  }
127
127
 
128
+ /**
129
+ * @deprecated
130
+ * PLEASE MAKE IDENTICAL CHANGES TO email-service package email-templates/styles.hbs
131
+ */
128
132
  function getButtonsHeadStyles() {
133
+ // DEPRECATED!
134
+ // PLEASE MAKE IDENTICAL CHANGES TO email-service package email-templates/styles.hbs
129
135
  return (`
130
136
  .like-icon {
131
137
  mix-blend-mode: darken;
@@ -563,13 +563,17 @@ async function createEmailBatches({emailModel, memberRows, memberSegment, option
563
563
 
564
564
  debug('createEmailBatches: storing recipient list');
565
565
  const startOfRecipientStorage = Date.now();
566
- const emails = memberRows.map(row => row.email);
567
- const emailSuppressionData = await emailSuppressionList.getBulkSuppressionData(emails);
568
- const emailSuppressedLookup = _.zipObject(emails, emailSuppressionData);
569
- const filteredRows = memberRows.filter((row) => {
570
- return emailSuppressedLookup[row.email].suppressed === false;
571
- });
572
- const batches = _.chunk(filteredRows, bulkEmailService.BATCH_SIZE);
566
+ let rowsToBatch = memberRows;
567
+ if (labs.isSet('suppressionList')) {
568
+ const emails = memberRows.map(row => row.email);
569
+ const emailSuppressionData = await emailSuppressionList.getBulkSuppressionData(emails);
570
+ const emailSuppressedLookup = _.zipObject(emails, emailSuppressionData);
571
+ const filteredRows = memberRows.filter((row) => {
572
+ return emailSuppressedLookup[row.email].suppressed === false;
573
+ });
574
+ rowsToBatch = filteredRows;
575
+ }
576
+ const batches = _.chunk(rowsToBatch, bulkEmailService.BATCH_SIZE);
573
577
  const batchIds = await Promise.mapSeries(batches, storeRecipientBatch);
574
578
  debug(`createEmailBatches: stored recipient list (${Date.now() - startOfRecipientStorage}ms)`);
575
579
  logging.info(`[createEmailBatches] stored recipient list (${Date.now() - startOfRecipientStorage}ms)`);
@@ -1,3 +1,15 @@
1
+ // ---------------------------------------------
2
+ // ---------------------------------------------
3
+ //
4
+ // WARNING!!
5
+ //
6
+ // THIS FILE IS DEPRECATED. PLEASE ALSO MAKE IDENTICAL CHANGES IN THE EMAIL-SERVICE PACKAGE -> email-templates/template.hbs
7
+ //
8
+ // WARNING!!
9
+ //
10
+ // ---------------------------------------------
11
+ // ---------------------------------------------
12
+
1
13
  const {escapeHtml: escape} = require('@tryghost/string');
2
14
  const feedbackButtons = require('./feedback-buttons');
3
15
 
@@ -197,7 +197,8 @@ function createApiInstance(config) {
197
197
  Product: models.Product,
198
198
  Settings: models.Settings,
199
199
  Comment: models.Comment,
200
- MemberFeedback: models.MemberFeedback
200
+ MemberFeedback: models.MemberFeedback,
201
+ EmailSpamComplaintEvent: models.EmailSpamComplaintEvent
201
202
  },
202
203
  stripeAPIService: stripeService.api,
203
204
  tiersService: tiersService,
@@ -7,7 +7,7 @@ class MembersConfigProvider {
7
7
  /**
8
8
  * @param {object} options
9
9
  * @param {{get: (key: string) => any}} options.settingsCache
10
- * @param {{getDefaultEmailDomain(): string, getMembersSupportAddress(): string, isStripeConnected(): boolean}} options.settingsHelpers
10
+ * @param {{getDefaultEmailDomain(): string, getMembersSupportAddress(): string, getNoReplyAddress(): string, isStripeConnected(): boolean}} options.settingsHelpers
11
11
  * @param {any} options.urlUtils
12
12
  */
13
13
  constructor({settingsCache, settingsHelpers, urlUtils}) {
@@ -20,11 +20,17 @@ class MembersConfigProvider {
20
20
  return this._settingsHelpers.getDefaultEmailDomain();
21
21
  }
22
22
 
23
+ /**
24
+ * @deprecated Use settingsHelpers.getNoReplyAddress or settingsHelpers.getMembersSupportAddress instead
25
+ */
23
26
  getEmailFromAddress() {
24
27
  // Individual from addresses are set per newsletter - this is the fallback address
25
- return `noreply@${this.defaultEmailDomain}`;
28
+ return this._settingsHelpers.getNoReplyAddress();
26
29
  }
27
30
 
31
+ /**
32
+ * @deprecated Use settingsHelpers.getNoReplyAddress or settingsHelpers.getMembersSupportAddress instead
33
+ */
28
34
  getEmailSupportAddress() {
29
35
  return this._settingsHelpers.getMembersSupportAddress();
30
36
  }
@@ -33,6 +39,9 @@ class MembersConfigProvider {
33
39
  return this.getEmailSupportAddress();
34
40
  }
35
41
 
42
+ /**
43
+ * @deprecated Use settingsHelpers.isStripeConnected instead
44
+ */
36
45
  isStripeConnected() {
37
46
  return this._settingsHelpers.isStripeConnected();
38
47
  }
@@ -7,7 +7,6 @@ const MembersConfigProvider = require('./config');
7
7
  const MembersCSVImporter = require('@tryghost/members-importer');
8
8
  const MembersStats = require('./stats/members-stats');
9
9
  const memberJobs = require('./jobs');
10
- const createMembersSettingsInstance = require('./settings');
11
10
  const logging = require('@tryghost/logging');
12
11
  const urlUtils = require('../../../shared/url-utils');
13
12
  const labsService = require('../../../shared/labs');
@@ -42,7 +41,6 @@ const membersStats = new MembersStats({
42
41
  });
43
42
 
44
43
  let membersApi;
45
- let membersSettings;
46
44
  let verificationTrigger;
47
45
 
48
46
  const membersImporter = new MembersCSVImporter({
@@ -155,7 +153,7 @@ module.exports = {
155
153
  job: stripeService.migrations.execute.bind(stripeService.migrations)
156
154
  });
157
155
 
158
- await jobsService.awaitCompletion(membersMigrationJobName);
156
+ await jobsService.awaitOneOffCompletion(membersMigrationJobName);
159
157
  }
160
158
  }
161
159
 
@@ -170,13 +168,6 @@ module.exports = {
170
168
  return membersApi;
171
169
  },
172
170
 
173
- get settings() {
174
- if (!membersSettings) {
175
- membersSettings = createMembersSettingsInstance(membersConfig);
176
- }
177
- return membersSettings;
178
- },
179
-
180
171
  ssr: null,
181
172
 
182
173
  stripeConnect: require('./stripe-connect'),
@@ -19,7 +19,7 @@ class MembersEventsServiceWrapper {
19
19
  models: {
20
20
  MemberCreatedEvent: models.MemberCreatedEvent,
21
21
  SubscriptionCreatedEvent: models.SubscriptionCreatedEvent
22
- },
22
+ },
23
23
  labsService
24
24
  });
25
25
 
@@ -27,7 +27,7 @@ class MembersEventsServiceWrapper {
27
27
  services: {
28
28
  settingsCache
29
29
  },
30
- async getMembersApi() {
30
+ getMembersApi() {
31
31
  return members.api;
32
32
  }
33
33
  });
@@ -94,6 +94,10 @@ class SettingsHelpers {
94
94
  }
95
95
  return supportAddress;
96
96
  }
97
+
98
+ getNoReplyAddress() {
99
+ return `noreply@${this.getDefaultEmailDomain()}`;
100
+ }
97
101
  }
98
102
 
99
103
  module.exports = SettingsHelpers;
@@ -291,6 +291,8 @@ module.exports = function apiRoutes() {
291
291
  router.get('/emails', mw.authAdminApi, http(api.emails.browse));
292
292
  router.get('/emails/:id', mw.authAdminApi, http(api.emails.read));
293
293
  router.put('/emails/:id/retry', mw.authAdminApi, http(api.emails.retry));
294
+ router.get('/emails/:id/batches', mw.authAdminApi, http(api.emails.browseBatches));
295
+ router.get('/emails/:id/recipient-failures', mw.authAdminApi, http(api.emails.browseFailures));
294
296
 
295
297
  // ## Snippets
296
298
  router.get('/snippets', mw.authAdminApi, http(api.snippets.browse));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghost",
3
- "version": "5.24.2",
3
+ "version": "5.25.1",
4
4
  "description": "The professional publishing platform",
5
5
  "author": "Ghost Foundation",
6
6
  "homepage": "https://ghost.org",
@@ -35,7 +35,7 @@
35
35
  "test:browser": "NODE_ENV=development playwright test --browser=chromium test/e2e-browser",
36
36
  "test:browser:record": "NODE_ENV=development yarn start record-test",
37
37
  "test:ci": "c8 -c ./.c8rc.e2e.json yarn test:ci:base",
38
- "test:ci:base": "yarn test:e2e -b",
38
+ "test:ci:base": "yarn test:e2e -b && yarn test:integration -b && yarn test:regression -b",
39
39
  "test:unit:slow": "yarn test:unit --reporter=mocha-slow-test-reporter",
40
40
  "test:int:slow": "yarn test:integration --reporter=mocha-slow-test-reporter",
41
41
  "test:e2e:slow": "yarn test:e2e --reporter=mocha-slow-test-reporter",
@@ -50,87 +50,88 @@
50
50
  "prepack": "yarn workspace ghost-admin run build:prod && yarn build:css && npx --yes daniellockyer/monobundle"
51
51
  },
52
52
  "engines": {
53
- "node": "^14.17.0 || ^16.13.0",
53
+ "node": "^14.17.0 || ^16.13.0 || ^18.0.0",
54
54
  "cli": "^1.17.0"
55
55
  },
56
56
  "dependencies": {
57
- "@sentry/node": "7.21.1",
57
+ "@sentry/node": "7.23.0",
58
58
  "@tryghost/adapter-base-cache": "0.1.2",
59
- "@tryghost/adapter-manager": "file:components/tryghost-adapter-manager-5.24.2.tgz",
59
+ "@tryghost/adapter-manager": "file:components/tryghost-adapter-manager-5.25.1.tgz",
60
60
  "@tryghost/admin-api-schema": "4.2.0",
61
- "@tryghost/api-framework": "file:components/tryghost-api-framework-5.24.2.tgz",
62
- "@tryghost/api-version-compatibility-service": "file:components/tryghost-api-version-compatibility-service-5.24.2.tgz",
63
- "@tryghost/audience-feedback": "file:components/tryghost-audience-feedback-5.24.2.tgz",
61
+ "@tryghost/api-framework": "file:components/tryghost-api-framework-5.25.1.tgz",
62
+ "@tryghost/api-version-compatibility-service": "file:components/tryghost-api-version-compatibility-service-5.25.1.tgz",
63
+ "@tryghost/audience-feedback": "file:components/tryghost-audience-feedback-5.25.1.tgz",
64
64
  "@tryghost/bookshelf-plugins": "0.6.1",
65
- "@tryghost/bootstrap-socket": "file:components/tryghost-bootstrap-socket-5.24.2.tgz",
65
+ "@tryghost/bootstrap-socket": "file:components/tryghost-bootstrap-socket-5.25.1.tgz",
66
66
  "@tryghost/color-utils": "0.1.21",
67
67
  "@tryghost/config-url-helpers": "1.0.3",
68
- "@tryghost/constants": "file:components/tryghost-constants-5.24.2.tgz",
69
- "@tryghost/custom-theme-settings-service": "file:components/tryghost-custom-theme-settings-service-5.24.2.tgz",
70
- "@tryghost/data-generator": "file:components/tryghost-data-generator-5.24.2.tgz",
68
+ "@tryghost/constants": "file:components/tryghost-constants-5.25.1.tgz",
69
+ "@tryghost/custom-theme-settings-service": "file:components/tryghost-custom-theme-settings-service-5.25.1.tgz",
70
+ "@tryghost/data-generator": "file:components/tryghost-data-generator-5.25.1.tgz",
71
71
  "@tryghost/database-info": "0.3.12",
72
72
  "@tryghost/debug": "0.1.19",
73
- "@tryghost/domain-events": "file:components/tryghost-domain-events-5.24.2.tgz",
74
- "@tryghost/email-analytics-provider-mailgun": "file:components/tryghost-email-analytics-provider-mailgun-5.24.2.tgz",
75
- "@tryghost/email-analytics-service": "file:components/tryghost-email-analytics-service-5.24.2.tgz",
76
- "@tryghost/email-content-generator": "file:components/tryghost-email-content-generator-5.24.2.tgz",
77
- "@tryghost/email-service": "file:components/tryghost-email-service-5.24.2.tgz",
78
- "@tryghost/email-suppression-list": "file:components/tryghost-email-suppression-list-5.24.2.tgz",
73
+ "@tryghost/domain-events": "file:components/tryghost-domain-events-5.25.1.tgz",
74
+ "@tryghost/email-analytics-provider-mailgun": "file:components/tryghost-email-analytics-provider-mailgun-5.25.1.tgz",
75
+ "@tryghost/email-analytics-service": "file:components/tryghost-email-analytics-service-5.25.1.tgz",
76
+ "@tryghost/email-content-generator": "file:components/tryghost-email-content-generator-5.25.1.tgz",
77
+ "@tryghost/email-service": "file:components/tryghost-email-service-5.25.1.tgz",
78
+ "@tryghost/email-suppression-list": "file:components/tryghost-email-suppression-list-5.25.1.tgz",
79
79
  "@tryghost/errors": "1.2.18",
80
- "@tryghost/express-dynamic-redirects": "file:components/tryghost-express-dynamic-redirects-5.24.2.tgz",
80
+ "@tryghost/express-dynamic-redirects": "file:components/tryghost-express-dynamic-redirects-5.25.1.tgz",
81
81
  "@tryghost/helpers": "1.1.74",
82
- "@tryghost/html-to-plaintext": "file:components/tryghost-html-to-plaintext-5.24.2.tgz",
82
+ "@tryghost/html-to-plaintext": "file:components/tryghost-html-to-plaintext-5.25.1.tgz",
83
83
  "@tryghost/http-cache-utils": "0.1.4",
84
84
  "@tryghost/image-transform": "1.2.2",
85
- "@tryghost/job-manager": "file:components/tryghost-job-manager-5.24.2.tgz",
85
+ "@tryghost/job-manager": "file:components/tryghost-job-manager-5.25.1.tgz",
86
86
  "@tryghost/kg-card-factory": "3.1.7",
87
87
  "@tryghost/kg-default-atoms": "3.1.4",
88
88
  "@tryghost/kg-default-cards": "5.18.5",
89
+ "@tryghost/kg-default-nodes": "0.0.1",
89
90
  "@tryghost/kg-lexical-html-renderer": "0.0.11",
90
91
  "@tryghost/kg-mobiledoc-html-renderer": "5.3.9",
91
92
  "@tryghost/limit-service": "1.2.3",
92
- "@tryghost/link-redirects": "file:components/tryghost-link-redirects-5.24.2.tgz",
93
- "@tryghost/link-replacer": "file:components/tryghost-link-replacer-5.24.2.tgz",
94
- "@tryghost/link-tracking": "file:components/tryghost-link-tracking-5.24.2.tgz",
93
+ "@tryghost/link-redirects": "file:components/tryghost-link-redirects-5.25.1.tgz",
94
+ "@tryghost/link-replacer": "file:components/tryghost-link-replacer-5.25.1.tgz",
95
+ "@tryghost/link-tracking": "file:components/tryghost-link-tracking-5.25.1.tgz",
95
96
  "@tryghost/logging": "2.3.2",
96
- "@tryghost/magic-link": "file:components/tryghost-magic-link-5.24.2.tgz",
97
- "@tryghost/mailgun-client": "file:components/tryghost-mailgun-client-5.24.2.tgz",
98
- "@tryghost/member-attribution": "file:components/tryghost-member-attribution-5.24.2.tgz",
99
- "@tryghost/member-events": "file:components/tryghost-member-events-5.24.2.tgz",
100
- "@tryghost/members-api": "file:components/tryghost-members-api-5.24.2.tgz",
101
- "@tryghost/members-csv": "file:components/tryghost-members-csv-5.24.2.tgz",
102
- "@tryghost/members-events-service": "file:components/tryghost-members-events-service-5.24.2.tgz",
103
- "@tryghost/members-importer": "file:components/tryghost-members-importer-5.24.2.tgz",
104
- "@tryghost/members-offers": "file:components/tryghost-members-offers-5.24.2.tgz",
105
- "@tryghost/members-ssr": "file:components/tryghost-members-ssr-5.24.2.tgz",
106
- "@tryghost/members-stripe-service": "file:components/tryghost-members-stripe-service-5.24.2.tgz",
97
+ "@tryghost/magic-link": "file:components/tryghost-magic-link-5.25.1.tgz",
98
+ "@tryghost/mailgun-client": "file:components/tryghost-mailgun-client-5.25.1.tgz",
99
+ "@tryghost/member-attribution": "file:components/tryghost-member-attribution-5.25.1.tgz",
100
+ "@tryghost/member-events": "file:components/tryghost-member-events-5.25.1.tgz",
101
+ "@tryghost/members-api": "file:components/tryghost-members-api-5.25.1.tgz",
102
+ "@tryghost/members-csv": "file:components/tryghost-members-csv-5.25.1.tgz",
103
+ "@tryghost/members-events-service": "file:components/tryghost-members-events-service-5.25.1.tgz",
104
+ "@tryghost/members-importer": "file:components/tryghost-members-importer-5.25.1.tgz",
105
+ "@tryghost/members-offers": "file:components/tryghost-members-offers-5.25.1.tgz",
106
+ "@tryghost/members-ssr": "file:components/tryghost-members-ssr-5.25.1.tgz",
107
+ "@tryghost/members-stripe-service": "file:components/tryghost-members-stripe-service-5.25.1.tgz",
107
108
  "@tryghost/metrics": "1.0.16",
108
- "@tryghost/minifier": "file:components/tryghost-minifier-5.24.2.tgz",
109
- "@tryghost/mw-api-version-mismatch": "file:components/tryghost-mw-api-version-mismatch-5.24.2.tgz",
110
- "@tryghost/mw-cache-control": "file:components/tryghost-mw-cache-control-5.24.2.tgz",
111
- "@tryghost/mw-error-handler": "file:components/tryghost-mw-error-handler-5.24.2.tgz",
112
- "@tryghost/mw-session-from-token": "file:components/tryghost-mw-session-from-token-5.24.2.tgz",
113
- "@tryghost/mw-vhost": "file:components/tryghost-mw-vhost-5.24.2.tgz",
109
+ "@tryghost/minifier": "file:components/tryghost-minifier-5.25.1.tgz",
110
+ "@tryghost/mw-api-version-mismatch": "file:components/tryghost-mw-api-version-mismatch-5.25.1.tgz",
111
+ "@tryghost/mw-cache-control": "file:components/tryghost-mw-cache-control-5.25.1.tgz",
112
+ "@tryghost/mw-error-handler": "file:components/tryghost-mw-error-handler-5.25.1.tgz",
113
+ "@tryghost/mw-session-from-token": "file:components/tryghost-mw-session-from-token-5.25.1.tgz",
114
+ "@tryghost/mw-vhost": "file:components/tryghost-mw-vhost-5.25.1.tgz",
114
115
  "@tryghost/nodemailer": "0.3.29",
115
116
  "@tryghost/nql": "0.11.0",
116
- "@tryghost/oembed-service": "file:components/tryghost-oembed-service-5.24.2.tgz",
117
- "@tryghost/package-json": "file:components/tryghost-package-json-5.24.2.tgz",
117
+ "@tryghost/oembed-service": "file:components/tryghost-oembed-service-5.25.1.tgz",
118
+ "@tryghost/package-json": "file:components/tryghost-package-json-5.25.1.tgz",
118
119
  "@tryghost/pretty-cli": "1.2.31",
119
120
  "@tryghost/promise": "0.2.1",
120
121
  "@tryghost/request": "0.1.31",
121
- "@tryghost/security": "file:components/tryghost-security-5.24.2.tgz",
122
- "@tryghost/session-service": "file:components/tryghost-session-service-5.24.2.tgz",
123
- "@tryghost/settings-path-manager": "file:components/tryghost-settings-path-manager-5.24.2.tgz",
122
+ "@tryghost/security": "file:components/tryghost-security-5.25.1.tgz",
123
+ "@tryghost/session-service": "file:components/tryghost-session-service-5.25.1.tgz",
124
+ "@tryghost/settings-path-manager": "file:components/tryghost-settings-path-manager-5.25.1.tgz",
124
125
  "@tryghost/social-urls": "0.1.33",
125
- "@tryghost/staff-service": "file:components/tryghost-staff-service-5.24.2.tgz",
126
- "@tryghost/stats-service": "file:components/tryghost-stats-service-5.24.2.tgz",
126
+ "@tryghost/staff-service": "file:components/tryghost-staff-service-5.25.1.tgz",
127
+ "@tryghost/stats-service": "file:components/tryghost-stats-service-5.25.1.tgz",
127
128
  "@tryghost/string": "0.2.1",
128
- "@tryghost/tiers": "file:components/tryghost-tiers-5.24.2.tgz",
129
+ "@tryghost/tiers": "file:components/tryghost-tiers-5.25.1.tgz",
129
130
  "@tryghost/tpl": "0.1.19",
130
- "@tryghost/update-check-service": "file:components/tryghost-update-check-service-5.24.2.tgz",
131
- "@tryghost/url-utils": "4.2.0",
131
+ "@tryghost/update-check-service": "file:components/tryghost-update-check-service-5.25.1.tgz",
132
+ "@tryghost/url-utils": "4.3.0",
132
133
  "@tryghost/validator": "0.1.29",
133
- "@tryghost/verification-trigger": "file:components/tryghost-verification-trigger-5.24.2.tgz",
134
+ "@tryghost/verification-trigger": "file:components/tryghost-verification-trigger-5.25.1.tgz",
134
135
  "@tryghost/version": "0.1.16",
135
136
  "@tryghost/zip": "1.1.29",
136
137
  "amperize": "0.6.1",
@@ -203,16 +204,17 @@
203
204
  "cli-progress": "3.11.2",
204
205
  "cssnano": "5.1.14",
205
206
  "eslint": "8.28.0",
207
+ "expect": "^28.1.3",
206
208
  "html-validate": "7.10.0",
207
209
  "inquirer": "8.2.5",
208
- "jwks-rsa": "2.1.5",
210
+ "jwks-rsa": "3.0.0",
209
211
  "mocha": "10.1.0",
210
212
  "mocha-slow-test-reporter": "0.1.2",
211
213
  "mock-knex": "TryGhost/mock-knex#8ecb8c227bf463c991c3d820d33f59efc3ab9682",
212
214
  "nock": "13.2.9",
213
215
  "papaparse": "5.3.2",
214
216
  "postcss": "8.4.19",
215
- "postcss-cli": "10.0.0",
217
+ "postcss-cli": "10.1.0",
216
218
  "rewire": "6.0.0",
217
219
  "should": "13.2.3",
218
220
  "sinon": "14.0.2",
@@ -223,58 +225,58 @@
223
225
  "@tryghost/logging": "2.3.2",
224
226
  "moment": "2.24.0",
225
227
  "moment-timezone": "0.5.23",
226
- "@tryghost/adapter-manager": "file:components/tryghost-adapter-manager-5.24.2.tgz",
227
- "@tryghost/api-framework": "file:components/tryghost-api-framework-5.24.2.tgz",
228
- "@tryghost/api-version-compatibility-service": "file:components/tryghost-api-version-compatibility-service-5.24.2.tgz",
229
- "@tryghost/audience-feedback": "file:components/tryghost-audience-feedback-5.24.2.tgz",
230
- "@tryghost/bootstrap-socket": "file:components/tryghost-bootstrap-socket-5.24.2.tgz",
231
- "@tryghost/constants": "file:components/tryghost-constants-5.24.2.tgz",
232
- "@tryghost/custom-theme-settings-service": "file:components/tryghost-custom-theme-settings-service-5.24.2.tgz",
233
- "@tryghost/data-generator": "file:components/tryghost-data-generator-5.24.2.tgz",
234
- "@tryghost/domain-events": "file:components/tryghost-domain-events-5.24.2.tgz",
235
- "@tryghost/email-analytics-provider-mailgun": "file:components/tryghost-email-analytics-provider-mailgun-5.24.2.tgz",
236
- "@tryghost/email-analytics-service": "file:components/tryghost-email-analytics-service-5.24.2.tgz",
237
- "@tryghost/email-content-generator": "file:components/tryghost-email-content-generator-5.24.2.tgz",
238
- "@tryghost/email-events": "file:components/tryghost-email-events-5.24.2.tgz",
239
- "@tryghost/email-service": "file:components/tryghost-email-service-5.24.2.tgz",
240
- "@tryghost/email-suppression-list": "file:components/tryghost-email-suppression-list-5.24.2.tgz",
241
- "@tryghost/express-dynamic-redirects": "file:components/tryghost-express-dynamic-redirects-5.24.2.tgz",
242
- "@tryghost/extract-api-key": "file:components/tryghost-extract-api-key-5.24.2.tgz",
243
- "@tryghost/html-to-plaintext": "file:components/tryghost-html-to-plaintext-5.24.2.tgz",
244
- "@tryghost/job-manager": "file:components/tryghost-job-manager-5.24.2.tgz",
245
- "@tryghost/link-redirects": "file:components/tryghost-link-redirects-5.24.2.tgz",
246
- "@tryghost/link-replacer": "file:components/tryghost-link-replacer-5.24.2.tgz",
247
- "@tryghost/link-tracking": "file:components/tryghost-link-tracking-5.24.2.tgz",
248
- "@tryghost/magic-link": "file:components/tryghost-magic-link-5.24.2.tgz",
249
- "@tryghost/mailgun-client": "file:components/tryghost-mailgun-client-5.24.2.tgz",
250
- "@tryghost/member-attribution": "file:components/tryghost-member-attribution-5.24.2.tgz",
251
- "@tryghost/member-events": "file:components/tryghost-member-events-5.24.2.tgz",
252
- "@tryghost/members-api": "file:components/tryghost-members-api-5.24.2.tgz",
253
- "@tryghost/members-csv": "file:components/tryghost-members-csv-5.24.2.tgz",
254
- "@tryghost/members-events-service": "file:components/tryghost-members-events-service-5.24.2.tgz",
255
- "@tryghost/members-importer": "file:components/tryghost-members-importer-5.24.2.tgz",
256
- "@tryghost/members-ssr": "file:components/tryghost-members-ssr-5.24.2.tgz",
257
- "@tryghost/minifier": "file:components/tryghost-minifier-5.24.2.tgz",
258
- "@tryghost/mw-api-version-mismatch": "file:components/tryghost-mw-api-version-mismatch-5.24.2.tgz",
259
- "@tryghost/mw-cache-control": "file:components/tryghost-mw-cache-control-5.24.2.tgz",
260
- "@tryghost/mw-error-handler": "file:components/tryghost-mw-error-handler-5.24.2.tgz",
261
- "@tryghost/mw-session-from-token": "file:components/tryghost-mw-session-from-token-5.24.2.tgz",
262
- "@tryghost/mw-update-user-last-seen": "file:components/tryghost-mw-update-user-last-seen-5.24.2.tgz",
263
- "@tryghost/mw-vhost": "file:components/tryghost-mw-vhost-5.24.2.tgz",
264
- "@tryghost/oembed-service": "file:components/tryghost-oembed-service-5.24.2.tgz",
265
- "@tryghost/members-offers": "file:components/tryghost-members-offers-5.24.2.tgz",
266
- "@tryghost/package-json": "file:components/tryghost-package-json-5.24.2.tgz",
267
- "@tryghost/members-payments": "file:components/tryghost-members-payments-5.24.2.tgz",
268
- "@tryghost/referrers": "file:components/tryghost-referrers-5.24.2.tgz",
269
- "@tryghost/security": "file:components/tryghost-security-5.24.2.tgz",
270
- "@tryghost/session-service": "file:components/tryghost-session-service-5.24.2.tgz",
271
- "@tryghost/settings-path-manager": "file:components/tryghost-settings-path-manager-5.24.2.tgz",
272
- "@tryghost/staff-service": "file:components/tryghost-staff-service-5.24.2.tgz",
273
- "@tryghost/stats-service": "file:components/tryghost-stats-service-5.24.2.tgz",
274
- "@tryghost/members-stripe-service": "file:components/tryghost-members-stripe-service-5.24.2.tgz",
275
- "@tryghost/tiers": "file:components/tryghost-tiers-5.24.2.tgz",
276
- "@tryghost/update-check-service": "file:components/tryghost-update-check-service-5.24.2.tgz",
277
- "@tryghost/verification-trigger": "file:components/tryghost-verification-trigger-5.24.2.tgz",
278
- "@tryghost/version-notifications-data-service": "file:components/tryghost-version-notifications-data-service-5.24.2.tgz"
228
+ "@tryghost/adapter-manager": "file:components/tryghost-adapter-manager-5.25.1.tgz",
229
+ "@tryghost/api-framework": "file:components/tryghost-api-framework-5.25.1.tgz",
230
+ "@tryghost/api-version-compatibility-service": "file:components/tryghost-api-version-compatibility-service-5.25.1.tgz",
231
+ "@tryghost/audience-feedback": "file:components/tryghost-audience-feedback-5.25.1.tgz",
232
+ "@tryghost/bootstrap-socket": "file:components/tryghost-bootstrap-socket-5.25.1.tgz",
233
+ "@tryghost/constants": "file:components/tryghost-constants-5.25.1.tgz",
234
+ "@tryghost/custom-theme-settings-service": "file:components/tryghost-custom-theme-settings-service-5.25.1.tgz",
235
+ "@tryghost/data-generator": "file:components/tryghost-data-generator-5.25.1.tgz",
236
+ "@tryghost/domain-events": "file:components/tryghost-domain-events-5.25.1.tgz",
237
+ "@tryghost/email-analytics-provider-mailgun": "file:components/tryghost-email-analytics-provider-mailgun-5.25.1.tgz",
238
+ "@tryghost/email-analytics-service": "file:components/tryghost-email-analytics-service-5.25.1.tgz",
239
+ "@tryghost/email-content-generator": "file:components/tryghost-email-content-generator-5.25.1.tgz",
240
+ "@tryghost/email-events": "file:components/tryghost-email-events-5.25.1.tgz",
241
+ "@tryghost/email-service": "file:components/tryghost-email-service-5.25.1.tgz",
242
+ "@tryghost/email-suppression-list": "file:components/tryghost-email-suppression-list-5.25.1.tgz",
243
+ "@tryghost/express-dynamic-redirects": "file:components/tryghost-express-dynamic-redirects-5.25.1.tgz",
244
+ "@tryghost/extract-api-key": "file:components/tryghost-extract-api-key-5.25.1.tgz",
245
+ "@tryghost/html-to-plaintext": "file:components/tryghost-html-to-plaintext-5.25.1.tgz",
246
+ "@tryghost/job-manager": "file:components/tryghost-job-manager-5.25.1.tgz",
247
+ "@tryghost/link-redirects": "file:components/tryghost-link-redirects-5.25.1.tgz",
248
+ "@tryghost/link-replacer": "file:components/tryghost-link-replacer-5.25.1.tgz",
249
+ "@tryghost/link-tracking": "file:components/tryghost-link-tracking-5.25.1.tgz",
250
+ "@tryghost/magic-link": "file:components/tryghost-magic-link-5.25.1.tgz",
251
+ "@tryghost/mailgun-client": "file:components/tryghost-mailgun-client-5.25.1.tgz",
252
+ "@tryghost/member-attribution": "file:components/tryghost-member-attribution-5.25.1.tgz",
253
+ "@tryghost/member-events": "file:components/tryghost-member-events-5.25.1.tgz",
254
+ "@tryghost/members-api": "file:components/tryghost-members-api-5.25.1.tgz",
255
+ "@tryghost/members-csv": "file:components/tryghost-members-csv-5.25.1.tgz",
256
+ "@tryghost/members-events-service": "file:components/tryghost-members-events-service-5.25.1.tgz",
257
+ "@tryghost/members-importer": "file:components/tryghost-members-importer-5.25.1.tgz",
258
+ "@tryghost/members-ssr": "file:components/tryghost-members-ssr-5.25.1.tgz",
259
+ "@tryghost/minifier": "file:components/tryghost-minifier-5.25.1.tgz",
260
+ "@tryghost/mw-api-version-mismatch": "file:components/tryghost-mw-api-version-mismatch-5.25.1.tgz",
261
+ "@tryghost/mw-cache-control": "file:components/tryghost-mw-cache-control-5.25.1.tgz",
262
+ "@tryghost/mw-error-handler": "file:components/tryghost-mw-error-handler-5.25.1.tgz",
263
+ "@tryghost/mw-session-from-token": "file:components/tryghost-mw-session-from-token-5.25.1.tgz",
264
+ "@tryghost/mw-update-user-last-seen": "file:components/tryghost-mw-update-user-last-seen-5.25.1.tgz",
265
+ "@tryghost/mw-vhost": "file:components/tryghost-mw-vhost-5.25.1.tgz",
266
+ "@tryghost/oembed-service": "file:components/tryghost-oembed-service-5.25.1.tgz",
267
+ "@tryghost/members-offers": "file:components/tryghost-members-offers-5.25.1.tgz",
268
+ "@tryghost/package-json": "file:components/tryghost-package-json-5.25.1.tgz",
269
+ "@tryghost/members-payments": "file:components/tryghost-members-payments-5.25.1.tgz",
270
+ "@tryghost/referrers": "file:components/tryghost-referrers-5.25.1.tgz",
271
+ "@tryghost/security": "file:components/tryghost-security-5.25.1.tgz",
272
+ "@tryghost/session-service": "file:components/tryghost-session-service-5.25.1.tgz",
273
+ "@tryghost/settings-path-manager": "file:components/tryghost-settings-path-manager-5.25.1.tgz",
274
+ "@tryghost/staff-service": "file:components/tryghost-staff-service-5.25.1.tgz",
275
+ "@tryghost/stats-service": "file:components/tryghost-stats-service-5.25.1.tgz",
276
+ "@tryghost/members-stripe-service": "file:components/tryghost-members-stripe-service-5.25.1.tgz",
277
+ "@tryghost/tiers": "file:components/tryghost-tiers-5.25.1.tgz",
278
+ "@tryghost/update-check-service": "file:components/tryghost-update-check-service-5.25.1.tgz",
279
+ "@tryghost/verification-trigger": "file:components/tryghost-verification-trigger-5.25.1.tgz",
280
+ "@tryghost/version-notifications-data-service": "file:components/tryghost-version-notifications-data-service-5.25.1.tgz"
279
281
  }
280
282
  }