0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

Added initial tiers service to Ghost

refs https://github.com/TryGhost/Team/issues/2078

This allows us to start wiring up the new package to the Admin & Content API's
This commit is contained in:
Fabien "egg" O'Carroll 2022-10-21 15:27:45 +07:00
parent df145797b3
commit cc14ce2b20
5 changed files with 152 additions and 0 deletions

View file

@ -274,6 +274,7 @@ async function initServices({config}) {
debug('Begin: Services');
const stripe = require('./server/services/stripe');
const members = require('./server/services/members');
const tiers = require('./server/services/tiers');
const permissions = require('./server/services/permissions');
const xmlrpc = require('./server/services/xmlrpc');
const slack = require('./server/services/slack');
@ -304,6 +305,7 @@ async function initServices({config}) {
memberAttribution.init(),
staffService.init(),
members.init(),
tiers.init(),
membersEvents.init(),
permissions.init(),
xmlrpc.listen(),

View file

@ -0,0 +1,116 @@
const {Tier} = require('@tryghost/tiers');
/**
* @typedef {import('@tryghost/tiers/lib/TiersAPI').ITierRepository} ITierRepository
*/
/**
* @implements {ITierRepository}
*/
module.exports = class TierRepository {
/** @type {Object} */
#ProductModel;
/** @type {import('@tryghost/domain-events')} */
#DomainEvents;
/**
* @param {object} deps
* @param {object} deps.ProductModel Bookshelf Model
* @param {import('@tryghost/domain-events')} deps.DomainEvents
*/
constructor(deps) {
this.#ProductModel = deps.ProductModel;
this.#DomainEvents = deps.DomainEvents;
}
/**
* @private
*/
mapToTier(model) {
const json = model.toJSON();
return {
id: json.id,
name: json.name,
slug: json.slug,
status: json.active ? 'active' : 'archived',
welcomePageURL: json.welcome_page_url,
visibility: json.visibility,
trialDays: json.trial_days,
description: json.description,
type: json.type,
currency: json.currency,
monthlyPrice: json.monthly_price,
yearlyPrice: json.yearly_price,
createdAt: json.created_at,
updatedAt: json.updated_at,
benefits: json.benefits.map(item => item.name)
};
}
/**
* @param {object} [options]
* @param {string} [options.filter]
* @returns {Promise<import('@tryghost/tiers/lib/Tier')[]>}
*/
async getAll(options = {}) {
const collection = await this.#ProductModel.findAll({...options, withRelated: ['benefits']});
const result = [];
for (const model of collection.models) {
const tier = await Tier.create(this.mapToTier(model));
result.push(tier);
}
return result;
}
/**
* @param {import('bson-objectid').default} id
* @returns {Promise<import('@tryghost/tiers/lib/Tier')>}
*/
async getById(id) {
const model = await this.#ProductModel.findOne({id: id.toHexString()}, {withRelated: ['benefits']});
return await Tier.create(this.mapToTier(model));
}
/**
* @param {import('@tryghost/tiers/lib/Tier')} tier
* @returns {Promise<void>}
*/
async save(tier) {
const data = {
id: tier.id.toHexString(),
name: tier.name,
slug: tier.slug,
active: tier.status === 'active',
welcome_page_url: tier.welcomePageURL,
visibility: tier.visibility,
trial_days: tier.trialDays,
description: tier.description,
type: tier.type,
currency: tier.currency,
monthly_price: tier.monthlyPrice,
yearly_price: tier.yearlyPrice,
created_at: tier.createdAt,
updated_at: tier.updatedAt,
benefits: tier.benefits.map(name => ({name}))
};
const existing = await this.#ProductModel.findOne({id: data.id}, {require: false});
if (!existing) {
await this.#ProductModel.add(data);
} else {
await this.#ProductModel.edit(data, {
id: data.id
});
}
for (const event of tier.events) {
this.#DomainEvents.dispatch(event);
}
}
};

View file

@ -0,0 +1 @@
module.exports = require('./service');

View file

@ -0,0 +1,32 @@
class TiersServiceWrapper {
async init() {
if (this.api) {
// Already done
return;
}
const {TiersAPI} = require('@tryghost/tiers');
const DomainEvents = require('@tryghost/domain-events');
const models = require('../../models');
const TierRepository = require('./TierRepository');
const repository = new TierRepository({
ProductModel: models.Product,
DomainEvents
});
const slugService = {
async generate(input) {
return models.Product.generateSlug(models.Product, input, {});
}
};
this.api = new TiersAPI({
repository,
slugService
});
}
}
module.exports = new TiersServiceWrapper();

View file

@ -120,6 +120,7 @@
"@tryghost/staff-service": "0.0.0",
"@tryghost/stats-service": "0.0.0",
"@tryghost/string": "0.2.1",
"@tryghost/tiers": "0.0.0",
"@tryghost/tpl": "0.1.19",
"@tryghost/update-check-service": "0.0.0",
"@tryghost/url-utils": "4.2.0",