Skip to content

Commit 331dc77

Browse files
authored
Adds descriptions to the schema language via docblocks (#464)
This adds descriptions to the `buildASTSchema` (string->schema) and `schemaPrinter` (schema->string) via walking the previous full-line contiguous comment block. This is dependent on #463.
1 parent 9ae4399 commit 331dc77

File tree

6 files changed

+320
-45
lines changed

6 files changed

+320
-45
lines changed

src/utilities/__tests__/buildASTSchema-test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,36 @@ type Hello {
6666
expect(output).to.equal(body);
6767
});
6868

69+
it('Supports descriptions', () => {
70+
const body = `
71+
schema {
72+
query: Hello
73+
}
74+
75+
# This is a directive
76+
directive @foo(
77+
# It has an argument
78+
arg: Int
79+
) on FIELD
80+
81+
# With an enum
82+
enum Color {
83+
RED
84+
85+
# Not a creative color
86+
GREEN
87+
BLUE
88+
}
89+
90+
# What a great type
91+
type Hello {
92+
# And a field to boot
93+
str: String
94+
}
95+
`;
96+
const output = cycleOutput(body);
97+
expect(output).to.equal(body);
98+
});
6999

70100
it('Maintains @skip & @include', () => {
71101
const body = `

src/utilities/__tests__/extendSchema-test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,20 @@ describe('extendSchema', () => {
131131
} ]);
132132
});
133133

134+
it('can describe the extended fields', async () => {
135+
const ast = parse(`
136+
extend type Query {
137+
# New field description.
138+
newField: String
139+
}
140+
`);
141+
const extendedSchema = extendSchema(testSchema, ast);
142+
143+
expect(
144+
extendedSchema.getType('Query').getFields().newField.description
145+
).to.equal('New field description.');
146+
});
147+
134148
it('extends objects by adding new fields', () => {
135149
const ast = parse(`
136150
extend type Foo {

src/utilities/__tests__/schemaPrinter-test.js

Lines changed: 110 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -601,12 +601,32 @@ schema {
601601
query: Root
602602
}
603603
604-
directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
605-
606-
directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
607-
608-
directive @deprecated(reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE
609-
604+
# Directs the executor to include this field or fragment only when the \`if\` argument is true.
605+
directive @include(
606+
# Included when true.
607+
if: Boolean!
608+
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
609+
610+
# Directs the executor to skip this field or fragment when the \`if\` argument is true.
611+
directive @skip(
612+
# Skipped when true.
613+
if: Boolean!
614+
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
615+
616+
# Marks an element of a GraphQL schema as no longer supported.
617+
directive @deprecated(
618+
# Explains why this element was deprecated, usually also including a suggestion
619+
# for how to access supported similar data. Formatted in
620+
# [Markdown](https://daringfireball.net/projects/markdown/).
621+
reason: String = "No longer supported"
622+
) on FIELD_DEFINITION | ENUM_VALUE
623+
624+
# A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.
625+
#
626+
# In some cases, you need to provide options to alter GraphQL's execution behavior
627+
# in ways field arguments will not suffice, such as conditionally including or
628+
# skipping a field. Directives provide this by describing additional information
629+
# to the executor.
610630
type __Directive {
611631
name: String!
612632
description: String
@@ -617,34 +637,76 @@ type __Directive {
617637
onField: Boolean! @deprecated(reason: "Use \`locations\`.")
618638
}
619639
640+
# A Directive can be adjacent to many parts of the GraphQL language, a
641+
# __DirectiveLocation describes one such possible adjacencies.
620642
enum __DirectiveLocation {
643+
# Location adjacent to a query operation.
621644
QUERY
645+
646+
# Location adjacent to a mutation operation.
622647
MUTATION
648+
649+
# Location adjacent to a subscription operation.
623650
SUBSCRIPTION
651+
652+
# Location adjacent to a field.
624653
FIELD
654+
655+
# Location adjacent to a fragment definition.
625656
FRAGMENT_DEFINITION
657+
658+
# Location adjacent to a fragment spread.
626659
FRAGMENT_SPREAD
660+
661+
# Location adjacent to an inline fragment.
627662
INLINE_FRAGMENT
663+
664+
# Location adjacent to a schema definition.
628665
SCHEMA
666+
667+
# Location adjacent to a scalar definition.
629668
SCALAR
669+
670+
# Location adjacent to an object type definition.
630671
OBJECT
672+
673+
# Location adjacent to a field definition.
631674
FIELD_DEFINITION
675+
676+
# Location adjacent to an argument definition.
632677
ARGUMENT_DEFINITION
678+
679+
# Location adjacent to an interface definition.
633680
INTERFACE
681+
682+
# Location adjacent to a union definition.
634683
UNION
684+
685+
# Location adjacent to an enum definition.
635686
ENUM
687+
688+
# Location adjacent to an enum value definition.
636689
ENUM_VALUE
690+
691+
# Location adjacent to an input object type definition.
637692
INPUT_OBJECT
693+
694+
# Location adjacent to an input object field definition.
638695
INPUT_FIELD_DEFINITION
639696
}
640697
698+
# One possible value for a given Enum. Enum values are unique values, not a
699+
# placeholder for a string or numeric value. However an Enum value is returned in
700+
# a JSON response as a string.
641701
type __EnumValue {
642702
name: String!
643703
description: String
644704
isDeprecated: Boolean!
645705
deprecationReason: String
646706
}
647707
708+
# Object and Interface types are described by a list of Fields, each of which has
709+
# a name, potentially a list of arguments, and a return type.
648710
type __Field {
649711
name: String!
650712
description: String
@@ -654,21 +716,46 @@ type __Field {
654716
deprecationReason: String
655717
}
656718
719+
# Arguments provided to Fields or Directives and the input fields of an
720+
# InputObject are represented as Input Values which describe their type and
721+
# optionally a default value.
657722
type __InputValue {
658723
name: String!
659724
description: String
660725
type: __Type!
726+
727+
# A GraphQL-formatted string representing the default value for this input value.
661728
defaultValue: String
662729
}
663730
731+
# A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all
732+
# available types and directives on the server, as well as the entry points for
733+
# query, mutation, and subscription operations.
664734
type __Schema {
735+
# A list of all types supported by this server.
665736
types: [__Type!]!
737+
738+
# The type that query operations will be rooted at.
666739
queryType: __Type!
740+
741+
# If this server supports mutation, the type that mutation operations will be rooted at.
667742
mutationType: __Type
743+
744+
# If this server support subscription, the type that subscription operations will be rooted at.
668745
subscriptionType: __Type
746+
747+
# A list of all directives supported by this server.
669748
directives: [__Directive!]!
670749
}
671750
751+
# The fundamental unit of any GraphQL Schema is the type. There are many kinds of
752+
# types in GraphQL as represented by the \`__TypeKind\` enum.
753+
#
754+
# Depending on the kind of a type, certain fields describe information about that
755+
# type. Scalar types provide no information beyond a name and description, while
756+
# Enum types provide their values. Object and Interface types provide the fields
757+
# they describe. Abstract types, Union and Interface, provide the Object types
758+
# possible at runtime. List and NonNull types compose other types.
672759
type __Type {
673760
kind: __TypeKind!
674761
name: String
@@ -681,17 +768,34 @@ type __Type {
681768
ofType: __Type
682769
}
683770
771+
# An enum describing what kind of type a given \`__Type\` is.
684772
enum __TypeKind {
773+
# Indicates this type is a scalar.
685774
SCALAR
775+
776+
# Indicates this type is an object. \`fields\` and \`interfaces\` are valid fields.
686777
OBJECT
778+
779+
# Indicates this type is an interface. \`fields\` and \`possibleTypes\` are valid fields.
687780
INTERFACE
781+
782+
# Indicates this type is a union. \`possibleTypes\` is a valid field.
688783
UNION
784+
785+
# Indicates this type is an enum. \`enumValues\` is a valid field.
689786
ENUM
787+
788+
# Indicates this type is an input object. \`inputFields\` is a valid field.
690789
INPUT_OBJECT
790+
791+
# Indicates this type is a list. \`ofType\` is a valid field.
691792
LIST
793+
794+
# Indicates this type is a non-null. \`ofType\` is a valid field.
692795
NON_NULL
693796
}
694797
`;
798+
console.error(output); // eslint-disable-line
695799
expect(output).to.equal(introspectionSchema);
696800
});
697801
});

0 commit comments

Comments
 (0)