text: import BottleneckLight from 'bottleneck/light';
  
  const VERSION = "3.4.1";
  
  const noop = () => Promise.resolve();
  // @ts-ignore
  function wrapRequest(state, request, options) {
      return state.retryLimiter.schedule(doRequest, state, request, options);
  }
  // @ts-ignore
  async function doRequest(state, request, options) {
      const isWrite = options.method !== "GET" && options.method !== "HEAD";
      const isSearch = options.method === "GET" && options.url.startsWith("/search/");
      const isGraphQL = options.url.startsWith("/graphql");
      const retryCount = ~~options.request.retryCount;
      const jobOptions = retryCount > 0 ? { priority: 0, weight: 0 } : {};
      if (state.clustering) {
          // Remove a job from Redis if it has not completed or failed within 60s
          // Examples: Node process terminated, client disconnected, etc.
          // @ts-ignore
          jobOptions.expiration = 1000 * 60;
      }
      // Guarantee at least 1000ms between writes
      // GraphQL can also trigger writes
      if (isWrite || isGraphQL) {
          await state.write.key(state.id).schedule(jobOptions, noop);
      }
      // Guarantee at least 3000ms between requests that trigger notifications
      if (isWrite && state.triggersNotification(options.url)) {
          await state.notifications.key(state.id).schedule(jobOptions, noop);
      }
      // Guarantee at least 2000ms between search requests
      if (isSearch) {
          await state.search.key(state.id).schedule(jobOptions, noop);
      }
      const req = state.global.key(state.id).schedule(jobOptions, request, options);
      if (isGraphQL) {
          const res = await req;
          if (res.data.errors != null &&
              // @ts-ignore
              res.data.errors.some((error) => error.type === "RATE_LIMITED")) {
              const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), {
                  headers: res.headers,
                  data: res.data,
              });
              throw error;
          }
      }
      return req;
  }
  
  var triggersNotificationPaths = [
      "/orgs/{org}/invitations",
      "/orgs/{org}/invitations/{invitation_id}",
      "/orgs/{org}/teams/{team_slug}/discussions",
      "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments",
      "/repos/{owner}/{repo}/collaborators/{username}",
      "/repos/{owner}/{repo}/commits/{commit_sha}/comments",
      "/repos/{owner}/{repo}/issues",
      "/repos/{owner}/{repo}/issues/{issue_number}/comments",
      "/repos/{owner}/{repo}/pulls",
      "/repos/{owner}/{repo}/pulls/{pull_number}/comments",
      "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies",
      "/repos/{owner}/{repo}/pulls/{pull_number}/merge",
      "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers",
      "/repos/{owner}/{repo}/pulls/{pull_number}/reviews",
      "/repos/{owner}/{repo}/releases",
      "/teams/{team_id}/discussions",
      "/teams/{team_id}/discussions/{discussion_number}/comments",
  ];
  
  // @ts-ignore
  function routeMatcher(paths) {
      // EXAMPLE. For the following paths:
      /* [
          "/orgs/{org}/invitations",
          "/repos/{owner}/{repo}/collaborators/{username}"
      ] */
      // @ts-ignore
      const regexes = paths.map((path) => path
          .split("/")
          // @ts-ignore
          .map((c) => (c.startsWith("{") ? "(?:.+?)" : c))
          .join("/"));
      // 'regexes' would contain:
      /* [
          '/orgs/(?:.+?)/invitations',
          '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)'
      ] */
      // @ts-ignore
      const regex = `^(?:${regexes.map((r) => `(?:${r})`).join("|")})[^/]*$`;
      // 'regex' would contain:
      /*
        ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$
    
        It may look scary, but paste it into https://www.debuggex.com/
        and it will make a lot more sense!
      */
      return new RegExp(regex, "i");
  }
  
  // @ts-ignore
  // Workaround to allow tests to directly access the triggersNotification function.
  const regex = routeMatcher(triggersNotificationPaths);
  const triggersNotification = regex.test.bind(regex);
  const groups = {};
  // @ts-ignore
  const createGroups = function (Bottleneck, common) {
      // @ts-ignore
      groups.global = new Bottleneck.Group({
          id: "octokit-global",
          maxConcurrent: 10,
          ...common,
      });
      // @ts-ignore
      groups.search = new Bottleneck.Group({
          id: "octokit-search",
          maxConcurrent: 1,
          minTime: 2000,
          ...common,
      });
      // @ts-ignore
      groups.write = new Bottleneck.Group({
          id: "octokit-write",
          maxConcurrent: 1,
          minTime: 1000,
          ...common,
      });
      // @ts-ignore
      groups.notifications = new Bottleneck.Group({
          id: "octokit-notifications",
          maxConcurrent: 1,
          minTime: 3000,
          ...common,
      });
  };
  function throttling(octokit, octokitOptions = {}) {
      const { enabled = true, Bottleneck = BottleneckLight, id = "no-id", timeout = 1000 * 60 * 2, // Redis TTL: 2 minutes
      connection, } = octokitOptions.throttle || {};
      if (!enabled) {
          return;
      }
      const common = { connection, timeout };
      // @ts-ignore
      if (groups.global == null) {
          createGroups(Bottleneck, common);
      }
      const state = Object.assign({
          clustering: connection != null,
          triggersNotification,
          minimumAbuseRetryAfter: 5,
          retryAfterBaseValue: 1000,
          retryLimiter: new Bottleneck(),
          id,
          ...groups,
      }, 
      // @ts-ignore
      octokitOptions.throttle);
      if (typeof state.onAbuseLimit !== "function" ||
          typeof state.onRateLimit !== "function") {
          throw new Error(`octokit/plugin-throttling error:
          You must pass the onAbuseLimit and onRateLimit error handlers.
          See https://github.com/octokit/rest.js#throttling
  
          const octokit = new Octokit({
            throttle: {
              onAbuseLimit: (retryAfter, options) => {/* ... */},
              onRateLimit: (retryAfter, options) => {/* ... */}
            }
          })
      `);
      }
      const events = {};
      const emitter = new Bottleneck.Events(events);
      // @ts-ignore
      events.on("abuse-limit", state.onAbuseLimit);
      // @ts-ignore
      events.on("rate-limit", state.onRateLimit);
      // @ts-ignore
      events.on("error", (e) => console.warn("Error in throttling-plugin limit handler", e));
      // @ts-ignore
      state.retryLimiter.on("failed", async function (error, info) {
          const options = info.args[info.args.length - 1];
          const shouldRetryGraphQL = options.url.startsWith("/graphql") && error.status !== 401;
          if (!(shouldRetryGraphQL || error.status === 403)) {
              return;
          }
          const retryCount = ~~options.request.retryCount;
          options.request.retryCount = retryCount;
          const { wantRetry, retryAfter } = await (async function () {
              if (/\babuse\b/i.test(error.message)) {
                  // The user has hit the abuse rate limit. (REST and GraphQL)
                  // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits
                  // The Retry-After header can sometimes be blank when hitting an abuse limit,
                  // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default.
                  const retryAfter = Math.max(~~error.headers["retry-after"], state.minimumAbuseRetryAfter);
                  const wantRetry = await emitter.trigger("abuse-limit", retryAfter, options, octokit);
                  return { wantRetry, retryAfter };
              }
              if (error.headers != null &&
                  error.headers["x-ratelimit-remaining"] === "0") {
                  // The user has used all their allowed calls for the current time period (REST and GraphQL)
                  // https://docs.github.com/en/rest/reference/rate-limit (REST)
                  // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL)
                  const rateLimitReset = new Date(~~error.headers["x-ratelimit-reset"] * 1000).getTime();
                  const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0);
                  const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit);
                  return { wantRetry, retryAfter };
              }
              return {};
          })();
          if (wantRetry) {
              options.request.retryCount++;
              // @ts-ignore
              return retryAfter * state.retryAfterBaseValue;
          }
      });
      octokit.hook.wrap("request", wrapRequest.bind(null, state));
  }
  throttling.VERSION = VERSION;
  throttling.triggersNotification = triggersNotification;
  
  export { throttling };
  //# sourceMappingURL=index.js.map
  