diff --git a/packages/graphql-shield/src/generator.ts b/packages/graphql-shield/src/generator.ts index 2ecdcc183..adb94522a 100644 --- a/packages/graphql-shield/src/generator.ts +++ b/packages/graphql-shield/src/generator.ts @@ -19,6 +19,24 @@ import { import { isRuleFunction, isRuleFieldMap, isRule, isLogicRule, withDefault } from './utils.js' import { ValidationError } from './validation.js' +interface IInternalOptions { + excludeRulesWithFragments: boolean + excludeRulesWithoutFragments: boolean +} + +function shouldApplyRule(rule: ShieldRule, internalOptions: IInternalOptions) { + const hasFragment = 'extractFragment' in rule ? !!rule.extractFragment() : !!rule.extractFragments().length + + if ( + (internalOptions.excludeRulesWithFragments && hasFragment) || + (internalOptions.excludeRulesWithoutFragments && !hasFragment) + ) { + return false + } + + return true +} + /** * * @param options @@ -108,11 +126,20 @@ function generateFieldMiddlewareFromRule( * Generates middleware from rule for a particular type. * */ -function applyRuleToType(type: GraphQLObjectType, rules: ShieldRule | IRuleFieldMap, options: IOptions): IMiddlewareFieldMap { +function applyRuleToType( + type: GraphQLObjectType, + rules: ShieldRule | IRuleFieldMap, + options: IOptions, + internalOptions: IInternalOptions, +): IMiddlewareFieldMap { if (isRuleFunction(rules)) { /* Apply defined rule function to every field */ const fieldMap = type.getFields() + if (!shouldApplyRule(rules, internalOptions)) { + return {} + } + const middleware = Object.keys(fieldMap).reduce((middleware, field) => { return { ...middleware, @@ -142,13 +169,15 @@ function applyRuleToType(type: GraphQLObjectType, rules: ShieldRule | IRuleField /* Generation */ - const middleware = Object.keys(fieldMap).reduce( - (middleware, field) => ({ + const middleware = Object.keys(fieldMap).reduce((middleware, field) => { + if (!shouldApplyRule(rules[field], internalOptions)) { + return middleware + } + return { ...middleware, [field]: generateFieldMiddlewareFromRule(withDefault(defaultTypeRule || options.fallbackRule)(rules[field]), options), - }), - {}, - ) + } + }, {}) return middleware } else { @@ -176,7 +205,12 @@ function applyRuleToType(type: GraphQLObjectType, rules: ShieldRule | IRuleField * Applies the same rule over entire schema. * */ -function applyRuleToSchema(schema: GraphQLSchema, rule: ShieldRule, options: IOptions): IMiddlewareTypeMap { +function applyRuleToSchema( + schema: GraphQLSchema, + rule: ShieldRule, + options: IOptions, + internalOptions: IInternalOptions, +): IMiddlewareTypeMap { const typeMap = schema.getTypeMap() const middleware = Object.keys(typeMap) @@ -187,7 +221,7 @@ function applyRuleToSchema(schema: GraphQLSchema, rule: ShieldRule, options: IOp if (isObjectType(type)) { return { ...middleware, - [typeName]: applyRuleToType(type, rule, options), + [typeName]: applyRuleToType(type, rule, options, internalOptions), } } else { return middleware @@ -209,10 +243,11 @@ export function generateMiddlewareFromSchemaAndRuleTree( schema: GraphQLSchema, rules: IRules, options: IOptions, + internalOptions: IInternalOptions, ): IMiddlewareTypeMap { if (isRuleFunction(rules)) { /* Applies rule to entire schema. */ - return applyRuleToSchema(schema, rules, options) + return applyRuleToSchema(schema, rules, options, internalOptions) } else { /** * Checks type map and field map and applies rules @@ -242,7 +277,7 @@ export function generateMiddlewareFromSchemaAndRuleTree( if (isObjectType(type)) { return { ...middleware, - [typeName]: applyRuleToType(type, rules[typeName], options), + [typeName]: applyRuleToType(type, rules[typeName], options, internalOptions), } } else { return middleware diff --git a/packages/graphql-shield/src/shield.ts b/packages/graphql-shield/src/shield.ts index ad9053089..a081cd5c1 100644 --- a/packages/graphql-shield/src/shield.ts +++ b/packages/graphql-shield/src/shield.ts @@ -1,9 +1,8 @@ -import { GraphQLFieldResolver, GraphQLSchema } from 'graphql' +import { buildSchema, execute, ExecutionArgs, GraphQLFieldResolver, GraphQLSchema, printSchema } from 'graphql' import hash from 'object-hash' import { composeResolvers, ResolversComposition } from '@graphql-tools/resolvers-composition' import { addResolversToSchema } from '@graphql-tools/schema' -import { wrapSchema } from '@graphql-tools/wrap' import { IOptions, @@ -97,33 +96,54 @@ function applyComposition(schema: GraphQLSchema, middleware: IMiddlewareTypeMap) return addResolversToSchema({ schema, resolvers }) } -/** - * - * @param schema - * @param ruleTree - * @param options - * - * Validates rules and applies defined rule tree to the schema. - * - */ -export function shield(schema: GraphQLSchema, ruleTree: IRules, options: IOptionsConstructor = {}): GraphQLSchema { +type ExecuteFn = typeof execute + +// TODO: process logical rules and fallback rule +export function wrapExecuteFn( + executeFn: ExecuteFn, + config: { schema: GraphQLSchema; ruleTree: IRules; options?: IOptionsConstructor }, +): (executionArgs: ExecutionArgs) => ReturnType { + const { schema, ruleTree, options = {} } = config + const normalizedOptions = normalizeOptions(options) const ruleTreeValidity = validateRuleTree(ruleTree) - if (ruleTreeValidity.status === 'ok') { - const middleware = generateMiddlewareFromSchemaAndRuleTree(schema, ruleTree, normalizedOptions) - if (normalizedOptions.disableFragmentsAndPostExecRules) { - return applyComposition(schema, middleware) - } + if (ruleTreeValidity.status !== 'ok') { + throw new ValidationError(ruleTreeValidity.message) + } + + const middleware = generateMiddlewareFromSchemaAndRuleTree(schema, ruleTree, normalizedOptions, { + excludeRulesWithFragments: true, + excludeRulesWithoutFragments: false, + }) + const authSchema = applyComposition(schema, middleware) - const fragmentReplacements = getFragmentReplacements(middleware) + const postExecSchema = buildSchema(printSchema(schema)) + const postExecMiddleware = generateMiddlewareFromSchemaAndRuleTree(schema, ruleTree, normalizedOptions, { + excludeRulesWithFragments: false, + excludeRulesWithoutFragments: true, + }) + const postExecAuthSchema = applyComposition(postExecSchema, postExecMiddleware) - const wrappedSchema = wrapSchema({ - schema, - transforms: [new ReplaceFieldWithFragment(fragmentReplacements || [])], + return async function executeWithAuth(executionArgs: ExecutionArgs) { + const result = await executeFn({ ...executionArgs, schema: authSchema }) + + const postExecResult = await executeFn({ + ...executionArgs, + schema: postExecAuthSchema, + rootValue: result.data, }) - return applyComposition(wrappedSchema, middleware) - } else { - throw new ValidationError(ruleTreeValidity.message) + + const errors = [...(result.errors ?? []), ...(postExecResult.errors ?? [])] + const extensions = { + ...result.extensions, + ...postExecResult.extensions, + } + + return { + data: postExecResult.data, + ...(errors.length > 0 ? { errors } : {}), + ...(Object.keys(extensions).length > 0 ? { extensions } : {}), + } } } diff --git a/packages/graphql-shield/tests/cache.test.ts b/packages/graphql-shield/tests/cache.test.ts index b42da465e..bb75ed6df 100644 --- a/packages/graphql-shield/tests/cache.test.ts +++ b/packages/graphql-shield/tests/cache.test.ts @@ -1,7 +1,8 @@ -import { graphql } from 'graphql' +import { execute, graphql, parse } from 'graphql' import { makeExecutableSchema } from '@graphql-tools/schema' import { shield, rule } from '../src/index' import { IHashFunction } from '../src/types' +import { wrapExecuteFn } from '../src/shield' describe('caching:', () => { test('Strict cache - Rule is called multiple times, based on different parent.', async () => { @@ -34,7 +35,7 @@ describe('caching:', () => { Test: rule({ cache: 'strict' })(allowMock), } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ @@ -45,11 +46,14 @@ describe('caching:', () => { } } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - contextValue: {}, - }) + + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ schema, document: parse(query) }) + + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // contextValue: {}, + // }) expect(res).toEqual({ data: { @@ -94,7 +98,7 @@ describe('caching:', () => { Query: rule({ cache: 'strict' })(allowMock), } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ @@ -108,11 +112,13 @@ describe('caching:', () => { f: c(arg: "foo") } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - contextValue: {}, - }) + + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ schema, document: parse(query) }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // contextValue: {}, + // }) /* Tests */ @@ -174,7 +180,7 @@ describe('caching:', () => { }, } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) // Execution const query = ` @@ -186,11 +192,13 @@ describe('caching:', () => { e } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - contextValue: {}, - }) + + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ schema, document: parse(query) }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // contextValue: {}, + // }) /* Tests */ @@ -243,7 +251,7 @@ describe('caching:', () => { Query: allow, } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ @@ -256,11 +264,13 @@ describe('caching:', () => { e } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - contextValue: {}, - }) + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ schema, document: parse(query) }) + + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // contextValue: {}, + // }) /* Tests */ @@ -308,7 +318,7 @@ describe('caching:', () => { })(allowMock), } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ @@ -320,11 +330,13 @@ describe('caching:', () => { a3: a(arg: "boo") } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - contextValue: {}, - }) + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ schema, document: parse(query) }) + + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // contextValue: {}, + // }) /* Tests */ @@ -370,9 +382,9 @@ test('Customize hash function', async () => { Query: rule({ cache: 'strict' })(allowMock), } - const schemaWithPermissions = shield(schema, ruleTree, { - hashFunction, - }) + // const schemaWithPermissions = shield(schema, ruleTree, { + // hashFunction, + // }) /* Execution */ @@ -382,11 +394,14 @@ test('Customize hash function', async () => { b(arg: "bar") } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - contextValue: {}, - }) + + const res = await wrapExecuteFn(execute, { schema, ruleTree, options: { hashFunction } })({ schema, document: parse(query) }) + + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // contextValue: {}, + // }) /* Tests */ @@ -439,7 +454,7 @@ describe('legacy cache:', () => { Test: rule({ cache: true })(allowMock), } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ @@ -450,11 +465,13 @@ describe('legacy cache:', () => { } } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - contextValue: {}, - }) + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ schema, document: parse(query) }) + + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // contextValue: {}, + // }) /* Tests */ @@ -501,7 +518,7 @@ describe('legacy cache:', () => { Query: allow, } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) // Execution const query = ` @@ -513,11 +530,14 @@ describe('legacy cache:', () => { e } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - contextValue: {}, - }) + + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ schema, document: parse(query) }) + + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // contextValue: {}, + // }) expect(res).toEqual({ data: { diff --git a/packages/graphql-shield/tests/fallback.test.ts b/packages/graphql-shield/tests/fallback.test.ts index 0ee275008..c091111b0 100644 --- a/packages/graphql-shield/tests/fallback.test.ts +++ b/packages/graphql-shield/tests/fallback.test.ts @@ -1,6 +1,7 @@ -import { graphql } from 'graphql' +import { execute, graphql, parse } from 'graphql' import { makeExecutableSchema } from '@graphql-tools/schema' import { shield, rule, allow } from '../src/index' +import { wrapExecuteFn } from '../src/shield' describe('fallbackError correctly handles errors', () => { test('error in resolver returns fallback error.', async () => { @@ -32,9 +33,9 @@ describe('fallbackError correctly handles errors', () => { Query: allow, } - const schemaWithPermissions = shield(schema, ruleTree, { - fallbackError, - }) + // const schemaWithPermissions = shield(schema, ruleTree, { + // fallbackError, + // }) /* Execution */ @@ -43,10 +44,11 @@ describe('fallbackError correctly handles errors', () => { test } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - }) + const res = await wrapExecuteFn(execute, { schema, ruleTree, options: { fallbackError } })({ schema, document: parse(query) }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ @@ -80,9 +82,9 @@ describe('fallbackError correctly handles errors', () => { Query: allow, } - const schemaWithPermissions = shield(schema, ruleTree, { - fallbackError, - }) + // const schemaWithPermissions = shield(schema, ruleTree, { + // fallbackError, + // }) /* Execution */ @@ -91,10 +93,11 @@ describe('fallbackError correctly handles errors', () => { test } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - }) + const res = await wrapExecuteFn(execute, { schema, ruleTree, options: { fallbackError } })({ schema, document: parse(query) }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ @@ -128,9 +131,9 @@ describe('fallbackError correctly handles errors', () => { Query: allow, } - const schemaWithPermissions = shield(schema, ruleTree, { - fallbackError: fallbackMessage, - }) + // const schemaWithPermissions = shield(schema, ruleTree, { + // fallbackError: fallbackMessage, + // }) /* Execution */ const query = ` @@ -138,10 +141,14 @@ describe('fallbackError correctly handles errors', () => { test } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree, options: { fallbackError: fallbackMessage } })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ @@ -172,9 +179,9 @@ describe('fallbackError correctly handles errors', () => { Query: allow, } - const schemaWithPermissions = shield(schema, ruleTree, { - fallbackError, - }) + // const schemaWithPermissions = shield(schema, ruleTree, { + // fallbackError, + // }) /* Execution */ @@ -183,10 +190,11 @@ describe('fallbackError correctly handles errors', () => { test } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - }) + const res = await wrapExecuteFn(execute, { schema, ruleTree, options: { fallbackError } })({ schema, document: parse(query) }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ @@ -223,9 +231,9 @@ describe('fallbackError correctly handles errors', () => { Query: allow, } - const schemaWithPermissions = shield(schema, ruleTree, { - fallbackError, - }) + // const schemaWithPermissions = shield(schema, ruleTree, { + // fallbackError, + // }) /* Execution */ @@ -234,10 +242,11 @@ describe('fallbackError correctly handles errors', () => { test } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - }) + const res = await wrapExecuteFn(execute, { schema, ruleTree, options: { fallbackError } })({ schema, document: parse(query) }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ @@ -272,9 +281,9 @@ describe('external errors can be controlled correctly', () => { Query: allow, } - const schemaWithPermissions = shield(schema, ruleTree, { - allowExternalErrors: true, - }) + // const schemaWithPermissions = shield(schema, ruleTree, { + // allowExternalErrors: true, + // }) /* Execution */ @@ -283,10 +292,14 @@ describe('external errors can be controlled correctly', () => { test } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree, options: { allowExternalErrors: true } })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ @@ -314,9 +327,9 @@ describe('external errors can be controlled correctly', () => { Query: allow, } - const schemaWithPermissions = shield(schema, ruleTree, { - allowExternalErrors: true, - }) + // const schemaWithPermissions = shield(schema, ruleTree, { + // allowExternalErrors: true, + // }) /* Execution */ @@ -325,10 +338,14 @@ describe('external errors can be controlled correctly', () => { test } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree, options: { allowExternalErrors: true } })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ @@ -358,9 +375,9 @@ describe('debug mode works as expected', () => { Query: allow, } - const schemaWithPermissions = shield(schema, ruleTree, { - debug: true, - }) + // const schemaWithPermissions = shield(schema, ruleTree, { + // debug: true, + // }) /* Execution */ @@ -369,10 +386,14 @@ describe('debug mode works as expected', () => { test } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree, options: { debug: true } })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ @@ -405,9 +426,9 @@ describe('debug mode works as expected', () => { Query: allow, } - const schemaWithPermissions = shield(schema, ruleTree, { - debug: true, - }) + // const schemaWithPermissions = shield(schema, ruleTree, { + // debug: true, + // }) /* Execution */ @@ -416,10 +437,14 @@ describe('debug mode works as expected', () => { test } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree, options: { debug: true } })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ @@ -449,7 +474,7 @@ describe('custom errors work as expected', () => { }), } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ const query = ` @@ -457,10 +482,14 @@ describe('custom errors work as expected', () => { test } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ @@ -489,7 +518,7 @@ describe('custom errors work as expected', () => { }), } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ const query = ` @@ -497,10 +526,14 @@ describe('custom errors work as expected', () => { test } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ @@ -552,9 +585,9 @@ describe('fallbackRule correctly applies fallback rule', () => { }, } - const schemaWithPermissions = shield(schema, ruleTree, { - fallbackRule: fallbackRule, - }) + // const schemaWithPermissions = shield(schema, ruleTree, { + // fallbackRule: fallbackRule, + // }) /* Execution */ @@ -568,10 +601,14 @@ describe('fallbackRule correctly applies fallback rule', () => { } } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree, options: { fallbackRule: fallbackRule } })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ diff --git a/packages/graphql-shield/tests/fragments.test.ts b/packages/graphql-shield/tests/fragments.test.ts index c2ddfedb9..fb6a79077 100644 --- a/packages/graphql-shield/tests/fragments.test.ts +++ b/packages/graphql-shield/tests/fragments.test.ts @@ -1,9 +1,9 @@ -import { graphql } from 'graphql' +import { execute, graphql, parse } from 'graphql' import { makeExecutableSchema } from '@graphql-tools/schema' import { rule, and, not, or } from '../src/index' import { allow } from '../src/constructors' import { generateMiddlewareFromSchemaAndRuleTree } from '../src/generator' -import { getFragmentReplacements, normalizeOptions, shield } from '../src/shield' +import { getFragmentReplacements, normalizeOptions, shield, wrapExecuteFn } from '../src/shield' describe('Fragment extraction', () => { test('Extracts fragment from rule correctly.', async () => { @@ -102,7 +102,10 @@ describe('Fragment application', () => { const schema = makeExecutableSchema({ typeDefs, resolvers }) const fragmentReplacements = getFragmentReplacements( - generateMiddlewareFromSchemaAndRuleTree(schema, ruleTree, normalizeOptions({})), + generateMiddlewareFromSchemaAndRuleTree(schema, ruleTree, normalizeOptions({}), { + excludeRulesWithoutFragments: true, + excludeRulesWithFragments: false, + }), ) expect(fragmentReplacements).toEqual([ @@ -144,7 +147,7 @@ describe('Fragment application', () => { }, ]) - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ const query = ` @@ -157,12 +160,16 @@ describe('Fragment application', () => { } } ` - - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) + expect(res).toEqual({ data: { user: { diff --git a/packages/graphql-shield/tests/generator.test.ts b/packages/graphql-shield/tests/generator.test.ts index fbefcbaa9..d2c98d938 100644 --- a/packages/graphql-shield/tests/generator.test.ts +++ b/packages/graphql-shield/tests/generator.test.ts @@ -1,7 +1,8 @@ import { makeExecutableSchema } from '@graphql-tools/schema' import { isAsyncIterable } from '@graphql-tools/utils' -import { graphql, parse, subscribe } from 'graphql' +import { execute, graphql, parse, subscribe } from 'graphql' import { shield, rule } from '../src' +import { wrapExecuteFn } from '../src/shield' describe('generates correct middleware', () => { test('correctly applies schema rule to schema', async () => { @@ -34,7 +35,7 @@ describe('generates correct middleware', () => { const allowMock = jest.fn().mockResolvedValue(true) const schemaRule = rule({ cache: 'no_cache' })(allowMock) - const schemaWithPermissions = shield(schema, schemaRule) + // const schemaWithPermissions = shield(schema, schemaRule) /* Execution */ const query = ` @@ -45,11 +46,14 @@ describe('generates correct middleware', () => { } } ` - - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree: schemaRule })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) /* Tests */ @@ -96,7 +100,7 @@ describe('generates correct middleware', () => { Query: rule({ cache: 'no_cache' })(allowMock), } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ const query = ` @@ -108,11 +112,16 @@ describe('generates correct middleware', () => { } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) + /* Tests */ expect(res).toEqual({ @@ -158,7 +167,7 @@ describe('generates correct middleware', () => { Query: { a: rule({ cache: 'no_cache' })(allowMock) }, } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ const query = ` @@ -170,11 +179,16 @@ describe('generates correct middleware', () => { } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) + /* Tests */ expect(res).toEqual({ @@ -230,7 +244,7 @@ describe('generates correct middleware', () => { }, } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ const query = ` @@ -239,11 +253,16 @@ describe('generates correct middleware', () => { } ` - const subscription = await subscribe({ - schema: schemaWithPermissions, + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ + schema, document: parse(query), }) + // const subscription = await subscribe({ + // schema: schemaWithPermissions, + // document: parse(query), + // }) + /* Tests */ expect(isAsyncIterable(subscription)).toBe(true) @@ -314,7 +333,7 @@ describe('generates correct middleware', () => { }, } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ const query = ` @@ -328,11 +347,16 @@ describe('generates correct middleware', () => { } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) + /* Tests */ expect(res).toEqual({ @@ -396,10 +420,10 @@ describe('generates correct middleware', () => { } /* First usage */ - shield(schema, ruleTree) + // shield(schema, ruleTree) /* Second usage */ - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ const query = ` @@ -413,11 +437,16 @@ describe('generates correct middleware', () => { } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ + schema, + document: parse(query), }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) + /* Tests */ expect(res).toEqual({ diff --git a/packages/graphql-shield/tests/input.test.ts b/packages/graphql-shield/tests/input.test.ts index 41bb337a8..16d339255 100644 --- a/packages/graphql-shield/tests/input.test.ts +++ b/packages/graphql-shield/tests/input.test.ts @@ -1,6 +1,7 @@ -import { graphql } from 'graphql' +import { execute, graphql, parse } from 'graphql' import { makeExecutableSchema } from '@graphql-tools/schema' import { shield, inputRule } from '../src' +import { wrapExecuteFn } from '../src/shield' describe('input rule', () => { test('schema validation works as expected', async () => { @@ -36,7 +37,7 @@ describe('input rule', () => { }, } - const schemaWithPermissions = shield(schema, ruleTree) + // const schemaWithPermissions = shield(schema, ruleTree) /* Execution */ @@ -46,10 +47,12 @@ describe('input rule', () => { failure: login(email: "notemail") } ` - const res = await graphql({ - schema: schemaWithPermissions, - source: query, - }) + // const res = await graphql({ + // schema: schemaWithPermissions, + // source: query, + // }) + + const res = await wrapExecuteFn(execute, { schema, ruleTree })({ schema, document: parse(query) }) /* Tests */