mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-21 01:41:46 +03:00
a1962f38cd
refs https://github.com/TryGhost/Team/issues/597
- To be able to transpile the library for different runtimes (make it polymorphic) had to get rid of dependencies that were not compatible with ES Modules
- By making errors an injectable constructor option it removes the depencency and allows to transpile the library for multiple targets
- The `errors` option is now a required parameter for `loadLimits` method. It errors if it's missing (error message copy inspired by content api error 69fcea0582/packages/content-api/lib/index.js (L21)
)
101 lines
2.9 KiB
JavaScript
101 lines
2.9 KiB
JavaScript
const {MaxLimit, FlagLimit} = require('./limit');
|
|
const config = require('./config');
|
|
const _ = require('lodash');
|
|
|
|
class LimitService {
|
|
constructor() {
|
|
this.limits = {};
|
|
}
|
|
|
|
/**
|
|
* Initializes the limits based on configuration
|
|
*
|
|
* @param {Object} options
|
|
* @param {Object} options.limits - hash containing limit configurations keyed by limit name and containing
|
|
* @param {String} options.helpLink - URL pointing to help resources for when limit is reached
|
|
* @param {Object} options.db - knex db connection instance or other data source for the limit checks
|
|
* @param {Object} options.errors - instance of errors compatible with Ghost-Ignition's errors (https://github.com/TryGhost/Ignition#errors)
|
|
*/
|
|
loadLimits({limits, helpLink, db, errors}) {
|
|
if (!errors) {
|
|
throw new Error(`Config Missing: 'errors' is required. `);
|
|
}
|
|
|
|
this.errors = errors;
|
|
|
|
Object.keys(limits).forEach((name) => {
|
|
name = _.camelCase(name);
|
|
|
|
if (config[name]) {
|
|
/** @type LimitConfig */
|
|
let limitConfig = _.merge({}, limits[name], config[name]);
|
|
|
|
if (_.has(limitConfig, 'max')) {
|
|
this.limits[name] = new MaxLimit({name: name, config: limitConfig, helpLink, db, errors});
|
|
} else {
|
|
this.limits[name] = new FlagLimit({name: name, config: limitConfig, helpLink, errors});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
isLimited(limitName) {
|
|
return !!this.limits[_.camelCase(limitName)];
|
|
}
|
|
|
|
async checkIsOverLimit(limitName) {
|
|
if (!this.isLimited(limitName)) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await this.limits[limitName].errorIfIsOverLimit();
|
|
return false;
|
|
} catch (error) {
|
|
if (error instanceof this.errors.HostLimitError) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
async checkWouldGoOverLimit(limitName) {
|
|
if (!this.isLimited(limitName)) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await this.limits[limitName].errorIfWouldGoOverLimit();
|
|
return false;
|
|
} catch (error) {
|
|
if (error instanceof this.errors.HostLimitError) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
async errorIfIsOverLimit(limitName) {
|
|
if (!this.isLimited(limitName)) {
|
|
return;
|
|
}
|
|
|
|
await this.limits[limitName].errorIfIsOverLimit();
|
|
}
|
|
|
|
async errorIfWouldGoOverLimit(limitName) {
|
|
if (!this.isLimited(limitName)) {
|
|
return;
|
|
}
|
|
|
|
await this.limits[limitName].errorIfWouldGoOverLimit();
|
|
}
|
|
}
|
|
|
|
module.exports = LimitService;
|
|
|
|
/**
|
|
* @typedef {Object} LimitConfig
|
|
* @prop {Number} [max] - max limit
|
|
* @prop {Boolean} [disabled] - flag disabling/enabling limit
|
|
* @prop {String} error - custom error to be displayed when the limit is reached
|
|
*/
|