From 0df817d047d05e95b995b29a6f7c967c863f855e Mon Sep 17 00:00:00 2001
From: Arda TANRIKULU <ardatanrikulu@gmail.com>
Date: Thu, 7 Jan 2021 02:05:45 +0300
Subject: [PATCH] feat(graphql): support exported schemaHeaders

---
 .changeset/perfect-books-invite.md            |  6 ++++++
 packages/handlers/graphql/src/index.ts        | 14 ++++++++++++--
 packages/handlers/graphql/yaml-config.graphql |  3 ++-
 packages/types/src/config-schema.json         | 13 ++++++++++---
 packages/types/src/config.ts                  |  5 ++---
 5 files changed, 32 insertions(+), 9 deletions(-)
 create mode 100644 .changeset/perfect-books-invite.md

diff --git a/.changeset/perfect-books-invite.md b/.changeset/perfect-books-invite.md
new file mode 100644
index 0000000000000..5f5a27629a9bd
--- /dev/null
+++ b/.changeset/perfect-books-invite.md
@@ -0,0 +1,6 @@
+---
+'@graphql-mesh/graphql': minor
+'@graphql-mesh/types': minor
+---
+
+feat(graphql): support exported schemaHeaders
diff --git a/packages/handlers/graphql/src/index.ts b/packages/handlers/graphql/src/index.ts
index e699bec19bf76..2255d2a9db82a 100644
--- a/packages/handlers/graphql/src/index.ts
+++ b/packages/handlers/graphql/src/index.ts
@@ -58,7 +58,17 @@ export default class GraphQLHandler implements MeshHandler {
       });
     };
     let schema: GraphQLSchema;
-    const schemaHeadersFactory = getInterpolatedHeadersFactory(this.config.schemaHeaders);
+    let schemaHeaders =
+      typeof this.config.schemaHeaders === 'string'
+        ? await loadFromModuleExportExpression(this.config.schemaHeaders)
+        : this.config.schemaHeaders;
+    if (typeof schemaHeaders === 'function') {
+      schemaHeaders = schemaHeaders();
+    }
+    if ('then' in schemaHeaders) {
+      schemaHeaders = await schemaHeaders;
+    }
+    const schemaHeadersFactory = getInterpolatedHeadersFactory(schemaHeaders);
     const introspectionExecutor: AsyncExecutor = async (params): Promise<any> => {
       const { executor } = await getExecutorAndSubscriberForParams(
         params,
@@ -71,7 +81,7 @@ export default class GraphQLHandler implements MeshHandler {
       const result = await urlLoader.handleSDLAsync(this.config.introspection, {
         customFetch: customFetch as any,
         ...this.config,
-        headers: this.config.schemaHeaders,
+        headers: schemaHeaders,
       });
       schema = result.schema;
     } else if (this.config.cacheIntrospection) {
diff --git a/packages/handlers/graphql/yaml-config.graphql b/packages/handlers/graphql/yaml-config.graphql
index 27cbc61f4ca04..55924a4bffba1 100644
--- a/packages/handlers/graphql/yaml-config.graphql
+++ b/packages/handlers/graphql/yaml-config.graphql
@@ -14,8 +14,9 @@ type GraphQLHandler @md {
   endpoint: String!
   """
   JSON object representing the Headers to add to the runtime of the API calls only for schema introspection
+  You can also provide `.js` or `.ts` file path that exports schemaHeaders as an object
   """
-  schemaHeaders: JSON
+  schemaHeaders: Any
   """
   JSON object representing the Headers to add to the runtime of the API calls only for operation during runtime
   """
diff --git a/packages/types/src/config-schema.json b/packages/types/src/config-schema.json
index 3a0f23bdb8f55..514bad8f4f479 100644
--- a/packages/types/src/config-schema.json
+++ b/packages/types/src/config-schema.json
@@ -471,9 +471,16 @@
           "description": "A url or file path to your remote GraphQL endpoint.\nIf you provide a path to a code file(js or ts),\nother options will be ignored and the schema exported from the file will be used directly."
         },
         "schemaHeaders": {
-          "type": "object",
-          "properties": {},
-          "description": "JSON object representing the Headers to add to the runtime of the API calls only for schema introspection"
+          "anyOf": [
+            {
+              "type": "object",
+              "additionalProperties": true
+            },
+            {
+              "type": "string"
+            }
+          ],
+          "description": "JSON object representing the Headers to add to the runtime of the API calls only for schema introspection\nYou can also provide `.js` or `.ts` file path that exports schemaHeaders as an object"
         },
         "operationHeaders": {
           "type": "object",
diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts
index c971a5d0f3c28..814398e08cbab 100644
--- a/packages/types/src/config.ts
+++ b/packages/types/src/config.ts
@@ -121,10 +121,9 @@ export interface GraphQLHandler {
   endpoint: string;
   /**
    * JSON object representing the Headers to add to the runtime of the API calls only for schema introspection
+   * You can also provide `.js` or `.ts` file path that exports schemaHeaders as an object
    */
-  schemaHeaders?: {
-    [k: string]: any;
-  };
+  schemaHeaders?: any;
   /**
    * JSON object representing the Headers to add to the runtime of the API calls only for operation during runtime
    */