@tryghost/limit-service 1.3.1 → 1.4.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/README.md +17 -3
- package/lib/LimitService.js +21 -0
- package/lib/limit.js +11 -44
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -68,8 +68,12 @@ const limits = {
|
|
|
68
68
|
error: 'Your plan supports uploads of max size up to {{max}}. Please upgrade to reenable uploading.'
|
|
69
69
|
},
|
|
70
70
|
limitStripeConnect: {},
|
|
71
|
-
limitAnalytics: {
|
|
72
|
-
|
|
71
|
+
limitAnalytics: {
|
|
72
|
+
disabled: false
|
|
73
|
+
},
|
|
74
|
+
limitSocialWeb: {
|
|
75
|
+
disabled: true
|
|
76
|
+
}
|
|
73
77
|
};
|
|
74
78
|
|
|
75
79
|
// This information is needed for the limit service to work with "max periodic" limits
|
|
@@ -134,6 +138,16 @@ if (limitService.isLimited('uploads')) {
|
|
|
134
138
|
await limitService.errorIfIsOverLimit('uploads', {currentCount: frame.file.size});
|
|
135
139
|
}
|
|
136
140
|
|
|
141
|
+
// Limits expose an async `checkWouldGoOverLimit` method, which can be used to check whether a limit has been reached, but not throw an error:
|
|
142
|
+
if (await limitService.checkWouldGoOverLimit('members')) {
|
|
143
|
+
console.log('Members limit has been reached!');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Flag limits additionally expose a `isDisabled` sync check, which can be used instead of the async `checkWouldGoOverLimit`:
|
|
147
|
+
if (limitService.isDisabled('limitSocialWeb')) {
|
|
148
|
+
console.log('Social web is disabled by config!'));
|
|
149
|
+
}
|
|
150
|
+
|
|
137
151
|
// check if any of the limits are acceding
|
|
138
152
|
if (limitService.checkIfAnyOverLimit()) {
|
|
139
153
|
console.log('One of the limits has acceded!');
|
|
@@ -158,7 +172,7 @@ db.transaction((transacting) => {
|
|
|
158
172
|
|
|
159
173
|
### Types of limits
|
|
160
174
|
At the moment there are four different types of limits that limit service allows to define. These types are:
|
|
161
|
-
1. `flag` - is an "on/off" switch for certain feature. Example use case: "disable all emails". It's identified by a `disabled: true` property in the "limits" configuration.
|
|
175
|
+
1. `flag` - is an "on/off" switch for certain feature. Example use case: "disable all emails". It's identified by a `disabled: true` property in the "limits" configuration.
|
|
162
176
|
2. `max` - checks if the maximum amount of the resource has been used up.Example use case: "disable creating a staff user when maximum of 5 has been reached". To configure this limit add `max: NUMBER` to the configuration. The limits that support max checks are: `members`, and `staff`
|
|
163
177
|
3. `maxPeriodic` - it's a variation of `max` type with a difference that the check is done over certain period of time. Example use case: "disable sending emails when the sent emails count has acceded a limit for last billing period". To enable this limit define `maxPeriodic: NUMBER` in the limit configuration and provide a subscription configuration when initializing the limit service instance. The subscription object comes as a separate parameter and has to contain two properties: `startDate` and `interval`, where `startDate` is a date in ISO 8601 format and period is `'month'` (other values like `'year'` are not supported yet)
|
|
164
178
|
4. `allowList` - checks if provided value is defined in configured "allowlist". Example use case: "disable theme activation if it is not an official theme". To configure this limit define ` allowlist: ['VALUE_1', 'VALUE_2', 'VALUE_N']` property in the "limits" parameter.
|
package/lib/LimitService.js
CHANGED
|
@@ -69,6 +69,27 @@ class LimitService {
|
|
|
69
69
|
return !!this.limits[camelCase(limitName)];
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Check if a limit is disabled, applicable only to limits that support the disabled flag (e.g. FlagLimit)
|
|
74
|
+
* @returns {boolean|undefined} undefined if limit is not configured
|
|
75
|
+
* @throws {IncorrectUsageError} if limit does not support disabled flag
|
|
76
|
+
*/
|
|
77
|
+
isDisabled(limitName) {
|
|
78
|
+
if (!this.isLimited(limitName)) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const limit = this.limits[camelCase(limitName)];
|
|
83
|
+
|
|
84
|
+
if (typeof limit.isDisabled !== 'function') {
|
|
85
|
+
throw new IncorrectUsageError({
|
|
86
|
+
message: `Limit ${limitName} does not support .isDisabled()`
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return limit.isDisabled();
|
|
91
|
+
}
|
|
92
|
+
|
|
72
93
|
/**
|
|
73
94
|
*
|
|
74
95
|
* @param {String} limitName - name of the configured limit
|
package/lib/limit.js
CHANGED
|
@@ -264,7 +264,6 @@ class FlagLimit extends Limit {
|
|
|
264
264
|
* @param {Number} options.config.disabled - disabled/enabled flag for the limit
|
|
265
265
|
* @param {String} options.config.error - error message to use when limit is reached
|
|
266
266
|
* @param {String} options.helpLink - URL to the resource explaining how the limit works
|
|
267
|
-
* @param {Function} [options.config.currentCountQuery] - query checking the state that would be compared against the limit
|
|
268
267
|
* @param {Object} [options.db] - instance of knex db connection that currentCountQuery can use to run state check through
|
|
269
268
|
* @param {Object} options.errors - instance of errors compatible with GhostError errors (@tryghost/errors)
|
|
270
269
|
*/
|
|
@@ -274,7 +273,6 @@ class FlagLimit extends Limit {
|
|
|
274
273
|
|
|
275
274
|
this.disabled = config.disabled;
|
|
276
275
|
this.fallbackMessage = `Your plan does not support ${userFacingLimitName}. Please upgrade to enable ${userFacingLimitName}.`;
|
|
277
|
-
this.currentCountQueryFn = config?.currentCountQuery || null;
|
|
278
276
|
}
|
|
279
277
|
|
|
280
278
|
generateError() {
|
|
@@ -290,59 +288,28 @@ class FlagLimit extends Limit {
|
|
|
290
288
|
}
|
|
291
289
|
|
|
292
290
|
/**
|
|
293
|
-
*
|
|
294
|
-
* @param {Object} [options.transacting] Transaction to run the count query on
|
|
295
|
-
* @returns {Promise<boolean>} - returns the current count of items that would be compared against the limit
|
|
291
|
+
* Flag limits are on/off so using a feature is always over the limit
|
|
296
292
|
*/
|
|
297
|
-
async
|
|
298
|
-
if (
|
|
299
|
-
return false;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
return await this.currentCountQueryFn(options.transacting ?? this.db?.knex);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// As Flag limits are on/off, we won't check against max values.
|
|
306
|
-
// `errorIfWouldGoOverLimit` and `errorIfIsOverLimit` end up doing the same thing.
|
|
307
|
-
async _isOrWouldOverLimitError(options = {}) {
|
|
308
|
-
if (!this.disabled) {
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
// If no currentCountQuery is provided, throw error when disabled
|
|
313
|
-
if (!this.currentCountQueryFn || typeof this.currentCountQueryFn !== 'function') {
|
|
314
|
-
throw this.generateError();
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// If currentCountQuery is provided, check if feature is in use
|
|
318
|
-
const featureInUse = await this.currentCountQuery(options);
|
|
319
|
-
|
|
320
|
-
// Only throw error if feature is NOT in use (allowing grandfathering)
|
|
321
|
-
if (!featureInUse) {
|
|
293
|
+
async errorIfWouldGoOverLimit() {
|
|
294
|
+
if (this.disabled) {
|
|
322
295
|
throw this.generateError();
|
|
323
296
|
}
|
|
324
297
|
}
|
|
325
298
|
|
|
326
299
|
/**
|
|
327
|
-
* Flag limits are
|
|
328
|
-
*
|
|
329
|
-
* feature is in use. This is a use case for when we introduce a new limit and
|
|
330
|
-
* customers have already been using this feature. We don't want to take it
|
|
331
|
-
* away from them.
|
|
300
|
+
* Flag limits are on/off. They don't necessarily mean the limit wasn't possible to reach
|
|
301
|
+
* NOTE: this method should not be relied on as it's impossible to check the limit was surpassed!
|
|
332
302
|
*/
|
|
333
|
-
async
|
|
334
|
-
|
|
303
|
+
async errorIfIsOverLimit() {
|
|
304
|
+
return;
|
|
335
305
|
}
|
|
336
306
|
|
|
337
307
|
/**
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
* feature is in use. This is a use case for when we introduce a new limit and
|
|
341
|
-
* customers have already been using this feature. We don't want to take it
|
|
342
|
-
* away from them.
|
|
308
|
+
* Checks whether the Flag limit is disabled or not
|
|
309
|
+
* @returns boolean
|
|
343
310
|
*/
|
|
344
|
-
|
|
345
|
-
|
|
311
|
+
isDisabled() {
|
|
312
|
+
return !!this.disabled;
|
|
346
313
|
}
|
|
347
314
|
}
|
|
348
315
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tryghost/limit-service",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/TryGhost/SDK.git",
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"lodash": "^4.17.21",
|
|
35
35
|
"luxon": "^1.26.0"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "8d4cf3dfddc7c9fd6c499e672be94e64123b23bd"
|
|
38
38
|
}
|