@envelop/rate-limiter 3.4.0-alpha-c0cc559.0 → 3.4.0-alpha-e9434aa.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/{index.mjs → cjs/index.js} +12 -17
- package/cjs/package.json +1 -0
- package/cjs/utils.js +13 -0
- package/{index.js → esm/index.js} +25 -24
- package/esm/utils.js +13 -0
- package/package.json +33 -12
- package/{index.d.ts → typings/index.d.ts} +1 -1
- package/{utils.d.ts → typings/utils.d.ts} +0 -0
- package/README.md +0 -62
|
@@ -1,22 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const astNode = field.astNode;
|
|
9
|
-
const rateLimitDirective = (_a = astNode === null || astNode === void 0 ? void 0 : astNode.directives) === null || _a === void 0 ? void 0 : _a.find(d => d.name.value === name);
|
|
10
|
-
return rateLimitDirective || null;
|
|
11
|
-
}
|
|
12
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useRateLimiter = exports.DIRECTIVE_SDL = exports.UnauthenticatedError = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const utils_js_1 = require("./utils.js");
|
|
6
|
+
const graphql_rate_limit_1 = require("graphql-rate-limit");
|
|
7
|
+
tslib_1.__exportStar(require("./utils.js"), exports);
|
|
13
8
|
class UnauthenticatedError extends Error {
|
|
14
9
|
}
|
|
15
|
-
|
|
10
|
+
exports.UnauthenticatedError = UnauthenticatedError;
|
|
11
|
+
exports.DIRECTIVE_SDL = `
|
|
16
12
|
directive @rateLimit(max: Int, window: String, message: String) on FIELD_DEFINITION
|
|
17
13
|
`;
|
|
18
14
|
const useRateLimiter = (options) => {
|
|
19
|
-
const rateLimiterFn = getGraphQLRateLimiter({ identifyContext: options.identifyFn });
|
|
15
|
+
const rateLimiterFn = (0, graphql_rate_limit_1.getGraphQLRateLimiter)({ identifyContext: options.identifyFn });
|
|
20
16
|
return {
|
|
21
17
|
async onContextBuilding({ extendContext }) {
|
|
22
18
|
extendContext({
|
|
@@ -25,7 +21,7 @@ const useRateLimiter = (options) => {
|
|
|
25
21
|
},
|
|
26
22
|
async onResolverCalled({ args, root, context, info }) {
|
|
27
23
|
var _a, _b, _c;
|
|
28
|
-
const rateLimitDirectiveNode = getDirective(info, options.rateLimitDirectiveName || 'rateLimit');
|
|
24
|
+
const rateLimitDirectiveNode = (0, utils_js_1.getDirective)(info, options.rateLimitDirectiveName || 'rateLimit');
|
|
29
25
|
if (rateLimitDirectiveNode && rateLimitDirectiveNode.arguments) {
|
|
30
26
|
const maxNode = (_a = rateLimitDirectiveNode.arguments.find(arg => arg.name.value === 'max')) === null || _a === void 0 ? void 0 : _a.value;
|
|
31
27
|
const windowNode = (_b = rateLimitDirectiveNode.arguments.find(arg => arg.name.value === 'window')) === null || _b === void 0 ? void 0 : _b.value;
|
|
@@ -59,8 +55,7 @@ const useRateLimiter = (options) => {
|
|
|
59
55
|
},
|
|
60
56
|
};
|
|
61
57
|
};
|
|
58
|
+
exports.useRateLimiter = useRateLimiter;
|
|
62
59
|
function interpolate(message, args) {
|
|
63
60
|
return message.replace(/\{{([^)]*)\}}/g, (_, key) => args[key.trim()]);
|
|
64
61
|
}
|
|
65
|
-
|
|
66
|
-
export { DIRECTIVE_SDL, UnauthenticatedError, getDirective, useRateLimiter };
|
package/cjs/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
package/cjs/utils.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDirective = void 0;
|
|
4
|
+
function getDirective(info, name) {
|
|
5
|
+
var _a;
|
|
6
|
+
const { parentType, fieldName, schema } = info;
|
|
7
|
+
const schemaType = schema.getType(parentType.name);
|
|
8
|
+
const field = schemaType.getFields()[fieldName];
|
|
9
|
+
const astNode = field.astNode;
|
|
10
|
+
const rateLimitDirective = (_a = astNode === null || astNode === void 0 ? void 0 : astNode.directives) === null || _a === void 0 ? void 0 : _a.find(d => d.name.value === name);
|
|
11
|
+
return rateLimitDirective || null;
|
|
12
|
+
}
|
|
13
|
+
exports.getDirective = getDirective;
|
|
@@ -1,26 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.useRateLimiter = exports.DIRECTIVE_SDL = exports.UnauthenticatedError = void 0;
|
|
18
|
+
const utils_js_1 = require("./utils.js");
|
|
19
|
+
const graphql_rate_limit_1 = require("graphql-rate-limit");
|
|
20
|
+
__exportStar(require("./utils.js"), exports);
|
|
17
21
|
class UnauthenticatedError extends Error {
|
|
18
22
|
}
|
|
19
|
-
|
|
23
|
+
exports.UnauthenticatedError = UnauthenticatedError;
|
|
24
|
+
exports.DIRECTIVE_SDL = `
|
|
20
25
|
directive @rateLimit(max: Int, window: String, message: String) on FIELD_DEFINITION
|
|
21
26
|
`;
|
|
22
27
|
const useRateLimiter = (options) => {
|
|
23
|
-
const rateLimiterFn =
|
|
28
|
+
const rateLimiterFn = (0, graphql_rate_limit_1.getGraphQLRateLimiter)({ identifyContext: options.identifyFn });
|
|
24
29
|
return {
|
|
25
30
|
async onContextBuilding({ extendContext }) {
|
|
26
31
|
extendContext({
|
|
@@ -29,7 +34,7 @@ const useRateLimiter = (options) => {
|
|
|
29
34
|
},
|
|
30
35
|
async onResolverCalled({ args, root, context, info }) {
|
|
31
36
|
var _a, _b, _c;
|
|
32
|
-
const rateLimitDirectiveNode = getDirective(info, options.rateLimitDirectiveName || 'rateLimit');
|
|
37
|
+
const rateLimitDirectiveNode = (0, utils_js_1.getDirective)(info, options.rateLimitDirectiveName || 'rateLimit');
|
|
33
38
|
if (rateLimitDirectiveNode && rateLimitDirectiveNode.arguments) {
|
|
34
39
|
const maxNode = (_a = rateLimitDirectiveNode.arguments.find(arg => arg.name.value === 'max')) === null || _a === void 0 ? void 0 : _a.value;
|
|
35
40
|
const windowNode = (_b = rateLimitDirectiveNode.arguments.find(arg => arg.name.value === 'window')) === null || _b === void 0 ? void 0 : _b.value;
|
|
@@ -63,11 +68,7 @@ const useRateLimiter = (options) => {
|
|
|
63
68
|
},
|
|
64
69
|
};
|
|
65
70
|
};
|
|
71
|
+
exports.useRateLimiter = useRateLimiter;
|
|
66
72
|
function interpolate(message, args) {
|
|
67
73
|
return message.replace(/\{{([^)]*)\}}/g, (_, key) => args[key.trim()]);
|
|
68
74
|
}
|
|
69
|
-
|
|
70
|
-
exports.DIRECTIVE_SDL = DIRECTIVE_SDL;
|
|
71
|
-
exports.UnauthenticatedError = UnauthenticatedError;
|
|
72
|
-
exports.getDirective = getDirective;
|
|
73
|
-
exports.useRateLimiter = useRateLimiter;
|
package/esm/utils.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDirective = void 0;
|
|
4
|
+
function getDirective(info, name) {
|
|
5
|
+
var _a;
|
|
6
|
+
const { parentType, fieldName, schema } = info;
|
|
7
|
+
const schemaType = schema.getType(parentType.name);
|
|
8
|
+
const field = schemaType.getFields()[fieldName];
|
|
9
|
+
const astNode = field.astNode;
|
|
10
|
+
const rateLimitDirective = (_a = astNode === null || astNode === void 0 ? void 0 : astNode.directives) === null || _a === void 0 ? void 0 : _a.find(d => d.name.value === name);
|
|
11
|
+
return rateLimitDirective || null;
|
|
12
|
+
}
|
|
13
|
+
exports.getDirective = getDirective;
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@envelop/rate-limiter",
|
|
3
|
-
"version": "3.4.0-alpha-
|
|
3
|
+
"version": "3.4.0-alpha-e9434aa.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
|
-
"@envelop/core": "2.4.0-alpha-
|
|
6
|
+
"@envelop/core": "2.4.0-alpha-e9434aa.0",
|
|
7
7
|
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
@@ -11,26 +11,47 @@
|
|
|
11
11
|
},
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
14
|
-
"url": "https://github.com/
|
|
14
|
+
"url": "https://github.com/n1ru4l/envelop.git",
|
|
15
15
|
"directory": "packages/plugins/rate-limiter"
|
|
16
16
|
},
|
|
17
17
|
"author": "Dotan Simha <dotansimha@gmail.com>",
|
|
18
18
|
"license": "MIT",
|
|
19
|
-
"main": "index.js",
|
|
20
|
-
"module": "index.
|
|
21
|
-
"typings": "index.d.ts",
|
|
19
|
+
"main": "cjs/index.js",
|
|
20
|
+
"module": "esm/index.js",
|
|
21
|
+
"typings": "typings/index.d.ts",
|
|
22
22
|
"typescript": {
|
|
23
|
-
"definition": "index.d.ts"
|
|
23
|
+
"definition": "typings/index.d.ts"
|
|
24
24
|
},
|
|
25
|
+
"type": "module",
|
|
25
26
|
"exports": {
|
|
26
27
|
".": {
|
|
27
|
-
"require":
|
|
28
|
-
|
|
28
|
+
"require": {
|
|
29
|
+
"types": "./typings/index.d.ts",
|
|
30
|
+
"default": "./cjs/index.js"
|
|
31
|
+
},
|
|
32
|
+
"import": {
|
|
33
|
+
"types": "./typings/index.d.ts",
|
|
34
|
+
"default": "./esm/index.js"
|
|
35
|
+
},
|
|
36
|
+
"default": {
|
|
37
|
+
"types": "./typings/index.d.ts",
|
|
38
|
+
"default": "./esm/index.js"
|
|
39
|
+
}
|
|
29
40
|
},
|
|
30
41
|
"./*": {
|
|
31
|
-
"require":
|
|
32
|
-
|
|
42
|
+
"require": {
|
|
43
|
+
"types": "./typings/*.d.ts",
|
|
44
|
+
"default": "./cjs/*.js"
|
|
45
|
+
},
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./typings/*.d.ts",
|
|
48
|
+
"default": "./esm/*.js"
|
|
49
|
+
},
|
|
50
|
+
"default": {
|
|
51
|
+
"types": "./typings/*.d.ts",
|
|
52
|
+
"default": "./esm/*.js"
|
|
53
|
+
}
|
|
33
54
|
},
|
|
34
55
|
"./package.json": "./package.json"
|
|
35
56
|
}
|
|
36
|
-
}
|
|
57
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Plugin } from '@envelop/core';
|
|
2
2
|
import { GraphQLResolveInfo } from 'graphql';
|
|
3
3
|
import { getGraphQLRateLimiter } from 'graphql-rate-limit';
|
|
4
|
-
export * from './utils';
|
|
4
|
+
export * from './utils.js';
|
|
5
5
|
export declare class UnauthenticatedError extends Error {
|
|
6
6
|
}
|
|
7
7
|
export declare type IdentifyFn<ContextType = unknown> = (context: ContextType) => string;
|
|
File without changes
|
package/README.md
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
## `@envelop/rate-limiter`
|
|
2
|
-
|
|
3
|
-
This plugins uses [`graphql-rate-limit`](https://github.com/teamplanes/graphql-rate-limit#readme) in order to limit the rate of calling queries and mutations.
|
|
4
|
-
|
|
5
|
-
## Getting Started
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
yarn add @envelop/rate-limiter
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage Example
|
|
12
|
-
|
|
13
|
-
```ts
|
|
14
|
-
import { envelop } from '@envelop/core';
|
|
15
|
-
import { useRateLimiter, IdentifyFn } from '@envelop/rate-limiter';
|
|
16
|
-
|
|
17
|
-
const identifyFn: IdentifyFn = async context => {
|
|
18
|
-
return context.request.ip;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const getEnveloped = envelop({
|
|
22
|
-
plugins: [
|
|
23
|
-
// ... other plugins ...
|
|
24
|
-
useRateLimiter({
|
|
25
|
-
identifyFn,
|
|
26
|
-
}),
|
|
27
|
-
],
|
|
28
|
-
});
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
> By default, we assume that you have the GraphQL directive definition as part of your GraphQL schema (`directive @rateLimit(max: Int, window: String, message: String) on FIELD_DEFINITION`).
|
|
32
|
-
|
|
33
|
-
Then, in your GraphQL schema SDL, you can add `@rateLimit` directive to your fields, and the limiter will get called only while resolving that specific field:
|
|
34
|
-
|
|
35
|
-
```graphql
|
|
36
|
-
type Query {
|
|
37
|
-
posts: [Post]! @rateLimit(
|
|
38
|
-
window: "5s", // time interval window for request limit quota
|
|
39
|
-
max: 10, // maximum requests allowed in time window
|
|
40
|
-
message: "Too many calls!" // quota reached error message
|
|
41
|
-
)
|
|
42
|
-
# unlimitedField: String
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
> You can apply that directive to any GraphQL `field` definition, not only to root fields.
|
|
47
|
-
|
|
48
|
-
### Error message interpolation
|
|
49
|
-
|
|
50
|
-
The `message` argument of the `@rateLimit` directive can be dynamic. You `{{var}}` or `{{ var }}` syntax to interpolate variables.
|
|
51
|
-
|
|
52
|
-
```graphql
|
|
53
|
-
type Query {
|
|
54
|
-
posts: [Post]! @rateLimit(window: "5s", max: 10, message: "Too many calls made by {{ id }}")
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
> The only available variable so far is `id`.
|
|
59
|
-
|
|
60
|
-
## Notes
|
|
61
|
-
|
|
62
|
-
You can find more details here: hhttps://github.com/teamplanes/graphql-rate-limit#readme
|