Skip to content

Commit

Permalink
RFC: Directive location: schema definition
Browse files Browse the repository at this point in the history
This allows directives to be defined on schema definitions.
  • Loading branch information
leebyron committed May 6, 2016
1 parent 1b6824b commit 664ea8b
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/language/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ export type TypeSystemDefinition = SchemaDefinition
export type SchemaDefinition = {
kind: 'SchemaDefinition';
loc?: ?Location;
directives: Array<Directive>;
operationTypes: Array<OperationTypeDefinition>;
}

Expand Down
4 changes: 3 additions & 1 deletion src/language/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -701,13 +701,14 @@ function parseTypeSystemDefinition(parser: Parser): TypeSystemDefinition {
}

/**
* SchemaDefinition : schema { OperationTypeDefinition+ }
* SchemaDefinition : schema Directives? { OperationTypeDefinition+ }
*
* OperationTypeDefinition : OperationType : NamedType
*/
function parseSchemaDefinition(parser: Parser): SchemaDefinition {
const start = parser.token.start;
expectKeyword(parser, 'schema');
const directives = parseDirectives(parser);
const operationTypes = many(
parser,
TokenKind.BRACE_L,
Expand All @@ -716,6 +717,7 @@ function parseSchemaDefinition(parser: Parser): SchemaDefinition {
);
return {
kind: SCHEMA_DEFINITION,
directives,
operationTypes,
loc: loc(parser, start),
};
Expand Down
8 changes: 6 additions & 2 deletions src/language/printer.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,12 @@ const printDocASTReducer = {

// Type System Definitions

SchemaDefinition: ({ operationTypes }) =>
'schema ' + block(operationTypes),
SchemaDefinition: ({ directives, operationTypes }) =>
join([
'schema',
join(directives, ' '),
block(operationTypes),
], ' '),

OperationTypeDefinition: ({ operation, type }) =>
operation + ': ' + type,
Expand Down
2 changes: 1 addition & 1 deletion src/language/visitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const QueryDocumentKeys = {
ListType: [ 'type' ],
NonNullType: [ 'type' ],

SchemaDefinition: [ 'operationTypes' ],
SchemaDefinition: [ 'directives', 'operationTypes' ],
OperationTypeDefinition: [ 'type' ],

ScalarTypeDefinition: [ 'name', 'directives' ],
Expand Down
1 change: 1 addition & 0 deletions src/type/directives.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const DirectiveLocation = {
FRAGMENT_SPREAD: 'FRAGMENT_SPREAD',
INLINE_FRAGMENT: 'INLINE_FRAGMENT',
// Schema Definitions
SCHEMA: 'SCHEMA',
SCALAR: 'SCALAR',
OBJECT: 'OBJECT',
FIELD_DEFINITION: 'FIELD_DEFINITION',
Expand Down
4 changes: 4 additions & 0 deletions src/type/introspection.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ export const __DirectiveLocation = new GraphQLEnumType({
value: DirectiveLocation.INLINE_FRAGMENT,
description: 'Location adjacent to an inline fragment.'
},
SCHEMA: {
value: DirectiveLocation.SCHEMA,
description: 'Location adjacent to a schema definition.'
},
SCALAR: {
value: DirectiveLocation.SCALAR,
description: 'Location adjacent to a scalar definition.'
Expand Down
1 change: 1 addition & 0 deletions src/utilities/__tests__/schemaPrinter-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ enum __DirectiveLocation {
FRAGMENT_DEFINITION
FRAGMENT_SPREAD
INLINE_FRAGMENT
SCHEMA
SCALAR
OBJECT
FIELD_DEFINITION
Expand Down
9 changes: 9 additions & 0 deletions src/validation/__tests__/KnownDirectives-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ describe('Validate: Known directives', () => {
input MyInput @onInputObject {
myField: Int @onInputFieldDefinition
}
schema @onSchema {
query: MyQuery
}
`);
});

Expand All @@ -173,6 +177,10 @@ describe('Validate: Known directives', () => {
input MyInput @onEnum {
myField: Int @onArgumentDefinition
}
schema @onObject {
query: MyQuery
}
`, [
misplacedDirective('onInterface', 'OBJECT', 2, 43),
misplacedDirective('onInputFieldDefinition', 'ARGUMENT_DEFINITION', 3, 30),
Expand All @@ -186,6 +194,7 @@ describe('Validate: Known directives', () => {
misplacedDirective('onUnion', 'ENUM_VALUE', 15, 20),
misplacedDirective('onEnum', 'INPUT_OBJECT', 18, 23),
misplacedDirective('onArgumentDefinition', 'INPUT_FIELD_DEFINITION', 19, 24),
misplacedDirective('onObject', 'SCHEMA', 22, 16),
]);
});

Expand Down
4 changes: 4 additions & 0 deletions src/validation/__tests__/harness.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,10 @@ export const testSchema = new GraphQLSchema({
name: 'onInlineFragment',
locations: [ 'INLINE_FRAGMENT' ],
}),
new GraphQLDirective({
name: 'onSchema',
locations: [ 'SCHEMA' ],
}),
new GraphQLDirective({
name: 'onScalar',
locations: [ 'SCALAR' ],
Expand Down
12 changes: 7 additions & 5 deletions src/validation/rules/KnownDirectives.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ import {
FRAGMENT_SPREAD,
INLINE_FRAGMENT,
OPERATION_DEFINITION,
ENUM_TYPE_DEFINITION,
ENUM_VALUE_DEFINITION,
SCHEMA_DEFINITION,
SCALAR_TYPE_DEFINITION,
OBJECT_TYPE_DEFINITION,
FIELD_DEFINITION,
INPUT_OBJECT_TYPE_DEFINITION,
INPUT_VALUE_DEFINITION,
INTERFACE_TYPE_DEFINITION,
OBJECT_TYPE_DEFINITION,
SCALAR_TYPE_DEFINITION,
UNION_TYPE_DEFINITION,
ENUM_TYPE_DEFINITION,
ENUM_VALUE_DEFINITION,
INPUT_OBJECT_TYPE_DEFINITION,
} from '../../language/kinds';
import { DirectiveLocation } from '../../type/directives';

Expand Down Expand Up @@ -91,6 +92,7 @@ function getDirectiveLocationForASTPath(ancestors) {
case FRAGMENT_SPREAD: return DirectiveLocation.FRAGMENT_SPREAD;
case INLINE_FRAGMENT: return DirectiveLocation.INLINE_FRAGMENT;
case FRAGMENT_DEFINITION: return DirectiveLocation.FRAGMENT_DEFINITION;
case SCHEMA_DEFINITION: return DirectiveLocation.SCHEMA;
case SCALAR_TYPE_DEFINITION: return DirectiveLocation.SCALAR;
case OBJECT_TYPE_DEFINITION: return DirectiveLocation.OBJECT;
case FIELD_DEFINITION: return DirectiveLocation.FIELD_DEFINITION;
Expand Down

0 comments on commit 664ea8b

Please sign in to comment.