ardatan / graphql-mesh

🕸️ GraphQL Federation Framework for any API services such as REST, OpenAPI, Swagger, SOAP, gRPC and more...
https://the-guild.dev/graphql/mesh
MIT License
3.27k stars 339 forks source link

usePropagateHeaders interface is too strict #7815

Open aarne opened 3 hours ago

aarne commented 3 hours ago

Issue workflow progress

Progress of the issue based on the Contributor Workflow


Describe the bug

usePropagateHeaders expects currently this response Record<string, string> | void | Promise<Record<string, string | null | undefined> | void>; this unfortunately means that one cannot return multiple header values with the same name. Common use case is set-cookie for example but not only.

Expected behavior

Change the interface to accept Record<string, string|string[]>, or HeadersInit

Environment:

Additional context

aarne commented 2 hours ago

simplest option for the minimal fix

diff --git a/esm/plugins/usePropagateHeaders.js b/esm/plugins/usePropagateHeaders.js
index 13e2140f22c2028d925ba5050aaa5c7a8999c8b3..fab0e26430d1a2a27b6631c39e8e7e3dc392c001 100644
--- a/esm/plugins/usePropagateHeaders.js
+++ b/esm/plugins/usePropagateHeaders.js
@@ -42,7 +42,13 @@ export function usePropagateHeaders(opts) {
                 for (const key in headers) {
                     const value = headers[key];
                     if (value) {
-                        response.headers.set(key, value);
+                        if (Array.isArray(value)) {
+                            for (const v of value) {
+                                response.headers.append(key, v);
+                            }
+                        } else {
+                            response.headers.set(key, value);
+                        }
                     }
                 }
             }
diff --git a/typings/plugins/usePropagateHeaders.d.ts b/typings/plugins/usePropagateHeaders.d.ts
index 780cd99fed2e4f06dd90186911d94e78d4c7469a..47c24c77d2d1690c34076ea3daf75eb846a36830 100644
--- a/typings/plugins/usePropagateHeaders.d.ts
+++ b/typings/plugins/usePropagateHeaders.d.ts
@@ -8,8 +8,8 @@ interface FromSubgraphsToClientPayload {
     subgraphName: string;
 }
 export interface PropagateHeadersOpts {
-    fromClientToSubgraphs?: (payload: FromClientToSubgraphsPayload) => Record<string, string> | void | Promise<Record<string, string | null | undefined> | void>;
-    fromSubgraphsToClient?: (payload: FromSubgraphsToClientPayload) => Record<string, string> | void | Promise<Record<string, string | null | undefined> | void>;
+    fromClientToSubgraphs?: (payload: FromClientToSubgraphsPayload) => Record<string, string | string[]> | void | Promise<Record<string, string | string[] | null | undefined> | void>;
+    fromSubgraphsToClient?: (payload: FromSubgraphsToClientPayload) => Record<string, string | string[]> | void | Promise<Record<string, string | string[] | null | undefined> | void>;
 }
 export declare function usePropagateHeaders<TContext>(opts: PropagateHeadersOpts): GatewayPlugin<TContext>;
 export {};
ardatan commented 2 hours ago

Good catch! Would you send a PR to fix it?