Skip to content

Commit a68212e

Browse files
committed
[RFC] Type extension syntax
This proposal introduces a syntactic addition for client-side tools that perform code generation. It allows those tools to describe "extensions" to the server-supplied GraphQL schema. Tools may then use this information to generate client side Plain-Ol'-Data types which include these client-side-only extensions. The syntax I'm proposing is: ``` TypeExtensionDefinition : `extend` ObjectDefinition ``` An example of this might look like: ``` type User { name: String birthday: Int } extend type User { age: Int } ``` While I could have proposed simply `extend User { ... }`, I chose to fully reuse the ObjectDefinition rule to preserve the future ability to expand this syntax to include extending interfaces, enums, and other types.
1 parent 0800c34 commit a68212e

File tree

5 files changed

+44
-0
lines changed

5 files changed

+44
-0
lines changed

src/language/ast.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export type Node = Name
5555
| EnumTypeDefinition
5656
| EnumValueDefinition
5757
| InputObjectTypeDefinition
58+
| TypeExtensionDefinition
5859

5960
// Name
6061

@@ -75,6 +76,7 @@ export type Document = {
7576
export type Definition = OperationDefinition
7677
| FragmentDefinition
7778
| TypeDefinition
79+
| TypeExtensionDefinition
7880

7981
export type OperationDefinition = {
8082
kind: 'OperationDefinition';
@@ -323,3 +325,11 @@ export type InputObjectTypeDefinition = {
323325
name: Name;
324326
fields: Array<InputValueDefinition>;
325327
}
328+
329+
// Type Extention
330+
331+
export type TypeExtensionDefinition = {
332+
kind: 'TypeExtensionDefinition';
333+
loc?: ?Location;
334+
definition: ObjectTypeDefinition;
335+
}

src/language/kinds.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,7 @@ export const SCALAR_TYPE_DEFINITION = 'ScalarTypeDefinition';
5959
export const ENUM_TYPE_DEFINITION = 'EnumTypeDefinition';
6060
export const ENUM_VALUE_DEFINITION = 'EnumValueDefinition';
6161
export const INPUT_OBJECT_TYPE_DEFINITION = 'InputObjectTypeDefinition';
62+
63+
// Type Extension Definitions
64+
65+
export const TYPE_EXTENSION_DEFINITION = 'TypeExtensionDefinition';

src/language/parser.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ import type {
4848
EnumTypeDefinition,
4949
EnumValueDefinition,
5050
InputObjectTypeDefinition,
51+
52+
TypeExtensionDefinition,
5153
} from './ast';
5254

5355
import {
@@ -89,6 +91,8 @@ import {
8991
ENUM_TYPE_DEFINITION,
9092
ENUM_VALUE_DEFINITION,
9193
INPUT_OBJECT_TYPE_DEFINITION,
94+
95+
TYPE_EXTENTION_DEFINITION,
9296
} from './kinds';
9397

9498

@@ -177,6 +181,7 @@ function parseDocument(parser): Document {
177181
* - OperationDefinition
178182
* - FragmentDefinition
179183
* - TypeDefinition
184+
* - TypeExtensionDefinition
180185
*/
181186
function parseDefinition(parser): Definition {
182187
if (peek(parser, TokenKind.BRACE_L)) {
@@ -196,6 +201,8 @@ function parseDefinition(parser): Definition {
196201
case 'scalar':
197202
case 'enum':
198203
case 'input': return parseTypeDefinition(parser);
204+
205+
case 'extend': return parseTypeExtensionDefinition(parser);
199206
}
200207
}
201208

@@ -883,6 +890,23 @@ function parseInputObjectTypeDefinition(parser): InputObjectTypeDefinition {
883890
}
884891

885892

893+
// Implements the parsing rules for Type Extension
894+
895+
/**
896+
* TypeExtensionDefinition : extend ObjectTypeDefinition
897+
*/
898+
function parseTypeExtensionDefinition(parser): TypeExtensionDefinition {
899+
var start = parser.token.start;
900+
expectKeyword(parser, 'extend');
901+
var definition = parseObjectTypeDefinition(parser);
902+
return {
903+
kind: TYPE_EXTENTION_DEFINITION,
904+
definition,
905+
loc: loc(parser, start),
906+
};
907+
}
908+
909+
886910
// Core parsing utility functions
887911

888912
/**

src/language/printer.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ var printDocASTReducer = {
115115

116116
InputObjectTypeDefinition: ({ name, fields }) =>
117117
`input ${name} ${block(fields)}`,
118+
119+
// Type Extension Definition
120+
121+
TypeExtensionDefinition: ({ definition }) => `extend ${definition}`,
118122
};
119123

120124
/**

src/language/visitor.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ export var QueryDocumentKeys = {
4747
EnumTypeDefinition: [ 'name', 'values' ],
4848
EnumValueDefinition: [ 'name' ],
4949
InputObjectTypeDefinition: [ 'name', 'fields' ],
50+
51+
TypeExtensionDefinition: [ 'definition' ],
5052
};
5153

5254
export const BREAK = {};

0 commit comments

Comments
 (0)