Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GraphQLSchema types field #327

Merged
merged 1 commit into from
Mar 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/__tests__/starWarsIntrospectionTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ describe('Star Wars Introspection Tests', () => {
name: 'Character'
},
{
name: 'Human'
name: 'String'
},
{
name: 'String'
name: 'Human'
},
{
name: 'Droid'
Expand Down
3 changes: 2 additions & 1 deletion src/__tests__/starWarsSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,5 +270,6 @@ const queryType = new GraphQLObjectType({
* type we defined above) and export it.
*/
export const StarWarsSchema = new GraphQLSchema({
query: queryType
query: queryType,
types: [ humanType, droidType ]
});
11 changes: 4 additions & 7 deletions src/execution/__tests__/abstract.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ describe('Execute: Handles execution of abstract types', () => {
}
});

// Added to interface type when defined
/* eslint-disable no-unused-vars */

const DogType = new GraphQLObjectType({
name: 'Dog',
interfaces: [ PetType ],
Expand All @@ -74,8 +71,6 @@ describe('Execute: Handles execution of abstract types', () => {
}
});

/* eslint-enable no-unused-vars */

const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
Expand All @@ -87,7 +82,8 @@ describe('Execute: Handles execution of abstract types', () => {
}
}
}
})
}),
types: [ CatType, DogType ]
});

const query = `{
Expand Down Expand Up @@ -231,7 +227,8 @@ describe('Execute: Handles execution of abstract types', () => {
}
}
}
})
}),
types: [ CatType, DogType ]
});

const query = `{
Expand Down
5 changes: 3 additions & 2 deletions src/execution/__tests__/union-interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ const PersonType = new GraphQLObjectType({
});

const schema = new GraphQLSchema({
query: PersonType
query: PersonType,
types: [ PetType ]
});

const garfield = new Cat('Garfield', false);
Expand Down Expand Up @@ -143,9 +144,9 @@ describe('Execute: Union and intersection types', () => {
],
interfaces: null,
possibleTypes: [
{ name: 'Person' },
{ name: 'Dog' },
{ name: 'Cat' },
{ name: 'Person' }
],
enumValues: null,
inputFields: null
Expand Down
8 changes: 5 additions & 3 deletions src/execution/execute.js
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,8 @@ function doesFragmentConditionMatch(
return true;
}
if (isAbstractType(conditionalType)) {
return ((conditionalType: any): GraphQLAbstractType).isPossibleType(type);
const abstractType = ((conditionalType: any): GraphQLAbstractType);
return exeContext.schema.isPossibleType(abstractType, type);
}
return false;
}
Expand Down Expand Up @@ -806,7 +807,8 @@ function completeAbstractValue(
return null;
}

if (runtimeType && !returnType.isPossibleType(runtimeType)) {
const schema = exeContext.schema;
if (runtimeType && !schema.isPossibleType(returnType, runtimeType)) {
throw new GraphQLError(
`Runtime Object type "${runtimeType}" is not a possible type ` +
`for "${returnType}".`,
Expand Down Expand Up @@ -872,7 +874,7 @@ function defaultResolveTypeFn(
info: GraphQLResolveInfo,
abstractType: GraphQLAbstractType
): ?GraphQLObjectType {
const possibleTypes = abstractType.getPossibleTypes();
const possibleTypes = info.schema.getPossibleTypes(abstractType);
for (let i = 0; i < possibleTypes.length; i++) {
const type = possibleTypes[i];
if (typeof type.isTypeOf === 'function' && type.isTypeOf(value, info)) {
Expand Down
6 changes: 4 additions & 2 deletions src/type/__tests__/definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ describe('Type System: Example', () => {
fields: {
iface: { type: SomeInterface }
}
})
}),
types: [ SomeSubtype ]
});

expect(schema.getTypeMap().SomeSubtype).to.equal(SomeSubtype);
Expand Down Expand Up @@ -256,7 +257,8 @@ describe('Type System: Example', () => {
fields: {
iface: { type: SomeInterface }
}
})
}),
types: [ SomeSubtype ]
});

expect(schema.getTypeMap().SomeSubtype).to.equal(SomeSubtype);
Expand Down
17 changes: 8 additions & 9 deletions src/type/__tests__/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ function schemaWithFieldType(type) {
query: new GraphQLObjectType({
name: 'Query',
fields: { f: { type } }
})
}),
types: [ type ],
});
}

Expand Down Expand Up @@ -261,32 +262,29 @@ describe('Type System: A Schema must contain uniquely named types', () => {
fields: { f: { type: GraphQLString } },
});

/* eslint-disable no-unused-vars */

// Automatically included in Interface
const FirstBadObject = new GraphQLObjectType({
name: 'BadObject',
interfaces: [ AnotherInterface ],
fields: { f: { type: GraphQLString } },
});

// Automatically included in Interface
const SecondBadObject = new GraphQLObjectType({
name: 'BadObject',
interfaces: [ AnotherInterface ],
fields: { f: { type: GraphQLString } },
});

/* eslint-enable no-unused-vars */

const QueryType = new GraphQLObjectType({
name: 'Query',
fields: {
iface: { type: AnotherInterface },
}
});

return new GraphQLSchema({ query: QueryType });
return new GraphQLSchema({
query: QueryType,
types: [ FirstBadObject, SecondBadObject ]
});
}).to.throw(
'Schema must contain unique named types but contains multiple types ' +
'named "BadObject".'
Expand Down Expand Up @@ -1114,7 +1112,8 @@ describe('Type System: Objects can only implement interfaces', () => {
fields: {
f: { type: BadObjectType }
}
})
}),
types: [ BadObjectType ]
});
}

Expand Down
42 changes: 1 addition & 41 deletions src/type/definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

import invariant from '../jsutils/invariant';
import isNullish from '../jsutils/isNullish';
import keyMap from '../jsutils/keyMap';
import { ENUM } from '../language/kinds';
import { assertValidName } from '../utilities/assertValidName';
import type {
Expand Down Expand Up @@ -321,7 +320,6 @@ export class GraphQLObjectType {
}
this.isTypeOf = config.isTypeOf;
this._typeConfig = config;
addImplementationToInterfaces(this);
}

getFields(): GraphQLFieldDefinitionMap {
Expand Down Expand Up @@ -444,18 +442,6 @@ function isPlainObj(obj) {
return obj && typeof obj === 'object' && !Array.isArray(obj);
}

/**
* Update the interfaces to know about this implementation.
* This is an rare and unfortunate use of mutation in the type definition
* implementations, but avoids an expensive "getPossibleTypes"
* implementation for Interface types.
*/
function addImplementationToInterfaces(impl) {
impl.getInterfaces().forEach(type => {
type._implementations.push(impl);
});
}

export type GraphQLObjectTypeConfig = {
name: string;
interfaces?: GraphQLInterfacesThunk | Array<GraphQLInterfaceType>;
Expand Down Expand Up @@ -565,8 +551,6 @@ export class GraphQLInterfaceType {

_typeConfig: GraphQLInterfaceTypeConfig;
_fields: GraphQLFieldDefinitionMap;
_implementations: Array<GraphQLObjectType>;
_possibleTypes: { [typeName: string]: GraphQLObjectType };

constructor(config: GraphQLInterfaceTypeConfig) {
invariant(config.name, 'Type must be named.');
Expand All @@ -581,25 +565,13 @@ export class GraphQLInterfaceType {
}
this.resolveType = config.resolveType;
this._typeConfig = config;
this._implementations = [];
}

getFields(): GraphQLFieldDefinitionMap {
return this._fields ||
(this._fields = defineFieldMap(this, this._typeConfig.fields));
}

getPossibleTypes(): Array<GraphQLObjectType> {
return this._implementations;
}

isPossibleType(type: GraphQLObjectType): boolean {
const possibleTypes = this._possibleTypes || (this._possibleTypes =
keyMap(this.getPossibleTypes(), possibleType => possibleType.name)
);
return Boolean(possibleTypes[type.name]);
}

toString(): string {
return this.name;
}
Expand Down Expand Up @@ -686,22 +658,10 @@ export class GraphQLUnionType {
this._typeConfig = config;
}

getPossibleTypes(): Array<GraphQLObjectType> {
getTypes(): Array<GraphQLObjectType> {
return this._types;
}

isPossibleType(type: GraphQLObjectType): boolean {
let possibleTypeNames = this._possibleTypeNames;
if (!possibleTypeNames) {
this._possibleTypeNames = possibleTypeNames =
this.getPossibleTypes().reduce(
(map, possibleType) => ((map[possibleType.name] = true), map),
{}
);
}
return possibleTypeNames[type.name] === true;
}

toString(): string {
return this.name;
}
Expand Down
18 changes: 9 additions & 9 deletions src/type/introspection.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const __Schema = new GraphQLObjectType({
})
});

const __Directive = new GraphQLObjectType({
export const __Directive = new GraphQLObjectType({
name: '__Directive',
description:
'A Directive provides a way to describe alternate runtime execution and ' +
Expand Down Expand Up @@ -115,7 +115,7 @@ const __Directive = new GraphQLObjectType({
}),
});

const __DirectiveLocation = new GraphQLEnumType({
export const __DirectiveLocation = new GraphQLEnumType({
name: '__DirectiveLocation',
description:
'A Directive can be adjacent to many parts of the GraphQL language, a ' +
Expand Down Expand Up @@ -152,7 +152,7 @@ const __DirectiveLocation = new GraphQLEnumType({
}
});

const __Type = new GraphQLObjectType({
export const __Type = new GraphQLObjectType({
name: '__Type',
description:
'The fundamental unit of any GraphQL Schema is the type. There are ' +
Expand Down Expand Up @@ -218,10 +218,10 @@ const __Type = new GraphQLObjectType({
},
possibleTypes: {
type: new GraphQLList(new GraphQLNonNull(__Type)),
resolve(type) {
resolve(type, args, { schema }) {
if (type instanceof GraphQLInterfaceType ||
type instanceof GraphQLUnionType) {
return type.getPossibleTypes();
return schema.getPossibleTypes(type);
}
}
},
Expand Down Expand Up @@ -253,7 +253,7 @@ const __Type = new GraphQLObjectType({
})
});

const __Field = new GraphQLObjectType({
export const __Field = new GraphQLObjectType({
name: '__Field',
description:
'Object and Interface types are described by a list of Fields, each of ' +
Expand All @@ -277,7 +277,7 @@ const __Field = new GraphQLObjectType({
})
});

const __InputValue = new GraphQLObjectType({
export const __InputValue = new GraphQLObjectType({
name: '__InputValue',
description:
'Arguments provided to Fields or Directives and the input fields of an ' +
Expand All @@ -299,7 +299,7 @@ const __InputValue = new GraphQLObjectType({
})
});

const __EnumValue = new GraphQLObjectType({
export const __EnumValue = new GraphQLObjectType({
name: '__EnumValue',
description:
'One possible value for a given Enum. Enum values are unique values, not ' +
Expand Down Expand Up @@ -329,7 +329,7 @@ export const TypeKind = {
NON_NULL: 'NON_NULL',
};

const __TypeKind = new GraphQLEnumType({
export const __TypeKind = new GraphQLEnumType({
name: '__TypeKind',
description: 'An enum describing what kind of type a given `__Type` is.',
values: {
Expand Down
Loading