Advertisement
aleffelixf

AuthenticatedDataSource.js

Mar 17th, 2020
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const {RemoteGraphQLDataSource} = require('@apollo/gateway')
  2. const {fetch, Request} = require('apollo-server-env')
  3. const {isObject} = require('@apollo/gateway/dist/utilities/predicates')
  4. const FormData = require('form-data')
  5.  
  6. module.exports = class AuthenticatedDataSource extends RemoteGraphQLDataSource {
  7.  
  8.     willSendRequest({request, context}) {
  9.         request.http.headers.set('Authorization', context.token)
  10.     }
  11.  
  12.     process(args) {
  13.         console.dir(this.didEncounterError)
  14.         const {request} = args
  15.         const fileVariables = Object.entries(request.variables || {}).filter(
  16.             ([, value]) => value instanceof Promise,
  17.         )
  18.        
  19.         if (fileVariables.length > 0) {
  20.             return this.processFileUpload(request, fileVariables);
  21.         } else {
  22.             return super.process(args);
  23.         }
  24.     }
  25.  
  26.     async processFileUpload(request, fileVariables) {
  27.         const form = new FormData()
  28.  
  29.         const variables = request.variables
  30.         for (const [variableName] of fileVariables) {
  31.             variables[variableName] = null
  32.         }
  33.  
  34.         const operations = JSON.stringify({
  35.             query: request.query,
  36.             variables,
  37.         })
  38.  
  39.         form.append('operations', operations)
  40.  
  41.         const resolvedFiles = await Promise.all(
  42.             fileVariables.map(async ([variableName, file]) => {
  43.               const contents = await file
  44.               return [variableName, contents]
  45.             }),
  46.         )
  47.  
  48.         const fileMap = resolvedFiles.reduce(
  49.             (map, [variableName], i) => ({
  50.               ...map,
  51.               [i]: [`variables.${variableName}`],
  52.             }),
  53.             {},
  54.         )
  55.         form.append('map', JSON.stringify(fileMap))
  56.  
  57.         await Promise.all(
  58.             resolvedFiles.map(async ([, contents], i) => {
  59.               const { filename, mimetype, createReadStream } = contents
  60.               const stream = await createReadStream()
  61.               form.append(i, stream, { filename, contentType: mimetype })
  62.             }),
  63.         )
  64.  
  65.         const headers = (request.http && request.http.headers) || {}
  66.  
  67.         request.http = {
  68.             method: 'POST',
  69.             url: this.url,
  70.             headers,
  71.             headers: { ...headers, ...form.getHeaders() },
  72.         }
  73.  
  74.         const options = {
  75.             ...request.http,
  76.             body: form,
  77.         }
  78.  
  79.         const httpRequest = new Request(request.http.url, options);
  80.  
  81.         try {
  82.             const httpResponse = await fetch(httpRequest);
  83.  
  84.             const body = await this.didReceiveResponse(httpResponse, httpRequest)
  85.  
  86.             if (!isObject(body)) {
  87.                 throw new Error(`Expected JSON response body, but received: ${body}`)
  88.             }
  89.  
  90.             const response = {
  91.                 ...body,
  92.                 http: httpResponse,
  93.             }
  94.  
  95.             return response
  96.         } catch (error) {
  97.             this.didEncounterError(error, httpRequest)
  98.             throw error
  99.         }
  100.     }
  101.  
  102. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement