# github.js

    const Bottleneck = require('bottleneck')
    const Octokit = require('@octokit/rest')

    /**
     * the [@octokit/rest Node.js module](https://github.com/octokit/rest.js),
     * 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/rest.js}
     */

    const defaultCallback = response => response
    async function paginate (octokit, responsePromise, callback = defaultCallback) {
      let collection = []
      let getNextPage = true
      let done = () => {
        getNextPage = false
      }
      let response = await responsePromise
      collection = collection.concat(await callback(response, done))
      // eslint-disable-next-line no-unmodified-loop-condition
      while (getNextPage && octokit.hasNextPage(response)) {
        response = await octokit.getNextPage(response)
        collection = collection.concat(await callback(response, done))
      }
      return collection
    }

    function EnhancedGitHubClient (options) {
      const octokit = Octokit(options)
      const limiter = options.limiter || new Bottleneck({ maxConcurrent: 1, minTime: 1000 })
      const logger = options.logger
      const noop = () => Promise.resolve()

      octokit.hook.before('request', limiter.schedule.bind(limiter, noop))
      octokit.hook.error('request', (error, options) => {
        const {method, url, headers, ...params} = options
        const msg = `GitHub request: ${method} ${url} - ${error.code} ${error.status}`
        logger.debug({params}, msg)
        throw error
      })
      octokit.hook.after('request', (result, options) => {
        const {method, url, headers, ...params} = options
        const msg = `GitHub request: ${method} ${url} - ${result.meta.status}`
        logger.debug({params}, msg)
      })
      octokit.paginate = paginate.bind(null, octokit)

      return octokit
    }

    module.exports = EnhancedGitHubClient