# github.js

    const Bottleneck = require('bottleneck')
    const GitHubApi = require('github')

    /**
     * the [github Node.js module](https://github.com/octokit/node-github),
     * which wraps the [GitHub API](https://developer.github.com/v3/) and allows
     * you to do almost anything programmatically that you can do through a web
     * browser.
     * @typedef github
     * @see {@link https://github.com/octokit/node-github}
     */

    // Default callback should just return the response passed to it.
    const defaultCallback = response => response

    class EnhancedGitHubClient extends GitHubApi {
      constructor (options) {
        super(options)
        this.limiter = new Bottleneck(1, 1000)
        this.logger = options.logger
      }

      handler (params, block, callback) {
        // Only allow one request at a time with a 1s delay
        // https://github.com/octokit/node-github/issues/526
        this.limiter.submit(super.handler.bind(this), params, block, (err, res) => {
          let msg = `GitHub request: ${block.method} ${block.url}`
          if (res) {
            msg += ` - ${res.meta.status}`
          } else if (err) {
            msg += ` - ${err.code} ${err.status}`
          }
          this.logger.debug({params}, msg)

          if (res) {
            this.logger.trace(res, 'GitHub response:')
          }

          callback(err, res)
        })
      }

      async paginate (responsePromise, callback = defaultCallback) {
        let collection = []
        let response = await responsePromise
        collection = collection.concat(await callback(response))
        while (this.hasNextPage(response)) {
          response = await this.getNextPage(response)
          collection = collection.concat(await callback(response))
        }
        return collection
      }
    }

    module.exports = EnhancedGitHubClient