Skip to content

Commit

Permalink
Add ability to remove types
Browse files Browse the repository at this point in the history
  • Loading branch information
freiksenet committed Dec 12, 2017
1 parent 98d1277 commit dae909b
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 7 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "graphql-tools",
"version": "2.12.0-alpha-2",
"version": "2.12.0-alpha-3",
"description": "Useful tools to create and manipulate GraphQL schemas.",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand Down
18 changes: 14 additions & 4 deletions src/stitching/mergeSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export default function mergeSchemas({
}

const resolveType = createResolveType(name => {
if (!types[name]) {
if (types[name] === undefined) {
throw new Error(`Can't find type ${name}.`);
}
return types[name];
Expand Down Expand Up @@ -234,13 +234,23 @@ export default function mergeSchemas({
}

function createResolveType(
getType: (name: string, type: GraphQLType) => GraphQLType,
getType: (name: string, type: GraphQLType) => GraphQLType | null,
): ResolveType<any> {
const resolveType = <T extends GraphQLType>(type: T): T => {
if (type instanceof GraphQLList) {
return new GraphQLList(resolveType(type.ofType)) as T;
const innerType = resolveType(type.ofType);
if (innerType === null) {
return null;
} else {
return new GraphQLList(innerType) as T;
}
} else if (type instanceof GraphQLNonNull) {
return new GraphQLNonNull(resolveType(type.ofType)) as T;
const innerType = resolveType(type.ofType);
if (innerType === null) {
return null;
} else {
return new GraphQLNonNull(innerType) as T;
}
} else if (isNamedType(type)) {
return getType(getNamedType(type).name, type) as T;
} else {
Expand Down
12 changes: 10 additions & 2 deletions src/stitching/schemaRecreation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ export function fieldMapToFieldConfigMap(
): GraphQLFieldConfigMap<any, any> {
const result: GraphQLFieldConfigMap<any, any> = {};
Object.keys(fields).forEach(name => {
result[name] = fieldToFieldConfig(fields[name], resolveType);
const field = fields[name];
const type = resolveType(field.type);
if (type !== null) {
result[name] = fieldToFieldConfig(fields[name], resolveType);
}
});
return result;
}
Expand Down Expand Up @@ -120,7 +124,11 @@ function inputFieldMapToFieldConfigMap(
): GraphQLInputFieldConfigMap {
const result: GraphQLInputFieldConfigMap = {};
Object.keys(fields).forEach(name => {
result[name] = inputFieldToFieldConfig(fields[name], resolveType);
const field = fields[name];
const type = resolveType(field.type);
if (type !== null) {
result[name] = inputFieldToFieldConfig(fields[name], resolveType);
}
});
return result;
}
Expand Down
116 changes: 116 additions & 0 deletions src/test/testMergeSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
parse,
ExecutionResult,
} from 'graphql';
import { VisitType } from '../Interfaces';
import mergeSchemas from '../stitching/mergeSchemas';
import {
propertySchema as localPropertySchema,
Expand Down Expand Up @@ -1810,3 +1811,118 @@ bookingById(id: $b1) {
});
});
});

describe('mergeSchema options', () => {
describe('should filter types', () => {
let schema: GraphQLSchema;

before(async () => {
const bookingSchema = await remoteBookingSchema;
const createTypeFilteringVisitTypes = (
typeNames: Array<string>,
): VisitType => {
return (name, candidates) => {
if (
['ID', 'String', 'DateTime'].includes(name) ||
typeNames.includes(name)
) {
return candidates[candidates.length - 1].type;
} else {
return null;
}
};
};
schema = mergeSchemas({
schemas: [
{
name: 'Booking',
schema: bookingSchema,
},
{
name: 'Selector',
schema: `
type Query {
bookingById(id: ID!): Booking
},
`,
},
],
visitType: createTypeFilteringVisitTypes(['Query', 'Booking']),
resolvers: {
Query: {
bookingById(parent, args, context, info) {
return info.mergeInfo.delegate(
'Booking',
'query',
'bookingById',
args,
context,
info,
);
},
},
},
});
});

it('should work normally', async () => {
const result = await graphql(
schema,
`
query {
bookingById(id: "b1") {
id
propertyId
startTime
endTime
}
}
`,
);

expect(result).to.deep.equal({
data: {
bookingById: {
endTime: '2016-06-03',
id: 'b1',
propertyId: 'p1',
startTime: '2016-05-04',
},
},
});
});

it('should error on removed types', async () => {
const result = await graphql(
schema,
`
query {
bookingById(id: "b1") {
id
propertyId
startTime
endTime
customer {
id
}
}
}
`,
);
expect(result).to.deep.equal({
errors: [
{
locations: [
{
column: 15,
line: 8,
},
],
message: 'Cannot query field "customer" on type "Booking".',
path: undefined,
},
],
});
});
});
});

0 comments on commit dae909b

Please sign in to comment.