Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4b4cb69

Browse files
committedMay 10, 2021
Preserve defaultValue literals
Fixes #3051
1 parent c853294 commit 4b4cb69

22 files changed

+202
-71
lines changed
 

‎src/execution/values.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type { GraphQLSchema } from '../type/schema';
1717
import type { GraphQLField } from '../type/definition';
1818
import type { GraphQLDirective } from '../type/directives';
1919
import { isInputType, isNonNullType } from '../type/definition';
20+
import { getCoercedDefaultValue } from '../type/defaultValues';
2021

2122
import { typeFromAST } from '../utilities/typeFromAST';
2223
import { valueFromAST } from '../utilities/valueFromAST';
@@ -173,8 +174,11 @@ export function getArgumentValues(
173174
const argumentNode = argNodeMap[name];
174175

175176
if (!argumentNode) {
176-
if (argDef.defaultValue !== undefined) {
177-
coercedValues[name] = argDef.defaultValue;
177+
if (argDef.defaultValue) {
178+
coercedValues[name] = getCoercedDefaultValue(
179+
argDef.defaultValue,
180+
argDef.type,
181+
);
178182
} else if (isNonNullType(argType)) {
179183
throw new GraphQLError(
180184
`Argument "${name}" of required type "${inspect(argType)}" ` +
@@ -194,8 +198,11 @@ export function getArgumentValues(
194198
variableValues == null ||
195199
!hasOwnProperty(variableValues, variableName)
196200
) {
197-
if (argDef.defaultValue !== undefined) {
198-
coercedValues[name] = argDef.defaultValue;
201+
if (argDef.defaultValue) {
202+
coercedValues[name] = getCoercedDefaultValue(
203+
argDef.defaultValue,
204+
argDef.type,
205+
);
199206
} else if (isNonNullType(argType)) {
200207
throw new GraphQLError(
201208
`Argument "${name}" of required type "${inspect(argType)}" ` +

‎src/index.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ export {
126126
// Validate GraphQL schema.
127127
validateSchema,
128128
assertValidSchema,
129+
// Operate on default values.
130+
getCoercedDefaultValue,
131+
getLiteralDefaultValue,
129132
} from './type/index';
130133

131134
export {
@@ -150,6 +153,7 @@ export {
150153
GraphQLArgumentConfig,
151154
GraphQLArgumentExtensions,
152155
GraphQLInputValue,
156+
GraphQLDefaultValueUsage,
153157
GraphQLInputValueConfig,
154158
GraphQLEnumTypeConfig,
155159
GraphQLEnumTypeExtensions,

‎src/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ export {
125125
// Validate GraphQL schema.
126126
validateSchema,
127127
assertValidSchema,
128+
// Operate on default values.
129+
getCoercedDefaultValue,
130+
getLiteralDefaultValue,
128131
} from './type/index';
129132

130133
export type {
@@ -146,6 +149,7 @@ export type {
146149
GraphQLArgument,
147150
GraphQLArgumentConfig,
148151
GraphQLInputValue,
152+
GraphQLDefaultValueUsage,
149153
GraphQLInputValueConfig,
150154
GraphQLEnumTypeConfig,
151155
GraphQLEnumValue,

‎src/type/__tests__/predicate-test.js

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ import {
6969
assertNamedType,
7070
getNullableType,
7171
getNamedType,
72+
defineInputValue,
7273
} from '../definition';
7374

7475
const ObjectType = new GraphQLObjectType({ name: 'Object', fields: {} });
@@ -562,19 +563,14 @@ describe('Type predicates', () => {
562563
});
563564

564565
describe('isRequiredInput', () => {
565-
function buildArg(config: {|
566+
function buildArg({
567+
type,
568+
defaultValue,
569+
}: {|
566570
type: GraphQLInputType,
567571
defaultValue?: mixed,
568572
|}): GraphQLArgument {
569-
return {
570-
name: 'someArg',
571-
type: config.type,
572-
description: undefined,
573-
defaultValue: config.defaultValue,
574-
deprecationReason: null,
575-
extensions: undefined,
576-
astNode: undefined,
577-
};
573+
return defineInputValue({ type, defaultValue }, 'someArg');
578574
}
579575

580576
it('returns true for required arguments', () => {
@@ -608,19 +604,14 @@ describe('Type predicates', () => {
608604
expect(isRequiredInput(optArg4)).to.equal(false);
609605
});
610606

611-
function buildInputField(config: {|
607+
function buildInputField({
608+
type,
609+
defaultValue,
610+
}: {|
612611
type: GraphQLInputType,
613612
defaultValue?: mixed,
614613
|}): GraphQLInputField {
615-
return {
616-
name: 'someInputField',
617-
type: config.type,
618-
description: undefined,
619-
defaultValue: config.defaultValue,
620-
deprecationReason: null,
621-
extensions: undefined,
622-
astNode: undefined,
623-
};
614+
return defineInputValue({ type, defaultValue }, 'someInputField');
624615
}
625616

626617
it('returns true for required input field', () => {

‎src/type/defaultValues.d.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { ConstValueNode } from '../language/ast';
2+
3+
import { GraphQLInputType, GraphQLDefaultValueUsage } from './definition';
4+
5+
export function getLiteralDefaultValue(
6+
usage: GraphQLDefaultValueUsage,
7+
type: GraphQLInputType,
8+
): ConstValueNode;
9+
10+
export function getCoercedDefaultValue(
11+
usage: GraphQLDefaultValueUsage,
12+
type: GraphQLInputType,
13+
): unknown;

‎src/type/defaultValues.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { invariant } from '../jsutils/invariant';
2+
import type { ConstValueNode } from '../language/ast';
3+
4+
import { astFromValue } from '../utilities/astFromValue';
5+
import { valueFromAST } from '../utilities/valueFromAST';
6+
7+
import type { GraphQLInputType, GraphQLDefaultValueUsage } from './definition';
8+
9+
export function getLiteralDefaultValue(
10+
usage: GraphQLDefaultValueUsage,
11+
type: GraphQLInputType,
12+
): ConstValueNode {
13+
if (usage.literal) {
14+
return usage.literal;
15+
}
16+
const literal = astFromValue(usage.value, type);
17+
invariant(literal, 'Value cannot be converted to literal for this type');
18+
return literal;
19+
}
20+
21+
export function getCoercedDefaultValue(
22+
usage: GraphQLDefaultValueUsage,
23+
type: GraphQLInputType,
24+
): mixed {
25+
return usage.value !== undefined
26+
? usage.value
27+
: valueFromAST(usage.literal, type);
28+
}

‎src/type/definition.d.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
FieldNode,
2424
FragmentDefinitionNode,
2525
ValueNode,
26+
ConstValueNode,
2627
ScalarTypeExtensionNode,
2728
UnionTypeExtensionNode,
2829
EnumTypeExtensionNode,
@@ -575,12 +576,17 @@ export interface GraphQLInputValue<Extensions> {
575576
name: string;
576577
description: Maybe<string>;
577578
type: GraphQLInputType;
578-
defaultValue: unknown;
579+
defaultValue: Maybe<GraphQLDefaultValueUsage>;
579580
deprecationReason: Maybe<string>;
580581
extensions: Maybe<Readonly<Extensions>>;
581582
astNode: Maybe<InputValueDefinitionNode>;
582583
}
583584

585+
export interface GraphQLDefaultValueUsage {
586+
value: unknown;
587+
literal: Maybe<ConstValueNode>;
588+
}
589+
584590
export interface GraphQLInputValueConfig<Extensions> {
585591
description?: Maybe<string>;
586592
type: GraphQLInputType;

‎src/type/definition.js

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import type {
4141
FieldNode,
4242
FragmentDefinitionNode,
4343
ValueNode,
44+
ConstValueNode,
4445
} from '../language/ast';
4546

4647
import { valueFromASTUntyped } from '../utilities/valueFromASTUntyped';
@@ -971,11 +972,18 @@ export function defineInputValue(
971972
!('resolve' in config),
972973
`${name} has a resolve property, but inputs cannot define resolvers.`,
973974
);
975+
let defaultValue;
976+
if (config.defaultValue !== undefined || config.defaultValueLiteral) {
977+
defaultValue = {
978+
value: config.defaultValue,
979+
literal: config.defaultValueLiteral,
980+
};
981+
}
974982
return {
975983
name,
976984
description: config.description,
977985
type: config.type,
978-
defaultValue: config.defaultValue,
986+
defaultValue,
979987
deprecationReason: config.deprecationReason,
980988
extensions: config.extensions && toObjMap(config.extensions),
981989
astNode: config.astNode,
@@ -991,7 +999,8 @@ export function inputValueToConfig(
991999
return {
9921000
description: inputValue.description,
9931001
type: inputValue.type,
994-
defaultValue: inputValue.defaultValue,
1002+
defaultValue: inputValue.defaultValue?.value,
1003+
defaultValueLiteral: inputValue.defaultValue?.literal,
9951004
deprecationReason: inputValue.deprecationReason,
9961005
extensions: inputValue.extensions,
9971006
astNode: inputValue.astNode,
@@ -1002,16 +1011,22 @@ export type GraphQLInputValue = {|
10021011
name: string,
10031012
description: ?string,
10041013
type: GraphQLInputType,
1005-
defaultValue: mixed,
1014+
defaultValue: ?GraphQLDefaultValueUsage,
10061015
deprecationReason: ?string,
10071016
extensions: ?ReadOnlyObjMap<mixed>,
10081017
astNode: ?InputValueDefinitionNode,
10091018
|};
10101019

1020+
export type GraphQLDefaultValueUsage = {|
1021+
value: mixed,
1022+
literal: ?ConstValueNode,
1023+
|};
1024+
10111025
export type GraphQLInputValueConfig = {|
10121026
description?: ?string,
10131027
type: GraphQLInputType,
10141028
defaultValue?: mixed,
1029+
defaultValueLiteral?: ?ConstValueNode,
10151030
deprecationReason?: ?string,
10161031
extensions?: ?ReadOnlyObjMapLike<mixed>,
10171032
astNode?: ?InputValueDefinitionNode,

‎src/type/index.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export {
8282
GraphQLArgumentConfig,
8383
GraphQLArgumentExtensions,
8484
GraphQLInputValue,
85+
GraphQLDefaultValueUsage,
8586
GraphQLInputValueConfig,
8687
GraphQLEnumTypeConfig,
8788
GraphQLEnumTypeExtensions,
@@ -117,6 +118,11 @@ export {
117118
GraphQLScalarLiteralParser,
118119
} from './definition';
119120

121+
export {
122+
getCoercedDefaultValue,
123+
getLiteralDefaultValue,
124+
} from './defaultValues';
125+
120126
export {
121127
// Predicate
122128
isDirective,

‎src/type/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export type {
136136
GraphQLArgument,
137137
GraphQLArgumentConfig,
138138
GraphQLInputValue,
139+
GraphQLDefaultValueUsage,
139140
GraphQLInputValueConfig,
140141
GraphQLEnumTypeConfig,
141142
GraphQLEnumValue,
@@ -162,5 +163,10 @@ export type {
162163
GraphQLScalarLiteralParser,
163164
} from './definition';
164165

166+
export {
167+
getCoercedDefaultValue,
168+
getLiteralDefaultValue,
169+
} from './defaultValues';
170+
165171
// Validate GraphQL schema.
166172
export { validateSchema, assertValidSchema } from './validate';

‎src/type/introspection.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { invariant } from '../jsutils/invariant';
33

44
import { print } from '../language/printer';
55
import { DirectiveLocation } from '../language/directiveLocation';
6-
import { astFromValue } from '../utilities/astFromValue';
76

87
import type { GraphQLSchema } from './schema';
98
import type { GraphQLDirective } from './directives';
@@ -31,6 +30,7 @@ import {
3130
isNonNullType,
3231
isAbstractType,
3332
} from './definition';
33+
import { getLiteralDefaultValue } from './defaultValues';
3434

3535
export const __Schema: GraphQLObjectType = new GraphQLObjectType({
3636
name: '__Schema',
@@ -382,11 +382,15 @@ export const __InputValue: GraphQLObjectType = new GraphQLObjectType({
382382
type: GraphQLString,
383383
description:
384384
'A GraphQL-formatted string representing the default value for this input value.',
385-
resolve(inputValue) {
386-
const { type, defaultValue } = inputValue;
387-
const valueAST = astFromValue(defaultValue, type);
388-
return valueAST ? print(valueAST) : null;
389-
},
385+
resolve: (inputValue) =>
386+
inputValue.defaultValue
387+
? print(
388+
getLiteralDefaultValue(
389+
inputValue.defaultValue,
390+
inputValue.type,
391+
),
392+
)
393+
: null,
390394
},
391395
isDeprecated: {
392396
type: new GraphQLNonNull(GraphQLBoolean),

‎src/utilities/TypeInfo.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ export class TypeInfo {
209209
}
210210
}
211211
this._argument = argDef;
212-
this._defaultValueStack.push(argDef ? argDef.defaultValue : undefined);
212+
this._defaultValueStack.push(argDef?.defaultValue?.value);
213213
this._inputTypeStack.push(isInputType(argType) ? argType : undefined);
214214
break;
215215
}
@@ -233,9 +233,7 @@ export class TypeInfo {
233233
inputFieldType = inputField.type;
234234
}
235235
}
236-
this._defaultValueStack.push(
237-
inputField ? inputField.defaultValue : undefined,
238-
);
236+
this._defaultValueStack.push(inputField?.defaultValue?.value);
239237
this._inputTypeStack.push(
240238
isInputType(inputFieldType) ? inputFieldType : undefined,
241239
);

‎src/utilities/__tests__/astFromValue-test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ describe('astFromValue', () => {
5151
kind: 'BooleanValue',
5252
value: false,
5353
});
54+
55+
expect(astFromValue(null, NonNullBoolean)).to.equal(null);
5456
});
5557

5658
it('converts Int values to Int ASTs', () => {

‎src/utilities/__tests__/buildClientSchema-test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ describe('Type System: build schema from introspection', () => {
438438
}
439439
440440
type Query {
441+
defaultID(intArg: ID = "123"): String
441442
defaultInt(intArg: Int = 30): String
442443
defaultList(listArg: [Int] = [1, 2, 3]): String
443444
defaultObject(objArg: Geo = {lat: 37.485, lon: -122.148}): String
@@ -592,6 +593,27 @@ describe('Type System: build schema from introspection', () => {
592593
expect(result.data).to.deep.equal({ foo: 'bar' });
593594
});
594595

596+
it('can use client schema for execution if resolves are later added', () => {
597+
const schema = buildSchema(`
598+
type Query {
599+
foo(bar: String = "abc"): String
600+
}
601+
`);
602+
603+
const introspection = introspectionFromSchema(schema);
604+
const clientSchema = buildClientSchema(introspection);
605+
606+
clientSchema.getType('Query').getFields().foo.resolve = (_value, args) =>
607+
args.bar;
608+
609+
const result = graphqlSync({
610+
schema: clientSchema,
611+
source: '{ foo }',
612+
});
613+
614+
expect(result.data).to.deep.equal({ foo: 'abc' });
615+
});
616+
595617
it('can build invalid schema', () => {
596618
const schema = buildSchema('type Query', { assumeValid: true });
597619

‎src/utilities/__tests__/valueFromAST-test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,21 @@ describe('valueFromAST', () => {
188188
);
189189
});
190190

191+
it('uses default values for unprovided fields', () => {
192+
const type = new GraphQLInputObjectType({
193+
name: 'TestInput',
194+
fields: {
195+
int: { type: GraphQLInt, defaultValue: 42 },
196+
float: {
197+
type: GraphQLFloat,
198+
defaultValueLiteral: { kind: 'FloatValue', value: '3.14' },
199+
},
200+
},
201+
});
202+
203+
expectValueFrom('{}', type).to.deep.equal({ int: 42, float: 3.14 });
204+
});
205+
191206
const testInputObj = new GraphQLInputObjectType({
192207
name: 'TestInput',
193208
fields: {

‎src/utilities/astFromValue.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { invariant } from '../jsutils/invariant';
33
import { isObjectLike } from '../jsutils/isObjectLike';
44
import { isIterableObject } from '../jsutils/isIterableObject';
55

6-
import type { ValueNode } from '../language/ast';
6+
import type { ConstValueNode } from '../language/ast';
77
import { Kind } from '../language/kinds';
88

99
import type { GraphQLInputType } from '../type/definition';
@@ -37,13 +37,15 @@ import {
3737
* | null | NullValue |
3838
*
3939
*/
40-
export function astFromValue(value: mixed, type: GraphQLInputType): ?ValueNode {
40+
export function astFromValue(
41+
value: mixed,
42+
type: GraphQLInputType,
43+
): ?ConstValueNode {
4144
if (isNonNullType(type)) {
42-
const astValue = astFromValue(value, type.ofType);
43-
if (astValue?.kind === Kind.NULL) {
45+
if (value === null) {
4446
return null;
4547
}
46-
return astValue;
48+
return astFromValue(value, type.ofType);
4749
}
4850

4951
// only explicit null, not undefined, NaN

‎src/utilities/buildClientSchema.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { devAssert } from '../jsutils/devAssert';
33
import { keyValMap } from '../jsutils/keyValMap';
44
import { isObjectLike } from '../jsutils/isObjectLike';
55

6-
import { parseValue } from '../language/parser';
6+
import { parseConstValue } from '../language/parser';
77

88
import type { GraphQLSchemaValidationOptions } from '../type/schema';
99
import type {
@@ -47,7 +47,6 @@ import type {
4747
IntrospectionTypeRef,
4848
IntrospectionNamedTypeRef,
4949
} from './getIntrospectionQuery';
50-
import { valueFromAST } from './valueFromAST';
5150

5251
/**
5352
* Build a GraphQLSchema for use by client tools.
@@ -367,14 +366,13 @@ export function buildClientSchema(
367366
);
368367
}
369368

370-
const defaultValue =
371-
inputValueIntrospection.defaultValue != null
372-
? valueFromAST(parseValue(inputValueIntrospection.defaultValue), type)
373-
: undefined;
374369
return {
375370
description: inputValueIntrospection.description,
376371
type,
377-
defaultValue,
372+
defaultValueLiteral:
373+
inputValueIntrospection.defaultValue != null
374+
? parseConstValue(inputValueIntrospection.defaultValue)
375+
: undefined,
378376
deprecationReason: inputValueIntrospection.deprecationReason,
379377
};
380378
}

‎src/utilities/coerceInputValue.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
isListType,
1818
isNonNullType,
1919
} from '../type/definition';
20+
import { getCoercedDefaultValue } from '../type/defaultValues';
2021

2122
type OnErrorCB = (
2223
path: $ReadOnlyArray<string | number>,
@@ -102,8 +103,11 @@ function coerceInputValueImpl(
102103
const fieldValue = inputValue[field.name];
103104

104105
if (fieldValue === undefined) {
105-
if (field.defaultValue !== undefined) {
106-
coercedValue[field.name] = field.defaultValue;
106+
if (field.defaultValue) {
107+
coercedValue[field.name] = getCoercedDefaultValue(
108+
field.defaultValue,
109+
field.type,
110+
);
107111
} else if (isNonNullType(field.type)) {
108112
const typeStr = inspect(field.type);
109113
onError(

‎src/utilities/extendSchema.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ import {
8080
GraphQLInputObjectType,
8181
} from '../type/definition';
8282

83-
import { valueFromAST } from './valueFromAST';
84-
8583
type Options = {|
8684
...GraphQLSchemaValidationOptions,
8785

@@ -496,7 +494,7 @@ export function extendSchemaImpl(
496494
configMap[node.name.value] = {
497495
type,
498496
description: node.description?.value,
499-
defaultValue: valueFromAST(node.defaultValue, type),
497+
defaultValueLiteral: node.defaultValue,
500498
deprecationReason: getDeprecationReason(node),
501499
astNode: node,
502500
};

‎src/utilities/findBreakingChanges.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import { inspect } from '../jsutils/inspect';
33
import { invariant } from '../jsutils/invariant';
44
import { naturalCompare } from '../jsutils/naturalCompare';
55

6+
import type { ConstValueNode } from '../language/ast';
67
import { print } from '../language/printer';
78
import { visit } from '../language/visitor';
89

910
import type { GraphQLSchema } from '../type/schema';
1011
import type {
1112
GraphQLField,
1213
GraphQLType,
13-
GraphQLInputType,
1414
GraphQLNamedType,
1515
GraphQLEnumType,
1616
GraphQLUnionType,
@@ -31,8 +31,7 @@ import {
3131
isNamedType,
3232
isRequiredInput,
3333
} from '../type/definition';
34-
35-
import { astFromValue } from './astFromValue';
34+
import { getLiteralDefaultValue } from '../type/defaultValues';
3635

3736
export const BreakingChangeType = Object.freeze({
3837
TYPE_REMOVED: 'TYPE_REMOVED',
@@ -402,18 +401,23 @@ function findArgChanges(
402401
`${oldType.name}.${oldField.name} arg ${oldArg.name} has changed type from ` +
403402
`${String(oldArg.type)} to ${String(newArg.type)}.`,
404403
});
405-
} else if (oldArg.defaultValue !== undefined) {
406-
if (newArg.defaultValue === undefined) {
404+
} else if (oldArg.defaultValue) {
405+
if (!newArg.defaultValue) {
407406
schemaChanges.push({
408407
type: DangerousChangeType.ARG_DEFAULT_VALUE_CHANGE,
409408
description: `${oldType.name}.${oldField.name} arg ${oldArg.name} defaultValue was removed.`,
410409
});
411410
} else {
411+
const newArgDefaultValue = newArg.defaultValue;
412412
// Since we looking only for client's observable changes we should
413413
// compare default values in the same representation as they are
414414
// represented inside introspection.
415-
const oldValueStr = stringifyValue(oldArg.defaultValue, oldArg.type);
416-
const newValueStr = stringifyValue(newArg.defaultValue, newArg.type);
415+
const oldValueStr = stringifyValue(
416+
getLiteralDefaultValue(oldArg.defaultValue, oldArg.type),
417+
);
418+
const newValueStr = stringifyValue(
419+
getLiteralDefaultValue(newArgDefaultValue, newArg.type),
420+
);
417421

418422
if (oldValueStr !== newValueStr) {
419423
schemaChanges.push({
@@ -533,10 +537,7 @@ function typeKindName(type: GraphQLNamedType): string {
533537
invariant(false, 'Unexpected type: ' + inspect((type: empty)));
534538
}
535539

536-
function stringifyValue(value: mixed, type: GraphQLInputType): string {
537-
const ast = astFromValue(value, type);
538-
invariant(ast != null);
539-
540+
function stringifyValue(ast: ConstValueNode): string {
540541
const sortedAST = visit(ast, {
541542
ObjectValue(objectNode) {
542543
// Make a copy since sort mutates array

‎src/utilities/printSchema.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
isEnumType,
3232
isInputObjectType,
3333
} from '../type/definition';
34+
import { getLiteralDefaultValue } from '../type/defaultValues';
3435

3536
import { astFromValue } from './astFromValue';
3637

@@ -258,10 +259,11 @@ function printArgs(
258259
}
259260

260261
function printInputValue(arg: GraphQLInputField): string {
261-
const defaultAST = astFromValue(arg.defaultValue, arg.type);
262262
let argDecl = arg.name + ': ' + String(arg.type);
263-
if (defaultAST) {
264-
argDecl += ` = ${print(defaultAST)}`;
263+
if (arg.defaultValue) {
264+
argDecl += ` = ${print(
265+
getLiteralDefaultValue(arg.defaultValue, arg.type),
266+
)}`;
265267
}
266268
return argDecl + printDeprecated(arg.deprecationReason);
267269
}

‎src/utilities/valueFromAST.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,13 @@ export function valueFromAST(
111111
for (const field of Object.values(type.getFields())) {
112112
const fieldNode = fieldNodes[field.name];
113113
if (!fieldNode || isMissingVariable(fieldNode.value, variables)) {
114-
if (field.defaultValue !== undefined) {
115-
coercedObj[field.name] = field.defaultValue;
114+
if (field.defaultValue) {
115+
// NOTE: This is an inlined version of "getCoercedDefaultValue" which
116+
// cannot be used directly since it would cause a circular dependency.
117+
coercedObj[field.name] =
118+
field.defaultValue.value !== undefined
119+
? field.defaultValue.value
120+
: valueFromAST(field.defaultValue.literal, field.type);
116121
} else if (isNonNullType(field.type)) {
117122
return; // Invalid: intentionally return no value.
118123
}

0 commit comments

Comments
 (0)
Please sign in to comment.