graphql-safe-guards 1.1.1 → 1.1.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/CHANGELOG.md CHANGED
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ---
9
9
 
10
+ ## [Unreleased]
11
+
12
+ ## [1.1.2] – 2026-01-22
13
+
10
14
  ## [1.1.0] – 2026-01-22
11
15
 
12
16
  ### Added
@@ -19,12 +23,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
19
23
 
20
24
  ### Changed
21
25
 
22
- - Improved README clarity around introspection and validation behavior.
26
+ - `ignoreIntrospection` option to exclude GraphQL introspection queries
27
+ from depth and complexity validation.
23
28
 
24
29
  ### Fixed
25
30
 
26
- - Prevented GraphQL introspection queries from being blocked by strict
27
- depth or complexity limits when `ignoreIntrospection` is enabled.
31
+ - Ensured GraphQL introspection queries are excluded from depth and
32
+ complexity validation when `ignoreIntrospection` is enabled.
28
33
 
29
34
  ---
30
35
 
package/README.md CHANGED
@@ -42,8 +42,8 @@ const server = new ApolloServer({
42
42
 
43
43
  ```ts
44
44
  createSafeGuards({
45
- depth?: number; // default: 5
46
- complexity?: number; // default: 100
45
+ depth?: number; // default: 3 (strict preset)
46
+ complexity?: number; // default: 50 (strict preset)
47
47
 
48
48
  /**
49
49
  * If true, GraphQL introspection queries are ignored
@@ -74,6 +74,22 @@ const server = new ApolloServer({
74
74
  });
75
75
  ```
76
76
 
77
+ ## Presets (Recommended)
78
+
79
+ graphql-safe-guards includes opinionated, production-ready presets for common use cases.
80
+
81
+ ```ts
82
+ createSafeGuards({ preset: "strict" });
83
+ createSafeGuards({ preset: "balanced" });
84
+ createSafeGuards({ preset: "relaxed" });
85
+ ```
86
+
87
+ | Preset | Depth | Complexity | Use case |
88
+ | -------- | ----- | ---------- | --------------------------- |
89
+ | strict | 3 | 50 | Public APIs, read-only APIs |
90
+ | balanced | 4 | 100 | Private frontends |
91
+ | relaxed | 6 | 200 | Admin / internal tools |
92
+
77
93
  ---
78
94
 
79
95
  ## What It Does
@@ -112,6 +128,14 @@ Most GraphQL servers need **both**, but wiring them together is repetitive.
112
128
  `graphql-safe-guards` provides a **single, predictable entry point**
113
129
  for GraphQL query safety.
114
130
 
131
+ ### Environment-based setup
132
+
133
+ ```ts
134
+ createSafeGuards({
135
+ preset: process.env.NODE_ENV === "production" ? "strict" : "balanced",
136
+ });
137
+ ```
138
+
115
139
  ---
116
140
 
117
141
  ## 🗺️ Roadmap
@@ -122,7 +146,7 @@ for GraphQL query safety.
122
146
  - ✅ Presets support (`strict`, `balanced`, `relaxed`)
123
147
  - ✅ Backward-compatible API
124
148
  - ✅ Integration tests with `graphql-js`
125
- - 🔜 Preset for private APIs (privateApi)
149
+ - 🔜 Additional presets based on community feedback
126
150
 
127
151
  > Roadmap items may change based on feedback and real-world usage.
128
152
 
package/dist/index.js CHANGED
@@ -6,24 +6,19 @@ const graphql_complexity_validation_1 = require("graphql-complexity-validation")
6
6
  const presets_1 = require("./presets");
7
7
  const wrapIgnoreIntrospection_1 = require("./utils/wrapIgnoreIntrospection");
8
8
  function createSafeGuards(options = {}) {
9
- var _a, _b, _c, _d, _e;
9
+ var _a, _b, _c;
10
10
  const presetConfig = options.preset
11
11
  ? presets_1.SAFE_GUARD_PRESETS[options.preset]
12
- : undefined;
13
- 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;
14
- 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;
15
- const ignoreIntrospection = (_e = options.ignoreIntrospection) !== null && _e !== void 0 ? _e : false;
16
- const rules = [
12
+ : presets_1.SAFE_GUARD_PRESETS.strict;
13
+ const depth = (_a = options.depth) !== null && _a !== void 0 ? _a : presetConfig.depth;
14
+ const complexity = (_b = options.complexity) !== null && _b !== void 0 ? _b : presetConfig.complexity;
15
+ const ignoreIntrospection = (_c = options.ignoreIntrospection) !== null && _c !== void 0 ? _c : presetConfig.ignoreIntrospection;
16
+ let rules = [
17
17
  (0, graphql_safe_depth_1.createDepthLimitRule)({ maxDepth: depth }),
18
18
  (0, graphql_complexity_validation_1.createComplexityLimitRule)({ maxComplexity: complexity }),
19
19
  ];
20
- if (!ignoreIntrospection) {
21
- return rules;
20
+ if (ignoreIntrospection) {
21
+ rules = rules.map((rule) => (0, wrapIgnoreIntrospection_1.wrapIgnoreIntrospection)(rule));
22
22
  }
23
- return rules.map((rule) => (0, wrapIgnoreIntrospection_1.wrapIgnoreIntrospection)(rule));
24
- // el original
25
- // return [
26
- // createDepthLimitRule({ maxDepth: depth }),
27
- // createComplexityLimitRule({ maxComplexity: complexity }),
28
- // ];
23
+ return rules;
29
24
  }
package/dist/presets.d.ts CHANGED
@@ -2,13 +2,16 @@ export declare const SAFE_GUARD_PRESETS: {
2
2
  readonly strict: {
3
3
  readonly depth: 3;
4
4
  readonly complexity: 50;
5
+ readonly ignoreIntrospection: false;
5
6
  };
6
7
  readonly balanced: {
7
8
  readonly depth: 5;
8
9
  readonly complexity: 100;
10
+ readonly ignoreIntrospection: true;
9
11
  };
10
12
  readonly relaxed: {
11
13
  readonly depth: 8;
12
14
  readonly complexity: 200;
15
+ readonly ignoreIntrospection: true;
13
16
  };
14
17
  };
package/dist/presets.js CHANGED
@@ -5,13 +5,16 @@ exports.SAFE_GUARD_PRESETS = {
5
5
  strict: {
6
6
  depth: 3,
7
7
  complexity: 50,
8
+ ignoreIntrospection: false,
8
9
  },
9
10
  balanced: {
10
11
  depth: 5,
11
12
  complexity: 100,
13
+ ignoreIntrospection: true,
12
14
  },
13
15
  relaxed: {
14
16
  depth: 8,
15
17
  complexity: 200,
18
+ ignoreIntrospection: true,
16
19
  },
17
20
  };
@@ -1,20 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.wrapIgnoreIntrospection = wrapIgnoreIntrospection;
4
+ const INTROSPECTION_FIELDS = new Set(["__schema", "__type"]);
4
5
  function wrapIgnoreIntrospection(rule) {
5
6
  return (context) => {
6
7
  const visitor = rule(context);
7
8
  return {
8
9
  Field(node) {
9
- // Detecta introspection (__schema, __type)
10
- if (node.name.value.startsWith("__")) {
11
- return false;
10
+ // Ignora introspection sin romper traversal
11
+ if (INTROSPECTION_FIELDS.has(node.name.value)) {
12
+ return null;
12
13
  }
13
- // Delegamos al visitor original si existe
14
+ // Delegate safely if Field visitor exists
14
15
  const fieldVisitor = visitor === null || visitor === void 0 ? void 0 : visitor.Field;
15
16
  if (typeof fieldVisitor === "function") {
16
17
  return fieldVisitor(node);
17
18
  }
19
+ return undefined;
18
20
  },
19
21
  };
20
22
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphql-safe-guards",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Opinionated GraphQL security guards (depth + complexity) in one import",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",