Skip to content

Commit

Permalink
introspection: Add missing support for deprecated input values (#2855)
Browse files Browse the repository at this point in the history
Fixes #2834
  • Loading branch information
IvanGoncharov committed Nov 24, 2020
1 parent 8c6e7c7 commit 3f129b5
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 4 deletions.
35 changes: 34 additions & 1 deletion src/utilities/__tests__/buildClientSchema-test.js
Expand Up @@ -486,6 +486,14 @@ describe('Type System: build schema from introspection', () => {

it('builds a schema aware of deprecation', () => {
const sdl = dedent`
directive @someDirective(
"""This is a shiny new argument"""
shinyArg: SomeInputObject
"""This was our design mistake :("""
oldArg: String @deprecated(reason: "Use shinyArg")
) on QUERY
enum Color {
"""So rosy"""
RED
Expand All @@ -500,13 +508,32 @@ describe('Type System: build schema from introspection', () => {
MAUVE @deprecated(reason: "No longer in fashion")
}
input SomeInputObject {
"""Nothing special about it, just deprecated for some unknown reason"""
oldField: String @deprecated(reason: "Don't use it, use newField instead!")
"""Same field but with a new name"""
newField: String
}
type Query {
"""This is a shiny string field"""
shinyString: String
"""This is a deprecated string field"""
deprecatedString: String @deprecated(reason: "Use shinyString")
"""Color of a week"""
color: Color
"""Some random field"""
someField(
"""This is a shiny new argument"""
shinyArg: SomeInputObject
"""This was our design mistake :("""
oldArg: String @deprecated(reason: "Use shinyArg")
): String
}
`;

Expand All @@ -515,8 +542,14 @@ describe('Type System: build schema from introspection', () => {

it('builds a schema with empty deprecation reasons', () => {
const sdl = dedent`
directive @someDirective(someArg: SomeInputObject @deprecated(reason: "")) on QUERY
type Query {
someField: String @deprecated(reason: "")
someField(someArg: SomeInputObject @deprecated(reason: "")): SomeEnum @deprecated(reason: "")
}
input SomeInputObject {
someInputField: String @deprecated(reason: "")
}
enum SomeEnum {
Expand Down
42 changes: 42 additions & 0 deletions src/utilities/__tests__/getIntrospectionQuery-test.js
Expand Up @@ -74,4 +74,46 @@ describe('getIntrospectionQuery', () => {
'specifiedByUrl',
);
});

it('include "isDeprecated" field on input values', () => {
expectIntrospectionQuery().toMatch('isDeprecated', 2);

expectIntrospectionQuery({ inputValueDeprecation: true }).toMatch(
'isDeprecated',
3,
);

expectIntrospectionQuery({ inputValueDeprecation: false }).toMatch(
'isDeprecated',
2,
);
});

it('include "deprecationReason" field on input values', () => {
expectIntrospectionQuery().toMatch('deprecationReason', 2);

expectIntrospectionQuery({ inputValueDeprecation: true }).toMatch(
'deprecationReason',
3,
);

expectIntrospectionQuery({ inputValueDeprecation: false }).toMatch(
'deprecationReason',
2,
);
});

it('include deprecated input field and args', () => {
expectIntrospectionQuery().toMatch('includeDeprecated: true', 2);

expectIntrospectionQuery({ inputValueDeprecation: true }).toMatch(
'includeDeprecated: true',
5,
);

expectIntrospectionQuery({ inputValueDeprecation: false }).toMatch(
'includeDeprecated: true',
2,
);
});
});
1 change: 1 addition & 0 deletions src/utilities/buildClientSchema.js
Expand Up @@ -377,6 +377,7 @@ export function buildClientSchema(
description: inputValueIntrospection.description,
type,
defaultValue,
deprecationReason: inputValueIntrospection.deprecationReason,
};
}

Expand Down
6 changes: 6 additions & 0 deletions src/utilities/getIntrospectionQuery.d.ts
Expand Up @@ -18,6 +18,10 @@ export interface IntrospectionOptions {
// Whether to include `description` field on schema.
// Default: false
schemaDescription?: boolean;

// Whether target GraphQL server support deprecation of input values.
// Default: false
inputValueDeprecation?: boolean;
}

export function getIntrospectionQuery(options?: IntrospectionOptions): string;
Expand Down Expand Up @@ -169,6 +173,8 @@ export interface IntrospectionInputValue {
readonly description?: Maybe<string>;
readonly type: IntrospectionInputTypeRef;
readonly defaultValue?: Maybe<string>;
readonly isDeprecated?: boolean;
readonly deprecationReason?: Maybe<string>;
}

export interface IntrospectionEnumValue {
Expand Down
19 changes: 16 additions & 3 deletions src/utilities/getIntrospectionQuery.js
Expand Up @@ -16,6 +16,10 @@ export type IntrospectionOptions = {|
// Whether to include `description` field on schema.
// Default: false
schemaDescription?: boolean,

// Whether target GraphQL server support deprecation of input values.
// Default: false
inputValueDeprecation?: boolean,
|};

export function getIntrospectionQuery(options?: IntrospectionOptions): string {
Expand All @@ -24,6 +28,7 @@ export function getIntrospectionQuery(options?: IntrospectionOptions): string {
specifiedByUrl: false,
directiveIsRepeatable: false,
schemaDescription: false,
inputValueDeprecation: false,
...options,
};

Expand All @@ -38,6 +43,10 @@ export function getIntrospectionQuery(options?: IntrospectionOptions): string {
? descriptions
: '';

function inputDeprecation(str) {
return optionsWithDefault.inputValueDeprecation ? str : '';
}

return `
query IntrospectionQuery {
__schema {
Expand All @@ -53,7 +62,7 @@ export function getIntrospectionQuery(options?: IntrospectionOptions): string {
${descriptions}
${directiveIsRepeatable}
locations
args {
args${inputDeprecation('(includeDeprecated: true)')} {
...InputValue
}
}
Expand All @@ -68,7 +77,7 @@ export function getIntrospectionQuery(options?: IntrospectionOptions): string {
fields(includeDeprecated: true) {
name
${descriptions}
args {
args${inputDeprecation('(includeDeprecated: true)')} {
...InputValue
}
type {
Expand All @@ -77,7 +86,7 @@ export function getIntrospectionQuery(options?: IntrospectionOptions): string {
isDeprecated
deprecationReason
}
inputFields {
inputFields${inputDeprecation('(includeDeprecated: true)')} {
...InputValue
}
interfaces {
Expand All @@ -99,6 +108,8 @@ export function getIntrospectionQuery(options?: IntrospectionOptions): string {
${descriptions}
type { ...TypeRef }
defaultValue
${inputDeprecation('isDeprecated')}
${inputDeprecation('deprecationReason')}
}
fragment TypeRef on __Type {
Expand Down Expand Up @@ -280,6 +291,8 @@ export type IntrospectionInputValue = {|
+description?: ?string,
+type: IntrospectionInputTypeRef,
+defaultValue: ?string,
+isDeprecated?: boolean,
+deprecationReason?: ?string,
|};

export type IntrospectionEnumValue = {|
Expand Down
1 change: 1 addition & 0 deletions src/utilities/introspectionFromSchema.js
Expand Up @@ -29,6 +29,7 @@ export function introspectionFromSchema(
specifiedByUrl: true,
directiveIsRepeatable: true,
schemaDescription: true,
inputValueDeprecation: true,
...options,
};

Expand Down

0 comments on commit 3f129b5

Please sign in to comment.