Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/curly-banks-stand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@envelop/core': patch
---

Fixes `onFetch` hook not having the `state` attribute in payload on non-upstream `fetch` calls.
18 changes: 17 additions & 1 deletion packages/core/src/plugin-with-state.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
import { MaybePromise } from '@whatwg-node/promise-helpers';

/**
* A function allowing to add a `state` to the payload (first object parameter of any function)
*/
export function withState<
P extends { instrumentation?: GenericInstrumentation },
HttpState = object,
GraphqlState = object,
SubExecState = object,
>(
pluginFactory: (
getState: <SP extends {}>(
payload: SP,
) => PayloadWithState<SP, HttpState, GraphqlState, SubExecState>['state'],
) => PluginWithState<P, HttpState, GraphqlState, SubExecState>,
): P;
// Secondary signature with simpler generics when you have the same state in all layers
export function withState<P extends { instrumentation?: GenericInstrumentation }, State = object>(
pluginFactory: (
getState: <SP extends {}>(payload: SP) => PayloadWithState<SP, State, State, State>['state'],
Expand Down Expand Up @@ -75,7 +91,7 @@ export function withState<
} else {
result[hookName] = {
[hook.name](payload: any, ...args: any[]) {
if (payload && (payload.request || payload.context || payload.executionRequest)) {
if (payload && Object.getPrototypeOf(payload) === Object.prototype) {
return hook(
{
...payload,
Expand Down
40 changes: 29 additions & 11 deletions packages/core/test/plugin-with-state.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ describe('pluginWithState', () => {
expect(plugin).toEqual({ test: 'test' });
});

it('should keep parameters when there is no state to add', () => {
const objectPayload = {};
it('should add state to first parameter only if it a plain object', () => {
const objectPayload = new Date();
expect(plugin.hook(objectPayload)[0]).toBe(objectPayload);
expect(Object.hasOwn(objectPayload, 'state')).toBeFalsy();

const arrayPayload: any[] = [];
expect(plugin.hook(arrayPayload)[0]).toBe(arrayPayload);
Expand Down Expand Up @@ -106,7 +107,9 @@ describe('pluginWithState', () => {
});

describe('instrumentation', () => {
const plugin = withState(() => ({ instrumentation: { hook: (...args: any[]): any => args } }));
const plugin = withState(() => ({
instrumentation: { hook: (...args: any[]): any => args },
}));

it('should add request state', () => {
expect(plugin.instrumentation.hook({ request: {} })).toMatchObject([
Expand Down Expand Up @@ -139,8 +142,16 @@ describe('pluginWithState', () => {
]);

expect(
plugin.instrumentation.hook({ executionRequest: {}, request: {}, context: {} }),
).toMatchObject([{ state: { forSubgraphExecution: {}, forRequest: {}, forOperation: {} } }]);
plugin.instrumentation.hook({
executionRequest: {},
request: {},
context: {},
}),
).toMatchObject([
{
state: { forSubgraphExecution: {}, forRequest: {}, forOperation: {} },
},
]);
});

it('should have a stable state', () => {
Expand All @@ -156,8 +167,9 @@ describe('pluginWithState', () => {
forOperation,
);
expect(
plugin.instrumentation.hook({ executionRequest: refs.executionRequest })[0]
.forSubgraphExecution,
plugin.instrumentation.hook({
executionRequest: refs.executionRequest,
})[0].forSubgraphExecution,
).toBe(forSubgraphExecution);
});
});
Expand All @@ -178,7 +190,9 @@ describe('pluginWithState', () => {
});

it('should add subgraph execution state', () => {
expect(getState({ executionRequest: {} })).toMatchObject({ forSubgraphExecution: {} });
expect(getState({ executionRequest: {} })).toMatchObject({
forSubgraphExecution: {},
});
});

it('should combine all states', () => {
Expand Down Expand Up @@ -236,9 +250,13 @@ describe('pluginWithState', () => {
forSubgraphExecution,
);

expect(getMostSpecificState({ forOperation, forRequest, forSubgraphExecution })).toBe(
forSubgraphExecution,
);
expect(
getMostSpecificState({
forOperation,
forRequest,
forSubgraphExecution,
}),
).toBe(forSubgraphExecution);
});
});
});