Skip to content

Commit

Permalink
refactor(graphql): abort js directive chain on null
Browse files Browse the repository at this point in the history
When one chain element returns null, abort execution, to retain
the same behaviour as in Drupal.
  • Loading branch information
pmelab committed Nov 15, 2023
1 parent 7c9aae6 commit ad2ab97
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
19 changes: 19 additions & 0 deletions packages/npm/@amazeelabs/graphql-directives/src/resolvers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ const echo: GraphQLFieldResolver<unknown, any, { msg: string }> = (
{ msg },
) => new Promise((resolve) => resolve(msg));

const resolveToNull: GraphQLFieldResolver<unknown, any, {}> = () =>
new Promise((resolve) => resolve(null));

const throwIfCalled: GraphQLFieldResolver<unknown, any, {}> = () =>
new Promise(() => {
throw 'parent is undefined';
});

describe('extractResolverMapping', () => {
it('extracts fields with attached directives', () => {
expect(extractResolverMapping(schema, { echo })).toEqual({
Expand Down Expand Up @@ -72,6 +80,17 @@ describe('executeResolver', () => {
'my value',
);
});

it('aborts a chain on null', async () => {
const resolver = buildResolver(
[
['resolveToNull', {}],
['throwIfCalled', {}],
],
{ resolveToNull, throwIfCalled },
);
expect(await resolver(undefined, {}, undefined, null as any)).toEqual(null);
});
});

describe('createResolveConfig', () => {
Expand Down
13 changes: 10 additions & 3 deletions packages/npm/@amazeelabs/graphql-directives/src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { flow, isString } from 'lodash-es';
export function createResolveConfig(
schema: GraphQLSchema,
directives: Record<string, GraphQLFieldResolver<any, any>>,
api?: any
api?: any,
): Record<string, Record<string, GraphQLFieldResolver<any, any>>> {
const mapping = extractResolverMapping(schema, directives);
const config: Record<
Expand All @@ -17,7 +17,11 @@ export function createResolveConfig(
config[type] = {};
}
Object.keys(mapping[type]).forEach((field) => {
config[type][field] = buildResolver(mapping[type][field], directives, api);
config[type][field] = buildResolver(
mapping[type][field],
directives,
api,
);
});
});
return config;
Expand Down Expand Up @@ -67,7 +71,7 @@ export function extractResolverMapping(
export function buildResolver(
config: Array<[string, Record<string, unknown>]>,
directives: Record<string, Function>,
api?: any
api?: any,
): GraphQLFieldResolver<any, any> {
return async (source, args, context, info) => {
const fns = [
Expand All @@ -77,6 +81,9 @@ export function buildResolver(
...config.map(([name, spec]) => {
return async (parent: any) => {
const value = await parent;
if (value === null) {
return null;
}
return directives[name](
value,
processDirectiveArguments(value, args, spec),
Expand Down

0 comments on commit ad2ab97

Please sign in to comment.