Skip to content
This repository has been archived by the owner on Apr 15, 2020. It is now read-only.

Commit

Permalink
chore(upstream): graphql v15 support
Browse files Browse the repository at this point in the history
 - add code support for interfaces that implement interfaces
 - changes one implementation within tests to implement the interface implementer :)
 - removes some verbose tests to make the above changes more facile
 - do not call extendSchema after buildSchema as both now process extensions
 - use getIntrospectionQuery method instead of introspectionQuery object
 - type/lint changes
  • Loading branch information
yaacovCR committed Jan 6, 2020
1 parent fff22aa commit 12277ba
Show file tree
Hide file tree
Showing 10 changed files with 26 additions and 220 deletions.
3 changes: 1 addition & 2 deletions .travis.yml
Expand Up @@ -8,7 +8,6 @@ install:
- npm install -g mocha coveralls
- npm install
- npm install graphql@$GRAPHQL_VERSION
- npm install @types/graphql@$TYPES_GRAPHQL_VERSION

script:
- npm test
Expand All @@ -20,4 +19,4 @@ script:
sudo: false

env:
- GRAPHQL_VERSION='^14.0' TYPES_GRAPHQL_VERSION='^14.0'
- GRAPHQL_VERSION='^15.0.0-rc.1'
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -62,7 +62,7 @@
"uuid": "^3.3.3"
},
"peerDependencies": {
"graphql": "^14.2.0"
"graphql": "^15.0.0-rc.1"
},
"devDependencies": {
"@types/apollo-upload-client": "^8.1.3",
Expand All @@ -82,7 +82,7 @@
"dateformat": "^3.0.3",
"express": "^4.17.1",
"express-graphql": "^0.9.0",
"graphql": "^14.5.8",
"graphql": "^15.0.0-rc.1",
"graphql-subscriptions": "^1.1.0",
"graphql-type-json": "^0.3.1",
"graphql-upload": "^9.0.0",
Expand Down
8 changes: 0 additions & 8 deletions src/generate/buildSchemaFromTypeDefinitions.ts
@@ -1,13 +1,11 @@
import {
parse,
extendSchema,
buildASTSchema,
GraphQLSchema,
DocumentNode,
} from 'graphql';
import { ITypeDefinitions, GraphQLParseOptions } from '../Interfaces';

import extractExtensionDefinitions from './extractExtensionDefinitions';
import concatenateTypeDefs from './concatenateTypeDefs';
import SchemaError from './SchemaError';

Expand Down Expand Up @@ -43,12 +41,6 @@ function buildSchemaFromTypeDefinitions(
backcompatOptions,
);

const extensionsAst = extractExtensionDefinitions(astDocument);
if (extensionsAst.definitions.length > 0) {
// TODO fix types https://github.com/apollographql/graphql-tools/issues/542
schema = (extendSchema as any)(schema, extensionsAst, backcompatOptions);
}

return schema;
}

Expand Down
4 changes: 2 additions & 2 deletions src/stitching/introspectSchema.ts
@@ -1,10 +1,10 @@
import { GraphQLSchema, DocumentNode } from 'graphql';
import { introspectionQuery, buildClientSchema, parse } from 'graphql';
import { getIntrospectionQuery, buildClientSchema, parse } from 'graphql';
import { ApolloLink } from 'apollo-link';
import { Fetcher } from '../Interfaces';
import linkToFetcher from './linkToFetcher';

const parsedIntrospectionQuery: DocumentNode = parse(introspectionQuery);
const parsedIntrospectionQuery: DocumentNode = parse(getIntrospectionQuery());

export default async function introspectSchema(
fetcher: ApolloLink | Fetcher,
Expand Down
4 changes: 4 additions & 0 deletions src/stitching/typeFromAST.ts
Expand Up @@ -83,6 +83,10 @@ function makeInterfaceType(
return new GraphQLInterfaceType({
name: node.name.value,
fields: () => makeFields(node.fields),
interfaces: () =>
node.interfaces.map(
iface => createNamedStub(iface.name.value, 'interface') as GraphQLInterfaceType,
),
description: getDescription(node, backcompatOptions),
resolveType: parent => resolveFromParentTypename(parent),
});
Expand Down
199 changes: 2 additions & 197 deletions src/test/testAlternateMergeSchemas.ts
Expand Up @@ -614,98 +614,11 @@ type Query {
});

describe('WrapType transform', () => {
let transformedPropertySchema: GraphQLSchema;

before(async () => {
transformedPropertySchema = transformSchema(propertySchema, [
it('should work', async () => {
const transformedPropertySchema = transformSchema(propertySchema, [
new WrapType('Query', 'Namespace_Query', 'namespace'),
]);
});

it('should modify the schema', () => {
/* tslint:disable:max-line-length */
expect(printSchema(transformedPropertySchema)).to.equal(`type Address {
street: String
city: String
state: String
zip: String
}
"""Simple fake datetime"""
scalar DateTime
input InputWithDefault {
test: String = "Foo"
}

"""
The \`JSON\` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
"""
scalar JSON
type Location {
name: String!
}
type Namespace_Query {
propertyById(id: ID!): Property
properties(limit: Int): [Property!]
contextTest(key: String!): String
dateTimeTest: DateTime
jsonTest(input: JSON): JSON
interfaceTest(kind: TestInterfaceKind): TestInterface
unionTest(output: String): TestUnion
errorTest: String
errorTestNonNull: String!
relay: Query!
defaultInputTest(input: InputWithDefault!): String
}
type Property {
id: ID!
name: String!
location: Location
address: Address
error: String
}
type Query {
namespace: Namespace_Query
}
type TestImpl1 implements TestInterface {
kind: TestInterfaceKind
testString: String
foo: String
}
type TestImpl2 implements TestInterface {
kind: TestInterfaceKind
testString: String
bar: String
}
interface TestInterface {
kind: TestInterfaceKind
testString: String
}
enum TestInterfaceKind {
ONE
TWO
}
union TestUnion = TestImpl1 | UnionImpl
type UnionImpl {
someField: String
}
`
/* tslint:enable:max-line-length */
);
});

it('should work', async () => {
const result = await graphql(
transformedPropertySchema,
`
Expand Down Expand Up @@ -759,114 +672,6 @@ type UnionImpl {
});
});

describe('ExtendSchema transform', () => {
let transformedPropertySchema: GraphQLSchema;

before(async () => {
transformedPropertySchema = transformSchema(propertySchema, [
new ExtendSchema({
typeDefs: `
extend type Property {
locationName: String
wrap: Wrap
}
type Wrap {
id: ID
name: String
}
`,
}),
]);
});

it('should work', () => {
/* tslint:disable:max-line-length */
expect(printSchema(transformedPropertySchema)).to.equal(`type Address {
street: String
city: String
state: String
zip: String
}
"""Simple fake datetime"""
scalar DateTime
input InputWithDefault {
test: String = "Foo"
}
"""
The \`JSON\` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
"""
scalar JSON
type Location {
name: String!
}
type Property {
id: ID!
name: String!
location: Location
address: Address
error: String
locationName: String
wrap: Wrap
}
type Query {
propertyById(id: ID!): Property
properties(limit: Int): [Property!]
contextTest(key: String!): String
dateTimeTest: DateTime
jsonTest(input: JSON): JSON
interfaceTest(kind: TestInterfaceKind): TestInterface
unionTest(output: String): TestUnion
errorTest: String
errorTestNonNull: String!
relay: Query!
defaultInputTest(input: InputWithDefault!): String
}
type TestImpl1 implements TestInterface {
kind: TestInterfaceKind
testString: String
foo: String
}
type TestImpl2 implements TestInterface {
kind: TestInterfaceKind
testString: String
bar: String
}
interface TestInterface {
kind: TestInterfaceKind
testString: String
}
enum TestInterfaceKind {
ONE
TWO
}
union TestUnion = TestImpl1 | UnionImpl
type UnionImpl {
someField: String
}
type Wrap {
id: ID
name: String
}
`
/* tslint:enable:max-line-length */
);
});
});

describe('schema transformation with extraction of nested fields', () => {
it('should work via ExtendSchema transform', async () => {
const transformedPropertySchema = transformSchema(propertySchema, [
Expand Down
2 changes: 1 addition & 1 deletion src/test/testSchemaGenerator.ts
Expand Up @@ -248,7 +248,7 @@ describe('generating schema from shorthand', () => {
},
query: {
name: 'RootQuery',
description: '',
description: <string>null,
fields: [
{
name: 'species',
Expand Down
7 changes: 6 additions & 1 deletion src/test/testingSchemas.ts
Expand Up @@ -276,7 +276,12 @@ const propertyRootTypeDefs = `
foo: String
}
type TestImpl2 implements TestInterface {
interface TestNestedInterface implements TestInterface {
kind: TestInterfaceKind
testString: String
}
type TestImpl2 implements TestNestedInterface & TestInterface {
kind: TestInterfaceKind
testString: String
bar: String
Expand Down
6 changes: 5 additions & 1 deletion src/utils/clone.ts
Expand Up @@ -24,7 +24,11 @@ export function cloneType(type: GraphQLNamedType): GraphQLNamedType {
interfaces: config.interfaces.slice(),
});
} else if (type instanceof GraphQLInterfaceType) {
return new GraphQLInterfaceType(type.toConfig());
const config = type.toConfig();
return new GraphQLInterfaceType({
...config,
interfaces: config.interfaces.slice(),
});
} else if (type instanceof GraphQLUnionType) {
const config = type.toConfig();
return new GraphQLUnionType({
Expand Down
9 changes: 3 additions & 6 deletions src/utils/heal.ts
Expand Up @@ -111,13 +111,10 @@ export function healTypes(
}

function heal(type: VisitableSchemaType) {
if (type instanceof GraphQLObjectType) {
if (type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType) {
healFields(type);
healInterfaces(type);

} else if (type instanceof GraphQLInterfaceType) {
healFields(type);

} else if (type instanceof GraphQLUnionType) {
healUnderlyingTypes(type);

Expand Down Expand Up @@ -145,7 +142,7 @@ export function healTypes(
});
}

function healInterfaces(type: GraphQLObjectType) {
function healInterfaces(type: GraphQLObjectType | GraphQLInterfaceType) {
updateEachKey(type.getInterfaces(), iface => {
const healedType = healType(iface);
return healedType;
Expand Down Expand Up @@ -200,7 +197,7 @@ export function healTypes(
function pruneTypes(typeMap: NamedTypeMap, directives: ReadonlyArray<GraphQLDirective>) {
const implementedInterfaces = {};
each(typeMap, (namedType, typeName) => {
if (namedType instanceof GraphQLObjectType) {
if (namedType instanceof GraphQLObjectType || namedType instanceof GraphQLInterfaceType) {
each(namedType.getInterfaces(), iface => {
implementedInterfaces[iface.name] = true;
});
Expand Down

0 comments on commit 12277ba

Please sign in to comment.