diff --git a/src/execution/getVariableSignature.ts b/src/execution/getVariableSignature.ts index d23c310eb5..8f9fd4a5d2 100644 --- a/src/execution/getVariableSignature.ts +++ b/src/execution/getVariableSignature.ts @@ -4,9 +4,12 @@ import type { VariableDefinitionNode } from '../language/ast.js'; import { print } from '../language/printer.js'; import { isInputType } from '../type/definition.js'; -import type { GraphQLInputType, GraphQLSchema } from '../type/index.js'; +import type { + GraphQLDefaultValueUsage, + GraphQLInputType, + GraphQLSchema, +} from '../type/index.js'; -import { coerceInputLiteral } from '../utilities/coerceInputValue.js'; import { typeFromAST } from '../utilities/typeFromAST.js'; /** @@ -18,7 +21,7 @@ import { typeFromAST } from '../utilities/typeFromAST.js'; export interface GraphQLVariableSignature { name: string; type: GraphQLInputType; - defaultValue: unknown; + defaultValue: GraphQLDefaultValueUsage | undefined; } export function getVariableSignature( @@ -43,8 +46,6 @@ export function getVariableSignature( return { name: varName, type: varType, - defaultValue: defaultValue - ? coerceInputLiteral(varDefNode.defaultValue, varType) - : undefined, + defaultValue: defaultValue ? { literal: defaultValue } : undefined, }; } diff --git a/src/execution/values.ts b/src/execution/values.ts index c153a616a5..5ac0c7656c 100644 --- a/src/execution/values.ts +++ b/src/execution/values.ts @@ -20,6 +20,7 @@ import type { GraphQLDirective } from '../type/directives.js'; import type { GraphQLSchema } from '../type/schema.js'; import { + coerceDefaultValue, coerceInputLiteral, coerceInputValue, } from '../utilities/coerceInputValue.js'; @@ -90,8 +91,11 @@ function coerceVariableValues( const { name: varName, type: varType } = varSignature; if (!Object.hasOwn(inputs, varName)) { - if (varDefNode.defaultValue) { - coercedValues[varName] = varSignature.defaultValue; + if (varSignature.defaultValue) { + coercedValues[varName] = coerceDefaultValue( + varSignature.defaultValue, + varType, + ); } else if (isNonNullType(varType)) { const varTypeStr = inspect(varType); onError( @@ -173,8 +177,11 @@ export function experimentalGetArgumentValues( const argumentNode = argNodeMap.get(name); if (argumentNode == null) { - if (argDef.defaultValue !== undefined) { - coercedValues[name] = argDef.defaultValue; + if (argDef.defaultValue) { + coercedValues[name] = coerceDefaultValue( + argDef.defaultValue, + argDef.type, + ); } else if (isNonNullType(argType)) { throw new GraphQLError( `Argument "${name}" of required type "${inspect(argType)}" ` + @@ -197,8 +204,11 @@ export function experimentalGetArgumentValues( scopedVariableValues == null || !Object.hasOwn(scopedVariableValues, variableName) ) { - if (argDef.defaultValue !== undefined) { - coercedValues[name] = argDef.defaultValue; + if (argDef.defaultValue) { + coercedValues[name] = coerceDefaultValue( + argDef.defaultValue, + argDef.type, + ); } else if (isNonNullType(argType)) { throw new GraphQLError( `Argument "${name}" of required type "${inspect(argType)}" ` + diff --git a/src/index.ts b/src/index.ts index ca1fb0430f..b3a6b85902 100644 --- a/src/index.ts +++ b/src/index.ts @@ -199,6 +199,7 @@ export type { GraphQLScalarSerializer, GraphQLScalarValueParser, GraphQLScalarLiteralParser, + GraphQLDefaultValueUsage, } from './type/index.js'; // Parse and operate on GraphQL language source files. diff --git a/src/type/__tests__/definition-test.ts b/src/type/__tests__/definition-test.ts index 9a491fc31f..c5e6ebf38a 100644 --- a/src/type/__tests__/definition-test.ts +++ b/src/type/__tests__/definition-test.ts @@ -4,6 +4,7 @@ import { describe, it } from 'mocha'; import { identityFunc } from '../../jsutils/identityFunc.js'; import { inspect } from '../../jsutils/inspect.js'; +import { Kind } from '../../language/kinds.js'; import { parseValue } from '../../language/parser.js'; import type { GraphQLNullableType, GraphQLType } from '../definition.js'; @@ -581,6 +582,63 @@ describe('Type System: Input Objects', () => { 'not used anymore', ); }); + + describe('Input Object fields may have default values', () => { + it('accepts an Input Object type with a default value', () => { + const inputObjType = new GraphQLInputObjectType({ + name: 'SomeInputObject', + fields: { + f: { type: ScalarType, defaultValue: 3 }, + }, + }); + expect(inputObjType.getFields().f).to.deep.include({ + name: 'f', + description: undefined, + type: ScalarType, + defaultValue: { value: 3 }, + deprecationReason: undefined, + extensions: {}, + astNode: undefined, + }); + }); + + it('accepts an Input Object type with a default value literal', () => { + const inputObjType = new GraphQLInputObjectType({ + name: 'SomeInputObject', + fields: { + f: { + type: ScalarType, + defaultValueLiteral: { kind: Kind.INT, value: '3' }, + }, + }, + }); + expect(inputObjType.getFields().f).to.deep.include({ + name: 'f', + description: undefined, + type: ScalarType, + defaultValue: { literal: { kind: 'IntValue', value: '3' } }, + deprecationReason: undefined, + extensions: {}, + astNode: undefined, + }); + }); + + it('rejects an Input Object type with potentially conflicting default values', () => { + const inputObjType = new GraphQLInputObjectType({ + name: 'SomeInputObject', + fields: { + f: { + type: ScalarType, + defaultValue: 3, + defaultValueLiteral: { kind: Kind.INT, value: '3' }, + }, + }, + }); + expect(() => inputObjType.getFields()).to.throw( + 'Argument "f" has both a defaultValue and a defaultValueLiteral property, but only one must be provided.', + ); + }); + }); }); describe('Type System: List', () => { diff --git a/src/type/__tests__/predicate-test.ts b/src/type/__tests__/predicate-test.ts index c1e1fb3059..a71ce8c012 100644 --- a/src/type/__tests__/predicate-test.ts +++ b/src/type/__tests__/predicate-test.ts @@ -574,7 +574,10 @@ describe('Type predicates', () => { name: 'someArg', type: config.type, description: undefined, - defaultValue: config.defaultValue, + defaultValue: + config.defaultValue !== undefined + ? { value: config.defaultValue } + : undefined, deprecationReason: null, extensions: Object.create(null), astNode: undefined, @@ -622,7 +625,10 @@ describe('Type predicates', () => { name: 'someInputField', type: config.type, description: undefined, - defaultValue: config.defaultValue, + defaultValue: + config.defaultValue !== undefined + ? { value: config.defaultValue } + : undefined, deprecationReason: null, extensions: Object.create(null), astNode: undefined, diff --git a/src/type/definition.ts b/src/type/definition.ts index b0e783b691..9318eb3d41 100644 --- a/src/type/definition.ts +++ b/src/type/definition.ts @@ -16,6 +16,7 @@ import { toObjMap } from '../jsutils/toObjMap.js'; import { GraphQLError } from '../error/GraphQLError.js'; import type { + ConstValueNode, EnumTypeDefinitionNode, EnumTypeExtensionNode, EnumValueDefinitionNode, @@ -799,7 +800,7 @@ export function defineArguments( name: assertName(argName), description: argConfig.description, type: argConfig.type, - defaultValue: argConfig.defaultValue, + defaultValue: defineDefaultValue(argName, argConfig), deprecationReason: argConfig.deprecationReason, extensions: toObjMap(argConfig.extensions), astNode: argConfig.astNode, @@ -946,6 +947,7 @@ export interface GraphQLArgumentConfig { description?: Maybe; type: GraphQLInputType; defaultValue?: unknown; + defaultValueLiteral?: ConstValueNode | undefined; deprecationReason?: Maybe; extensions?: Maybe>; astNode?: Maybe; @@ -971,7 +973,7 @@ export interface GraphQLArgument { name: string; description: Maybe; type: GraphQLInputType; - defaultValue: unknown; + defaultValue: GraphQLDefaultValueUsage | undefined; deprecationReason: Maybe; extensions: Readonly; astNode: Maybe; @@ -985,6 +987,26 @@ export type GraphQLFieldMap = ObjMap< GraphQLField >; +export type GraphQLDefaultValueUsage = + | { value: unknown; literal?: never } + | { literal: ConstValueNode; value?: never }; + +export function defineDefaultValue( + argName: string, + config: GraphQLArgumentConfig | GraphQLInputFieldConfig, +): GraphQLDefaultValueUsage | undefined { + if (config.defaultValue === undefined && !config.defaultValueLiteral) { + return; + } + devAssert( + !(config.defaultValue !== undefined && config.defaultValueLiteral), + `Argument "${argName}" has both a defaultValue and a defaultValueLiteral property, but only one must be provided.`, + ); + return config.defaultValueLiteral + ? { literal: config.defaultValueLiteral } + : { value: config.defaultValue }; +} + /** * Custom extensions * @@ -1572,7 +1594,7 @@ function defineInputFieldMap( name: assertName(fieldName), description: fieldConfig.description, type: fieldConfig.type, - defaultValue: fieldConfig.defaultValue, + defaultValue: defineDefaultValue(fieldName, fieldConfig), deprecationReason: fieldConfig.deprecationReason, extensions: toObjMap(fieldConfig.extensions), astNode: fieldConfig.astNode, @@ -1613,6 +1635,7 @@ export interface GraphQLInputFieldConfig { description?: Maybe; type: GraphQLInputType; defaultValue?: unknown; + defaultValueLiteral?: ConstValueNode | undefined; deprecationReason?: Maybe; extensions?: Maybe>; astNode?: Maybe; @@ -1624,7 +1647,7 @@ export interface GraphQLInputField { name: string; description: Maybe; type: GraphQLInputType; - defaultValue: unknown; + defaultValue: GraphQLDefaultValueUsage | undefined; deprecationReason: Maybe; extensions: Readonly; astNode: Maybe; diff --git a/src/type/index.ts b/src/type/index.ts index 6617a7bfe1..dfbca75ad0 100644 --- a/src/type/index.ts +++ b/src/type/index.ts @@ -119,6 +119,7 @@ export type { GraphQLScalarSerializer, GraphQLScalarValueParser, GraphQLScalarLiteralParser, + GraphQLDefaultValueUsage, } from './definition.js'; export { diff --git a/src/type/introspection.ts b/src/type/introspection.ts index e6e121e1cc..b72b162cbb 100644 --- a/src/type/introspection.ts +++ b/src/type/introspection.ts @@ -407,8 +407,13 @@ export const __InputValue: GraphQLObjectType = new GraphQLObjectType({ 'A GraphQL-formatted string representing the default value for this input value.', resolve(inputValue) { const { type, defaultValue } = inputValue; - const valueAST = astFromValue(defaultValue, type); - return valueAST ? print(valueAST) : null; + if (!defaultValue) { + return null; + } + const literal = + defaultValue.literal ?? astFromValue(defaultValue.value, type); + invariant(literal != null, 'Invalid default value'); + return print(literal); }, }, isDeprecated: { diff --git a/src/utilities/TypeInfo.ts b/src/utilities/TypeInfo.ts index 75a4eab9ff..e49733f0c2 100644 --- a/src/utilities/TypeInfo.ts +++ b/src/utilities/TypeInfo.ts @@ -14,6 +14,7 @@ import { getEnterLeaveForKind } from '../language/visitor.js'; import type { GraphQLArgument, GraphQLCompositeType, + GraphQLDefaultValueUsage, GraphQLEnumValue, GraphQLField, GraphQLInputField, @@ -53,7 +54,7 @@ export class TypeInfo { private _parentTypeStack: Array>; private _inputTypeStack: Array>; private _fieldDefStack: Array>>; - private _defaultValueStack: Array>; + private _defaultValueStack: Array; private _directive: Maybe; private _argument: Maybe; private _enumValue: Maybe; @@ -124,7 +125,7 @@ export class TypeInfo { return this._fieldDefStack.at(-1); } - getDefaultValue(): Maybe { + getDefaultValue(): GraphQLDefaultValueUsage | undefined { return this._defaultValueStack.at(-1); } diff --git a/src/utilities/__tests__/buildClientSchema-test.ts b/src/utilities/__tests__/buildClientSchema-test.ts index b6b433626d..0ad292d03a 100644 --- a/src/utilities/__tests__/buildClientSchema-test.ts +++ b/src/utilities/__tests__/buildClientSchema-test.ts @@ -439,6 +439,7 @@ describe('Type System: build schema from introspection', () => { } type Query { + defaultID(intArg: ID = "123"): String defaultInt(intArg: Int = 30): String defaultList(listArg: [Int] = [1, 2, 3]): String defaultObject(objArg: Geo = { lat: 37.485, lon: -122.148 }): String @@ -609,6 +610,28 @@ describe('Type System: build schema from introspection', () => { expect(result.data).to.deep.equal({ foo: 'bar' }); }); + it('can use client schema for execution if resolvers are added', () => { + const schema = buildSchema(` + type Query { + foo(bar: String = "abc"): String + } + `); + + const introspection = introspectionFromSchema(schema); + const clientSchema = buildClientSchema(introspection); + + const QueryType: GraphQLObjectType = clientSchema.getType('Query') as any; + QueryType.getFields().foo.resolve = (_value, args) => args.bar; + + const result = graphqlSync({ + schema: clientSchema, + source: '{ foo }', + }); + + expect(result.data).to.deep.equal({ foo: 'abc' }); + expect(result.data).to.deep.equal({ foo: 'abc' }); + }); + it('can build invalid schema', () => { const schema = buildSchema('type Query', { assumeValid: true }); diff --git a/src/utilities/__tests__/coerceInputValue-test.ts b/src/utilities/__tests__/coerceInputValue-test.ts index 15467e8456..78dede7b81 100644 --- a/src/utilities/__tests__/coerceInputValue-test.ts +++ b/src/utilities/__tests__/coerceInputValue-test.ts @@ -5,6 +5,7 @@ import { identityFunc } from '../../jsutils/identityFunc.js'; import { invariant } from '../../jsutils/invariant.js'; import type { ObjMap } from '../../jsutils/ObjMap.js'; +import { Kind } from '../../language/kinds.js'; import { parseValue } from '../../language/parser.js'; import { print } from '../../language/printer.js'; @@ -24,7 +25,11 @@ import { GraphQLString, } from '../../type/scalars.js'; -import { coerceInputLiteral, coerceInputValue } from '../coerceInputValue.js'; +import { + coerceDefaultValue, + coerceInputLiteral, + coerceInputValue, +} from '../coerceInputValue.js'; interface CoerceResult { value: unknown; @@ -716,10 +721,14 @@ describe('coerceInputLiteral', () => { name: 'TestInput', fields: { int: { type: GraphQLInt, defaultValue: 42 }, + float: { + type: GraphQLFloat, + defaultValueLiteral: { kind: Kind.FLOAT, value: '3.14' }, + }, }, }); - test('{}', type, { int: 42 }); + test('{}', type, { int: 42, float: 3.14 }); }); const testInputObj = new GraphQLInputObjectType({ @@ -807,3 +816,26 @@ describe('coerceInputLiteral', () => { }); }); }); + +describe('coerceDefaultValue', () => { + it('memoizes coercion', () => { + const parseValueCalls: any = []; + + const spyScalar = new GraphQLScalarType({ + name: 'SpyScalar', + parseValue(value) { + parseValueCalls.push(value); + return value; + }, + }); + + const defaultValueUsage = { + literal: { kind: Kind.STRING, value: 'hello' }, + } as const; + expect(coerceDefaultValue(defaultValueUsage, spyScalar)).to.equal('hello'); + + // Call a second time + expect(coerceDefaultValue(defaultValueUsage, spyScalar)).to.equal('hello'); + expect(parseValueCalls).to.deep.equal(['hello']); + }); +}); diff --git a/src/utilities/buildClientSchema.ts b/src/utilities/buildClientSchema.ts index c109b18fa7..f1f52e8a52 100644 --- a/src/utilities/buildClientSchema.ts +++ b/src/utilities/buildClientSchema.ts @@ -32,7 +32,6 @@ import { specifiedScalarTypes } from '../type/scalars.js'; import type { GraphQLSchemaValidationOptions } from '../type/schema.js'; import { GraphQLSchema } from '../type/schema.js'; -import { coerceInputLiteral } from './coerceInputValue.js'; import type { IntrospectionDirective, IntrospectionEnumType, @@ -374,17 +373,13 @@ export function buildClientSchema( ); } - const defaultValue = - inputValueIntrospection.defaultValue != null - ? coerceInputLiteral( - parseConstValue(inputValueIntrospection.defaultValue), - type, - ) - : undefined; return { description: inputValueIntrospection.description, type, - defaultValue, + defaultValueLiteral: + inputValueIntrospection.defaultValue != null + ? parseConstValue(inputValueIntrospection.defaultValue) + : undefined, deprecationReason: inputValueIntrospection.deprecationReason, }; } diff --git a/src/utilities/coerceInputValue.ts b/src/utilities/coerceInputValue.ts index 37ac966aab..7fbce75fb5 100644 --- a/src/utilities/coerceInputValue.ts +++ b/src/utilities/coerceInputValue.ts @@ -15,7 +15,10 @@ import { GraphQLError } from '../error/GraphQLError.js'; import type { ValueNode, VariableNode } from '../language/ast.js'; import { Kind } from '../language/kinds.js'; -import type { GraphQLInputType } from '../type/definition.js'; +import type { + GraphQLDefaultValueUsage, + GraphQLInputType, +} from '../type/definition.js'; import { assertLeafType, isInputObjectType, @@ -111,8 +114,11 @@ function coerceInputValueImpl( const fieldValue = inputValue[field.name]; if (fieldValue === undefined) { - if (field.defaultValue !== undefined) { - coercedValue[field.name] = field.defaultValue; + if (field.defaultValue) { + coercedValue[field.name] = coerceDefaultValue( + field.defaultValue, + field.type, + ); } else if (isNonNullType(field.type)) { const typeStr = inspect(field.type); onError( @@ -322,8 +328,11 @@ export function coerceInputLiteral( if (isRequiredInputField(field)) { return; // Invalid: intentionally return no value. } - if (field.defaultValue !== undefined) { - coercedValue[field.name] = field.defaultValue; + if (field.defaultValue) { + coercedValue[field.name] = coerceDefaultValue( + field.defaultValue, + field.type, + ); } } else { const fieldValue = coerceInputLiteral( @@ -375,3 +384,21 @@ function getVariableValue( return variables?.[varName]; } + +/** + * @internal + */ +export function coerceDefaultValue( + defaultValue: GraphQLDefaultValueUsage, + type: GraphQLInputType, +): unknown { + // Memoize the result of coercing the default value in a hidden field. + let coercedValue = (defaultValue as any)._memoizedCoercedValue; + if (coercedValue === undefined) { + coercedValue = defaultValue.literal + ? coerceInputLiteral(defaultValue.literal, type) + : defaultValue.value; + (defaultValue as any)._memoizedCoercedValue = coercedValue; + } + return coercedValue; +} diff --git a/src/utilities/extendSchema.ts b/src/utilities/extendSchema.ts index d18b53d028..f43c15330d 100644 --- a/src/utilities/extendSchema.ts +++ b/src/utilities/extendSchema.ts @@ -83,8 +83,6 @@ import { assertValidSDLExtension } from '../validation/validate.js'; import { getDirectiveValues } from '../execution/values.js'; -import { coerceInputLiteral } from './coerceInputValue.js'; - interface Options extends GraphQLSchemaValidationOptions { /** * Set to true to assume the SDL is valid. @@ -535,9 +533,7 @@ export function extendSchemaImpl( argConfigMap[arg.name.value] = { type, description: arg.description?.value, - defaultValue: arg.defaultValue - ? coerceInputLiteral(arg.defaultValue, type) - : undefined, + defaultValueLiteral: arg.defaultValue, deprecationReason: getDeprecationReason(arg), astNode: arg, }; @@ -564,9 +560,7 @@ export function extendSchemaImpl( inputFieldMap[field.name.value] = { type, description: field.description?.value, - defaultValue: field.defaultValue - ? coerceInputLiteral(field.defaultValue, type) - : undefined, + defaultValueLiteral: field.defaultValue, deprecationReason: getDeprecationReason(field), astNode: field, }; diff --git a/src/utilities/findBreakingChanges.ts b/src/utilities/findBreakingChanges.ts index 2921074625..e6f4f79055 100644 --- a/src/utilities/findBreakingChanges.ts +++ b/src/utilities/findBreakingChanges.ts @@ -5,6 +5,7 @@ import { keyMap } from '../jsutils/keyMap.js'; import { print } from '../language/printer.js'; import type { + GraphQLDefaultValueUsage, GraphQLEnumType, GraphQLField, GraphQLInputObjectType, @@ -534,8 +535,11 @@ function typeKindName(type: GraphQLNamedType): string { invariant(false, 'Unexpected type: ' + inspect(type)); } -function stringifyValue(value: unknown, type: GraphQLInputType): string { - const ast = astFromValue(value, type); +function stringifyValue( + defaultValue: GraphQLDefaultValueUsage, + type: GraphQLInputType, +): string { + const ast = defaultValue.literal ?? astFromValue(defaultValue.value, type); invariant(ast != null); return print(sortValueNode(ast)); } diff --git a/src/utilities/printSchema.ts b/src/utilities/printSchema.ts index 7d4a5e4f5a..b02580c6fa 100644 --- a/src/utilities/printSchema.ts +++ b/src/utilities/printSchema.ts @@ -259,10 +259,13 @@ function printArgs( } function printInputValue(arg: GraphQLInputField): string { - const defaultAST = astFromValue(arg.defaultValue, arg.type); let argDecl = arg.name + ': ' + String(arg.type); - if (defaultAST) { - argDecl += ` = ${print(defaultAST)}`; + if (arg.defaultValue) { + const literal = + arg.defaultValue.literal ?? + astFromValue(arg.defaultValue.value, arg.type); + invariant(literal != null, 'Invalid default value'); + argDecl += ` = ${print(literal)}`; } return argDecl + printDeprecated(arg.deprecationReason); } diff --git a/src/utilities/valueFromAST.ts b/src/utilities/valueFromAST.ts index eb95ea3cdb..5b1ced4302 100644 --- a/src/utilities/valueFromAST.ts +++ b/src/utilities/valueFromAST.ts @@ -14,6 +14,8 @@ import { isNonNullType, } from '../type/definition.js'; +import { coerceDefaultValue } from './coerceInputValue.js'; + /** * Produces a JavaScript value given a GraphQL Value AST. * @@ -114,8 +116,11 @@ export function valueFromAST( for (const field of Object.values(type.getFields())) { const fieldNode = fieldNodes.get(field.name); if (fieldNode == null || isMissingVariable(fieldNode.value, variables)) { - if (field.defaultValue !== undefined) { - coercedObj[field.name] = field.defaultValue; + if (field.defaultValue) { + coercedObj[field.name] = coerceDefaultValue( + field.defaultValue, + field.type, + ); } else if (isNonNullType(field.type)) { return; // Invalid: intentionally return no value. } diff --git a/src/validation/ValidationContext.ts b/src/validation/ValidationContext.ts index 7f7114c4ef..d45e7a46a4 100644 --- a/src/validation/ValidationContext.ts +++ b/src/validation/ValidationContext.ts @@ -19,6 +19,7 @@ import { visit } from '../language/visitor.js'; import type { GraphQLArgument, GraphQLCompositeType, + GraphQLDefaultValueUsage, GraphQLEnumValue, GraphQLField, GraphQLInputType, @@ -34,7 +35,7 @@ type NodeWithSelectionSet = OperationDefinitionNode | FragmentDefinitionNode; interface VariableUsage { readonly node: VariableNode; readonly type: Maybe; - readonly defaultValue: Maybe; + readonly defaultValue: GraphQLDefaultValueUsage | undefined; readonly fragmentVariableDefinition: Maybe; } diff --git a/src/validation/rules/VariablesInAllowedPositionRule.ts b/src/validation/rules/VariablesInAllowedPositionRule.ts index e68a595c4f..888e49d3dd 100644 --- a/src/validation/rules/VariablesInAllowedPositionRule.ts +++ b/src/validation/rules/VariablesInAllowedPositionRule.ts @@ -7,7 +7,10 @@ import type { ValueNode, VariableDefinitionNode } from '../../language/ast.js'; import { Kind } from '../../language/kinds.js'; import type { ASTVisitor } from '../../language/visitor.js'; -import type { GraphQLType } from '../../type/definition.js'; +import type { + GraphQLDefaultValueUsage, + GraphQLType, +} from '../../type/definition.js'; import { isNonNullType } from '../../type/definition.js'; import type { GraphQLSchema } from '../../type/schema.js'; @@ -95,7 +98,7 @@ function allowedVariableUsage( varType: GraphQLType, varDefaultValue: Maybe, locationType: GraphQLType, - locationDefaultValue: Maybe, + locationDefaultValue: GraphQLDefaultValueUsage | undefined, ): boolean { if (isNonNullType(locationType) && !isNonNullType(varType)) { const hasNonNullVariableDefaultValue =