ghost 5.8.1 → 5.9.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 (117) hide show
  1. package/components/tryghost-adapter-manager-0.0.0.tgz +0 -0
  2. package/components/tryghost-api-framework-0.0.0.tgz +0 -0
  3. package/components/tryghost-bootstrap-socket-0.0.0.tgz +0 -0
  4. package/components/tryghost-custom-theme-settings-service-0.0.0.tgz +0 -0
  5. package/components/tryghost-email-analytics-provider-mailgun-0.0.0.tgz +0 -0
  6. package/components/tryghost-email-analytics-service-0.0.0.tgz +0 -0
  7. package/components/tryghost-job-manager-0.0.0.tgz +0 -0
  8. package/components/tryghost-mailgun-client-0.0.0.tgz +0 -0
  9. package/components/tryghost-member-analytics-service-0.0.0.tgz +0 -0
  10. package/components/tryghost-members-api-0.0.0.tgz +0 -0
  11. package/components/tryghost-members-importer-0.0.0.tgz +0 -0
  12. package/components/tryghost-members-offers-0.0.0.tgz +0 -0
  13. package/components/tryghost-members-payments-0.0.0.tgz +0 -0
  14. package/components/tryghost-members-ssr-0.0.0.tgz +0 -0
  15. package/components/tryghost-members-stripe-service-0.0.0.tgz +0 -0
  16. package/components/tryghost-minifier-0.0.0.tgz +0 -0
  17. package/components/tryghost-mw-cache-control-0.0.0.tgz +0 -0
  18. package/components/tryghost-mw-error-handler-0.0.0.tgz +0 -0
  19. package/components/tryghost-package-json-0.0.0.tgz +0 -0
  20. package/components/tryghost-session-service-0.0.0.tgz +0 -0
  21. package/components/tryghost-settings-path-manager-0.0.0.tgz +0 -0
  22. package/components/tryghost-update-check-service-0.0.0.tgz +0 -0
  23. package/content/themes/casper/README.md +1 -1
  24. package/content/themes/casper/assets/built/portal.min.js +3 -0
  25. package/content/themes/casper/assets/built/screen.css +1 -1
  26. package/content/themes/casper/assets/built/screen.css.map +1 -1
  27. package/content/themes/casper/assets/css/screen.css +119 -37
  28. package/content/themes/casper/package.json +3 -3
  29. package/content/themes/casper/partials/post-card.hbs +3 -1
  30. package/content/themes/casper/post.hbs +7 -7
  31. package/content/themes/casper/yarn.lock +69 -68
  32. package/core/boot.js +2 -0
  33. package/core/built/admin/assets/{chunk.143.904e017ad397bb681e9d.js → chunk.143.e35fdb482bc822313f0c.js} +5 -5
  34. package/core/built/admin/assets/{chunk.178.9541bdb92bded29cd60d.js → chunk.178.1d381d687652f2597fe2.js} +4 -4
  35. package/core/built/admin/assets/{chunk.351.cbc224ca65c14ef5322d.js → chunk.351.73f27952f867334a8228.js} +3 -3
  36. package/core/built/admin/assets/{chunk.351.cbc224ca65c14ef5322d.js.LICENSE.txt → chunk.351.73f27952f867334a8228.js.LICENSE.txt} +0 -0
  37. package/core/built/admin/assets/{ghost-b469423d0fbe5e40af17b560f7e3cead.css → ghost-686c383caa6a3469cefb939ab10e21b6.css} +1 -1
  38. package/core/built/admin/assets/{ghost-dark-bcb6f4517a2dfe23a0a280632bfca00c.css → ghost-dark-6814c399ff5b3d9c8efe2d92bc7ec779.css} +1 -1
  39. package/core/built/admin/assets/{ghost-a66a04418efe85083a3adca0fb16bb52.js → ghost-eca1a709a74b1af277e48aad4e16c9db.js} +94 -92
  40. package/core/built/admin/assets/{vendor-46baf13852f545c6c89756c8e0ccbff2.js → vendor-516c9e43b4aeb92079dc1ab92c9ce492.js} +3 -3
  41. package/core/built/admin/index.html +6 -6
  42. package/core/frontend/helpers/comment_count.js +7 -15
  43. package/core/frontend/helpers/comments.js +4 -16
  44. package/core/frontend/helpers/ghost_head.js +1 -1
  45. package/core/frontend/public/ghost.min.css +1 -1
  46. package/core/frontend/src/comment-counts/js/comment-counts.js +12 -1
  47. package/core/server/api/endpoints/comments-members.js +23 -1
  48. package/core/server/api/endpoints/index.js +52 -52
  49. package/core/server/api/endpoints/utils/serializers/input/comments.js +18 -0
  50. package/core/server/api/endpoints/utils/serializers/input/db.js +1 -1
  51. package/core/server/api/endpoints/utils/serializers/input/index.js +4 -0
  52. package/core/server/api/endpoints/utils/serializers/input/integrations.js +2 -2
  53. package/core/server/api/endpoints/utils/serializers/input/tiers.js +1 -1
  54. package/core/server/api/{shared → endpoints/utils}/serializers/input/utils/settings-filter-type-group-mapper.js +0 -0
  55. package/core/server/api/{shared → endpoints/utils}/serializers/input/utils/settings-key-group-mapper.js +0 -0
  56. package/core/server/api/{shared → endpoints/utils}/serializers/input/utils/settings-key-type-mapper.js +0 -0
  57. package/core/server/api/endpoints/utils/serializers/output/mappers/comments.js +12 -12
  58. package/core/server/api/endpoints/utils/serializers/output/tiers.js +1 -1
  59. package/core/server/api/index.js +0 -2
  60. package/core/server/data/db/connection.js +0 -4
  61. package/core/server/data/importer/importers/data/settings.js +2 -2
  62. package/core/server/data/migrations/versions/5.9/2022-08-09-08-32-added-new-integration-type.js +24 -0
  63. package/core/server/data/schema/clients/mysql.js +0 -15
  64. package/core/server/data/schema/commands.js +0 -9
  65. package/core/server/data/schema/fixtures/fixtures.json +1 -1
  66. package/core/server/data/schema/schema.js +3 -3
  67. package/core/server/models/base/plugins/user-type.js +1 -9
  68. package/core/server/models/comment.js +96 -15
  69. package/core/server/models/label.js +14 -0
  70. package/core/server/models/newsletter.js +21 -0
  71. package/core/server/models/stripe-customer-subscription.js +6 -0
  72. package/core/server/models/tag.js +20 -0
  73. package/core/server/models/user.js +20 -0
  74. package/core/server/run-update-check.js +1 -1
  75. package/core/server/services/auth/api-key/admin.js +1 -1
  76. package/core/server/services/auth/api-key/content.js +1 -1
  77. package/core/server/services/bulk-email/bulk-email-processor.js +18 -11
  78. package/core/server/services/bulk-email/index.js +1 -17
  79. package/core/server/services/comments/controller.js +9 -0
  80. package/core/server/services/comments/email-templates/new-comment-reply.hbs +2 -2
  81. package/core/server/services/comments/email-templates/new-comment.hbs +2 -2
  82. package/core/server/services/comments/email-templates/report.hbs +2 -2
  83. package/core/server/services/comments/service.js +16 -3
  84. package/core/server/services/comments/stats.js +2 -0
  85. package/core/server/services/email-analytics/jobs/fetch-latest.js +1 -1
  86. package/core/server/services/mega/post-email-serializer.js +2 -2
  87. package/core/server/services/permissions/can-this.js +154 -161
  88. package/core/server/services/permissions/parse-context.js +1 -8
  89. package/core/server/services/webhooks/serialize.js +3 -3
  90. package/core/server/web/api/endpoints/admin/routes.js +1 -1
  91. package/core/server/web/api/endpoints/content/routes.js +1 -1
  92. package/core/server/web/api/testmode/jobs/graceful-job.js +1 -1
  93. package/core/server/web/comments/routes.js +2 -1
  94. package/core/server/web/shared/middleware/index.js +1 -1
  95. package/core/shared/config/defaults.json +2 -2
  96. package/core/shared/labs.js +0 -1
  97. package/package.json +31 -29
  98. package/yarn.lock +330 -276
  99. package/core/server/api/README.md +0 -130
  100. package/core/server/api/shared/frame.js +0 -95
  101. package/core/server/api/shared/headers.js +0 -152
  102. package/core/server/api/shared/http.js +0 -127
  103. package/core/server/api/shared/index.js +0 -25
  104. package/core/server/api/shared/pipeline.js +0 -259
  105. package/core/server/api/shared/serializers/handle.js +0 -140
  106. package/core/server/api/shared/serializers/index.js +0 -13
  107. package/core/server/api/shared/serializers/input/all.js +0 -41
  108. package/core/server/api/shared/serializers/input/index.js +0 -5
  109. package/core/server/api/shared/serializers/output/index.js +0 -1
  110. package/core/server/api/shared/utils/index.js +0 -5
  111. package/core/server/api/shared/utils/options.js +0 -23
  112. package/core/server/api/shared/validators/handle.js +0 -68
  113. package/core/server/api/shared/validators/index.js +0 -9
  114. package/core/server/api/shared/validators/input/all.js +0 -213
  115. package/core/server/api/shared/validators/input/index.js +0 -5
  116. package/core/server/services/bulk-email/mailgun.js +0 -122
  117. package/core/server/web/shared/middleware/cache-control.js +0 -43
@@ -9020,8 +9020,8 @@ const o=++m
9020
9020
  r.recycle(u(e,o),o),this._appendComponent(r),t.push(r)}for(;O>M;){let r
9021
9021
  r=!0===i&&n.pop()||new l
9022
9022
  const o=--O
9023
- r.recycle(u(e,o),o),this._prependComponent(r),t.unshift(r)}if(n.length>0)if(!0===i)for(let l=n.length-1;l>=0;l--){const t=n[l]
9024
- u(e,t.index)?d(this._domPool,null,t.realUpperBound,t.realLowerBound):(Ember.run((()=>{r.removeObject(t)})),n.splice(l,1))}else r.removeObjects(n),n.length=0
9023
+ r.recycle(u(e,o),o),this._prependComponent(r),t.unshift(r)}if(n.length>0)if(!0===i)for(let l=0;l<n.length;l++){const e=n[l]
9024
+ d(this._domPool,null,e.realUpperBound,e.realLowerBound)}else r.removeObjects(n),n.length=0
9025
9025
  const A=M,g=b-h-1,v=1===A?"item":"items",y=1===g?"item":"items"
9026
9026
  p.style.height=`${Math.max(z,0)}px`,p.innerHTML=A>0?`And ${A} ${v} before`:"",c.style.height=`${Math.max(f,0)}px`,c.innerHTML=g>0?`And ${g} ${y} after`:""}_appendComponent(e){const{virtualComponents:t,_occludedContentAfter:r,_appendComponentPool:n,shouldRecycle:i,_itemContainer:o}=this,a=r.realUpperBound
9027
9027
  !0===e.rendered?d(o,a,e.realUpperBound,e.realLowerBound):(t.insertAt(t.get("length")-1,e),e.rendered=!0,i||(n.unshift(e),null===this._nextLayout&&(this._nextLayout=this.schedule("layout",(()=>{for(this._nextLayout=null;n.length>0;){const e=n.pop(),t=r.realUpperBound
@@ -13818,4 +13818,4 @@ return void 0===n&&(n=(0,t.createStorage)(null,(()=>!1)),r.set(e,n)),n}dirtyStor
13818
13818
  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"
13819
13819
  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}})}))
13820
13820
 
13821
- //# sourceMappingURL=vendor-46baf13852f545c6c89756c8e0ccbff2.map
13821
+ //# sourceMappingURL=vendor-516c9e43b4aeb92079dc1ab92c9ce492.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.8%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22moment%22%3A%7B%22includeTimezone%22%3A%22all%22%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.9%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22moment%22%3A%7B%22includeTimezone%22%3A%22all%22%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-bc9d2c9e5c8a33f0c92e81189d48e04c.css">
40
- <link integrity="" rel="stylesheet" href="assets/ghost-b469423d0fbe5e40af17b560f7e3cead.css" title="light">
40
+ <link integrity="" rel="stylesheet" href="assets/ghost-686c383caa6a3469cefb939ab10e21b6.css" title="light">
41
41
 
42
42
 
43
43
  </head>
@@ -53,9 +53,9 @@
53
53
 
54
54
  <div id="ember-basic-dropdown-wormhole"></div>
55
55
 
56
- <script src="assets/vendor-46baf13852f545c6c89756c8e0ccbff2.js"></script>
57
- <script src="assets/chunk.351.cbc224ca65c14ef5322d.js"></script>
58
- <script src="assets/chunk.143.904e017ad397bb681e9d.js"></script>
59
- <script src="assets/ghost-a66a04418efe85083a3adca0fb16bb52.js"></script>
56
+ <script src="assets/vendor-516c9e43b4aeb92079dc1ab92c9ce492.js"></script>
57
+ <script src="assets/chunk.351.73f27952f867334a8228.js"></script>
58
+ <script src="assets/chunk.143.e35fdb482bc822313f0c.js"></script>
59
+ <script src="assets/ghost-eca1a709a74b1af277e48aad4e16c9db.js"></script>
60
60
  </body>
61
61
  </html>
@@ -1,31 +1,23 @@
1
1
  const {SafeString} = require('../services/handlebars');
2
- const {labs} = require('../services/proxy');
3
2
  const {html} = require('common-tags');
4
3
 
5
- function commentCount(options) {
4
+ module.exports = function commentCount(options) {
6
5
  const empty = options.hash.empty === undefined ? '' : options.hash.empty;
7
6
  const singular = options.hash.singular === undefined ? 'comment' : options.hash.singular;
8
7
  const plural = options.hash.plural === undefined ? 'comments' : options.hash.plural;
8
+ const autowrap = options.hash.autowrap !== 'false';
9
+ const tag = autowrap ? options.hash.autowrap || 'span' : 'script';
10
+ const className = options.hash.class;
9
11
  return new SafeString(html`
10
12
  <script
11
13
  data-ghost-comment-count="${this.id}"
12
14
  data-ghost-comment-count-empty="${empty}"
13
15
  data-ghost-comment-count-singular="${singular}"
14
16
  data-ghost-comment-count-plural="${plural}"
17
+ data-ghost-comment-count-tag="${tag}"
18
+ data-ghost-comment-count-class-name="${className}"
19
+ data-ghost-comment-count-autowrap="${autowrap ? 'true' : 'false'}"
15
20
  >
16
21
  </script>
17
22
  `);
18
- }
19
-
20
- module.exports = function commentsLabsWrapper() {
21
- const self = this;
22
- const args = arguments;
23
-
24
- return labs.enabledHelper({
25
- flagKey: 'comments',
26
- flagName: 'Comments',
27
- helperName: 'comment_count'
28
- }, () => {
29
- return commentCount.apply(self, args);
30
- });
31
23
  };
@@ -1,8 +1,8 @@
1
1
  const {SafeString} = require('../services/handlebars');
2
- const {urlUtils, getFrontendKey, labs, settingsCache} = require('../services/proxy');
2
+ const {urlUtils, getFrontendKey, settingsCache} = require('../services/proxy');
3
3
  const {getFrontendAppConfig, getDataAttributes} = require('../utils/frontend-apps');
4
4
 
5
- async function comments(options) {
5
+ module.exports = async function comments(options) {
6
6
  // todo: For now check on the comment id to exclude normal pages (we probably have a better way to do this)
7
7
 
8
8
  const commentId = this.comment_id;
@@ -66,7 +66,8 @@ async function comments(options) {
66
66
  'avatar-saturation': avatarSaturation,
67
67
  'accent-color': accentColor,
68
68
  'app-version': appVersion,
69
- 'comments-enabled': commentsEnabled
69
+ 'comments-enabled': commentsEnabled,
70
+ publication: settingsCache.get('title')
70
71
  };
71
72
 
72
73
  const dataAttributes = getDataAttributes(data);
@@ -74,19 +75,6 @@ async function comments(options) {
74
75
  return new SafeString(`
75
76
  <script defer src="${scriptUrl}" ${dataAttributes} crossorigin="anonymous"></script>
76
77
  `);
77
- }
78
-
79
- module.exports = async function commentsLabsWrapper() {
80
- const self = this;
81
- const args = arguments;
82
-
83
- return labs.enabledHelper({
84
- flagKey: 'comments',
85
- flagName: 'Comments',
86
- helperName: 'comments'
87
- }, () => {
88
- return comments.apply(self, args);
89
- });
90
78
  };
91
79
 
92
80
  module.exports.async = true;
@@ -229,7 +229,7 @@ module.exports = async function ghost_head(options) { // eslint-disable-line cam
229
229
  head.push(`<link rel="stylesheet" type="text/css" href="${getAssetUrl('public/cards.min.css')}">`);
230
230
  }
231
231
 
232
- if (labs.isSet('comments') && settingsCache.get('enable_comments') !== 'off') {
232
+ if (settingsCache.get('enable_comments') !== 'off') {
233
233
  head.push(`<script defer src="${getAssetUrl('public/comment-counts.min.js')}" data-ghost-comments-counts-api="${urlUtils.getSiteUrl(true)}members/api/comments/counts/"></script>`);
234
234
  }
235
235
 
@@ -1 +1 @@
1
- /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;font-family:sans-serif}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.black{color:#15171a}.darkgrey{color:#394047}.midgrey{color:#7c8b9a}.lightgrey{color:#ced4d9}.blue{color:#14b8ff}.red{color:#f50b23}.orange{color:#ffb41f}.green{color:#30cf43}.darkgrey-hover:hover{color:#394047}.midgrey-hover:hover{color:#7c8b9a}.lightgrey-hover:hover{color:#ced4d9}.blue-hover:hover{color:#14b8ff}.red-hover:hover{color:#f50b23}.orange-hover:hover{color:#ffb41f}.green-hover:hover{color:#30cf43}*,:after,:before{box-sizing:border-box}html{-webkit-tap-highlight-color:rgba(0,0,0,0);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:62.5%;letter-spacing:.2px;line-height:1.65;overflow:hidden}body,html{height:100%;width:100%}body{color:#343f44;font-size:1.4rem;overflow:auto;overflow-x:hidden}.gh-view{-ms-flex-positive:1;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;flex-grow:1}h1,h2{text-rendering:optimizeLegibility;color:#343f44;font-size:2.9rem;line-height:1.15em;margin:0 0 .3em;text-indent:-1px}@media (max-width:500px){h1{font-size:2.4rem}}.gh-input{-webkit-appearance:none;border:1px solid #d6e3eb;border-radius:4px;color:#4b5b62;display:block;font-size:1.6rem;font-weight:300;height:40px;line-height:1em;padding:10px 12px;transition:border-color .15s linear;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text;width:100%}.gh-input:focus{border-color:#b4cbda;outline:0}.gh-btn{fill:#829aa8;-webkit-font-smoothing:subpixel-antialiased;border:1px solid #d6e3eb;border-radius:5px;color:#829aa8;display:inline-block;outline:none;text-decoration:none!important;transition:all .2s ease;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.gh-btn span{border-radius:4px;display:block;font-size:1.3rem;font-weight:400;height:33px;letter-spacing:.2px;line-height:33px;padding:0 12px;text-align:center}.gh-btn:hover{border-color:#b4cbda}.gh-btn-hover-blue:hover{border-color:#3eb0ef;color:#3eb0ef}.gh-btn-blue{fill:#fff;background:linear-gradient(#3da1d6,#2288bf);border:0;box-shadow:0 1px 0 rgba(0,0,0,.12);color:#fff;padding:1px;text-shadow:0 -1px 0 rgba(0,0,0,.1);transition:none!important}.gh-btn-blue span{background:linear-gradient(#4ab6f0,#2fa5e4 60%,#2fa5e4 90%,#38a9e5);box-shadow:inset 0 1px 0 hsla(0,0%,100%,.1)}.gh-btn-blue:active,.gh-btn-blue:focus{background:#1e78a9}.gh-btn-blue:active span,.gh-btn-blue:focus span{background:#29a0e0;box-shadow:none}.gh-btn-block{display:block;width:100%}.gh-input-icon{display:block;position:relative}.gh-input-icon svg{fill:color(var(--midgrey) l(15%));height:14px;left:10px;position:absolute;top:50%;transform:translateY(-7px);width:auto;z-index:2}.gh-input-icon input{padding-left:35px}.gh-app{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;height:100%;overflow:hidden}.gh-viewport{max-height:100%;overflow:hidden}.gh-main,.gh-viewport{-ms-flex-positive:1;display:-ms-flexbox;display:flex;flex-grow:1}.gh-main{background:#fff;overflow-y:auto;position:relative}.gh-flow{background:linear-gradient(315deg,#efefef,#fff);min-height:100%;overflow-y:auto}.gh-flow,.gh-flow-content-wrap{display:flex;flex-direction:column;flex-grow:1}.gh-flow-content-wrap{align-items:center;flex-shrink:0;justify-content:center;margin:0 24px;padding-bottom:8vh}.gh-flow-content-wrap .site-icon{border-radius:3px;height:70px;width:70px}.gh-flow-content{background:#fff;border-radius:3px;box-shadow:0 2.8px 2.2px rgba(0,0,0,.02),0 6.7px 5.3px rgba(0,0,0,.02),0 12.5px 10px rgba(0,0,0,.02),0 22.3px 17.9px rgba(0,0,0,.03),0 41.8px 33.4px rgba(0,0,0,.03),0 100px 80px rgba(0,0,0,.05);color:var(--darkgrey);display:flex;flex-direction:column;font-size:1.9rem;font-weight:300;line-height:1.5em;margin:4rem 0 6rem;max-width:520px;padding:40px;width:100%}.gh-flow-content.unsubscribe{align-items:center;justify-content:center;margin:4rem 0;max-width:560px;min-height:200px;text-align:center}@media (max-width:500px){.gh-flow-content{background:transparent;box-shadow:none;padding:0}}.gh-flow-content header{align-items:center;display:flex;flex-direction:column}.gh-flow-content h1{color:#15171a;font-size:4.1rem;font-weight:700;line-height:1.15em;margin-bottom:24px}.gh-flow-content.unsubscribe h1{font-size:3.2rem}@media (max-width:600px){.gh-flow-content h1,.gh-flow-content.unsubscribe h1{font-size:6vw}}.gh-flow-content.unsubscribe p{color:#394047;font-size:1.8rem;margin:0 0 .4em}@media (max-width:500px){.gh-flow-content.unsubscribe p{font-size:1.6rem;line-height:1.5}}.gh-flow-content .gh-btn{display:block;margin:20px auto 0;max-width:400px}.gh-flow-content .form-group{margin-bottom:2.5rem;position:relative}.gh-flow-content .form-group.error .gh-input{border-color:#f50b23;box-shadow:0 0 0 3px rgba(239,24,24,.15)}.gh-flow-content .main-error{color:#7c8b9a;font-size:1.35rem;font-weight:400;margin:0;position:absolute;right:0;text-align:center;user-select:text}.gh-flow-em{font-weight:500}.unsubscribe-footer{font-size:1.5rem;text-align:center}@media (max-width:500px){.unsubscribe-footer{font-size:1.4rem;line-height:1.4em;padding:0 24px}}.unsubscribe-footer p{color:#7c8b9a;margin:0 0 .4rem}.unsubscribe-footer a{color:#15171a;text-decoration:none}.unsubscribe-footer a:hover{text-decoration:underline}.gh-signin{margin-bottom:1.5rem}.gh-signin .gh-input,.gh-signin .gh-input:-webkit-autofill:first-line{border-radius:8px;font-size:1.8rem;height:54px;padding:12px 16px}.gh-signin .gh-input::placeholder{color:#abb4be;font-weight:400;opacity:1}.gh-signin .gh-input::-webkit-input-placeholder{color:#abb4be;font-weight:400}.gh-signin .gh-input:-ms-input-placeholder{color:#abb4be;font-weight:400}.gh-signin .gh-input::-moz-placeholder{color:#abb4be;font-weight:400;opacity:1}.gh-signin .gh-input:focus{border-color:#30cf43;box-shadow:0 0 0 3px rgba(26,170,96,.15)}.gh-signin .gh-btn{-webkit-font-smoothing:subpixel-antialiased;background:#15171a;border-radius:8px;font-weight:300;height:54px;line-height:54px;margin:0;margin-top:32px;max-width:unset;transition:all .4s ease;width:100%}.gh-signin .gh-btn span{color:#fff;font-size:1.8rem}.error-content{flex-grow:1;justify-content:center;padding:8vw;user-select:text}.error-content,.error-details{align-items:center;display:flex}.error-details{margin-bottom:4rem}.error-ghost{height:115px;margin:15px}@media (max-width:630px){.error-ghost{display:none}}.error-code{color:#c5d2d9;font-size:10vw;font-weight:600;letter-spacing:-.4vw;line-height:.9em;margin:0}.error-description{border:none;color:#54666d;font-size:2.3rem;font-weight:300;line-height:1.3em;margin:0;padding:0}.error-message{align-items:center;display:flex;flex-direction:column;margin:15px}.error-message a{font-size:1.4rem;line-height:1;margin:8px 0}.error-link{background-color:transparent;color:#5ba4e5;text-decoration:none;transition:background .3s,color .3s}.error-stack{background-color:hsla(0,0%,100%,.3);margin:1rem auto;max-width:800px;padding:2rem}.error-stack-list{list-style-type:none;margin:0;padding:0}.error-stack-list li{display:block}.error-stack-list li:before{color:#bbb;content:"\21AA";display:inline-block;font-size:1.2rem;margin-right:.5rem}.error-stack-function{font-weight:700}
1
+ /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.black{color:#15171a}.darkgrey{color:#394047}.midgrey{color:#7c8b9a}.lightgrey{color:#ced4d9}.blue{color:#14b8ff}.red{color:#f50b23}.orange{color:#ffb41f}.green{color:#30cf43}.darkgrey-hover:hover{color:#394047}.midgrey-hover:hover{color:#7c8b9a}.lightgrey-hover:hover{color:#ced4d9}.blue-hover:hover{color:#14b8ff}.red-hover:hover{color:#f50b23}.orange-hover:hover{color:#ffb41f}.green-hover:hover{color:#30cf43}*,:after,:before{box-sizing:border-box}html{overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:62.5%;line-height:1.65;letter-spacing:.2px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body,html{width:100%;height:100%}body{overflow:auto;overflow-x:hidden;color:#343f44;font-size:1.4rem}.gh-view{-ms-flex-positive:1;flex-grow:1;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}h1,h2{margin:0 0 .3em;color:#343f44;line-height:1.15em;text-rendering:optimizeLegibility;text-indent:-1px;font-size:2.9rem}@media (max-width:500px){h1{font-size:2.4rem}}.gh-input{display:block;padding:10px 12px;width:100%;height:40px;border:1px solid #d6e3eb;border-radius:4px;color:#4b5b62;font-size:1.6rem;line-height:1em;font-weight:300;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text;transition:border-color .15s linear;-webkit-appearance:none}.gh-input:focus{outline:0;border-color:#b4cbda}.gh-btn{display:inline-block;outline:none;border:1px solid #d6e3eb;color:#829aa8;text-decoration:none!important;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;fill:#829aa8;border-radius:5px;transition:all .2s ease;-webkit-font-smoothing:subpixel-antialiased}.gh-btn span{display:block;padding:0 12px;height:33px;font-size:1.3rem;line-height:33px;font-weight:400;text-align:center;letter-spacing:.2px;border-radius:4px}.gh-btn:hover{border-color:#b4cbda}.gh-btn-hover-blue:hover{border-color:#3eb0ef;color:#3eb0ef}.gh-btn-blue{padding:1px;border:0;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.1);fill:#fff;background:linear-gradient(#3da1d6,#2288bf);box-shadow:0 1px 0 rgba(0,0,0,.12);transition:none!important}.gh-btn-blue span{background:linear-gradient(#4ab6f0,#2fa5e4 60%,#2fa5e4 90%,#38a9e5);box-shadow:inset 0 1px 0 hsla(0,0%,100%,.1)}.gh-btn-blue:active,.gh-btn-blue:focus{background:#1e78a9}.gh-btn-blue:active span,.gh-btn-blue:focus span{background:#29a0e0;box-shadow:none}.gh-btn-block{display:block;width:100%}.gh-input-icon{position:relative;display:block}.gh-input-icon svg{position:absolute;top:50%;left:10px;z-index:2;height:14px;width:auto;fill:color(var(--midgrey) l(15%));transform:translateY(-7px)}.gh-input-icon input{padding-left:35px}.gh-app{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;overflow:hidden;height:100%}.gh-viewport{overflow:hidden;max-height:100%}.gh-main,.gh-viewport{-ms-flex-positive:1;flex-grow:1;display:-ms-flexbox;display:flex}.gh-main{position:relative;background:#fff;overflow-y:auto}.gh-flow{overflow-y:auto;min-height:100%;background:linear-gradient(315deg,#efefef,#fff)}.gh-flow,.gh-flow-content-wrap{flex-grow:1;display:flex;flex-direction:column}.gh-flow-content-wrap{flex-shrink:0;justify-content:center;align-items:center;margin:0 24px;padding-bottom:8vh}.gh-flow-content-wrap .site-icon{width:70px;height:70px;border-radius:3px}.gh-flow-content{display:flex;flex-direction:column;max-width:520px;width:100%;margin:4rem 0 6rem;padding:40px;background:#fff;color:var(--darkgrey);font-size:1.9rem;line-height:1.5em;font-weight:300;border-radius:3px;box-shadow:0 2.8px 2.2px rgba(0,0,0,.02),0 6.7px 5.3px rgba(0,0,0,.02),0 12.5px 10px rgba(0,0,0,.02),0 22.3px 17.9px rgba(0,0,0,.03),0 41.8px 33.4px rgba(0,0,0,.03),0 100px 80px rgba(0,0,0,.05)}.gh-flow-content.unsubscribe{align-items:center;justify-content:center;max-width:560px;min-height:200px;margin:4rem 0;text-align:center}@media (max-width:500px){.gh-flow-content{padding:0;background:transparent;box-shadow:none}}.gh-flow-content header{display:flex;flex-direction:column;align-items:center}.gh-flow-content h1{margin-bottom:24px;color:#15171a;font-size:4.1rem;font-weight:700;line-height:1.15em}.gh-flow-content.unsubscribe h1{font-size:3.2rem}@media (max-width:600px){.gh-flow-content.unsubscribe h1,.gh-flow-content h1{font-size:6vw}}.gh-flow-content.unsubscribe p{margin:0 0 .4em;color:#394047;font-size:1.8rem}@media (max-width:500px){.gh-flow-content.unsubscribe p{font-size:1.6rem;line-height:1.5}}.gh-flow-content .gh-btn{display:block;margin:20px auto 0;max-width:400px}.gh-flow-content .form-group{position:relative;margin-bottom:2.5rem}.gh-flow-content .form-group.error .gh-input{border-color:#f50b23;box-shadow:0 0 0 3px rgba(239,24,24,.15)}.gh-flow-content .main-error{position:absolute;right:0;margin:0;color:#7c8b9a;font-size:1.35rem;font-weight:400;text-align:center;user-select:text}.gh-flow-em{font-weight:500}.unsubscribe-footer{text-align:center;font-size:1.5rem}@media (max-width:500px){.unsubscribe-footer{padding:0 24px;font-size:1.4rem;line-height:1.4em}}.unsubscribe-footer p{color:#7c8b9a;margin:0 0 .4rem}.unsubscribe-footer a{color:#15171a;text-decoration:none}.unsubscribe-footer a:hover{text-decoration:underline}.gh-signin{margin-bottom:1.5rem}.gh-signin .gh-input,.gh-signin .gh-input:-webkit-autofill:first-line{height:54px;padding:12px 16px;font-size:1.8rem;border-radius:8px}.gh-signin .gh-input::placeholder{color:#abb4be;font-weight:400;opacity:1}.gh-signin .gh-input::-webkit-input-placeholder{color:#abb4be;font-weight:400}.gh-signin .gh-input:-ms-input-placeholder{color:#abb4be;font-weight:400}.gh-signin .gh-input::-moz-placeholder{color:#abb4be;font-weight:400;opacity:1}.gh-signin .gh-input:focus{border-color:#30cf43;box-shadow:0 0 0 3px rgba(26,170,96,.15)}.gh-signin .gh-btn{margin:0;width:100%;height:54px;max-width:unset;margin-top:32px;background:#15171a;font-weight:300;line-height:54px;border-radius:8px;transition:all .4s ease;-webkit-font-smoothing:subpixel-antialiased}.gh-signin .gh-btn span{color:#fff;font-size:1.8rem}.error-content{flex-grow:1;justify-content:center;user-select:text;padding:8vw}.error-content,.error-details{display:flex;align-items:center}.error-details{margin-bottom:4rem}.error-ghost{margin:15px;height:115px}@media (max-width:630px){.error-ghost{display:none}}.error-code{margin:0;color:#c5d2d9;font-size:10vw;font-weight:600;line-height:.9em;letter-spacing:-.4vw}.error-description{margin:0;padding:0;border:none;color:#54666d;font-size:2.3rem;font-weight:300;line-height:1.3em}.error-message{display:flex;flex-direction:column;margin:15px;align-items:center}.error-message a{font-size:1.4rem;line-height:1;margin:8px 0}.error-link{background-color:transparent;color:#5ba4e5;transition:background .3s,color .3s;text-decoration:none}.error-stack{margin:1rem auto;padding:2rem;max-width:800px;background-color:hsla(0,0%,100%,.3)}.error-stack-list{margin:0;padding:0;list-style-type:none}.error-stack-list li{display:block}.error-stack-list li:before{content:"\21AA";display:inline-block;margin-right:.5rem;color:#bbb;font-size:1.2rem}.error-stack-function{font-weight:700}
@@ -42,7 +42,18 @@
42
42
  text = count;
43
43
  }
44
44
  }
45
- e.insertAdjacentText('afterend', text);
45
+ if (text) {
46
+ if (e.dataset.ghostCommentCountAutowrap !== 'false') {
47
+ const el = document.createElement(e.dataset.ghostCommentCountTag);
48
+ if (e.dataset.ghostCommentCountClassName) {
49
+ el.classList.add(e.dataset.ghostCommentCountClassName);
50
+ }
51
+ el.textContent = text;
52
+ e.insertAdjacentElement('afterend', el);
53
+ } else {
54
+ e.insertAdjacentText('afterend', text);
55
+ }
56
+ }
46
57
  e.remove();
47
58
  });
48
59
  }
@@ -3,7 +3,7 @@ const tpl = require('@tryghost/tpl');
3
3
  const errors = require('@tryghost/errors');
4
4
  const models = require('../../models');
5
5
  const commentsService = require('../../services/comments');
6
- const ALLOWED_INCLUDES = ['post', 'member', 'likes', 'replies', 'parent'];
6
+ const ALLOWED_INCLUDES = ['member', 'replies', 'replies.member', 'replies.count.likes', 'replies.liked', 'count.replies', 'count.likes', 'liked', 'post', 'parent'];
7
7
  const UNSAFE_ATTRS = ['status'];
8
8
 
9
9
  const messages = {
@@ -37,6 +37,28 @@ module.exports = {
37
37
  }
38
38
  },
39
39
 
40
+ replies: {
41
+ options: [
42
+ 'include',
43
+ 'page',
44
+ 'limit',
45
+ 'fields',
46
+ 'filter',
47
+ 'order',
48
+ 'debug',
49
+ 'id'
50
+ ],
51
+ validation: {
52
+ options: {
53
+ include: ALLOWED_INCLUDES
54
+ }
55
+ },
56
+ permissions: 'browse',
57
+ query(frame) {
58
+ return commentsService.controller.replies(frame);
59
+ }
60
+ },
61
+
40
62
  read: {
41
63
  options: [
42
64
  'include'
@@ -1,4 +1,4 @@
1
- const shared = require('../shared');
1
+ const apiFramework = require('@tryghost/api-framework');
2
2
  const localUtils = require('./utils');
3
3
 
4
4
  // ESLint Override Notice
@@ -9,19 +9,19 @@ const localUtils = require('./utils');
9
9
 
10
10
  module.exports = {
11
11
  get authentication() {
12
- return shared.pipeline(require('./authentication'), localUtils);
12
+ return apiFramework.pipeline(require('./authentication'), localUtils);
13
13
  },
14
14
 
15
15
  get db() {
16
- return shared.pipeline(require('./db'), localUtils);
16
+ return apiFramework.pipeline(require('./db'), localUtils);
17
17
  },
18
18
 
19
19
  get identities() {
20
- return shared.pipeline(require('./identities'), localUtils);
20
+ return apiFramework.pipeline(require('./identities'), localUtils);
21
21
  },
22
22
 
23
23
  get integrations() {
24
- return shared.pipeline(require('./integrations'), localUtils);
24
+ return apiFramework.pipeline(require('./integrations'), localUtils);
25
25
  },
26
26
 
27
27
  // @TODO: transform
@@ -30,147 +30,147 @@ module.exports = {
30
30
  },
31
31
 
32
32
  get schedules() {
33
- return shared.pipeline(require('./schedules'), localUtils);
33
+ return apiFramework.pipeline(require('./schedules'), localUtils);
34
34
  },
35
35
 
36
36
  get pages() {
37
- return shared.pipeline(require('./pages'), localUtils);
37
+ return apiFramework.pipeline(require('./pages'), localUtils);
38
38
  },
39
39
 
40
40
  get redirects() {
41
- return shared.pipeline(require('./redirects'), localUtils);
41
+ return apiFramework.pipeline(require('./redirects'), localUtils);
42
42
  },
43
43
 
44
44
  get roles() {
45
- return shared.pipeline(require('./roles'), localUtils);
45
+ return apiFramework.pipeline(require('./roles'), localUtils);
46
46
  },
47
47
 
48
48
  get slugs() {
49
- return shared.pipeline(require('./slugs'), localUtils);
49
+ return apiFramework.pipeline(require('./slugs'), localUtils);
50
50
  },
51
51
 
52
52
  get webhooks() {
53
- return shared.pipeline(require('./webhooks'), localUtils);
53
+ return apiFramework.pipeline(require('./webhooks'), localUtils);
54
54
  },
55
55
 
56
56
  get posts() {
57
- return shared.pipeline(require('./posts'), localUtils);
57
+ return apiFramework.pipeline(require('./posts'), localUtils);
58
58
  },
59
59
 
60
60
  get invites() {
61
- return shared.pipeline(require('./invites'), localUtils);
61
+ return apiFramework.pipeline(require('./invites'), localUtils);
62
62
  },
63
63
 
64
64
  get mail() {
65
- return shared.pipeline(require('./mail'), localUtils);
65
+ return apiFramework.pipeline(require('./mail'), localUtils);
66
66
  },
67
67
 
68
68
  get notifications() {
69
- return shared.pipeline(require('./notifications'), localUtils);
69
+ return apiFramework.pipeline(require('./notifications'), localUtils);
70
70
  },
71
71
 
72
72
  get settings() {
73
- return shared.pipeline(require('./settings'), localUtils);
73
+ return apiFramework.pipeline(require('./settings'), localUtils);
74
74
  },
75
75
 
76
76
  get membersStripeConnect() {
77
- return shared.pipeline(require('./members-stripe-connect'), localUtils);
77
+ return apiFramework.pipeline(require('./members-stripe-connect'), localUtils);
78
78
  },
79
79
 
80
80
  get members() {
81
- return shared.pipeline(require('./members'), localUtils);
81
+ return apiFramework.pipeline(require('./members'), localUtils);
82
82
  },
83
83
 
84
84
  get offers() {
85
- return shared.pipeline(require('./offers'), localUtils);
85
+ return apiFramework.pipeline(require('./offers'), localUtils);
86
86
  },
87
87
 
88
88
  get tiers() {
89
- return shared.pipeline(require('./tiers'), localUtils);
89
+ return apiFramework.pipeline(require('./tiers'), localUtils);
90
90
  },
91
91
 
92
92
  get memberSigninUrls() {
93
- return shared.pipeline(require('./member-signin-urls.js'), localUtils);
93
+ return apiFramework.pipeline(require('./member-signin-urls.js'), localUtils);
94
94
  },
95
95
 
96
96
  get labels() {
97
- return shared.pipeline(require('./labels'), localUtils);
97
+ return apiFramework.pipeline(require('./labels'), localUtils);
98
98
  },
99
99
 
100
100
  get images() {
101
- return shared.pipeline(require('./images'), localUtils);
101
+ return apiFramework.pipeline(require('./images'), localUtils);
102
102
  },
103
103
 
104
104
  get media() {
105
- return shared.pipeline(require('./media'), localUtils);
105
+ return apiFramework.pipeline(require('./media'), localUtils);
106
106
  },
107
107
 
108
108
  get files() {
109
- return shared.pipeline(require('./files'), localUtils);
109
+ return apiFramework.pipeline(require('./files'), localUtils);
110
110
  },
111
111
 
112
112
  get tags() {
113
- return shared.pipeline(require('./tags'), localUtils);
113
+ return apiFramework.pipeline(require('./tags'), localUtils);
114
114
  },
115
115
 
116
116
  get users() {
117
- return shared.pipeline(require('./users'), localUtils);
117
+ return apiFramework.pipeline(require('./users'), localUtils);
118
118
  },
119
119
 
120
120
  get previews() {
121
- return shared.pipeline(require('./previews'), localUtils);
121
+ return apiFramework.pipeline(require('./previews'), localUtils);
122
122
  },
123
123
 
124
124
  get emailPost() {
125
- return shared.pipeline(require('./email-post'), localUtils);
125
+ return apiFramework.pipeline(require('./email-post'), localUtils);
126
126
  },
127
127
 
128
128
  get oembed() {
129
- return shared.pipeline(require('./oembed'), localUtils);
129
+ return apiFramework.pipeline(require('./oembed'), localUtils);
130
130
  },
131
131
 
132
132
  get slack() {
133
- return shared.pipeline(require('./slack'), localUtils);
133
+ return apiFramework.pipeline(require('./slack'), localUtils);
134
134
  },
135
135
 
136
136
  get config() {
137
- return shared.pipeline(require('./config'), localUtils);
137
+ return apiFramework.pipeline(require('./config'), localUtils);
138
138
  },
139
139
 
140
140
  get explore() {
141
- return shared.pipeline(require('./explore'), localUtils);
141
+ return apiFramework.pipeline(require('./explore'), localUtils);
142
142
  },
143
143
 
144
144
  get themes() {
145
- return shared.pipeline(require('./themes'), localUtils);
145
+ return apiFramework.pipeline(require('./themes'), localUtils);
146
146
  },
147
147
 
148
148
  get actions() {
149
- return shared.pipeline(require('./actions'), localUtils);
149
+ return apiFramework.pipeline(require('./actions'), localUtils);
150
150
  },
151
151
 
152
152
  get email_previews() {
153
- return shared.pipeline(require('./email-previews'), localUtils);
153
+ return apiFramework.pipeline(require('./email-previews'), localUtils);
154
154
  },
155
155
 
156
156
  get emails() {
157
- return shared.pipeline(require('./emails'), localUtils);
157
+ return apiFramework.pipeline(require('./emails'), localUtils);
158
158
  },
159
159
 
160
160
  get site() {
161
- return shared.pipeline(require('./site'), localUtils);
161
+ return apiFramework.pipeline(require('./site'), localUtils);
162
162
  },
163
163
 
164
164
  get snippets() {
165
- return shared.pipeline(require('./snippets'), localUtils);
165
+ return apiFramework.pipeline(require('./snippets'), localUtils);
166
166
  },
167
167
 
168
168
  get stats() {
169
- return shared.pipeline(require('./stats'), localUtils);
169
+ return apiFramework.pipeline(require('./stats'), localUtils);
170
170
  },
171
171
 
172
172
  get customThemeSettings() {
173
- return shared.pipeline(require('./custom-theme-settings'), localUtils);
173
+ return apiFramework.pipeline(require('./custom-theme-settings'), localUtils);
174
174
  },
175
175
 
176
176
  get serializers() {
@@ -178,11 +178,11 @@ module.exports = {
178
178
  },
179
179
 
180
180
  get newsletters() {
181
- return shared.pipeline(require('./newsletters'), localUtils);
181
+ return apiFramework.pipeline(require('./newsletters'), localUtils);
182
182
  },
183
183
 
184
184
  get comments() {
185
- return shared.pipeline(require('./comments'), localUtils);
185
+ return apiFramework.pipeline(require('./comments'), localUtils);
186
186
  },
187
187
 
188
188
  /**
@@ -194,38 +194,38 @@ module.exports = {
194
194
  * `api.admin` soon. Need to figure out how serializers & validation works then.
195
195
  */
196
196
  get pagesPublic() {
197
- return shared.pipeline(require('./pages-public'), localUtils, 'content');
197
+ return apiFramework.pipeline(require('./pages-public'), localUtils, 'content');
198
198
  },
199
199
 
200
200
  get tagsPublic() {
201
- return shared.pipeline(require('./tags-public'), localUtils, 'content');
201
+ return apiFramework.pipeline(require('./tags-public'), localUtils, 'content');
202
202
  },
203
203
 
204
204
  get publicSettings() {
205
- return shared.pipeline(require('./settings-public'), localUtils, 'content');
205
+ return apiFramework.pipeline(require('./settings-public'), localUtils, 'content');
206
206
  },
207
207
 
208
208
  get postsPublic() {
209
- return shared.pipeline(require('./posts-public'), localUtils, 'content');
209
+ return apiFramework.pipeline(require('./posts-public'), localUtils, 'content');
210
210
  },
211
211
 
212
212
  get authorsPublic() {
213
- return shared.pipeline(require('./authors-public'), localUtils, 'content');
213
+ return apiFramework.pipeline(require('./authors-public'), localUtils, 'content');
214
214
  },
215
215
 
216
216
  get tiersPublic() {
217
- return shared.pipeline(require('./tiers-public'), localUtils, 'content');
217
+ return apiFramework.pipeline(require('./tiers-public'), localUtils, 'content');
218
218
  },
219
219
 
220
220
  get newslettersPublic() {
221
- return shared.pipeline(require('./newsletters-public'), localUtils, 'content');
221
+ return apiFramework.pipeline(require('./newsletters-public'), localUtils, 'content');
222
222
  },
223
223
 
224
224
  get offersPublic() {
225
- return shared.pipeline(require('./offers-public'), localUtils, 'content');
225
+ return apiFramework.pipeline(require('./offers-public'), localUtils, 'content');
226
226
  },
227
227
 
228
228
  get commentsMembers() {
229
- return shared.pipeline(require('./comments-members'), localUtils, 'members');
229
+ return apiFramework.pipeline(require('./comments-members'), localUtils, 'members');
230
230
  }
231
231
  };
@@ -0,0 +1,18 @@
1
+ module.exports = {
2
+ all(_apiConfig, frame) {
3
+ if (!frame.options.withRelated || frame.options.withRelated.length === 0) {
4
+ return;
5
+ }
6
+
7
+ // Map the 'liked' relation to 'count.liked'
8
+ frame.options.withRelated = frame.options.withRelated.map((relation) => {
9
+ if (relation === 'liked') {
10
+ return 'count.liked';
11
+ }
12
+ if (relation === 'replies.liked') {
13
+ return 'replies.count.liked';
14
+ }
15
+ return relation;
16
+ });
17
+ }
18
+ };
@@ -1,6 +1,6 @@
1
1
  const _ = require('lodash');
2
2
  const debug = require('@tryghost/debug')('api:endpoints:utils:serializers:input:db');
3
- const optionsUtil = require('../../../../shared/utils/options');
3
+ const optionsUtil = require('@tryghost/api-framework').utils.options;
4
4
 
5
5
  const INTERNAL_OPTIONS = ['transacting', 'forUpdate'];
6
6
 
@@ -45,5 +45,9 @@ module.exports = {
45
45
 
46
46
  get webhooks() {
47
47
  return require('./webhooks');
48
+ },
49
+
50
+ get comments() {
51
+ return require('./comments');
48
52
  }
49
53
  };
@@ -3,9 +3,9 @@ const debug = require('@tryghost/debug')('api:endpoints:utils:serializers:input:
3
3
 
4
4
  function setDefaultFilter(frame) {
5
5
  if (frame.options.filter) {
6
- frame.options.filter = `(${frame.options.filter})+type:[custom,builtin]`;
6
+ frame.options.filter = `(${frame.options.filter})+type:[custom,builtin,core]`;
7
7
  } else {
8
- frame.options.filter = 'type:[custom,builtin]';
8
+ frame.options.filter = 'type:[custom,builtin,core]';
9
9
  }
10
10
  }
11
11
 
@@ -24,7 +24,7 @@ function convertTierInput(input) {
24
24
  };
25
25
 
26
26
  if (labs.isSet('freeTrial')) {
27
- converted.trial_days = input.trial_days;
27
+ converted.trial_days = input.trial_days || 0;
28
28
  }
29
29
 
30
30
  if (input.monthly_price && input.currency) {
@@ -25,6 +25,11 @@ const postFields = [
25
25
  'url'
26
26
  ];
27
27
 
28
+ const countFields = [
29
+ 'replies',
30
+ 'likes'
31
+ ];
32
+
28
33
  const commentMapper = (model, frame) => {
29
34
  const jsonModel = model.toJSON ? model.toJSON(frame.options) : model;
30
35
 
@@ -36,12 +41,6 @@ const commentMapper = (model, frame) => {
36
41
  response.member = null;
37
42
  }
38
43
 
39
- if (jsonModel.likes) {
40
- response.likes_count = jsonModel.likes.length;
41
- } else {
42
- response.likes_count = 0;
43
- }
44
-
45
44
  if (jsonModel.replies) {
46
45
  response.replies = jsonModel.replies.map(reply => commentMapper(reply, frame));
47
46
  }
@@ -56,11 +55,12 @@ const commentMapper = (model, frame) => {
56
55
  response.post = _.pick(jsonModel.post, postFields);
57
56
  }
58
57
 
59
- // todo
60
- response.liked = false;
61
- if (jsonModel.likes && frame.original.context.member && frame.original.context.member.id) {
62
- const id = frame.original.context.member.id;
63
- response.liked = !!jsonModel.likes.find(l => l.member_id === id);
58
+ if (jsonModel.count && jsonModel.count.liked !== undefined) {
59
+ response.liked = jsonModel.count.liked > 0;
60
+ }
61
+
62
+ if (jsonModel.count) {
63
+ response.count = _.pick(jsonModel.count, countFields);
64
64
  }
65
65
 
66
66
  if (utils.isMembersAPI(frame)) {
@@ -68,7 +68,7 @@ const commentMapper = (model, frame) => {
68
68
  response.html = null;
69
69
  }
70
70
  }
71
-
71
+
72
72
  return response;
73
73
  };
74
74