Skip to content

Commit

Permalink
Throw when a field returning an @inaccessible type isn't marked @inac…
Browse files Browse the repository at this point in the history
  • Loading branch information
martijnwalraven committed Jul 8, 2021
1 parent c35efaa commit 01a3675
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('removeInaccessibleElements', () => {
}
type Query {
fooField: Foo
fooField: Foo @inaccessible
}
type Foo @inaccessible {
Expand Down Expand Up @@ -72,7 +72,7 @@ describe('removeInaccessibleElements', () => {
}
type Query {
fooField: Foo
fooField: Foo @inaccessible
}
interface Foo @inaccessible {
Expand Down Expand Up @@ -103,7 +103,7 @@ describe('removeInaccessibleElements', () => {
}
type Query {
fooField: Foo
fooField: Foo @inaccessible
}
union Foo @inaccessible = Bar | Baz
Expand All @@ -123,4 +123,35 @@ describe('removeInaccessibleElements', () => {
expect(schema.getType('Bar')).toBeDefined();
expect(schema.getType('Baz')).toBeDefined();
});

it(`throws when a field returning an @inaccessible type isn't marked @inaccessible itself`, () => {
let schema = buildSchema(`
directive @core(feature: String!) repeatable on SCHEMA
directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION
schema
@core(feature: "https://specs.apollo.dev/core/v0.1")
@core(feature: "https://specs.apollo.dev/inaccessible/v0.1")
{
query: Query
}
type Query {
fooField: Foo
}
type Foo @inaccessible {
someField: String
}
union Bar = Foo
`);

expect(() => {
removeInaccessibleElements(schema);
}).toThrow(
`Field Query.fooField returns an @inaccessible type without being marked @inaccessible itself`,
);
});
});
17 changes: 11 additions & 6 deletions query-planner-js/src/composedSchema/removeInaccessibleElements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
GraphQLNamedType,
isUnionType,
GraphQLUnionType,
GraphQLError,
GraphQLCompositeType,
} from 'graphql';
import { transformSchema } from 'apollo-graphql';

Expand Down Expand Up @@ -45,15 +47,15 @@ export function removeInaccessibleElements(

return new GraphQLObjectType({
...typeConfig,
fields: removeInaccessibleFields(typeConfig.fields),
fields: removeInaccessibleFields(type, typeConfig.fields),
interfaces: removeInaccessibleTypes(typeConfig.interfaces)
});
} else if (isInterfaceType(type)) {
const typeConfig = type.toConfig();

return new GraphQLInterfaceType({
...typeConfig,
fields: removeInaccessibleFields(typeConfig.fields),
fields: removeInaccessibleFields(type, typeConfig.fields),
interfaces: removeInaccessibleTypes(typeConfig.interfaces)
});
} else if (isUnionType(type)) {
Expand All @@ -70,21 +72,24 @@ export function removeInaccessibleElements(
});

function removeInaccessibleFields(
type: GraphQLCompositeType,
fieldMapConfig: GraphQLFieldConfigMap<any, any>,
) {
const newFieldMapConfig: GraphQLFieldConfigMap<any, any> =
Object.create(null);

for (const [fieldName, fieldConfig] of Object.entries(fieldMapConfig)) {
if (typesToRemove.has(getNamedType(fieldConfig.type))) {
continue;
}

if (
fieldConfig.astNode &&
hasDirective(inaccessibleDirective!, fieldConfig.astNode)
) {
continue;
} else if (typesToRemove.has(getNamedType(fieldConfig.type))) {
throw new GraphQLError(
`Field ${type.name}.${fieldName} returns ` +
`an @inaccessible type without being marked @inaccessible itself.`,
fieldConfig.astNode,
);
}

newFieldMapConfig[fieldName] = fieldConfig;
Expand Down

0 comments on commit 01a3675

Please sign in to comment.