Skip to content
Merged
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/early-donkeys-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-tools/executor-graphql-ws': minor
---

Read and use `connectionParams` from operation extensions
13 changes: 13 additions & 0 deletions packages/executors/graphql-ws/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,20 @@ function isClient(client: Client | GraphQLWSExecutorOptions): client is Client {

export function buildGraphQLWSExecutor(clientOptionsOrClient: GraphQLWSExecutorOptions | Client): Executor {
let graphqlWSClient: Client;
let executorConnectionParams = {};
if (isClient(clientOptionsOrClient)) {
graphqlWSClient = clientOptionsOrClient;
} else {
graphqlWSClient = createClient({
webSocketImpl: WebSocket,
lazy: true,
connectionParams: () => {
const optionsConnectionParams =
(typeof clientOptionsOrClient.connectionParams === 'function'
? clientOptionsOrClient.connectionParams()
: clientOptionsOrClient.connectionParams) || {};
return Object.assign(optionsConnectionParams, executorConnectionParams);
},
...clientOptionsOrClient,
});
if (clientOptionsOrClient.onClient) {
Expand All @@ -40,6 +48,11 @@ export function buildGraphQLWSExecutor(clientOptionsOrClient: GraphQLWSExecutorO
extensions,
operationType = getOperationASTFromRequest(executionRequest).operation,
} = executionRequest;
// additional connection params can be supplied through the "connectionParams" field in extensions.
// TODO: connection params only from the FIRST operation in lazy mode will be used (detect connectionParams changes and reconnect, too implicit?)
if (extensions?.['connectionParams'] && typeof extensions?.['connectionParams'] === 'object') {
executorConnectionParams = Object.assign(executorConnectionParams, extensions['connectionParams']);
}
const query = print(document);
const iterableIterator = graphqlWSClient.iterate<TData, TExtensions>({
query,
Expand Down
10 changes: 9 additions & 1 deletion packages/executors/legacy-ws/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export enum LEGACY_WS {
}

export interface LegacyWSExecutorOpts {
connectionParams?: Record<string, any>;
connectionParams?: Record<string, unknown> | (() => Record<string, unknown>);
headers?: Record<string, any>;
}

Expand All @@ -25,6 +25,7 @@ export function buildWSLegacyExecutor(
WebSocketImpl: typeof WebSocket,
options?: LegacyWSExecutorOpts
): Executor {
let executorConnectionParams = {};
let websocket: WebSocket | null = null;

const ensureWebsocket = (errorHandler: (error: Error) => void = err => console.error(err)) => {
Expand All @@ -46,6 +47,7 @@ export function buildWSLegacyExecutor(
payload = options?.connectionParams;
break;
}
payload = Object.assign(payload, executorConnectionParams);
websocket!.send(
JSON.stringify({
type: LEGACY_WS.CONNECTION_INIT,
Expand Down Expand Up @@ -82,6 +84,12 @@ export function buildWSLegacyExecutor(
};

return function legacyExecutor(request: ExecutionRequest) {
// additional connection params can be supplied through the "connectionParams" field in extensions.
// TODO: connection params only from the FIRST operation in lazy mode will be used (detect connectionParams changes and reconnect, too implicit?)
if (request.extensions?.['connectionParams'] && typeof request.extensions?.['connectionParams'] === 'object') {
executorConnectionParams = Object.assign(executorConnectionParams, request.extensions['connectionParams']);
}

const id = Date.now().toString();
return observableToAsyncIterable({
subscribe(observer) {
Expand Down
4 changes: 2 additions & 2 deletions packages/loaders/url/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export interface LoadFromUrlOptions extends BaseLoaderOptions, Partial<Introspec
/**
* Connection Parameters for WebSockets connection
*/
connectionParams?: any;
connectionParams?: Record<string, unknown> | (() => Record<string, unknown>);
/**
* Enable Batching
*/
Expand Down Expand Up @@ -154,7 +154,7 @@ export class UrlLoader implements Loader<LoadFromUrlOptions> {
buildWSExecutor(
subscriptionsEndpoint: string,
webSocketImpl: typeof WebSocket,
connectionParams?: Record<string, any>
connectionParams?: Record<string, unknown> | (() => Record<string, unknown>)
): Executor {
const WS_URL = switchProtocols(subscriptionsEndpoint, {
https: 'wss',
Expand Down