From a034acb8733d0d0983db09bbbce55b4bf208bf56 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Thu, 7 May 2020 22:43:44 -0400 Subject: [PATCH] do not send variables with value undefined graphql-js converts these to null See https://github.com/graphql/graphql-js/issues/2533 --- src/delegate/createRequest.ts | 5 +- src/delegate/transforms/FilterToSchema.ts | 5 +- src/stitch/typeFromAST.ts | 2 +- src/test/alternateStitchSchemas.test.ts | 66 +++++++++++++++++++++++ src/utils/updateArgument.ts | 6 ++- 5 files changed, 80 insertions(+), 4 deletions(-) diff --git a/src/delegate/createRequest.ts b/src/delegate/createRequest.ts index dedac325dea..d418f85d9f3 100644 --- a/src/delegate/createRequest.ts +++ b/src/delegate/createRequest.ts @@ -113,10 +113,13 @@ export function createRequest({ sourceSchema, def.type as NamedTypeNode, ) as GraphQLInputType; - newVariables[varName] = serializeInputValue( + const serializedValue = serializeInputValue( varType, variableValues[varName], ); + if (serializedValue !== undefined) { + newVariables[varName] = serializedValue; + } }); } diff --git a/src/delegate/transforms/FilterToSchema.ts b/src/delegate/transforms/FilterToSchema.ts index 65d2d63df1c..cf0e7542fc8 100644 --- a/src/delegate/transforms/FilterToSchema.ts +++ b/src/delegate/transforms/FilterToSchema.ts @@ -142,7 +142,10 @@ function filterToSchema( }); const newVariables = usedVariables.reduce((acc, variableName) => { - acc[variableName] = variables[variableName]; + const variableValue = variables[variableName]; + if (variableValue !== undefined) { + acc[variableName] = variableValue; + } return acc; }, {}); diff --git a/src/stitch/typeFromAST.ts b/src/stitch/typeFromAST.ts index a4739cb1e5c..f48e2b98f76 100644 --- a/src/stitch/typeFromAST.ts +++ b/src/stitch/typeFromAST.ts @@ -188,7 +188,7 @@ function makeValues( [node.name.value]: { type: createStub(node.type, 'input'), defaultValue: - node.defaultValue != null + node.defaultValue !== undefined ? valueFromASTUntyped(node.defaultValue) : undefined, description: getDescription(node, backcompatOptions), diff --git a/src/test/alternateStitchSchemas.test.ts b/src/test/alternateStitchSchemas.test.ts index 216a4f935f6..34ff64ff2e9 100644 --- a/src/test/alternateStitchSchemas.test.ts +++ b/src/test/alternateStitchSchemas.test.ts @@ -426,6 +426,72 @@ describe('transform object fields', () => { }); }); +describe('optional arguments', () => { + const schema = makeExecutableSchema({ + typeDefs: ` + enum Arg { + possibleArg + } + type Query { + test(arg: Arg): Boolean + } + `, + resolvers: { + Query: { + test: (_root, args, _context) => args.arg === undefined + } + } + }); + + const stitchedSchema = stitchSchemas({ + schemas: [schema], + }); + + it('work with schema stitching', async () => { + const query = ` + { + test + } + `; + + const originalResult = await graphql(schema, query); + expect(originalResult.data.test).toEqual(true); + + const stitchedResult = await graphql(stitchedSchema, query); + expect(stitchedResult.data.test).toEqual(true); + }); + + it('work with schema stitching when using variables', async () => { + const query = ` + query test($arg: Arg) { + test(arg: $arg) + } + `; + + const originalResult = await graphql(schema, query); + expect(originalResult.data.test).toEqual(true); + + const stitchedResult = await graphql(stitchedSchema, query); + expect(stitchedResult.data.test).toEqual(true); + }); + + // See https://github.com/graphql/graphql-js/issues/2533 + it('may not work as expected when explicitly passing in an undefined value', async () => { + const query = ` + query test($arg: Arg) { + test(arg: $arg) + } + `; + + const originalResult = await graphql(schema, query, {}, {}, { arg: undefined }); + expect(originalResult.data.test).toEqual(false); + + const stitchedResult = await graphql(stitchedSchema, query, {}, {}, { arg: undefined }); + expect(stitchedResult.data.test).toEqual(false); + }); +}); + + describe('default values', () => { test('should work to add a default value even when renaming root fields', async () => { const transformedPropertySchema = transformSchema(propertySchema, [ diff --git a/src/utils/updateArgument.ts b/src/utils/updateArgument.ts index cd1c80fef00..5e18edb7ac6 100644 --- a/src/utils/updateArgument.ts +++ b/src/utils/updateArgument.ts @@ -47,5 +47,9 @@ export function updateArgument( type: astFromType(argType), }; - variableValues[varName] = newArg; + if (newArg === undefined) { + delete variableValues[varName]; + } else { + variableValues[varName] = newArg; + } }