graphql-safe-guards 1.0.1 → 1.0.2
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 +61 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -3
- package/dist/presets.d.ts +14 -0
- package/dist/presets.js +17 -0
- package/dist/types.d.ts +3 -0
- package/package.json +1 -1
- package/test/graphqlSafeGuards.test.ts +21 -8
package/README.md
CHANGED
|
@@ -2,29 +2,83 @@
|
|
|
2
2
|
|
|
3
3
|
Protect your GraphQL API with a single import.
|
|
4
4
|
|
|
5
|
+
A tiny utility that **combines depth limiting and query complexity validation**
|
|
6
|
+
using native GraphQL validation rules.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
5
10
|
## Installation
|
|
6
11
|
|
|
12
|
+
```bash
|
|
7
13
|
npm install graphql-safe-guards
|
|
14
|
+
```
|
|
8
15
|
|
|
9
|
-
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Usage (Apollo Server)
|
|
10
19
|
|
|
11
20
|
```ts
|
|
12
|
-
import {
|
|
21
|
+
import { ApolloServer } from "@apollo/server";
|
|
22
|
+
import { createSafeGuards } from "graphql-safe-guards";
|
|
13
23
|
|
|
14
24
|
const server = new ApolloServer({
|
|
15
25
|
schema,
|
|
16
|
-
validationRules:
|
|
26
|
+
validationRules: createSafeGuards({
|
|
17
27
|
depth: 3,
|
|
18
28
|
complexity: 10,
|
|
19
29
|
}),
|
|
20
30
|
});
|
|
21
31
|
```
|
|
22
32
|
|
|
23
|
-
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
createSafeGuards({
|
|
39
|
+
depth?: number; // default: 5
|
|
40
|
+
complexity?: number; // default: 100
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## What It Does
|
|
24
47
|
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
48
|
+
- Limits query depth
|
|
49
|
+
- Limits query complexity
|
|
50
|
+
- Uses native GraphQL validation
|
|
51
|
+
- No schema directives
|
|
52
|
+
- No runtime execution cost
|
|
28
53
|
- Framework agnostic
|
|
29
54
|
|
|
55
|
+
Internally, this package composes:
|
|
56
|
+
|
|
57
|
+
- `graphql-safe-depth`
|
|
58
|
+
- `graphql-complexity-validation`
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Supported Frameworks
|
|
63
|
+
|
|
64
|
+
- Apollo Server
|
|
65
|
+
- GraphQL Yoga
|
|
66
|
+
- Envelop
|
|
67
|
+
- NestJS GraphQL
|
|
68
|
+
- Plain `graphql-js`
|
|
69
|
+
|
|
30
70
|
---
|
|
71
|
+
|
|
72
|
+
## Why this exists
|
|
73
|
+
|
|
74
|
+
Depth limiting and complexity analysis solve **different problems**.
|
|
75
|
+
Most GraphQL servers need **both**, but wiring them together is repetitive.
|
|
76
|
+
|
|
77
|
+
`graphql-safe-guards` provides a **single, predictable entry point**
|
|
78
|
+
for GraphQL query safety.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
MIT © Mateo Diaz
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ValidationRule } from "graphql";
|
|
2
2
|
import { GraphQLSafeGuardsOptions } from "./types";
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function createSafeGuards(options?: GraphQLSafeGuardsOptions): ValidationRule[];
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.createSafeGuards = createSafeGuards;
|
|
4
4
|
const graphql_safe_depth_1 = require("graphql-safe-depth");
|
|
5
5
|
const graphql_complexity_validation_1 = require("graphql-complexity-validation");
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
const presets_1 = require("./presets");
|
|
7
|
+
function createSafeGuards(options = {}) {
|
|
8
|
+
var _a, _b, _c, _d;
|
|
9
|
+
const presetConfig = options.preset
|
|
10
|
+
? presets_1.SAFE_GUARD_PRESETS[options.preset]
|
|
11
|
+
: undefined;
|
|
12
|
+
const depth = (_b = (_a = options.depth) !== null && _a !== void 0 ? _a : presetConfig === null || presetConfig === void 0 ? void 0 : presetConfig.depth) !== null && _b !== void 0 ? _b : 5;
|
|
13
|
+
const complexity = (_d = (_c = options.complexity) !== null && _c !== void 0 ? _c : presetConfig === null || presetConfig === void 0 ? void 0 : presetConfig.complexity) !== null && _d !== void 0 ? _d : 100;
|
|
8
14
|
return [
|
|
9
15
|
(0, graphql_safe_depth_1.createDepthLimitRule)({ maxDepth: depth }),
|
|
10
16
|
(0, graphql_complexity_validation_1.createComplexityLimitRule)({ maxComplexity: complexity }),
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const SAFE_GUARD_PRESETS: {
|
|
2
|
+
readonly strict: {
|
|
3
|
+
readonly depth: 3;
|
|
4
|
+
readonly complexity: 50;
|
|
5
|
+
};
|
|
6
|
+
readonly balanced: {
|
|
7
|
+
readonly depth: 5;
|
|
8
|
+
readonly complexity: 100;
|
|
9
|
+
};
|
|
10
|
+
readonly relaxed: {
|
|
11
|
+
readonly depth: 8;
|
|
12
|
+
readonly complexity: 200;
|
|
13
|
+
};
|
|
14
|
+
};
|
package/dist/presets.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SAFE_GUARD_PRESETS = void 0;
|
|
4
|
+
exports.SAFE_GUARD_PRESETS = {
|
|
5
|
+
strict: {
|
|
6
|
+
depth: 3,
|
|
7
|
+
complexity: 50,
|
|
8
|
+
},
|
|
9
|
+
balanced: {
|
|
10
|
+
depth: 5,
|
|
11
|
+
complexity: 100,
|
|
12
|
+
},
|
|
13
|
+
relaxed: {
|
|
14
|
+
depth: 8,
|
|
15
|
+
complexity: 200,
|
|
16
|
+
},
|
|
17
|
+
};
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
import {
|
|
2
|
+
import { createSafeGuards } from "../src";
|
|
3
3
|
|
|
4
|
-
describe("
|
|
5
|
-
it("
|
|
6
|
-
const rules =
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
describe("createSafeGuards", () => {
|
|
5
|
+
it("uses strict preset", () => {
|
|
6
|
+
const rules = createSafeGuards({ preset: "strict" });
|
|
7
|
+
|
|
8
|
+
expect(rules).toHaveLength(2);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("allows overriding preset values", () => {
|
|
12
|
+
const rules = createSafeGuards({
|
|
13
|
+
preset: "strict",
|
|
14
|
+
depth: 10,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
expect(rules).toHaveLength(2);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("works without preset (backward compatible)", () => {
|
|
21
|
+
const rules = createSafeGuards({
|
|
22
|
+
depth: 4,
|
|
23
|
+
complexity: 20,
|
|
9
24
|
});
|
|
10
25
|
|
|
11
26
|
expect(rules).toHaveLength(2);
|
|
12
|
-
expect(typeof rules[0]).toBe("function");
|
|
13
|
-
expect(typeof rules[1]).toBe("function");
|
|
14
27
|
});
|
|
15
28
|
});
|