ghost 4.15.0 → 4.17.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 (137) hide show
  1. package/.eslintrc.js +7 -1
  2. package/content/themes/casper/assets/built/screen.css +1 -1
  3. package/content/themes/casper/assets/built/screen.css.map +1 -1
  4. package/content/themes/casper/assets/css/screen.css +1 -1
  5. package/content/themes/casper/default.hbs +2 -2
  6. package/content/themes/casper/package.json +1 -1
  7. package/content/themes/casper/page.hbs +28 -26
  8. package/content/themes/casper/partials/post-card.hbs +2 -2
  9. package/content/themes/casper/post.hbs +67 -65
  10. package/content/themes/casper/tag.hbs +2 -2
  11. package/core/boot.js +7 -7
  12. package/core/bridge.js +4 -3
  13. package/core/built/assets/{chunk.3.4b1d9e20e57164ac9c29.js → chunk.3.b80d3e1e6b8556aaff3c.js} +72 -71
  14. package/core/built/assets/ghost-dark-f7bf2dd8d8c702716f75bfa4ccd92df2.css +1 -0
  15. package/core/built/assets/{ghost.min-e35cfee26d942c364166f57f3dcc9e75.js → ghost.min-52a5420ffcea6bf17761b5c59cf020e2.js} +979 -908
  16. package/core/built/assets/ghost.min-741246f42f000c073999a5363434ea2c.css +1 -0
  17. package/core/built/assets/icons/discount-bubble.svg +1 -0
  18. package/core/built/assets/{vendor.min-ca33abc718f21a51327841d58f8875d0.js → vendor.min-1bfc9d56d27508db88ef417deb55f16f.js} +454 -434
  19. package/core/frontend/apps/amp/lib/helpers/amp_analytics.js +2 -2
  20. package/core/frontend/apps/amp/lib/helpers/amp_components.js +2 -1
  21. package/core/frontend/apps/amp/lib/helpers/amp_content.js +5 -1
  22. package/core/frontend/apps/amp/lib/helpers/amp_style.js +1 -1
  23. package/core/frontend/apps/amp/lib/router.js +8 -4
  24. package/core/frontend/apps/private-blogging/index.js +13 -5
  25. package/core/frontend/apps/private-blogging/lib/helpers/input_password.js +1 -1
  26. package/core/frontend/apps/private-blogging/lib/middleware.js +8 -3
  27. package/core/frontend/helpers/asset.js +10 -2
  28. package/core/frontend/helpers/author.js +5 -3
  29. package/core/frontend/helpers/authors.js +4 -3
  30. package/core/frontend/helpers/body_class.js +1 -1
  31. package/core/frontend/helpers/cancel_link.js +9 -2
  32. package/core/frontend/helpers/concat.js +1 -1
  33. package/core/frontend/helpers/content.js +1 -1
  34. package/core/frontend/helpers/date.js +1 -1
  35. package/core/frontend/helpers/encode.js +1 -1
  36. package/core/frontend/helpers/excerpt.js +2 -1
  37. package/core/frontend/helpers/facebook_url.js +2 -1
  38. package/core/frontend/helpers/foreach.js +11 -2
  39. package/core/frontend/helpers/get.js +14 -3
  40. package/core/frontend/helpers/ghost_foot.js +2 -1
  41. package/core/frontend/helpers/ghost_head.js +10 -1
  42. package/core/frontend/helpers/has.js +8 -3
  43. package/core/frontend/helpers/img_url.js +9 -3
  44. package/core/frontend/helpers/is.js +7 -2
  45. package/core/frontend/helpers/lang.js +1 -1
  46. package/core/frontend/helpers/link.js +11 -2
  47. package/core/frontend/helpers/link_class.js +11 -2
  48. package/core/frontend/helpers/match.js +12 -3
  49. package/core/frontend/helpers/navigation.js +13 -4
  50. package/core/frontend/helpers/pagination.js +15 -5
  51. package/core/frontend/helpers/plural.js +8 -2
  52. package/core/frontend/helpers/post_class.js +1 -1
  53. package/core/frontend/helpers/prev_post.js +9 -2
  54. package/core/frontend/helpers/price.js +11 -6
  55. package/core/frontend/helpers/products.js +2 -1
  56. package/core/frontend/helpers/reading_time.js +4 -2
  57. package/core/frontend/helpers/t.js +1 -1
  58. package/core/frontend/helpers/tags.js +3 -1
  59. package/core/frontend/helpers/title.js +1 -1
  60. package/core/frontend/helpers/twitter_url.js +2 -1
  61. package/core/frontend/helpers/url.js +3 -1
  62. package/core/frontend/services/proxy.js +34 -57
  63. package/core/frontend/services/rendering.js +24 -0
  64. package/core/frontend/services/routing/controllers/channel.js +6 -2
  65. package/core/frontend/services/routing/controllers/collection.js +6 -2
  66. package/core/frontend/services/routing/middlewares/page-param.js +6 -2
  67. package/core/frontend/services/theme-engine/middleware.js +23 -6
  68. package/core/frontend/services/theme-engine/preview.js +31 -8
  69. package/core/server/adapters/scheduling/post-scheduling/scheduler-intergation.js +6 -4
  70. package/core/server/adapters/storage/LocalFileStorage.js +10 -4
  71. package/core/server/api/canary/custom-theme-settings.js +22 -0
  72. package/core/server/api/canary/index.js +4 -0
  73. package/core/server/api/canary/members.js +1 -1
  74. package/core/server/api/canary/redirects.js +5 -5
  75. package/core/server/api/canary/settings.js +16 -148
  76. package/core/server/api/canary/utils/serializers/output/custom-theme-settings.js +13 -0
  77. package/core/server/api/canary/utils/serializers/output/index.js +4 -0
  78. package/core/server/api/canary/utils/validators/input/settings.js +23 -1
  79. package/core/server/api/v2/redirects.js +3 -3
  80. package/core/server/api/v2/settings.js +3 -4
  81. package/core/server/api/v3/redirects.js +5 -5
  82. package/core/server/api/v3/settings.js +16 -136
  83. package/core/server/api/v3/utils/validators/input/settings.js +23 -1
  84. package/core/server/data/db/state-manager.js +1 -1
  85. package/core/server/data/exporter/table-lists.js +3 -1
  86. package/core/server/data/importer/import-manager.js +398 -0
  87. package/core/server/data/importer/importers/data/data-importer.js +162 -0
  88. package/core/server/data/importer/importers/data/index.js +1 -162
  89. package/core/server/data/importer/index.js +1 -379
  90. package/core/server/data/migrations/versions/4.16/01-add-custom-theme-settings-table.js +9 -0
  91. package/core/server/data/migrations/versions/4.17/01-add-custom-theme-settings-permissions.js +21 -0
  92. package/core/server/data/migrations/versions/4.17/02-add-offers-table.js +19 -0
  93. package/core/server/data/migrations/versions/4.17/03-add-offers-permissions.js +35 -0
  94. package/core/server/data/schema/fixtures/fixtures.json +32 -0
  95. package/core/server/data/schema/schema.js +33 -0
  96. package/core/server/models/custom-theme-setting.js +9 -0
  97. package/core/server/models/index.js +2 -0
  98. package/core/server/services/custom-theme-settings.js +8 -0
  99. package/core/server/services/members/api.js +4 -1
  100. package/core/server/services/redirects/index.js +15 -0
  101. package/core/{frontend → server}/services/redirects/settings.js +13 -6
  102. package/core/server/services/redirects/validation.js +44 -0
  103. package/core/{frontend/services/settings → server/services/route-settings}/default-routes.yaml +0 -0
  104. package/core/server/services/route-settings/default-settings-manager.js +62 -0
  105. package/core/server/services/route-settings/index.js +32 -1
  106. package/core/server/services/route-settings/route-settings.js +38 -12
  107. package/core/server/services/route-settings/settings-loader.js +102 -0
  108. package/core/{frontend/services/settings → server/services/route-settings}/validate.js +38 -28
  109. package/core/server/services/route-settings/yaml-parser.js +53 -0
  110. package/core/server/services/settings/index.js +13 -16
  111. package/core/server/services/settings/settings-bread-service.js +188 -0
  112. package/core/server/services/settings/settings-utils.js +32 -0
  113. package/core/server/services/themes/ThemeStorage.js +5 -4
  114. package/core/server/services/themes/activation-bridge.js +14 -0
  115. package/core/server/services/themes/validate.js +5 -2
  116. package/core/server/web/admin/views/default-prod.html +4 -4
  117. package/core/server/web/admin/views/default.html +4 -4
  118. package/core/server/web/api/canary/admin/routes.js +5 -1
  119. package/core/server/web/members/app.js +3 -0
  120. package/core/server/web/oauth/app.js +7 -8
  121. package/core/server/web/shared/middlewares/custom-redirects.js +82 -59
  122. package/core/server/web/site/routes.js +2 -2
  123. package/core/shared/config/defaults.json +2 -2
  124. package/core/shared/config/overrides.json +1 -1
  125. package/core/shared/custom-theme-settings-cache.js +3 -0
  126. package/core/shared/i18n/translations/en.json +2 -13
  127. package/core/shared/labs.js +2 -2
  128. package/package.json +42 -41
  129. package/yarn.lock +916 -901
  130. package/core/built/assets/ghost-dark-faf931d90e92535e6c03ca16793cbe7b.css +0 -1
  131. package/core/built/assets/ghost.min-7aa074ad556a8455155ac88ceaca03ab.css +0 -1
  132. package/core/frontend/services/redirects/index.js +0 -9
  133. package/core/frontend/services/redirects/validation.js +0 -28
  134. package/core/frontend/services/settings/ensure-settings.js +0 -47
  135. package/core/frontend/services/settings/index.js +0 -104
  136. package/core/frontend/services/settings/loader.js +0 -89
  137. package/core/frontend/services/settings/yaml-parser.js +0 -31
@@ -0,0 +1,162 @@
1
+ const _ = require('lodash');
2
+ const Promise = require('bluebird');
3
+ const semver = require('semver');
4
+ const {IncorrectUsageError} = require('@tryghost/errors');
5
+ const debug = require('@tryghost/debug')('importer:data');
6
+ const {sequence} = require('@tryghost/promise');
7
+ const models = require('../../../../models');
8
+ const PostsImporter = require('./posts');
9
+ const TagsImporter = require('./tags');
10
+ const SettingsImporter = require('./settings');
11
+ const UsersImporter = require('./users');
12
+ const RolesImporter = require('./roles');
13
+ let importers = {};
14
+ let DataImporter;
15
+
16
+ DataImporter = {
17
+ type: 'data',
18
+
19
+ preProcess: function preProcess(importData) {
20
+ importData.preProcessedByData = true;
21
+ return importData;
22
+ },
23
+
24
+ init: function init(importData) {
25
+ importers.users = new UsersImporter(importData.data);
26
+ importers.roles = new RolesImporter(importData.data);
27
+ importers.tags = new TagsImporter(importData.data);
28
+ importers.posts = new PostsImporter(importData.data);
29
+ importers.settings = new SettingsImporter(importData.data);
30
+
31
+ return importData;
32
+ },
33
+
34
+ // Allow importing with an options object that is passed through the importer
35
+ doImport: function doImport(importData, importOptions) {
36
+ importOptions = importOptions || {};
37
+
38
+ const ops = [];
39
+ let errors = [];
40
+ let results = [];
41
+
42
+ const modelOptions = {
43
+ importing: true,
44
+ context: {
45
+ internal: true
46
+ }
47
+ };
48
+
49
+ if (!Object.prototype.hasOwnProperty.call(importOptions, 'returnImportedData')) {
50
+ importOptions.returnImportedData = false;
51
+ }
52
+
53
+ if (importOptions.importPersistUser) {
54
+ modelOptions.importPersistUser = importOptions.importPersistUser;
55
+ }
56
+
57
+ if (!importData.meta) {
58
+ return Promise.reject(new IncorrectUsageError({
59
+ message: 'Wrong importer structure. `meta` is missing.',
60
+ help: 'https://ghost.org/docs/migration/custom/'
61
+ }));
62
+ }
63
+
64
+ if (!importData.meta.version) {
65
+ return Promise.reject(new IncorrectUsageError({
66
+ message: 'Wrong importer structure. `meta.version` is missing.',
67
+ help: 'https://ghost.org/docs/migration/custom/'
68
+ }));
69
+ }
70
+
71
+ // CASE: We deny LTS imports, because these are major version jumps. Only imports from v1 until the latest are supported.
72
+ // We can detect a wrong structure by checking the meta version field. Ghost v0 doesn't use semver compliant versions.
73
+ if (!semver.valid(importData.meta.version)) {
74
+ return Promise.reject(new IncorrectUsageError({
75
+ message: 'Detected unsupported file structure.',
76
+ help: 'Please install Ghost 1.0, import the file and then update your blog to the latest Ghost version.\nVisit https://ghost.org/docs/update/ or ask for help in our https://forum.ghost.org.'
77
+ }));
78
+ }
79
+
80
+ this.init(importData);
81
+
82
+ return models.Base.transaction(function (transacting) {
83
+ modelOptions.transacting = transacting;
84
+
85
+ _.each(importers, function (importer) {
86
+ ops.push(function doModelImport() {
87
+ return importer.fetchExisting(modelOptions, importOptions)
88
+ .then(function () {
89
+ return importer.beforeImport(modelOptions, importOptions);
90
+ })
91
+ .then(function () {
92
+ if (importer.options.requiredImportedData.length) {
93
+ _.each(importer.options.requiredImportedData, (key) => {
94
+ importer.requiredImportedData[key] = importers[key].importedData;
95
+ });
96
+ }
97
+
98
+ if (importer.options.requiredExistingData.length) {
99
+ _.each(importer.options.requiredExistingData, (key) => {
100
+ importer.requiredExistingData[key] = importers[key].existingData;
101
+ });
102
+ }
103
+
104
+ return importer.replaceIdentifiers(modelOptions, importOptions);
105
+ })
106
+ .then(function () {
107
+ return importer.doImport(modelOptions, importOptions)
108
+ .then(function (_results) {
109
+ results = results.concat(_results);
110
+ });
111
+ });
112
+ });
113
+ });
114
+
115
+ sequence(ops)
116
+ .then(function () {
117
+ results.forEach(function (promise) {
118
+ if (!promise.isFulfilled()) {
119
+ errors = errors.concat(promise.reason());
120
+ }
121
+ });
122
+
123
+ if (errors.length === 0) {
124
+ transacting.commit();
125
+ } else {
126
+ transacting.rollback(errors);
127
+ }
128
+ });
129
+ }).then(function () {
130
+ /**
131
+ * data: imported data
132
+ * originalData: data from the json file
133
+ * problems: warnings
134
+ */
135
+ const toReturn = {
136
+ data: {},
137
+ originalData: importData.data,
138
+ problems: []
139
+ };
140
+
141
+ _.each(importers, function (importer) {
142
+ toReturn.problems = toReturn.problems.concat(importer.problems);
143
+
144
+ if (importOptions.returnImportedData) {
145
+ toReturn.data[importer.dataKeyToImport] = importer.importedDataToReturn;
146
+ }
147
+ });
148
+
149
+ return toReturn;
150
+ }).catch(function (err) {
151
+ debug(err);
152
+ return Promise.reject(err);
153
+ }).finally(() => {
154
+ // release memory
155
+ importers = {};
156
+ results = null;
157
+ importData = null;
158
+ });
159
+ }
160
+ };
161
+
162
+ module.exports = DataImporter;
@@ -1,162 +1 @@
1
- const _ = require('lodash');
2
- const Promise = require('bluebird');
3
- const semver = require('semver');
4
- const {IncorrectUsageError} = require('@tryghost/errors');
5
- const debug = require('@tryghost/debug')('importer:data');
6
- const {sequence} = require('@tryghost/promise');
7
- const models = require('../../../../models');
8
- const PostsImporter = require('./posts');
9
- const TagsImporter = require('./tags');
10
- const SettingsImporter = require('./settings');
11
- const UsersImporter = require('./users');
12
- const RolesImporter = require('./roles');
13
- let importers = {};
14
- let DataImporter;
15
-
16
- DataImporter = {
17
- type: 'data',
18
-
19
- preProcess: function preProcess(importData) {
20
- importData.preProcessedByData = true;
21
- return importData;
22
- },
23
-
24
- init: function init(importData) {
25
- importers.users = new UsersImporter(importData.data);
26
- importers.roles = new RolesImporter(importData.data);
27
- importers.tags = new TagsImporter(importData.data);
28
- importers.posts = new PostsImporter(importData.data);
29
- importers.settings = new SettingsImporter(importData.data);
30
-
31
- return importData;
32
- },
33
-
34
- // Allow importing with an options object that is passed through the importer
35
- doImport: function doImport(importData, importOptions) {
36
- importOptions = importOptions || {};
37
-
38
- const ops = [];
39
- let errors = [];
40
- let results = [];
41
-
42
- const modelOptions = {
43
- importing: true,
44
- context: {
45
- internal: true
46
- }
47
- };
48
-
49
- if (!Object.prototype.hasOwnProperty.call(importOptions, 'returnImportedData')) {
50
- importOptions.returnImportedData = false;
51
- }
52
-
53
- if (importOptions.importPersistUser) {
54
- modelOptions.importPersistUser = importOptions.importPersistUser;
55
- }
56
-
57
- if (!importData.meta) {
58
- return Promise.reject(new IncorrectUsageError({
59
- message: 'Wrong importer structure. `meta` is missing.',
60
- help: 'https://ghost.org/docs/migration/custom/'
61
- }));
62
- }
63
-
64
- if (!importData.meta.version) {
65
- return Promise.reject(new IncorrectUsageError({
66
- message: 'Wrong importer structure. `meta.version` is missing.',
67
- help: 'https://ghost.org/docs/migration/custom/'
68
- }));
69
- }
70
-
71
- // CASE: We deny LTS imports, because these are major version jumps. Only imports from v1 until the latest are supported.
72
- // We can detect a wrong structure by checking the meta version field. Ghost v0 doesn't use semver compliant versions.
73
- if (!semver.valid(importData.meta.version)) {
74
- return Promise.reject(new IncorrectUsageError({
75
- message: 'Detected unsupported file structure.',
76
- help: 'Please install Ghost 1.0, import the file and then update your blog to the latest Ghost version.\nVisit https://ghost.org/docs/update/ or ask for help in our https://forum.ghost.org.'
77
- }));
78
- }
79
-
80
- this.init(importData);
81
-
82
- return models.Base.transaction(function (transacting) {
83
- modelOptions.transacting = transacting;
84
-
85
- _.each(importers, function (importer) {
86
- ops.push(function doModelImport() {
87
- return importer.fetchExisting(modelOptions, importOptions)
88
- .then(function () {
89
- return importer.beforeImport(modelOptions, importOptions);
90
- })
91
- .then(function () {
92
- if (importer.options.requiredImportedData.length) {
93
- _.each(importer.options.requiredImportedData, (key) => {
94
- importer.requiredImportedData[key] = importers[key].importedData;
95
- });
96
- }
97
-
98
- if (importer.options.requiredExistingData.length) {
99
- _.each(importer.options.requiredExistingData, (key) => {
100
- importer.requiredExistingData[key] = importers[key].existingData;
101
- });
102
- }
103
-
104
- return importer.replaceIdentifiers(modelOptions, importOptions);
105
- })
106
- .then(function () {
107
- return importer.doImport(modelOptions, importOptions)
108
- .then(function (_results) {
109
- results = results.concat(_results);
110
- });
111
- });
112
- });
113
- });
114
-
115
- sequence(ops)
116
- .then(function () {
117
- results.forEach(function (promise) {
118
- if (!promise.isFulfilled()) {
119
- errors = errors.concat(promise.reason());
120
- }
121
- });
122
-
123
- if (errors.length === 0) {
124
- transacting.commit();
125
- } else {
126
- transacting.rollback(errors);
127
- }
128
- });
129
- }).then(function () {
130
- /**
131
- * data: imported data
132
- * originalData: data from the json file
133
- * problems: warnings
134
- */
135
- const toReturn = {
136
- data: {},
137
- originalData: importData.data,
138
- problems: []
139
- };
140
-
141
- _.each(importers, function (importer) {
142
- toReturn.problems = toReturn.problems.concat(importer.problems);
143
-
144
- if (importOptions.returnImportedData) {
145
- toReturn.data[importer.dataKeyToImport] = importer.importedDataToReturn;
146
- }
147
- });
148
-
149
- return toReturn;
150
- }).catch(function (err) {
151
- debug(err);
152
- return Promise.reject(err);
153
- }).finally(() => {
154
- // release memory
155
- importers = {};
156
- results = null;
157
- importData = null;
158
- });
159
- }
160
- };
161
-
162
- module.exports = DataImporter;
1
+ module.exports = require('./data-importer');