ghost 4.37.0 → 4.38.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.
- package/content/themes/casper/LICENSE +1 -1
- package/content/themes/casper/README.md +1 -1
- package/content/themes/casper/assets/built/global.css +1 -1
- package/content/themes/casper/assets/built/global.css.map +1 -1
- package/content/themes/casper/assets/built/screen.css +1 -1
- package/content/themes/casper/assets/built/screen.css.map +1 -1
- package/content/themes/casper/assets/css/global.css +14 -6
- package/content/themes/casper/assets/css/screen.css +9 -1
- package/content/themes/casper/package.json +2 -2
- package/content/themes/casper/partials/post-card.hbs +1 -1
- package/content/themes/casper/post.hbs +18 -19
- package/content/themes/casper/yarn.lock +186 -217
- package/core/built/assets/ghost-dark-9f760f16230b8bc52e188d6ce28516b0.css +1 -0
- package/core/built/assets/{ghost.min-c1938f6ee696bf08bd6bf93cac341ea2.js → ghost.min-6386b02480494a69c3bfe66206754836.js} +339 -279
- package/core/built/assets/ghost.min-f4c59dd57a2136df8b0a34f87c099034.css +1 -0
- package/core/built/assets/icons/eye.svg +4 -1
- package/core/built/assets/icons/member-add.svg +3 -0
- package/core/built/assets/icons/pin.svg +4 -1
- package/core/built/assets/{vendor.min-6dc30be68238b5c55df0cdc1f2dc8b8d.js → vendor.min-c814d3c4b3f543c4cd5ef3aacd0fc645.js} +36 -34
- package/core/frontend/helpers/get.js +4 -0
- package/core/frontend/helpers/match.js +12 -0
- package/core/frontend/helpers/prev_post.js +11 -1
- package/core/frontend/helpers/tiers.js +59 -0
- package/core/frontend/helpers/tpl/content-cta.hbs +1 -1
- package/core/frontend/services/routing/router-manager.js +1 -1
- package/core/frontend/web/site.js +10 -0
- package/core/server/api/canary/index.js +4 -0
- package/core/server/api/canary/members.js +2 -1
- package/core/server/api/canary/products.js +3 -6
- package/core/server/api/canary/tiers-public.js +34 -0
- package/core/server/api/canary/tiers.js +3 -6
- package/core/server/api/canary/utils/serializers/output/email-posts.js +7 -1
- package/core/server/api/canary/utils/serializers/output/pages.js +9 -2
- package/core/server/api/canary/utils/serializers/output/posts.js +8 -2
- package/core/server/api/canary/utils/serializers/output/preview.js +7 -1
- package/core/server/api/canary/utils/serializers/output/products.js +3 -1
- package/core/server/api/canary/utils/serializers/output/tiers.js +4 -2
- package/core/server/api/canary/utils/serializers/output/utils/mapper.js +17 -7
- package/core/server/data/db/connection.js +3 -2
- package/core/server/data/migrations/versions/3.29/01-remove-duplicate-subscriptions.js +2 -1
- package/core/server/data/migrations/versions/3.29/02-remove-duplicate-customers.js +2 -1
- package/core/server/data/migrations/versions/3.29/03-remove-orphaned-customers.js +2 -1
- package/core/server/data/migrations/versions/3.29/04-remove-orphaned-subscriptions.js +2 -1
- package/core/server/data/migrations/versions/3.29/05-add-member-constraints.js +3 -2
- package/core/server/data/migrations/versions/3.39/06-add-email-recipient-index.js +4 -3
- package/core/server/data/migrations/versions/4.0/14-remove-orphaned-stripe-records.js +2 -1
- package/core/server/data/migrations/versions/4.0/26-add-cascade-on-delete.js +2 -1
- package/core/server/data/migrations/versions/4.0/29-fix-foreign-key-for-members-stripe-customers-subscriptions.js +2 -1
- package/core/server/data/migrations/versions/4.1/02-add-unique-constraint-for-member-stripe-tables.js +2 -1
- package/core/server/data/migrations/versions/4.20/05-remove-not-null-constraint-from-portal-title.js +3 -2
- package/core/server/data/migrations/versions/4.33/2022-01-18-09-07-remove-duplicate-offer-redemptions.js +2 -2
- package/core/server/data/migrations/versions/4.35/2022-02-01-11-48-update-email-recipient-filter-column-type.js +2 -1
- package/core/server/data/migrations/versions/4.35/2022-02-01-12-03-update-recipient-filter-column-type.js +2 -1
- package/core/server/data/migrations/versions/4.37/2022-02-21-09-53-backfill-members-last-seen-at-column.js +3 -2
- package/core/server/data/migrations/versions/4.38/2022-03-01-08-46-add-visibility-to-tiers.js +11 -0
- package/core/server/data/migrations/versions/4.38/2022-03-03-16-12-add-visibility-to-tiers.js +8 -0
- package/core/server/data/migrations/versions/4.38/2022-03-03-16-17-drop-tiers-visible-column.js +7 -0
- package/core/server/data/schema/clients/index.js +1 -1
- package/core/server/data/schema/clients/mysql.js +4 -4
- package/core/server/data/schema/commands.js +42 -50
- package/core/server/data/schema/fixtures/fixtures.json +4 -2
- package/core/server/data/schema/schema.js +7 -0
- package/core/server/models/product.js +2 -1
- package/core/server/services/auth/api-key/admin.js +15 -6
- package/core/server/services/auth/setup.js +5 -0
- package/core/server/services/email-analytics/lib/event-processor.js +18 -1
- package/core/server/services/members/middleware.js +3 -0
- package/core/server/services/members/service.js +13 -1
- package/core/server/web/admin/views/default-prod.html +4 -4
- package/core/server/web/admin/views/default.html +4 -4
- package/core/server/web/api/app.js +3 -0
- package/core/server/web/api/canary/admin/middleware.js +2 -0
- package/core/server/web/api/canary/content/routes.js +1 -0
- package/core/server/web/members/app.js +1 -1
- package/core/shared/config/defaults.json +2 -2
- package/core/shared/config/utils.js +5 -1
- package/core/shared/labs.js +1 -0
- package/package.json +47 -44
- package/yarn.lock +606 -574
- package/core/built/assets/ghost-dark-d54723f7267e66fa2595f897076e86c2.css +0 -1
- package/core/built/assets/ghost.min-02a5f8954bd85fe28817b8c8b111b8aa.css +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const debug = require('@tryghost/debug')('api:canary:utils:serializers:output:pages');
|
|
2
2
|
const mapper = require('./utils/mapper');
|
|
3
|
+
const membersService = require('../../../../../services/members');
|
|
3
4
|
|
|
4
5
|
module.exports = {
|
|
5
6
|
async all(models, apiConfig, frame) {
|
|
@@ -10,9 +11,15 @@ module.exports = {
|
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
12
13
|
let pages = [];
|
|
14
|
+
|
|
15
|
+
const tiersModels = await membersService.api.productRepository.list({
|
|
16
|
+
withRelated: ['monthlyPrice', 'yearlyPrice']
|
|
17
|
+
});
|
|
18
|
+
const tiers = tiersModels.data ? tiersModels.data.map(tierModel => tierModel.toJSON()) : [];
|
|
19
|
+
|
|
13
20
|
if (models.meta) {
|
|
14
21
|
for (let model of models.data) {
|
|
15
|
-
let page = await mapper.mapPage(model, frame);
|
|
22
|
+
let page = await mapper.mapPage(model, frame, {tiers});
|
|
16
23
|
pages.push(page);
|
|
17
24
|
}
|
|
18
25
|
frame.response = {
|
|
@@ -22,7 +29,7 @@ module.exports = {
|
|
|
22
29
|
|
|
23
30
|
return;
|
|
24
31
|
}
|
|
25
|
-
let page = await mapper.mapPage(models, frame);
|
|
32
|
+
let page = await mapper.mapPage(models, frame, {tiers});
|
|
26
33
|
frame.response = {
|
|
27
34
|
pages: [page]
|
|
28
35
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const debug = require('@tryghost/debug')('api:canary:utils:serializers:output:posts');
|
|
2
2
|
const mapper = require('./utils/mapper');
|
|
3
|
+
const membersService = require('../../../../../services/members');
|
|
3
4
|
|
|
4
5
|
module.exports = {
|
|
5
6
|
async all(models, apiConfig, frame) {
|
|
@@ -10,9 +11,14 @@ module.exports = {
|
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
12
13
|
let posts = [];
|
|
14
|
+
|
|
15
|
+
const tiersModels = await membersService.api.productRepository.list({
|
|
16
|
+
withRelated: ['monthlyPrice', 'yearlyPrice']
|
|
17
|
+
});
|
|
18
|
+
const tiers = tiersModels.data ? tiersModels.data.map(tierModel => tierModel.toJSON()) : [];
|
|
13
19
|
if (models.meta) {
|
|
14
20
|
for (let model of models.data) {
|
|
15
|
-
let post = await mapper.mapPost(model, frame);
|
|
21
|
+
let post = await mapper.mapPost(model, frame, {tiers});
|
|
16
22
|
posts.push(post);
|
|
17
23
|
}
|
|
18
24
|
frame.response = {
|
|
@@ -22,7 +28,7 @@ module.exports = {
|
|
|
22
28
|
|
|
23
29
|
return;
|
|
24
30
|
}
|
|
25
|
-
let post = await mapper.mapPost(models, frame);
|
|
31
|
+
let post = await mapper.mapPost(models, frame, {tiers});
|
|
26
32
|
frame.response = {
|
|
27
33
|
posts: [post]
|
|
28
34
|
};
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
const mapper = require('./utils/mapper');
|
|
2
|
+
const membersService = require('../../../../../services/members');
|
|
2
3
|
|
|
3
4
|
module.exports = {
|
|
4
5
|
async all(model, apiConfig, frame) {
|
|
5
|
-
const
|
|
6
|
+
const tiersModels = await membersService.api.productRepository.list({
|
|
7
|
+
withRelated: ['monthlyPrice', 'yearlyPrice']
|
|
8
|
+
});
|
|
9
|
+
const tiers = tiersModels.data ? tiersModels.data.map(tierModel => tierModel.toJSON()) : [];
|
|
10
|
+
|
|
11
|
+
const data = await mapper.mapPost(model, frame, {tiers});
|
|
6
12
|
frame.response = {
|
|
7
13
|
preview: [data]
|
|
8
14
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
const debug = require('@tryghost/debug')('api:canary:utils:serializers:output:products');
|
|
3
3
|
const _ = require('lodash');
|
|
4
|
+
const utils = require('../../../../shared/utils');
|
|
4
5
|
|
|
5
6
|
const allowedIncludes = ['stripe_prices', 'monthly_price', 'yearly_price'];
|
|
6
7
|
|
|
@@ -22,7 +23,7 @@ module.exports = {
|
|
|
22
23
|
*/
|
|
23
24
|
function paginatedProducts(page, _apiConfig, frame) {
|
|
24
25
|
const requestedQueryIncludes = frame.original && frame.original.query && frame.original.query.include && frame.original.query.include.split(',') || [];
|
|
25
|
-
const requestedOptionsIncludes = frame.original && frame.original.options && frame.original.options.include || [];
|
|
26
|
+
const requestedOptionsIncludes = utils.options.trimAndLowerCase(frame.original && frame.original.options && frame.original.options.include || []);
|
|
26
27
|
return {
|
|
27
28
|
products: page.data.map((model) => {
|
|
28
29
|
return cleanIncludes(
|
|
@@ -74,6 +75,7 @@ function serializeProduct(product, options, apiType) {
|
|
|
74
75
|
description: json.description,
|
|
75
76
|
slug: json.slug,
|
|
76
77
|
active: json.active,
|
|
78
|
+
visibility: json.visibility,
|
|
77
79
|
type: json.type,
|
|
78
80
|
welcome_page_url: json.welcome_page_url,
|
|
79
81
|
created_at: json.created_at,
|
|
@@ -3,6 +3,7 @@ const debug = require('@tryghost/debug')('api:canary:utils:serializers:output:ti
|
|
|
3
3
|
const _ = require('lodash');
|
|
4
4
|
|
|
5
5
|
const allowedIncludes = ['monthly_price', 'yearly_price'];
|
|
6
|
+
const utils = require('../../../../shared/utils');
|
|
6
7
|
|
|
7
8
|
module.exports = {
|
|
8
9
|
browse: createSerializer('browse', paginatedTiers),
|
|
@@ -22,7 +23,7 @@ module.exports = {
|
|
|
22
23
|
*/
|
|
23
24
|
function paginatedTiers(page, _apiConfig, frame) {
|
|
24
25
|
const requestedQueryIncludes = frame.original && frame.original.query && frame.original.query.include && frame.original.query.include.split(',') || [];
|
|
25
|
-
const requestedOptionsIncludes = frame.original && frame.original.options && frame.original.options.include || [];
|
|
26
|
+
const requestedOptionsIncludes = utils.options.trimAndLowerCase(frame.original && frame.original.options && frame.original.options.include || []);
|
|
26
27
|
return {
|
|
27
28
|
tiers: page.data.map((model) => {
|
|
28
29
|
return cleanIncludes(
|
|
@@ -81,7 +82,8 @@ function serializeTier(tier, options, apiType) {
|
|
|
81
82
|
stripe_prices: json.stripePrices ? json.stripePrices.map(price => serializeStripePrice(price, hideStripeData)) : null,
|
|
82
83
|
monthly_price: serializeStripePrice(json.monthlyPrice, hideStripeData),
|
|
83
84
|
yearly_price: serializeStripePrice(json.yearlyPrice, hideStripeData),
|
|
84
|
-
benefits: json.benefits || null
|
|
85
|
+
benefits: json.benefits || null,
|
|
86
|
+
visibility: json.visibility
|
|
85
87
|
};
|
|
86
88
|
|
|
87
89
|
return serialized;
|
|
@@ -31,7 +31,8 @@ const mapTag = (model, frame) => {
|
|
|
31
31
|
return jsonModel;
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
const mapPost = async (model, frame) => {
|
|
34
|
+
const mapPost = async (model, frame, options = {}) => {
|
|
35
|
+
const {tiers: tiersData} = options || {};
|
|
35
36
|
const extendedOptions = Object.assign(_.cloneDeep(frame.options), {
|
|
36
37
|
extraProperties: ['canonical_url']
|
|
37
38
|
});
|
|
@@ -45,12 +46,21 @@ const mapPost = async (model, frame) => {
|
|
|
45
46
|
// Attach tiers to custom nql visibility filter
|
|
46
47
|
if (labsService.isSet('multipleProducts')
|
|
47
48
|
&& jsonModel.visibility
|
|
48
|
-
&& !['members', 'public', 'paid', 'tiers'].includes(jsonModel.visibility)
|
|
49
49
|
) {
|
|
50
|
-
|
|
50
|
+
if (['members', 'public'].includes(jsonModel.visibility) && jsonModel.tiers) {
|
|
51
|
+
jsonModel.tiers = tiersData || [];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (jsonModel.visibility === 'paid' && jsonModel.tiers) {
|
|
55
|
+
jsonModel.tiers = tiersData ? tiersData.filter(t => t.type === 'paid') : [];
|
|
56
|
+
}
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
if (!['members', 'public', 'paid', 'tiers'].includes(jsonModel.visibility)) {
|
|
59
|
+
const tiers = await postsService.getProductsFromVisibilityFilter(jsonModel.visibility);
|
|
60
|
+
|
|
61
|
+
jsonModel.visibility = 'tiers';
|
|
62
|
+
jsonModel.tiers = tiers;
|
|
63
|
+
}
|
|
54
64
|
}
|
|
55
65
|
|
|
56
66
|
if (utils.isContentAPI(frame)) {
|
|
@@ -103,8 +113,8 @@ const mapPost = async (model, frame) => {
|
|
|
103
113
|
return jsonModel;
|
|
104
114
|
};
|
|
105
115
|
|
|
106
|
-
const mapPage = async (model, frame) => {
|
|
107
|
-
const jsonModel = await mapPost(model, frame);
|
|
116
|
+
const mapPage = async (model, frame, options) => {
|
|
117
|
+
const jsonModel = await mapPost(model, frame, options);
|
|
108
118
|
|
|
109
119
|
delete jsonModel.email_subject;
|
|
110
120
|
delete jsonModel.email_recipient_filter;
|
|
@@ -32,9 +32,10 @@ function configure(dbConfig) {
|
|
|
32
32
|
process.env.BTHREADS_BACKEND = 'child_process';
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
if (client === '
|
|
36
|
-
dbConfig.connection.timezone = '
|
|
35
|
+
if (client === 'mysql2') {
|
|
36
|
+
dbConfig.connection.timezone = 'Z';
|
|
37
37
|
dbConfig.connection.charset = 'utf8mb4';
|
|
38
|
+
dbConfig.connection.decimalNumbers = true;
|
|
38
39
|
|
|
39
40
|
// NOTE: disabled so that worker processes can use the db without
|
|
40
41
|
// requiring logging and causing file desriptor leaks.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
2
3
|
|
|
3
4
|
module.exports = {
|
|
4
5
|
config: {
|
|
@@ -6,7 +7,7 @@ module.exports = {
|
|
|
6
7
|
},
|
|
7
8
|
|
|
8
9
|
async up({transacting: knex}) {
|
|
9
|
-
if (knex
|
|
10
|
+
if (!DatabaseInfo.isMySQL(knex)) {
|
|
10
11
|
logging.warn('Skipping cleanup of duplicate subscriptions - database is not MySQL');
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
2
3
|
|
|
3
4
|
module.exports = {
|
|
4
5
|
config: {
|
|
@@ -6,7 +7,7 @@ module.exports = {
|
|
|
6
7
|
},
|
|
7
8
|
|
|
8
9
|
async up({transacting: knex}) {
|
|
9
|
-
if (knex
|
|
10
|
+
if (!DatabaseInfo.isMySQL(knex)) {
|
|
10
11
|
logging.warn('Skipping cleanup of duplicate customers - database is not MySQL');
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
2
3
|
|
|
3
4
|
module.exports = {
|
|
4
5
|
config: {
|
|
@@ -6,7 +7,7 @@ module.exports = {
|
|
|
6
7
|
},
|
|
7
8
|
|
|
8
9
|
async up({transacting: knex}) {
|
|
9
|
-
if (knex
|
|
10
|
+
if (!DatabaseInfo.isMySQL(knex)) {
|
|
10
11
|
logging.warn('Skipping cleanup of orphaned customers - database is not MySQL');
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
2
3
|
|
|
3
4
|
module.exports = {
|
|
4
5
|
config: {
|
|
@@ -6,7 +7,7 @@ module.exports = {
|
|
|
6
7
|
},
|
|
7
8
|
|
|
8
9
|
async up({transacting: knex}) {
|
|
9
|
-
if (knex
|
|
10
|
+
if (!DatabaseInfo.isMySQL(knex)) {
|
|
10
11
|
logging.warn('Skipping cleanup of orphaned subscriptions - database is not MySQL');
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
2
3
|
|
|
3
4
|
module.exports = {
|
|
4
5
|
config: {
|
|
@@ -6,7 +7,7 @@ module.exports = {
|
|
|
6
7
|
},
|
|
7
8
|
|
|
8
9
|
async up({transacting: knex}) {
|
|
9
|
-
if (knex
|
|
10
|
+
if (!DatabaseInfo.isMySQL(knex)) {
|
|
10
11
|
return logging.warn('Skipping member tables index creation - database is not MySQL');
|
|
11
12
|
}
|
|
12
13
|
|
|
@@ -91,7 +92,7 @@ module.exports = {
|
|
|
91
92
|
},
|
|
92
93
|
|
|
93
94
|
async down({transacting: knex}) {
|
|
94
|
-
if (knex
|
|
95
|
+
if (!DatabaseInfo.isMySQL(knex)) {
|
|
95
96
|
return logging.warn('Skipping member tables index removal - database is not MySQL');
|
|
96
97
|
}
|
|
97
98
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const {createNonTransactionalMigration} = require('../../utils');
|
|
3
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
3
4
|
|
|
4
5
|
module.exports = createNonTransactionalMigration(
|
|
5
6
|
async function up(knex) {
|
|
6
7
|
let hasIndex = false;
|
|
7
8
|
|
|
8
|
-
if (knex
|
|
9
|
+
if (DatabaseInfo.isSQLite(knex)) {
|
|
9
10
|
const result = await knex.raw(`select * from sqlite_master where type = 'index' and tbl_name = 'email_recipients' and name = 'email_recipients_email_id_member_email_index'`);
|
|
10
11
|
hasIndex = result.length !== 0;
|
|
11
12
|
} else {
|
|
@@ -27,7 +28,7 @@ module.exports = createNonTransactionalMigration(
|
|
|
27
28
|
async function down(knex) {
|
|
28
29
|
let missingIndex = false;
|
|
29
30
|
|
|
30
|
-
if (knex
|
|
31
|
+
if (DatabaseInfo.isSQLite(knex)) {
|
|
31
32
|
const result = await knex.raw(`select * from sqlite_master where type = 'index' and tbl_name = 'email_recipients' and name = 'email_recipients_email_id_member_email_index'`);
|
|
32
33
|
missingIndex = result.length === 0;
|
|
33
34
|
} else {
|
|
@@ -42,7 +43,7 @@ module.exports = createNonTransactionalMigration(
|
|
|
42
43
|
|
|
43
44
|
logging.info('Dropping composite index on email_recipients for [email_id, member_email]');
|
|
44
45
|
|
|
45
|
-
if (knex
|
|
46
|
+
if (DatabaseInfo.isMySQL(knex)) {
|
|
46
47
|
await knex.schema.table('email_recipients', (table) => {
|
|
47
48
|
table.dropForeign('email_id');
|
|
48
49
|
table.dropIndex(['email_id', 'member_email']);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const {createIrreversibleMigration} = require('../../utils');
|
|
2
2
|
const logging = require('@tryghost/logging');
|
|
3
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
3
4
|
|
|
4
5
|
module.exports = createIrreversibleMigration(async function up(connection) {
|
|
5
|
-
if (connection
|
|
6
|
+
if (DatabaseInfo.isMySQL(connection)) {
|
|
6
7
|
logging.info('Skipping removal of orphaned stripe records for MySQL');
|
|
7
8
|
return;
|
|
8
9
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const {createIrreversibleMigration} = require('../../utils');
|
|
3
3
|
const {addForeign, dropForeign} = require('../../../schema/commands');
|
|
4
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
4
5
|
|
|
5
6
|
module.exports = createIrreversibleMigration(async (knex) => {
|
|
6
|
-
if (knex
|
|
7
|
+
if (!DatabaseInfo.isSQLite(knex)) {
|
|
7
8
|
return logging.warn('Skipping adding "on delete cascade" - database is not SQLite3');
|
|
8
9
|
}
|
|
9
10
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const {createIrreversibleMigration} = require('../../utils');
|
|
3
3
|
const {addForeign, dropForeign} = require('../../../schema/commands');
|
|
4
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
4
5
|
|
|
5
6
|
module.exports = createIrreversibleMigration(async (knex) => {
|
|
6
|
-
if (knex
|
|
7
|
+
if (!DatabaseInfo.isSQLite(knex)) {
|
|
7
8
|
return logging.warn('Skipping fixing foreign key for members_stripe_customers_subscriptions - database is not SQLite3');
|
|
8
9
|
}
|
|
9
10
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const {createTransactionalMigration} = require('../../utils');
|
|
3
3
|
const {addUnique} = require('../../../schema/commands');
|
|
4
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
4
5
|
|
|
5
6
|
module.exports = createTransactionalMigration(
|
|
6
7
|
async function up(connection) {
|
|
7
|
-
if (connection
|
|
8
|
+
if (!DatabaseInfo.isSQLite(connection)) {
|
|
8
9
|
return logging.warn('Skipping adding unique constraint for members_stripe_customers_subscriptions and members_stripe_customers - database is not SQLite3');
|
|
9
10
|
}
|
|
10
11
|
|
package/core/server/data/migrations/versions/4.20/05-remove-not-null-constraint-from-portal-title.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const {createNonTransactionalMigration} = require('../../utils');
|
|
3
3
|
const {addUnique} = require('../../../schema/commands');
|
|
4
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
4
5
|
|
|
5
6
|
module.exports = createNonTransactionalMigration(
|
|
6
7
|
async function up(knex) {
|
|
@@ -14,7 +15,7 @@ module.exports = createNonTransactionalMigration(
|
|
|
14
15
|
table.string('portal_title', 191).nullable();
|
|
15
16
|
});
|
|
16
17
|
|
|
17
|
-
if (knex
|
|
18
|
+
if (DatabaseInfo.isSQLite(knex)) {
|
|
18
19
|
// eslint-disable-next-line no-restricted-syntax
|
|
19
20
|
for (const column of ['name', 'code', 'stripe_coupon_id']) {
|
|
20
21
|
await addUnique('offers', column, knex);
|
|
@@ -32,7 +33,7 @@ module.exports = createNonTransactionalMigration(
|
|
|
32
33
|
table.string('portal_title', 191).notNullable();
|
|
33
34
|
});
|
|
34
35
|
|
|
35
|
-
if (knex
|
|
36
|
+
if (DatabaseInfo.isSQLite(knex)) {
|
|
36
37
|
// eslint-disable-next-line no-restricted-syntax
|
|
37
38
|
for (const column of ['name', 'code', 'stripe_coupon_id']) {
|
|
38
39
|
await addUnique('offers', column, knex);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
|
-
|
|
3
2
|
const {createTransactionalMigration} = require('../../utils');
|
|
3
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
4
4
|
|
|
5
5
|
module.exports = createTransactionalMigration(
|
|
6
6
|
async function up(knex) {
|
|
7
|
-
if (knex
|
|
7
|
+
if (!DatabaseInfo.isMySQL(knex)) {
|
|
8
8
|
logging.warn('Skipping cleanup of duplicate offer redemptions - database is not MySQL');
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const {createNonTransactionalMigration} = require('../../utils');
|
|
3
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
3
4
|
|
|
4
5
|
module.exports = createNonTransactionalMigration(
|
|
5
6
|
async function up(knex) {
|
|
6
|
-
if (knex
|
|
7
|
+
if (DatabaseInfo.isSQLite(knex)) {
|
|
7
8
|
logging.warn('Skipping migration for SQLite3');
|
|
8
9
|
return;
|
|
9
10
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const {createNonTransactionalMigration} = require('../../utils');
|
|
3
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
3
4
|
|
|
4
5
|
module.exports = createNonTransactionalMigration(
|
|
5
6
|
async function up(knex) {
|
|
6
|
-
if (knex
|
|
7
|
+
if (DatabaseInfo.isSQLite(knex)) {
|
|
7
8
|
logging.warn('Skipping migration for SQLite3');
|
|
8
9
|
return;
|
|
9
10
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const {createTransactionalMigration} = require('../../utils');
|
|
3
|
+
const DatabaseInfo = require('@tryghost/database-info');
|
|
3
4
|
|
|
4
5
|
module.exports = createTransactionalMigration(
|
|
5
6
|
async function up(knex) {
|
|
6
|
-
if (knex
|
|
7
|
+
if (DatabaseInfo.isSQLite(knex)) {
|
|
7
8
|
logging.warn('Skipping migration for SQLite3');
|
|
8
9
|
return;
|
|
9
10
|
}
|
|
@@ -21,7 +22,7 @@ module.exports = createTransactionalMigration(
|
|
|
21
22
|
`);
|
|
22
23
|
},
|
|
23
24
|
async function down(knex) {
|
|
24
|
-
if (knex
|
|
25
|
+
if (DatabaseInfo.isSQLite(knex)) {
|
|
25
26
|
logging.warn('Skipping migration for SQLite3');
|
|
26
27
|
return;
|
|
27
28
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const {createAddColumnMigration} = require('../../utils');
|
|
2
|
+
|
|
3
|
+
module.exports = createAddColumnMigration('products', 'visible', {
|
|
4
|
+
type: 'boolean',
|
|
5
|
+
nullable: false,
|
|
6
|
+
defaultTo: false
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
module.exports.up = async () => {
|
|
10
|
+
// noop - column will be replaced with `visibility` instead
|
|
11
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const _ = require('lodash');
|
|
2
2
|
const db = require('../../../data/db');
|
|
3
3
|
|
|
4
|
-
const doRawAndFlatten = function doRaw(query, transaction, flattenFn) {
|
|
5
|
-
return
|
|
4
|
+
const doRawAndFlatten = function doRaw(query, transaction = db.knex, flattenFn) {
|
|
5
|
+
return transaction.raw(query).then(function (response) {
|
|
6
6
|
return _.flatten(flattenFn(response));
|
|
7
7
|
});
|
|
8
8
|
};
|
|
@@ -31,8 +31,8 @@ const getColumns = function getColumns(table, transaction) {
|
|
|
31
31
|
// a wrong datatype in schema.js some installations using mysql could have been created using the
|
|
32
32
|
// data type text instead of mediumtext.
|
|
33
33
|
// For details see: https://github.com/TryGhost/Ghost/issues/1947
|
|
34
|
-
const checkPostTable = function checkPostTable(transaction) {
|
|
35
|
-
return
|
|
34
|
+
const checkPostTable = function checkPostTable(transaction = db.knex) {
|
|
35
|
+
return transaction.raw('SHOW FIELDS FROM posts where Field ="html" OR Field = "markdown"').then(function (response) {
|
|
36
36
|
return _.flatten(_.map(response[0], function (entry) {
|
|
37
37
|
if (entry.Type.toLowerCase() !== 'mediumtext') {
|
|
38
38
|
return (transaction || db.knex).raw('ALTER TABLE posts MODIFY ' + entry.Field + ' MEDIUMTEXT');
|