Skip to content

Commit

Permalink
[federation] explude non-resolvable entities from Entity union
Browse files Browse the repository at this point in the history
  • Loading branch information
hayes committed Mar 1, 2024
1 parent 57269ec commit 0debcce
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 13 deletions.
5 changes: 5 additions & 0 deletions .changeset/popular-spiders-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@pothos/plugin-federation': patch
---

Exclude non resolveAble entities from Entity union
25 changes: 18 additions & 7 deletions packages/plugin-federation/src/global-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,25 @@ declare global {
param: Param,
options: {
key: KeySelection | KeySelection[];
resolvable?: boolean;
interfaceObject?: Param extends ObjectRef<unknown> ? boolean : never;
resolveReference: (
parent: KeySelection[typeof selectionShapeKey],
context: Types['Context'],
info: GraphQLResolveInfo,
) => MaybePromise<ShapeFromTypeParam<Types, Param, true>>;
},
} & (
| {
resolvable: false;
resolveReference?: (
parent: KeySelection[typeof selectionShapeKey],
context: Types['Context'],
info: GraphQLResolveInfo,
) => MaybePromise<ShapeFromTypeParam<Types, Param, true>>;
}
| {
resolvable?: true;
resolveReference: (
parent: KeySelection[typeof selectionShapeKey],
context: Types['Context'],
info: GraphQLResolveInfo,
) => MaybePromise<ShapeFromTypeParam<Types, Param, true>>;
}
),
) => void;
}

Expand Down
28 changes: 24 additions & 4 deletions packages/plugin-federation/src/schema-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,32 @@ import { entityMapping, getUsedDirectives, mergeDirectives } from './util';

const schemaBuilderProto = SchemaBuilder.prototype as PothosSchemaTypes.SchemaBuilder<SchemaTypes>;

export function hasDirective(type: GraphQLNamedType, directive: string) {
function hasResolvableKey(type: GraphQLNamedType) {
if (Array.isArray(type.extensions?.directives)) {
return type.extensions?.directives.some((d) => (d as { name: string }).name === directive);
return type.extensions?.directives.some(
(d: { name: string; args: Record<string, unknown> }) =>
d.name === 'key' && d.args.resolvable !== false,
);
}

return directive in ((type.extensions?.directives ?? {}) as {});
const directives = (type.extensions?.directives ?? {}) as {
key?:
| {
resolvable?: boolean;
}[]
| {
resolvable?: boolean;
};
};
if (!('key' in directives)) {
return false;
}

if (Array.isArray(directives.key)) {
return directives.key.some((d) => d.resolvable !== false);
}

return directives.key?.resolvable !== false;
}

schemaBuilderProto.selection = <Shape extends object>(selection: SelectionFromShape<Shape>) => ({
Expand Down Expand Up @@ -89,7 +109,7 @@ schemaBuilderProto.toSubGraphSchema = function toSubGraphSchema(
queryType?.toConfig();

const entityTypes = Object.values(types).filter(
(type) => isObjectType(type) && hasDirective(type, 'key'),
(type) => isObjectType(type) && hasResolvableKey(type),
);

const hasEntities = entityTypes.length > 0;
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-federation/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const entityMapping = new WeakMap<
key: Selection<object> | Selection<object>[];
resolvable?: boolean;
interfaceObject?: boolean;
resolveReference: (val: object, context: {}, info: GraphQLResolveInfo) => unknown;
resolveReference?: (val: object, context: {}, info: GraphQLResolveInfo) => unknown;
}
>
>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type Query {
}
type User
@key(fields: "id")
@key(fields: "id", resolvable: true)
{
id: ID
name: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const UserType = builder.objectRef<User>('User').implement({

builder.asEntity(UserType, {
key: builder.selection<{ id: string }>('id'),
resolvable: true,
resolveReference: (user) => users.find(({ id }) => user.id === id),
});

Expand Down

0 comments on commit 0debcce

Please sign in to comment.