Skip to content

Commit 63929b1

Browse files
committed
on perform plugin
1 parent dbfb294 commit 63929b1

File tree

4 files changed

+87
-14
lines changed

4 files changed

+87
-14
lines changed

packages/core/src/orchestrator.ts

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ import {
3131
ValidateFunction,
3232
ExecutionResult,
3333
PerformFunction,
34+
OnPerformHook,
35+
OnPerformHookResult,
36+
OnPerformDoneHook,
3437
} from '@envelop/types';
3538
import {
3639
errorAsyncIterator,
@@ -118,15 +121,17 @@ export function createEnvelopOrchestrator<PluginsContext extends DefaultContext>
118121
subscribe: [] as OnSubscribeHook<any>[],
119122
execute: [] as OnExecuteHook<any>[],
120123
context: [] as OnContextBuildingHook<any>[],
124+
perform: [] as OnPerformHook<any>[],
121125
};
122126

123-
for (const { onContextBuilding, onExecute, onParse, onSubscribe, onValidate, onEnveloped } of plugins) {
127+
for (const { onContextBuilding, onExecute, onParse, onSubscribe, onValidate, onEnveloped, onPerform } of plugins) {
124128
onEnveloped && beforeCallbacks.init.push(onEnveloped);
125129
onContextBuilding && beforeCallbacks.context.push(onContextBuilding);
126130
onExecute && beforeCallbacks.execute.push(onExecute);
127131
onParse && beforeCallbacks.parse.push(onParse);
128132
onSubscribe && beforeCallbacks.subscribe.push(onSubscribe);
129133
onValidate && beforeCallbacks.validate.push(onValidate);
134+
onPerform && beforeCallbacks.perform.push(onPerform);
130135
}
131136

132137
const init: EnvelopOrchestrator['init'] = initialContext => {
@@ -565,6 +570,24 @@ export function createEnvelopOrchestrator<PluginsContext extends DefaultContext>
565570
const contextFactory = customContextFactory(initialContext);
566571

567572
return async (params, contextExtension) => {
573+
const context = await contextFactory(contextExtension);
574+
575+
const doneFns: OnPerformDoneHook[] = [];
576+
for (const onPerform of beforeCallbacks.perform) {
577+
const result = await onPerform({
578+
context,
579+
extendContext: extension => {
580+
Object.assign(context, extension);
581+
},
582+
params,
583+
setParams: newParams => {
584+
params = newParams;
585+
},
586+
});
587+
588+
result?.onPerformDone && doneFns.push(result.onPerformDone);
589+
}
590+
568591
let document;
569592
try {
570593
document = parse(params.query);
@@ -577,23 +600,33 @@ export function createEnvelopOrchestrator<PluginsContext extends DefaultContext>
577600
return { errors: validationErrors };
578601
}
579602

580-
const context = await contextFactory(contextExtension);
581-
603+
let result;
582604
if (isSubscriptionOperation(document, params.operationName)) {
583-
return await customSubscribe({
605+
result = await customSubscribe({
606+
document,
607+
schema,
608+
variableValues: params.variables,
609+
contextValue: context,
610+
});
611+
} else {
612+
result = await customExecute({
584613
document,
585614
schema,
586615
variableValues: params.variables,
587616
contextValue: context,
588617
});
589618
}
590619

591-
return await customExecute({
592-
document,
593-
schema,
594-
variableValues: params.variables,
595-
contextValue: context,
596-
});
620+
for (const doneFn of doneFns) {
621+
doneFn({
622+
result,
623+
setResult: newResult => {
624+
result = newResult;
625+
},
626+
});
627+
}
628+
629+
return result;
597630
};
598631
};
599632

packages/core/test/perform.spec.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { parse, validate, execute, subscribe } from 'graphql';
2-
import { envelop, useSchema } from '../src/index.js';
2+
import { envelop, OnPerformDoneHook, OnPerformHook, useSchema } from '../src/index.js';
33
import { assertSingleExecutionValue, assertStreamExecutionValue } from '@envelop/testing';
44
import { makeExecutableSchema } from '@graphql-tools/schema';
55

@@ -103,4 +103,40 @@ describe('perform', () => {
103103
}
104104
`);
105105
});
106+
107+
it('should invoke onPerform plugin hooks', async () => {
108+
const onPerformDoneFn = jest.fn((() => {
109+
// noop
110+
}) as OnPerformDoneHook);
111+
const onPerformFn = jest.fn((() => ({
112+
onPerformDone: onPerformDoneFn,
113+
})) as OnPerformHook<any>);
114+
115+
const getEnveloped = envelop({
116+
...graphqlFuncs,
117+
plugins: [
118+
useSchema(schema),
119+
{
120+
onPerform: onPerformFn,
121+
},
122+
],
123+
});
124+
125+
const params = { query: '{ hello }' };
126+
const { perform } = getEnveloped({ initial: 'context' });
127+
await perform(params, { extension: 'context' });
128+
129+
expect(onPerformFn).toBeCalled();
130+
expect(onPerformFn.mock.calls[0][0].context).toEqual({ initial: 'context', extension: 'context' });
131+
expect(onPerformFn.mock.calls[0][0].params).toBe(params);
132+
133+
expect(onPerformDoneFn).toBeCalled();
134+
expect(onPerformDoneFn.mock.calls[0][0].result).toMatchInlineSnapshot(`
135+
Object {
136+
"data": Object {
137+
"hello": "world",
138+
},
139+
}
140+
`);
141+
});
106142
});

packages/types/src/hooks.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,9 @@ export type PerformFunction<ContextExtension = unknown> = (
519519
contextExtension?: ContextExtension
520520
) => Promise<AsyncIterableIteratorOrValue<ExecutionResult>>;
521521

522-
export type OnPerformEventPayload = {
522+
export type OnPerformEventPayload<ContextType> = {
523+
context: Readonly<ContextType>;
524+
extendContext: (contextExtension: Partial<ContextType>) => void;
523525
params: PerformParams;
524526
setParams: (newParams: PerformParams) => void;
525527
};
@@ -535,4 +537,6 @@ export type OnPerformHookResult = {
535537
onPerformDone?: OnPerformDoneHook;
536538
};
537539

538-
export type OnPerformHook = (options: OnPerformEventPayload) => PromiseOrValue<void | OnPerformHookResult>;
540+
export type OnPerformHook<ContextType> = (
541+
options: OnPerformEventPayload<ContextType>
542+
) => PromiseOrValue<void | OnPerformHookResult>;

packages/types/src/plugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,5 @@ export interface Plugin<PluginContext extends Record<string, any> = {}> {
4646
/**
4747
* Invoked for each perform call.
4848
*/
49-
onPerform?: OnPerformHook;
49+
onPerform?: OnPerformHook<PluginContext>;
5050
}

0 commit comments

Comments
 (0)