UNPKG

gitlab-api-async-iterator

Version:

Async iterator for GitLab API based on axios

136 lines (111 loc) 3.06 kB
const _defaultAxios = require("axios"); const timeout = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const requestMethods = [ "request", "get", "delete", "head", "options", "post", "put", "patch", ]; const waitBeforeRetry = async (error, retries, logger) => { // Be forgiving if we hit server errors or rate limits and retry after some time if ( error && error.response && [429, 500, 502, 503, 504].includes(error.response.status) ) { let wait; const log = [`Got a status code of ${error.response.status}.`]; if (error.response.headers) { try { const { "ratelimit-reset": rateLimitReset, "ratelimit-resettime": rateLimitResetTime, "retry-after": retryAfter, } = error.response.headers; if (rateLimitReset) { wait = parseInt(rateLimitReset, 10) * 1000 - new Date().getTime(); log.push( `Found a ratelimit-reset header, waiting until ${rateLimitResetTime}.` ); } if (retryAfter) { wait = parseInt(retryAfter, 10) * 1000; log.push(`Found a retry-after header (${retryAfter}).`); } } catch (e) {} } if (!wait) { wait = 2 ** retries * 100; } log.push(`Waiting ${wait} ms`); if (logger) { logger(log.join(" ")); } await timeout(wait); return retries + 1; } else { throw error; } }; const getTokenFromProcess = () => process && process.env && (process.env.GITLAB_TOKEN || process.env.DANGER_GITLAB_API_TOKEN); const GitLabAPIFactory = (axiosInstance, options = {}) => { const { maxRetries = 5, baseURL = "https://gitlab.com/api/v4/", privateToken, logger, } = options; const token = privateToken || getTokenFromProcess(); if (!token) { throw new Error( "Please provide a GitLab token as an ENV variable via GITLAB_TOKEN or DANGER_GITLAB_API_TOKEN" ); } axiosInstance.defaults.baseURL = baseURL; axiosInstance.defaults.headers.common["PRIVATE-TOKEN"] = token; return new Proxy(axiosInstance, { get(target, prop) { if (requestMethods.includes(prop)) { return async (...args) => { let retries = 0; do { try { return await target[prop](...args); } catch (e) { if (retries >= maxRetries) { throw e; } retries = await waitBeforeRetry(e, retries, logger); } } while (true); }; } return target[prop]; }, }); }; /** * @deprecated * @param options */ const deprecatedFactory = (options = {}) => { const { maxRetries, baseURL, privateToken, ...axiosOptions } = options; const _gitlabAPI = _defaultAxios.create({ ...axiosOptions, }); return GitLabAPIFactory(_gitlabAPI, { maxRetries, baseURL, privateToken, logger: console.warn, }); }; module.exports = deprecatedFactory; module.exports.setupGitLabAPI = GitLabAPIFactory;