diff --git a/src/utilities/__tests__/valueFromAST-test.ts b/src/utilities/__tests__/valueFromAST-test.ts index 05924f3c56..5cef710f61 100644 --- a/src/utilities/__tests__/valueFromAST-test.ts +++ b/src/utilities/__tests__/valueFromAST-test.ts @@ -252,11 +252,19 @@ describe('valueFromAST', () => { expectValueFrom('$var', GraphQLBoolean, { var: true }).to.equal(true); expectValueFrom('$var', GraphQLBoolean, { var: null }).to.equal(null); expectValueFrom('$var', nonNullBool, { var: null }).to.equal(undefined); + expectValueFrom('$toString', GraphQLBoolean, {}).to.equal(undefined); + expectValueFrom('$var', GraphQLBoolean, { var: undefined }).to.equal( + undefined, + ); }); it('asserts variables are provided as items in lists', () => { expectValueFrom('[ $foo ]', listOfBool, {}).to.deep.equal([null]); + expectValueFrom('[ $foo ]', listOfBool, { foo: undefined }).to.deep.equal([ + null, + ]); expectValueFrom('[ $foo ]', listOfNonNullBool, {}).to.equal(undefined); + expectValueFrom('[ $toString ]', listOfBool, {}).to.deep.equal([null]); expectValueFrom('[ $foo ]', listOfNonNullBool, { foo: true, }).to.deep.equal([true]); @@ -285,5 +293,14 @@ describe('valueFromAST', () => { int: 42, requiredBool: true, }); + + expectValueFrom( + '{ int: $toString, requiredBool: true }', + testInputObj, + {}, + ).to.deep.equal({ + int: 42, + requiredBool: true, + }); }); }); diff --git a/src/utilities/valueFromAST.ts b/src/utilities/valueFromAST.ts index 2e6cc1c613..686f568b58 100644 --- a/src/utilities/valueFromAST.ts +++ b/src/utilities/valueFromAST.ts @@ -48,7 +48,11 @@ export function valueFromAST( if (valueNode.kind === Kind.VARIABLE) { const variableName = valueNode.name.value; - if (variables == null || variables[variableName] === undefined) { + if ( + variables == null || + variables[variableName] === undefined || + !hasOwnProperty(variables, variableName) + ) { // No valid return value. return; } @@ -168,6 +172,12 @@ function isMissingVariable( ): boolean { return ( valueNode.kind === Kind.VARIABLE && - (variables == null || variables[valueNode.name.value] === undefined) + (variables == null || + variables[valueNode.name.value] === undefined || + !hasOwnProperty(variables, valueNode.name.value)) ); } + +function hasOwnProperty(obj: ObjMap, prop: string): boolean { + return Object.prototype.hasOwnProperty.call(obj, prop); +}