ghost 5.25.3 → 5.25.5

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 (157) hide show
  1. package/components/tryghost-adapter-manager-5.25.5.tgz +0 -0
  2. package/components/tryghost-api-framework-5.25.5.tgz +0 -0
  3. package/components/{tryghost-api-version-compatibility-service-5.25.3.tgz → tryghost-api-version-compatibility-service-5.25.5.tgz} +0 -0
  4. package/components/tryghost-audience-feedback-5.25.5.tgz +0 -0
  5. package/components/tryghost-bootstrap-socket-5.25.5.tgz +0 -0
  6. package/components/tryghost-constants-5.25.5.tgz +0 -0
  7. package/components/tryghost-custom-theme-settings-service-5.25.5.tgz +0 -0
  8. package/components/{tryghost-data-generator-5.25.3.tgz → tryghost-data-generator-5.25.5.tgz} +0 -0
  9. package/components/tryghost-domain-events-5.25.5.tgz +0 -0
  10. package/components/{tryghost-email-analytics-provider-mailgun-5.25.3.tgz → tryghost-email-analytics-provider-mailgun-5.25.5.tgz} +0 -0
  11. package/components/tryghost-email-analytics-service-5.25.5.tgz +0 -0
  12. package/components/{tryghost-email-content-generator-5.25.3.tgz → tryghost-email-content-generator-5.25.5.tgz} +0 -0
  13. package/components/{tryghost-email-events-5.25.3.tgz → tryghost-email-events-5.25.5.tgz} +0 -0
  14. package/components/tryghost-email-service-5.25.5.tgz +0 -0
  15. package/components/tryghost-email-suppression-list-5.25.5.tgz +0 -0
  16. package/components/tryghost-express-dynamic-redirects-5.25.5.tgz +0 -0
  17. package/components/{tryghost-extract-api-key-5.25.3.tgz → tryghost-extract-api-key-5.25.5.tgz} +0 -0
  18. package/components/tryghost-html-to-plaintext-5.25.5.tgz +0 -0
  19. package/components/tryghost-job-manager-5.25.5.tgz +0 -0
  20. package/components/tryghost-link-redirects-5.25.5.tgz +0 -0
  21. package/components/tryghost-link-replacer-5.25.5.tgz +0 -0
  22. package/components/tryghost-link-tracking-5.25.5.tgz +0 -0
  23. package/components/tryghost-magic-link-5.25.5.tgz +0 -0
  24. package/components/tryghost-mailgun-client-5.25.5.tgz +0 -0
  25. package/components/tryghost-member-attribution-5.25.5.tgz +0 -0
  26. package/components/{tryghost-member-events-5.25.3.tgz → tryghost-member-events-5.25.5.tgz} +0 -0
  27. package/components/{tryghost-members-api-5.25.3.tgz → tryghost-members-api-5.25.5.tgz} +0 -0
  28. package/components/tryghost-members-csv-5.25.5.tgz +0 -0
  29. package/components/tryghost-members-events-service-5.25.5.tgz +0 -0
  30. package/components/{tryghost-members-importer-5.25.3.tgz → tryghost-members-importer-5.25.5.tgz} +0 -0
  31. package/components/tryghost-members-offers-5.25.5.tgz +0 -0
  32. package/components/tryghost-members-payments-5.25.5.tgz +0 -0
  33. package/components/tryghost-members-ssr-5.25.5.tgz +0 -0
  34. package/components/{tryghost-members-stripe-service-5.25.3.tgz → tryghost-members-stripe-service-5.25.5.tgz} +0 -0
  35. package/components/{tryghost-minifier-5.25.3.tgz → tryghost-minifier-5.25.5.tgz} +0 -0
  36. package/components/tryghost-mw-api-version-mismatch-5.25.5.tgz +0 -0
  37. package/components/tryghost-mw-cache-control-5.25.5.tgz +0 -0
  38. package/components/tryghost-mw-error-handler-5.25.5.tgz +0 -0
  39. package/components/tryghost-mw-session-from-token-5.25.5.tgz +0 -0
  40. package/components/tryghost-mw-update-user-last-seen-5.25.5.tgz +0 -0
  41. package/components/tryghost-mw-vhost-5.25.5.tgz +0 -0
  42. package/components/tryghost-oembed-service-5.25.5.tgz +0 -0
  43. package/components/tryghost-package-json-5.25.5.tgz +0 -0
  44. package/components/tryghost-referrers-5.25.5.tgz +0 -0
  45. package/components/tryghost-security-5.25.5.tgz +0 -0
  46. package/components/tryghost-session-service-5.25.5.tgz +0 -0
  47. package/components/tryghost-settings-path-manager-5.25.5.tgz +0 -0
  48. package/components/{tryghost-staff-service-5.25.3.tgz → tryghost-staff-service-5.25.5.tgz} +0 -0
  49. package/components/tryghost-stats-service-5.25.5.tgz +0 -0
  50. package/components/tryghost-tiers-5.25.5.tgz +0 -0
  51. package/components/tryghost-update-check-service-5.25.5.tgz +0 -0
  52. package/components/tryghost-verification-trigger-5.25.5.tgz +0 -0
  53. package/components/tryghost-version-notifications-data-service-5.25.5.tgz +0 -0
  54. package/content/themes/casper/assets/built/casper.js +1 -1
  55. package/content/themes/casper/assets/built/casper.js.map +1 -1
  56. package/content/themes/casper/assets/built/screen.css +1 -1
  57. package/content/themes/casper/assets/built/screen.css.map +1 -1
  58. package/content/themes/casper/assets/css/screen.css +52 -5
  59. package/content/themes/casper/assets/js/dropdown.js +1 -1
  60. package/content/themes/casper/assets/js/infinite-scroll.js +2 -0
  61. package/content/themes/casper/author.hbs +57 -51
  62. package/content/themes/casper/default.hbs +10 -7
  63. package/content/themes/casper/index.hbs +2 -0
  64. package/content/themes/casper/package.json +1 -1
  65. package/content/themes/casper/tag.hbs +3 -0
  66. package/core/built/admin/assets/{chunk.143.37f5727f90df66ade091.js → chunk.143.ce979d0e79756c847be1.js} +20 -20
  67. package/core/built/admin/assets/{chunk.178.fbba40422427964e79c9.js → chunk.178.20fd180216b1dde2c738.js} +4 -4
  68. package/core/built/admin/assets/{chunk.507.f7ed7e0b5ac069083e0c.js → chunk.507.18a4d11e74a0b6e03a69.js} +107 -102
  69. package/core/built/admin/assets/{chunk.613.551c7c3e872b9a811863.js → chunk.613.7e15b585f6a677d191bb.js} +157 -151
  70. package/core/built/admin/assets/{chunk.613.551c7c3e872b9a811863.js.LICENSE.txt → chunk.613.7e15b585f6a677d191bb.js.LICENSE.txt} +0 -0
  71. package/core/built/admin/assets/{ghost-15f77300dbb6762873d6692e0485a37a.js → ghost-04991abb5f64c0b3442a093dbfa55a67.js} +55 -52
  72. package/core/built/admin/assets/img/themes/Alto-0dfe76694ed222d6d96fc9c8db979a38.png +0 -0
  73. package/core/built/admin/assets/img/themes/Bulletin-d66dec818ad0ba2965dd7eb3130c621c.png +0 -0
  74. package/core/built/admin/assets/img/themes/Casper-9a0ce71df3a1c589c1414ad2aa5b8aeb.png +0 -0
  75. package/core/built/admin/assets/img/themes/Dawn-302fbfdbc352098a256137159bd83dd8.png +0 -0
  76. package/core/built/admin/assets/img/themes/Digest-698e78d8e8481daff8ae4a8647528dc9.png +0 -0
  77. package/core/built/admin/assets/img/themes/Dope-d099dfca697adae16baa76f89520c5b3.png +0 -0
  78. package/core/built/admin/assets/img/themes/Ease-7075f809892f10c58892e15a57a4aae4.png +0 -0
  79. package/core/built/admin/assets/img/themes/Edge-1e5e0eec6941d7bdca02cebb66187357.png +0 -0
  80. package/core/built/admin/assets/img/themes/Edition-10111a2b8458168dcff81b7fb151be70.png +0 -0
  81. package/core/built/admin/assets/img/themes/Episode-e4c86d1f75ef1d8a77791d7fd519fdd4.png +0 -0
  82. package/core/built/admin/assets/img/themes/Headline-f70eaf49b9fcae1ddfe3d4496d8be54d.png +0 -0
  83. package/core/built/admin/assets/img/themes/Journal-07d35b2311501d2738bad1907ba2f7e1.png +0 -0
  84. package/core/built/admin/assets/img/themes/London-4e042390da16fecef947f3a7001d03db.png +0 -0
  85. package/core/built/admin/assets/img/themes/Ruby-b896885448e0f28ca62c6dcd56c732aa.png +0 -0
  86. package/core/built/admin/assets/img/themes/Solo-0292eb9ae0ca7b578cff50824d40cc86.png +0 -0
  87. package/core/built/admin/assets/img/themes/Taste-a24d2a786900d9caff7e773ca0040991.png +0 -0
  88. package/core/built/admin/assets/img/themes/Wave-b98fadfd3ed16e8b2e383dd8e8e5dca2.png +0 -0
  89. package/core/built/admin/assets/{vendor-0d29a566ca9747f2cfba9d7c98e39f53.js → vendor-a5908fe1facfc5cd41d8b915a996bfed.js} +5 -4
  90. package/core/built/admin/index.html +4 -4
  91. package/core/frontend/helpers/get.js +67 -16
  92. package/core/server/api/endpoints/db.js +1 -1
  93. package/core/server/api/endpoints/utils/serializers/output/mappers/newsletters.js +1 -0
  94. package/core/server/data/importer/importers/data/data-importer.js +1 -1
  95. package/core/server/services/mega/mega.js +10 -4
  96. package/core/server/services/members/middleware.js +18 -3
  97. package/core/server/services/members-events/index.js +4 -1
  98. package/core/server/services/stripe/service.js +3 -1
  99. package/core/shared/config/defaults.json +14 -6
  100. package/package.json +139 -138
  101. package/yarn.lock +678 -439
  102. package/components/tryghost-adapter-manager-5.25.3.tgz +0 -0
  103. package/components/tryghost-api-framework-5.25.3.tgz +0 -0
  104. package/components/tryghost-audience-feedback-5.25.3.tgz +0 -0
  105. package/components/tryghost-bootstrap-socket-5.25.3.tgz +0 -0
  106. package/components/tryghost-constants-5.25.3.tgz +0 -0
  107. package/components/tryghost-custom-theme-settings-service-5.25.3.tgz +0 -0
  108. package/components/tryghost-domain-events-5.25.3.tgz +0 -0
  109. package/components/tryghost-email-analytics-service-5.25.3.tgz +0 -0
  110. package/components/tryghost-email-service-5.25.3.tgz +0 -0
  111. package/components/tryghost-email-suppression-list-5.25.3.tgz +0 -0
  112. package/components/tryghost-express-dynamic-redirects-5.25.3.tgz +0 -0
  113. package/components/tryghost-html-to-plaintext-5.25.3.tgz +0 -0
  114. package/components/tryghost-job-manager-5.25.3.tgz +0 -0
  115. package/components/tryghost-link-redirects-5.25.3.tgz +0 -0
  116. package/components/tryghost-link-replacer-5.25.3.tgz +0 -0
  117. package/components/tryghost-link-tracking-5.25.3.tgz +0 -0
  118. package/components/tryghost-magic-link-5.25.3.tgz +0 -0
  119. package/components/tryghost-mailgun-client-5.25.3.tgz +0 -0
  120. package/components/tryghost-member-attribution-5.25.3.tgz +0 -0
  121. package/components/tryghost-members-csv-5.25.3.tgz +0 -0
  122. package/components/tryghost-members-events-service-5.25.3.tgz +0 -0
  123. package/components/tryghost-members-offers-5.25.3.tgz +0 -0
  124. package/components/tryghost-members-payments-5.25.3.tgz +0 -0
  125. package/components/tryghost-members-ssr-5.25.3.tgz +0 -0
  126. package/components/tryghost-mw-api-version-mismatch-5.25.3.tgz +0 -0
  127. package/components/tryghost-mw-cache-control-5.25.3.tgz +0 -0
  128. package/components/tryghost-mw-error-handler-5.25.3.tgz +0 -0
  129. package/components/tryghost-mw-session-from-token-5.25.3.tgz +0 -0
  130. package/components/tryghost-mw-update-user-last-seen-5.25.3.tgz +0 -0
  131. package/components/tryghost-mw-vhost-5.25.3.tgz +0 -0
  132. package/components/tryghost-oembed-service-5.25.3.tgz +0 -0
  133. package/components/tryghost-package-json-5.25.3.tgz +0 -0
  134. package/components/tryghost-referrers-5.25.3.tgz +0 -0
  135. package/components/tryghost-security-5.25.3.tgz +0 -0
  136. package/components/tryghost-session-service-5.25.3.tgz +0 -0
  137. package/components/tryghost-settings-path-manager-5.25.3.tgz +0 -0
  138. package/components/tryghost-stats-service-5.25.3.tgz +0 -0
  139. package/components/tryghost-tiers-5.25.3.tgz +0 -0
  140. package/components/tryghost-update-check-service-5.25.3.tgz +0 -0
  141. package/components/tryghost-verification-trigger-5.25.3.tgz +0 -0
  142. package/components/tryghost-version-notifications-data-service-5.25.3.tgz +0 -0
  143. package/core/built/admin/assets/img/themes/Alto-f4db5af43ca9771c7ac1f754de3ddf2f.png +0 -0
  144. package/core/built/admin/assets/img/themes/Bulletin-57d45b992ff0e26e0acdce7ed4cccd67.png +0 -0
  145. package/core/built/admin/assets/img/themes/Casper-19b7267aac5acc6abfaaed7e41eddae8.jpg +0 -0
  146. package/core/built/admin/assets/img/themes/Dawn-be81aa8c8caae8fcfb5d5fbec823fdcc.png +0 -0
  147. package/core/built/admin/assets/img/themes/Digest-d3467ac22a290e1ad3a543014758286e.png +0 -0
  148. package/core/built/admin/assets/img/themes/Dope-6f8e0bbc199ce4af9a60859e9e6a74ad.png +0 -0
  149. package/core/built/admin/assets/img/themes/Ease-9c279ea6cec3c0f1823f81c9dd24b116.png +0 -0
  150. package/core/built/admin/assets/img/themes/Edge-0258906309e11fd075a1d9880aa09b20.png +0 -0
  151. package/core/built/admin/assets/img/themes/Edition-d8f508e93bc24bdf2716ae6f8b3d44f8.png +0 -0
  152. package/core/built/admin/assets/img/themes/Headline-c5070cf549e797a6a72b87237caa1617.jpg +0 -0
  153. package/core/built/admin/assets/img/themes/Journal-accf0031bbae0919900a049061e65a04.png +0 -0
  154. package/core/built/admin/assets/img/themes/London-3f07efcee9e5bfb9a33827064eb77e70.jpg +0 -0
  155. package/core/built/admin/assets/img/themes/Ruby-11a53c62015612f4b3aca8f503121225.png +0 -0
  156. package/core/built/admin/assets/img/themes/Solo-8634b5681d888995e0f5fe8ac1a27ba0.png +0 -0
  157. package/core/built/admin/assets/img/themes/Wave-86e8044c2d76cb57a9030e4c24ac9520.png +0 -0
@@ -12319,8 +12319,9 @@ let e=this.container
12319
12319
  e.dataset.kgHasLinkToolbar=!0,this._addEventListener(e,"mouseover",this._handleMouseover),this._addEventListener(e,"mouseout",this._handleMouseout)}willDestroyElement(){super.willDestroyElement(...arguments),this._removeAllEventListeners()}edit(){let e=this._getLinkRange()
12320
12320
  this.editLink(e,this._targetRect)}remove(){let e=this.editor,t=this._getLinkRange(),r=e.range
12321
12321
  e.run((e=>{e.toggleMarkup("a",t)})),this.set("showToolbar",!1),e.selectRange(r)}_getLinkRange(){if(!this._target)return
12322
- let e=this.editor,t=this._targetRect.x+this._targetRect.width/2,r=this._targetRect.y+this._targetRect.height/2,n=e.positionAtPoint(t,r),i=n.marker&&n.marker.markups.findBy("tagName","a")
12323
- if(i){return n.toRange().expandByMarker((e=>!!e.markups.includes(i)))}}_handleMouseover(e){if(this._canShowToolbar){let t=(0,n.getEventTargetMatchingTag)("a",e.target,this.container)
12322
+ const e=this.editor,t=this._targetRect.x+this._targetRect.width/2,r=this._targetRect.y+this._targetRect.height/2
12323
+ try{const n=e.positionAtPoint(t,r),i=n.marker&&n.marker.markups.findBy("tagName","a")
12324
+ if(i){return n.toRange().expandByMarker((e=>!!e.markups.includes(i)))}}catch(n){console.error(n)}}_handleMouseover(e){if(this._canShowToolbar){let t=(0,n.getEventTargetMatchingTag)("a",e.target,this.container)
12324
12325
  t&&t.isContentEditable&&t.closest("[data-kg-has-link-toolbar=true]")===this.container&&(this._timeout=Ember.run.later(this,(function(){this._showToolbar(t,{x:e.clientX,y:e.clientY})}),120))}}_handleMouseout(e){if(this._cancelTimeouts(),this.showToolbar){let t=e.toElement||e.relatedTarget
12325
12326
  t&&t!==this.element&&t!==this._target&&!t.closest(`#${this.elementId}`)&&this.set("showToolbar",!1)}}_showToolbar(e,r){this._target=e
12326
12327
  let n=e.getAttribute("href"),i=this.config.blogUrl
@@ -12379,7 +12380,7 @@ e&&e.focus()}_handleWindowMousedown(e){e.target.closest(`#${this.elementId}, .fu
12379
12380
  r<this.element.parentNode.getBoundingClientRect().left&&(r+=40)
12380
12381
  try{let e=i.positionAtPoint(r,n)
12381
12382
  if(e){let t=e.toRange()
12382
- this._showOrHideButton(t)}}catch(t){if(t instanceof TypeError==!1)throw t}!this.showButton&&this._hasCursorButton&&this._showOrHideButton(this.editorRange)}this._mousemoveTicking=!1}_handleKeydown(e){if("Escape"===e.key)return this._moveCaretToCachedEditorRange(),void this._hideMenu();["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(e.key)&&this._hideMenu()}_handleResize(){this.showButton&&(this._throttleResize=Ember.run.throttle(this,this._positionMenu,100))}_moveCaretToCachedEditorRange(){this._ignoreRangeChange=!0,this.set("editorRange",this._editorRange),this.editor.selectRange(this._editorRange)}},m(p.prototype,"style",[s],Object.getOwnPropertyDescriptor(p.prototype,"style"),p.prototype),m(p.prototype,"itemSections",[l],Object.getOwnPropertyDescriptor(p.prototype,"itemSections"),p.prototype),m(p.prototype,"openMenu",[u],Object.getOwnPropertyDescriptor(p.prototype,"openMenu"),p.prototype),m(p.prototype,"closeMenu",[d],Object.getOwnPropertyDescriptor(p.prototype,"closeMenu"),p.prototype),m(p.prototype,"itemClicked",[c],Object.getOwnPropertyDescriptor(p.prototype,"itemClicked"),p.prototype),h=p))||h)||h)
12383
+ this._showOrHideButton(t)}}catch(t){t instanceof TypeError==!1&&console.error(t)}!this.showButton&&this._hasCursorButton&&this._showOrHideButton(this.editorRange)}this._mousemoveTicking=!1}_handleKeydown(e){if("Escape"===e.key)return this._moveCaretToCachedEditorRange(),void this._hideMenu();["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(e.key)&&this._hideMenu()}_handleResize(){this.showButton&&(this._throttleResize=Ember.run.throttle(this,this._positionMenu,100))}_moveCaretToCachedEditorRange(){this._ignoreRangeChange=!0,this.set("editorRange",this._editorRange),this.editor.selectRange(this._editorRange)}},m(p.prototype,"style",[s],Object.getOwnPropertyDescriptor(p.prototype,"style"),p.prototype),m(p.prototype,"itemSections",[l],Object.getOwnPropertyDescriptor(p.prototype,"itemSections"),p.prototype),m(p.prototype,"openMenu",[u],Object.getOwnPropertyDescriptor(p.prototype,"openMenu"),p.prototype),m(p.prototype,"closeMenu",[d],Object.getOwnPropertyDescriptor(p.prototype,"closeMenu"),p.prototype),m(p.prototype,"itemClicked",[c],Object.getOwnPropertyDescriptor(p.prototype,"itemClicked"),p.prototype),h=p))||h)||h)
12383
12384
  e.default=v,Ember._setComponentTemplate(g,v)})),define("koenig-editor/components/koenig-settings-panel",["exports","@glimmer/component","ember-concurrency"],(function(e,t,r){"use strict"
12384
12385
  var n,i,o,a,s
12385
12386
  function l(e,t,r,n,i){var o={}
@@ -13339,4 +13340,4 @@ return void 0===n&&(n=(0,t.createStorage)(null,(()=>!1)),r.set(e,n)),n}dirtyStor
13339
13340
  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"
13340
13341
  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}})}))
13341
13342
 
13342
- //# sourceMappingURL=vendor-0d29a566ca9747f2cfba9d7c98e39f53.map
13343
+ //# sourceMappingURL=vendor-a5908fe1facfc5cd41d8b915a996bfed.map
@@ -56,9 +56,9 @@
56
56
 
57
57
  <div id="ember-basic-dropdown-wormhole"></div>
58
58
 
59
- <script src="assets/vendor-0d29a566ca9747f2cfba9d7c98e39f53.js"></script>
60
- <script src="assets/chunk.613.551c7c3e872b9a811863.js"></script>
61
- <script src="assets/chunk.143.37f5727f90df66ade091.js"></script>
62
- <script src="assets/ghost-15f77300dbb6762873d6692e0485a37a.js"></script>
59
+ <script src="assets/vendor-a5908fe1facfc5cd41d8b915a996bfed.js"></script>
60
+ <script src="assets/chunk.613.7e15b585f6a677d191bb.js"></script>
61
+ <script src="assets/chunk.143.ce979d0e79756c847be1.js"></script>
62
+ <script src="assets/ghost-04991abb5f64c0b3442a093dbfa55a67.js"></script>
63
63
  </body>
64
64
  </html>
@@ -117,9 +117,59 @@ function parseOptions(globals, data, options) {
117
117
  return options;
118
118
  }
119
119
 
120
+ /**
121
+ *
122
+ * @param {String} resource
123
+ * @param {String} controllerName
124
+ * @param {String} action
125
+ * @param {Object} apiOptions
126
+ * @returns {Promise<Object>}
127
+ */
128
+ async function makeAPICall(resource, controllerName, action, apiOptions) {
129
+ const controller = api[controllerName];
130
+
131
+ let timer;
132
+
133
+ try {
134
+ let response;
135
+
136
+ if (config.get('optimization:getHelper:timeout:threshold')) {
137
+ const logLevel = config.get('optimization:getHelper:timeout:level') || 'error';
138
+ const threshold = config.get('optimization:getHelper:timeout:threshold');
139
+
140
+ const apiResponse = controller[action](apiOptions);
141
+
142
+ const timeout = new Promise((resolve) => {
143
+ timer = setTimeout(() => {
144
+ logging[logLevel](new errors.HelperWarning({
145
+ message: `{{#get}} took longer than ${threshold}ms and was aborted`,
146
+ code: 'ABORTED_GET_HELPER',
147
+ errorDetails: {
148
+ api: `${controllerName}.${action}`,
149
+ apiOptions
150
+ }
151
+ }));
152
+
153
+ resolve({[resource]: []});
154
+ }, threshold);
155
+ });
156
+
157
+ response = await Promise.race([apiResponse, timeout]);
158
+ clearTimeout(timer);
159
+ } else {
160
+ response = await controller[action](apiOptions);
161
+ }
162
+
163
+ return response;
164
+ } catch (err) {
165
+ clearTimeout(timer);
166
+ throw err;
167
+ }
168
+ }
169
+
120
170
  /**
121
171
  * ## Get
122
- * @param {Object} resource
172
+ * @param {String} resource
123
173
  * @param {Object} options
124
174
  * @returns {Promise<any>}
125
175
  */
@@ -149,7 +199,6 @@ module.exports = async function get(resource, options) {
149
199
  }
150
200
 
151
201
  const controllerName = RESOURCES[resource].alias;
152
- const controller = api[controllerName];
153
202
  const action = isBrowse(apiOptions) ? 'browse' : 'read';
154
203
 
155
204
  // Parse the options we're going to pass to the API
@@ -157,7 +206,7 @@ module.exports = async function get(resource, options) {
157
206
  apiOptions.context = {member: data.member};
158
207
 
159
208
  try {
160
- const response = await controller[action](apiOptions);
209
+ const response = await makeAPICall(resource, controllerName, action, apiOptions);
161
210
 
162
211
  // prepare data properties for use with handlebars
163
212
  if (response[resource] && response[resource].length) {
@@ -185,19 +234,21 @@ module.exports = async function get(resource, options) {
185
234
  data.error = error.message;
186
235
  return options.inverse(self, {data: data});
187
236
  } finally {
188
- const totalMs = Date.now() - start;
189
- const logLevel = config.get('logging:slowHelper:level');
190
- const threshold = config.get('logging:slowHelper:threshold');
191
- if (totalMs > threshold) {
192
- logging[logLevel](new errors.HelperWarning({
193
- message: `{{#get}} helper took ${totalMs}ms to complete`,
194
- code: 'SLOW_GET_HELPER',
195
- errorDetails: {
196
- api: `${controllerName}.${action}`,
197
- apiOptions,
198
- returnedRows: returnedRowsCount
199
- }
200
- }));
237
+ if (config.get('optimization:getHelper:notify:threshold')) {
238
+ const totalMs = Date.now() - start;
239
+ const logLevel = config.get('optimization:getHelper:notify:level') || 'warn';
240
+ const threshold = config.get('optimization:getHelper:notify:threshold');
241
+ if (totalMs > threshold) {
242
+ logging[logLevel](new errors.HelperWarning({
243
+ message: `{{#get}} helper took ${totalMs}ms to complete`,
244
+ code: 'SLOW_GET_HELPER',
245
+ errorDetails: {
246
+ api: `${controllerName}.${action}`,
247
+ apiOptions,
248
+ returnedRows: returnedRowsCount
249
+ }
250
+ }));
251
+ }
201
252
  }
202
253
  }
203
254
  };
@@ -83,7 +83,7 @@ module.exports = {
83
83
  permissions: true,
84
84
  query(frame) {
85
85
  const siteTimezone = settingsCache.get('timezone');
86
- const importTag = `Import ${moment().tz(siteTimezone).format('YYYY-MM-DD HH:mm')}`;
86
+ const importTag = `#Import ${moment().tz(siteTimezone).format('YYYY-MM-DD HH:mm')}`;
87
87
  return importer.importFromFile(frame.file, {
88
88
  user: {
89
89
  email: frame.user.get('email')
@@ -10,6 +10,7 @@ module.exports = (model, frame) => {
10
10
  name: jsonModel.name,
11
11
  description: jsonModel.description,
12
12
  slug: jsonModel.slug,
13
+ sender_email: jsonModel.sender_email,
13
14
  subscribe_on_signup: jsonModel.subscribe_on_signup,
14
15
  visibility: jsonModel.visibility,
15
16
  sort_order: jsonModel.sort_order,
@@ -55,7 +55,7 @@ DataImporter = {
55
55
  importData.data.tags.push({
56
56
  id: tagId,
57
57
  name: importOptions.importTag,
58
- slug: slugify(importOptions.importTag)
58
+ slug: slugify(importOptions.importTag.replace(/^#/, 'hash-'))
59
59
  });
60
60
  if (!('posts_tags' in importData.data)) {
61
61
  importData.data.posts_tags = [];
@@ -571,19 +571,25 @@ async function createEmailBatches({emailModel, memberRows, memberSegment, option
571
571
  return batchIds;
572
572
  }
573
573
 
574
- const statusChangedHandler = (emailModel, options) => {
574
+ const statusChangedHandler = async (emailModel, options) => {
575
575
  const emailRetried = emailModel.wasChanged()
576
576
  && emailModel.get('status') === 'pending'
577
577
  && emailModel.previous('status') === 'failed';
578
578
 
579
579
  if (emailRetried) {
580
- pendingEmailHandler(emailModel, options);
580
+ await pendingEmailHandler(emailModel, options);
581
581
  }
582
582
  };
583
583
 
584
584
  function listen() {
585
- events.on('email.added', pendingEmailHandler);
586
- events.on('email.edited', statusChangedHandler);
585
+ events.on('email.added', (emailModel, options) => pendingEmailHandler(emailModel, options).catch((e) => {
586
+ logging.error('Error in email.added event handler');
587
+ logging.error(e);
588
+ }));
589
+ events.on('email.edited', (emailModel, options) => statusChangedHandler(emailModel, options).catch((e) => {
590
+ logging.error('Error in email.edited event handler');
591
+ logging.error(e);
592
+ }));
587
593
  }
588
594
 
589
595
  // Public API
@@ -77,7 +77,10 @@ const deleteSession = async function (req, res) {
77
77
  res.writeHead(204);
78
78
  res.end();
79
79
  } catch (err) {
80
- res.writeHead(err.statusCode, {
80
+ if (!err.statusCode) {
81
+ logging.error(err);
82
+ }
83
+ res.writeHead(err.statusCode ?? 500, {
81
84
  'Content-Type': 'text/plain;charset=UTF-8'
82
85
  });
83
86
  res.end(err.message);
@@ -101,11 +104,20 @@ const getMemberData = async function (req, res) {
101
104
  const deleteSuppression = async function (req, res) {
102
105
  try {
103
106
  const member = await membersService.ssr.getMemberDataFromSession(req, res);
107
+ const options = {
108
+ id: member.id,
109
+ withRelated: ['newsletters']
110
+ };
104
111
  await emailSuppressionList.removeEmail(member.email);
112
+ await membersService.api.members.update({subscribed: true}, options);
113
+
105
114
  res.writeHead(204);
106
115
  res.end();
107
116
  } catch (err) {
108
- res.writeHead(err.statusCode, {
117
+ if (!err.statusCode) {
118
+ logging.error(err);
119
+ }
120
+ res.writeHead(err.statusCode ?? 500, {
109
121
  'Content-Type': 'text/plain;charset=UTF-8'
110
122
  });
111
123
  res.end(err.message);
@@ -188,7 +200,10 @@ const updateMemberData = async function (req, res) {
188
200
  res.json(null);
189
201
  }
190
202
  } catch (err) {
191
- res.writeHead(err.statusCode, {
203
+ if (!err.statusCode) {
204
+ logging.error(err);
205
+ }
206
+ res.writeHead(err.statusCode ?? 500, {
192
207
  'Content-Type': 'text/plain;charset=UTF-8'
193
208
  });
194
209
  res.end(err.message);
@@ -23,13 +23,16 @@ class MembersEventsServiceWrapper {
23
23
  labsService
24
24
  });
25
25
 
26
+ const db = require('../../data/db');
27
+
26
28
  this.lastSeenAtUpdater = new LastSeenAtUpdater({
27
29
  services: {
28
30
  settingsCache
29
31
  },
30
32
  getMembersApi() {
31
33
  return members.api;
32
- }
34
+ },
35
+ db
33
36
  });
34
37
 
35
38
  this.eventStorage.subscribe(DomainEvents);
@@ -22,7 +22,9 @@ async function configureApi() {
22
22
  }
23
23
 
24
24
  const debouncedConfigureApi = _.debounce(() => {
25
- configureApi();
25
+ configureApi().catch((err) => {
26
+ logging.error(err);
27
+ });
26
28
  }, 600);
27
29
 
28
30
  module.exports = new StripeService({
@@ -58,11 +58,7 @@
58
58
  },
59
59
  "transports": [
60
60
  "stdout"
61
- ],
62
- "slowHelper": {
63
- "level": "warn",
64
- "threshold": 200
65
- }
61
+ ]
66
62
  },
67
63
  "spam": {
68
64
  "user_login": {
@@ -145,6 +141,18 @@
145
141
  "maxAge": 0
146
142
  }
147
143
  },
144
+ "optimization": {
145
+ "getHelper": {
146
+ "timeout": {
147
+ "threshold": 5000,
148
+ "level": "error"
149
+ },
150
+ "notify": {
151
+ "threshold": 200,
152
+ "level": "warn"
153
+ }
154
+ }
155
+ },
148
156
  "imageOptimization": {
149
157
  "resize": true,
150
158
  "srcsets": true
@@ -161,7 +169,7 @@
161
169
  },
162
170
  "portal": {
163
171
  "url": "https://cdn.jsdelivr.net/ghost/portal@~{version}/umd/portal.min.js",
164
- "version": "2.21"
172
+ "version": "2.22"
165
173
  },
166
174
  "sodoSearch": {
167
175
  "url": "https://cdn.jsdelivr.net/ghost/sodo-search@~{version}/umd/sodo-search.min.js",