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

Commit

Permalink
fix(healing): empty types should be pruned even if fields of those ty…
Browse files Browse the repository at this point in the history
…pes still exist

Fixes #37.
  • Loading branch information
yaacovCR committed Jan 16, 2020
1 parent e551855 commit 3545d73
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 11 deletions.
35 changes: 35 additions & 0 deletions src/test/testUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* tslint:disable:no-unused-expression */

import { expect } from 'chai';

import { healSchema } from '../utils';
import { makeExecutableSchema } from '../makeExecutableSchema';
import { GraphQLObjectType, GraphQLObjectTypeConfig } from 'graphql';

describe('heal', () => {
it('should prune empty types', () => {
const schema = makeExecutableSchema({
typeDefs: `
type WillBeEmptyObject {
willBeRemoved: String
}
type Query {
someQuery: WillBeEmptyObject
}
`
});
const originalTypeMap = schema.getTypeMap();

const config = originalTypeMap['WillBeEmptyObject'].toConfig() as GraphQLObjectTypeConfig<any, any>;
originalTypeMap['WillBeEmptyObject'] = new GraphQLObjectType({
...config,
fields: {},
});

healSchema(schema);

const healedTypeMap = schema.getTypeMap();
expect(healedTypeMap).not.to.haveOwnProperty('WillBeEmptyObject');
});
});
2 changes: 2 additions & 0 deletions src/test/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ import './testTransforms';
import './testExtensionExtraction';
import './testIntegration';
import './testUpload';
import './testUtils';

25 changes: 14 additions & 11 deletions src/utils/heal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,22 +208,25 @@ function pruneTypes(typeMap: NamedTypeMap, directives: ReadonlyArray<GraphQLDire
});

let prunedTypeMap = false;
updateEachKey(typeMap, (type, typeName) => {
let shouldPrune: boolean = false;
if (type instanceof GraphQLObjectType) {
each(typeMap, (type, typeName) => {
if (type instanceof GraphQLObjectType || type instanceof GraphQLInputObjectType) {
// prune types with no fields
shouldPrune = !Object.keys(type.getFields()).length;
if (!Object.keys(type.getFields()).length) {
typeMap[typeName] = null;
prunedTypeMap = true;
}
} else if (type instanceof GraphQLUnionType) {
// prune unions without underlying types
shouldPrune = !type.getTypes().length;
if (!type.getTypes().length) {
typeMap[typeName] = null;
prunedTypeMap = true;
}
} else if (type instanceof GraphQLInterfaceType) {
// prune interfaces without fields or without implementations
shouldPrune = !Object.keys(type.getFields()).length || !implementedInterfaces[type.name];
}

if (shouldPrune) {
prunedTypeMap = true;
return null;
if (!Object.keys(type.getFields()).length || !implementedInterfaces[type.name]) {
typeMap[typeName] = null;
prunedTypeMap = true;
}
}
});

Expand Down

0 comments on commit 3545d73

Please sign in to comment.