ghost 5.52.2 → 5.53.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 (158) hide show
  1. package/components/tryghost-adapter-cache-memory-ttl-5.53.0.tgz +0 -0
  2. package/components/{tryghost-adapter-cache-redis-5.52.2.tgz → tryghost-adapter-cache-redis-5.53.0.tgz} +0 -0
  3. package/components/{tryghost-adapter-manager-5.52.2.tgz → tryghost-adapter-manager-5.53.0.tgz} +0 -0
  4. package/components/{tryghost-announcement-bar-settings-5.52.2.tgz → tryghost-announcement-bar-settings-5.53.0.tgz} +0 -0
  5. package/components/{tryghost-api-framework-5.52.2.tgz → tryghost-api-framework-5.53.0.tgz} +0 -0
  6. package/components/tryghost-api-version-compatibility-service-5.53.0.tgz +0 -0
  7. package/components/{tryghost-audience-feedback-5.52.2.tgz → tryghost-audience-feedback-5.53.0.tgz} +0 -0
  8. package/components/{tryghost-bootstrap-socket-5.52.2.tgz → tryghost-bootstrap-socket-5.53.0.tgz} +0 -0
  9. package/components/{tryghost-collections-5.52.2.tgz → tryghost-collections-5.53.0.tgz} +0 -0
  10. package/components/tryghost-constants-5.53.0.tgz +0 -0
  11. package/components/{tryghost-custom-theme-settings-service-5.52.2.tgz → tryghost-custom-theme-settings-service-5.53.0.tgz} +0 -0
  12. package/components/{tryghost-data-generator-5.52.2.tgz → tryghost-data-generator-5.53.0.tgz} +0 -0
  13. package/components/{tryghost-domain-events-5.52.2.tgz → tryghost-domain-events-5.53.0.tgz} +0 -0
  14. package/components/tryghost-dynamic-routing-events-5.53.0.tgz +0 -0
  15. package/components/{tryghost-email-analytics-provider-mailgun-5.52.2.tgz → tryghost-email-analytics-provider-mailgun-5.53.0.tgz} +0 -0
  16. package/components/{tryghost-email-analytics-service-5.52.2.tgz → tryghost-email-analytics-service-5.53.0.tgz} +0 -0
  17. package/components/tryghost-email-content-generator-5.53.0.tgz +0 -0
  18. package/components/tryghost-email-events-5.53.0.tgz +0 -0
  19. package/components/{tryghost-email-service-5.52.2.tgz → tryghost-email-service-5.53.0.tgz} +0 -0
  20. package/components/tryghost-email-suppression-list-5.53.0.tgz +0 -0
  21. package/components/tryghost-event-aware-cache-wrapper-5.53.0.tgz +0 -0
  22. package/components/tryghost-express-dynamic-redirects-5.53.0.tgz +0 -0
  23. package/components/{tryghost-external-media-inliner-5.52.2.tgz → tryghost-external-media-inliner-5.53.0.tgz} +0 -0
  24. package/components/tryghost-extract-api-key-5.53.0.tgz +0 -0
  25. package/components/tryghost-html-to-plaintext-5.53.0.tgz +0 -0
  26. package/components/tryghost-i18n-5.53.0.tgz +0 -0
  27. package/components/tryghost-importer-handler-content-files-5.53.0.tgz +0 -0
  28. package/components/tryghost-importer-revue-5.53.0.tgz +0 -0
  29. package/components/{tryghost-in-memory-repository-5.52.2.tgz → tryghost-in-memory-repository-5.53.0.tgz} +0 -0
  30. package/components/{tryghost-job-manager-5.52.2.tgz → tryghost-job-manager-5.53.0.tgz} +0 -0
  31. package/components/tryghost-link-redirects-5.53.0.tgz +0 -0
  32. package/components/{tryghost-link-replacer-5.52.2.tgz → tryghost-link-replacer-5.53.0.tgz} +0 -0
  33. package/components/tryghost-link-tracking-5.53.0.tgz +0 -0
  34. package/components/tryghost-magic-link-5.53.0.tgz +0 -0
  35. package/components/tryghost-mail-events-5.53.0.tgz +0 -0
  36. package/components/{tryghost-mailgun-client-5.52.2.tgz → tryghost-mailgun-client-5.53.0.tgz} +0 -0
  37. package/components/tryghost-member-attribution-5.53.0.tgz +0 -0
  38. package/components/tryghost-member-events-5.53.0.tgz +0 -0
  39. package/components/{tryghost-members-api-5.52.2.tgz → tryghost-members-api-5.53.0.tgz} +0 -0
  40. package/components/tryghost-members-csv-5.53.0.tgz +0 -0
  41. package/components/{tryghost-members-events-service-5.52.2.tgz → tryghost-members-events-service-5.53.0.tgz} +0 -0
  42. package/components/tryghost-members-importer-5.53.0.tgz +0 -0
  43. package/components/tryghost-members-offers-5.53.0.tgz +0 -0
  44. package/components/tryghost-members-payments-5.53.0.tgz +0 -0
  45. package/components/{tryghost-members-ssr-5.52.2.tgz → tryghost-members-ssr-5.53.0.tgz} +0 -0
  46. package/components/{tryghost-members-stripe-service-5.52.2.tgz → tryghost-members-stripe-service-5.53.0.tgz} +0 -0
  47. package/components/{tryghost-mentions-email-report-5.52.2.tgz → tryghost-mentions-email-report-5.53.0.tgz} +0 -0
  48. package/components/{tryghost-milestones-5.52.2.tgz → tryghost-milestones-5.53.0.tgz} +0 -0
  49. package/components/{tryghost-minifier-5.52.2.tgz → tryghost-minifier-5.53.0.tgz} +0 -0
  50. package/components/{tryghost-mw-api-version-mismatch-5.52.2.tgz → tryghost-mw-api-version-mismatch-5.53.0.tgz} +0 -0
  51. package/components/tryghost-mw-cache-control-5.53.0.tgz +0 -0
  52. package/components/tryghost-mw-error-handler-5.53.0.tgz +0 -0
  53. package/components/tryghost-mw-session-from-token-5.53.0.tgz +0 -0
  54. package/components/tryghost-mw-update-user-last-seen-5.53.0.tgz +0 -0
  55. package/components/tryghost-mw-version-match-5.53.0.tgz +0 -0
  56. package/components/tryghost-mw-vhost-5.53.0.tgz +0 -0
  57. package/components/tryghost-oembed-service-5.53.0.tgz +0 -0
  58. package/components/{tryghost-package-json-5.52.2.tgz → tryghost-package-json-5.53.0.tgz} +0 -0
  59. package/components/tryghost-post-revisions-5.53.0.tgz +0 -0
  60. package/components/tryghost-posts-service-5.53.0.tgz +0 -0
  61. package/components/tryghost-referrers-5.53.0.tgz +0 -0
  62. package/components/{tryghost-security-5.52.2.tgz → tryghost-security-5.53.0.tgz} +0 -0
  63. package/components/tryghost-session-service-5.53.0.tgz +0 -0
  64. package/components/tryghost-settings-path-manager-5.53.0.tgz +0 -0
  65. package/components/tryghost-slack-notifications-5.53.0.tgz +0 -0
  66. package/components/{tryghost-staff-service-5.52.2.tgz → tryghost-staff-service-5.53.0.tgz} +0 -0
  67. package/components/tryghost-stats-service-5.53.0.tgz +0 -0
  68. package/components/{tryghost-tiers-5.52.2.tgz → tryghost-tiers-5.53.0.tgz} +0 -0
  69. package/components/tryghost-update-check-service-5.53.0.tgz +0 -0
  70. package/components/tryghost-verification-trigger-5.53.0.tgz +0 -0
  71. package/components/tryghost-version-notifications-data-service-5.53.0.tgz +0 -0
  72. package/components/{tryghost-webmentions-5.52.2.tgz → tryghost-webmentions-5.53.0.tgz} +0 -0
  73. package/content/themes/casper/assets/built/screen.css +1 -1
  74. package/content/themes/casper/assets/built/screen.css.map +1 -1
  75. package/content/themes/casper/assets/css/screen.css +20 -22
  76. package/content/themes/casper/package.json +1 -1
  77. package/core/boot.js +11 -1
  78. package/core/built/admin/assets/{chunk.143.954795f438685a17c91b.js → chunk.143.bde70b283feb96f5da5f.js} +5 -5
  79. package/core/built/admin/assets/{chunk.178.3396586d36aa01be2ba2.js → chunk.178.64cbd26e5a0f197ae940.js} +4 -4
  80. package/core/built/admin/assets/{chunk.658.4548e702d296a29726d6.js → chunk.658.015cf0d0dfedc206ac34.js} +9 -8
  81. package/core/built/admin/assets/{ghost-b73f018429dcbc18d6d47037187d6a81.js → ghost-9138adfcfe7ef4611bca06d60f1df85e.js} +39 -37
  82. package/core/built/admin/assets/{ghost-dark-179670faac46fe5fe58d9da626e1c0a8.css → ghost-dark-89bdd1ed3ac362374bdc9d2fb574ad96.css} +1 -1
  83. package/core/built/admin/assets/{vendor-2e4b0ccaa065f6709f955c29ec9e18a3.js → vendor-c85ef50819caa584c404a0e3dcaa4e69.js} +1 -1
  84. package/core/built/admin/index.html +5 -5
  85. package/core/frontend/helpers/comments.js +1 -3
  86. package/core/frontend/helpers/ghost_head.js +5 -0
  87. package/core/frontend/services/apps/index.js +2 -3
  88. package/core/frontend/src/cards/css/signup.css +73 -44
  89. package/core/frontend/utils/frontend-apps.js +2 -2
  90. package/core/frontend/web/middleware/handle-image-sizes.js +3 -0
  91. package/core/server/adapters/scheduling/post-scheduling/index.js +3 -3
  92. package/core/server/api/endpoints/index.js +4 -0
  93. package/core/server/api/endpoints/mail-events.js +14 -0
  94. package/core/server/api/endpoints/pages.js +1 -0
  95. package/core/server/api/endpoints/utils/serializers/output/index.js +4 -0
  96. package/core/server/api/endpoints/utils/serializers/output/mail-events.js +9 -0
  97. package/core/server/api/endpoints/utils/validators/input/index.js +4 -0
  98. package/core/server/api/endpoints/utils/validators/input/mail-events.js +7 -0
  99. package/core/server/data/exporter/exporter.js +3 -3
  100. package/core/server/data/exporter/table-lists.js +3 -1
  101. package/core/server/data/migrations/init/1-create-tables.js +5 -5
  102. package/core/server/data/migrations/versions/5.53/2023-06-13-12-24-add-temp-mail-events-table.js +9 -0
  103. package/core/server/data/migrations/versions/5.53/2023-06-20-10-18-add-collections-posts-table.js +10 -0
  104. package/core/server/data/migrations/versions/5.53/2023-06-20-10-18-add-collections-table.js +15 -0
  105. package/core/server/data/schema/schema.js +24 -0
  106. package/core/server/models/mail-event.js +12 -0
  107. package/core/server/models/settings.js +3 -3
  108. package/core/server/models/user.js +7 -7
  109. package/core/server/services/api-version-compatibility/legacy-api-path-match.js +1 -1
  110. package/core/server/services/mail-events/BookshelfMailEventRepository.js +40 -0
  111. package/core/server/services/mail-events/index.js +21 -0
  112. package/core/server/web/api/endpoints/admin/routes.js +1 -0
  113. package/core/server/web/shared/middleware/api/spam-prevention.js +1 -1
  114. package/core/shared/config/defaults.json +1 -1
  115. package/core/shared/labs.js +2 -2
  116. package/package.json +144 -142
  117. package/yarn.lock +1163 -942
  118. package/components/tryghost-adapter-cache-memory-ttl-5.52.2.tgz +0 -0
  119. package/components/tryghost-api-version-compatibility-service-5.52.2.tgz +0 -0
  120. package/components/tryghost-constants-5.52.2.tgz +0 -0
  121. package/components/tryghost-dynamic-routing-events-5.52.2.tgz +0 -0
  122. package/components/tryghost-email-content-generator-5.52.2.tgz +0 -0
  123. package/components/tryghost-email-events-5.52.2.tgz +0 -0
  124. package/components/tryghost-email-suppression-list-5.52.2.tgz +0 -0
  125. package/components/tryghost-event-aware-cache-wrapper-5.52.2.tgz +0 -0
  126. package/components/tryghost-express-dynamic-redirects-5.52.2.tgz +0 -0
  127. package/components/tryghost-extract-api-key-5.52.2.tgz +0 -0
  128. package/components/tryghost-html-to-plaintext-5.52.2.tgz +0 -0
  129. package/components/tryghost-i18n-5.52.2.tgz +0 -0
  130. package/components/tryghost-importer-handler-content-files-5.52.2.tgz +0 -0
  131. package/components/tryghost-importer-revue-5.52.2.tgz +0 -0
  132. package/components/tryghost-link-redirects-5.52.2.tgz +0 -0
  133. package/components/tryghost-link-tracking-5.52.2.tgz +0 -0
  134. package/components/tryghost-magic-link-5.52.2.tgz +0 -0
  135. package/components/tryghost-member-attribution-5.52.2.tgz +0 -0
  136. package/components/tryghost-member-events-5.52.2.tgz +0 -0
  137. package/components/tryghost-members-csv-5.52.2.tgz +0 -0
  138. package/components/tryghost-members-importer-5.52.2.tgz +0 -0
  139. package/components/tryghost-members-offers-5.52.2.tgz +0 -0
  140. package/components/tryghost-members-payments-5.52.2.tgz +0 -0
  141. package/components/tryghost-mw-cache-control-5.52.2.tgz +0 -0
  142. package/components/tryghost-mw-error-handler-5.52.2.tgz +0 -0
  143. package/components/tryghost-mw-session-from-token-5.52.2.tgz +0 -0
  144. package/components/tryghost-mw-update-user-last-seen-5.52.2.tgz +0 -0
  145. package/components/tryghost-mw-version-match-5.52.2.tgz +0 -0
  146. package/components/tryghost-mw-vhost-5.52.2.tgz +0 -0
  147. package/components/tryghost-oembed-service-5.52.2.tgz +0 -0
  148. package/components/tryghost-post-revisions-5.52.2.tgz +0 -0
  149. package/components/tryghost-posts-service-5.52.2.tgz +0 -0
  150. package/components/tryghost-referrers-5.52.2.tgz +0 -0
  151. package/components/tryghost-session-service-5.52.2.tgz +0 -0
  152. package/components/tryghost-settings-path-manager-5.52.2.tgz +0 -0
  153. package/components/tryghost-slack-notifications-5.52.2.tgz +0 -0
  154. package/components/tryghost-stats-service-5.52.2.tgz +0 -0
  155. package/components/tryghost-update-check-service-5.52.2.tgz +0 -0
  156. package/components/tryghost-verification-trigger-5.52.2.tgz +0 -0
  157. package/components/tryghost-version-notifications-data-service-5.52.2.tgz +0 -0
  158. /package/core/built/admin/assets/{chunk.658.4548e702d296a29726d6.js.LICENSE.txt → chunk.658.015cf0d0dfedc206ac34.js.LICENSE.txt} +0 -0
@@ -14093,4 +14093,4 @@ return void 0===n&&(n=(0,t.createStorage)(null,(()=>!1)),r.set(e,n)),n}dirtyStor
14093
14093
  r&&(0,t.setValue)(r,null)}constructor(e){o(this,"storages",new WeakMap),o(this,"vals",void 0),this.vals=new WeakSet(e)}has(e){return(0,t.getValue)(this.storageFor(e)),this.vals.has(e)}add(e){return this.vals.add(e),this.dirtyStorageFor(e),this}delete(e){return this.dirtyStorageFor(e),this.vals.delete(e)}get[i](){return this.vals[Symbol.toStringTag]}}e.TrackedWeakSet=s,Object.setPrototypeOf(s.prototype,WeakSet.prototype)})),define("tracked-built-ins/index",["exports","tracked-built-ins/-private/decorator","tracked-built-ins/-private/array","tracked-built-ins/-private/object","tracked-built-ins/-private/map","tracked-built-ins/-private/set"],(function(e,t,r,n,i,o){"use strict"
14094
14094
  Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"TrackedArray",{enumerable:!0,get:function(){return r.default}}),Object.defineProperty(e,"TrackedMap",{enumerable:!0,get:function(){return i.TrackedMap}}),Object.defineProperty(e,"TrackedObject",{enumerable:!0,get:function(){return n.default}}),Object.defineProperty(e,"TrackedSet",{enumerable:!0,get:function(){return o.TrackedSet}}),Object.defineProperty(e,"TrackedWeakMap",{enumerable:!0,get:function(){return i.TrackedWeakMap}}),Object.defineProperty(e,"TrackedWeakSet",{enumerable:!0,get:function(){return o.TrackedWeakSet}}),Object.defineProperty(e,"tracked",{enumerable:!0,get:function(){return t.default}})}))
14095
14095
 
14096
- //# sourceMappingURL=vendor-2e4b0ccaa065f6709f955c29ec9e18a3.map
14096
+ //# sourceMappingURL=vendor-c85ef50819caa584c404a0e3dcaa4e69.map
@@ -8,7 +8,7 @@
8
8
  <title>Ghost Admin</title>
9
9
 
10
10
 
11
- <meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.52%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22ember-websockets%22%3A%7B%22socketIO%22%3Atrue%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%7D" />
11
+ <meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.53%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22ember-websockets%22%3A%7B%22socketIO%22%3Atrue%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%7D" />
12
12
 
13
13
  <meta name="HandheldFriendly" content="True" />
14
14
  <meta name="MobileOptimized" content="320" />
@@ -56,9 +56,9 @@
56
56
 
57
57
  <div id="ember-basic-dropdown-wormhole"></div>
58
58
 
59
- <script src="assets/vendor-2e4b0ccaa065f6709f955c29ec9e18a3.js"></script>
60
- <script src="assets/chunk.658.4548e702d296a29726d6.js"></script>
61
- <script src="assets/chunk.143.954795f438685a17c91b.js"></script>
62
- <script src="assets/ghost-b73f018429dcbc18d6d47037187d6a81.js"></script>
59
+ <script src="assets/vendor-c85ef50819caa584c404a0e3dcaa4e69.js"></script>
60
+ <script src="assets/chunk.658.015cf0d0dfedc206ac34.js"></script>
61
+ <script src="assets/chunk.143.bde70b283feb96f5da5f.js"></script>
62
+ <script src="assets/ghost-9138adfcfe7ef4611bca06d60f1df85e.js"></script>
63
63
  </body>
64
64
  </html>
@@ -50,7 +50,7 @@ module.exports = async function comments(options) {
50
50
  }
51
51
 
52
52
  const frontendKey = await getFrontendKey();
53
- const {scriptUrl, stylesUrl, appVersion} = getFrontendAppConfig('comments');
53
+ const {scriptUrl, stylesUrl} = getFrontendAppConfig('comments');
54
54
 
55
55
  const data = {
56
56
  'ghost-comments': urlUtils.getSiteUrl(),
@@ -61,11 +61,9 @@ module.exports = async function comments(options) {
61
61
  title: title,
62
62
  count: count,
63
63
  'post-id': this.id,
64
- 'sentry-dsn': '', /* todo: insert sentry dsn key here */
65
64
  'color-scheme': colorScheme,
66
65
  'avatar-saturation': avatarSaturation,
67
66
  'accent-color': accentColor,
68
- 'app-version': appVersion,
69
67
  'comments-enabled': commentsEnabled,
70
68
  publication: settingsCache.get('title')
71
69
  };
@@ -76,6 +76,11 @@ function getMembersHelper(data, frontendKey) {
76
76
  function getSearchHelper(frontendKey) {
77
77
  const adminUrl = urlUtils.getAdminUrl() || urlUtils.getSiteUrl();
78
78
  const {scriptUrl, stylesUrl} = getFrontendAppConfig('sodoSearch');
79
+
80
+ if (!scriptUrl) {
81
+ return '';
82
+ }
83
+
79
84
  const attrs = {
80
85
  key: frontendKey,
81
86
  styles: stylesUrl,
@@ -1,5 +1,4 @@
1
1
  const debug = require('@tryghost/debug')('services:apps');
2
- const Promise = require('bluebird');
3
2
  const tpl = require('@tryghost/tpl');
4
3
  const logging = require('@tryghost/logging');
5
4
  const errors = require('@tryghost/errors');
@@ -15,8 +14,8 @@ module.exports = {
15
14
  init: function () {
16
15
  debug('init begin');
17
16
  const appsToLoad = config.get('apps:internal');
18
-
19
- return Promise.map(appsToLoad, appName => loader.activateAppByName(appName))
17
+ const appPromises = appsToLoad.map(appName => loader.activateAppByName(appName));
18
+ return Promise.all(appPromises)
20
19
  .catch(function (err) {
21
20
  logging.error(new errors.InternalServerError({
22
21
  err: err,
@@ -1,3 +1,7 @@
1
+ .kg-signup-card {
2
+ position: relative;
3
+ }
4
+
1
5
  .kg-signup-card,
2
6
  .kg-signup-card * {
3
7
  box-sizing: border-box;
@@ -8,12 +12,16 @@
8
12
  color: currentColor;
9
13
  }
10
14
 
11
- .kg-signup-card.kg-layout-split {
15
+ .kg-signup-card.kg-style-accent {
16
+ background-color: var(--ghost-accent-color);
17
+ }
18
+
19
+ .kg-layout-split .kg-signup-card-content {
12
20
  display: grid;
13
21
  grid-template-columns: 1fr 1fr;
14
22
  }
15
23
 
16
- .kg-signup-card-container {
24
+ .kg-signup-card-text {
17
25
  position: relative;
18
26
  display: flex;
19
27
  flex-direction: column;
@@ -26,41 +34,58 @@
26
34
  text-align: left;
27
35
  }
28
36
 
29
- .kg-width-wide .kg-signup-card-container {
37
+ .kg-width-wide .kg-signup-card-text {
30
38
  padding: 6.4vmax;
31
39
  }
32
40
 
33
- .kg-width-full .kg-signup-card-container {
34
- padding: 9.6vmax 7.2vmax;
41
+ .kg-width-full .kg-signup-card-text {
42
+ padding: 9.6vmax 0;
35
43
  }
36
44
 
37
- .kg-layout-split .kg-signup-card-container {
45
+ .kg-layout-split .kg-signup-card-text {
38
46
  padding: 9.6vmax 4vmax;
39
47
  }
40
48
 
41
- .kg-signup-card-container.align-center {
42
- align-items: center;
43
- text-align: center;
49
+ .kg-layout-split.kg-content-wide .kg-signup-card-text {
50
+ padding: 9.6vmax 0 9.6vmax 4vmax;
44
51
  }
45
52
 
46
- .kg-signup-card-container.kg-style-accent {
47
- background-color: var(--ghost-accent-color);
53
+ .kg-layout-split.kg-content-wide.kg-swapped .kg-signup-card-text {
54
+ padding: 9.6vmax 4vmax 9.6vmax 0;
48
55
  }
49
56
 
50
- .kg-signup-card.kg-swapped .kg-signup-card-container {
57
+ .kg-swapped .kg-signup-card-text {
51
58
  grid-row: 1;
52
59
  }
53
60
 
61
+ .kg-signup-card-text.kg-align-center {
62
+ align-items: center;
63
+ text-align: center;
64
+ }
65
+
54
66
  .kg-signup-card.kg-style-image h2.kg-signup-card-heading,
55
67
  .kg-signup-card.kg-style-image h3.kg-signup-card-subheading,
56
68
  .kg-signup-card.kg-style-image .kg-signup-card-button {
57
69
  z-index: 999;
58
70
  }
59
71
 
72
+ /* Background image */
73
+
74
+ .kg-signup-card > picture > .kg-signup-card-image {
75
+ position: absolute;
76
+ top: 0;
77
+ left: 0;
78
+ width: 100%;
79
+ height: 100%;
80
+ object-fit: cover;
81
+ object-position: center;
82
+ background-color: #FFFFFF;
83
+ pointer-events: none;
84
+ }
60
85
 
61
86
  /* Split layout image */
62
87
 
63
- .kg-signup-card-image {
88
+ .kg-signup-card-content .kg-signup-card-image {
64
89
  /* this will force the image to follow the signup card height */
65
90
  height: 0;
66
91
  min-height: 100%;
@@ -69,38 +94,36 @@
69
94
  object-position: center;
70
95
  }
71
96
 
72
- .kg-background-size-contain .kg-signup-card-image {
97
+ .kg-content-wide .kg-signup-card-content .kg-signup-card-image {
98
+ height: 100%;
99
+ padding: 8rem 0;
73
100
  object-fit: contain;
74
101
  }
75
102
 
76
- .kg-signup-card-image.kg-style-accent {
77
- background-color: var(--ghost-accent-color);
78
- }
79
-
80
103
  /* Heading */
81
104
 
82
105
  .kg-signup-card h2.kg-signup-card-heading {
83
106
  margin: 0;
84
- font-size: 4.8vmin;
107
+ font-size: clamp(2.8rem, 4vw, 4rem);
85
108
  font-weight: 700;
86
109
  line-height: 1em;
87
110
  letter-spacing: -0.01em;
88
111
  }
89
112
 
90
- .kg-signup-card h2.kg-signup-card-heading strong {
91
- font-weight: 800;
92
- }
93
-
94
113
  .kg-signup-card.kg-width-wide h2.kg-signup-card-heading {
95
- font-size: 5.6vmin;
114
+ font-size: clamp(2.8rem, 5vw, 5.2rem);
96
115
  }
97
116
 
98
117
  .kg-signup-card.kg-width-full h2.kg-signup-card-heading {
99
- font-size: 7.4vmin;
118
+ font-size: clamp(3.6rem, 5.6vw, 6.4rem);
100
119
  }
101
120
 
102
121
  .kg-signup-card.kg-width-full.kg-layout-split h2.kg-signup-card-heading {
103
- font-size: 6.4vmin;
122
+ font-size: clamp(3.2rem, 4vw, 5.6rem);
123
+ }
124
+
125
+ .kg-signup-card.kg-width-full.kg-layout-split.kg-content-wide h2.kg-signup-card-heading {
126
+ font-size: clamp(2.8rem, 4vw, 5.2rem);
104
127
  }
105
128
 
106
129
  /* Subheading */
@@ -112,13 +135,13 @@
112
135
  .kg-signup-card h3.kg-signup-card-subheading {
113
136
  max-width: 40em;
114
137
  margin: 0;
115
- font-size: 1.25em;
138
+ font-size: clamp(1.05em, 2vw, 2rem);
116
139
  font-weight: 500;
117
140
  line-height: 1.4em;
118
141
  }
119
142
 
120
143
  .kg-signup-card h2 + h3.kg-signup-card-subheading {
121
- margin: 0.35em 0 0;
144
+ margin: 0.6em 0 0;
122
145
  }
123
146
 
124
147
  .kg-signup-card h3.kg-signup-card-subheading strong {
@@ -126,16 +149,16 @@
126
149
  }
127
150
 
128
151
  .kg-signup-card.kg-width-wide h3.kg-signup-card-subheading {
129
- font-size: 1.5em;
152
+ font-size: clamp(1.05em, 2vw, 2.4rem);
130
153
  }
131
154
 
132
155
  .kg-signup-card.kg-width-full h3.kg-signup-card-subheading:not(.kg-layout-split h3.kg-signup-card-subheading) {
133
156
  max-width: 65vmax;
134
- font-size: 1.75em;
157
+ font-size: clamp(1.05em, 2vw, 2.6rem);
135
158
  }
136
159
 
137
160
  .kg-signup-card.kg-width-full.kg-layout-split h3.kg-signup-card-subheading {
138
- font-size: 1.5em;
161
+ font-size: clamp(1.05em, 2vw, 2.4rem);
139
162
  }
140
163
 
141
164
  /* Subscribe form */
@@ -147,7 +170,7 @@
147
170
  width: 100%;
148
171
  }
149
172
 
150
- .align-center .kg-signup-card-form {
173
+ .kg-align-center .kg-signup-card-form {
151
174
  justify-content: center;
152
175
  }
153
176
 
@@ -309,24 +332,37 @@
309
332
  /* Responsive styles */
310
333
 
311
334
  @media (max-width: 640px) {
312
- .kg-signup-card.kg-layout-split {
335
+ .kg-layout-split .kg-signup-card-content {
313
336
  grid-template-columns: 1fr;
314
337
  }
315
338
 
316
- .kg-width-wide .kg-signup-card-container {
339
+ .kg-width-wide .kg-signup-card-text {
317
340
  padding: 6.4vmax 4vmax;
318
341
  }
319
342
 
320
- .kg-width-full .kg-signup-card-container {
321
- padding: 9.6vmax 4vmax;
343
+ .kg-layout-split.kg-content-wide .kg-signup-card-text,
344
+ .kg-layout-split.kg-content-wide.kg-swapped .kg-signup-card-text {
345
+ padding: 9.6vmax 0;
346
+ }
347
+
348
+ .kg-signup-card.kg-width-full h3.kg-signup-card-subheading:not(.kg-layout-split h3.kg-signup-card-subheading) {
349
+ max-width: unset;
322
350
  }
323
351
 
324
- .kg-signup-card-image {
352
+ .kg-signup-card-content .kg-signup-card-image:not(.kg-content-wide .kg-signup-card-content .kg-signup-card-image) {
325
353
  height: auto;
326
354
  min-height: unset;
327
355
  aspect-ratio: 1 / 1;
328
356
  }
329
357
 
358
+ .kg-content-wide .kg-signup-card-content .kg-signup-card-image {
359
+ padding: 2.4rem 0 0;
360
+ }
361
+
362
+ .kg-content-wide.kg-swapped .kg-signup-card-content .kg-signup-card-image {
363
+ padding: 0 0 2.4rem;
364
+ }
365
+
330
366
  .kg-signup-card-input {
331
367
  height: 4.2rem;
332
368
  padding: 6px 12px;
@@ -341,11 +377,4 @@
341
377
  .kg-signup-card.kg-width-full .kg-signup-card-button {
342
378
  font-size: 1em;
343
379
  }
344
-
345
- .kg-signup-card h3.kg-signup-card-subheading,
346
- .kg-signup-card.kg-width-wide h3.kg-signup-card-subheading,
347
- .kg-signup-card.kg-width-full.kg-layout-split h3.kg-signup-card-subheading,
348
- .kg-signup-card.kg-width-full h3.kg-signup-card-subheading:not(.kg-layout-split h3.kg-signup-card-subheading) {
349
- font-size: 1em;
350
- }
351
380
  }
@@ -4,10 +4,10 @@ function getFrontendAppConfig(app) {
4
4
  const appVersion = config.get(`${app}:version`);
5
5
  let scriptUrl = config.get(`${app}:url`);
6
6
  let stylesUrl = config.get(`${app}:styles`);
7
- if (scriptUrl.includes('{version}')) {
7
+ if (typeof scriptUrl === 'string' && scriptUrl.includes('{version}')) {
8
8
  scriptUrl = scriptUrl.replace('{version}', appVersion);
9
9
  }
10
- if (stylesUrl?.includes('{version}')) {
10
+ if (typeof stylesUrl === 'string' && stylesUrl?.includes('{version}')) {
11
11
  stylesUrl = stylesUrl.replace('{version}', appVersion);
12
12
  }
13
13
  return {
@@ -13,6 +13,9 @@ const FORMAT_PATH_REGEX = /^\/format\/([^./]+)\//;
13
13
  const TRAILING_SLASH_REGEX = /\/+$/;
14
14
 
15
15
  module.exports = function (req, res, next) {
16
+ // In admin we need to read images and calculate the average color (blocked by CORS otherwise)
17
+ res.setHeader('Access-Control-Allow-Origin', '*');
18
+
16
19
  if (!SIZE_PATH_REGEX.test(req.url)) {
17
20
  return next();
18
21
  }
@@ -1,8 +1,8 @@
1
- const Promise = require('bluebird');
2
1
  const events = require('../../../lib/common/events');
3
2
  const localUtils = require('../utils');
4
3
  const PostScheduler = require('./PostScheduler');
5
4
  const getSchedulerIntegration = require('./scheduler-intergation');
5
+ const {sequence} = require('@tryghost/promise');
6
6
 
7
7
  /**
8
8
  * @description Load all scheduled posts/pages from database.
@@ -13,7 +13,7 @@ const loadScheduledResources = async function () {
13
13
  const SCHEDULED_RESOURCES = ['post', 'page'];
14
14
 
15
15
  // Fetches all scheduled resources(posts/pages) with default API
16
- const results = await Promise.mapSeries(SCHEDULED_RESOURCES, async (resourceType) => {
16
+ const results = await sequence(SCHEDULED_RESOURCES.map(resourceType => async () => {
17
17
  const result = await api.schedules.getScheduled.query({
18
18
  options: {
19
19
  resource: resourceType
@@ -21,7 +21,7 @@ const loadScheduledResources = async function () {
21
21
  });
22
22
 
23
23
  return result[resourceType] || [];
24
- });
24
+ }));
25
25
 
26
26
  return SCHEDULED_RESOURCES.reduce(function (obj, entry, index) {
27
27
  return Object.assign(obj, {
@@ -201,6 +201,10 @@ module.exports = {
201
201
  return apiFramework.pipeline(require('./links'), localUtils);
202
202
  },
203
203
 
204
+ get mailEvents() {
205
+ return apiFramework.pipeline(require('./mail-events'), localUtils);
206
+ },
207
+
204
208
  /**
205
209
  * Content API Controllers
206
210
  *
@@ -0,0 +1,14 @@
1
+ const mailEvents = require('../../services/mail-events');
2
+
3
+ module.exports = {
4
+ docName: 'mail_events',
5
+ add: {
6
+ headers: {
7
+ cacheInvalidate: false
8
+ },
9
+ permissions: false,
10
+ async query(frame) {
11
+ return mailEvents.service.processPayload(frame.data);
12
+ }
13
+ }
14
+ };
@@ -140,6 +140,7 @@ module.exports = {
140
140
  'formats',
141
141
  'source',
142
142
  'force_rerender',
143
+ 'save_revision',
143
144
  // NOTE: only for internal context
144
145
  'forUpdate',
145
146
  'transacting'
@@ -139,5 +139,9 @@ module.exports = {
139
139
 
140
140
  get links() {
141
141
  return require('./links');
142
+ },
143
+
144
+ get mail_events() {
145
+ return require('./mail-events');
142
146
  }
143
147
  };
@@ -0,0 +1,9 @@
1
+ const debug = require('@tryghost/debug')('api:endpoints:utils:serializers:output:mail-events');
2
+
3
+ module.exports = {
4
+ add(response, apiConfig, frame) {
5
+ debug('add');
6
+
7
+ frame.response = {};
8
+ }
9
+ };
@@ -75,5 +75,9 @@ module.exports = {
75
75
 
76
76
  get snippets() {
77
77
  return require('./snippets');
78
+ },
79
+
80
+ get mail_events() {
81
+ return require('./mail-events');
78
82
  }
79
83
  };
@@ -0,0 +1,7 @@
1
+ const mailEvents = require('../../../../../services/mail-events');
2
+
3
+ module.exports = {
4
+ add(apiConfig, frame) {
5
+ mailEvents.service.validatePayload(frame.data);
6
+ }
7
+ };
@@ -1,10 +1,10 @@
1
1
  const _ = require('lodash');
2
- const Promise = require('bluebird');
3
2
  const db = require('../../data/db');
4
3
  const commands = require('../schema').commands;
5
4
  const ghostVersion = require('@tryghost/version');
6
5
  const tpl = require('@tryghost/tpl');
7
6
  const errors = require('@tryghost/errors');
7
+ const {sequence} = require('@tryghost/promise');
8
8
 
9
9
  const messages = {
10
10
  errorExportingData: 'Error exporting data'
@@ -36,9 +36,9 @@ const doExport = async function doExport(options) {
36
36
  try {
37
37
  const tables = await commands.getTables(options.transacting);
38
38
 
39
- const tableData = await Promise.mapSeries(tables, function (tableName) {
39
+ const tableData = await sequence(tables.map(tableName => async () => {
40
40
  return exportTable(tableName, options);
41
- });
41
+ }));
42
42
 
43
43
  const exportData = {
44
44
  meta: {
@@ -47,7 +47,9 @@ const BACKUP_TABLES = [
47
47
  'members_feedback',
48
48
  'suppressions',
49
49
  'email_spam_complaint_events',
50
- 'milestones'
50
+ 'milestones',
51
+ 'collections',
52
+ 'collections_posts'
51
53
  ];
52
54
 
53
55
  // NOTE: exposing only tables which are going to be included in a "default" export file
@@ -1,8 +1,8 @@
1
- const Promise = require('bluebird');
2
1
  const commands = require('../../schema').commands;
3
2
  const schema = require('../../schema').tables;
4
3
  const logging = require('@tryghost/logging');
5
4
  const schemaTables = Object.keys(schema);
5
+ const {sequence} = require('@tryghost/promise');
6
6
 
7
7
  module.exports.up = async (options) => {
8
8
  const connection = options.connection;
@@ -10,10 +10,10 @@ module.exports.up = async (options) => {
10
10
  const existingTables = await commands.getTables(connection);
11
11
  const missingTables = schemaTables.filter(t => !existingTables.includes(t));
12
12
 
13
- await Promise.mapSeries(missingTables, async (table) => {
13
+ await sequence(missingTables.map(table => async () => {
14
14
  logging.info('Creating table: ' + table);
15
15
  await commands.createTable(table, connection);
16
- });
16
+ }));
17
17
  };
18
18
 
19
19
  /**
@@ -24,9 +24,9 @@ module.exports.up = async (options) => {
24
24
 
25
25
  // Reference between tables!
26
26
  schemaTables.reverse();
27
- await Promise.mapSeries(schemaTables, async (table) => {
27
+ await sequence(schemaTables.map(table => async () => {
28
28
  logging.info('Drop table: ' + table);
29
29
  await commands.deleteTable(table, connection);
30
- });
30
+ }));
31
31
  };
32
32
  */
@@ -0,0 +1,9 @@
1
+ const {addTable} = require('../../utils');
2
+
3
+ module.exports = addTable('temp_mail_events', {
4
+ id: {type: 'string', maxlength: 100, nullable: false, primary: true},
5
+ type: {type: 'string', maxlength: 50, nullable: false},
6
+ message_id: {type: 'string', maxlength: 150, nullable: false},
7
+ recipient: {type: 'string', maxlength: 191, nullable: false},
8
+ occurred_at: {type: 'dateTime', nullable: false}
9
+ });
@@ -0,0 +1,10 @@
1
+ // For information on writing migrations, see https://www.notion.so/ghost/Database-migrations-eb5b78c435d741d2b34a582d57c24253
2
+
3
+ const {addTable} = require('../../utils');
4
+
5
+ module.exports = addTable('collections_posts', {
6
+ id: {type: 'string', maxlength: 24, nullable: false, primary: true},
7
+ collection_id: {type: 'string', maxlength: 24, nullable: false, references: 'collections.id', cascadeDelete: true},
8
+ post_id: {type: 'string', maxlength: 24, nullable: false, references: 'posts.id', cascadeDelete: true},
9
+ sort_order: {type: 'integer', nullable: false, unsigned: true, defaultTo: 0}
10
+ });
@@ -0,0 +1,15 @@
1
+ // For information on writing migrations, see https://www.notion.so/ghost/Database-migrations-eb5b78c435d741d2b34a582d57c24253
2
+
3
+ const {addTable} = require('../../utils');
4
+
5
+ module.exports = addTable('collections', {
6
+ id: {type: 'string', maxlength: 24, nullable: false, primary: true},
7
+ title: {type: 'string', maxlength: 191, nullable: false},
8
+ slug: {type: 'string', maxlength: 191, nullable: false, unique: true},
9
+ description: {type: 'string', maxlength: 2000, nullable: true},
10
+ type: {type: 'string', maxlength: 50, nullable: false},
11
+ filter: {type: 'text', maxlength: 1000000000, nullable: true},
12
+ feature_image: {type: 'string', maxlength: 2000, nullable: true},
13
+ created_at: {type: 'dateTime', nullable: false},
14
+ updated_at: {type: 'dateTime', nullable: true}
15
+ });
@@ -1021,5 +1021,29 @@ module.exports = {
1021
1021
  currency: {type: 'string', maxlength: 24, nullable: true},
1022
1022
  created_at: {type: 'dateTime', nullable: false},
1023
1023
  email_sent_at: {type: 'dateTime', nullable: true}
1024
+ },
1025
+ temp_mail_events: {
1026
+ id: {type: 'string', maxlength: 100, nullable: false, primary: true},
1027
+ type: {type: 'string', maxlength: 50, nullable: false},
1028
+ message_id: {type: 'string', maxlength: 150, nullable: false},
1029
+ recipient: {type: 'string', maxlength: 191, nullable: false},
1030
+ occurred_at: {type: 'dateTime', nullable: false}
1031
+ },
1032
+ collections: {
1033
+ id: {type: 'string', maxlength: 24, nullable: false, primary: true},
1034
+ title: {type: 'string', maxlength: 191, nullable: false},
1035
+ slug: {type: 'string', maxlength: 191, nullable: false, unique: true},
1036
+ description: {type: 'string', maxlength: 2000, nullable: true},
1037
+ type: {type: 'string', maxlength: 50, nullable: false},
1038
+ filter: {type: 'text', maxlength: 1000000000, nullable: true},
1039
+ feature_image: {type: 'string', maxlength: 2000, nullable: true},
1040
+ created_at: {type: 'dateTime', nullable: false},
1041
+ updated_at: {type: 'dateTime', nullable: true}
1042
+ },
1043
+ collections_posts: {
1044
+ id: {type: 'string', maxlength: 24, nullable: false, primary: true},
1045
+ collection_id: {type: 'string', maxlength: 24, nullable: false, references: 'collections.id', cascadeDelete: true},
1046
+ post_id: {type: 'string', maxlength: 24, nullable: false, references: 'posts.id', cascadeDelete: true},
1047
+ sort_order: {type: 'integer', nullable: false, unsigned: true, defaultTo: 0}
1024
1048
  }
1025
1049
  };
@@ -0,0 +1,12 @@
1
+ const ghostBookshelf = require('./base');
2
+
3
+ const MailEvent = ghostBookshelf.Model.extend({
4
+ tableName: 'temp_mail_events',
5
+ defaults() {
6
+ return {};
7
+ }
8
+ }, {});
9
+
10
+ module.exports = {
11
+ MailEvent: ghostBookshelf.model('MailEvent', MailEvent)
12
+ };
@@ -1,4 +1,3 @@
1
- const Promise = require('bluebird');
2
1
  const _ = require('lodash');
3
2
  const uuid = require('uuid');
4
3
  const crypto = require('crypto');
@@ -211,8 +210,8 @@ Settings = ghostBookshelf.Model.extend({
211
210
  data = [data];
212
211
  }
213
212
 
214
- return Promise.map(data, function (item) {
215
- // Accept an array of models as input
213
+ // Accept an array of models as input
214
+ const promises = data.map(function (item) {
216
215
  if (item.toJSON) {
217
216
  item = item.toJSON();
218
217
  }
@@ -254,6 +253,7 @@ Settings = ghostBookshelf.Model.extend({
254
253
  return Promise.reject(new errors.NotFoundError({message: tpl(messages.unableToFindSetting, {key: item.key})}));
255
254
  });
256
255
  });
256
+ return Promise.all(promises);
257
257
  },
258
258
 
259
259
  populateDefaults: async function populateDefaults(unfilteredOptions) {