mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Wired up Tiers service to Tiers Content & Admin API
refs https://github.com/TryGhost/Team/issues/2078
This commit is contained in:
parent
cc14ce2b20
commit
31610f9b94
6 changed files with 51 additions and 155 deletions
|
@ -1,8 +1,4 @@
|
|||
// NOTE: We must not cache references to membersService.api
|
||||
// as it is a getter and may change during runtime.
|
||||
const membersService = require('../../services/members');
|
||||
|
||||
const allowedIncludes = ['monthly_price', 'yearly_price', 'benefits'];
|
||||
const tiersService = require('../../services/tiers');
|
||||
|
||||
module.exports = {
|
||||
docName: 'tiers',
|
||||
|
@ -11,22 +7,14 @@ module.exports = {
|
|||
options: [
|
||||
'limit',
|
||||
'fields',
|
||||
'include',
|
||||
'filter',
|
||||
'order',
|
||||
'debug',
|
||||
'page'
|
||||
],
|
||||
permissions: true,
|
||||
validation: {
|
||||
options: {
|
||||
include: {
|
||||
values: allowedIncludes
|
||||
}
|
||||
}
|
||||
},
|
||||
async query(frame) {
|
||||
const page = await membersService.api.productRepository.list(frame.options);
|
||||
const page = await tiersService.api.browse(frame.options);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,4 @@
|
|||
const errors = require('@tryghost/errors');
|
||||
const membersService = require('../../services/members');
|
||||
|
||||
const tpl = require('@tryghost/tpl');
|
||||
|
||||
const allowedIncludes = ['monthly_price', 'yearly_price', 'benefits'];
|
||||
|
||||
const messages = {
|
||||
productNotFound: 'Tier not found.'
|
||||
};
|
||||
const tiersService = require('../../services/tiers');
|
||||
|
||||
module.exports = {
|
||||
docName: 'tiers',
|
||||
|
@ -16,7 +7,6 @@ module.exports = {
|
|||
options: [
|
||||
'limit',
|
||||
'fields',
|
||||
'include',
|
||||
'filter',
|
||||
'order',
|
||||
'debug',
|
||||
|
@ -25,48 +15,21 @@ module.exports = {
|
|||
permissions: {
|
||||
docName: 'products'
|
||||
},
|
||||
validation: {
|
||||
options: {
|
||||
include: {
|
||||
values: allowedIncludes
|
||||
}
|
||||
}
|
||||
},
|
||||
async query(frame) {
|
||||
const page = await membersService.api.productRepository.list(frame.options);
|
||||
|
||||
const page = await tiersService.api.browse(frame.options);
|
||||
return page;
|
||||
}
|
||||
},
|
||||
|
||||
read: {
|
||||
options: [
|
||||
'include'
|
||||
],
|
||||
headers: {},
|
||||
data: [
|
||||
'id'
|
||||
],
|
||||
validation: {
|
||||
options: {
|
||||
include: {
|
||||
values: allowedIncludes
|
||||
}
|
||||
}
|
||||
},
|
||||
permissions: {
|
||||
docName: 'products'
|
||||
},
|
||||
async query(frame) {
|
||||
const model = await membersService.api.productRepository.get(frame.data, frame.options);
|
||||
|
||||
if (!model) {
|
||||
throw new errors.NotFoundError({
|
||||
message: tpl(messages.productNotFound)
|
||||
});
|
||||
}
|
||||
|
||||
return model;
|
||||
return await tiersService.api.read(frame.data.id);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -84,11 +47,7 @@ module.exports = {
|
|||
docName: 'products'
|
||||
},
|
||||
async query(frame) {
|
||||
const model = await membersService.api.productRepository.create(
|
||||
frame.data,
|
||||
frame.options
|
||||
);
|
||||
return model;
|
||||
return await tiersService.api.add(frame.data);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -111,12 +70,7 @@ module.exports = {
|
|||
docName: 'products'
|
||||
},
|
||||
async query(frame) {
|
||||
const model = await membersService.api.productRepository.update(
|
||||
frame.data,
|
||||
frame.options
|
||||
);
|
||||
|
||||
return model;
|
||||
return await tiersService.api.edit(frame.options.id, frame.data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const localUtils = require('../../index');
|
||||
const labs = require('../../../../../../shared/labs');
|
||||
|
||||
const forceActiveFilter = (frame) => {
|
||||
if (frame.options.filter) {
|
||||
|
@ -10,39 +9,31 @@ const forceActiveFilter = (frame) => {
|
|||
};
|
||||
|
||||
function convertTierInput(input) {
|
||||
const converted = {
|
||||
id: input.id,
|
||||
name: input.name,
|
||||
description: input.description,
|
||||
slug: input.slug,
|
||||
active: input.active,
|
||||
type: input.type,
|
||||
welcome_page_url: input.welcome_page_url,
|
||||
created_at: input.created_at,
|
||||
updated_at: input.updated_at,
|
||||
visibility: input.visibility
|
||||
};
|
||||
const converted = Object.assign({}, input);
|
||||
|
||||
if (labs.isSet('freeTrial')) {
|
||||
converted.trial_days = input.trial_days || 0;
|
||||
if (Reflect.has(converted, 'active')) {
|
||||
converted.status = converted.active ? 'active' : 'archived';
|
||||
delete converted.active;
|
||||
}
|
||||
|
||||
if (input.monthly_price && input.currency) {
|
||||
converted.monthly_price = {
|
||||
amount: input.monthly_price,
|
||||
currency: input.currency
|
||||
};
|
||||
if (Reflect.has(converted, 'welcome_page_url')) {
|
||||
converted.welcomePageURL = converted.welcome_page_url;
|
||||
delete converted.welcome_page_url;
|
||||
}
|
||||
|
||||
if (input.yearly_price && input.currency) {
|
||||
converted.yearly_price = {
|
||||
amount: input.yearly_price,
|
||||
currency: input.currency
|
||||
};
|
||||
if (Reflect.has(converted, 'trial_days')) {
|
||||
converted.trialDays = converted.trial_days;
|
||||
delete converted.trial_days;
|
||||
}
|
||||
|
||||
if (input.benefits) {
|
||||
converted.benefits = input.benefits.map(name => ({name}));
|
||||
if (Reflect.has(converted, 'monthly_price')) {
|
||||
converted.monthlyPrice = converted.monthly_price;
|
||||
delete converted.monthly_price;
|
||||
}
|
||||
|
||||
if (Reflect.has(converted, 'yearly_price')) {
|
||||
converted.yearlyPrice = converted.yearly_price;
|
||||
delete converted.yearly_price;
|
||||
}
|
||||
|
||||
return converted;
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
//@ts-check
|
||||
const debug = require('@tryghost/debug')('api:endpoints:utils:serializers:output:tiers');
|
||||
|
||||
const allowedIncludes = ['monthly_price', 'yearly_price'];
|
||||
const localUtils = require('../../index');
|
||||
const {utils} = require('@tryghost/api-framework');
|
||||
const labs = require('../../../../../../shared/labs');
|
||||
|
||||
module.exports = {
|
||||
browse: createSerializer('browse', paginatedTiers),
|
||||
read: createSerializer('read', singleTier),
|
||||
|
@ -49,11 +44,10 @@ function singleTier(model, _apiConfig, frame) {
|
|||
/**
|
||||
* @param {import('bookshelf').Model} tier
|
||||
* @param {object} options
|
||||
* @param {object} frame
|
||||
*
|
||||
* @returns {SerializedTier}
|
||||
*/
|
||||
function serializeTier(tier, options, frame) {
|
||||
function serializeTier(tier, options) {
|
||||
const json = tier.toJSON(options);
|
||||
|
||||
const serialized = {
|
||||
|
@ -61,66 +55,32 @@ function serializeTier(tier, options, frame) {
|
|||
name: json.name,
|
||||
description: json.description,
|
||||
slug: json.slug,
|
||||
active: json.active,
|
||||
active: json.status === 'active',
|
||||
type: json.type,
|
||||
welcome_page_url: json.welcome_page_url,
|
||||
created_at: json.created_at,
|
||||
updated_at: json.updated_at,
|
||||
welcome_page_url: json.welcomePageURL,
|
||||
created_at: json.createdAt,
|
||||
updated_at: json.updatedAt,
|
||||
visibility: json.visibility,
|
||||
benefits: null
|
||||
benefits: json.benefits,
|
||||
currency: json.currency,
|
||||
monthly_price: json.monthlyPrice,
|
||||
yearly_price: json.yearlyPrice,
|
||||
trial_days: json.trialDays
|
||||
};
|
||||
|
||||
if (labs.isSet('freeTrial')) {
|
||||
serialized.trial_days = json.trial_days;
|
||||
}
|
||||
|
||||
if (Array.isArray(json.benefits)) {
|
||||
serialized.benefits = json.benefits.map(benefit => benefit.name);
|
||||
} else {
|
||||
if (!Array.isArray(serialized.benefits)) {
|
||||
serialized.benefits = null;
|
||||
}
|
||||
|
||||
if (serialized.type === 'paid') {
|
||||
serialized.currency = json.monthlyPrice?.currency;
|
||||
serialized.monthly_price = json.monthlyPrice?.amount;
|
||||
serialized.yearly_price = json.yearlyPrice?.amount;
|
||||
}
|
||||
|
||||
if (!localUtils.isContentAPI(frame)) {
|
||||
const requestedQueryIncludes = frame.original && frame.original.query && frame.original.query.include && frame.original.query.include.split(',') || [];
|
||||
const requestedOptionsIncludes = utils.options.trimAndLowerCase(frame.original && frame.original.options && frame.original.options.include || []);
|
||||
|
||||
return cleanIncludes(
|
||||
allowedIncludes,
|
||||
requestedQueryIncludes.concat(requestedOptionsIncludes),
|
||||
serialized
|
||||
);
|
||||
if (serialized.type === 'free') {
|
||||
delete serialized.currency;
|
||||
delete serialized.monthly_price;
|
||||
delete serialized.yearly_price;
|
||||
}
|
||||
|
||||
return serialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template Data
|
||||
*
|
||||
* @param {string[]} allowed
|
||||
* @param {string[]} requested
|
||||
* @param {Data & Object<string, any>} data
|
||||
*
|
||||
* @returns {Data}
|
||||
*/
|
||||
function cleanIncludes(allowed, requested, data) {
|
||||
const cleaned = {
|
||||
...data
|
||||
};
|
||||
for (const include of allowed) {
|
||||
if (!requested.includes(include)) {
|
||||
delete cleaned[include];
|
||||
}
|
||||
}
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template Data
|
||||
* @template Response
|
||||
|
|
|
@ -4,7 +4,7 @@ exports[`Tiers API Can browse Tiers 1: [body] 1`] = `
|
|||
Object {
|
||||
"meta": Object {
|
||||
"pagination": Object {
|
||||
"limit": 15,
|
||||
"limit": 2,
|
||||
"next": null,
|
||||
"page": 1,
|
||||
"pages": 1,
|
||||
|
@ -15,7 +15,7 @@ Object {
|
|||
"tiers": Array [
|
||||
Object {
|
||||
"active": true,
|
||||
"benefits": null,
|
||||
"benefits": Array [],
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"description": null,
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
|
@ -29,10 +29,12 @@ Object {
|
|||
},
|
||||
Object {
|
||||
"active": true,
|
||||
"benefits": null,
|
||||
"benefits": Array [],
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"currency": "USD",
|
||||
"description": null,
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"monthly_price": 500,
|
||||
"name": "Default Product",
|
||||
"slug": "default-product",
|
||||
"trial_days": 0,
|
||||
|
@ -40,6 +42,7 @@ Object {
|
|||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"visibility": "public",
|
||||
"welcome_page_url": "/welcome-paid",
|
||||
"yearly_price": 5000,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ exports[`Tiers Content API Can request only active tiers 1: [body] 1`] = `
|
|||
Object {
|
||||
"meta": Object {
|
||||
"pagination": Object {
|
||||
"limit": 15,
|
||||
"limit": 2,
|
||||
"next": null,
|
||||
"page": 1,
|
||||
"pages": 1,
|
||||
|
@ -31,10 +31,10 @@ Object {
|
|||
"active": true,
|
||||
"benefits": Array [],
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}/,
|
||||
"currency": "GBP",
|
||||
"currency": "USD",
|
||||
"description": null,
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"monthly_price": 1200,
|
||||
"monthly_price": 500,
|
||||
"name": "Default Product",
|
||||
"slug": "default-product",
|
||||
"trial_days": 0,
|
||||
|
@ -42,7 +42,7 @@ Object {
|
|||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}/,
|
||||
"visibility": "public",
|
||||
"welcome_page_url": "/welcome-paid",
|
||||
"yearly_price": 12000,
|
||||
"yearly_price": 5000,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ exports[`Tiers Content API Can request only active tiers 2: [headers] 1`] = `
|
|||
Object {
|
||||
"access-control-allow-origin": "*",
|
||||
"cache-control": "public, max-age=0",
|
||||
"content-length": "730",
|
||||
"content-length": "727",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Accept-Encoding",
|
||||
|
|
Loading…
Add table
Reference in a new issue