ghost 5.54.3 → 5.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/components/tryghost-adapter-cache-memory-ttl-5.55.0.tgz +0 -0
  2. package/components/tryghost-adapter-cache-redis-5.55.0.tgz +0 -0
  3. package/components/{tryghost-adapter-manager-5.54.3.tgz → tryghost-adapter-manager-5.55.0.tgz} +0 -0
  4. package/components/tryghost-announcement-bar-settings-5.55.0.tgz +0 -0
  5. package/components/{tryghost-api-framework-5.54.3.tgz → tryghost-api-framework-5.55.0.tgz} +0 -0
  6. package/components/tryghost-api-version-compatibility-service-5.55.0.tgz +0 -0
  7. package/components/tryghost-audience-feedback-5.55.0.tgz +0 -0
  8. package/components/tryghost-bootstrap-socket-5.55.0.tgz +0 -0
  9. package/components/tryghost-collections-5.55.0.tgz +0 -0
  10. package/components/tryghost-constants-5.55.0.tgz +0 -0
  11. package/components/tryghost-custom-theme-settings-service-5.55.0.tgz +0 -0
  12. package/components/{tryghost-data-generator-5.54.3.tgz → tryghost-data-generator-5.55.0.tgz} +0 -0
  13. package/components/tryghost-domain-events-5.55.0.tgz +0 -0
  14. package/components/tryghost-dynamic-routing-events-5.55.0.tgz +0 -0
  15. package/components/tryghost-email-analytics-provider-mailgun-5.55.0.tgz +0 -0
  16. package/components/tryghost-email-analytics-service-5.55.0.tgz +0 -0
  17. package/components/tryghost-email-content-generator-5.55.0.tgz +0 -0
  18. package/components/tryghost-email-events-5.55.0.tgz +0 -0
  19. package/components/tryghost-email-service-5.55.0.tgz +0 -0
  20. package/components/tryghost-email-suppression-list-5.55.0.tgz +0 -0
  21. package/components/tryghost-event-aware-cache-wrapper-5.55.0.tgz +0 -0
  22. package/components/tryghost-express-dynamic-redirects-5.55.0.tgz +0 -0
  23. package/components/{tryghost-external-media-inliner-5.54.3.tgz → tryghost-external-media-inliner-5.55.0.tgz} +0 -0
  24. package/components/{tryghost-extract-api-key-5.54.3.tgz → tryghost-extract-api-key-5.55.0.tgz} +0 -0
  25. package/components/tryghost-html-to-plaintext-5.55.0.tgz +0 -0
  26. package/components/tryghost-i18n-5.55.0.tgz +0 -0
  27. package/components/{tryghost-importer-handler-content-files-5.54.3.tgz → tryghost-importer-handler-content-files-5.55.0.tgz} +0 -0
  28. package/components/{tryghost-importer-revue-5.54.3.tgz → tryghost-importer-revue-5.55.0.tgz} +0 -0
  29. package/components/tryghost-in-memory-repository-5.55.0.tgz +0 -0
  30. package/components/{tryghost-job-manager-5.54.3.tgz → tryghost-job-manager-5.55.0.tgz} +0 -0
  31. package/components/tryghost-link-redirects-5.55.0.tgz +0 -0
  32. package/components/{tryghost-link-replacer-5.54.3.tgz → tryghost-link-replacer-5.55.0.tgz} +0 -0
  33. package/components/tryghost-link-tracking-5.55.0.tgz +0 -0
  34. package/components/{tryghost-magic-link-5.54.3.tgz → tryghost-magic-link-5.55.0.tgz} +0 -0
  35. package/components/tryghost-mail-events-5.55.0.tgz +0 -0
  36. package/components/tryghost-mailgun-client-5.55.0.tgz +0 -0
  37. package/components/{tryghost-member-attribution-5.54.3.tgz → tryghost-member-attribution-5.55.0.tgz} +0 -0
  38. package/components/tryghost-member-events-5.55.0.tgz +0 -0
  39. package/components/tryghost-members-api-5.55.0.tgz +0 -0
  40. package/components/tryghost-members-csv-5.55.0.tgz +0 -0
  41. package/components/{tryghost-members-events-service-5.54.3.tgz → tryghost-members-events-service-5.55.0.tgz} +0 -0
  42. package/components/tryghost-members-importer-5.55.0.tgz +0 -0
  43. package/components/tryghost-members-offers-5.55.0.tgz +0 -0
  44. package/components/tryghost-members-payments-5.55.0.tgz +0 -0
  45. package/components/tryghost-members-ssr-5.55.0.tgz +0 -0
  46. package/components/tryghost-members-stripe-service-5.55.0.tgz +0 -0
  47. package/components/tryghost-mentions-email-report-5.55.0.tgz +0 -0
  48. package/components/tryghost-milestones-5.55.0.tgz +0 -0
  49. package/components/tryghost-minifier-5.55.0.tgz +0 -0
  50. package/components/tryghost-model-to-domain-event-interceptor-5.55.0.tgz +0 -0
  51. package/components/tryghost-mw-api-version-mismatch-5.55.0.tgz +0 -0
  52. package/components/tryghost-mw-cache-control-5.55.0.tgz +0 -0
  53. package/components/{tryghost-mw-error-handler-5.54.3.tgz → tryghost-mw-error-handler-5.55.0.tgz} +0 -0
  54. package/components/tryghost-mw-session-from-token-5.55.0.tgz +0 -0
  55. package/components/tryghost-mw-update-user-last-seen-5.55.0.tgz +0 -0
  56. package/components/tryghost-mw-version-match-5.55.0.tgz +0 -0
  57. package/components/tryghost-mw-vhost-5.55.0.tgz +0 -0
  58. package/components/tryghost-oembed-service-5.55.0.tgz +0 -0
  59. package/components/{tryghost-package-json-5.54.3.tgz → tryghost-package-json-5.55.0.tgz} +0 -0
  60. package/components/tryghost-post-revisions-5.55.0.tgz +0 -0
  61. package/components/tryghost-posts-service-5.55.0.tgz +0 -0
  62. package/components/tryghost-referrers-5.55.0.tgz +0 -0
  63. package/components/{tryghost-security-5.54.3.tgz → tryghost-security-5.55.0.tgz} +0 -0
  64. package/components/tryghost-session-service-5.55.0.tgz +0 -0
  65. package/components/tryghost-settings-path-manager-5.55.0.tgz +0 -0
  66. package/components/tryghost-slack-notifications-5.55.0.tgz +0 -0
  67. package/components/{tryghost-staff-service-5.54.3.tgz → tryghost-staff-service-5.55.0.tgz} +0 -0
  68. package/components/tryghost-stats-service-5.55.0.tgz +0 -0
  69. package/components/{tryghost-tiers-5.54.3.tgz → tryghost-tiers-5.55.0.tgz} +0 -0
  70. package/components/tryghost-update-check-service-5.55.0.tgz +0 -0
  71. package/components/tryghost-verification-trigger-5.55.0.tgz +0 -0
  72. package/components/tryghost-version-notifications-data-service-5.55.0.tgz +0 -0
  73. package/components/{tryghost-webmentions-5.54.3.tgz → tryghost-webmentions-5.55.0.tgz} +0 -0
  74. package/content/themes/casper/assets/built/screen.css +1 -1
  75. package/content/themes/casper/assets/built/screen.css.map +1 -1
  76. package/content/themes/casper/assets/css/screen.css +22 -6
  77. package/content/themes/casper/page.hbs +26 -24
  78. package/core/built/admin/assets/{chunk.143.fbb46d934931ab3f351d.js → chunk.143.60a057de7aaa4abc6a26.js} +6 -7
  79. package/core/built/admin/assets/{chunk.178.aef0c4fe1860cee21418.js → chunk.178.f18f14cc0e6c67a6fd36.js} +4 -4
  80. package/core/built/admin/assets/{chunk.486.3896d2a7816cf03a0794.js → chunk.757.c768dcbeaf1cee916395.js} +1146 -1360
  81. package/core/built/admin/assets/{ghost-14eecea754ec854244d71e1300ec75f2.js → ghost-135607a3c421c472feb9f59f14c625fb.js} +782 -901
  82. package/core/built/admin/assets/{vendor-0d244308df4eb04209cbd5fa6abe358b.js → vendor-0a8fc851393c473cd269f04fc4e97974.js} +2167 -2552
  83. package/core/built/admin/index.html +5 -5
  84. package/core/frontend/helpers/collection.js +146 -0
  85. package/core/frontend/public/ghost.min.css +1 -0
  86. package/core/frontend/src/cards/css/header_v2.css +283 -0
  87. package/core/frontend/src/cards/css/signup.css +1 -0
  88. package/core/server/api/endpoints/collections.js +0 -19
  89. package/core/server/api/endpoints/posts-public.js +5 -2
  90. package/core/server/api/endpoints/utils/serializers/output/index.js +0 -4
  91. package/core/server/data/migrations/versions/5.55/2023-07-10-05-15-55-add-built-in-collections.js +60 -0
  92. package/core/server/data/migrations/versions/5.55/2023-07-10-05-16-55-add-built-in-collection-posts.js +99 -0
  93. package/core/server/data/schema/fixtures/fixtures.json +33 -0
  94. package/core/server/lib/lexical.js +2 -2
  95. package/core/server/models/post.js +1 -1
  96. package/core/server/services/collections/BookshelfCollectionsRepository.js +39 -10
  97. package/core/server/services/collections/PostsRepository.js +17 -52
  98. package/core/server/services/collections/service.js +4 -24
  99. package/core/server/web/api/endpoints/admin/routes.js +0 -1
  100. package/package.json +145 -144
  101. package/yarn.lock +1820 -1678
  102. package/components/tryghost-adapter-cache-memory-ttl-5.54.3.tgz +0 -0
  103. package/components/tryghost-adapter-cache-redis-5.54.3.tgz +0 -0
  104. package/components/tryghost-announcement-bar-settings-5.54.3.tgz +0 -0
  105. package/components/tryghost-api-version-compatibility-service-5.54.3.tgz +0 -0
  106. package/components/tryghost-audience-feedback-5.54.3.tgz +0 -0
  107. package/components/tryghost-bootstrap-socket-5.54.3.tgz +0 -0
  108. package/components/tryghost-collections-5.54.3.tgz +0 -0
  109. package/components/tryghost-constants-5.54.3.tgz +0 -0
  110. package/components/tryghost-custom-theme-settings-service-5.54.3.tgz +0 -0
  111. package/components/tryghost-domain-events-5.54.3.tgz +0 -0
  112. package/components/tryghost-dynamic-routing-events-5.54.3.tgz +0 -0
  113. package/components/tryghost-email-analytics-provider-mailgun-5.54.3.tgz +0 -0
  114. package/components/tryghost-email-analytics-service-5.54.3.tgz +0 -0
  115. package/components/tryghost-email-content-generator-5.54.3.tgz +0 -0
  116. package/components/tryghost-email-events-5.54.3.tgz +0 -0
  117. package/components/tryghost-email-service-5.54.3.tgz +0 -0
  118. package/components/tryghost-email-suppression-list-5.54.3.tgz +0 -0
  119. package/components/tryghost-event-aware-cache-wrapper-5.54.3.tgz +0 -0
  120. package/components/tryghost-express-dynamic-redirects-5.54.3.tgz +0 -0
  121. package/components/tryghost-html-to-plaintext-5.54.3.tgz +0 -0
  122. package/components/tryghost-i18n-5.54.3.tgz +0 -0
  123. package/components/tryghost-in-memory-repository-5.54.3.tgz +0 -0
  124. package/components/tryghost-link-redirects-5.54.3.tgz +0 -0
  125. package/components/tryghost-link-tracking-5.54.3.tgz +0 -0
  126. package/components/tryghost-mail-events-5.54.3.tgz +0 -0
  127. package/components/tryghost-mailgun-client-5.54.3.tgz +0 -0
  128. package/components/tryghost-member-events-5.54.3.tgz +0 -0
  129. package/components/tryghost-members-api-5.54.3.tgz +0 -0
  130. package/components/tryghost-members-csv-5.54.3.tgz +0 -0
  131. package/components/tryghost-members-importer-5.54.3.tgz +0 -0
  132. package/components/tryghost-members-offers-5.54.3.tgz +0 -0
  133. package/components/tryghost-members-payments-5.54.3.tgz +0 -0
  134. package/components/tryghost-members-ssr-5.54.3.tgz +0 -0
  135. package/components/tryghost-members-stripe-service-5.54.3.tgz +0 -0
  136. package/components/tryghost-mentions-email-report-5.54.3.tgz +0 -0
  137. package/components/tryghost-milestones-5.54.3.tgz +0 -0
  138. package/components/tryghost-minifier-5.54.3.tgz +0 -0
  139. package/components/tryghost-model-to-domain-event-interceptor-5.54.3.tgz +0 -0
  140. package/components/tryghost-mw-api-version-mismatch-5.54.3.tgz +0 -0
  141. package/components/tryghost-mw-cache-control-5.54.3.tgz +0 -0
  142. package/components/tryghost-mw-session-from-token-5.54.3.tgz +0 -0
  143. package/components/tryghost-mw-update-user-last-seen-5.54.3.tgz +0 -0
  144. package/components/tryghost-mw-version-match-5.54.3.tgz +0 -0
  145. package/components/tryghost-mw-vhost-5.54.3.tgz +0 -0
  146. package/components/tryghost-oembed-service-5.54.3.tgz +0 -0
  147. package/components/tryghost-post-revisions-5.54.3.tgz +0 -0
  148. package/components/tryghost-posts-service-5.54.3.tgz +0 -0
  149. package/components/tryghost-referrers-5.54.3.tgz +0 -0
  150. package/components/tryghost-session-service-5.54.3.tgz +0 -0
  151. package/components/tryghost-settings-path-manager-5.54.3.tgz +0 -0
  152. package/components/tryghost-slack-notifications-5.54.3.tgz +0 -0
  153. package/components/tryghost-stats-service-5.54.3.tgz +0 -0
  154. package/components/tryghost-update-check-service-5.54.3.tgz +0 -0
  155. package/components/tryghost-verification-trigger-5.54.3.tgz +0 -0
  156. package/components/tryghost-version-notifications-data-service-5.54.3.tgz +0 -0
  157. package/core/server/api/endpoints/utils/serializers/output/collections.js +0 -10
  158. /package/core/built/admin/assets/{chunk.486.3896d2a7816cf03a0794.js.LICENSE.txt → chunk.757.c768dcbeaf1cee916395.js.LICENSE.txt} +0 -0
@@ -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%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.54%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22ember-websockets%22%3A%7B%22socketIO%22%3Atrue%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%7D" />
11
+ <meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%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.55%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22ember-websockets%22%3A%7B%22socketIO%22%3Atrue%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%7D" />
12
12
 
13
13
  <meta name="HandheldFriendly" content="True" />
14
14
  <meta name="MobileOptimized" content="320" />
@@ -56,9 +56,9 @@
56
56
 
57
57
  <div id="ember-basic-dropdown-wormhole"></div>
58
58
 
59
- <script src="assets/vendor-0d244308df4eb04209cbd5fa6abe358b.js"></script>
60
- <script src="assets/chunk.486.3896d2a7816cf03a0794.js"></script>
61
- <script src="assets/chunk.143.fbb46d934931ab3f351d.js"></script>
62
- <script src="assets/ghost-14eecea754ec854244d71e1300ec75f2.js"></script>
59
+ <script src="assets/vendor-0a8fc851393c473cd269f04fc4e97974.js"></script>
60
+ <script src="assets/chunk.757.c768dcbeaf1cee916395.js"></script>
61
+ <script src="assets/chunk.143.60a057de7aaa4abc6a26.js"></script>
62
+ <script src="assets/ghost-135607a3c421c472feb9f59f14c625fb.js"></script>
63
63
  </body>
64
64
  </html>
@@ -0,0 +1,146 @@
1
+ // # Get Helper
2
+ // Usage: `{{#get "posts" limit="5"}}`, `{{#get "tags" limit="all"}}`
3
+ // Fetches data from the API
4
+ const {config, api, prepareContextResource} = require('../services/proxy');
5
+ const {hbs} = require('../services/handlebars');
6
+
7
+ const logging = require('@tryghost/logging');
8
+ const errors = require('@tryghost/errors');
9
+ const tpl = require('@tryghost/tpl');
10
+
11
+ const messages = {
12
+ mustBeCalledAsBlock: 'The {\\{{helperName}}} helper must be called as a block. E.g. {{#{helperName}}}...{{/{helperName}}}',
13
+ invalidResource: 'Invalid "{resource}" resource given to get helper'
14
+ };
15
+
16
+ const createFrame = hbs.handlebars.createFrame;
17
+
18
+ /**
19
+ * ## Parse Options
20
+ * Ensure options passed in make sense
21
+ *
22
+ * @param {Object} options
23
+ * @returns {*}
24
+ */
25
+ function parseOptions(options) {
26
+ if (options.limit === 'all' || !options.limit) {
27
+ return {
28
+ limit: 3
29
+ };
30
+ }
31
+
32
+ return {
33
+ limit: options.limit
34
+ };
35
+ }
36
+
37
+ /**
38
+ *
39
+ * @param {String} resource
40
+ * @param {String} controllerName
41
+ * @param {String} action
42
+ * @param {Object} apiOptions
43
+ * @returns {Promise<Object>}
44
+ */
45
+ async function makeAPICall(resource, controllerName, action, apiOptions) {
46
+ const controller = api[controllerName];
47
+
48
+ let timer;
49
+
50
+ try {
51
+ let response;
52
+
53
+ if (config.get('optimization:getHelper:timeout:threshold')) {
54
+ const logLevel = config.get('optimization:getHelper:timeout:level') || 'error';
55
+ const threshold = config.get('optimization:getHelper:timeout:threshold');
56
+
57
+ const apiResponse = controller[action](apiOptions);
58
+
59
+ const timeout = new Promise((resolve) => {
60
+ timer = setTimeout(() => {
61
+ logging[logLevel](new errors.HelperWarning({
62
+ message: `{{#get}} took longer than ${threshold}ms and was aborted`,
63
+ code: 'ABORTED_GET_HELPER',
64
+ errorDetails: {
65
+ api: `${controllerName}.${action}`,
66
+ apiOptions
67
+ }
68
+ }));
69
+
70
+ resolve({[resource]: []});
71
+ }, threshold);
72
+ });
73
+
74
+ response = await Promise.race([apiResponse, timeout]);
75
+ clearTimeout(timer);
76
+ } else {
77
+ response = await controller[action](apiOptions);
78
+ }
79
+
80
+ return response;
81
+ } catch (err) {
82
+ clearTimeout(timer);
83
+ throw err;
84
+ }
85
+ }
86
+
87
+ /**
88
+ * ## Get
89
+ * @param {string} slug
90
+ * @param {object} options
91
+ * @returns {Promise<any>}
92
+ */
93
+ module.exports = async function collection(slug, options) {
94
+ options = options || {};
95
+ options.hash = options.hash || {};
96
+ options.data = options.data || {};
97
+
98
+ const self = this;
99
+ const data = createFrame(options.data);
100
+
101
+ let apiOptions = options.hash;
102
+
103
+ if (!options.fn) {
104
+ data.error = tpl(messages.mustBeCalledAsBlock, {helperName: 'collection'});
105
+ logging.warn(data.error);
106
+ return;
107
+ }
108
+
109
+ const resource = 'posts';
110
+ const controllerName = 'postsPublic';
111
+ const action = 'browse';
112
+
113
+ // Parse the options we're going to pass to the API
114
+ apiOptions = parseOptions(apiOptions);
115
+ apiOptions.context = {member: data.member};
116
+ apiOptions.collection = slug;
117
+
118
+ try {
119
+ const response = await makeAPICall(resource, controllerName, action, apiOptions);
120
+
121
+ // prepare data properties for use with handlebars
122
+ if (response[resource] && response[resource].length) {
123
+ response[resource].forEach(prepareContextResource);
124
+ }
125
+
126
+ // block params allows the theme developer to name the data using something like
127
+ // `{{#get "posts" as |result pageInfo|}}`
128
+ const blockParams = [response[resource]];
129
+ if (response.meta && response.meta.pagination) {
130
+ response.pagination = response.meta.pagination;
131
+ blockParams.push(response.meta.pagination);
132
+ }
133
+
134
+ // Call the main template function
135
+ return options.fn(response, {
136
+ data: data,
137
+ blockParams: blockParams
138
+ });
139
+ } catch (error) {
140
+ logging.error(error);
141
+ data.error = error.message;
142
+ return options.inverse(self, {data: data});
143
+ }
144
+ };
145
+
146
+ module.exports.async = true;
@@ -0,0 +1 @@
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}
@@ -0,0 +1,283 @@
1
+ .kg-header-card-v2 {
2
+ position: relative;
3
+ }
4
+
5
+ .kg-header-card-v2,
6
+ .kg-header-card-v2 * {
7
+ box-sizing: border-box;
8
+ }
9
+
10
+ .kg-header-card-v2 a,
11
+ .kg-header-card-v2 a span {
12
+ color: currentColor;
13
+ }
14
+
15
+ .kg-header-card-v2.kg-style-accent {
16
+ background-color: var(--ghost-accent-color);
17
+ }
18
+
19
+ .kg-layout-split .kg-header-card-v2-content {
20
+ display: grid;
21
+ grid-template-columns: 1fr 1fr;
22
+ }
23
+
24
+ .kg-header-card-v2-text {
25
+ position: relative;
26
+ display: flex;
27
+ flex-direction: column;
28
+ align-items: flex-start;
29
+ justify-content: center;
30
+ height: 100%;
31
+ padding: 4vmax;
32
+ background-size: cover;
33
+ background-position: center;
34
+ text-align: left;
35
+ }
36
+
37
+ .kg-width-wide .kg-header-card-v2-text {
38
+ padding: 6.4vmax;
39
+ }
40
+
41
+ .kg-width-full .kg-header-card-v2-text {
42
+ padding: 12vmax 0;
43
+ }
44
+
45
+ .kg-layout-split .kg-header-card-v2-text {
46
+ padding: 12vmax 4vmax;
47
+ }
48
+
49
+ .kg-layout-split.kg-content-wide .kg-header-card-v2-text {
50
+ padding: 10vmax 0 10vmax 4vmax;
51
+ }
52
+
53
+ .kg-layout-split.kg-content-wide.kg-swapped .kg-header-card-v2-text {
54
+ padding: 10vmax 4vmax 10vmax 0;
55
+ }
56
+
57
+ .kg-swapped .kg-header-card-v2-text {
58
+ grid-row: 1;
59
+ }
60
+
61
+ .kg-header-card-v2-text.kg-align-center {
62
+ align-items: center;
63
+ text-align: center;
64
+ }
65
+
66
+ .kg-header-card-v2.kg-style-image h2.kg-header-card-v2-heading,
67
+ .kg-header-card-v2.kg-style-image h3.kg-header-card-v2-subheading,
68
+ .kg-header-card-v2.kg-style-image .kg-header-card-v2-button {
69
+ z-index: 999;
70
+ }
71
+
72
+ /* Background image */
73
+
74
+ .kg-header-card-v2 > picture > .kg-header-card-v2-image {
75
+ position: absolute;
76
+ top: 0;
77
+ left: 0;
78
+ width: 100%;
79
+ height: 100%;
80
+ object-fit: cover;
81
+ object-position: center;
82
+ background-color: #FFFFFF;
83
+ pointer-events: none;
84
+ }
85
+
86
+ /* Split layout image */
87
+
88
+ .kg-header-card-v2-content .kg-header-card-v2-image {
89
+ /* this will force the image to follow the signup card height */
90
+ height: 0;
91
+ min-height: 100%;
92
+ /**/
93
+ object-fit: cover;
94
+ object-position: center;
95
+ }
96
+
97
+ .kg-content-wide .kg-header-card-v2-content .kg-header-card-v2-image {
98
+ height: 100%;
99
+ padding: 8rem 0;
100
+ object-fit: contain;
101
+ }
102
+
103
+ /* Heading */
104
+
105
+ .kg-header-card-v2 h2.kg-header-card-v2-heading {
106
+ margin: 0;
107
+ font-size: clamp(2.8rem, 4vw, 4rem);
108
+ font-weight: 700;
109
+ line-height: 1em;
110
+ letter-spacing: -0.01em;
111
+ }
112
+
113
+ .kg-header-card-v2.kg-width-wide h2.kg-header-card-v2-heading {
114
+ font-size: clamp(2.8rem, 5vw, 5.2rem);
115
+ }
116
+
117
+ .kg-header-card-v2.kg-width-full h2.kg-header-card-v2-heading {
118
+ font-size: clamp(3.6rem, 5.6vw, 6.4rem);
119
+ }
120
+
121
+ .kg-header-card-v2.kg-width-full.kg-layout-split h2.kg-header-card-v2-heading {
122
+ font-size: clamp(3.2rem, 4vw, 5.6rem);
123
+ }
124
+
125
+ .kg-header-card-v2.kg-width-full.kg-layout-split.kg-content-wide h2.kg-header-card-v2-heading {
126
+ font-size: clamp(2.8rem, 4vw, 5.2rem);
127
+ }
128
+
129
+ /* Subheading */
130
+
131
+ .kg-header-card-v2-subheading {
132
+ margin: 0 0 2em;
133
+ }
134
+
135
+ .kg-header-card-v2 h3.kg-header-card-v2-subheading {
136
+ max-width: 40em;
137
+ margin: 0;
138
+ font-size: clamp(1.05em, 2vw, 2rem);
139
+ font-weight: 500;
140
+ line-height: 1.4em;
141
+ }
142
+
143
+ .kg-header-card-v2 h2 + h3.kg-header-card-v2-subheading {
144
+ margin: 0.6em 0 0;
145
+ }
146
+
147
+ .kg-header-card-v2 h3.kg-header-card-v2-subheading strong {
148
+ font-weight: 600;
149
+ }
150
+
151
+ .kg-header-card-v2.kg-width-wide h3.kg-header-card-v2-subheading {
152
+ font-size: clamp(1.05em, 2vw, 2.4rem);
153
+ }
154
+
155
+ .kg-header-card-v2.kg-width-full h3.kg-header-card-v2-subheading:not(.kg-layout-split h3.kg-header-card-v2-subheading) {
156
+ max-width: 65vmax;
157
+ font-size: clamp(1.05em, 2vw, 2.6rem);
158
+ }
159
+
160
+ .kg-header-card-v2.kg-width-full.kg-layout-split h3.kg-header-card-v2-subheading {
161
+ font-size: clamp(1.05em, 2vw, 2.4rem);
162
+ }
163
+
164
+ .kg-width-wide .kg-header-card-v2-fields,
165
+ .kg-width-full .kg-header-card-v2-fields {
166
+ width: 100%;
167
+ max-width: 500px;
168
+ }
169
+
170
+ .kg-header-card-v2-input {
171
+ width: 100%;
172
+ height: 4.6rem;
173
+ margin-right: 3px;
174
+ padding: 12px 16px;
175
+ border: none;
176
+ font-size: 1.1em;
177
+ }
178
+
179
+ .kg-header-card-v2-input:focus,
180
+ .kg-header-card-v2-input:focus-visible {
181
+ outline: none;
182
+ }
183
+
184
+ .kg-header-card-v2-button {
185
+ display: flex;
186
+ position: relative;
187
+ align-items: center;
188
+ height: 4.6rem;
189
+ padding: 0 1.2em;
190
+ outline: none;
191
+ border: none;
192
+ font-size: 1em;
193
+ font-weight: 600;
194
+ line-height: 1em;
195
+ text-align: center;
196
+ text-decoration: none;
197
+ letter-spacing: .2px;
198
+ white-space: nowrap;
199
+ text-overflow: ellipsis;
200
+ border-radius: 3px;
201
+ transition: opacity .2s ease;
202
+ }
203
+
204
+ .kg-header-card-v2-button.kg-style-accent {
205
+ background-color: var(--ghost-accent-color);
206
+ }
207
+
208
+ .kg-header-card-v2 h2 + .kg-header-card-v2-button,
209
+ .kg-header-card-v2 h3 + .kg-header-card-v2-button {
210
+ margin: 1.5em 0 0;
211
+ }
212
+
213
+ .kg-header-card-v2 .kg-header-card-v2-button:hover {
214
+ opacity: 0.85;
215
+ }
216
+
217
+ .kg-header-card-v2.kg-width-wide .kg-header-card-v2-button {
218
+ font-size: 1.05em;
219
+ }
220
+
221
+ .kg-header-card-v2.kg-width-wide h2 + .kg-header-card-v2-button,
222
+ .kg-header-card-v2.kg-width-wide h3 + .kg-header-card-v2-button {
223
+ margin-top: 1.75em;
224
+ }
225
+
226
+ .kg-header-card-v2.kg-width-full .kg-header-card-v2-button {
227
+ font-size: 1.1em;
228
+ }
229
+
230
+ .kg-header-card-v2.kg-width-full h2 + .kg-header-card-v2-button,
231
+ .kg-header-card-v2.kg-width-full h3 + .kg-header-card-v2-button {
232
+ margin-top: 2em;
233
+ }
234
+
235
+ /* Responsive styles */
236
+
237
+ @media (max-width: 640px) {
238
+ .kg-layout-split .kg-header-card-v2-content {
239
+ grid-template-columns: 1fr;
240
+ }
241
+
242
+ .kg-width-wide .kg-header-card-v2-text {
243
+ padding: 6.4vmax 4vmax;
244
+ }
245
+
246
+ .kg-layout-split.kg-content-wide .kg-header-card-v2-text,
247
+ .kg-layout-split.kg-content-wide.kg-swapped .kg-header-card-v2-text {
248
+ padding: 9.6vmax 0;
249
+ }
250
+
251
+ .kg-header-card-v2.kg-width-full h3.kg-header-card-v2-subheading:not(.kg-layout-split h3.kg-header-card-v2-subheading) {
252
+ max-width: unset;
253
+ }
254
+
255
+ .kg-header-card-v2-content .kg-header-card-v2-image:not(.kg-content-wide .kg-header-card-v2-content .kg-header-card-v2-image) {
256
+ height: auto;
257
+ min-height: unset;
258
+ aspect-ratio: 1 / 1;
259
+ }
260
+
261
+ .kg-content-wide .kg-header-card-v2-content .kg-header-card-v2-image {
262
+ padding: 2.4rem 0 0;
263
+ }
264
+
265
+ .kg-content-wide.kg-swapped .kg-header-card-v2-content .kg-header-card-v2-image {
266
+ padding: 0 0 2.4rem;
267
+ }
268
+
269
+ .kg-header-card-v2-input {
270
+ height: 4.2rem;
271
+ padding: 6px 12px;
272
+ font-size: 1em;
273
+ }
274
+
275
+ .kg-header-card-v2-button {
276
+ height: 4.2rem;
277
+ }
278
+
279
+ .kg-header-card-v2.kg-width-wide .kg-header-card-v2-button,
280
+ .kg-header-card-v2.kg-width-full .kg-header-card-v2-button {
281
+ font-size: 1em;
282
+ }
283
+ }
@@ -210,6 +210,7 @@
210
210
  margin-right: 3px;
211
211
  padding: 12px 16px;
212
212
  border: none;
213
+ background: #FFFFFF;
213
214
  font-size: 1.1em;
214
215
  }
215
216
 
@@ -25,25 +25,6 @@ module.exports = {
25
25
  }
26
26
  },
27
27
 
28
- browsePosts: {
29
- headers: {
30
- cacheInvalidate: false
31
- },
32
- data: [
33
- 'id'
34
- ],
35
- options: [
36
- 'limit',
37
- 'page'
38
- ],
39
- permissions: {
40
- method: 'browse'
41
- },
42
- query(frame) {
43
- return collectionsService.api.getAllPosts(frame.data.id, frame.options);
44
- }
45
- },
46
-
47
28
  read: {
48
29
  headers: {
49
30
  cacheInvalidate: false
@@ -3,6 +3,8 @@ const tpl = require('@tryghost/tpl');
3
3
  const errors = require('@tryghost/errors');
4
4
  const {mapQuery} = require('@tryghost/mongo-utils');
5
5
  const postsPublicService = require('../../services/posts-public');
6
+ const getPostServiceInstance = require('../../services/posts/posts-service');
7
+ const postsService = getPostServiceInstance();
6
8
 
7
9
  const allowedIncludes = ['tags', 'authors', 'tiers', 'sentiment'];
8
10
 
@@ -38,7 +40,8 @@ module.exports = {
38
40
  'order',
39
41
  'page',
40
42
  'debug',
41
- 'absolute_urls'
43
+ 'absolute_urls',
44
+ 'collection'
42
45
  ],
43
46
  validation: {
44
47
  options: {
@@ -56,7 +59,7 @@ module.exports = {
56
59
  ...frame.options,
57
60
  mongoTransformer: rejectPrivateFieldsTransformer
58
61
  };
59
- return models.Post.findPage(options);
62
+ return postsService.browsePosts(options);
60
63
  }
61
64
  },
62
65
 
@@ -21,10 +21,6 @@ module.exports = {
21
21
  return require('./authentication');
22
22
  },
23
23
 
24
- get collections() {
25
- return require('./collections');
26
- },
27
-
28
24
  get db() {
29
25
  return require('./db');
30
26
  },
@@ -0,0 +1,60 @@
1
+ const logging = require('@tryghost/logging');
2
+ const {default: ObjectID} = require('bson-objectid');
3
+ const {createTransactionalMigration} = require('../../utils');
4
+
5
+ module.exports = createTransactionalMigration(
6
+ async function up(knex) {
7
+ logging.info('Creating built in collections');
8
+
9
+ const existingLatestCollection = await knex('collections')
10
+ .where({
11
+ slug: 'latest'
12
+ })
13
+ .first();
14
+
15
+ if (existingLatestCollection) {
16
+ logging.warn('Latest collection already exists, skipping');
17
+ } else {
18
+ await knex('collections').insert({
19
+ id: (new ObjectID()).toHexString(),
20
+ title: 'Latest',
21
+ slug: 'latest',
22
+ description: 'All posts',
23
+ type: 'automatic',
24
+ filter: '',
25
+ created_at: knex.raw('current_timestamp')
26
+ });
27
+ }
28
+
29
+ const existingFeaturedCollection = await knex('collections')
30
+ .where({
31
+ slug: 'featured'
32
+ })
33
+ .first();
34
+
35
+ if (existingFeaturedCollection) {
36
+ logging.warn('Featured collection already exists, skipping');
37
+ } else {
38
+ await knex('collections').insert({
39
+ id: (new ObjectID()).toHexString(),
40
+ title: 'Featured',
41
+ slug: 'featured',
42
+ description: 'Featured posts',
43
+ type: 'automatic',
44
+ filter: 'featured:true',
45
+ created_at: knex.raw('current_timestamp')
46
+ });
47
+ }
48
+ },
49
+ async function down(knex) {
50
+ logging.info('Deleting built in collections');
51
+
52
+ await knex('collections').where({
53
+ slug: 'latest'
54
+ }).del();
55
+
56
+ await knex('collections').where({
57
+ slug: 'featured'
58
+ }).del();
59
+ }
60
+ );