Skip to content

Commit 4b489ab

Browse files
committed
ease upgrade path for programmatic default values
1 parent 1d98a6a commit 4b489ab

28 files changed

+321
-222
lines changed

integrationTests/ts/basic-test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const queryType: GraphQLObjectType = new GraphQLObjectType({
1111
args: {
1212
who: {
1313
type: GraphQLString,
14-
defaultValue: 'World',
14+
externalDefaultValue: 'World',
1515
},
1616
},
1717
resolve(_root, args: { who: string }) {

integrationTests/ts/esm.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const queryType: GraphQLObjectType = new GraphQLObjectType({
1515
args: {
1616
who: {
1717
type: GraphQLString,
18-
defaultValue: 'World',
18+
externalDefaultValue: 'World',
1919
},
2020
},
2121
resolve(_root, args: { who: string }) {

src/execution/__tests__/executor-test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ describe('Execute: Handles basic execution tasks', () => {
246246
signature: {
247247
name: 'var',
248248
type: GraphQLString,
249-
defaultValue: undefined,
249+
externalDefaultValue: undefined,
250250
},
251251
value: 'abc',
252252
},

src/execution/__tests__/variables-test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,11 @@ const TestType = new GraphQLObjectType({
142142
}),
143143
fieldWithDefaultArgumentValue: fieldWithInputArg({
144144
type: GraphQLString,
145-
defaultValue: 'Hello World',
145+
externalDefaultValue: 'Hello World',
146146
}),
147147
fieldWithNonNullableStringInputAndDefaultArgumentValue: fieldWithInputArg({
148148
type: new GraphQLNonNull(GraphQLString),
149-
defaultValue: 'Hello World',
149+
externalDefaultValue: 'Hello World',
150150
}),
151151
fieldWithNestedInputObject: fieldWithInputArg({
152152
type: TestNestedInputObject,
@@ -187,7 +187,7 @@ const schema = new GraphQLSchema({
187187
type: new GraphQLNonNull(GraphQLBoolean),
188188
description: 'Skipped when true.',
189189
// default values will override operation variables in the setting of defined fragment variables that are not provided
190-
defaultValue: true,
190+
externalDefaultValue: true,
191191
},
192192
},
193193
}),

src/execution/getVariableSignature.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import { GraphQLError } from '../error/GraphQLError.js';
22

3-
import type { VariableDefinitionNode } from '../language/ast.js';
3+
import type {
4+
ConstValueNode,
5+
VariableDefinitionNode,
6+
} from '../language/ast.js';
47
import { print } from '../language/printer.js';
58

69
import { isInputType } from '../type/definition.js';
7-
import type {
8-
GraphQLDefaultValueUsage,
9-
GraphQLInputType,
10-
GraphQLSchema,
11-
} from '../type/index.js';
10+
import type { GraphQLInputType, GraphQLSchema } from '../type/index.js';
1211

1312
import { typeFromAST } from '../utilities/typeFromAST.js';
1413

@@ -21,7 +20,8 @@ import { typeFromAST } from '../utilities/typeFromAST.js';
2120
export interface GraphQLVariableSignature {
2221
name: string;
2322
type: GraphQLInputType;
24-
defaultValue: GraphQLDefaultValueUsage | undefined;
23+
defaultValue?: never;
24+
externalDefaultValue: { literal: ConstValueNode } | undefined;
2525
}
2626

2727
export function getVariableSignature(
@@ -46,6 +46,6 @@ export function getVariableSignature(
4646
return {
4747
name: varName,
4848
type: varType,
49-
defaultValue: defaultValue ? { literal: defaultValue } : undefined,
49+
externalDefaultValue: defaultValue ? { literal: defaultValue } : undefined,
5050
};
5151
}

src/execution/values.ts

+6-10
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,9 @@ export function experimentalGetArgumentValues(
226226
{ nodes: node },
227227
);
228228
}
229-
if (argDef.defaultValue) {
230-
coercedValues[name] = coerceDefaultValue(
231-
argDef.defaultValue,
232-
argDef.type,
233-
);
229+
const coercedDefaultValue = coerceDefaultValue(argDef);
230+
if (coercedDefaultValue !== undefined) {
231+
coercedValues[name] = coercedDefaultValue;
234232
}
235233
continue;
236234
}
@@ -249,11 +247,9 @@ export function experimentalGetArgumentValues(
249247
!Object.hasOwn(scopedVariableValues.coerced, variableName)) &&
250248
!isRequiredArgument(argDef)
251249
) {
252-
if (argDef.defaultValue) {
253-
coercedValues[name] = coerceDefaultValue(
254-
argDef.defaultValue,
255-
argDef.type,
256-
);
250+
const coercedDefaultValue = coerceDefaultValue(argDef);
251+
if (coercedDefaultValue !== undefined) {
252+
coercedValues[name] = coercedDefaultValue;
257253
}
258254
continue;
259255
}

src/type/__tests__/definition-test.ts

+15-7
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,8 @@ describe('Type System: Objects', () => {
195195
input: {
196196
description: 'Argument description.',
197197
type: ScalarType,
198-
defaultValue: 'DefaultValue',
198+
defaultValue: undefined,
199+
externalDefaultValue: 'DefaultValue',
199200
defaultValueLiteral: undefined,
200201
deprecationReason: 'Argument deprecation reason.',
201202
extensions: { someExtension: 'extension' },
@@ -343,6 +344,7 @@ describe('Type System: Objects', () => {
343344
description: undefined,
344345
type: ScalarType,
345346
defaultValue: undefined,
347+
externalDefaultValue: undefined,
346348
deprecationReason: undefined,
347349
extensions: {},
348350
astNode: undefined,
@@ -467,6 +469,7 @@ describe('Type System: Interfaces', () => {
467469
description: 'Argument description.',
468470
type: ScalarType,
469471
defaultValue: undefined,
472+
externalDefaultValue: undefined,
470473
defaultValueLiteral: dummyAny,
471474
deprecationReason: 'Argument deprecation reason.',
472475
extensions: { someExtension: 'extension' },
@@ -802,7 +805,8 @@ describe('Type System: Input Objects', () => {
802805
input: {
803806
description: 'Argument description.',
804807
type: ScalarType,
805-
defaultValue: 'DefaultValue',
808+
defaultValue: undefined,
809+
externalDefaultValue: 'DefaultValue',
806810
defaultValueLiteral: undefined,
807811
deprecationReason: 'Argument deprecation reason.',
808812
extensions: { someExtension: 'extension' },
@@ -832,6 +836,7 @@ describe('Type System: Input Objects', () => {
832836
description: undefined,
833837
type: ScalarType,
834838
defaultValue: undefined,
839+
externalDefaultValue: undefined,
835840
deprecationReason: undefined,
836841
extensions: {},
837842
astNode: undefined,
@@ -852,6 +857,7 @@ describe('Type System: Input Objects', () => {
852857
description: undefined,
853858
type: ScalarType,
854859
defaultValue: undefined,
860+
externalDefaultValue: undefined,
855861
extensions: {},
856862
deprecationReason: undefined,
857863
astNode: undefined,
@@ -901,14 +907,15 @@ describe('Type System: Input Objects', () => {
901907
const inputObjType = new GraphQLInputObjectType({
902908
name: 'SomeInputObject',
903909
fields: {
904-
f: { type: ScalarType, defaultValue: 3 },
910+
f: { type: ScalarType, externalDefaultValue: 3 },
905911
},
906912
});
907913
expect(inputObjType.getFields().f).to.deep.include({
908914
name: 'f',
909915
description: undefined,
910916
type: ScalarType,
911-
defaultValue: { value: 3 },
917+
defaultValue: undefined,
918+
externalDefaultValue: { value: 3 },
912919
deprecationReason: undefined,
913920
extensions: {},
914921
astNode: undefined,
@@ -929,7 +936,8 @@ describe('Type System: Input Objects', () => {
929936
name: 'f',
930937
description: undefined,
931938
type: ScalarType,
932-
defaultValue: { literal: { kind: 'IntValue', value: '3' } },
939+
defaultValue: undefined,
940+
externalDefaultValue: { literal: { kind: 'IntValue', value: '3' } },
933941
deprecationReason: undefined,
934942
extensions: {},
935943
astNode: undefined,
@@ -942,13 +950,13 @@ describe('Type System: Input Objects', () => {
942950
fields: {
943951
f: {
944952
type: ScalarType,
945-
defaultValue: 3,
953+
externalDefaultValue: 3,
946954
defaultValueLiteral: { kind: Kind.INT, value: '3' },
947955
},
948956
},
949957
});
950958
expect(() => inputObjType.getFields()).to.throw(
951-
'Argument "f" has both a defaultValue and a defaultValueLiteral property, but only one must be provided.',
959+
'Argument "f" has both an externalDefaultValue and a defaultValueLiteral property, but only one must be provided.',
952960
);
953961
});
954962
});

src/type/__tests__/directive-test.ts

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ describe('Type System: Directive', () => {
3939
description: undefined,
4040
type: GraphQLString,
4141
defaultValue: undefined,
42+
externalDefaultValue: undefined,
4243
deprecationReason: undefined,
4344
extensions: {},
4445
astNode: undefined,
@@ -48,6 +49,7 @@ describe('Type System: Directive', () => {
4849
description: undefined,
4950
type: GraphQLInt,
5051
defaultValue: undefined,
52+
externalDefaultValue: undefined,
5153
deprecationReason: undefined,
5254
extensions: {},
5355
astNode: undefined,

src/type/__tests__/enumType-test.ts

+27-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const QueryType = new GraphQLObjectType({
7171
args: {
7272
fromEnum: {
7373
type: ComplexEnum,
74-
defaultValue: 'ONE',
74+
externalDefaultValue: 'ONE',
7575
},
7676
provideGoodValue: { type: GraphQLBoolean },
7777
provideBadValue: { type: GraphQLBoolean },
@@ -90,6 +90,18 @@ const QueryType = new GraphQLObjectType({
9090
return fromEnum;
9191
},
9292
},
93+
complexEnumWithLegacyDefault: {
94+
type: ComplexEnum,
95+
args: {
96+
fromEnum: {
97+
type: ComplexEnum,
98+
defaultValue: Complex1,
99+
},
100+
},
101+
resolve(_source, { fromEnum }) {
102+
return fromEnum;
103+
},
104+
},
93105
thunkValuesString: {
94106
type: GraphQLString,
95107
args: {
@@ -438,6 +450,20 @@ describe('Type System: Enum Values', () => {
438450
});
439451
});
440452

453+
it('may be internally represented with complex values using legacy internal defaults', () => {
454+
const result = executeQuery(`
455+
{
456+
complexEnumWithLegacyDefault
457+
}
458+
`);
459+
460+
expectJSON(result).toDeepEqual({
461+
data: {
462+
complexEnumWithLegacyDefault: 'ONE',
463+
},
464+
});
465+
});
466+
441467
it('may have values specified via a callback', () => {
442468
const result = executeQuery('{ thunkValuesString(fromEnum: B) }');
443469

src/type/__tests__/predicate-test.ts

+14-12
Original file line numberDiff line numberDiff line change
@@ -568,15 +568,16 @@ describe('Type predicates', () => {
568568
describe('isRequiredArgument', () => {
569569
function buildArg(config: {
570570
type: GraphQLInputType;
571-
defaultValue?: unknown;
571+
externalDefaultValue?: unknown;
572572
}): GraphQLArgument {
573573
return {
574574
name: 'someArg',
575575
type: config.type,
576576
description: undefined,
577-
defaultValue:
578-
config.defaultValue !== undefined
579-
? { value: config.defaultValue }
577+
defaultValue: undefined,
578+
externalDefaultValue:
579+
config.externalDefaultValue !== undefined
580+
? { value: config.externalDefaultValue }
580581
: undefined,
581582
deprecationReason: null,
582583
extensions: Object.create(null),
@@ -599,7 +600,7 @@ describe('Type predicates', () => {
599600

600601
const optArg2 = buildArg({
601602
type: GraphQLString,
602-
defaultValue: null,
603+
externalDefaultValue: null,
603604
});
604605
expect(isRequiredArgument(optArg2)).to.equal(false);
605606

@@ -610,7 +611,7 @@ describe('Type predicates', () => {
610611

611612
const optArg4 = buildArg({
612613
type: new GraphQLNonNull(GraphQLString),
613-
defaultValue: 'default',
614+
externalDefaultValue: 'default',
614615
});
615616
expect(isRequiredArgument(optArg4)).to.equal(false);
616617
});
@@ -619,15 +620,16 @@ describe('Type predicates', () => {
619620
describe('isRequiredInputField', () => {
620621
function buildInputField(config: {
621622
type: GraphQLInputType;
622-
defaultValue?: unknown;
623+
externalDefaultValue?: unknown;
623624
}): GraphQLInputField {
624625
return {
625626
name: 'someInputField',
626627
type: config.type,
627628
description: undefined,
628-
defaultValue:
629-
config.defaultValue !== undefined
630-
? { value: config.defaultValue }
629+
defaultValue: undefined,
630+
externalDefaultValue:
631+
config.externalDefaultValue !== undefined
632+
? { value: config.externalDefaultValue }
631633
: undefined,
632634
deprecationReason: null,
633635
extensions: Object.create(null),
@@ -650,7 +652,7 @@ describe('Type predicates', () => {
650652

651653
const optField2 = buildInputField({
652654
type: GraphQLString,
653-
defaultValue: null,
655+
externalDefaultValue: null,
654656
});
655657
expect(isRequiredInputField(optField2)).to.equal(false);
656658

@@ -661,7 +663,7 @@ describe('Type predicates', () => {
661663

662664
const optField4 = buildInputField({
663665
type: new GraphQLNonNull(GraphQLString),
664-
defaultValue: 'default',
666+
externalDefaultValue: 'default',
665667
});
666668
expect(isRequiredInputField(optField4)).to.equal(false);
667669
});

0 commit comments

Comments
 (0)