ghost 5.95.0 → 5.96.1

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 (200) hide show
  1. package/components/tryghost-adapter-cache-memory-ttl-5.96.1.tgz +0 -0
  2. package/components/{tryghost-adapter-cache-redis-5.95.0.tgz → tryghost-adapter-cache-redis-5.96.1.tgz} +0 -0
  3. package/components/tryghost-adapter-manager-5.96.1.tgz +0 -0
  4. package/components/tryghost-announcement-bar-settings-5.96.1.tgz +0 -0
  5. package/components/{tryghost-api-framework-5.95.0.tgz → tryghost-api-framework-5.96.1.tgz} +0 -0
  6. package/components/tryghost-api-version-compatibility-service-5.96.1.tgz +0 -0
  7. package/components/tryghost-audience-feedback-5.96.1.tgz +0 -0
  8. package/components/tryghost-bookshelf-repository-5.96.1.tgz +0 -0
  9. package/components/tryghost-bootstrap-socket-5.96.1.tgz +0 -0
  10. package/components/tryghost-collections-5.96.1.tgz +0 -0
  11. package/components/tryghost-constants-5.96.1.tgz +0 -0
  12. package/components/{tryghost-custom-theme-settings-service-5.95.0.tgz → tryghost-custom-theme-settings-service-5.96.1.tgz} +0 -0
  13. package/components/{tryghost-data-generator-5.95.0.tgz → tryghost-data-generator-5.96.1.tgz} +0 -0
  14. package/components/{tryghost-domain-events-5.95.0.tgz → tryghost-domain-events-5.96.1.tgz} +0 -0
  15. package/components/tryghost-donations-5.96.1.tgz +0 -0
  16. package/components/tryghost-dynamic-routing-events-5.96.1.tgz +0 -0
  17. package/components/tryghost-email-addresses-5.96.1.tgz +0 -0
  18. package/components/tryghost-email-analytics-provider-mailgun-5.96.1.tgz +0 -0
  19. package/components/{tryghost-email-analytics-service-5.95.0.tgz → tryghost-email-analytics-service-5.96.1.tgz} +0 -0
  20. package/components/tryghost-email-content-generator-5.96.1.tgz +0 -0
  21. package/components/tryghost-email-events-5.96.1.tgz +0 -0
  22. package/components/tryghost-email-service-5.96.1.tgz +0 -0
  23. package/components/tryghost-email-suppression-list-5.96.1.tgz +0 -0
  24. package/components/tryghost-express-dynamic-redirects-5.96.1.tgz +0 -0
  25. package/components/{tryghost-external-media-inliner-5.95.0.tgz → tryghost-external-media-inliner-5.96.1.tgz} +0 -0
  26. package/components/tryghost-extract-api-key-5.96.1.tgz +0 -0
  27. package/components/tryghost-ghost-5.96.1.tgz +0 -0
  28. package/components/tryghost-html-to-plaintext-5.96.1.tgz +0 -0
  29. package/components/tryghost-i18n-5.96.1.tgz +0 -0
  30. package/components/{tryghost-importer-handler-content-files-5.95.0.tgz → tryghost-importer-handler-content-files-5.96.1.tgz} +0 -0
  31. package/components/{tryghost-importer-revue-5.95.0.tgz → tryghost-importer-revue-5.96.1.tgz} +0 -0
  32. package/components/tryghost-in-memory-repository-5.96.1.tgz +0 -0
  33. package/components/{tryghost-job-manager-5.95.0.tgz → tryghost-job-manager-5.96.1.tgz} +0 -0
  34. package/components/tryghost-link-redirects-5.96.1.tgz +0 -0
  35. package/components/tryghost-link-replacer-5.96.1.tgz +0 -0
  36. package/components/{tryghost-link-tracking-5.95.0.tgz → tryghost-link-tracking-5.96.1.tgz} +0 -0
  37. package/components/tryghost-magic-link-5.96.1.tgz +0 -0
  38. package/components/tryghost-mail-events-5.96.1.tgz +0 -0
  39. package/components/{tryghost-mailgun-client-5.95.0.tgz → tryghost-mailgun-client-5.96.1.tgz} +0 -0
  40. package/components/{tryghost-member-attribution-5.95.0.tgz → tryghost-member-attribution-5.96.1.tgz} +0 -0
  41. package/components/tryghost-member-events-5.96.1.tgz +0 -0
  42. package/components/{tryghost-members-api-5.95.0.tgz → tryghost-members-api-5.96.1.tgz} +0 -0
  43. package/components/tryghost-members-csv-5.96.1.tgz +0 -0
  44. package/components/{tryghost-members-events-service-5.95.0.tgz → tryghost-members-events-service-5.96.1.tgz} +0 -0
  45. package/components/tryghost-members-importer-5.96.1.tgz +0 -0
  46. package/components/tryghost-members-offers-5.96.1.tgz +0 -0
  47. package/components/tryghost-members-payments-5.96.1.tgz +0 -0
  48. package/components/tryghost-members-ssr-5.96.1.tgz +0 -0
  49. package/components/tryghost-members-stripe-service-5.96.1.tgz +0 -0
  50. package/components/{tryghost-mentions-email-report-5.95.0.tgz → tryghost-mentions-email-report-5.96.1.tgz} +0 -0
  51. package/components/tryghost-metrics-server-5.96.1.tgz +0 -0
  52. package/components/{tryghost-milestones-5.95.0.tgz → tryghost-milestones-5.96.1.tgz} +0 -0
  53. package/components/tryghost-minifier-5.96.1.tgz +0 -0
  54. package/components/tryghost-model-to-domain-event-interceptor-5.96.1.tgz +0 -0
  55. package/components/tryghost-mw-api-version-mismatch-5.96.1.tgz +0 -0
  56. package/components/tryghost-mw-cache-control-5.96.1.tgz +0 -0
  57. package/components/tryghost-mw-error-handler-5.96.1.tgz +0 -0
  58. package/components/{tryghost-mw-session-from-token-5.95.0.tgz → tryghost-mw-session-from-token-5.96.1.tgz} +0 -0
  59. package/components/tryghost-mw-update-user-last-seen-5.96.1.tgz +0 -0
  60. package/components/{tryghost-mw-version-match-5.95.0.tgz → tryghost-mw-version-match-5.96.1.tgz} +0 -0
  61. package/components/tryghost-mw-vhost-5.96.1.tgz +0 -0
  62. package/components/tryghost-nql-filter-expansions-5.96.1.tgz +0 -0
  63. package/components/tryghost-oembed-service-5.96.1.tgz +0 -0
  64. package/components/tryghost-package-json-5.96.1.tgz +0 -0
  65. package/components/tryghost-post-events-5.96.1.tgz +0 -0
  66. package/components/{tryghost-post-revisions-5.95.0.tgz → tryghost-post-revisions-5.96.1.tgz} +0 -0
  67. package/components/tryghost-posts-service-5.96.1.tgz +0 -0
  68. package/components/tryghost-recommendations-5.96.1.tgz +0 -0
  69. package/components/tryghost-referrers-5.96.1.tgz +0 -0
  70. package/components/{tryghost-security-5.95.0.tgz → tryghost-security-5.96.1.tgz} +0 -0
  71. package/components/{tryghost-session-service-5.95.0.tgz → tryghost-session-service-5.96.1.tgz} +0 -0
  72. package/components/tryghost-settings-path-manager-5.96.1.tgz +0 -0
  73. package/components/tryghost-slack-notifications-5.96.1.tgz +0 -0
  74. package/components/{tryghost-staff-service-5.95.0.tgz → tryghost-staff-service-5.96.1.tgz} +0 -0
  75. package/components/{tryghost-stats-service-5.95.0.tgz → tryghost-stats-service-5.96.1.tgz} +0 -0
  76. package/components/{tryghost-tiers-5.95.0.tgz → tryghost-tiers-5.96.1.tgz} +0 -0
  77. package/components/{tryghost-update-check-service-5.95.0.tgz → tryghost-update-check-service-5.96.1.tgz} +0 -0
  78. package/components/tryghost-verification-trigger-5.96.1.tgz +0 -0
  79. package/components/tryghost-version-notifications-data-service-5.96.1.tgz +0 -0
  80. package/components/tryghost-webmentions-5.96.1.tgz +0 -0
  81. package/core/boot.js +43 -0
  82. package/core/bridge.js +11 -8
  83. package/core/built/admin/assets/admin-x-activitypub/admin-x-activitypub.js +3 -3
  84. package/core/built/admin/assets/admin-x-activitypub/{index-6868a2ce.mjs → index-def21e23.mjs} +4359 -3811
  85. package/core/built/admin/assets/admin-x-activitypub/modals-09282c4e.mjs +250 -0
  86. package/core/built/admin/assets/admin-x-demo/admin-x-demo.js +1 -1
  87. package/core/built/admin/assets/admin-x-demo/{index-2575d977.mjs → index-3d57e7aa.mjs} +766 -762
  88. package/core/built/admin/assets/admin-x-demo/{modals-3cdb55d2.mjs → modals-191eb359.mjs} +2 -2
  89. package/core/built/admin/assets/admin-x-settings/{CodeEditorView-c5fded51.mjs → CodeEditorView-85a3642c.mjs} +2 -2
  90. package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +1 -1
  91. package/core/built/admin/assets/admin-x-settings/{index-baad1fa3.mjs → index-ebbd8de9.mjs} +2939 -2942
  92. package/core/built/admin/assets/admin-x-settings/{index-b78b238b.mjs → index-eeeca6f6.mjs} +2 -2
  93. package/core/built/admin/assets/admin-x-settings/{modals-d557f15c.mjs → modals-8a98634b.mjs} +11206 -16095
  94. package/core/built/admin/assets/chunk.524.9b3ed6b39dd6c575a36f.js +35 -0
  95. package/core/built/admin/assets/{chunk.582.57a31e68e4e9afe84109.js → chunk.582.5218d47941a18a44ead8.js} +6 -6
  96. package/core/built/admin/assets/{chunk.602.a3d38ba0a516decd78ce.js → chunk.874.e1d421507701daac30fb.js} +5226 -6255
  97. package/core/built/admin/assets/{ghost-9397fa4c9aadec9cff772a6d4db6b1f8.js → ghost-286f9a114755e8c3c7e9c37550f624a9.js} +86 -82
  98. package/core/built/admin/assets/ghost-c75b9d653495f9cfce528f6e10900b3f.css +1 -0
  99. package/core/built/admin/assets/ghost-dark-6ea629e177f77314f5d75c0ca97190ab.css +1 -0
  100. package/core/built/admin/assets/{vendor-b83f61eee071be0ef00075df9ff7782d.js → vendor-88cd9f5cf5eba65221e2d2a636531eaa.js} +19 -17
  101. package/core/built/admin/index.html +6 -6
  102. package/core/frontend/helpers/content_api_key.js +19 -0
  103. package/core/frontend/helpers/get.js +24 -41
  104. package/core/frontend/helpers/ghost_head.js +3 -3
  105. package/core/frontend/meta/generate-excerpt.js +1 -2
  106. package/core/frontend/services/{admin-auth-assets/AdminAuthAssetsService.js → assets-minification/AdminAuthAssets.js} +22 -62
  107. package/core/frontend/services/assets-minification/AssetsMinificationBase.js +79 -0
  108. package/core/frontend/services/{card-assets/CardAssetService.js → assets-minification/CardAssets.js} +20 -37
  109. package/core/frontend/services/assets-minification/CommentCountsAssets.js +34 -0
  110. package/core/frontend/services/assets-minification/MemberAttributionAssets.js +46 -0
  111. package/core/frontend/services/assets-minification/index.js +16 -0
  112. package/core/frontend/services/sitemap/BaseSiteMapGenerator.js +4 -1
  113. package/core/frontend/web/site.js +5 -4
  114. package/core/server/data/importer/importers/data/PostsImporter.js +2 -2
  115. package/core/server/data/migrations/versions/4.0/23-regenerate-posts-html.js +1 -1
  116. package/core/server/data/migrations/versions/4.9/05-fix-missed-mobiledoc-url-transforms.js +1 -1
  117. package/core/server/data/migrations/versions/5.0/2022-05-21-00-00-regenerate-posts-html.js +1 -1
  118. package/core/server/data/schema/schema.js +2 -2
  119. package/core/server/lib/mobiledoc.js +4 -0
  120. package/core/server/models/member.js +1 -1
  121. package/core/server/models/post.js +1 -1
  122. package/core/server/services/email-service/EmailServiceWrapper.js +1 -1
  123. package/core/server/services/themes/activate.js +2 -2
  124. package/core/server/services/themes/index.js +4 -1
  125. package/core/server/services/themes/validate.js +7 -5
  126. package/core/server/views/maintenance.html +3 -3
  127. package/core/server/web/admin/app.js +2 -1
  128. package/core/shared/config/defaults.json +7 -4
  129. package/core/shared/config/env/config.testing-browser.json +3 -0
  130. package/core/shared/config/env/config.testing-mysql.json +3 -0
  131. package/core/shared/config/env/config.testing.json +3 -0
  132. package/core/shared/config/helpers.js +4 -1
  133. package/core/shared/config/utils.js +5 -6
  134. package/core/shared/prometheus-client.js +36 -0
  135. package/package.json +156 -153
  136. package/yarn.lock +433 -264
  137. package/components/tryghost-adapter-cache-memory-ttl-5.95.0.tgz +0 -0
  138. package/components/tryghost-adapter-manager-5.95.0.tgz +0 -0
  139. package/components/tryghost-announcement-bar-settings-5.95.0.tgz +0 -0
  140. package/components/tryghost-api-version-compatibility-service-5.95.0.tgz +0 -0
  141. package/components/tryghost-audience-feedback-5.95.0.tgz +0 -0
  142. package/components/tryghost-bookshelf-repository-5.95.0.tgz +0 -0
  143. package/components/tryghost-bootstrap-socket-5.95.0.tgz +0 -0
  144. package/components/tryghost-collections-5.95.0.tgz +0 -0
  145. package/components/tryghost-constants-5.95.0.tgz +0 -0
  146. package/components/tryghost-donations-5.95.0.tgz +0 -0
  147. package/components/tryghost-dynamic-routing-events-5.95.0.tgz +0 -0
  148. package/components/tryghost-email-addresses-5.95.0.tgz +0 -0
  149. package/components/tryghost-email-analytics-provider-mailgun-5.95.0.tgz +0 -0
  150. package/components/tryghost-email-content-generator-5.95.0.tgz +0 -0
  151. package/components/tryghost-email-events-5.95.0.tgz +0 -0
  152. package/components/tryghost-email-service-5.95.0.tgz +0 -0
  153. package/components/tryghost-email-suppression-list-5.95.0.tgz +0 -0
  154. package/components/tryghost-express-dynamic-redirects-5.95.0.tgz +0 -0
  155. package/components/tryghost-extract-api-key-5.95.0.tgz +0 -0
  156. package/components/tryghost-ghost-5.95.0.tgz +0 -0
  157. package/components/tryghost-html-to-plaintext-5.95.0.tgz +0 -0
  158. package/components/tryghost-i18n-5.95.0.tgz +0 -0
  159. package/components/tryghost-in-memory-repository-5.95.0.tgz +0 -0
  160. package/components/tryghost-link-redirects-5.95.0.tgz +0 -0
  161. package/components/tryghost-link-replacer-5.95.0.tgz +0 -0
  162. package/components/tryghost-magic-link-5.95.0.tgz +0 -0
  163. package/components/tryghost-mail-events-5.95.0.tgz +0 -0
  164. package/components/tryghost-member-events-5.95.0.tgz +0 -0
  165. package/components/tryghost-members-csv-5.95.0.tgz +0 -0
  166. package/components/tryghost-members-importer-5.95.0.tgz +0 -0
  167. package/components/tryghost-members-offers-5.95.0.tgz +0 -0
  168. package/components/tryghost-members-payments-5.95.0.tgz +0 -0
  169. package/components/tryghost-members-ssr-5.95.0.tgz +0 -0
  170. package/components/tryghost-members-stripe-service-5.95.0.tgz +0 -0
  171. package/components/tryghost-minifier-5.95.0.tgz +0 -0
  172. package/components/tryghost-model-to-domain-event-interceptor-5.95.0.tgz +0 -0
  173. package/components/tryghost-mw-api-version-mismatch-5.95.0.tgz +0 -0
  174. package/components/tryghost-mw-cache-control-5.95.0.tgz +0 -0
  175. package/components/tryghost-mw-error-handler-5.95.0.tgz +0 -0
  176. package/components/tryghost-mw-update-user-last-seen-5.95.0.tgz +0 -0
  177. package/components/tryghost-mw-vhost-5.95.0.tgz +0 -0
  178. package/components/tryghost-nql-filter-expansions-5.95.0.tgz +0 -0
  179. package/components/tryghost-oembed-service-5.95.0.tgz +0 -0
  180. package/components/tryghost-package-json-5.95.0.tgz +0 -0
  181. package/components/tryghost-post-events-5.95.0.tgz +0 -0
  182. package/components/tryghost-posts-service-5.95.0.tgz +0 -0
  183. package/components/tryghost-recommendations-5.95.0.tgz +0 -0
  184. package/components/tryghost-referrers-5.95.0.tgz +0 -0
  185. package/components/tryghost-settings-path-manager-5.95.0.tgz +0 -0
  186. package/components/tryghost-slack-notifications-5.95.0.tgz +0 -0
  187. package/components/tryghost-verification-trigger-5.95.0.tgz +0 -0
  188. package/components/tryghost-version-notifications-data-service-5.95.0.tgz +0 -0
  189. package/components/tryghost-webmentions-5.95.0.tgz +0 -0
  190. package/core/built/admin/assets/admin-x-activitypub/modals-d56ac37e.mjs +0 -342
  191. package/core/built/admin/assets/chunk.524.d49d5b3795688b5f880d.js +0 -35
  192. package/core/built/admin/assets/ghost-8f07a67edb1191d1cdddd8a296bbdc4d.css +0 -1
  193. package/core/built/admin/assets/ghost-dark-fe1f347ef1a04509da6bbac199a51d23.css +0 -1
  194. package/core/frontend/services/admin-auth-assets/index.js +0 -4
  195. package/core/frontend/services/card-assets/index.js +0 -4
  196. package/core/frontend/services/comment-counts-assets/CommentCountsAssetsService.js +0 -59
  197. package/core/frontend/services/comment-counts-assets/index.js +0 -4
  198. package/core/frontend/services/member-attribution-assets/MemberAttributionAssetsService.js +0 -83
  199. package/core/frontend/services/member-attribution-assets/index.js +0 -4
  200. /package/core/built/admin/assets/{chunk.602.a3d38ba0a516decd78ce.js.LICENSE.txt → chunk.874.e1d421507701daac30fb.js.LICENSE.txt} +0 -0
@@ -0,0 +1,34 @@
1
+ const Minifier = require('@tryghost/minifier');
2
+ const path = require('path');
3
+ const config = require('../../../shared/config');
4
+ const AssetsMinificationBase = require('./AssetsMinificationBase');
5
+
6
+ module.exports = class CommentCountsAssets extends AssetsMinificationBase {
7
+ constructor(options = {}) {
8
+ super(options);
9
+
10
+ this.src = options.src || path.join(config.get('paths').assetSrc, 'comment-counts');
11
+ this.dest = options.dest || config.getContentPath('public');
12
+ this.minifier = new Minifier({src: this.src, dest: this.dest});
13
+
14
+ this.files = [];
15
+ }
16
+
17
+ /**
18
+ * @override
19
+ */
20
+ generateGlobs() {
21
+ return {
22
+ 'comment-counts.min.js': 'js/*.js'
23
+ };
24
+ }
25
+
26
+ /**
27
+ * @override
28
+ */
29
+ async load() {
30
+ await this.clearFiles();
31
+ const globs = this.generateGlobs();
32
+ this.files = await this.minify(globs);
33
+ }
34
+ };
@@ -0,0 +1,46 @@
1
+ const Minifier = require('@tryghost/minifier');
2
+ const path = require('path');
3
+ const config = require('../../../shared/config');
4
+ const AssetsMinificationBase = require('./AssetsMinificationBase');
5
+
6
+ module.exports = class MemberAttributionAssets extends AssetsMinificationBase {
7
+ constructor(options = {}) {
8
+ super(options);
9
+
10
+ /** @private */
11
+ this.src = options.src || path.join(config.get('paths').assetSrc, 'member-attribution');
12
+ /** @private */
13
+ this.dest = options.dest || config.getContentPath('public');
14
+
15
+ this.minifier = new Minifier({src: this.src, dest: this.dest});
16
+ }
17
+
18
+ /**
19
+ * @override
20
+ */
21
+ generateGlobs() {
22
+ return {
23
+ 'member-attribution.min.js': '*.js'
24
+ };
25
+ }
26
+
27
+ /**
28
+ * @private
29
+ */
30
+ generateReplacements() {
31
+ return {};
32
+ }
33
+
34
+ /**
35
+ * Minify, move into the destination directory, and clear existing asset files.
36
+ *
37
+ * @override
38
+ * @returns {Promise<void>}
39
+ */
40
+ async load() {
41
+ const globs = this.generateGlobs();
42
+ const replacements = this.generateReplacements();
43
+ await this.clearFiles();
44
+ await this.minify(globs, {replacements});
45
+ }
46
+ };
@@ -0,0 +1,16 @@
1
+ const AdminAuthAssets = require('./AdminAuthAssets');
2
+ const CardAssets = require('./CardAssets');
3
+ const CommentCountsAssets = require('./CommentCountsAssets');
4
+ const MemberAttributionAssets = require('./MemberAttributionAssets');
5
+
6
+ const adminAuthAssets = new AdminAuthAssets();
7
+ const cardAssets = new CardAssets();
8
+ const commentCountsAssets = new CommentCountsAssets();
9
+ const memberAttributionAssets = new MemberAttributionAssets();
10
+
11
+ module.exports = {
12
+ adminAuthAssets,
13
+ cardAssets,
14
+ commentCountsAssets,
15
+ memberAttributionAssets
16
+ };
@@ -95,6 +95,9 @@ class BaseSiteMapGenerator {
95
95
  this.lastModified = Date.now();
96
96
  }
97
97
 
98
+ /**
99
+ * @returns {moment.Moment}
100
+ */
98
101
  getLastModifiedForDatum(datum) {
99
102
  if (datum.updated_at || datum.published_at || datum.created_at) {
100
103
  const modifiedDate = datum.updated_at || datum.published_at || datum.created_at;
@@ -126,7 +129,7 @@ class BaseSiteMapGenerator {
126
129
  node = {
127
130
  url: [
128
131
  {loc: url},
129
- {lastmod: moment(this.getLastModifiedForDatum(datum)).toISOString()}
132
+ {lastmod: this.getLastModifiedForDatum(datum).toISOString()}
130
133
  ]
131
134
  };
132
135
 
@@ -16,6 +16,7 @@ const membersService = require('../../server/services/members');
16
16
  const offersService = require('../../server/services/offers');
17
17
  const customRedirects = require('../../server/services/custom-redirects');
18
18
  const linkRedirects = require('../../server/services/link-redirection');
19
+ const {cardAssets, commentCountsAssets, memberAttributionAssets} = require('../services/assets-minification');
19
20
  const siteRoutes = require('./routes');
20
21
  const shared = require('../../server/web/shared');
21
22
  const errorHandler = require('@tryghost/mw-error-handler');
@@ -72,14 +73,14 @@ module.exports = function setupSiteApp(routerConfig) {
72
73
  siteApp.use(mw.servePublicFile('static', 'public/ghost.min.css', 'text/css', config.get('caching:publicAssets:maxAge')));
73
74
 
74
75
  // Card assets
75
- siteApp.use(mw.servePublicFile('built', 'public/cards.min.css', 'text/css', config.get('caching:publicAssets:maxAge')));
76
- siteApp.use(mw.servePublicFile('built', 'public/cards.min.js', 'application/javascript', config.get('caching:publicAssets:maxAge')));
76
+ siteApp.use(cardAssets.serveMiddleware(), mw.servePublicFile('built', 'public/cards.min.css', 'text/css', config.get('caching:publicAssets:maxAge')));
77
+ siteApp.use(cardAssets.serveMiddleware(), mw.servePublicFile('built', 'public/cards.min.js', 'application/javascript', config.get('caching:publicAssets:maxAge')));
77
78
 
78
79
  // Comment counts
79
- siteApp.use(mw.servePublicFile('built', 'public/comment-counts.min.js', 'application/javascript', config.get('caching:publicAssets:maxAge')));
80
+ siteApp.use(commentCountsAssets.serveMiddleware(), mw.servePublicFile('built', 'public/comment-counts.min.js', 'application/javascript', config.get('caching:publicAssets:maxAge')));
80
81
 
81
82
  // Member attribution
82
- siteApp.use(mw.servePublicFile('built', 'public/member-attribution.min.js', 'application/javascript', config.get('caching:publicAssets:maxAge')));
83
+ siteApp.use(memberAttributionAssets.serveMiddleware(), mw.servePublicFile('built', 'public/member-attribution.min.js', 'application/javascript', config.get('caching:publicAssets:maxAge')));
83
84
 
84
85
  // Serve site images using the storage adapter
85
86
  siteApp.use(STATIC_IMAGE_URL_PREFIX, mw.handleImageSizes, storage.getStorage('images').serve());
@@ -271,10 +271,10 @@ class PostsImporter extends BaseImporter {
271
271
  });
272
272
 
273
273
  model.mobiledoc = JSON.stringify(mobiledoc);
274
- model.html = mobiledocLib.mobiledocHtmlRenderer.render(JSON.parse(model.mobiledoc));
274
+ model.html = mobiledocLib.render(JSON.parse(model.mobiledoc));
275
275
  } else if (model.html && !model.lexical) {
276
276
  model.mobiledoc = JSON.stringify(mobiledocLib.htmlToMobiledocConverter(model.html));
277
- model.html = mobiledocLib.mobiledocHtmlRenderer.render(JSON.parse(model.mobiledoc));
277
+ model.html = mobiledocLib.render(JSON.parse(model.mobiledoc));
278
278
  }
279
279
 
280
280
  this.sanitizePostsMeta(model);
@@ -39,7 +39,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
39
39
  continue;
40
40
  }
41
41
 
42
- const html = mobiledocLib.mobiledocHtmlRenderer.render(mobiledoc);
42
+ const html = mobiledocLib.render(mobiledoc);
43
43
 
44
44
  const updatedAttrs = {
45
45
  html: html
@@ -59,7 +59,7 @@ module.exports = createTransactionalMigration(
59
59
  }
60
60
 
61
61
  try {
62
- html = mobiledocLib.mobiledocHtmlRenderer.render(JSON.parse(mobiledoc));
62
+ html = mobiledocLib.render(JSON.parse(mobiledoc));
63
63
  } catch (err) {
64
64
  logging.warn(`Invalid mobiledoc content structure for ${id}, unable to render. Skipping`);
65
65
  continue;
@@ -43,7 +43,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
43
43
  continue;
44
44
  }
45
45
 
46
- const html = mobiledocLib.mobiledocHtmlRenderer.render(mobiledoc);
46
+ const html = mobiledocLib.render(mobiledoc);
47
47
 
48
48
  const updatedAttrs = {
49
49
  html
@@ -113,7 +113,7 @@ module.exports = {
113
113
  meta_description: {type: 'string', maxlength: 2000, nullable: true, validations: {isLength: {max: 500}}},
114
114
  email_subject: {type: 'string', maxlength: 300, nullable: true},
115
115
  frontmatter: {type: 'text', maxlength: 65535, nullable: true},
116
- feature_image_alt: {type: 'string', maxlength: 191, nullable: true, validations: {isLength: {max: 125}}},
116
+ feature_image_alt: {type: 'string', maxlength: 191, nullable: true},
117
117
  feature_image_caption: {type: 'text', maxlength: 65535, nullable: true},
118
118
  email_only: {type: 'boolean', nullable: false, defaultTo: false}
119
119
  },
@@ -418,7 +418,7 @@ module.exports = {
418
418
  post_status: {type: 'string', maxlength: 50, nullable: true, validations: {isIn: [['draft', 'published', 'scheduled', 'sent']]}},
419
419
  reason: {type: 'string', maxlength: 50, nullable: true},
420
420
  feature_image: {type: 'string', maxlength: 2000, nullable: true},
421
- feature_image_alt: {type: 'string', maxlength: 191, nullable: true, validations: {isLength: {max: 125}}},
421
+ feature_image_alt: {type: 'string', maxlength: 191, nullable: true},
422
422
  feature_image_caption: {type: 'text', maxlength: 65535, nullable: true},
423
423
  custom_excerpt: {type: 'string', maxlength: 2000, nullable: true, validations: {isLength: {max: 300}}}
424
424
  },
@@ -73,6 +73,10 @@ module.exports = {
73
73
  return mobiledocHtmlRenderer;
74
74
  },
75
75
 
76
+ render(mobiledoc, options) {
77
+ return this.mobiledocHtmlRenderer.render(mobiledoc, options);
78
+ },
79
+
76
80
  get htmlToMobiledocConverter() {
77
81
  try {
78
82
  if (process.env.CI) {
@@ -2,7 +2,6 @@ const ghostBookshelf = require('./base');
2
2
  const crypto = require('crypto');
3
3
  const _ = require('lodash');
4
4
  const config = require('../../shared/config');
5
- const {gravatar} = require('../lib/image');
6
5
 
7
6
  const Member = ghostBookshelf.Model.extend({
8
7
  tableName: 'members',
@@ -397,6 +396,7 @@ const Member = ghostBookshelf.Model.extend({
397
396
  // Will not use gravatar if privacy.useGravatar is false in config
398
397
  attrs.avatar_image = null;
399
398
  if (attrs.email && !config.isPrivacyDisabled('useGravatar')) {
399
+ const {gravatar} = require('../lib/image');
400
400
  attrs.avatar_image = gravatar.url(attrs.email, {size: 250, default: 'blank'});
401
401
  }
402
402
 
@@ -742,7 +742,7 @@ Post = ghostBookshelf.Model.extend({
742
742
  )
743
743
  ) {
744
744
  try {
745
- this.set('html', mobiledocLib.mobiledocHtmlRenderer.render(JSON.parse(this.get('mobiledoc'))));
745
+ this.set('html', mobiledocLib.render(JSON.parse(this.get('mobiledoc'))));
746
746
  } catch (err) {
747
747
  throw new errors.ValidationError({
748
748
  message: tpl(messages.invalidMobiledocStructure),
@@ -59,7 +59,7 @@ class EmailServiceWrapper {
59
59
  settingsCache,
60
60
  settingsHelpers,
61
61
  renderers: {
62
- mobiledoc: mobiledocLib.mobiledocHtmlRenderer,
62
+ mobiledoc: mobiledocLib,
63
63
  lexical: lexicalLib
64
64
  },
65
65
  imageSize,
@@ -14,14 +14,14 @@ const messages = {
14
14
  themeCannotBeActivated: '{themeName} cannot be activated because it was not found in the theme directory.'
15
15
  };
16
16
 
17
- module.exports.loadAndActivate = async (themeName) => {
17
+ module.exports.loadAndActivate = async (themeName, options = {}) => {
18
18
  debug('loadAndActivate', themeName);
19
19
  try {
20
20
  // Just read the active theme for now
21
21
  const loadedTheme = await themeLoader.loadOneTheme(themeName);
22
22
  // Validate
23
23
  // @NOTE: this is now the only usage of check, rather than checkSafe...
24
- const checkedTheme = await validate.check(themeName, loadedTheme);
24
+ const checkedTheme = await validate.check(themeName, loadedTheme, {skipChecks: options.skipChecks});
25
25
 
26
26
  if (!validate.canActivate(checkedTheme)) {
27
27
  logging.error(validate.getThemeValidationError('activeThemeHasFatalErrors', themeName, checkedTheme));
@@ -5,6 +5,7 @@ const getJSON = require('./to-json');
5
5
  const installer = require('./installer');
6
6
  const validate = require('./validate');
7
7
  const settingsCache = require('../../../shared/settings-cache');
8
+ const config = require('../../../shared/config');
8
9
 
9
10
  module.exports = {
10
11
  /*
@@ -13,8 +14,10 @@ module.exports = {
13
14
  init: async () => {
14
15
  validate.init();
15
16
 
17
+ const skipChecks = config.get('optimization:themes:skipBootChecks') || false;
18
+
16
19
  const themeName = settingsCache.get('active_theme');
17
- return activate.loadAndActivate(themeName);
20
+ return activate.loadAndActivate(themeName, {skipChecks});
18
21
  },
19
22
  /**
20
23
  * Load all inactive themes
@@ -44,25 +44,27 @@ const getErrorsFromCheckedTheme = function getErrorsFromCheckedTheme(checkedThem
44
44
  };
45
45
  };
46
46
 
47
- const check = async function check(themeName, theme, isZip) {
47
+ const check = async function check(themeName, theme, options = {}) {
48
48
  debug('Begin: Check');
49
49
  // gscan can slow down boot time if we require on boot, for now nest the require.
50
50
  const gscan = require('gscan');
51
51
  const checkedVersion = 'v5';
52
52
  let checkedTheme;
53
53
 
54
- if (isZip) {
54
+ if (options.isZip === true) {
55
55
  debug('zip mode');
56
56
  checkedTheme = await gscan.checkZip(theme, {
57
57
  keepExtractedDir: true,
58
58
  checkVersion: checkedVersion,
59
- labs: labs.getAll()
59
+ labs: labs.getAll(),
60
+ skipChecks: options.skipChecks || false
60
61
  });
61
62
  } else {
62
63
  debug('non-zip mode');
63
64
  checkedTheme = await gscan.check(theme.path, {
64
65
  checkVersion: checkedVersion,
65
- labs: labs.getAll()
66
+ labs: labs.getAll(),
67
+ skipChecks: options.skipChecks || false
66
68
  });
67
69
  }
68
70
 
@@ -119,7 +121,7 @@ const getThemeErrors = async function getThemeErrors(themeName) {
119
121
  };
120
122
 
121
123
  const checkSafe = async function checkSafe(themeName, theme, isZip) {
122
- const checkedTheme = await check(themeName, theme, isZip);
124
+ const checkedTheme = await check(themeName, theme, {isZip});
123
125
 
124
126
  if (canActivate(checkedTheme)) {
125
127
  return checkedTheme;
@@ -4,7 +4,7 @@
4
4
  <meta charset="utf-8">
5
5
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>We'll be right back</title>
7
+ <title>Well be right back</title>
8
8
  <style type="text/css">
9
9
  * {
10
10
  box-sizing: border-box;
@@ -80,8 +80,8 @@ img {
80
80
  </head>
81
81
  <body>
82
82
  <div class="content">
83
- <h1>We'll be right back.</h1>
84
- <p>We're busy updating our site to give you the best experience, and will be back soon.</p>
83
+ <h1>Well be right back.</h1>
84
+ <p>Were busy updating our site to give you the best experience, and will be back soon.</p>
85
85
  </div>
86
86
  </body>
87
87
  </html>
@@ -9,6 +9,7 @@ const shared = require('../shared');
9
9
  const errorHandler = require('@tryghost/mw-error-handler');
10
10
  const sentry = require('../../../shared/sentry');
11
11
  const redirectAdminUrls = require('./middleware/redirect-admin-urls');
12
+ const bridge = require('../../../bridge');
12
13
 
13
14
  /**
14
15
  *
@@ -38,7 +39,7 @@ module.exports = function setupAdminApp() {
38
39
  // request to the Admin API /users/me/ endpoint to check if the user is logged in.
39
40
  //
40
41
  // Used by comments-ui to add moderation options to front-end comments when logged in.
41
- adminApp.use('/auth-frame', function authFrameMw(req, res, next) {
42
+ adminApp.use('/auth-frame', bridge.ensureAdminAuthAssetsMiddleware(), function authFrameMw(req, res, next) {
42
43
  // only render content when we have an Admin session cookie,
43
44
  // otherwise return a 204 to avoid JS and API requests being made unnecessarily
44
45
  try {
@@ -164,6 +164,9 @@
164
164
  "threshold": 200,
165
165
  "level": "warn"
166
166
  }
167
+ },
168
+ "themes": {
169
+ "skipBootChecks": false
167
170
  }
168
171
  },
169
172
  "imageOptimization": {
@@ -182,12 +185,12 @@
182
185
  },
183
186
  "portal": {
184
187
  "url": "https://cdn.jsdelivr.net/ghost/portal@~{version}/umd/portal.min.js",
185
- "version": "2.43"
188
+ "version": "2.44"
186
189
  },
187
190
  "sodoSearch": {
188
191
  "url": "https://cdn.jsdelivr.net/ghost/sodo-search@~{version}/umd/sodo-search.min.js",
189
192
  "styles": "https://cdn.jsdelivr.net/ghost/sodo-search@~{version}/umd/main.css",
190
- "version": "1.2"
193
+ "version": "1.3"
191
194
  },
192
195
  "announcementBar": {
193
196
  "url": "https://cdn.jsdelivr.net/ghost/announcement-bar@~{version}/umd/announcement-bar.min.js",
@@ -195,11 +198,11 @@
195
198
  },
196
199
  "comments": {
197
200
  "url": "https://cdn.jsdelivr.net/ghost/comments-ui@~{version}/umd/comments-ui.min.js",
198
- "version": "0.18"
201
+ "version": "0.19"
199
202
  },
200
203
  "signupForm": {
201
204
  "url": "https://cdn.jsdelivr.net/ghost/signup-form@~{version}/umd/signup-form.min.js",
202
- "version": "0.1"
205
+ "version": "0.2"
203
206
  },
204
207
  "tenor": {
205
208
  "googleApiKey": null,
@@ -11,6 +11,9 @@
11
11
  "server": {
12
12
  "port": 2369
13
13
  },
14
+ "metrics_server": {
15
+ "port": 9417
16
+ },
14
17
  "logging": {
15
18
  "level": "fatal"
16
19
  },
@@ -3,6 +3,9 @@
3
3
  "server": {
4
4
  "port": 2369
5
5
  },
6
+ "metrics_server": {
7
+ "port": 9417
8
+ },
6
9
  "database": {
7
10
  "client": "mysql",
8
11
  "connection": {
@@ -11,6 +11,9 @@
11
11
  "server": {
12
12
  "port": 2369
13
13
  },
14
+ "metrics_server": {
15
+ "port": 9417
16
+ },
14
17
  "logging": {
15
18
  "level": "error"
16
19
  },
@@ -1,7 +1,10 @@
1
1
  const path = require('path');
2
- const escapeRegExp = require('lodash/escapeRegExp');
3
2
  const {URL} = require('url');
4
3
 
4
+ function escapeRegExp(string) {
5
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
6
+ }
7
+
5
8
  const DEFAULT_HOST_ARG = /.*/;
6
9
 
7
10
  const getHostInfo = (config) => {
@@ -1,6 +1,5 @@
1
1
  const path = require('path');
2
- const fs = require('fs-extra');
3
- const _ = require('lodash');
2
+ const fs = require('fs');
4
3
 
5
4
  /**
6
5
  * transform all relative paths to absolute paths
@@ -11,11 +10,11 @@ const _ = require('lodash');
11
10
  * Path can be a "." to re-present current folder
12
11
  */
13
12
  const makePathsAbsolute = function makePathsAbsolute(nconf, obj, parent) {
14
- _.each(obj, function (configValue, pathsKey) {
15
- if (_.isObject(configValue)) {
13
+ Object.entries(obj).forEach(([pathsKey, configValue]) => {
14
+ if (configValue && typeof configValue === 'object') {
16
15
  makePathsAbsolute(nconf, configValue, parent + ':' + pathsKey);
17
16
  } else if (
18
- _.isString(configValue) &&
17
+ typeof configValue === 'string' &&
19
18
  (configValue.match(/\/+|\\+/) || configValue === '.') &&
20
19
  !path.isAbsolute(configValue)
21
20
  ) {
@@ -25,7 +24,7 @@ const makePathsAbsolute = function makePathsAbsolute(nconf, obj, parent) {
25
24
  };
26
25
 
27
26
  const doesContentPathExist = function doesContentPathExist(contentPath) {
28
- if (!fs.pathExistsSync(contentPath)) {
27
+ if (!fs.existsSync(contentPath)) {
29
28
  // new Error is allowed here, as we do not want config to depend on @tryghost/error
30
29
  // @TODO: revisit this decision when @tryghost/error is no longer dependent on all of ghost-ignition
31
30
  // eslint-disable-next-line ghost/ghost-custom/no-native-error
@@ -0,0 +1,36 @@
1
+ class PrometheusClient {
2
+ constructor() {
3
+ this.client = require('prom-client');
4
+ this.prefix = 'ghost_';
5
+ this.collectDefaultMetrics();
6
+ }
7
+
8
+ collectDefaultMetrics() {
9
+ this.client.collectDefaultMetrics({prefix: this.prefix});
10
+ }
11
+
12
+ async handleMetricsRequest(req, res) {
13
+ try {
14
+ res.set('Content-Type', this.getContentType());
15
+ res.end(await this.getMetrics());
16
+ } catch (err) {
17
+ res.status(500).end(err.message);
18
+ }
19
+ }
20
+
21
+ async getMetrics() {
22
+ return this.client.register.metrics();
23
+ }
24
+
25
+ getRegistry() {
26
+ return this.client.register;
27
+ }
28
+
29
+ getContentType() {
30
+ return this.getRegistry().contentType;
31
+ }
32
+ }
33
+
34
+ // Create a singleton instance and export it as the default export
35
+ const prometheusClient = new PrometheusClient();
36
+ module.exports = prometheusClient;