ghost 5.80.1 → 5.80.3

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 (191) hide show
  1. package/components/tryghost-adapter-cache-memory-ttl-5.80.3.tgz +0 -0
  2. package/components/{tryghost-adapter-cache-redis-5.80.1.tgz → tryghost-adapter-cache-redis-5.80.3.tgz} +0 -0
  3. package/components/{tryghost-adapter-manager-5.80.1.tgz → tryghost-adapter-manager-5.80.3.tgz} +0 -0
  4. package/components/tryghost-announcement-bar-settings-5.80.3.tgz +0 -0
  5. package/components/{tryghost-api-framework-5.80.1.tgz → tryghost-api-framework-5.80.3.tgz} +0 -0
  6. package/components/{tryghost-api-version-compatibility-service-5.80.1.tgz → tryghost-api-version-compatibility-service-5.80.3.tgz} +0 -0
  7. package/components/tryghost-audience-feedback-5.80.3.tgz +0 -0
  8. package/components/{tryghost-bookshelf-repository-5.80.1.tgz → tryghost-bookshelf-repository-5.80.3.tgz} +0 -0
  9. package/components/{tryghost-bootstrap-socket-5.80.1.tgz → tryghost-bootstrap-socket-5.80.3.tgz} +0 -0
  10. package/components/tryghost-collections-5.80.3.tgz +0 -0
  11. package/components/{tryghost-constants-5.80.1.tgz → tryghost-constants-5.80.3.tgz} +0 -0
  12. package/components/tryghost-custom-theme-settings-service-5.80.3.tgz +0 -0
  13. package/components/{tryghost-data-generator-5.80.1.tgz → tryghost-data-generator-5.80.3.tgz} +0 -0
  14. package/components/tryghost-domain-events-5.80.3.tgz +0 -0
  15. package/components/tryghost-donations-5.80.3.tgz +0 -0
  16. package/components/tryghost-dynamic-routing-events-5.80.3.tgz +0 -0
  17. package/components/tryghost-email-addresses-5.80.3.tgz +0 -0
  18. package/components/tryghost-email-analytics-provider-mailgun-5.80.3.tgz +0 -0
  19. package/components/tryghost-email-analytics-service-5.80.3.tgz +0 -0
  20. package/components/tryghost-email-content-generator-5.80.3.tgz +0 -0
  21. package/components/{tryghost-email-events-5.80.1.tgz → tryghost-email-events-5.80.3.tgz} +0 -0
  22. package/components/tryghost-email-service-5.80.3.tgz +0 -0
  23. package/components/tryghost-email-suppression-list-5.80.3.tgz +0 -0
  24. package/components/{tryghost-express-dynamic-redirects-5.80.1.tgz → tryghost-express-dynamic-redirects-5.80.3.tgz} +0 -0
  25. package/components/tryghost-external-media-inliner-5.80.3.tgz +0 -0
  26. package/components/tryghost-extract-api-key-5.80.3.tgz +0 -0
  27. package/components/tryghost-ghost-5.80.3.tgz +0 -0
  28. package/components/{tryghost-html-to-plaintext-5.80.1.tgz → tryghost-html-to-plaintext-5.80.3.tgz} +0 -0
  29. package/components/tryghost-i18n-5.80.3.tgz +0 -0
  30. package/components/tryghost-importer-handler-content-files-5.80.3.tgz +0 -0
  31. package/components/{tryghost-importer-revue-5.80.1.tgz → tryghost-importer-revue-5.80.3.tgz} +0 -0
  32. package/components/tryghost-in-memory-repository-5.80.3.tgz +0 -0
  33. package/components/tryghost-job-manager-5.80.3.tgz +0 -0
  34. package/components/tryghost-link-redirects-5.80.3.tgz +0 -0
  35. package/components/tryghost-link-replacer-5.80.3.tgz +0 -0
  36. package/components/tryghost-link-tracking-5.80.3.tgz +0 -0
  37. package/components/tryghost-magic-link-5.80.3.tgz +0 -0
  38. package/components/tryghost-mail-events-5.80.3.tgz +0 -0
  39. package/components/tryghost-mailgun-client-5.80.3.tgz +0 -0
  40. package/components/tryghost-member-attribution-5.80.3.tgz +0 -0
  41. package/components/{tryghost-member-events-5.80.1.tgz → tryghost-member-events-5.80.3.tgz} +0 -0
  42. package/components/tryghost-members-api-5.80.3.tgz +0 -0
  43. package/components/tryghost-members-csv-5.80.3.tgz +0 -0
  44. package/components/{tryghost-members-events-service-5.80.1.tgz → tryghost-members-events-service-5.80.3.tgz} +0 -0
  45. package/components/tryghost-members-importer-5.80.3.tgz +0 -0
  46. package/components/{tryghost-members-offers-5.80.1.tgz → tryghost-members-offers-5.80.3.tgz} +0 -0
  47. package/components/tryghost-members-payments-5.80.3.tgz +0 -0
  48. package/components/tryghost-members-ssr-5.80.3.tgz +0 -0
  49. package/components/{tryghost-members-stripe-service-5.80.1.tgz → tryghost-members-stripe-service-5.80.3.tgz} +0 -0
  50. package/components/tryghost-mentions-email-report-5.80.3.tgz +0 -0
  51. package/components/tryghost-milestones-5.80.3.tgz +0 -0
  52. package/components/tryghost-minifier-5.80.3.tgz +0 -0
  53. package/components/{tryghost-model-to-domain-event-interceptor-5.80.1.tgz → tryghost-model-to-domain-event-interceptor-5.80.3.tgz} +0 -0
  54. package/components/tryghost-mw-api-version-mismatch-5.80.3.tgz +0 -0
  55. package/components/tryghost-mw-cache-control-5.80.3.tgz +0 -0
  56. package/components/{tryghost-mw-error-handler-5.80.1.tgz → tryghost-mw-error-handler-5.80.3.tgz} +0 -0
  57. package/components/{tryghost-mw-session-from-token-5.80.1.tgz → tryghost-mw-session-from-token-5.80.3.tgz} +0 -0
  58. package/components/{tryghost-mw-update-user-last-seen-5.80.1.tgz → tryghost-mw-update-user-last-seen-5.80.3.tgz} +0 -0
  59. package/components/tryghost-mw-version-match-5.80.3.tgz +0 -0
  60. package/components/tryghost-mw-vhost-5.80.3.tgz +0 -0
  61. package/components/tryghost-nql-filter-expansions-5.80.3.tgz +0 -0
  62. package/components/tryghost-oembed-service-5.80.3.tgz +0 -0
  63. package/components/tryghost-package-json-5.80.3.tgz +0 -0
  64. package/components/{tryghost-post-events-5.80.1.tgz → tryghost-post-events-5.80.3.tgz} +0 -0
  65. package/components/tryghost-post-revisions-5.80.3.tgz +0 -0
  66. package/components/tryghost-posts-service-5.80.3.tgz +0 -0
  67. package/components/tryghost-recommendations-5.80.3.tgz +0 -0
  68. package/components/tryghost-referrers-5.80.3.tgz +0 -0
  69. package/components/{tryghost-security-5.80.1.tgz → tryghost-security-5.80.3.tgz} +0 -0
  70. package/components/tryghost-session-service-5.80.3.tgz +0 -0
  71. package/components/tryghost-settings-path-manager-5.80.3.tgz +0 -0
  72. package/components/tryghost-slack-notifications-5.80.3.tgz +0 -0
  73. package/components/{tryghost-staff-service-5.80.1.tgz → tryghost-staff-service-5.80.3.tgz} +0 -0
  74. package/components/{tryghost-stats-service-5.80.1.tgz → tryghost-stats-service-5.80.3.tgz} +0 -0
  75. package/components/tryghost-tiers-5.80.3.tgz +0 -0
  76. package/components/{tryghost-update-check-service-5.80.1.tgz → tryghost-update-check-service-5.80.3.tgz} +0 -0
  77. package/components/tryghost-verification-trigger-5.80.3.tgz +0 -0
  78. package/components/{tryghost-version-notifications-data-service-5.80.1.tgz → tryghost-version-notifications-data-service-5.80.3.tgz} +0 -0
  79. package/components/tryghost-webmentions-5.80.3.tgz +0 -0
  80. package/content/themes/casper/assets/built/screen.css +1 -1
  81. package/content/themes/casper/assets/built/screen.css.map +1 -1
  82. package/content/themes/casper/assets/css/screen.css +4 -0
  83. package/content/themes/casper/default.hbs +3 -3
  84. package/content/themes/casper/package.json +1 -1
  85. package/content/themes/casper/partials/post-card.hbs +1 -1
  86. package/content/themes/casper/post.hbs +3 -3
  87. package/content/themes/source/assets/built/screen.css +1 -1
  88. package/content/themes/source/assets/built/screen.css.map +1 -1
  89. package/content/themes/source/assets/built/source.js +1 -1
  90. package/content/themes/source/assets/built/source.js.map +1 -1
  91. package/content/themes/source/assets/css/screen.css +80 -33
  92. package/content/themes/source/assets/js/{casper.js → main.js} +14 -0
  93. package/content/themes/source/package.json +16 -1
  94. package/content/themes/source/partials/components/cta.hbs +1 -1
  95. package/content/themes/source/partials/components/footer.hbs +2 -2
  96. package/content/themes/source/partials/components/header-content.hbs +2 -2
  97. package/content/themes/source/partials/components/navigation.hbs +1 -1
  98. package/content/themes/source/partials/email-subscription.hbs +2 -2
  99. package/content/themes/source/partials/icons/lock.hbs +1 -5
  100. package/content/themes/source/partials/post-card.hbs +13 -3
  101. package/content/themes/source/post.hbs +18 -14
  102. package/core/boot.js +27 -0
  103. package/core/built/admin/assets/admin-x-demo/admin-x-demo.js +1 -1
  104. package/core/built/admin/assets/admin-x-demo/{index-0722d3aa.mjs → index-771f4964.mjs} +2 -2
  105. package/core/built/admin/assets/admin-x-demo/{modals-969dbbd3.mjs → modals-4c390700.mjs} +46 -46
  106. package/core/built/admin/assets/admin-x-settings/{CodeEditorView-cd254a7a.mjs → CodeEditorView-00610c2f.mjs} +2 -2
  107. package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +2 -2
  108. package/core/built/admin/assets/admin-x-settings/{index-b52632c4.mjs → index-2deb7a1f.mjs} +4273 -4908
  109. package/core/built/admin/assets/admin-x-settings/{index-613b352d.mjs → index-e308aac8.mjs} +2859 -2831
  110. package/core/built/admin/assets/admin-x-settings/{modals-99dbacc0.mjs → modals-e2ca767c.mjs} +13267 -10619
  111. package/core/built/admin/assets/{chunk.524.eecfc0cb2091306f132c.js → chunk.524.c6ed93ff44a9cb49235c.js} +6 -6
  112. package/core/built/admin/assets/{chunk.582.e04c74f002928b557602.js → chunk.582.4e31037f1eb4c88f017f.js} +4 -4
  113. package/core/built/admin/assets/{chunk.763.6b160e403073ecabbfa6.js → chunk.763.7849440ec6494d2449e9.js} +997 -1197
  114. package/core/built/admin/assets/{ghost-ea7a51891dfca9b7a04aacfffe7dea4e.js → ghost-594a7dd26bdb4fec210b285cab5555cb.js} +14 -14
  115. package/core/built/admin/assets/ghost-71cfcdf9410af9b3aec11a28f9a4130f.css +1 -0
  116. package/core/built/admin/assets/ghost-dark-1e5bec737be037b1b5cb2a423603271d.css +1 -0
  117. package/core/built/admin/assets/{vendor-6b83da0c6e6fede335947219c59e1543.js → vendor-43a631b7c834235c4ff0b2186b5ca27d.js} +7 -9
  118. package/core/built/admin/index.html +6 -6
  119. package/core/frontend/helpers/get.js +89 -2
  120. package/core/frontend/public/robots.txt +0 -1
  121. package/core/frontend/services/rendering/renderer.js +19 -1
  122. package/core/frontend/services/theme-engine/i18n/I18n.js +7 -6
  123. package/core/frontend/services/theme-engine/i18n/ThemeI18n.js +4 -3
  124. package/core/server/adapters/storage/LocalStorageBase.js +13 -1
  125. package/core/server/api/endpoints/images.js +14 -3
  126. package/core/server/api/endpoints/utils/serializers/input/tiers.js +30 -2
  127. package/core/server/services/auth/api-key/admin.js +92 -90
  128. package/core/server/services/members/service.js +3 -1
  129. package/core/server/services/slack-notifications/service.js +6 -3
  130. package/core/server/services/themes/installer.js +1 -1
  131. package/core/server/services/tiers/TierRepository.js +2 -1
  132. package/core/server/web/admin/app.js +18 -1
  133. package/core/server/web/api/endpoints/admin/app.js +10 -0
  134. package/core/shared/labs.js +1 -0
  135. package/package.json +152 -150
  136. package/yarn.lock +532 -324
  137. package/components/tryghost-adapter-cache-memory-ttl-5.80.1.tgz +0 -0
  138. package/components/tryghost-announcement-bar-settings-5.80.1.tgz +0 -0
  139. package/components/tryghost-audience-feedback-5.80.1.tgz +0 -0
  140. package/components/tryghost-collections-5.80.1.tgz +0 -0
  141. package/components/tryghost-custom-theme-settings-service-5.80.1.tgz +0 -0
  142. package/components/tryghost-domain-events-5.80.1.tgz +0 -0
  143. package/components/tryghost-donations-5.80.1.tgz +0 -0
  144. package/components/tryghost-dynamic-routing-events-5.80.1.tgz +0 -0
  145. package/components/tryghost-email-addresses-5.80.1.tgz +0 -0
  146. package/components/tryghost-email-analytics-provider-mailgun-5.80.1.tgz +0 -0
  147. package/components/tryghost-email-analytics-service-5.80.1.tgz +0 -0
  148. package/components/tryghost-email-content-generator-5.80.1.tgz +0 -0
  149. package/components/tryghost-email-service-5.80.1.tgz +0 -0
  150. package/components/tryghost-email-suppression-list-5.80.1.tgz +0 -0
  151. package/components/tryghost-external-media-inliner-5.80.1.tgz +0 -0
  152. package/components/tryghost-extract-api-key-5.80.1.tgz +0 -0
  153. package/components/tryghost-i18n-5.80.1.tgz +0 -0
  154. package/components/tryghost-importer-handler-content-files-5.80.1.tgz +0 -0
  155. package/components/tryghost-in-memory-repository-5.80.1.tgz +0 -0
  156. package/components/tryghost-job-manager-5.80.1.tgz +0 -0
  157. package/components/tryghost-link-redirects-5.80.1.tgz +0 -0
  158. package/components/tryghost-link-replacer-5.80.1.tgz +0 -0
  159. package/components/tryghost-link-tracking-5.80.1.tgz +0 -0
  160. package/components/tryghost-magic-link-5.80.1.tgz +0 -0
  161. package/components/tryghost-mail-events-5.80.1.tgz +0 -0
  162. package/components/tryghost-mailgun-client-5.80.1.tgz +0 -0
  163. package/components/tryghost-member-attribution-5.80.1.tgz +0 -0
  164. package/components/tryghost-members-api-5.80.1.tgz +0 -0
  165. package/components/tryghost-members-csv-5.80.1.tgz +0 -0
  166. package/components/tryghost-members-importer-5.80.1.tgz +0 -0
  167. package/components/tryghost-members-payments-5.80.1.tgz +0 -0
  168. package/components/tryghost-members-ssr-5.80.1.tgz +0 -0
  169. package/components/tryghost-mentions-email-report-5.80.1.tgz +0 -0
  170. package/components/tryghost-milestones-5.80.1.tgz +0 -0
  171. package/components/tryghost-minifier-5.80.1.tgz +0 -0
  172. package/components/tryghost-mw-api-version-mismatch-5.80.1.tgz +0 -0
  173. package/components/tryghost-mw-cache-control-5.80.1.tgz +0 -0
  174. package/components/tryghost-mw-version-match-5.80.1.tgz +0 -0
  175. package/components/tryghost-mw-vhost-5.80.1.tgz +0 -0
  176. package/components/tryghost-nql-filter-expansions-5.80.1.tgz +0 -0
  177. package/components/tryghost-oembed-service-5.80.1.tgz +0 -0
  178. package/components/tryghost-package-json-5.80.1.tgz +0 -0
  179. package/components/tryghost-post-revisions-5.80.1.tgz +0 -0
  180. package/components/tryghost-posts-service-5.80.1.tgz +0 -0
  181. package/components/tryghost-recommendations-5.80.1.tgz +0 -0
  182. package/components/tryghost-referrers-5.80.1.tgz +0 -0
  183. package/components/tryghost-session-service-5.80.1.tgz +0 -0
  184. package/components/tryghost-settings-path-manager-5.80.1.tgz +0 -0
  185. package/components/tryghost-slack-notifications-5.80.1.tgz +0 -0
  186. package/components/tryghost-tiers-5.80.1.tgz +0 -0
  187. package/components/tryghost-verification-trigger-5.80.1.tgz +0 -0
  188. package/components/tryghost-webmentions-5.80.1.tgz +0 -0
  189. package/core/built/admin/assets/ghost-40f01556960b49381176bbfa19a89c9a.css +0 -1
  190. package/core/built/admin/assets/ghost-dark-a86f0499bf2697104213d035da3a3b4d.css +0 -1
  191. /package/core/built/admin/assets/{chunk.763.6b160e403073ecabbfa6.js.LICENSE.txt → chunk.763.7849440ec6494d2449e9.js.LICENSE.txt} +0 -0
@@ -2478,10 +2478,8 @@ var e=this.handle
2478
2478
  return this.handle+=3,e}finishMalloc(e,t){this.table[e+1]=l(t,0)}size(){return this.offset}getaddr(e){return this.table[e]}gethandle(e){this.table.push(e,l(0,3),0)
2479
2479
  var t=this.handle
2480
2480
  return this.handle+=3,t}sizeof(e){return f(this.table,e)}scopesizeof(e){return m(this.table,e)}free(e){var t=this.table[e+1]
2481
- this.table[e+1]=u(t,1)}compact(){for(var e=0,{table:t,table:{length:r},heap:n}=this,i=0;i<r;i+=3){var o=t[i],s=t[i+1],a=s&Size.SIZE_MASK,l=0&s
2482
- if(2!==l)if(1===l)t[i+1]=u(s,2),e+=a
2483
- else if(0===l){for(var c=o;c<=i+a;c++)n[c-e]=n[c]
2484
- t[i]=o-e}else 3===l&&(t[i]=o-e)}this.offset=this.offset-e}pushPlaceholder(e){this.sizeCheck()
2481
+ this.table[e+1]=u(t,1)}compact(){for(var e=0,{table:t,table:{length:r},heap:n}=this,i=0;i<r;i+=3){for(var o=t[i],s=t[i+1],a=s&Size.SIZE_MASK,l=o;l<=i+a;l++)n[l-e]=n[l]
2482
+ t[i]=o-e}this.offset=this.offset-e}pushPlaceholder(e){this.sizeCheck()
2485
2483
  var t=this.offset++
2486
2484
  this.heap[t]=2147483647,this.placeholders.push([t,e])}pushStdlib(e){this.sizeCheck()
2487
2485
  var t=this.offset++
@@ -2645,7 +2643,7 @@ return this.slots[e]}set(e,t){if(e>=this.slots.length)throw new RangeError(`BUG:
2645
2643
  this.slots[e]=t}}e.PartialScopeImpl=ge
2646
2644
  var be=new class{constructor(){this.evaluateOpcode=(0,t.fillNulls)(104).slice()}add(e,t,r="syscall"){this.evaluateOpcode[e]={syscall:"machine"!==r,evaluate:t}}debugBefore(e,t){return{sp:undefined,pc:e.fetchValue(i.$pc),name:undefined,params:undefined,type:t.type,isMachine:t.isMachine,size:t.size,state:void 0}}debugAfter(e,t){}evaluate(e,t,r){var n=this.evaluateOpcode[r]
2647
2645
  n.syscall?n.evaluate(e,t):n.evaluate(e[l],t)}}
2648
- class ve{constructor(){(0,t.initializeGuid)(this)}}class ye extends ve{}function _e(e){return"function"!=typeof e.toString?"":String(e)}function we(e){return e===n.UNDEFINED_REFERENCE}function Ee(e){return 0|(e.dynamicLayout?1:0)|(e.dynamicTag?2:0)|(e.prepareArgs?4:0)|(e.createArgs?8:0)|(e.attributeHook?16:0)|(e.elementHook?32:0)|(e.dynamicScope?64:0)|(e.createCaller?128:0)|(e.updateHook?256:0)|(e.createInstance?512:0)|(e.wrapped?1024:0)|(e.willDestroy?2048:0)}function xe(e,t,r){return!!(t&r)}function ke(e,t){return!!(e&t)}be.add(16,((e,{op1:t})=>{var r=e.stack,n=e.runtime.resolver.resolve(t)(r.popJs(),e)
2646
+ class ve{constructor(){(0,t.initializeGuid)(this)}}class ye extends ve{}function _e(e){return"function"!=typeof e.toString?"":String(e)}function we(e){return e===n.UNDEFINED_REFERENCE}function Ee(e){return(e.dynamicLayout?1:0)|(e.dynamicTag?2:0)|(e.prepareArgs?4:0)|(e.createArgs?8:0)|(e.attributeHook?16:0)|(e.elementHook?32:0)|(e.dynamicScope?64:0)|(e.createCaller?128:0)|(e.updateHook?256:0)|(e.createInstance?512:0)|(e.wrapped?1024:0)|(e.willDestroy?2048:0)}function xe(e,t,r){return!!(t&r)}function ke(e,t){return!!(e&t)}be.add(16,((e,{op1:t})=>{var r=e.stack,n=e.runtime.resolver.resolve(t)(r.popJs(),e)
2649
2647
  e.loadValue(i.$v0,n)})),be.add(21,((e,{op1:t})=>{var r=e.referenceForSymbol(t)
2650
2648
  e.stack.pushJs(r)})),be.add(19,((e,{op1:t})=>{var r=e.stack.pop()
2651
2649
  e.scope().bindSymbol(t,r)})),be.add(20,((e,{op1:t})=>{var r=e.stack.popJs(),n=e.stack.popJs(),i=e.stack.popJs()
@@ -3382,7 +3380,7 @@ return C.ENCODE_AND_DECODE_PATH_SEGMENTS?h(r):r},y[2]=function(e,t){return g(t,e
3382
3380
  var _=Object.freeze({}),w=Object.freeze([])
3383
3381
  function E(e,t,r){t.length>0&&47===t.charCodeAt(0)&&(t=t.substr(1))
3384
3382
  for(var n=t.split("/"),i=void 0,o=void 0,s=0;s<n.length;s++){var a,l=n[s],u=0
3385
- 12&(a=2<<(u=""===l?4:58===l.charCodeAt(0)?1:42===l.charCodeAt(0)?2:0))&&(l=l.slice(1),(i=i||[]).push(l),(o=o||[]).push(0!=(4&a))),14&a&&r[u]++,e.push({type:u,value:c(l)})}return{names:i||w,shouldDecodes:o||w}}function x(e,t,r){return e.char===t&&e.negate===r}var k=function(e,t,r,n,i){this.states=e,this.id=t,this.char=r,this.negate=n,this.nextStates=i?t:null,this.pattern="",this._regex=void 0,this.handlers=void 0,this.types=void 0}
3383
+ 12&(a=2<<(u=""===l?4:58===l.charCodeAt(0)?1:42===l.charCodeAt(0)?2:0))&&(l=l.slice(1),(i=i||[]).push(l),(o=o||[]).push(!!(4&a))),14&a&&r[u]++,e.push({type:u,value:c(l)})}return{names:i||w,shouldDecodes:o||w}}function x(e,t,r){return e.char===t&&e.negate===r}var k=function(e,t,r,n,i){this.states=e,this.id=t,this.char=r,this.negate=n,this.nextStates=i?t:null,this.pattern="",this._regex=void 0,this.handlers=void 0,this.types=void 0}
3386
3384
  function O(e,t){return e.negate?e.char!==t&&-1!==e.char:e.char===t||-1===e.char}function P(e,t){for(var r=[],n=0,i=e.length;n<i;n++){var o=e[n]
3387
3385
  r=r.concat(o.match(t))}return r}k.prototype.regex=function(){return this._regex||(this._regex=new RegExp(this.pattern)),this._regex},k.prototype.get=function(e,t){var r=this.nextStates
3388
3386
  if(null!==r)if(f(r))for(var n=0;n<r.length;n++){var i=this.states[r[n]]
@@ -3736,7 +3734,7 @@ case 3:return[s,a,n]
3736
3734
  case 4:return[l,s,n]
3737
3735
  case 5:return[n,s,a]}},i.hsv.hsl=function(e){var t,r,n,i=e[0],o=e[1]/100,s=e[2]/100,a=Math.max(s,.01)
3738
3736
  return n=(2-o)*s,r=o*a,[i,100*(r=(r/=(t=(2-o)*a)<=1?t:2-t)||0),100*(n/=2)]},i.hwb.rgb=function(e){var t,r,n,i,o,s,a,l=e[0]/360,u=e[1]/100,c=e[2]/100,d=u+c
3739
- switch(d>1&&(u/=d,c/=d),n=6*l-(t=Math.floor(6*l)),0!=(1&t)&&(n=1-n),i=u+n*((r=1-c)-u),t){default:case 6:case 0:o=r,s=i,a=u
3737
+ switch(d>1&&(u/=d,c/=d),n=6*l-(t=Math.floor(6*l)),1&t&&(n=1-n),i=u+n*((r=1-c)-u),t){default:case 6:case 0:o=r,s=i,a=u
3740
3738
  break
3741
3739
  case 1:o=i,s=r,a=u
3742
3740
  break
@@ -5188,7 +5186,7 @@ if(Array.isArray(t))for(var i=0;i<t.length;i++)t[i]=e(t[i],r)
5188
5186
  else if("object"===n(t))for(var o in t)t.hasOwnProperty(o)&&(t[o]=e(t[o],r))
5189
5187
  return t}(e.data,t),e.attachments=void 0,e}},function(e,t){function r(e){e=e||{},this.ms=e.min||100,this.max=e.max||1e4,this.factor=e.factor||2,this.jitter=e.jitter>0&&e.jitter<=1?e.jitter:0,this.attempts=0}e.exports=r,r.prototype.duration=function(){var e=this.ms*Math.pow(this.factor,this.attempts++)
5190
5188
  if(this.jitter){var t=Math.random(),r=Math.floor(t*this.jitter*e)
5191
- e=0==(1&Math.floor(10*t))?e-r:e+r}return 0|Math.min(e,this.max)},r.prototype.reset=function(){this.attempts=0},r.prototype.setMin=function(e){this.ms=e},r.prototype.setMax=function(e){this.max=e},r.prototype.setJitter=function(e){this.jitter=e}}])})),"undefined"==typeof FastBoot&&(/*! VelocityJS.org (1.5.2). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License */
5189
+ e=1&Math.floor(10*t)?e+r:e-r}return 0|Math.min(e,this.max)},r.prototype.reset=function(){this.attempts=0},r.prototype.setMin=function(e){this.ms=e},r.prototype.setMax=function(e){this.max=e},r.prototype.setJitter=function(e){this.jitter=e}}])})),"undefined"==typeof FastBoot&&(/*! VelocityJS.org (1.5.2). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License */
5192
5190
  /*! VelocityJS.org jQuery Shim (1.0.1). (C) 2014 The jQuery Foundation. MIT @license: en.wikipedia.org/wiki/MIT_License. */
5193
5191
  function(e){"use strict"
5194
5192
  if(!e.jQuery){var t=function(e,r){return new t.fn.init(e,r)}
@@ -9914,4 +9912,4 @@ e.default=class{constructor(e){if(this._data=new t.default,e)for(let t=0;t<e.len
9914
9912
  return this}get(e){let t=this._data[e]
9915
9913
  return t===r.UNDEFINED_KEY?void 0:t}set(e,t){return this._data[e]=t,this}delete(e){return this._data[e]=r.UNDEFINED_KEY,!0}}}))
9916
9914
 
9917
- //# sourceMappingURL=vendor-0462eb4577b6a717a7cadbacd0d3b276.map
9915
+ //# sourceMappingURL=vendor-d101e8f704a5e36b553c9b65b75cd58d.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%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%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.80%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%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%22c1a8c8a94f%22%2C%22adminXDemoFilename%22%3A%22admin-x-demo.js%22%2C%22adminXDemoHash%22%3A%22d3a1c163cf%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%221c1d39191e%22%7D" />
11
+ <meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%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.80%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%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%22c1a8c8a94f%22%2C%22adminXDemoFilename%22%3A%22admin-x-demo.js%22%2C%22adminXDemoHash%22%3A%2224dcc6aee2%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%2233f4aa4a54%22%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-0ede59da8efb5e28fa929557f7ff7154.css">
40
- <link integrity="" rel="stylesheet" href="assets/ghost-40f01556960b49381176bbfa19a89c9a.css" title="light">
40
+ <link integrity="" rel="stylesheet" href="assets/ghost-71cfcdf9410af9b3aec11a28f9a4130f.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-6b83da0c6e6fede335947219c59e1543.js"></script>
60
- <script src="assets/chunk.763.6b160e403073ecabbfa6.js"></script>
61
- <script src="assets/chunk.524.eecfc0cb2091306f132c.js"></script>
62
- <script src="assets/ghost-ea7a51891dfca9b7a04aacfffe7dea4e.js"></script>
59
+ <script src="assets/vendor-43a631b7c834235c4ff0b2186b5ca27d.js"></script>
60
+ <script src="assets/chunk.763.7849440ec6494d2449e9.js"></script>
61
+ <script src="assets/chunk.524.c6ed93ff44a9cb49235c.js"></script>
62
+ <script src="assets/ghost-594a7dd26bdb4fec210b285cab5555cb.js"></script>
63
63
  </body>
64
64
  </html>
@@ -11,6 +11,7 @@ const Sentry = require('@sentry/node');
11
11
 
12
12
  const _ = require('lodash');
13
13
  const jsonpath = require('jsonpath');
14
+ const nqlLang = require('@tryghost/nql-lang');
14
15
 
15
16
  const messages = {
16
17
  mustBeCalledAsBlock: 'The {\\{{helperName}}} helper must be called as a block. E.g. {{#{helperName}}}...{{/{helperName}}}',
@@ -121,6 +122,84 @@ function parseOptions(globals, data, options) {
121
122
  return options;
122
123
  }
123
124
 
125
+ function optimiseFilterCacheability(resource, options) {
126
+ const noOptimisation = {
127
+ options,
128
+ parseResult(result) {
129
+ return result;
130
+ }
131
+ };
132
+ if (resource !== 'posts') {
133
+ return noOptimisation;
134
+ }
135
+
136
+ if (!options.filter) {
137
+ return noOptimisation;
138
+ }
139
+
140
+ try {
141
+ if (options.filter.split('id:-').length !== 2) {
142
+ return noOptimisation;
143
+ }
144
+
145
+ const parsedFilter = nqlLang.parse(options.filter);
146
+ // Support either `id:blah` or `id:blah+other:stuff`
147
+ if (!parsedFilter.$and && !parsedFilter.id) {
148
+ return noOptimisation;
149
+ }
150
+ const queries = parsedFilter.$and || [parsedFilter];
151
+ const query = queries.find((q) => {
152
+ return q?.id?.$ne;
153
+ });
154
+
155
+ if (!query) {
156
+ return noOptimisation;
157
+ }
158
+
159
+ const idToFilter = query.id.$ne;
160
+
161
+ let limit = options.limit;
162
+ if (options.limit !== 'all') {
163
+ limit = options.limit ? 1 + parseInt(options.limit, 10) : 16;
164
+ }
165
+
166
+ // We replace with id:-null so we don't have to deal with leading/trailing AND operators
167
+ const filter = options.filter.replace(/id:-[a-f0-9A-F]{24}/, 'id:-null');
168
+
169
+ const parseResult = function parseResult(result) {
170
+ const filteredPosts = result?.posts?.filter((post) => {
171
+ return post.id !== idToFilter;
172
+ }) || [];
173
+
174
+ const modifiedResult = {
175
+ ...result,
176
+ posts: limit === 'all' ? filteredPosts : filteredPosts.slice(0, limit - 1)
177
+ };
178
+
179
+ modifiedResult.meta = modifiedResult.meta || {};
180
+ modifiedResult.meta.cacheabilityOptimisation = true;
181
+
182
+ if (typeof modifiedResult?.meta?.pagination?.limit === 'number') {
183
+ modifiedResult.meta.pagination.limit = modifiedResult.meta.pagination.limit - 1;
184
+ }
185
+
186
+ return modifiedResult;
187
+ };
188
+
189
+ return {
190
+ options: {
191
+ ...options,
192
+ limit,
193
+ filter
194
+ },
195
+ parseResult
196
+ };
197
+ } catch (err) {
198
+ logging.warn(err);
199
+ return noOptimisation;
200
+ }
201
+ }
202
+
124
203
  /**
125
204
  *
126
205
  * @param {String} resource
@@ -131,6 +210,12 @@ function parseOptions(globals, data, options) {
131
210
  */
132
211
  async function makeAPICall(resource, controllerName, action, apiOptions) {
133
212
  const controller = api[controllerName];
213
+ let makeRequest = options => controller[action](options);
214
+
215
+ const {
216
+ options,
217
+ parseResult
218
+ } = optimiseFilterCacheability(resource, apiOptions);
134
219
 
135
220
  let timer;
136
221
 
@@ -141,7 +226,7 @@ async function makeAPICall(resource, controllerName, action, apiOptions) {
141
226
  const logLevel = config.get('optimization:getHelper:timeout:level') || 'error';
142
227
  const threshold = config.get('optimization:getHelper:timeout:threshold');
143
228
 
144
- const apiResponse = controller[action](apiOptions);
229
+ const apiResponse = makeRequest(options).then(parseResult);
145
230
 
146
231
  const timeout = new Promise((resolve) => {
147
232
  timer = setTimeout(() => {
@@ -161,7 +246,7 @@ async function makeAPICall(resource, controllerName, action, apiOptions) {
161
246
  response = await Promise.race([apiResponse, timeout]);
162
247
  clearTimeout(timer);
163
248
  } else {
164
- response = await controller[action](apiOptions);
249
+ response = await makeRequest(options).then(parseResult);
165
250
  }
166
251
 
167
252
  return response;
@@ -279,3 +364,5 @@ module.exports = async function get(resource, options) {
279
364
  };
280
365
 
281
366
  module.exports.async = true;
367
+
368
+ module.exports.optimiseFilterCacheability = optimiseFilterCacheability;
@@ -1,7 +1,6 @@
1
1
  User-agent: *
2
2
  Sitemap: {{blog-url}}/sitemap.xml
3
3
  Disallow: /ghost/
4
- Disallow: /p/
5
4
  Disallow: /email/
6
5
  Disallow: /r/
7
6
  Disallow: /webmentions/receive/
@@ -1,6 +1,12 @@
1
+ const path = require('path');
1
2
  const debug = require('@tryghost/debug')('services:routing:renderer:renderer');
3
+ const {IncorrectUsageError} = require('@tryghost/errors');
2
4
  const setContext = require('./context');
3
5
  const templates = require('./templates');
6
+ const tpl = require('@tryghost/tpl');
7
+ const messages = {
8
+ couldNotReadFile: 'Could not read file {file}'
9
+ };
4
10
 
5
11
  /**
6
12
  * @description Helper function to finally render the data.
@@ -26,5 +32,17 @@ module.exports = function renderer(req, res, data) {
26
32
  }
27
33
 
28
34
  // Render Call
29
- res.render(res._template, data);
35
+ res.render(res._template, data, function (err, html) {
36
+ if (err) {
37
+ if (err.code === 'ENOENT') {
38
+ return req.next(
39
+ new IncorrectUsageError({
40
+ message: tpl(messages.couldNotReadFile, {file: path.basename(err.path)})
41
+ })
42
+ );
43
+ }
44
+ return req.next(err);
45
+ }
46
+ res.send(html);
47
+ });
30
48
  };
@@ -14,9 +14,9 @@ const get = require('lodash/get');
14
14
  class I18n {
15
15
  /**
16
16
  * @param {object} [options]
17
- * @param {string} basePath - the base path to the translations directory
18
- * @param {string} [locale] - a locale string
19
- * @param {{dot|fulltext}} [stringMode] - which mode our translation keys use
17
+ * @param {string} options.basePath - the base path to the translations directory
18
+ * @param {string} [options.locale] - a locale string
19
+ * @param {string} [options.stringMode] - which mode our translation keys use
20
20
  */
21
21
  constructor(options = {}) {
22
22
  this._basePath = options.basePath || __dirname;
@@ -100,7 +100,7 @@ class I18n {
100
100
  /**
101
101
  * Attempt to load strings from a file
102
102
  *
103
- * @param {sting} [locale]
103
+ * @param {string} [locale]
104
104
  * @returns {object} strings
105
105
  */
106
106
  _loadStrings(locale) {
@@ -110,7 +110,7 @@ class I18n {
110
110
  return this._readTranslationsFile(locale);
111
111
  } catch (err) {
112
112
  if (err.code === 'ENOENT') {
113
- this._handleMissingFileError(locale, err);
113
+ this._handleMissingFileError(locale);
114
114
 
115
115
  if (locale !== this.defaultLocale()) {
116
116
  this._handleFallbackToDefault();
@@ -207,7 +207,7 @@ class I18n {
207
207
  */
208
208
  _readTranslationsFile(locale) {
209
209
  const filePath = path.join(...this._translationFileDirs(), this._translationFileName(locale));
210
- const content = fs.readFileSync(filePath);
210
+ const content = fs.readFileSync(filePath, 'utf8');
211
211
  return JSON.parse(content);
212
212
  }
213
213
 
@@ -276,6 +276,7 @@ class I18n {
276
276
  _handleMissingFileError(locale) {
277
277
  logging.warn(`i18n was unable to find ${locale}.json.`);
278
278
  }
279
+
279
280
  _handleInvalidFileError(locale, err) {
280
281
  logging.error(new errors.IncorrectUsageError({
281
282
  err,
@@ -4,9 +4,9 @@ const I18n = require('./I18n');
4
4
 
5
5
  class ThemeI18n extends I18n {
6
6
  /**
7
- * @param {objec} [options]
8
- * @param {string} basePath - the base path for the translation directory (e.g. where themes live)
9
- * @param {string} [locale] - a locale string
7
+ * @param {object} [options]
8
+ * @param {string} options.basePath - the base path for the translation directory (e.g. where themes live)
9
+ * @param {string} [options.locale] - a locale string
10
10
  */
11
11
  constructor(options = {}) {
12
12
  super(options);
@@ -48,6 +48,7 @@ class ThemeI18n extends I18n {
48
48
  logging.warn(`Theme translations file locales/${locale}.json not found.`);
49
49
  }
50
50
  }
51
+
51
52
  _handleInvalidFileError(locale, err) {
52
53
  logging.error(new errors.IncorrectUsageError({
53
54
  err,
@@ -58,7 +58,15 @@ class LocalStorageBase extends StorageBase {
58
58
  targetFilename = filename;
59
59
  await fs.mkdirs(targetDir);
60
60
 
61
- await fs.copy(file.path, targetFilename);
61
+ try {
62
+ await fs.copy(file.path, targetFilename);
63
+ } catch (err) {
64
+ if (err.code === 'ENAMETOOLONG') {
65
+ throw new errors.BadRequestError({err});
66
+ }
67
+
68
+ throw err;
69
+ }
62
70
 
63
71
  // The src for the image must be in URI format, not a file system path, which in Windows uses \
64
72
  // For local file system storage can use relative path so add a slash
@@ -149,6 +157,10 @@ class LocalStorageBase extends StorageBase {
149
157
  return next(new errors.NoPermissionError({err: err}));
150
158
  }
151
159
 
160
+ if (err.name === 'RangeNotSatisfiableError') {
161
+ return next(new errors.RangeNotSatisfiableError({err}));
162
+ }
163
+
152
164
  return next(new errors.InternalServerError({err: err}));
153
165
  }
154
166
 
@@ -1,8 +1,10 @@
1
1
  /* eslint-disable ghost/ghost-custom/max-api-complexity */
2
- const storage = require('../../adapters/storage');
2
+ const path = require('path');
3
+ const errors = require('@tryghost/errors');
3
4
  const imageTransform = require('@tryghost/image-transform');
5
+
6
+ const storage = require('../../adapters/storage');
4
7
  const config = require('../../../shared/config');
5
- const path = require('path');
6
8
 
7
9
  module.exports = {
8
10
  docName: 'images',
@@ -33,7 +35,16 @@ module.exports = {
33
35
  width: config.get('imageOptimization:defaultMaxWidth')
34
36
  }, imageOptimizationOptions);
35
37
 
36
- await imageTransform.resizeFromPath(options);
38
+ try {
39
+ await imageTransform.resizeFromPath(options);
40
+ } catch (err) {
41
+ // If the image processing fails, we don't want to store the image because it's corrupted/invalid
42
+ throw new errors.BadRequestError({
43
+ message: 'Image processing failed',
44
+ context: err.message,
45
+ help: 'Please verify that the image is valid'
46
+ });
47
+ }
37
48
 
38
49
  // Store the processed/optimized image
39
50
  const processedImageUrl = await store.save({
@@ -1,10 +1,26 @@
1
+ const {BadRequestError} = require('@tryghost/errors');
1
2
  const localUtils = require('../../index');
3
+ const nql = require('@tryghost/nql-lang');
4
+ const tpl = require('@tryghost/tpl');
5
+
6
+ const messages = {
7
+ invalidNQLFilter: 'The NQL filter you passed was invalid.'
8
+ };
2
9
 
3
10
  const forceActiveFilter = (frame) => {
4
11
  if (frame.options.filter) {
5
- frame.options.filter = `(${frame.options.filter})+active:true`;
12
+ frame.options.filter = {
13
+ $and: [
14
+ {
15
+ active: true
16
+ },
17
+ frame.options.filter
18
+ ]
19
+ };
6
20
  } else {
7
- frame.options.filter = 'active:true';
21
+ frame.options.filter = {
22
+ active: true
23
+ };
8
24
  }
9
25
  };
10
26
 
@@ -41,6 +57,18 @@ function convertTierInput(input) {
41
57
 
42
58
  module.exports = {
43
59
  all(_apiConfig, frame) {
60
+ if (frame.options.filter) {
61
+ try {
62
+ frame.options.filter = nql.parse(frame.options.filter);
63
+ } catch (err) {
64
+ throw new BadRequestError({
65
+ message: tpl(messages.invalidNQLFilter)
66
+ });
67
+ }
68
+ } else {
69
+ frame.options.filter = null;
70
+ }
71
+
44
72
  if (localUtils.isContentAPI(frame)) {
45
73
  // CASE: content api can only have active tiers
46
74
  forceActiveFilter(frame);