ghost 4.24.0 → 4.26.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 (147) hide show
  1. package/.eslintrc.js +39 -0
  2. package/content/themes/casper/assets/built/casper.js +1 -1
  3. package/content/themes/casper/assets/built/casper.js.map +1 -1
  4. package/content/themes/casper/assets/built/global.css +1 -1
  5. package/content/themes/casper/assets/built/global.css.map +1 -1
  6. package/content/themes/casper/assets/built/screen.css +1 -1
  7. package/content/themes/casper/assets/built/screen.css.map +1 -1
  8. package/content/themes/casper/assets/css/global.css +6 -1
  9. package/content/themes/casper/assets/css/screen.css +50 -215
  10. package/content/themes/casper/default.hbs +2 -2
  11. package/content/themes/casper/package.json +3 -2
  12. package/content/themes/casper/post.hbs +1 -1
  13. package/content/themes/casper/yarn.lock +173 -123
  14. package/core/app.js +8 -4
  15. package/core/boot.js +52 -25
  16. package/core/built/assets/ghost-dark-ef86e3bc7f0fb83d39d3d6a49bff8dd5.css +1 -0
  17. package/core/built/assets/ghost.min-57c1e677f42d596942d317ce93e8a62c.css +1 -0
  18. package/core/built/assets/{ghost.min-d5595f9c71ebc534ccf9ac78483d357c.js → ghost.min-f3c6886e191d34450e9ffca0c8fa056e.js} +504 -579
  19. package/core/built/assets/icons/audio-upload.svg +8 -0
  20. package/core/built/assets/{vendor.min-1a84ac3ef74edf31c6e86810b45221cc.js → vendor.min-b6b8d2a31d61830c2d8f65c5ba54236a.js} +2614 -2149
  21. package/core/frontend/apps/amp/lib/helpers/amp_content.js +2 -2
  22. package/core/frontend/apps/amp/lib/views/amp.hbs +75 -0
  23. package/core/frontend/apps/private-blogging/index.js +1 -1
  24. package/core/frontend/helpers/url.js +18 -1
  25. package/core/frontend/services/apps/index.js +1 -1
  26. package/core/frontend/services/apps/loader.js +3 -3
  27. package/core/frontend/services/helpers/handlebars.js +1 -1
  28. package/core/frontend/services/theme-engine/middleware/ensure-active-theme.js +34 -0
  29. package/core/frontend/services/theme-engine/middleware/index.js +6 -0
  30. package/core/frontend/services/theme-engine/middleware/update-global-template-options.js +116 -0
  31. package/core/frontend/services/theme-engine/middleware/update-local-template-data.js +9 -0
  32. package/core/frontend/services/theme-engine/middleware/update-local-template-options.js +57 -0
  33. package/core/frontend/src/cards/css/audio.css +186 -0
  34. package/core/frontend/src/cards/css/blockquote.css +27 -0
  35. package/core/frontend/src/cards/css/button.css +4 -0
  36. package/core/frontend/src/cards/css/callout.css +23 -14
  37. package/core/frontend/src/cards/css/toggle.css +42 -20
  38. package/core/frontend/src/cards/js/audio.js +137 -0
  39. package/core/frontend/web/middleware/error-handler.js +93 -0
  40. package/core/frontend/web/middleware/handle-image-sizes.js +3 -6
  41. package/core/frontend/web/middleware/index.js +1 -0
  42. package/core/frontend/web/site.js +2 -2
  43. package/core/server/adapters/scheduling/SchedulingDefault.js +2 -2
  44. package/core/server/adapters/storage/LocalStorageBase.js +2 -2
  45. package/core/server/api/canary/db.js +2 -2
  46. package/core/server/api/canary/media.js +3 -2
  47. package/core/server/api/canary/oembed.js +16 -1
  48. package/core/server/api/canary/session.js +1 -1
  49. package/core/server/api/canary/slugs.js +1 -1
  50. package/core/server/api/canary/utils/permissions.js +2 -2
  51. package/core/server/api/canary/utils/serializers/output/config.js +2 -6
  52. package/core/server/api/v2/db.js +2 -2
  53. package/core/server/api/v2/session.js +1 -1
  54. package/core/server/api/v2/slugs.js +1 -1
  55. package/core/server/api/v2/utils/permissions.js +2 -2
  56. package/core/server/api/v3/db.js +2 -2
  57. package/core/server/api/v3/session.js +1 -1
  58. package/core/server/api/v3/slugs.js +1 -1
  59. package/core/server/api/v3/utils/permissions.js +2 -2
  60. package/core/server/data/db/state-manager.js +4 -4
  61. package/core/server/data/exporter/export-filename.js +1 -1
  62. package/core/server/data/importer/handlers/json.js +1 -1
  63. package/core/server/data/importer/import-manager.js +1 -1
  64. package/core/server/data/importer/importers/data/base.js +1 -1
  65. package/core/server/data/migrations/utils.js +2 -2
  66. package/core/server/data/migrations/versions/1.25/1-update-koenig-beta-html.js +1 -0
  67. package/core/server/data/migrations/versions/3.1/08-add-uuid-values-to-members.js +1 -0
  68. package/core/server/data/migrations/versions/3.22/02-settings-key-renames.js +2 -0
  69. package/core/server/data/migrations/versions/3.22/05-migrate-members-subscription-settings.js +3 -0
  70. package/core/server/data/migrations/versions/3.22/06-migrate-stripe-connect-settings.js +2 -0
  71. package/core/server/data/migrations/versions/3.23/01-migrate-bulk-email-settings.js +1 -0
  72. package/core/server/data/migrations/versions/3.29/01-remove-duplicate-subscriptions.js +2 -0
  73. package/core/server/data/migrations/versions/3.29/02-remove-duplicate-customers.js +2 -0
  74. package/core/server/data/migrations/versions/3.38/04-populate-recipient-filter-column.js +2 -0
  75. package/core/server/data/migrations/versions/4.0/01-update-mobiledoc.js +2 -0
  76. package/core/server/data/migrations/versions/4.0/03-populate-status-column-for-members.js +4 -0
  77. package/core/server/data/migrations/versions/4.0/06-populate-members-subscribe-events-table.js +1 -0
  78. package/core/server/data/migrations/versions/4.0/17-populate-members-status-events-table.js +1 -0
  79. package/core/server/data/migrations/versions/4.0/18-transform-urls-absolute-to-transform-ready.js +5 -0
  80. package/core/server/data/migrations/versions/4.0/22-solve-orphaned-webhooks.js +1 -0
  81. package/core/server/data/migrations/versions/4.0/23-regenerate-posts-html.js +1 -0
  82. package/core/server/data/migrations/versions/4.0/25-populate-members-paid-subscription-events-table.js +2 -1
  83. package/core/server/data/migrations/versions/4.12/02-fix-member-statuses.js +1 -0
  84. package/core/server/data/migrations/versions/4.14/01-fix-comped-member-statuses.js +3 -0
  85. package/core/server/data/migrations/versions/4.14/02-fix-free-members-status-events.js +1 -0
  86. package/core/server/data/migrations/versions/4.20/05-remove-not-null-constraint-from-portal-title.js +2 -0
  87. package/core/server/data/migrations/versions/4.23/01-truncate-offer-names.js +1 -0
  88. package/core/server/data/migrations/versions/4.3/04-attach-members-to-product.js +1 -0
  89. package/core/server/data/migrations/versions/4.4/01-restore-free-members-signup-setting-from-backup.js +1 -0
  90. package/core/server/data/migrations/versions/4.6/01-remove-comped-status.js +1 -0
  91. package/core/server/data/migrations/versions/4.8/04-migrate-show-newsletter-header-setting.js +1 -0
  92. package/core/server/data/migrations/versions/4.9/05-fix-missed-mobiledoc-url-transforms.js +1 -0
  93. package/core/server/data/migrations/versions/4.9/06-add-comped-status.js +1 -0
  94. package/core/server/data/migrations/versions/4.9/07-update-comped-members-status-events.js +1 -0
  95. package/core/server/data/schema/commands.js +2 -2
  96. package/core/server/ghost-server.js +2 -2
  97. package/core/server/lib/image/image-size.js +2 -2
  98. package/core/server/models/base/listeners.js +2 -2
  99. package/core/server/models/member-email-change-event.js +2 -2
  100. package/core/server/models/member-login-event.js +2 -2
  101. package/core/server/models/member-paid-subscription-event.js +3 -3
  102. package/core/server/models/member-payment-event.js +3 -3
  103. package/core/server/models/member-product-event.js +6 -6
  104. package/core/server/models/member-status-event.js +5 -3
  105. package/core/server/models/member-subscribe-event.js +9 -3
  106. package/core/server/models/relations/authors.js +1 -1
  107. package/core/server/models/settings.js +1 -1
  108. package/core/server/notify.js +1 -2
  109. package/core/server/services/auth/passwordreset.js +1 -1
  110. package/core/server/services/auth/setup.js +1 -1
  111. package/core/server/services/mega/mega.js +6 -4
  112. package/core/server/services/mega/template.js +43 -17
  113. package/core/server/services/members/api.js +22 -0
  114. package/core/server/services/members/config.js +1 -1
  115. package/core/server/services/members/emails/signup-paid.js +168 -0
  116. package/core/server/services/members/service.js +6 -2
  117. package/core/server/services/members/stripe-connect.js +4 -2
  118. package/core/server/services/nft-oembed.js +7 -2
  119. package/core/server/services/oembed.js +15 -3
  120. package/core/server/services/permissions/can-this.js +1 -1
  121. package/core/server/services/redirects/api.js +2 -2
  122. package/core/server/services/route-settings/default-settings-manager.js +1 -1
  123. package/core/server/services/route-settings/route-settings.js +4 -12
  124. package/core/server/services/route-settings/settings-loader.js +4 -4
  125. package/core/server/services/route-settings/yaml-parser.js +1 -1
  126. package/core/server/services/slack.js +1 -1
  127. package/core/server/services/themes/storage.js +2 -2
  128. package/core/server/services/twitter-embed.js +81 -0
  129. package/core/server/services/xmlrpc.js +2 -2
  130. package/core/server/web/admin/views/default-prod.html +4 -4
  131. package/core/server/web/admin/views/default.html +4 -4
  132. package/core/server/web/api/canary/admin/middleware.js +1 -1
  133. package/core/server/web/api/v2/admin/middleware.js +1 -1
  134. package/core/server/web/api/v3/admin/middleware.js +1 -1
  135. package/core/server/web/parent/app.js +2 -22
  136. package/core/server/web/parent/backend.js +2 -0
  137. package/core/server/web/shared/middleware/error-handler.js +28 -150
  138. package/core/shared/config/defaults.json +7 -1
  139. package/core/shared/express.js +1 -1
  140. package/core/shared/labs.js +7 -7
  141. package/core/shared/sentry.js +1 -1
  142. package/package.json +38 -38
  143. package/yarn.lock +632 -941
  144. package/content/themes/casper/assets/js/gallery-card.js +0 -24
  145. package/core/built/assets/ghost-dark-e7b57ab951512c5719aee89b16b9a448.css +0 -1
  146. package/core/built/assets/ghost.min-7f3603dbeb5ebf0ec09e207ae82fb4e3.css +0 -1
  147. package/core/frontend/services/theme-engine/middleware.js +0 -209
@@ -42,7 +42,7 @@ const session = {
42
42
  });
43
43
  });
44
44
  }).catch(async (err) => {
45
- if (!errors.utils.isIgnitionError(err)) {
45
+ if (!errors.utils.isGhostError(err)) {
46
46
  throw new errors.UnauthorizedError({
47
47
  message: tpl(messages.accessDenied),
48
48
  err
@@ -39,7 +39,7 @@ module.exports = {
39
39
  return models.Base.Model.generateSlug(allowedTypes[frame.options.type], frame.data.name, {status: 'all'})
40
40
  .then((slug) => {
41
41
  if (!slug) {
42
- return Promise.reject(new errors.GhostError({message: tpl(messages.couldNotGenerateSlug)}));
42
+ return Promise.reject(new errors.InternalServerError({message: tpl(messages.couldNotGenerateSlug)}));
43
43
  }
44
44
  return slug;
45
45
  });
@@ -66,11 +66,11 @@ const nonePublicAuth = (apiConfig, frame) => {
66
66
  return Promise.reject(err);
67
67
  }
68
68
 
69
- if (errors.utils.isIgnitionError(err)) {
69
+ if (errors.utils.isGhostError(err)) {
70
70
  return Promise.reject(err);
71
71
  }
72
72
 
73
- return Promise.reject(new errors.GhostError({
73
+ return Promise.reject(new errors.InternalServerError({
74
74
  err: err
75
75
  }));
76
76
  });
@@ -59,8 +59,8 @@ class DatabaseStateManager {
59
59
 
60
60
  // CASE: database connection errors, unknown cases
61
61
  let errorToThrow = error;
62
- if (!errors.utils.isIgnitionError(errorToThrow)) {
63
- errorToThrow = new errors.GhostError({message: errorToThrow.message, err: errorToThrow});
62
+ if (!errors.utils.isGhostError(errorToThrow)) {
63
+ errorToThrow = new errors.InternalServerError({message: errorToThrow.message, err: errorToThrow});
64
64
  }
65
65
 
66
66
  throw errorToThrow;
@@ -94,8 +94,8 @@ class DatabaseStateManager {
94
94
  }
95
95
  } catch (error) {
96
96
  let errorToThrow = error;
97
- if (!errors.utils.isIgnitionError(error)) {
98
- errorToThrow = new errors.GhostError({message: errorToThrow.message, err: errorToThrow});
97
+ if (!errors.utils.isGhostError(error)) {
98
+ errorToThrow = new errors.InternalServerError({message: errorToThrow.message, err: errorToThrow});
99
99
  }
100
100
 
101
101
  throw errorToThrow;
@@ -26,7 +26,7 @@ const exportFileName = async function exportFileName(options) {
26
26
 
27
27
  return title + 'ghost.' + datetime + '.json';
28
28
  } catch (err) {
29
- logging.error(new errors.GhostError({err: err}));
29
+ logging.error(new errors.InternalServerError({err: err}));
30
30
  return 'ghost.' + datetime + '.json';
31
31
  }
32
32
  };
@@ -30,7 +30,7 @@ JSONHandler = {
30
30
  // if importData follows JSON-API format `{ db: [exportedData] }`
31
31
  if (_.keys(importData).length === 1) {
32
32
  if (!importData.db || !Array.isArray(importData.db)) {
33
- throw new errors.GhostError({
33
+ throw new errors.InternalServerError({
34
34
  message: tpl(messages.invalidJsonFormat)
35
35
  });
36
36
  }
@@ -121,7 +121,7 @@ class ImportManager {
121
121
 
122
122
  fs.remove(self.fileToDelete, function (err) {
123
123
  if (err) {
124
- logging.error(new errors.GhostError({
124
+ logging.error(new errors.InternalServerError({
125
125
  err: err,
126
126
  context: tpl(messages.couldNotCleanUpFile.error),
127
127
  help: tpl(messages.couldNotCleanUpFile.context)
@@ -145,7 +145,7 @@ class Base {
145
145
  });
146
146
  }
147
147
  } else {
148
- if (!errors.utils.isIgnitionError(err)) {
148
+ if (!errors.utils.isGhostError(err)) {
149
149
  err = new errors.DataImportError({
150
150
  message: err.message,
151
151
  context: JSON.stringify(obj),
@@ -143,7 +143,7 @@ function addPermissionToRole(config) {
143
143
  }).first();
144
144
 
145
145
  if (!permission) {
146
- throw new errors.GhostError({
146
+ throw new errors.InternalServerError({
147
147
  message: tpl(messages.permissionRoleActionError, {
148
148
  action: 'add',
149
149
  permission: config.permission,
@@ -158,7 +158,7 @@ function addPermissionToRole(config) {
158
158
  }).first();
159
159
 
160
160
  if (!role) {
161
- throw new errors.GhostError({
161
+ throw new errors.InternalServerError({
162
162
  message: tpl(messages.permissionRoleActionError, {
163
163
  action: 'add',
164
164
  permission: config.permission,
@@ -45,6 +45,7 @@ module.exports.up = function regenerateKoenigBetaHTML(options) {
45
45
  || (mobiledoc && !mobiledocIsCompatibleWithV1(mobiledoc))
46
46
  ) {
47
47
  // change imagecard.payload.imageStyle to imagecard.payload.cardWidth
48
+ // eslint-disable-next-line no-restricted-syntax
48
49
  mobiledoc.cards.forEach((card) => {
49
50
  if (card[0] === 'image') {
50
51
  card[1].cardWidth = card[1].imageStyle;
@@ -12,6 +12,7 @@ module.exports = {
12
12
 
13
13
  logging.info(`Adding uuid field value to ${membersWithoutUUID.length} members.`);
14
14
 
15
+ // eslint-disable-next-line no-restricted-syntax
15
16
  for (const member of membersWithoutUUID) {
16
17
  await conn('members').update('uuid', uuid.v4()).where('id', member.id);
17
18
  }
@@ -35,6 +35,7 @@ module.exports = {
35
35
  },
36
36
 
37
37
  async up(options) {
38
+ // eslint-disable-next-line no-restricted-syntax
38
39
  for (const renameMapping of renameMappings) {
39
40
  const oldSetting = await options.transacting('settings')
40
41
  .where('key', renameMapping.from)
@@ -61,6 +62,7 @@ module.exports = {
61
62
  },
62
63
 
63
64
  async down(options) {
65
+ // eslint-disable-next-line no-restricted-syntax
64
66
  for (const renameMapping of renameMappings) {
65
67
  const newSetting = await options.transacting('settings')
66
68
  .where('key', renameMapping.to)
@@ -24,6 +24,7 @@ module.exports = {
24
24
  key: 'stripe_plans'
25
25
  }];
26
26
 
27
+ // eslint-disable-next-line no-restricted-syntax
27
28
  for (const operation of defaultOperations) {
28
29
  logging.info(`Updating ${operation.key} setting group,type,flags`);
29
30
  await knex('settings')
@@ -86,6 +87,7 @@ module.exports = {
86
87
  value: JSON.stringify(stripePlans)
87
88
  }];
88
89
 
90
+ // eslint-disable-next-line no-restricted-syntax
89
91
  for (const operation of valueOperations) {
90
92
  logging.info(`Updating ${operation.key} setting value`);
91
93
  await knex('settings')
@@ -170,6 +172,7 @@ module.exports = {
170
172
  'stripe_secret_key'
171
173
  ];
172
174
 
175
+ // eslint-disable-next-line no-restricted-syntax
173
176
  for (const setting of settingsToDelete) {
174
177
  logging.info(`Deleting ${setting} setting`);
175
178
  }
@@ -20,6 +20,7 @@ module.exports = {
20
20
  key: 'stripe_connect_account_id'
21
21
  }];
22
22
 
23
+ // eslint-disable-next-line no-restricted-syntax
23
24
  for (const operation of defaultOperations) {
24
25
  logging.info(`Updating ${operation.key} setting group,type,flags`);
25
26
  await knex('settings')
@@ -62,6 +63,7 @@ module.exports = {
62
63
  value: stripeConnectIntegration.account_id || ''
63
64
  }];
64
65
 
66
+ // eslint-disable-next-line no-restricted-syntax
65
67
  for (const operation of valueOperations) {
66
68
  logging.info(`Updating ${operation.key} setting value`);
67
69
  await knex('settings')
@@ -35,6 +35,7 @@ module.exports = {
35
35
  value: bulkEmailSettings.baseUrl
36
36
  }];
37
37
 
38
+ // eslint-disable-next-line no-restricted-syntax
38
39
  for (const operation of operations) {
39
40
  logging.info(`Updating ${operation.key} setting's value, group, type & flags.`);
40
41
  await knex('settings')
@@ -23,6 +23,7 @@ module.exports = {
23
23
  }
24
24
 
25
25
  logging.info(`Found ${duplicates.length} duplicate stripe subscriptions`);
26
+ // eslint-disable-next-line no-restricted-syntax
26
27
  for (const duplicate of duplicates) {
27
28
  const subscriptions = await knex('members_stripe_customers_subscriptions')
28
29
  .select()
@@ -36,6 +37,7 @@ module.exports = {
36
37
 
37
38
  logging.info(`Keeping newest subscription ${newestSubscription.id} - ${newestSubscription.subscription_id}, last updated at ${newestSubscription.updated_at}`);
38
39
 
40
+ // eslint-disable-next-line no-restricted-syntax
39
41
  for (const subscriptionToDelete of olderSubscriptions) {
40
42
  logging.info(`Deleting duplicate subscription ${subscriptionToDelete.id} - ${subscriptionToDelete.subscription_id}, last updated at ${subscriptionToDelete.updated_at}`);
41
43
  await knex('members_stripe_customers_subscriptions')
@@ -23,6 +23,7 @@ module.exports = {
23
23
  }
24
24
 
25
25
  logging.info(`Found ${duplicates.length} duplicate stripe customers`);
26
+ // eslint-disable-next-line no-restricted-syntax
26
27
  for (const duplicate of duplicates) {
27
28
  const customers = await knex('members_stripe_customers')
28
29
  .select()
@@ -36,6 +37,7 @@ module.exports = {
36
37
 
37
38
  logging.info(`Keeping newest customer ${newestCustomer.id} - ${newestCustomer.customer_id}, last updated at ${newestCustomer.updated_at}`);
38
39
 
40
+ // eslint-disable-next-line no-restricted-syntax
39
41
  for (const customerToDelete of olderCustomers) {
40
42
  logging.info(`Deleting duplicate customer ${customerToDelete.id} - ${customerToDelete.customer_id}, last updated at ${customerToDelete.updated_at}`);
41
43
  await knex('members_stripe_customers')
@@ -25,12 +25,14 @@ module.exports = createTransactionalMigration(
25
25
  const paidPostIdChunks = chunk(paidPostIds, chunkSize);
26
26
  const membersAndPublicPostIdChunks = chunk(membersPostIds.concat(publicPostIds), chunkSize);
27
27
 
28
+ // eslint-disable-next-line no-restricted-syntax
28
29
  for (const paidPostIdsChunk of paidPostIdChunks) {
29
30
  await connection('emails')
30
31
  .update('recipient_filter', 'paid')
31
32
  .whereIn('post_id', paidPostIdsChunk);
32
33
  }
33
34
 
35
+ // eslint-disable-next-line no-restricted-syntax
34
36
  for (const membersAndPublicPostIdsChunk of membersAndPublicPostIdChunks) {
35
37
  await connection('emails')
36
38
  .update('recipient_filter', 'all')
@@ -15,6 +15,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
15
15
  // pushing all queries into the query builder buffer in parallel
16
16
  // https://stackoverflow.com/questions/54105280/how-to-loop-through-multi-line-sql-query-and-use-them-in-knex-transactions
17
17
 
18
+ // eslint-disable-next-line no-restricted-syntax
18
19
  for (const postIdRow of postIdRows) {
19
20
  const {id} = postIdRow;
20
21
  const [{mobiledoc: mobiledocJson}] = await knex('posts')
@@ -31,6 +32,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
31
32
  }
32
33
 
33
34
  if (mobiledoc.cards) {
35
+ // eslint-disable-next-line no-restricted-syntax
34
36
  mobiledoc.cards.forEach((card) => {
35
37
  // card-markdown card was used in 1.0 and aliased to markdown in 2.0 onwards
36
38
  // clean it up here whilst we're already modifying mobiledoc
@@ -5,6 +5,7 @@ const logging = require('@tryghost/logging');
5
5
  module.exports = createTransactionalMigration(
6
6
  async function up(knex) {
7
7
  logging.info('Updating members.status based on members_stripe_customers_subscriptions.status');
8
+ // eslint-disable-next-line no-restricted-syntax
8
9
  const paidMemberIds = (await knex('members')
9
10
  .select('members.id')
10
11
  .innerJoin(
@@ -24,6 +25,7 @@ module.exports = createTransactionalMigration(
24
25
  }
25
26
  )).map(({id}) => id);
26
27
 
28
+ // eslint-disable-next-line no-restricted-syntax
27
29
  const compedMemberIds = (await knex('members')
28
30
  .select('members.id')
29
31
  .innerJoin(
@@ -54,6 +56,7 @@ module.exports = createTransactionalMigration(
54
56
 
55
57
  const paidMemberIdChunks = chunk(paidMemberIds, chunkSize);
56
58
 
59
+ // eslint-disable-next-line no-restricted-syntax
57
60
  for (const paidMemberIdsChunk of paidMemberIdChunks) {
58
61
  await knex('members')
59
62
  .update('status', 'paid')
@@ -62,6 +65,7 @@ module.exports = createTransactionalMigration(
62
65
 
63
66
  const compedMemberIdChunks = chunk(compedMemberIds, chunkSize);
64
67
 
68
+ // eslint-disable-next-line no-restricted-syntax
65
69
  for (const compedMemberIdsChunk of compedMemberIdChunks) {
66
70
  await knex('members')
67
71
  .update('status', 'comped')
@@ -42,6 +42,7 @@ module.exports = createTransactionalMigration(
42
42
 
43
43
  const eventChunks = chunk(allEvents, chunkSize);
44
44
 
45
+ // eslint-disable-next-line no-restricted-syntax
45
46
  for (const events of eventChunks) {
46
47
  await knex.insert(events).into('members_subscribe_events');
47
48
  }
@@ -28,6 +28,7 @@ module.exports = createTransactionalMigration(
28
28
 
29
29
  const eventChunks = chunk(membersStatusEvents, chunkSize);
30
30
 
31
+ // eslint-disable-next-line no-restricted-syntax
31
32
  for (const events of eventChunks) {
32
33
  await knex.insert(events).into('members_status_events');
33
34
  }
@@ -18,6 +18,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
18
18
  // pushing all queries into the query builder buffer in parallel
19
19
  // https://stackoverflow.com/questions/54105280/how-to-loop-through-multi-line-sql-query-and-use-them-in-knex-transactions
20
20
 
21
+ // eslint-disable-next-line no-restricted-syntax
21
22
  for (const postIdRow of postIdRows) {
22
23
  const {id} = postIdRow;
23
24
  const [post] = await knex('posts')
@@ -80,6 +81,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
80
81
  .forUpdate()
81
82
  .select('id');
82
83
 
84
+ // eslint-disable-next-line no-restricted-syntax
83
85
  for (const userIdRow of userIdRows) {
84
86
  const {id} = userIdRow;
85
87
  const [user] = await knex('users')
@@ -108,6 +110,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
108
110
  .forUpdate()
109
111
  .select('id');
110
112
 
113
+ // eslint-disable-next-line no-restricted-syntax
111
114
  for (const tagIdRow of tagIdRows) {
112
115
  const {id} = tagIdRow;
113
116
  const [tag] = await knex('tags')
@@ -148,6 +151,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
148
151
  .forUpdate()
149
152
  .select('id');
150
153
 
154
+ // eslint-disable-next-line no-restricted-syntax
151
155
  for (const snippetIdRow of snippetIdRows) {
152
156
  const {id} = snippetIdRow;
153
157
  const [snippet] = await knex('snippets')
@@ -180,6 +184,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
180
184
  'twitter_image'
181
185
  ]);
182
186
 
187
+ // eslint-disable-next-line no-restricted-syntax
183
188
  for (const settingRow of settingsRows) {
184
189
  let {key, value} = settingRow;
185
190
 
@@ -77,6 +77,7 @@ module.exports = createIrreversibleMigration(
77
77
  };
78
78
  await knex('api_keys').insert(adminKey);
79
79
 
80
+ // eslint-disable-next-line no-restricted-syntax
80
81
  for (let i = 0; i < orphanedWebhooks.length; i++) {
81
82
  const webhook = orphanedWebhooks[i];
82
83
 
@@ -17,6 +17,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
17
17
  // pushing all queries into the query builder buffer in parallel
18
18
  // https://stackoverflow.com/questions/54105280/how-to-loop-through-multi-line-sql-query-and-use-them-in-knex-transactions
19
19
 
20
+ // eslint-disable-next-line no-restricted-syntax
20
21
  for (const postIdRow of postIdRows) {
21
22
  const {id} = postIdRow;
22
23
  const [post] = await knex('posts')
@@ -44,7 +44,7 @@ module.exports = createTransactionalMigration(
44
44
  return amount * 30;
45
45
  }
46
46
 
47
- throw new errors.GhostError({
47
+ throw new errors.InternalServerError({
48
48
  message: tpl(messages.unknownSubscriptionIntervalError , {
49
49
  interval
50
50
  })
@@ -116,6 +116,7 @@ module.exports = createTransactionalMigration(
116
116
 
117
117
  const eventChunks = chunk(allEvents, chunkSize);
118
118
 
119
+ // eslint-disable-next-line no-restricted-syntax
119
120
  for (const events of eventChunks) {
120
121
  await knex.insert(events).into('members_paid_subscription_events');
121
122
  }
@@ -26,6 +26,7 @@ module.exports = createTransactionalMigration(
26
26
 
27
27
  const chunks = chunkArray(freeMembersIds, chunkSize);
28
28
 
29
+ // eslint-disable-next-line no-restricted-syntax
29
30
  for (const chunk of chunks) {
30
31
  await knex('members')
31
32
  .update('status', 'free')
@@ -3,6 +3,7 @@ const {createTransactionalMigration} = require('../../utils');
3
3
  const logging = require('@tryghost/logging');
4
4
 
5
5
  module.exports = createTransactionalMigration(async function up(knex) {
6
+ // eslint-disable-next-line no-restricted-syntax
6
7
  const compedMemberIds = (await knex('members')
7
8
  .select('members.id')
8
9
  .innerJoin(
@@ -44,12 +45,14 @@ module.exports = createTransactionalMigration(async function up(knex) {
44
45
 
45
46
  const compedMemberIdChunks = chunk(compedMemberIds, chunkSize);
46
47
 
48
+ // eslint-disable-next-line no-restricted-syntax
47
49
  for (const compedMemberIdsChunk of compedMemberIdChunks) {
48
50
  await knex('members')
49
51
  .update('status', 'comped')
50
52
  .whereIn('id', compedMemberIdsChunk);
51
53
  }
52
54
 
55
+ // eslint-disable-next-line no-restricted-syntax
53
56
  for (const memberId of compedMemberIds) {
54
57
  const mostRecentStatusEvent = await knex('members_status_events')
55
58
  .select('*')
@@ -49,6 +49,7 @@ module.exports = createTransactionalMigration(
49
49
  // and so we're left with 998 for our WHERE IN clause values
50
50
  const chunkedEventsToUpdate = _.chunk(eventsToUpdate, 998);
51
51
 
52
+ // eslint-disable-next-line no-restricted-syntax
52
53
  for (const chunk of chunkedEventsToUpdate) {
53
54
  logging.info(`Updating a chunk of ${chunk.length} member status events`);
54
55
  await knex('members_status_events')
@@ -15,6 +15,7 @@ module.exports = createNonTransactionalMigration(
15
15
  });
16
16
 
17
17
  if (knex.client.config.client === 'sqlite3') {
18
+ // eslint-disable-next-line no-restricted-syntax
18
19
  for (const column of ['name', 'code', 'stripe_coupon_id']) {
19
20
  await addUnique('offers', column, knex);
20
21
  }
@@ -32,6 +33,7 @@ module.exports = createNonTransactionalMigration(
32
33
  });
33
34
 
34
35
  if (knex.client.config.client === 'sqlite3') {
36
+ // eslint-disable-next-line no-restricted-syntax
35
37
  for (const column of ['name', 'code', 'stripe_coupon_id']) {
36
38
  await addUnique('offers', column, knex);
37
39
  }
@@ -47,6 +47,7 @@ module.exports = createTransactionalMigration(
47
47
  return offers.concat(updatedRow);
48
48
  }, []);
49
49
 
50
+ // eslint-disable-next-line no-restricted-syntax
50
51
  for (const truncatedOffer of truncatedOffers) {
51
52
  await knex('offers')
52
53
  .update('name', truncatedOffer.name)
@@ -38,6 +38,7 @@ module.exports = createTransactionalMigration(
38
38
  const chunkSize = 333;
39
39
  const memberProductRelationsChunks = chunk(memberProductRelations, chunkSize);
40
40
 
41
+ // eslint-disable-next-line no-restricted-syntax
41
42
  for (const relations of memberProductRelationsChunks) {
42
43
  await knex.insert(relations).into('members_products');
43
44
  }
@@ -63,6 +63,7 @@ module.exports = createTransactionalMigration(
63
63
 
64
64
  let hasRestored = false;
65
65
 
66
+ // eslint-disable-next-line no-restricted-syntax
66
67
  for (const backupFile of backupFiles) {
67
68
  try {
68
69
  const backup = require(path.join(dataPath, backupFile));
@@ -9,6 +9,7 @@ module.exports = createTransactionalMigration(
9
9
  .where('status', 'comped');
10
10
  },
11
11
  async function down(knex) {
12
+ // eslint-disable-next-line no-restricted-syntax
12
13
  const compedMemberIds = (await knex('members')
13
14
  .select('members.id')
14
15
  .innerJoin(
@@ -27,6 +27,7 @@ module.exports = createTransactionalMigration(
27
27
  const newSettingKeys = ['newsletter_show_header_title', 'newsletter_show_header_icon'];
28
28
  const now = connection.raw('CURRENT_TIMESTAMP');
29
29
 
30
+ // eslint-disable-next-line no-restricted-syntax
30
31
  for (const settingKey of newSettingKeys) {
31
32
  const existingSetting = await connection('settings').where('key', settingKey).first();
32
33
 
@@ -33,6 +33,7 @@ module.exports = createTransactionalMigration(
33
33
  .forUpdate()
34
34
  .select('id');
35
35
 
36
+ // eslint-disable-next-line no-restricted-syntax
36
37
  for (const postIdRow of postIdRows) {
37
38
  const {id} = postIdRow;
38
39
  const [post] = await knex('posts')
@@ -3,6 +3,7 @@ const {createTransactionalMigration} = require('../../utils.js');
3
3
 
4
4
  module.exports = createTransactionalMigration(
5
5
  async function up(knex) {
6
+ // eslint-disable-next-line no-restricted-syntax
6
7
  const compedMemberIds = (await knex('members')
7
8
  .select('members.id')
8
9
  .innerJoin(
@@ -15,6 +15,7 @@ module.exports = createTransactionalMigration(
15
15
  logging.info(`Found ${compedMembers.length} comped members - checking members_status_events`);
16
16
  }
17
17
 
18
+ // eslint-disable-next-line no-restricted-syntax
18
19
  for (const member of compedMembers) {
19
20
  const mostRecentStatusEvent = await knex('members_status_events')
20
21
  .select('*')
@@ -139,7 +139,7 @@ async function hasForeignSQLite({fromTable, fromColumn, toTable, toColumn, trans
139
139
  const client = knex.client.config.client;
140
140
 
141
141
  if (client !== 'sqlite3') {
142
- throw new errors.GhostError({
142
+ throw new errors.InternalServerError({
143
143
  message: tpl(messages.hasForeignSQLite3)
144
144
  });
145
145
  }
@@ -265,7 +265,7 @@ async function hasPrimaryKeySQLite(tableName, transaction) {
265
265
  const client = knex.client.config.client;
266
266
 
267
267
  if (client !== 'sqlite3') {
268
- throw new errors.GhostError({
268
+ throw new errors.InternalServerError({
269
269
  message: tpl(messages.hasPrimaryKeySQLiteError)
270
270
  });
271
271
  }
@@ -107,13 +107,13 @@ class GhostServer {
107
107
  let ghostError;
108
108
 
109
109
  if (error.code === 'EADDRINUSE') {
110
- ghostError = new errors.GhostError({
110
+ ghostError = new errors.InternalServerError({
111
111
  message: tpl(messages.addressInUse.error),
112
112
  context: tpl(messages.addressInUse.context, {port: config.get('server').port}),
113
113
  help: tpl(messages.addressInUse.help)
114
114
  });
115
115
  } else {
116
- ghostError = new errors.GhostError({
116
+ ghostError = new errors.InternalServerError({
117
117
  message: tpl(messages.otherError.error, {errorNumber: error.errno}),
118
118
  context: tpl(messages.otherError.context),
119
119
  help: tpl(messages.otherError.help)
@@ -177,7 +177,7 @@ class ImageSize {
177
177
  context: err.url || imagePath
178
178
  }));
179
179
  }).catch(function (err) {
180
- if (errors.utils.isIgnitionError(err)) {
180
+ if (errors.utils.isGhostError(err)) {
181
181
  return Promise.reject(err);
182
182
  }
183
183
 
@@ -241,7 +241,7 @@ class ImageSize {
241
241
  }
242
242
  }));
243
243
  }).catch((err) => {
244
- if (errors.utils.isIgnitionError(err)) {
244
+ if (errors.utils.isGhostError(err)) {
245
245
  return Promise.reject(err);
246
246
  }
247
247
 
@@ -69,13 +69,13 @@ events.on('settings.timezone.edited', function (settingModel, options) {
69
69
  try {
70
70
  await models.Post.edit(post.toJSON(), _.merge({id: post.id}, options));
71
71
  } catch (err) {
72
- logging.error(new errors.GhostError({
72
+ logging.error(new errors.InternalServerError({
73
73
  err
74
74
  }));
75
75
  }
76
76
  });
77
77
  } catch (err) {
78
- logging.error(new errors.GhostError({
78
+ logging.error(new errors.InternalServerError({
79
79
  err: err,
80
80
  level: 'critical'
81
81
  }));
@@ -9,11 +9,11 @@ const MemberEmailChangeEvent = ghostBookshelf.Model.extend({
9
9
  }
10
10
  }, {
11
11
  async edit() {
12
- throw new errors.IncorrectUsageError('Cannot edit MemberEmailChangeEvent');
12
+ throw new errors.IncorrectUsageError({message: 'Cannot edit MemberEmailChangeEvent'});
13
13
  },
14
14
 
15
15
  async destroy() {
16
- throw new errors.IncorrectUsageError('Cannot destroy MemberEmailChangeEvent');
16
+ throw new errors.IncorrectUsageError({message: 'Cannot destroy MemberEmailChangeEvent'});
17
17
  }
18
18
  });
19
19
 
@@ -9,11 +9,11 @@ const MemberLoginEvent = ghostBookshelf.Model.extend({
9
9
  }
10
10
  }, {
11
11
  async edit() {
12
- throw new errors.IncorrectUsageError('Cannot edit MemberLoginEvent');
12
+ throw new errors.IncorrectUsageError({message: 'Cannot edit MemberLoginEvent'});
13
13
  },
14
14
 
15
15
  async destroy() {
16
- throw new errors.IncorrectUsageError('Cannot destroy MemberLoginEvent');
16
+ throw new errors.IncorrectUsageError({message: 'Cannot destroy MemberLoginEvent'});
17
17
  }
18
18
  });
19
19