* Wrap a github object (as provided by actions/github-script) so that every * `github.rest.*.*()` call automatically logs rate-limit headers from the * response. * * Usage: * ```js * const { createRateLimitAwareGithub } = require('./github_rate_limit_logger.cjs'); * const gh = createRateLimit
(github)
| 232 | * @returns {any} A proxied github object with automatic rate-limit logging |
| 233 | */ |
| 234 | function createRateLimitAwareGithub(github) { |
| 235 | /** |
| 236 | * Wrap a single REST namespace (e.g. github.rest.issues) so each method |
| 237 | * call intercepts the response and logs rate-limit headers. |
| 238 | * |
| 239 | * @param {any} namespace - The REST namespace object |
| 240 | * @param {string} namespaceName - Name used for logging (e.g. "issues") |
| 241 | * @returns {any} |
| 242 | */ |
| 243 | function wrapNamespace(namespace, namespaceName) { |
| 244 | return new Proxy(namespace, { |
| 245 | get(target, method) { |
| 246 | const fn = target[method]; |
| 247 | if (typeof fn !== "function") return fn; |
| 248 | const wrapper = async (/** @type {any[]} */ ...args) => { |
| 249 | const response = await fn.apply(target, args); |
| 250 | logRateLimitFromResponse(response, `${namespaceName}.${String(method)}`); |
| 251 | return response; |
| 252 | }; |
| 253 | // Wrap the wrapper in a Proxy so that Octokit-specific property accesses |
| 254 | // (e.g. .endpoint, used by github.paginate()) fall back to the original fn. |
| 255 | // Without this, github.paginate(github.rest.checks.listForRef, ...) throws |
| 256 | // "route.endpoint is not a function" because the wrapper does not have |
| 257 | // the .endpoint decorator that Octokit endpoint methods carry. |
| 258 | return new Proxy(wrapper, { |
| 259 | get(wrapperTarget, prop) { |
| 260 | const own = Reflect.get(wrapperTarget, prop); |
| 261 | if (own !== undefined) return own; |
| 262 | return Reflect.get(fn, prop); |
| 263 | }, |
| 264 | }); |
| 265 | }, |
| 266 | }); |
| 267 | } |
| 268 | |
| 269 | // Wrap github.rest so every namespace access returns an instrumented proxy. |
| 270 | const restProxy = new Proxy(github.rest, { |
| 271 | get(target, namespaceName) { |
| 272 | const ns = target[namespaceName]; |
| 273 | if (!ns || typeof ns !== "object") return ns; |
| 274 | return wrapNamespace(ns, String(namespaceName)); |
| 275 | }, |
| 276 | }); |
| 277 | |
| 278 | // Return a shallow proxy over github that replaces the `rest` property. |
| 279 | return new Proxy(github, { |
| 280 | get(target, prop) { |
| 281 | if (prop === "rest") return restProxy; |
| 282 | return target[prop]; |
| 283 | }, |
| 284 | }); |
| 285 | } |
| 286 | |
| 287 | module.exports = { |
| 288 | logRateLimitFromResponse, |
no outgoing calls
no test coverage detected