graphql-shield-node23 7.6.5
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 +31 -0
- package/dist/cjs/constructors.js +134 -0
- package/dist/cjs/generator.js +205 -0
- package/dist/cjs/index.js +15 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/rules.js +402 -0
- package/dist/cjs/shield.js +52 -0
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/utils.js +97 -0
- package/dist/cjs/validation.js +84 -0
- package/dist/esm/constructors.js +124 -0
- package/dist/esm/generator.js +201 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/rules.js +366 -0
- package/dist/esm/shield.js +45 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/utils.js +88 -0
- package/dist/esm/validation.js +79 -0
- package/dist/package.json +47 -0
- package/dist/typings/constructors.d.cts +91 -0
- package/dist/typings/constructors.d.ts +91 -0
- package/dist/typings/generator.d.cts +11 -0
- package/dist/typings/generator.d.ts +11 -0
- package/dist/typings/index.d.cts +3 -0
- package/dist/typings/index.d.ts +3 -0
- package/dist/typings/rules.d.cts +159 -0
- package/dist/typings/rules.d.ts +159 -0
- package/dist/typings/shield.d.cts +11 -0
- package/dist/typings/shield.d.ts +11 -0
- package/dist/typings/types.d.cts +64 -0
- package/dist/typings/types.d.ts +64 -0
- package/dist/typings/utils.d.cts +52 -0
- package/dist/typings/utils.d.ts +52 -0
- package/dist/typings/validation.d.cts +19 -0
- package/dist/typings/validation.d.ts +19 -0
- package/package.json +67 -0
- package/src/constructors.ts +157 -0
- package/src/generator.ts +294 -0
- package/src/index.ts +13 -0
- package/src/rules.ts +521 -0
- package/src/shield.ts +53 -0
- package/src/types.ts +94 -0
- package/src/utils.ts +101 -0
- package/src/validation.ts +90 -0
- package/tests/__snapshots__/input.test.ts.snap +7 -0
- package/tests/cache.test.ts +545 -0
- package/tests/constructors.test.ts +136 -0
- package/tests/fallback.test.ts +618 -0
- package/tests/fragments.test.ts +113 -0
- package/tests/generator.test.ts +356 -0
- package/tests/input.test.ts +63 -0
- package/tests/integration.test.ts +65 -0
- package/tests/logic.test.ts +530 -0
- package/tests/utils.test.ts +55 -0
- package/tests/validation.test.ts +139 -0
- package/tsconfig.json +10 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# graphql-shield
|
|
2
|
+
|
|
3
|
+
## 7.6.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1493](https://github.com/dimatill/graphql-shield/pull/1493) [`00d3c47`](https://github.com/dimatill/graphql-shield/commit/00d3c4764900e8835ae7c586ebe6a2e7f25fd688) Thanks [@dimatill](https://github.com/dimatill)! - ESM build fix
|
|
8
|
+
|
|
9
|
+
## 7.6.4
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#1470](https://github.com/dimatill/graphql-shield/pull/1470) [`ddf293e`](https://github.com/dimatill/graphql-shield/commit/ddf293e2554e31bf0de8eee00d07bdf58e4f8a8b) Thanks [@mhassan1](https://github.com/mhassan1)! - fix(deps): add missing `tslib` dependency
|
|
14
|
+
|
|
15
|
+
## 7.6.3
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [#1461](https://github.com/dimatill/graphql-shield/pull/1461) [`9b35bb7`](https://github.com/dimatill/graphql-shield/commit/9b35bb7184f8da7111c8524f01a33411e4693b79) Thanks [@dimatill](https://github.com/dimatill)! - fix wildcard rules are not reusable
|
|
20
|
+
|
|
21
|
+
## 7.6.1
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- 0da0a61: fix corrupted release
|
|
26
|
+
|
|
27
|
+
## 7.6.0
|
|
28
|
+
|
|
29
|
+
### Minor Changes
|
|
30
|
+
|
|
31
|
+
- 32b91fe: Bump Package Dependencies
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deny = exports.allow = exports.not = exports.or = exports.race = exports.chain = exports.and = exports.inputRule = exports.rule = void 0;
|
|
4
|
+
const rules_js_1 = require("./rules.js");
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param name
|
|
8
|
+
* @param options
|
|
9
|
+
*
|
|
10
|
+
* Wraps a function into a Rule class. This way we can identify rules
|
|
11
|
+
* once we start generating middleware from our ruleTree.
|
|
12
|
+
*
|
|
13
|
+
* 1.
|
|
14
|
+
* const auth = rule()(async (parent, args, ctx, info) => {
|
|
15
|
+
* return true
|
|
16
|
+
* })
|
|
17
|
+
*
|
|
18
|
+
* 2.
|
|
19
|
+
* const auth = rule('name')(async (parent, args, ctx, info) => {
|
|
20
|
+
* return true
|
|
21
|
+
* })
|
|
22
|
+
*
|
|
23
|
+
* 3.
|
|
24
|
+
* const auth = rule({
|
|
25
|
+
* name: 'name',
|
|
26
|
+
* fragment: 'string',
|
|
27
|
+
* cache: 'cache',
|
|
28
|
+
* })(async (parent, args, ctx, info) => {
|
|
29
|
+
* return true
|
|
30
|
+
* })
|
|
31
|
+
*
|
|
32
|
+
*/
|
|
33
|
+
const rule = (name, options) => (func) => {
|
|
34
|
+
if (typeof name === 'object') {
|
|
35
|
+
options = name;
|
|
36
|
+
name = Math.random().toString();
|
|
37
|
+
}
|
|
38
|
+
else if (typeof name === 'string') {
|
|
39
|
+
options = options || {};
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
name = Math.random().toString();
|
|
43
|
+
options = {};
|
|
44
|
+
}
|
|
45
|
+
return new rules_js_1.Rule(name, func, {
|
|
46
|
+
fragment: options.fragment,
|
|
47
|
+
cache: options.cache,
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
exports.rule = rule;
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
* Constructs a new InputRule based on the schema.
|
|
54
|
+
*
|
|
55
|
+
* @param schema
|
|
56
|
+
*/
|
|
57
|
+
const inputRule = (name) => (schema, options) => {
|
|
58
|
+
if (typeof name === 'string') {
|
|
59
|
+
return new rules_js_1.InputRule(name, schema, options);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
return new rules_js_1.InputRule(Math.random().toString(), schema, options);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
exports.inputRule = inputRule;
|
|
66
|
+
/**
|
|
67
|
+
*
|
|
68
|
+
* @param rules
|
|
69
|
+
*
|
|
70
|
+
* Logical operator and serves as a wrapper for and operation.
|
|
71
|
+
*
|
|
72
|
+
*/
|
|
73
|
+
const and = (...rules) => {
|
|
74
|
+
return new rules_js_1.RuleAnd(rules);
|
|
75
|
+
};
|
|
76
|
+
exports.and = and;
|
|
77
|
+
/**
|
|
78
|
+
*
|
|
79
|
+
* @param rules
|
|
80
|
+
*
|
|
81
|
+
* Logical operator and serves as a wrapper for and operation.
|
|
82
|
+
*
|
|
83
|
+
*/
|
|
84
|
+
const chain = (...rules) => {
|
|
85
|
+
return new rules_js_1.RuleChain(rules);
|
|
86
|
+
};
|
|
87
|
+
exports.chain = chain;
|
|
88
|
+
/**
|
|
89
|
+
*
|
|
90
|
+
* @param rules
|
|
91
|
+
*
|
|
92
|
+
* Logical operator and serves as a wrapper for and operation.
|
|
93
|
+
*
|
|
94
|
+
*/
|
|
95
|
+
const race = (...rules) => {
|
|
96
|
+
return new rules_js_1.RuleRace(rules);
|
|
97
|
+
};
|
|
98
|
+
exports.race = race;
|
|
99
|
+
/**
|
|
100
|
+
*
|
|
101
|
+
* @param rules
|
|
102
|
+
*
|
|
103
|
+
* Logical operator or serves as a wrapper for or operation.
|
|
104
|
+
*
|
|
105
|
+
*/
|
|
106
|
+
const or = (...rules) => {
|
|
107
|
+
return new rules_js_1.RuleOr(rules);
|
|
108
|
+
};
|
|
109
|
+
exports.or = or;
|
|
110
|
+
/**
|
|
111
|
+
*
|
|
112
|
+
* @param rule
|
|
113
|
+
*
|
|
114
|
+
* Logical operator not serves as a wrapper for not operation.
|
|
115
|
+
*
|
|
116
|
+
*/
|
|
117
|
+
const not = (rule, error) => {
|
|
118
|
+
if (typeof error === 'string')
|
|
119
|
+
return new rules_js_1.RuleNot(rule, new Error(error));
|
|
120
|
+
return new rules_js_1.RuleNot(rule, error);
|
|
121
|
+
};
|
|
122
|
+
exports.not = not;
|
|
123
|
+
/**
|
|
124
|
+
*
|
|
125
|
+
* Allow queries.
|
|
126
|
+
*
|
|
127
|
+
*/
|
|
128
|
+
exports.allow = new rules_js_1.RuleTrue();
|
|
129
|
+
/**
|
|
130
|
+
*
|
|
131
|
+
* Deny queries.
|
|
132
|
+
*
|
|
133
|
+
*/
|
|
134
|
+
exports.deny = new rules_js_1.RuleFalse();
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateMiddlewareGeneratorFromRuleTree = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const utils_js_1 = require("./utils.js");
|
|
6
|
+
const validation_js_1 = require("./validation.js");
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param options
|
|
10
|
+
*
|
|
11
|
+
* Generates a middleware function from a given rule and
|
|
12
|
+
* initializes the cache object in context.
|
|
13
|
+
*
|
|
14
|
+
*/
|
|
15
|
+
function generateFieldMiddlewareFromRule(rule, options) {
|
|
16
|
+
async function middleware(resolve, parent, args, ctx, info) {
|
|
17
|
+
// Cache
|
|
18
|
+
if (!ctx) {
|
|
19
|
+
ctx = {};
|
|
20
|
+
}
|
|
21
|
+
if (!ctx._shield) {
|
|
22
|
+
ctx._shield = {
|
|
23
|
+
cache: {},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
// Execution
|
|
27
|
+
try {
|
|
28
|
+
const res = await rule.resolve(parent, args, ctx, info, options);
|
|
29
|
+
if (res === true) {
|
|
30
|
+
return await resolve(parent, args, ctx, info);
|
|
31
|
+
}
|
|
32
|
+
else if (res === false) {
|
|
33
|
+
if (typeof options.fallbackError === 'function') {
|
|
34
|
+
return await options.fallbackError(null, parent, args, ctx, info);
|
|
35
|
+
}
|
|
36
|
+
return options.fallbackError;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
return res;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (options.debug) {
|
|
44
|
+
throw err;
|
|
45
|
+
}
|
|
46
|
+
else if (options.allowExternalErrors) {
|
|
47
|
+
return err;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
if (typeof options.fallbackError === 'function') {
|
|
51
|
+
return await options.fallbackError(err, parent, args, ctx, info);
|
|
52
|
+
}
|
|
53
|
+
return options.fallbackError;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if ((0, utils_js_1.isRule)(rule) && rule.extractFragment()) {
|
|
58
|
+
return {
|
|
59
|
+
fragment: rule.extractFragment(),
|
|
60
|
+
resolve: middleware,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if ((0, utils_js_1.isLogicRule)(rule)) {
|
|
64
|
+
return {
|
|
65
|
+
fragments: rule.extractFragments(),
|
|
66
|
+
resolve: middleware,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return middleware;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
* @param type
|
|
74
|
+
* @param rules
|
|
75
|
+
* @param options
|
|
76
|
+
*
|
|
77
|
+
* Generates middleware from rule for a particular type.
|
|
78
|
+
*
|
|
79
|
+
*/
|
|
80
|
+
function applyRuleToType(type, rules, options) {
|
|
81
|
+
if ((0, utils_js_1.isRuleFunction)(rules)) {
|
|
82
|
+
/* Apply defined rule function to every field */
|
|
83
|
+
const fieldMap = type.getFields();
|
|
84
|
+
const middleware = Object.keys(fieldMap).reduce((middleware, field) => {
|
|
85
|
+
return {
|
|
86
|
+
...middleware,
|
|
87
|
+
[field]: generateFieldMiddlewareFromRule(rules, options),
|
|
88
|
+
};
|
|
89
|
+
}, {});
|
|
90
|
+
return middleware;
|
|
91
|
+
}
|
|
92
|
+
else if ((0, utils_js_1.isRuleFieldMap)(rules)) {
|
|
93
|
+
/* Apply rules assigned to each field to each field */
|
|
94
|
+
const fieldMap = type.getFields();
|
|
95
|
+
/* Extract default type wildcard if any and remove it for validation */
|
|
96
|
+
const defaultTypeRule = rules['*'];
|
|
97
|
+
const { '*': _, ...rulesWithoutWildcard } = rules;
|
|
98
|
+
/* Validation */
|
|
99
|
+
const fieldErrors = Object.keys(rulesWithoutWildcard)
|
|
100
|
+
.filter((type) => !Object.prototype.hasOwnProperty.call(fieldMap, type))
|
|
101
|
+
.map((field) => `${type.name}.${field}`)
|
|
102
|
+
.join(', ');
|
|
103
|
+
if (fieldErrors.length > 0) {
|
|
104
|
+
throw new validation_js_1.ValidationError(`It seems like you have applied rules to ${fieldErrors} fields but Shield cannot find them in your schema.`);
|
|
105
|
+
}
|
|
106
|
+
/* Generation */
|
|
107
|
+
const middleware = Object.keys(fieldMap).reduce((middleware, field) => ({
|
|
108
|
+
...middleware,
|
|
109
|
+
[field]: generateFieldMiddlewareFromRule((0, utils_js_1.withDefault)(defaultTypeRule || options.fallbackRule)(rules[field]), options),
|
|
110
|
+
}), {});
|
|
111
|
+
return middleware;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
/* Apply fallbackRule to type with no defined rule */
|
|
115
|
+
const fieldMap = type.getFields();
|
|
116
|
+
const middleware = Object.keys(fieldMap).reduce((middleware, field) => ({
|
|
117
|
+
...middleware,
|
|
118
|
+
[field]: generateFieldMiddlewareFromRule(options.fallbackRule, options),
|
|
119
|
+
}), {});
|
|
120
|
+
return middleware;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
*
|
|
125
|
+
* @param schema
|
|
126
|
+
* @param rule
|
|
127
|
+
* @param options
|
|
128
|
+
*
|
|
129
|
+
* Applies the same rule over entire schema.
|
|
130
|
+
*
|
|
131
|
+
*/
|
|
132
|
+
function applyRuleToSchema(schema, rule, options) {
|
|
133
|
+
const typeMap = schema.getTypeMap();
|
|
134
|
+
const middleware = Object.keys(typeMap)
|
|
135
|
+
.filter((type) => !(0, graphql_1.isIntrospectionType)(typeMap[type]))
|
|
136
|
+
.reduce((middleware, typeName) => {
|
|
137
|
+
const type = typeMap[typeName];
|
|
138
|
+
if ((0, graphql_1.isObjectType)(type)) {
|
|
139
|
+
return {
|
|
140
|
+
...middleware,
|
|
141
|
+
[typeName]: applyRuleToType(type, rule, options),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
return middleware;
|
|
146
|
+
}
|
|
147
|
+
}, {});
|
|
148
|
+
return middleware;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
*
|
|
152
|
+
* @param rules
|
|
153
|
+
* @param wrapper
|
|
154
|
+
*
|
|
155
|
+
* Converts rule tree to middleware.
|
|
156
|
+
*
|
|
157
|
+
*/
|
|
158
|
+
function generateMiddlewareFromSchemaAndRuleTree(schema, rules, options) {
|
|
159
|
+
if ((0, utils_js_1.isRuleFunction)(rules)) {
|
|
160
|
+
/* Applies rule to entire schema. */
|
|
161
|
+
return applyRuleToSchema(schema, rules, options);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
/**
|
|
165
|
+
* Checks type map and field map and applies rules
|
|
166
|
+
* to particular fields.
|
|
167
|
+
*/
|
|
168
|
+
const typeMap = schema.getTypeMap();
|
|
169
|
+
/* Validation */
|
|
170
|
+
const typeErrors = Object.keys(rules)
|
|
171
|
+
.filter((type) => !Object.prototype.hasOwnProperty.call(typeMap, type))
|
|
172
|
+
.join(', ');
|
|
173
|
+
if (typeErrors.length > 0) {
|
|
174
|
+
throw new validation_js_1.ValidationError(`It seems like you have applied rules to ${typeErrors} types but Shield cannot find them in your schema.`);
|
|
175
|
+
}
|
|
176
|
+
// Generation
|
|
177
|
+
const middleware = Object.keys(typeMap)
|
|
178
|
+
.filter((type) => !(0, graphql_1.isIntrospectionType)(typeMap[type]))
|
|
179
|
+
.reduce((middleware, typeName) => {
|
|
180
|
+
const type = typeMap[typeName];
|
|
181
|
+
if ((0, graphql_1.isObjectType)(type)) {
|
|
182
|
+
return {
|
|
183
|
+
...middleware,
|
|
184
|
+
[typeName]: applyRuleToType(type, rules[typeName], options),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
return middleware;
|
|
189
|
+
}
|
|
190
|
+
}, {});
|
|
191
|
+
return middleware;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
*
|
|
196
|
+
* @param ruleTree
|
|
197
|
+
* @param options
|
|
198
|
+
*
|
|
199
|
+
* Generates middleware from given rules.
|
|
200
|
+
*
|
|
201
|
+
*/
|
|
202
|
+
function generateMiddlewareGeneratorFromRuleTree(ruleTree, options) {
|
|
203
|
+
return (schema) => generateMiddlewareFromSchemaAndRuleTree(schema, ruleTree, options);
|
|
204
|
+
}
|
|
205
|
+
exports.generateMiddlewareGeneratorFromRuleTree = generateMiddlewareGeneratorFromRuleTree;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.not = exports.or = exports.race = exports.chain = exports.and = exports.deny = exports.allow = exports.inputRule = exports.rule = exports.shield = void 0;
|
|
4
|
+
var shield_js_1 = require("./shield.js");
|
|
5
|
+
Object.defineProperty(exports, "shield", { enumerable: true, get: function () { return shield_js_1.shield; } });
|
|
6
|
+
var constructors_js_1 = require("./constructors.js");
|
|
7
|
+
Object.defineProperty(exports, "rule", { enumerable: true, get: function () { return constructors_js_1.rule; } });
|
|
8
|
+
Object.defineProperty(exports, "inputRule", { enumerable: true, get: function () { return constructors_js_1.inputRule; } });
|
|
9
|
+
Object.defineProperty(exports, "allow", { enumerable: true, get: function () { return constructors_js_1.allow; } });
|
|
10
|
+
Object.defineProperty(exports, "deny", { enumerable: true, get: function () { return constructors_js_1.deny; } });
|
|
11
|
+
Object.defineProperty(exports, "and", { enumerable: true, get: function () { return constructors_js_1.and; } });
|
|
12
|
+
Object.defineProperty(exports, "chain", { enumerable: true, get: function () { return constructors_js_1.chain; } });
|
|
13
|
+
Object.defineProperty(exports, "race", { enumerable: true, get: function () { return constructors_js_1.race; } });
|
|
14
|
+
Object.defineProperty(exports, "or", { enumerable: true, get: function () { return constructors_js_1.or; } });
|
|
15
|
+
Object.defineProperty(exports, "not", { enumerable: true, get: function () { return constructors_js_1.not; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|