Skip to content

Commit 13111be

Browse files
committed
Add deprecated directive to arguments and input values
1 parent db214ce commit 13111be

File tree

6 files changed

+526
-14
lines changed

6 files changed

+526
-14
lines changed

src/type/__tests__/introspection-test.js

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,17 @@ describe('Introspection', () => {
325325
},
326326
{
327327
name: 'inputFields',
328-
args: [],
328+
args: [
329+
{
330+
name: 'includeDeprecated',
331+
type: {
332+
kind: 'SCALAR',
333+
name: 'Boolean',
334+
ofType: null,
335+
},
336+
defaultValue: 'false',
337+
},
338+
],
329339
type: {
330340
kind: 'LIST',
331341
name: null,
@@ -441,7 +451,17 @@ describe('Introspection', () => {
441451
},
442452
{
443453
name: 'args',
444-
args: [],
454+
args: [
455+
{
456+
name: 'includeDeprecated',
457+
type: {
458+
kind: 'SCALAR',
459+
name: 'Boolean',
460+
ofType: null,
461+
},
462+
defaultValue: 'false',
463+
},
464+
],
445465
type: {
446466
kind: 'NON_NULL',
447467
name: null,
@@ -565,6 +585,32 @@ describe('Introspection', () => {
565585
isDeprecated: false,
566586
deprecationReason: null,
567587
},
588+
{
589+
name: 'isDeprecated',
590+
args: [],
591+
type: {
592+
kind: 'NON_NULL',
593+
name: null,
594+
ofType: {
595+
kind: 'SCALAR',
596+
name: 'Boolean',
597+
ofType: null,
598+
},
599+
},
600+
isDeprecated: false,
601+
deprecationReason: null,
602+
},
603+
{
604+
name: 'deprecationReason',
605+
args: [],
606+
type: {
607+
kind: 'SCALAR',
608+
name: 'String',
609+
ofType: null,
610+
},
611+
isDeprecated: false,
612+
deprecationReason: null,
613+
},
568614
],
569615
inputFields: null,
570616
interfaces: [],
@@ -880,7 +926,12 @@ describe('Introspection', () => {
880926
{
881927
name: 'deprecated',
882928
isRepeatable: false,
883-
locations: ['FIELD_DEFINITION', 'ENUM_VALUE'],
929+
locations: [
930+
'FIELD_DEFINITION',
931+
'ENUM_VALUE',
932+
'ARGUMENT_DEFINITION',
933+
'INPUT_FIELD_DEFINITION',
934+
],
884935
args: [
885936
{
886937
defaultValue: '"No longer supported"',

src/type/definition.js

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,8 @@ export type GraphQLArgumentConfig = {|
948948
type: GraphQLInputType,
949949
defaultValue?: mixed,
950950
extensions?: ?ReadOnlyObjMapLike<mixed>,
951+
description?: ?string,
952+
deprecationReason?: ?string,
951953
astNode?: ?InputValueDefinitionNode,
952954
|};
953955

@@ -976,10 +978,13 @@ export type GraphQLArgument = {|
976978
name: string,
977979
description: ?string,
978980
type: GraphQLInputType,
979-
defaultValue: mixed,
981+
defaultValue?: mixed,
980982
extensions: ?ReadOnlyObjMap<mixed>,
981-
astNode: ?InputValueDefinitionNode,
982-
|};
983+
description?: ?string,
984+
isDeprecated?: boolean,
985+
deprecationReason?: ?string,
986+
astNode?: ?InputValueDefinitionNode,
987+
};
983988

984989
export function isRequiredArgument(arg: GraphQLArgument): boolean %checks {
985990
return isNonNullType(arg.type) && arg.defaultValue === undefined;
@@ -1522,7 +1527,15 @@ function defineInputFieldMap(
15221527
`${config.name}.${fieldName} field has a resolve property, but Input Types cannot define resolvers.`,
15231528
);
15241529

1530+
invariant(
1531+
!fieldConfig.hasOwnProperty('isDeprecated'),
1532+
`${config.name}.${fieldName} should provide "deprecationReason" ` +
1533+
'instead of "isDeprecated".',
1534+
);
1535+
15251536
return {
1537+
...fieldConfig,
1538+
isDeprecated: Boolean(fieldConfig.deprecationReason),
15261539
name: fieldName,
15271540
description: fieldConfig.description,
15281541
type: fieldConfig.type,
@@ -1547,6 +1560,8 @@ export type GraphQLInputFieldConfig = {|
15471560
type: GraphQLInputType,
15481561
defaultValue?: mixed,
15491562
extensions?: ?ReadOnlyObjMapLike<mixed>,
1563+
description?: ?string,
1564+
deprecationReason?: ?string,
15501565
astNode?: ?InputValueDefinitionNode,
15511566
|};
15521567

@@ -1556,10 +1571,13 @@ export type GraphQLInputField = {|
15561571
name: string,
15571572
description: ?string,
15581573
type: GraphQLInputType,
1559-
defaultValue: mixed,
1574+
defaultValue?: mixed,
1575+
description?: ?string,
1576+
isDeprecated?: boolean,
1577+
deprecationReason?: ?string,
15601578
extensions: ?ReadOnlyObjMap<mixed>,
1561-
astNode: ?InputValueDefinitionNode,
1562-
|};
1579+
astNode?: ?InputValueDefinitionNode,
1580+
};
15631581

15641582
export function isRequiredInputField(
15651583
field: GraphQLInputField,

src/type/directives.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,12 @@ export const DEFAULT_DEPRECATION_REASON = 'No longer supported';
181181
export const GraphQLDeprecatedDirective = new GraphQLDirective({
182182
name: 'deprecated',
183183
description: 'Marks an element of a GraphQL schema as no longer supported.',
184-
locations: [DirectiveLocation.FIELD_DEFINITION, DirectiveLocation.ENUM_VALUE],
184+
locations: [
185+
DirectiveLocation.FIELD_DEFINITION,
186+
DirectiveLocation.ENUM_VALUE,
187+
DirectiveLocation.ARGUMENT_DEFINITION,
188+
DirectiveLocation.INPUT_FIELD_DEFINITION,
189+
],
185190
args: {
186191
reason: {
187192
type: GraphQLString,

src/type/introspection.js

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,18 @@ export const __Type = new GraphQLObjectType({
233233
name: {
234234
type: GraphQLString,
235235
resolve: type => (type.name !== undefined ? type.name : undefined),
236+
},
237+
description: {
238+
type: GraphQLString,
239+
resolve: obj => obj.description,
240+
},
241+
fields: {
242+
type: GraphQLList(GraphQLNonNull(__Field)),
243+
args: {
244+
includeDeprecated: {
245+
type: GraphQLBoolean,
246+
defaultValue: false,
247+
},
236248
},
237249
description: {
238250
type: GraphQLString,
@@ -297,6 +309,23 @@ export const __Type = new GraphQLObjectType({
297309
ofType: {
298310
type: __Type,
299311
resolve: type => (type.ofType !== undefined ? type.ofType : undefined),
312+
},
313+
inputFields: {
314+
type: GraphQLList(GraphQLNonNull(__InputValue)),
315+
args: {
316+
includeDeprecated: {
317+
type: GraphQLBoolean,
318+
defaultValue: false,
319+
},
320+
},
321+
resolve(type, { includeDeprecated }) {
322+
if (isInputObjectType(type)) {
323+
let values = objectValues(type.getFields());
324+
if (!includeDeprecated) {
325+
values = values.filter(value => !value.deprecationReason);
326+
}
327+
return values;
328+
}
300329
},
301330
}: GraphQLFieldConfigMap<GraphQLType, mixed>),
302331
});
@@ -317,7 +346,22 @@ export const __Field = new GraphQLObjectType({
317346
},
318347
args: {
319348
type: GraphQLNonNull(GraphQLList(GraphQLNonNull(__InputValue))),
320-
resolve: field => field.args,
349+
args: {
350+
includeDeprecated: {
351+
type: GraphQLBoolean,
352+
defaultValue: false,
353+
},
354+
},
355+
// resolve: field => field.args || [],
356+
resolve(field, { includeDeprecated }) {
357+
let args = field.args || [];
358+
359+
if (!includeDeprecated) {
360+
args = args.filter(arg => !arg.deprecationReason);
361+
}
362+
363+
return args;
364+
}
321365
},
322366
type: {
323367
type: GraphQLNonNull(__Type),
@@ -362,6 +406,14 @@ export const __InputValue = new GraphQLObjectType({
362406
return valueAST ? print(valueAST) : null;
363407
},
364408
},
409+
isDeprecated: {
410+
type: GraphQLNonNull(GraphQLBoolean),
411+
resolve: obj => obj.isDeprecated,
412+
},
413+
deprecationReason: {
414+
type: GraphQLString,
415+
resolve: obj => obj.deprecationReason,
416+
},
365417
}: GraphQLFieldConfigMap<GraphQLInputField, mixed>),
366418
});
367419

0 commit comments

Comments
 (0)