Skip to content

Commit

Permalink
New plugin: useOperationHeaders (#6610)
Browse files Browse the repository at this point in the history
* New plugin: useOperationHeaders

* Tests

* chore(dependencies): updated changesets for modified dependencies

* Relax Lint

* use setOptions

* Runtime

* Fix lockfile

* chore(dependencies): updated changesets for modified dependencies

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
ardatan and github-actions[bot] authored Feb 28, 2024
1 parent 381126e commit dbaf72c
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 3 deletions.
6 changes: 6 additions & 0 deletions .changeset/red-eyes-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@graphql-mesh/plugin-operation-headers": patch
"@graphql-mesh/types": patch
---

New Plugin: Operation Headers
6 changes: 3 additions & 3 deletions packages/legacy/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
SubschemaConfig,
Transform,
} from '@graphql-tools/delegate';
import { Executor, IResolvers } from '@graphql-tools/utils';
import { Executor, IResolvers, MaybePromise } from '@graphql-tools/utils';
import { TypedDocumentNode } from '@graphql-typed-document-node/core';
import * as YamlConfig from './config.js';

Expand Down Expand Up @@ -186,11 +186,11 @@ export interface OnFetchHookDonePayload {
setResponse: (response: Response) => void;
}

export type OnFetchHookDone = (payload: OnFetchHookDonePayload) => PromiseOrValue<void>;
export type OnFetchHookDone = (payload: OnFetchHookDonePayload) => MaybePromise<void>;

export type OnFetchHook<TContext> = (
payload: OnFetchHookPayload<TContext>,
) => PromiseOrValue<void | OnFetchHookDone>;
) => MaybePromise<void | OnFetchHookDone>;

export type RawSourceOutput = {
name: string;
Expand Down
49 changes: 49 additions & 0 deletions packages/plugins/operation-headers/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "@graphql-mesh/plugin-operation-headers",
"version": "0.0.0",
"type": "module",
"repository": {
"type": "git",
"url": "ardatan/graphql-mesh",
"directory": "packages/plugins/operation-headers"
},
"license": "MIT",
"engines": {
"node": ">=16.0.0"
},
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"exports": {
".": {
"require": {
"types": "./dist/typings/index.d.cts",
"default": "./dist/cjs/index.js"
},
"import": {
"types": "./dist/typings/index.d.ts",
"default": "./dist/esm/index.js"
},
"default": {
"types": "./dist/typings/index.d.ts",
"default": "./dist/esm/index.js"
}
},
"./package.json": "./package.json"
},
"typings": "dist/typings/index.d.ts",
"peerDependencies": {
"@graphql-mesh/serve-runtime": "^0.1.1",
"@graphql-mesh/types": "^0.96.6",
"@graphql-mesh/utils": "^0.96.6",
"graphql": "*",
"tslib": "^2.4.0"
},
"publishConfig": {
"access": "public",
"directory": "dist"
},
"sideEffects": false,
"typescript": {
"definition": "dist/typings/index.d.ts"
}
}
35 changes: 35 additions & 0 deletions packages/plugins/operation-headers/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { MeshServeContext, MeshServePlugin } from '@graphql-mesh/serve-runtime';
import type { MeshFetchRequestInit } from '@graphql-mesh/types';
import { getHeadersObj, mapMaybePromise } from '@graphql-mesh/utils';

export interface OperationHeadersFactoryPayload {
context: MeshServeContext;
url: string;
options: MeshFetchRequestInit;
}

export type OperationHeadersFactory = (
payload: OperationHeadersFactoryPayload,
) => Promise<Record<string, string>> | Record<string, string>;

export function useOperationHeaders(factoryFn: OperationHeadersFactory): MeshServePlugin {
return {
onFetch({ url, options, context, setOptions }) {
const existingHeaders = getHeadersObj(options.headers || {});
const newHeaders$ = factoryFn({
url,
options,
context,
});
return mapMaybePromise(newHeaders$, newHeaders => {
setOptions({
...options,
headers: {
...existingHeaders,
...newHeaders,
},
});
});
},
};
}
48 changes: 48 additions & 0 deletions packages/plugins/operation-headers/test/operation-headers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { useOperationHeaders } from '@graphql-mesh/plugin-operation-headers';
import { wrapFetchWithPlugins } from '@graphql-mesh/runtime';

describe('Operation Headers', () => {
it('works', async () => {
const wrappedFetch = wrapFetchWithPlugins([
{
onFetch({ setFetchFn }) {
setFetchFn(async (url, opts) => {
const req = new Request(url, opts);
if (req.headers.get('Authorization') !== 'Bearer test') {
return new Response('Unauthorized', { status: 401 });
}
return Response.json({ data: 'test' });
});
},
},
useOperationHeaders(({ context }) => ({
Authorization: `Bearer ${context.headers['x-auth-token']}`,
})),
]);
const authorizedRes = await wrappedFetch(
'http://localhost:3000',
{},
{
headers: {
'x-auth-token': 'test',
},
},
);
expect(authorizedRes.status).toBe(200);
const authorizedResJson = await authorizedRes.json();
expect(authorizedResJson).toEqual({ data: 'test' });

const unauthorizedRes = await wrappedFetch(
'http://localhost:3000',
{},
{
headers: {
'x-auth-token': 'wrong-token',
},
},
);
expect(unauthorizedRes.status).toBe(401);
const unauthorizedResText = await unauthorizedRes.text();
expect(unauthorizedResText).toBe('Unauthorized');
});
});
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5347,6 +5347,18 @@ __metadata:
languageName: unknown
linkType: soft

"@graphql-mesh/plugin-operation-headers@workspace:packages/plugins/operation-headers":
version: 0.0.0-use.local
resolution: "@graphql-mesh/plugin-operation-headers@workspace:packages/plugins/operation-headers"
peerDependencies:
"@graphql-mesh/serve-runtime": ^0.1.1
"@graphql-mesh/types": ^0.96.6
"@graphql-mesh/utils": ^0.96.6
graphql: "*"
tslib: ^2.4.0
languageName: unknown
linkType: soft

"@graphql-mesh/plugin-prometheus@workspace:packages/plugins/prometheus":
version: 0.0.0-use.local
resolution: "@graphql-mesh/plugin-prometheus@workspace:packages/plugins/prometheus"
Expand Down

0 comments on commit dbaf72c

Please sign in to comment.