mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-28 05:37:34 +03:00
5f928794c3
refs https://github.com/TryGhost/Team/issues/2078 These events are all required for other parts of the Ghost system to stay in sync. The events on each Tier object will be dispatched by the TierRepository once they've been persisted. TierCreatedEvent - generate Stripe Products & Prices TierNameChangeEvent - update Stripe Products TierPriceChangeEvent - update Stripe Products & Prices TierArchivedEvent - update the Portal settings for visible tiers - disable Stripe Products & Prices TierActivatedEvent - enable Stripe Products & Prices
147 lines
4.0 KiB
JavaScript
147 lines
4.0 KiB
JavaScript
const ObjectID = require('bson-objectid').default;
|
|
const {BadRequestError} = require('@tryghost/errors');
|
|
const Tier = require('./Tier');
|
|
|
|
/**
|
|
* @typedef {object} ITierRepository
|
|
* @prop {(id: ObjectID) => Promise<Tier>} getById
|
|
* @prop {(tier: Tier) => Promise<void>} save
|
|
* @prop {(options?: {filter?: string}) => Promise<Tier[]>} getAll
|
|
*/
|
|
|
|
/**
|
|
* @typedef {object} ISlugService
|
|
* @prop {(input: string) => Promise<string>} generate
|
|
*/
|
|
|
|
/**
|
|
* @template {Model}
|
|
* @typedef {object} Page<Model>
|
|
* @prop {Model[]} data
|
|
* @prop {object} meta
|
|
* @prop {object} meta.pagination
|
|
* @prop {number} meta.pagination.page - The current page
|
|
* @prop {number} meta.pagination.pages - The total number of pages
|
|
* @prop {number} meta.pagination.limit - The limit of models per page
|
|
* @prop {number} meta.pagination.total - The totaL number of models across all pages
|
|
* @prop {number|null} meta.pagination.prev - The number of the previous page, or null if there isn't one
|
|
* @prop {number|null} meta.pagination.next - The number of the next page, or null if there isn't one
|
|
*/
|
|
|
|
module.exports = class TiersAPI {
|
|
/** @type {ITierRepository} */
|
|
#repository;
|
|
|
|
/** @type {ISlugService} */
|
|
#slugService;
|
|
|
|
constructor(deps) {
|
|
this.#repository = deps.repository;
|
|
this.#slugService = deps.slugService;
|
|
}
|
|
|
|
/**
|
|
* @param {object} [options]
|
|
* @param {string} [options.filter] - An NQL filter string
|
|
*
|
|
* @returns {Promise<Page<Tier>>}
|
|
*/
|
|
async browse(options = {}) {
|
|
const tiers = await this.#repository.getAll(options);
|
|
|
|
return {
|
|
data: tiers,
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
pages: 1,
|
|
limit: tiers.length,
|
|
total: tiers.length,
|
|
prev: null,
|
|
next: null
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @param {string} idString
|
|
*
|
|
* @returns {Promise<Tier>}
|
|
*/
|
|
async read(idString) {
|
|
const id = ObjectID.createFromHexString(idString);
|
|
const tier = await this.#repository.getById(id);
|
|
|
|
return tier;
|
|
}
|
|
|
|
/**
|
|
* @param {string} id
|
|
* @param {object} data
|
|
* @returns {Promise<Tier>}
|
|
*/
|
|
async edit(idString, data) {
|
|
const id = ObjectID.createFromHexString(idString);
|
|
const tier = await this.#repository.getById(id);
|
|
|
|
const editableProperties = [
|
|
'name',
|
|
'benefits',
|
|
'description',
|
|
'visibility',
|
|
'active',
|
|
'trialDays',
|
|
'welcomePageURL'
|
|
];
|
|
|
|
for (const editableProperty of editableProperties) {
|
|
if (Reflect.has(data, editableProperty)) {
|
|
tier[editableProperty] = data[editableProperty];
|
|
}
|
|
}
|
|
|
|
tier.updatePricing({
|
|
currency: data.currency || tier.currency,
|
|
monthlyPrice: data.monthlyPrice || tier.monthlyPrice,
|
|
yearlyPrice: data.yearlyPrice || tier.yearlyPrice
|
|
});
|
|
|
|
await this.#repository.save(tier);
|
|
|
|
return tier;
|
|
}
|
|
|
|
/**
|
|
* @param {object} data
|
|
* @returns {Promise<Tier>}
|
|
*/
|
|
async add(data) {
|
|
if (data.type === 'free') {
|
|
throw new BadRequestError({
|
|
message: 'Cannot create free Tier'
|
|
});
|
|
}
|
|
|
|
const slug = await this.#slugService.generate(data.slug || data.name);
|
|
const tier = await Tier.create({
|
|
slug,
|
|
type: 'paid',
|
|
status: 'active',
|
|
visibility: data.visibility,
|
|
name: data.name,
|
|
description: data.description,
|
|
benefits: data.benefits,
|
|
welcomePageURL: data.welcomePageURL,
|
|
monthlyPrice: data.monthlyPrice,
|
|
yearlyPrice: data.yearlyPrice,
|
|
currency: data.currency,
|
|
trialDays: data.trialDays
|
|
});
|
|
|
|
await this.#repository.save(tier);
|
|
|
|
return tier;
|
|
}
|
|
};
|