Implementing the Printful API?

I don’t understand how to add the Basic encoded Authorization header in Node for this API to work.

Here is the site…

and the code they give…

let PrintfulClient = function(key){

  //API key
  let key = key

  let https = require('https')
  let querystring = require('querystring')
  let USER_AGENT = 'Printful API Node.js Library 1.1'

  /*
   * Perform a GET request to the API
   * path - Request path (e.g. 'orders' or 'orders/123')
   * params - Additional GET parameters as a hash
   */
  this.get = function(path, params){
      return new Request('GET', path, null, params)
  }

  /*
   * Perform a DELETE request to the API
   * path - Request path (e.g. 'orders' or 'orders/123')
   * params - Additional GET parameters as a hash
   */
  this.delete = function(path, params){
      return new Request('DELETE', path, null, params)
  }

  /*
   * Perform a POST request to the API
   * path - Request path (e.g. 'orders' or 'orders/123')
   * data - Request body data as a hash
   * params - Additional GET parameters as a hash
   */
  this.post = function(path, data, params){
      return new Request('POST', path, data, params)
  }

  /*
   * Perform a PUT request to the API
   * path - Request path (e.g. 'orders' or 'orders/123')
   * data - Request body data as a hash
   * params - Additional GET parameters as a hash
   */
  this.put = function(path, data, params){
      return new Request('PUT', path, data, params)
  }

  /*
   * Generic request wrapper returned by all API request functions
   * .success(callback) - set the success callback
   * .error(callback) - set the error callback
   */
  let Request = function(method, path, data, params){
      let _success, _error

      //Additinal info about the request
      let info = {
          code: null,//Response status code
          result: null,//Response result element data
          response: null,//Full Response data
          response_raw: null,//Raw response
          total_items: null,//Total information from paging (if any)
          method: method,
          path: path,
          data: data,
          params: params
      }

      //Set up success callback
      this.success = function(callback){
          _success = callback
          return this
      }

      //Set up error callback
      this.error = function(callback){
          _error = callback
          return this
      }

      if(params){
          path = path + '?' + querystring.stringify(params)
      }

      let options = {
          host: 'api.theprintful.com',
          port: 443,
          path: '/'+ path,
          method: method,
          auth: key,
          headers: {
              'User-Agent': USER_AGENT,
              'Content-Type': 'application/json'
          }
      }
      let req = https.request(options, function(res) {
          let body = ''
          res.on('data', function(chunk) {
              body += chunk
          })
          res.on('end', function() {
              info.response_raw = body
              console.log(body)
              try{
                  let json = JSON.parse(body)
              }
              catch(e){
                  if(_error){
                      _error('Invalid JSON in the response', info)
                  }
                  return
              }
              info.response = json

              if(typeof json.code == 'undefined' || typeof json.result == 'undefined'){
                  if(_error){
                      _error('Invalid API response', info)
                  }
                  return
              } else{
                  info.code = json.code
                  info.result = json.result
                  if(json.code <200 || json.code >=300){
                      if(_error){
                          _error(info.result, info)
                      }
                  } else if(_success){
                      if(json.paging){
                          info.total_items = json.paging.total
                      }
                      _success(info.result, info)
                  }
              }
          })
      }).on('error', function(e) {
          if(_error){
              _error('HTTP request failed - '+ e.message, info)
          }
      })
      if(data){
          req.write(JSON.stringify(data))
      }
      req.end()
      return this
  }

}

module.exports = PrintfulClient
let PrintfulClient = require('../routes/printfulClient.js')

    //
    // Replace this with your API key
    //
    let key = process.env.PRINTFULAPIHEADER

    /**
     * Callback for success
     * data - result element from the API response
     * info - additional data about the request and response
     */
    let ok_callback = function(data, info){
        console.log('SUCCESS')
        console.log(data)
        //If response includes paging information, show total number available
        if(info.total_items){
            console.log('Total items available: '+info.total_items)
        }
    }

    /**
     * Callback for failure
     * data - error message
     * info - additional data about the request
     */
    let error_callback = function(message, info){
        console.log('ERROR ' + message)
        //Dump raw response
        console.log(info.response_raw)
    }

    ///Construct client
    let pf = new PrintfulClient(key)

    //
    //Uncomment any of the following examples to test it
    //

    //Get information about the store
    // pf.get('store').success(ok_callback).error(error_callback)

    //Get product list
    //pf.get('products').success(ok_callback).error(error_callback)

    //Get variants for product 10
    //pf.get('products/10').success(ok_callback).error(error_callback)

    //Get information about Variant 1007
    //pf.get('products/variant/1007').success(ok_callback).error(error_callback)

    //Select 10 latest orders and get the total number of orders
    // pf.get('orders',{limit: 10}).success(ok_callback).error(error_callback)

    //Select order with ID 12345 (Replace with your order's ID)
    //pf.get('orders/12345').success(ok_callback).error(error_callback)

    //Select order with External ID 9900999 (Replace with your order's External ID)
    //pf.get('orders/@9900999').success(ok_callback).error(error_callback)

    //Confirm order with ID 12345 (Replace with your order's ID)
    //pf.post('orders/12345/confirm').success(ok_callback).error(error_callback)

    //Cancel order with ID 12345 (Replace with your order's ID)
    //pf.delete('orders/23479').success(ok_callback).error(error_callback)

Within the PrintfulClient object, there is a factory method called Request which contains an option property

let Request = function(method, path, data, params){
  let _success, _error

      //Additinal info about the request
      let info = {
          code: null,//Response status code
          result: null,//Response result element data
          response: null,//Full Response data
          response_raw: null,//Raw response
          total_items: null,//Total information from paging (if any)
          method: method,
          path: path,
          data: data,
          params: params
      }

      //Set up success callback
      this.success = function(callback){
          _success = callback
          return this
      }

      //Set up error callback
      this.error = function(callback){
          _error = callback
          return this
      }

      if(params){
          path = path + '?' + querystring.stringify(params)
      }

      let options = {
          host: 'api.theprintful.com',
          port: 443,
          path: '/'+ path,
          method: method,
          auth: key,
          headers: {
              'User-Agent': USER_AGENT,
              'Content-Type': 'application/json'
          }
      }
      let req = https.request(options, function(res) {
          let body = ''
          res.on('data', function(chunk) {
              body += chunk
          })
          res.on('end', function() {
              info.response_raw = body
              console.log(body)
              try{
                  let json = JSON.parse(body)
              }
              catch(e){
                  if(_error){
                      _error('Invalid JSON in the response', info)
                  }
                  return
              }
              info.response = json

              if(typeof json.code == 'undefined' || typeof json.result == 'undefined'){
                  if(_error){
                      _error('Invalid API response', info)
                  }
                  return
              } else{
                  info.code = json.code
                  info.result = json.result
                  if(json.code <200 || json.code >=300){
                      if(_error){
                          _error(info.result, info)
                      }
                  } else if(_success){
                      if(json.paging){
                          info.total_items = json.paging.total
                      }
                      _success(info.result, info)
                  }
              }
          })
      }).on('error', function(e) {
          if(_error){
              _error('HTTP request failed - '+ e.message, info)
          }
      })
      if(data){
          req.write(JSON.stringify(data))
      }
      req.end()
      return this
  }

If we drill down into the object, we see that there is a headers prop which contains the config for the http header object.

let options = {
          host: 'api.theprintful.com',
          port: 443,
          path: '/'+ path,
          method: method,
          auth: key,
          headers: {
              'User-Agent': USER_AGENT,
              'Content-Type': 'application/json',
              'Authorization': 'Basic' + apiKey // <--- Authorization prop goes here
          }
      }

If we check the api documentation, the api key is encoded with Base64, so we would need to make sure to include it in apiKey encoded.

From there the request method will take the options prop when invoked and include the header before sending out the http request.

This is from just looking at the code, no testing was done to confirm.