feat: guv
This commit is contained in:
parent
f3191d0e63
commit
33b1c94d2b
3
packages/governor/.gitignore
vendored
Normal file
3
packages/governor/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
/*.js
|
||||||
|
/*.js.map
|
||||||
|
!/webpack.config.js
|
39
packages/governor/package.json
Normal file
39
packages/governor/package.json
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"name": "@latus/governor",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"author": "cha0s",
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"build": "NODE_PATH=./node_modules webpack --mode production",
|
||||||
|
"clean": "rm -f yarn.lock && yarn",
|
||||||
|
"dev": "NODE_PATH=./node_modules webpack --mode development",
|
||||||
|
"forcepub": "npm unpublish --force $(node -e 'process.stdout.write(require(`./package.json`).name)') && npm publish",
|
||||||
|
"lint": "NODE_PATH=./node_modules eslint --format codeframe --ext mjs,js .",
|
||||||
|
"test": "NODE_PATH=./node_modules mocha --config ../../config/.mocharc.js",
|
||||||
|
"watch": "NODE_PATH=./node_modules webpack --watch --mode development"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"index.js",
|
||||||
|
"index.js.map"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"@latus/redis": "^1.0.0",
|
||||||
|
"@latus/socket": "^1.0.0",
|
||||||
|
"debug": "4.3.1",
|
||||||
|
"rate-limiter-flexible": "^2.1.13"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@neutrinojs/airbnb-base": "^9.4.0",
|
||||||
|
"@neutrinojs/copy": "9.4.0",
|
||||||
|
"@neutrinojs/library": "^9.4.0",
|
||||||
|
"@neutrinojs/mocha": "^9.4.0",
|
||||||
|
"chai": "4.2.0",
|
||||||
|
"eslint": "^7",
|
||||||
|
"eslint-import-resolver-webpack": "0.13.0",
|
||||||
|
"mocha": "^8",
|
||||||
|
"neutrino": "^9.4.0",
|
||||||
|
"webpack": "^4",
|
||||||
|
"webpack-cli": "^3"
|
||||||
|
}
|
||||||
|
}
|
14
packages/governor/src/index.js
Normal file
14
packages/governor/src/index.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import LimitedPacket from './limited-packet';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
hooks: {
|
||||||
|
'@latus/socket/packets.decorate': (Packets, latus) => (
|
||||||
|
Object.fromEntries(
|
||||||
|
Object.entries(Packets).map(([keyPrefix, Packet]) => [
|
||||||
|
keyPrefix,
|
||||||
|
!Packet.limit ? Packet : LimitedPacket(latus, [keyPrefix, Packet]),
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
30
packages/governor/src/limited-packet.js
Normal file
30
packages/governor/src/limited-packet.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import {ValidationError} from '@latus/socket';
|
||||||
|
|
||||||
|
import createLimiter from './limiter';
|
||||||
|
|
||||||
|
export default (latus, [keyPrefix, Packet]) => class LimitedPacket extends Packet {
|
||||||
|
|
||||||
|
constructor(...args) {
|
||||||
|
super(...args);
|
||||||
|
this.limit = createLimiter(latus, {keyPrefix, ...Packet.limit});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async validate(packet, socket) {
|
||||||
|
try {
|
||||||
|
await packet.limit.consume(socket.id);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error.msBeforeNext) {
|
||||||
|
throw new ValidationError({
|
||||||
|
code: 429,
|
||||||
|
ttr: Math.round(error.msBeforeNext / 1000) || 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
if (super.validate) {
|
||||||
|
super.validate(packet, socket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
7
packages/governor/src/limiter.js
Normal file
7
packages/governor/src/limiter.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import {createClient} from '@latus/redis';
|
||||||
|
import {RateLimiterRedis} from 'rate-limiter-flexible';
|
||||||
|
|
||||||
|
export default (latus, options) => new RateLimiterRedis({
|
||||||
|
...options,
|
||||||
|
storeClient: createClient(latus),
|
||||||
|
});
|
8
packages/governor/webpack.config.js
Normal file
8
packages/governor/webpack.config.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// Whilst the configuration object can be modified here, the recommended way of making
|
||||||
|
// changes is via the presets' options or Neutrino's API in `.neutrinorc.js` instead.
|
||||||
|
// Neutrino's inspect feature can be used to view/export the generated configuration.
|
||||||
|
const neutrino = require('neutrino');
|
||||||
|
|
||||||
|
const configOfConfigs = require(`${__dirname}/.neutrinorc`);
|
||||||
|
const configs = Array.isArray(configOfConfigs) ? configOfConfigs : [configOfConfigs];
|
||||||
|
module.exports = configs.map((config) => neutrino(config).webpack());
|
6797
packages/governor/yarn.lock
Normal file
6797
packages/governor/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user