ghost 5.49.2 → 5.50.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 (165) hide show
  1. package/components/tryghost-adapter-cache-memory-ttl-5.50.0.tgz +0 -0
  2. package/components/tryghost-adapter-cache-redis-5.50.0.tgz +0 -0
  3. package/components/tryghost-adapter-manager-5.50.0.tgz +0 -0
  4. package/components/tryghost-announcement-bar-settings-5.50.0.tgz +0 -0
  5. package/components/{tryghost-api-framework-5.49.2.tgz → tryghost-api-framework-5.50.0.tgz} +0 -0
  6. package/components/tryghost-api-version-compatibility-service-5.50.0.tgz +0 -0
  7. package/components/tryghost-audience-feedback-5.50.0.tgz +0 -0
  8. package/components/tryghost-bootstrap-socket-5.50.0.tgz +0 -0
  9. package/components/tryghost-collections-5.50.0.tgz +0 -0
  10. package/components/tryghost-constants-5.50.0.tgz +0 -0
  11. package/components/tryghost-custom-theme-settings-service-5.50.0.tgz +0 -0
  12. package/components/tryghost-data-generator-5.50.0.tgz +0 -0
  13. package/components/tryghost-domain-events-5.50.0.tgz +0 -0
  14. package/components/tryghost-dynamic-routing-events-5.50.0.tgz +0 -0
  15. package/components/tryghost-email-analytics-provider-mailgun-5.50.0.tgz +0 -0
  16. package/components/tryghost-email-analytics-service-5.50.0.tgz +0 -0
  17. package/components/tryghost-email-content-generator-5.50.0.tgz +0 -0
  18. package/components/tryghost-email-events-5.50.0.tgz +0 -0
  19. package/components/{tryghost-email-service-5.49.2.tgz → tryghost-email-service-5.50.0.tgz} +0 -0
  20. package/components/tryghost-email-suppression-list-5.50.0.tgz +0 -0
  21. package/components/tryghost-event-aware-cache-wrapper-5.50.0.tgz +0 -0
  22. package/components/tryghost-express-dynamic-redirects-5.50.0.tgz +0 -0
  23. package/components/tryghost-external-media-inliner-5.50.0.tgz +0 -0
  24. package/components/tryghost-extract-api-key-5.50.0.tgz +0 -0
  25. package/components/tryghost-html-to-plaintext-5.50.0.tgz +0 -0
  26. package/components/tryghost-i18n-5.50.0.tgz +0 -0
  27. package/components/tryghost-importer-handler-content-files-5.50.0.tgz +0 -0
  28. package/components/tryghost-importer-revue-5.50.0.tgz +0 -0
  29. package/components/tryghost-in-memory-repository-5.50.0.tgz +0 -0
  30. package/components/tryghost-job-manager-5.50.0.tgz +0 -0
  31. package/components/tryghost-link-redirects-5.50.0.tgz +0 -0
  32. package/components/tryghost-link-replacer-5.50.0.tgz +0 -0
  33. package/components/tryghost-link-tracking-5.50.0.tgz +0 -0
  34. package/components/{tryghost-magic-link-5.49.2.tgz → tryghost-magic-link-5.50.0.tgz} +0 -0
  35. package/components/tryghost-mailgun-client-5.50.0.tgz +0 -0
  36. package/components/tryghost-member-attribution-5.50.0.tgz +0 -0
  37. package/components/tryghost-member-events-5.50.0.tgz +0 -0
  38. package/components/{tryghost-members-api-5.49.2.tgz → tryghost-members-api-5.50.0.tgz} +0 -0
  39. package/components/tryghost-members-csv-5.50.0.tgz +0 -0
  40. package/components/tryghost-members-events-service-5.50.0.tgz +0 -0
  41. package/components/{tryghost-members-importer-5.49.2.tgz → tryghost-members-importer-5.50.0.tgz} +0 -0
  42. package/components/tryghost-members-offers-5.50.0.tgz +0 -0
  43. package/components/tryghost-members-payments-5.50.0.tgz +0 -0
  44. package/components/tryghost-members-ssr-5.50.0.tgz +0 -0
  45. package/components/tryghost-members-stripe-service-5.50.0.tgz +0 -0
  46. package/components/tryghost-mentions-email-report-5.50.0.tgz +0 -0
  47. package/components/tryghost-milestones-5.50.0.tgz +0 -0
  48. package/components/tryghost-minifier-5.50.0.tgz +0 -0
  49. package/components/tryghost-mw-api-version-mismatch-5.50.0.tgz +0 -0
  50. package/components/tryghost-mw-cache-control-5.50.0.tgz +0 -0
  51. package/components/tryghost-mw-error-handler-5.50.0.tgz +0 -0
  52. package/components/tryghost-mw-session-from-token-5.50.0.tgz +0 -0
  53. package/components/tryghost-mw-update-user-last-seen-5.50.0.tgz +0 -0
  54. package/components/tryghost-mw-version-match-5.50.0.tgz +0 -0
  55. package/components/tryghost-mw-vhost-5.50.0.tgz +0 -0
  56. package/components/tryghost-oembed-service-5.50.0.tgz +0 -0
  57. package/components/tryghost-package-json-5.50.0.tgz +0 -0
  58. package/components/tryghost-post-revisions-5.50.0.tgz +0 -0
  59. package/components/tryghost-posts-service-5.50.0.tgz +0 -0
  60. package/components/tryghost-referrers-5.50.0.tgz +0 -0
  61. package/components/tryghost-security-5.50.0.tgz +0 -0
  62. package/components/tryghost-session-service-5.50.0.tgz +0 -0
  63. package/components/tryghost-settings-path-manager-5.50.0.tgz +0 -0
  64. package/components/tryghost-slack-notifications-5.50.0.tgz +0 -0
  65. package/components/tryghost-staff-service-5.50.0.tgz +0 -0
  66. package/components/tryghost-stats-service-5.50.0.tgz +0 -0
  67. package/components/tryghost-tiers-5.50.0.tgz +0 -0
  68. package/components/tryghost-update-check-service-5.50.0.tgz +0 -0
  69. package/components/tryghost-verification-trigger-5.50.0.tgz +0 -0
  70. package/components/tryghost-version-notifications-data-service-5.50.0.tgz +0 -0
  71. package/components/tryghost-webmentions-5.50.0.tgz +0 -0
  72. package/core/built/admin/assets/{chunk.143.1d467437aed60c459bbb.js → chunk.143.d620849d367a8ef5e12c.js} +5 -5
  73. package/core/built/admin/assets/{chunk.178.6d55d1f7bc3a5eb2ec4b.js → chunk.178.decedb27e1076ab65650.js} +4 -4
  74. package/core/built/admin/assets/{chunk.124.ede028f827ba942bf7e3.js → chunk.976.cd1384578d700f188531.js} +792 -842
  75. package/core/built/admin/assets/fonts/Inter-italic.var.woff2 +0 -0
  76. package/core/built/admin/assets/fonts/Inter-roman.var.woff2 +0 -0
  77. package/core/built/admin/assets/ghost-51b822dbd104c8bcb90da467b093a741.css +1 -0
  78. package/core/built/admin/assets/{ghost-9169ef48d0474b34a0a2a01edd29683b.js → ghost-d2778bbeddb60475038da075bab0a650.js} +3730 -3720
  79. package/core/built/admin/assets/ghost-dark-05303b343febee7094cf9a0c49749c17.css +1 -0
  80. package/core/built/admin/assets/{vendor-e0851d527586cb85e37e146ec921136a.js → vendor-bc3bd83c56b822ae56193b0d231189c0.js} +2 -2
  81. package/core/built/admin/index.html +6 -6
  82. package/core/frontend/src/cards/css/product.css +1 -0
  83. package/core/frontend/src/cards/css/signup.css +60 -29
  84. package/core/server/api/endpoints/collections.js +74 -0
  85. package/core/server/api/endpoints/utils/serializers/output/mappers/collections.js +26 -7
  86. package/core/server/api/endpoints/utils/serializers/output/mappers/emails.js +0 -8
  87. package/core/server/models/post.js +38 -74
  88. package/core/server/services/Users.js +6 -9
  89. package/core/server/services/collections/PostsDataRepositoryBookshelf.js +23 -0
  90. package/core/server/services/collections/index.js +11 -5
  91. package/core/server/web/api/endpoints/admin/routes.js +2 -0
  92. package/core/shared/config/defaults.json +1 -1
  93. package/core/shared/labs.js +3 -7
  94. package/package.json +148 -146
  95. package/yarn.lock +857 -732
  96. package/components/tryghost-adapter-cache-memory-ttl-5.49.2.tgz +0 -0
  97. package/components/tryghost-adapter-cache-redis-5.49.2.tgz +0 -0
  98. package/components/tryghost-adapter-manager-5.49.2.tgz +0 -0
  99. package/components/tryghost-announcement-bar-settings-5.49.2.tgz +0 -0
  100. package/components/tryghost-api-version-compatibility-service-5.49.2.tgz +0 -0
  101. package/components/tryghost-audience-feedback-5.49.2.tgz +0 -0
  102. package/components/tryghost-bootstrap-socket-5.49.2.tgz +0 -0
  103. package/components/tryghost-collections-5.49.2.tgz +0 -0
  104. package/components/tryghost-constants-5.49.2.tgz +0 -0
  105. package/components/tryghost-custom-theme-settings-service-5.49.2.tgz +0 -0
  106. package/components/tryghost-data-generator-5.49.2.tgz +0 -0
  107. package/components/tryghost-domain-events-5.49.2.tgz +0 -0
  108. package/components/tryghost-dynamic-routing-events-5.49.2.tgz +0 -0
  109. package/components/tryghost-email-analytics-provider-mailgun-5.49.2.tgz +0 -0
  110. package/components/tryghost-email-analytics-service-5.49.2.tgz +0 -0
  111. package/components/tryghost-email-content-generator-5.49.2.tgz +0 -0
  112. package/components/tryghost-email-events-5.49.2.tgz +0 -0
  113. package/components/tryghost-email-suppression-list-5.49.2.tgz +0 -0
  114. package/components/tryghost-event-aware-cache-wrapper-5.49.2.tgz +0 -0
  115. package/components/tryghost-express-dynamic-redirects-5.49.2.tgz +0 -0
  116. package/components/tryghost-external-media-inliner-5.49.2.tgz +0 -0
  117. package/components/tryghost-extract-api-key-5.49.2.tgz +0 -0
  118. package/components/tryghost-html-to-plaintext-5.49.2.tgz +0 -0
  119. package/components/tryghost-i18n-5.49.2.tgz +0 -0
  120. package/components/tryghost-importer-handler-content-files-5.49.2.tgz +0 -0
  121. package/components/tryghost-importer-revue-5.49.2.tgz +0 -0
  122. package/components/tryghost-in-memory-repository-5.49.2.tgz +0 -0
  123. package/components/tryghost-job-manager-5.49.2.tgz +0 -0
  124. package/components/tryghost-link-redirects-5.49.2.tgz +0 -0
  125. package/components/tryghost-link-replacer-5.49.2.tgz +0 -0
  126. package/components/tryghost-link-tracking-5.49.2.tgz +0 -0
  127. package/components/tryghost-mailgun-client-5.49.2.tgz +0 -0
  128. package/components/tryghost-member-attribution-5.49.2.tgz +0 -0
  129. package/components/tryghost-member-events-5.49.2.tgz +0 -0
  130. package/components/tryghost-members-csv-5.49.2.tgz +0 -0
  131. package/components/tryghost-members-events-service-5.49.2.tgz +0 -0
  132. package/components/tryghost-members-offers-5.49.2.tgz +0 -0
  133. package/components/tryghost-members-payments-5.49.2.tgz +0 -0
  134. package/components/tryghost-members-ssr-5.49.2.tgz +0 -0
  135. package/components/tryghost-members-stripe-service-5.49.2.tgz +0 -0
  136. package/components/tryghost-mentions-email-report-5.49.2.tgz +0 -0
  137. package/components/tryghost-milestones-5.49.2.tgz +0 -0
  138. package/components/tryghost-minifier-5.49.2.tgz +0 -0
  139. package/components/tryghost-mw-api-version-mismatch-5.49.2.tgz +0 -0
  140. package/components/tryghost-mw-cache-control-5.49.2.tgz +0 -0
  141. package/components/tryghost-mw-error-handler-5.49.2.tgz +0 -0
  142. package/components/tryghost-mw-session-from-token-5.49.2.tgz +0 -0
  143. package/components/tryghost-mw-update-user-last-seen-5.49.2.tgz +0 -0
  144. package/components/tryghost-mw-version-match-5.49.2.tgz +0 -0
  145. package/components/tryghost-mw-vhost-5.49.2.tgz +0 -0
  146. package/components/tryghost-oembed-service-5.49.2.tgz +0 -0
  147. package/components/tryghost-package-json-5.49.2.tgz +0 -0
  148. package/components/tryghost-post-revisions-5.49.2.tgz +0 -0
  149. package/components/tryghost-posts-service-5.49.2.tgz +0 -0
  150. package/components/tryghost-referrers-5.49.2.tgz +0 -0
  151. package/components/tryghost-security-5.49.2.tgz +0 -0
  152. package/components/tryghost-session-service-5.49.2.tgz +0 -0
  153. package/components/tryghost-settings-path-manager-5.49.2.tgz +0 -0
  154. package/components/tryghost-slack-notifications-5.49.2.tgz +0 -0
  155. package/components/tryghost-staff-service-5.49.2.tgz +0 -0
  156. package/components/tryghost-stats-service-5.49.2.tgz +0 -0
  157. package/components/tryghost-tiers-5.49.2.tgz +0 -0
  158. package/components/tryghost-update-check-service-5.49.2.tgz +0 -0
  159. package/components/tryghost-verification-trigger-5.49.2.tgz +0 -0
  160. package/components/tryghost-version-notifications-data-service-5.49.2.tgz +0 -0
  161. package/components/tryghost-webmentions-5.49.2.tgz +0 -0
  162. package/core/built/admin/assets/fonts/Inter-e19174fb2c0e19b1fa67492a07886c75.ttf +0 -0
  163. package/core/built/admin/assets/ghost-dark-b4374a49465902d3cd1a297ed3f5222f.css +0 -1
  164. package/core/built/admin/assets/ghost-e5dfcf346304a62879b8aa8380b500c7.css +0 -1
  165. /package/core/built/admin/assets/{chunk.124.ede028f827ba942bf7e3.js.LICENSE.txt → chunk.976.cd1384578d700f188531.js.LICENSE.txt} +0 -0
@@ -11712,7 +11712,7 @@ e.default={content:'<g fill="none" fill-rule="evenodd"><path d="M31.252 8.488a4.
11712
11712
  Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
11713
11713
  e.default={content:'<path opacity=".4" d="M2 5h12a1 1 0 011 1v4a1 1 0 01-1 1H2a1 1 0 01-1-1V6a1 1 0 011-1z" fill="#394047"/><path fill-rule="evenodd" clip-rule="evenodd" d="M15 13.25a.75.75 0 01-.75.75H1.75a.75.75 0 010-1.5h12.5a.75.75 0 01.75.75zm0-10.5a.75.75 0 01-.75.75H1.75a.75.75 0 010-1.5h12.5a.75.75 0 01.75.75z" fill="#394047"/>',attrs:{fill:"none",viewBox:"0 0 16 16"}}})),define("ember-svg-jar/inlined/koenig/kg-edit",["exports"],(function(e){"use strict"
11714
11714
  Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
11715
- e.default={content:'<path d="M9.66 3.944c-.132-.125-.264-.125-.396 0L3.626 9.638c-.132.132-.132.264 0 .396l2.397 2.397c.132.132.264.132.396 0l5.638-5.693c.132-.132.132-.264 0-.396L9.66 3.944zm-6.98 6.974c-.074-.074-.162-.098-.263-.074a.262.262 0 00-.2.186l-1.2 3.595a.264.264 0 00.068.287c.082.08.178.103.287.067l3.595-1.198a.261.261 0 00.186-.2.263.263 0 00-.074-.264l-2.399-2.4zM13.862 2.13c-.931-.889-1.862-.889-2.793 0l-.399.399c-.132.132-.132.264 0 .396l2.396 2.397c.132.131.264.131.396 0l.4-.402c.927-.93.927-1.86 0-2.79z" fill="#FFF" fill-rule="evenodd"/>',attrs:{viewBox:"0 0 16 16"}}})),define("ember-svg-jar/inlined/koenig/kg-header-full-center",["exports"],(function(e){"use strict"
11715
+ e.default={content:'<g fill="currentColor"><path d="M13.086 5.5l-9.793 9.793a1.01 1.01 0 00-.241.391l-2 6a1 1 0 001.264 1.265l6-2c.147-.049.281-.132.391-.242l9.793-9.793L13.086 5.5zM22.414 4.172l-2.586-2.586a2.001 2.001 0 00-2.828 0l-2.5 2.5L19.914 9.5l2.5-2.5c.378-.378.586-.88.586-1.414s-.208-1.037-.586-1.414z"/></g>',attrs:{viewBox:"0 0 24 24"}}})),define("ember-svg-jar/inlined/koenig/kg-header-full-center",["exports"],(function(e){"use strict"
11716
11716
  Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
11717
11717
  e.default={content:'<path fill="#fff" d="M0 0h75v50H0z"/><path fill="#F1F1F1" d="M0 12h75v25H0z"/><rect x="21" y="19" width="32" height="10" rx="2" fill="#fff"/><rect x="21" y="6" width="32" height="1.5" rx=".75" fill="#F1F1F1"/><rect x="21" y="42" width="32" height="1.5" rx=".75" fill="#F1F1F1"/>',attrs:{viewBox:"0 0 75 50",fill:"none"}}})),define("ember-svg-jar/inlined/koenig/kg-header-full-left",["exports"],(function(e){"use strict"
11718
11718
  Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 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-e0851d527586cb85e37e146ec921136a.map
14096
+ //# sourceMappingURL=vendor-bc3bd83c56b822ae56193b0d231189c0.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.49%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.50%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" />
@@ -37,7 +37,7 @@
37
37
  </style>
38
38
 
39
39
  <link integrity="" rel="stylesheet" href="assets/vendor-3e6947aa681f0fb82b193090e520dc73.css">
40
- <link integrity="" rel="stylesheet" href="assets/ghost-e5dfcf346304a62879b8aa8380b500c7.css" title="light">
40
+ <link integrity="" rel="stylesheet" href="assets/ghost-51b822dbd104c8bcb90da467b093a741.css" title="light">
41
41
 
42
42
 
43
43
  </head>
@@ -56,9 +56,9 @@
56
56
 
57
57
  <div id="ember-basic-dropdown-wormhole"></div>
58
58
 
59
- <script src="assets/vendor-e0851d527586cb85e37e146ec921136a.js"></script>
60
- <script src="assets/chunk.124.ede028f827ba942bf7e3.js"></script>
61
- <script src="assets/chunk.143.1d467437aed60c459bbb.js"></script>
62
- <script src="assets/ghost-9169ef48d0474b34a0a2a01edd29683b.js"></script>
59
+ <script src="assets/vendor-bc3bd83c56b822ae56193b0d231189c0.js"></script>
60
+ <script src="assets/chunk.976.cd1384578d700f188531.js"></script>
61
+ <script src="assets/chunk.143.d620849d367a8ef5e12c.js"></script>
62
+ <script src="assets/ghost-d2778bbeddb60475038da075bab0a650.js"></script>
63
63
  </body>
64
64
  </html>
@@ -26,6 +26,7 @@
26
26
  .kg-product-card-image {
27
27
  grid-column: 1 / 3;
28
28
  justify-self: center;
29
+ height: auto;
29
30
  }
30
31
 
31
32
  .kg-product-card-title-container {
@@ -61,12 +61,12 @@
61
61
  /* Split layout image */
62
62
 
63
63
  .kg-signup-card-image {
64
- object-fit: cover;
65
- object-position: center;
66
64
  /* this will force the image to follow the signup card height */
67
65
  height: 0;
68
66
  min-height: 100%;
69
67
  /**/
68
+ object-fit: cover;
69
+ object-position: center;
70
70
  }
71
71
 
72
72
  .kg-signup-card-image.kg-style-accent {
@@ -76,11 +76,11 @@
76
76
  /* Heading */
77
77
 
78
78
  .kg-signup-card h2.kg-signup-card-heading {
79
+ margin: 0;
79
80
  font-size: 4.8vmin;
80
81
  font-weight: 700;
81
82
  line-height: 1em;
82
83
  letter-spacing: -0.01em;
83
- margin: 0;
84
84
  }
85
85
 
86
86
  .kg-signup-card h2.kg-signup-card-heading strong {
@@ -88,11 +88,11 @@
88
88
  }
89
89
 
90
90
  .kg-signup-card.kg-width-wide h2.kg-signup-card-heading {
91
- font-size: 6vmin;
91
+ font-size: 5.6vmin;
92
92
  }
93
93
 
94
94
  .kg-signup-card.kg-width-full h2.kg-signup-card-heading {
95
- font-size: 8vmin;
95
+ font-size: 7.4vmin;
96
96
  }
97
97
 
98
98
  .kg-signup-card.kg-width-full.kg-layout-split h2.kg-signup-card-heading {
@@ -106,11 +106,11 @@
106
106
  }
107
107
 
108
108
  .kg-signup-card h3.kg-signup-card-subheading {
109
+ max-width: 40em;
110
+ margin: 0;
109
111
  font-size: 1.25em;
110
112
  font-weight: 500;
111
113
  line-height: 1.4em;
112
- margin: 0;
113
- max-width: 40em;
114
114
  }
115
115
 
116
116
  .kg-signup-card h2 + h3.kg-signup-card-subheading {
@@ -125,7 +125,8 @@
125
125
  font-size: 1.5em;
126
126
  }
127
127
 
128
- .kg-signup-card.kg-width-full h3.kg-signup-card-subheading {
128
+ .kg-signup-card.kg-width-full h3.kg-signup-card-subheading:not(.kg-layout-split h3.kg-signup-card-subheading) {
129
+ max-width: 65vmax;
129
130
  font-size: 1.75em;
130
131
  }
131
132
 
@@ -137,9 +138,15 @@
137
138
 
138
139
  .kg-signup-card-form {
139
140
  position: relative;
141
+ display: flex;
142
+ flex-shrink: 0;
140
143
  width: 100%;
141
144
  }
142
145
 
146
+ .align-center .kg-signup-card-form {
147
+ justify-content: center;
148
+ }
149
+
143
150
  .kg-signup-card-heading + .kg-signup-card-form,
144
151
  .kg-signup-card-subheading + .kg-signup-card-form {
145
152
  margin: 2.4vmax 0 0;
@@ -157,34 +164,41 @@
157
164
 
158
165
  .kg-signup-card-fields {
159
166
  display: flex;
167
+ width: 100%;
168
+ padding: 3px;
169
+ background: #FFFFFF;
170
+ border: 1px solid #E6E6E6;
171
+ border-radius: 4px;
160
172
  }
161
173
 
162
- .align-center .kg-signup-card-fields {
163
- justify-content: center;
174
+ .kg-width-wide .kg-signup-card-fields,
175
+ .kg-width-full .kg-signup-card-fields:not(.kg-layout-split .kg-signup-card-fields) {
176
+ width: 100%;
177
+ max-width: 500px;
164
178
  }
165
179
 
166
180
  .kg-signup-card-input {
167
181
  width: 100%;
168
- border: solid 1px;
182
+ height: 4.6rem;
183
+ margin-right: 3px;
169
184
  padding: 12px 16px;
185
+ border: none;
170
186
  font-size: 1.1em;
171
187
  }
172
188
 
173
- .kg-width-wide .kg-signup-card-input,
174
- .kg-width-full .kg-signup-card-input:not(.kg-layout-split .kg-signup-card-input) {
175
- max-width: 400px;
176
- }
177
-
178
- .kg-signup-card-input.kg-style-accent {
179
- border-color: var(--ghost-accent-color);
189
+ .kg-signup-card-input:focus,
190
+ .kg-signup-card-input:focus-visible {
191
+ outline: none;
180
192
  }
181
193
 
182
194
  .kg-signup-card-button {
183
195
  display: flex;
184
196
  position: relative;
185
197
  align-items: center;
198
+ height: 4.6rem;
199
+ padding: 0 1.2em;
186
200
  outline: none;
187
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
201
+ border: none;
188
202
  font-size: 1em;
189
203
  font-weight: 600;
190
204
  line-height: 1em;
@@ -193,8 +207,7 @@
193
207
  letter-spacing: .2px;
194
208
  white-space: nowrap;
195
209
  text-overflow: ellipsis;
196
- height: 3em;
197
- padding: 0 1.2em;
210
+ border-radius: 3px;
198
211
  transition: opacity .2s ease;
199
212
  }
200
213
 
@@ -249,10 +262,16 @@
249
262
  line-height: 1.4em;
250
263
  }
251
264
 
265
+ .kg-signup-card-form.error .kg-signup-card-fields {
266
+ border: 1px solid #FF0000;
267
+ box-shadow: inset 0 0 0 1px rgba(255, 0, 0, 0.2);
268
+ }
269
+
252
270
  .kg-signup-card-form.error .kg-signup-card-error {
253
- display: block;
254
271
  position: absolute;
255
- top: -32px;
272
+ bottom: calc(-1rem - 1.6em);
273
+ display: block;
274
+ font-size: inherit;
256
275
  }
257
276
 
258
277
  .kg-signup-card-button-loading {
@@ -263,6 +282,10 @@
263
282
  display: none;
264
283
  }
265
284
 
285
+ .kg-signup-card-form.loading .kg-signup-card-button-default {
286
+ color: transparent;
287
+ }
288
+
266
289
  .kg-signup-card-form.loading .kg-signup-card-button-loading {
267
290
  display: flex;
268
291
  }
@@ -273,7 +296,8 @@
273
296
  margin: 1rem 0 0;
274
297
  }
275
298
 
276
- .kg-signup-card-form.success + .kg-signup-card-disclaimer {
299
+ .kg-signup-card-form.success + .kg-signup-card-disclaimer,
300
+ .kg-signup-card-form.error + .kg-signup-card-disclaimer {
277
301
  visibility: hidden;
278
302
  }
279
303
 
@@ -300,8 +324,15 @@
300
324
  }
301
325
 
302
326
  .kg-signup-card-input {
303
- font-size: inherit;
327
+ height: 4.2rem;
328
+ padding: 6px 12px;
329
+ font-size: 1em;
330
+ }
331
+
332
+ .kg-signup-card-button {
333
+ height: 4.2rem;
304
334
  }
335
+
305
336
  .kg-signup-card.kg-width-wide .kg-signup-card-button,
306
337
  .kg-signup-card.kg-width-full .kg-signup-card-button {
307
338
  font-size: 1em;
@@ -309,8 +340,8 @@
309
340
 
310
341
  .kg-signup-card h3.kg-signup-card-subheading,
311
342
  .kg-signup-card.kg-width-wide h3.kg-signup-card-subheading,
312
- .kg-signup-card.kg-width-full h3.kg-signup-card-subheading,
313
- .kg-signup-card.kg-width-full.kg-layout-split h3.kg-signup-card-subheading {
314
- font-size: 1.1em;
343
+ .kg-signup-card.kg-width-full.kg-layout-split h3.kg-signup-card-subheading,
344
+ .kg-signup-card.kg-width-full h3.kg-signup-card-subheading:not(.kg-layout-split h3.kg-signup-card-subheading) {
345
+ font-size: 1em;
315
346
  }
316
- }
347
+ }
@@ -91,6 +91,45 @@ module.exports = {
91
91
  }
92
92
  },
93
93
 
94
+ addPost: {
95
+ docName: 'collection_posts',
96
+ statusCode: 200,
97
+ headers: {},
98
+ options: [
99
+ 'id'
100
+ ],
101
+ data: [
102
+ 'post_id'
103
+ ],
104
+ validation: {
105
+ options: {
106
+ id: {
107
+ required: true
108
+ }
109
+ },
110
+ data: {
111
+ post_id: {
112
+ required: true
113
+ }
114
+ }
115
+ },
116
+ // @NOTE: should have permissions when moving out of Alpha
117
+ permissions: false,
118
+ async query(frame) {
119
+ const collectionPost = await collectionsService.api.addPost(frame.options.id, {
120
+ id: frame.data.posts[0].id
121
+ });
122
+
123
+ if (!collectionPost) {
124
+ throw new errors.NotFoundError({
125
+ message: tpl(messages.collectionNotFound)
126
+ });
127
+ }
128
+
129
+ return collectionPost;
130
+ }
131
+ },
132
+
94
133
  destroy: {
95
134
  statusCode: 204,
96
135
  headers: {
@@ -111,5 +150,40 @@ module.exports = {
111
150
  async query(frame) {
112
151
  return await collectionsService.api.destroy(frame.options.id);
113
152
  }
153
+ },
154
+
155
+ destroyPost: {
156
+ docName: 'collection_posts',
157
+ statusCode: 200,
158
+ headers: {
159
+ cacheInvalidate: true
160
+ },
161
+ options: [
162
+ 'id',
163
+ 'post_id'
164
+ ],
165
+ validation: {
166
+ options: {
167
+ id: {
168
+ required: true
169
+ },
170
+ post_id: {
171
+ required: true
172
+ }
173
+ }
174
+ },
175
+ // @NOTE: should have permissions when moving out of Alpha
176
+ permissions: false,
177
+ async query(frame) {
178
+ const collection = await collectionsService.api.destroyCollectionPost(frame.options.id, frame.options.post_id);
179
+
180
+ if (!collection) {
181
+ throw new errors.NotFoundError({
182
+ message: tpl(messages.collectionNotFound)
183
+ });
184
+ }
185
+
186
+ return collection;
187
+ }
114
188
  }
115
189
  };
@@ -1,22 +1,41 @@
1
1
  /**
2
2
  *
3
- * @param {import('@tryghost/collections').Collection} collection
3
+ * @param {import('@tryghost/collections').Collection | object} collection
4
4
  *
5
5
  * @returns {SerializedCollection}
6
6
  */
7
7
  const mapper = (collection) => {
8
- const json = collection.toJSON();
8
+ let json;
9
+ let posts;
10
+ if (collection.toJSON) {
11
+ json = collection.toJSON();
12
+ posts = json.posts.map((postId, index) => {
13
+ return {
14
+ id: postId,
15
+ sort_order: index
16
+ };
17
+ });
18
+ } else {
19
+ json = collection;
20
+ posts = json.posts.map((post) => {
21
+ return {
22
+ id: post.id,
23
+ sort_order: post.sort_order
24
+ };
25
+ });
26
+ }
9
27
 
10
28
  const serialized = {
11
29
  id: json.id,
12
- title: json.title,
30
+ title: json.title || null,
13
31
  slug: json.slug,
14
- description: json.description,
32
+ description: json.description || null,
15
33
  type: json.type,
16
34
  filter: json.filter,
17
- feature_image: json.featureImage,
18
- created_at: json.createdAt.toISOString().replace(/\d{3}Z$/, '000Z'),
19
- updated_at: json.updatedAt.toISOString().replace(/\d{3}Z$/, '000Z')
35
+ feature_image: json.feature_image || json.featureImage || null,
36
+ created_at: (json.created_at || json.createdAt).toISOString().replace(/\d{3}Z$/, '000Z'),
37
+ updated_at: (json.updated_at || json.updatedAt).toISOString().replace(/\d{3}Z$/, '000Z'),
38
+ posts
20
39
  };
21
40
 
22
41
  return serialized;
@@ -1,5 +1,3 @@
1
- const labs = require('../../../../../../../shared/labs');
2
- const config = require('../../../../../../../shared/config');
3
1
  const emailService = require('../../../../../../services/email-service');
4
2
 
5
3
  module.exports = (model, frame) => {
@@ -19,12 +17,6 @@ module.exports = (model, frame) => {
19
17
  }
20
18
  }
21
19
 
22
- if (!labs.isSet('emailErrors') && !!(config.get('bulkEmail') && config.get('bulkEmail').mailgun)) {
23
- if (jsonModel.status === 'failed') {
24
- jsonModel.status = 'submitted';
25
- }
26
- }
27
-
28
20
  // Removed loaded post relation if set
29
21
  delete jsonModel.post;
30
22
 
@@ -20,7 +20,6 @@ const {Tag} = require('./tag');
20
20
  const {Newsletter} = require('./newsletter');
21
21
  const {BadRequestError} = require('@tryghost/errors');
22
22
  const {PostRevisions} = require('@tryghost/post-revisions');
23
- const labs = require('../../shared/labs');
24
23
 
25
24
  const messages = {
26
25
  isAlreadyPublished: 'Your post is already published, please reload your page.',
@@ -869,80 +868,45 @@ Post = ghostBookshelf.Model.extend({
869
868
  });
870
869
  });
871
870
  }
871
+ if (!model.get('mobiledoc') && !options.importing && !options.migrating) {
872
+ const postRevisions = new PostRevisions({
873
+ config: {
874
+ max_revisions: POST_REVISIONS_COUNT,
875
+ revision_interval_ms: POST_REVISIONS_INTERVAL_MS
876
+ }
877
+ });
878
+ const authorId = this.contextUser(options);
879
+ ops.push(async function updateRevisions() {
880
+ const revisionModels = await ghostBookshelf.model('PostRevision')
881
+ .findAll(Object.assign({
882
+ filter: `post_id:${model.id}`,
883
+ columns: ['id', 'lexical', 'created_at', 'author_id', 'title', 'reason', 'post_status', 'created_at_ts', 'feature_image']
884
+ }, _.pick(options, 'transacting')));
885
+
886
+ const revisions = revisionModels.toJSON();
887
+
888
+ const current = {
889
+ id: model.id,
890
+ lexical: model.get('lexical'),
891
+ html: model.get('html'),
892
+ author_id: authorId,
893
+ feature_image: model.get('feature_image'),
894
+ feature_image_alt: model.get('posts_meta')?.feature_image_alt,
895
+ feature_image_caption: model.get('posts_meta')?.feature_image_caption,
896
+ title: model.get('title'),
897
+ post_status: model.get('status')
898
+ };
872
899
 
873
- if (!labs.isSet('postHistory')) {
874
- if (model.hasChanged('lexical') && !model.get('mobiledoc') && !options.importing && !options.migrating) {
875
- ops.push(function updateRevisions() {
876
- return ghostBookshelf.model('PostRevision')
877
- .findAll(Object.assign({
878
- filter: `post_id:${model.id}`,
879
- columns: ['id']
880
- }, _.pick(options, 'transacting')))
881
- .then((revisions) => {
882
- // Store previous + latest lexical content
883
- if (!revisions.length && options.method !== 'insert') {
884
- model.set('post_revisions', [{
885
- post_id: model.id,
886
- lexical: model.previous('lexical'),
887
- created_at_ts: Date.now() - 1
888
- }, {
889
- post_id: model.id,
890
- lexical: model.get('lexical'),
891
- created_at_ts: Date.now()
892
- }]);
893
- } else {
894
- const revisionsJSON = revisions.toJSON().slice(0, POST_REVISIONS_COUNT - 1);
895
-
896
- model.set('post_revisions', revisionsJSON.concat([{
897
- post_id: model.id,
898
- lexical: model.get('lexical'),
899
- created_at_ts: Date.now()
900
- }]));
901
- }
902
- });
903
- });
904
- }
905
- } else {
906
- if (!model.get('mobiledoc') && !options.importing && !options.migrating) {
907
- const postRevisions = new PostRevisions({
908
- config: {
909
- max_revisions: POST_REVISIONS_COUNT,
910
- revision_interval_ms: POST_REVISIONS_INTERVAL_MS
911
- }
912
- });
913
- const authorId = this.contextUser(options);
914
- ops.push(async function updateRevisions() {
915
- const revisionModels = await ghostBookshelf.model('PostRevision')
916
- .findAll(Object.assign({
917
- filter: `post_id:${model.id}`,
918
- columns: ['id', 'lexical', 'created_at', 'author_id', 'title', 'reason', 'post_status', 'created_at_ts', 'feature_image']
919
- }, _.pick(options, 'transacting')));
920
-
921
- const revisions = revisionModels.toJSON();
922
-
923
- const current = {
924
- id: model.id,
925
- lexical: model.get('lexical'),
926
- html: model.get('html'),
927
- author_id: authorId,
928
- feature_image: model.get('feature_image'),
929
- feature_image_alt: model.get('posts_meta')?.feature_image_alt,
930
- feature_image_caption: model.get('posts_meta')?.feature_image_caption,
931
- title: model.get('title'),
932
- post_status: model.get('status')
933
- };
934
-
935
- // This can be refactored once we have the status stored in each revision
936
- const revisionOptions = {
937
- forceRevision: options.save_revision,
938
- isPublished: newStatus === 'published',
939
- newStatus,
940
- olderStatus
941
- };
942
- const newRevisions = await postRevisions.getRevisions(current, revisions, revisionOptions);
943
- model.set('post_revisions', newRevisions);
944
- });
945
- }
900
+ // This can be refactored once we have the status stored in each revision
901
+ const revisionOptions = {
902
+ forceRevision: options.save_revision,
903
+ isPublished: newStatus === 'published',
904
+ newStatus,
905
+ olderStatus
906
+ };
907
+ const newRevisions = await postRevisions.getRevisions(current, revisions, revisionOptions);
908
+ model.set('post_revisions', newRevisions);
909
+ });
946
910
  }
947
911
 
948
912
  if (this.get('tiers')) {
@@ -5,7 +5,6 @@ const path = require('path');
5
5
  * @TODO: pass these in as dependencies
6
6
  */
7
7
  const {PostRevisions} = require('@tryghost/post-revisions');
8
- const labs = require('../../shared/labs');
9
8
 
10
9
  /**
11
10
  * @typedef {Object} IdbBackup
@@ -156,15 +155,13 @@ class Users {
156
155
  return this.models.Base.transaction(async (t) => {
157
156
  frameOptions.transacting = t;
158
157
 
159
- if (labs.isSet('postHistory')) {
160
- const postRevisions = new PostRevisions({
161
- model: this.models.PostRevision
162
- });
158
+ const postRevisions = new PostRevisions({
159
+ model: this.models.PostRevision
160
+ });
163
161
 
164
- await postRevisions.removeAuthorFromRevisions(frameOptions.id, {
165
- transacting: frameOptions.transacting
166
- });
167
- }
162
+ await postRevisions.removeAuthorFromRevisions(frameOptions.id, {
163
+ transacting: frameOptions.transacting
164
+ });
168
165
 
169
166
  await this.assignTagToUserPosts({
170
167
  id: frameOptions.id,
@@ -0,0 +1,23 @@
1
+ class PostsDataRepositoryBookshelf {
2
+ Post;
3
+
4
+ /**
5
+ * @param {Object} deps
6
+ * @param {import('../../models/post')} deps.Post
7
+ */
8
+ constructor(deps) {
9
+ this.Post = deps.Post;
10
+ }
11
+
12
+ /**
13
+ * @param {string[]} ids
14
+ * @returns {Promise<import('../../models/post')>}
15
+ **/
16
+ async getBulk(ids) {
17
+ return await this.Post.fetchAll({
18
+ filter: `id:[${ids.join(',')}]`
19
+ });
20
+ }
21
+ }
22
+
23
+ module.exports = PostsDataRepositoryBookshelf;
@@ -1,20 +1,26 @@
1
- const {CollectionsService, CollectionsRepositoryInMemory} = require('@tryghost/collections');
1
+ const {
2
+ CollectionsService,
3
+ CollectionsRepositoryInMemory
4
+ } = require('@tryghost/collections');
2
5
 
3
6
  class CollectionsServiceWrapper {
4
7
  api;
5
8
 
6
9
  constructor() {
7
- const inMemoryCollectionsRepository = new CollectionsRepositoryInMemory();
10
+ const collectionsRepositoryInMemory = new CollectionsRepositoryInMemory();
11
+
8
12
  const collectionsService = new CollectionsService({
9
- repository: inMemoryCollectionsRepository
13
+ collectionsRepository: collectionsRepositoryInMemory
10
14
  });
11
15
 
12
16
  this.api = {
13
17
  browse: collectionsService.getAll.bind(collectionsService),
14
18
  read: collectionsService.getById.bind(collectionsService),
15
- add: collectionsService.save.bind(collectionsService),
19
+ add: collectionsService.createCollection.bind(collectionsService),
16
20
  edit: collectionsService.edit.bind(collectionsService),
17
- destroy: collectionsService.destroy.bind(collectionsService)
21
+ addPost: collectionsService.addPostToCollection.bind(collectionsService),
22
+ destroy: collectionsService.destroy.bind(collectionsService),
23
+ destroyCollectionPost: collectionsService.removePostFromCollection.bind(collectionsService)
18
24
  };
19
25
  }
20
26
  }
@@ -24,6 +24,8 @@ module.exports = function apiRoutes() {
24
24
  router.post('/collections', mw.authAdminApi, labs.enabledMiddleware('collections'), http(api.collections.add));
25
25
  router.put('/collections/:id', mw.authAdminApi, labs.enabledMiddleware('collections'), http(api.collections.edit));
26
26
  router.del('/collections/:id', mw.authAdminApi, labs.enabledMiddleware('collections'), http(api.collections.destroy));
27
+ router.post('/collections/:id/posts', mw.authAdminApi, labs.enabledMiddleware('collections'), http(api.collections.addPost));
28
+ router.del('/collections/:id/posts/:post_id', mw.authAdminApi, labs.enabledMiddleware('collections'), http(api.collections.destroyPost));
27
29
 
28
30
  // ## Configuration
29
31
  router.get('/config', mw.authAdminApi, http(api.config.read));
@@ -176,7 +176,7 @@
176
176
  },
177
177
  "portal": {
178
178
  "url": "https://cdn.jsdelivr.net/ghost/portal@~{version}/umd/portal.min.js",
179
- "version": "2.32"
179
+ "version": "2.33"
180
180
  },
181
181
  "sodoSearch": {
182
182
  "url": "https://cdn.jsdelivr.net/ghost/sodo-search@~{version}/umd/sodo-search.min.js",