[
  {
    "path": ".github/ISSUE_TEMPLATE/bug.yml",
    "content": "name: Bug\ndescription: File a bug report\ntitle: \"[BUG]: \"\nlabels: [\"Type: Bug\", \"Status: Triage\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill out this bug report!\n  - type: textarea\n    id: what-happened\n    attributes:\n      label: What happened?\n      description: What did you do? What happened? What did you expect to happen?\n      placeholder: Put your description of the bug here.\n    validations:\n      required: true\n  - type: textarea\n    id: versions\n    attributes:\n      label: Versions\n      description: What versions of the relevant software are you running?\n      placeholder: Octokit.js v2.0.10, Node v16.18.0\n    validations:\n      required: true\n  - type: textarea\n    id: logs\n    attributes:\n      label: Relevant log output\n      description: |\n        Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.\n        Please check your logs before submission to ensure sensitive information is redacted.\n      render: shell\n  - type: checkboxes\n    id: terms\n    attributes:\n      label: Code of Conduct\n      description: By submitting this issue, you agree to follow our [Code of Conduct](CODE_OF_CONDUCT.md)\n      options:\n        - label: I agree to follow this project's Code of Conduct\n          required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/documentation.yml",
    "content": "name: Documentation\ndescription: Update or add documentation\ntitle: \"[DOCS]: \"\nlabels: [\"Type: Documentation\", \"Status: Triage\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill this out!\n  - type: textarea\n    id: describe-need\n    attributes:\n      label: Describe the need\n      description: What do you wish was different about our docs?\n      placeholder: Describe the need for documentation updates here.\n    validations:\n      required: true\n  - type: input\n    id: sdk_version\n    attributes:\n      label: SDK Version\n      description: Do these docs apply to a specific SDK version?\n      placeholder: Octokit.NET v4.0.1\n    validations:\n      required: false\n  - type: input\n    id: api_version\n    attributes:\n      label: API Version\n      description: Do these docs apply to a specific version of the GitHub REST API or GraphQL API?\n      placeholder: ex. v1.1.1\n    validations:\n      required: false\n  - type: textarea\n    id: logs\n    attributes:\n      label: Relevant log output\n      description: |\n        Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.\n        Please check your logs before submission to ensure sensitive information is redacted.\n      render: shell\n  - type: checkboxes\n    id: terms\n    attributes:\n      label: Code of Conduct\n      description: By submitting this issue, you agree to follow our [Code of Conduct](CODE_OF_CONDUCT.md)\n      options:\n        - label: I agree to follow this project's Code of Conduct\n          required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature.yml",
    "content": "name: Feature\ndescription: Suggest an idea for a new feature or enhancement\ntitle: \"[FEAT]: \"\nlabels: [\"Type: Feature\", \"Status: Triage\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill this out!\n  - type: textarea\n    id: describe-need\n    attributes:\n      label: Describe the need\n      description: What do you want to happen? What problem are you trying to solve?\n      placeholder: Describe the need for the feature.\n    validations:\n      required: true\n  - type: input\n    id: sdk_version\n    attributes:\n      label: SDK Version\n      description: Does this feature suggestion apply to a specific SDK version?\n      placeholder: Octokit.rb v6.0.0\n    validations:\n      required: false\n  - type: input\n    id: api_version\n    attributes:\n      label: API Version\n      description: Does this feature suggestion apply to a specific version of the GitHub REST API or GraphQL API?\n      placeholder: ex. v1.1.1\n    validations:\n      required: false\n  - type: textarea\n    id: logs\n    attributes:\n      label: Relevant log output\n      description: |\n        Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.\n        Please check your logs before submission to ensure sensitive information is redacted.\n      render: shell\n  - type: checkboxes\n    id: terms\n    attributes:\n      label: Code of Conduct\n      description: By submitting this issue, you agree to follow our [Code of Conduct](CODE_OF_CONDUCT.md)\n      options:\n        - label: I agree to follow this project's Code of Conduct\n          required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/maintenance.yml",
    "content": "name: Maintenance\ndescription: Dependencies, cleanup, refactoring, reworking of code\ntitle: \"[MAINT]: \"\nlabels: [\"Type: Maintenance\", \"Status: Triage\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill this out!\n  - type: textarea\n    id: describe-need\n    attributes:\n      label: Describe the need\n      description: What do you want to happen?\n      placeholder: Describe the maintenance need here.\n    validations:\n      required: true\n  - type: input\n    id: sdk_version\n    attributes:\n      label: SDK Version\n      description: Does this maintenance apply to a specific SDK version?\n      placeholder: terraform-provider-github v5.7.0\n    validations:\n      required: false\n  - type: input\n    id: api_version\n    attributes:\n      label: API Version\n      description: Does this maintenance apply to a specific version of the GitHub REST API or GraphQL API?\n      placeholder: ex. v1.1.1\n    validations:\n      required: false\n  - type: textarea\n    id: logs\n    attributes:\n      label: Relevant log output\n      description: |\n        Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.\n        Please check your logs before submission to ensure sensitive information is redacted.\n      render: shell\n  - type: checkboxes\n    id: terms\n    attributes:\n      label: Code of Conduct\n      description: By submitting this issue, you agree to follow our [Code of Conduct](CODE_OF_CONDUCT.md)\n      options:\n        - label: I agree to follow this project's Code of Conduct\n          required: true\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "<!-- Please refer to our contributing docs for any questions on submitting a pull request -->\n<!-- Issues are required for both bug fixes and features. -->\nResolves #ISSUE_NUMBER\n\n----\n\n### Before the change?\n<!-- Please describe the current behavior that you are modifying. -->\n\n* \n\n### After the change?\n<!-- Please describe the behavior or changes that are being added by this PR. -->\n\n* \n\n### Pull request checklist\n- [ ] Tests for the changes have been added (for bug fixes / features)\n- [ ] Docs have been reviewed and added / updated if needed (for bug fixes / features)\n\n### Does this introduce a breaking change?\n<!-- If this introduces a breaking change make sure to note it here any what the impact might be -->\n\nPlease see our docs on [breaking changes](https://github.com/octokit/.github/blob/master/community/breaking_changes.md) to help!\n\n- [ ] Yes\n- [ ] No\n\n----\n\n"
  },
  {
    "path": ".github/renovate.json",
    "content": "{\n  \"extends\": [\n    \"github>octokit/.github\"\n  ]\n}\n"
  },
  {
    "path": ".github/workflows/add_to_octokit_project.yml",
    "content": "name: Add PRs and issues to Octokit org project\n\non:\n  issues:\n    types: [reopened, opened]\n  pull_request_target:\n    types: [reopened, opened]\n\njobs:\n  add-to-project:\n    name: Add issue to project\n    runs-on: ubuntu-latest\n    continue-on-error: true\n    steps:\n      - uses: actions/add-to-project@v1.0.2\n        with:\n          project-url: https://github.com/orgs/octokit/projects/10\n          github-token: ${{ secrets.OCTOKITBOT_PROJECT_ACTION_TOKEN }}\n          labeled: \"Status: Stale\"\n          label-operator: NOT\n"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "content": "name: \"CodeQL\"\n\non:\n  push:\n    branches: [ \"main\", beta ]\n  pull_request:\n    # The branches below must be a subset of the branches above\n    branches: [ \"main\" ]\n  schedule:\n    - cron: '19 5 * * 1'\n\njobs:\n  analyze:\n    name: Analyze\n    runs-on: ubuntu-latest\n    permissions:\n      actions: read\n      contents: read\n      security-events: write\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [ 'javascript' ]\n\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v6\n\n    - name: Initialize CodeQL\n      uses: github/codeql-action/init@v4\n      with:\n        languages: ${{ matrix.language }}\n\n    - name: Autobuild\n      uses: github/codeql-action/autobuild@v4\n\n    - name: Perform CodeQL Analysis\n      uses: github/codeql-action/analyze@v4\n      with:\n        category: \"/language:${{matrix.language}}\"\n"
  },
  {
    "path": ".github/workflows/immediate-response.yml",
    "content": "name: Issue/PR response\npermissions:\n  issues: write\n  pull-requests: write\non:\n  issues:\n    types:\n      - opened\n  pull_request_target:\n    types:\n      - opened\njobs:\n  respond-to-issue:\n    if: ${{ github.actor != 'dependabot[bot]' && github.actor != 'renovate[bot]' && github.actor != 'githubactions[bot]' && github.actor != 'octokitbot' }}\n    runs-on: ubuntu-latest\n    steps:\n      - name: Determine issue or PR number\n        id: extract\n        run: echo \"NUMBER=${{ github.event.issue.number || github.event.pull_request.number }}\" >> \"$GITHUB_OUTPUT\"\n\n      - name: Respond to issue or PR\n        uses: peter-evans/create-or-update-comment@v5\n        with:\n          issue-number: ${{ steps.extract.outputs.NUMBER }}\n          body: >\n            👋 Hi! Thank you for this contribution! Just to let you know, our GitHub SDK team does a round of issue and PR reviews twice a week, every Monday and Friday!\n            We have a [process in place](https://github.com/octokit/.github/blob/main/community/prioritization_response.md#overview) for prioritizing and responding to your input. \n            Because you are a part of this community please feel free to comment, add to, or pick up any issues/PRs that are labeled with `Status: Up for grabs`.\n            You & others like you are the reason all of this works! So thank you & happy coding! 🚀\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\"on\":\n  push:\n    branches:\n      - main\n      - next\n      - beta\n      - \"*.x\"\n      - debug\n# These are recommended by the semantic-release docs: https://github.com/semantic-release/npm#npm-provenance\npermissions:\n    contents: write # to be able to publish a GitHub release\n    issues: write # to be able to comment on released issues\n    pull-requests: write # to be able to comment on released pull requests\n    id-token: write # to enable use of OIDC for npm provenance\n\njobs:\n  release:\n    name: release\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - uses: actions/setup-node@v6\n        with:\n          node-version: lts/*\n          cache: npm\n      - run: npm ci\n      - run: npm run build\n      - run: npx semantic-release\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          NPM_TOKEN: ${{ secrets.OCTOKITBOT_NPM_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Test\n\"on\":\n  push:\n    branches:\n      - main\n  pull_request:\n    types:\n      - opened\n      - synchronize\njobs:\n  test_matrix:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node_version:\n          - 20\n          - 22\n          - 24\n    steps:\n      - uses: actions/checkout@v6\n      - name: Use Node.js ${{ matrix.node_version }}\n        uses: actions/setup-node@v6\n        with:\n          node-version: ${{ matrix.node_version }}\n          cache: npm\n      - run: npm ci\n      - run: npm test\n  test:\n    runs-on: ubuntu-latest\n    needs: test_matrix\n    steps:\n      - run: exit 1\n        if: ${{ needs.test_matrix.result != 'success' }}\n      - uses: actions/checkout@v6\n      - uses: actions/setup-node@v6\n        with:\n          node-version: \"lts/*\"\n          cache: npm\n      - run: npm ci\n      - run: npm run test:typescript\n      - run: npm run lint\n      - run: npm run build\n    if: ${{ always() }}\n"
  },
  {
    "path": ".github/workflows/update-prettier.yml",
    "content": "name: Update Prettier\n\"on\":\n  push:\n    branches:\n      - renovate/prettier-*\n  workflow_dispatch: {}\njobs:\n  update_prettier:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - uses: actions/setup-node@v6\n        with:\n          cache: npm\n          node-version: lts/*\n      - run: npm ci\n      - run: npm run lint:fix\n      - uses: gr2m/create-or-update-pull-request-action@v1.x\n        env:\n          GITHUB_TOKEN: ${{ secrets.OCTOKITBOT_PAT }}\n        with:\n          title: Prettier updated\n          body: An update to prettier required updates to your code.\n          branch: ${{ github.ref }}\n          commit-message: \"style: prettier\"\n"
  },
  {
    "path": ".gitignore",
    "content": "coverage/\nnode_modules/\npkg/\n.idea/\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, gender identity and expression, level of experience,\nnationality, personal appearance, race, religion, or sexual identity and\norientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n- Using welcoming and inclusive language\n- Being respectful of differing viewpoints and experiences\n- Gracefully accepting constructive criticism\n- Focusing on what is best for the community\n- Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n- The use of sexualized language or imagery and unwelcome sexual attention or\n  advances\n- Trolling, insulting/derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n- Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at opensource+octokit@github.com. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at [https://contributor-covenant.org/version/1/4][version]\n\n[homepage]: https://contributor-covenant.org\n[version]: https://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# How to contribute\n\nPlease note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md).\nBy participating in this project you agree to abide by its terms.\n\nWe appreciate you taking the time to contribute to `octokit` or any of the projects in Octokit's ecosystem. Especially as a new contributor, you have a valuable perspective that we lost a long time ago: you will find things confusing and run into problems that no longer occur to us. Please share them with us, so we can make the experience for future contributors the best it could be.\n\nThank you 💖\n\n## Creating an Issue\n\nBefore you create a new Issue:\n\n1. Please make sure there is no open issue in the **Issues Section** of the repository you are working on yet. i.e. <https://github.com/octokit/octokit.js/issues?utf8=%E2%9C%93&q=is%3Aissue>\n2. If it is a bug report, include the steps to reproduce the issue, and please create a reproducible test case on [runkit.com](https://runkit.com/). Example: <https://runkit.com/gr2m/octokit-rest-js-1808>\n3. If it is a feature request, please share the motivation for the new feature, what alternatives you tried, and how you would implement it.\n4. Please include links to the corresponding GitHub documentation.\n\n## Set up the repository locally\n\nFirst, fork the repository.\n\nSet up the repository locally. Replace `<your account name>` with the name of the account you forked to and `<repository name>` with the repository name you forked.\n\n```shell\ngit clone https://github.com/<your account name>/<repository name>.git\ncd <repository name>\nnpm install\n```\n\nRun the tests before making changes to make sure the local setup is working as expected\n\n```shell\nnpm test\n```\n\n## Submitting the Pull Request\n\n- Create a new branch locally.\n- Make your changes in that branch and push them to your fork\n- Submit a pull request from your topic branch to the main branch on the `octokit/<repository name>` repository.\n- Be sure to tag any issues your pull request is taking care of / contributing to. Adding \"Closes #123\" to a pull request description will automatically close the issue once the pull request is merged in.\n\n## Testing a pull request from GitHub repo locally\n\nYou can install `@octokit/<repository name>` from each pull request. Replace `[PULL REQUEST NUMBER]`:\n\n```\nnpm install https://github.pika.dev/octokit/<repository name>/pr/[PULL REQUEST NUMBER]\n```\n\nOnce you are done testing, you can revert to the default module `@octokit/<repository name>` from npm with `npm install @octokit/<repository name>`\n\n## Maintainers\n\nSee [MAINTAINING.md](MAINTAINING.md)\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License\n\nCopyright (c) 2023 Octokit contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "MAINTAINING.md",
    "content": "# Maintenance releases\n\n## Merging the Pull Request & releasing a new version\n\nReleases are automated using [semantic-release](https://github.com/semantic-release/semantic-release).\nThe following commit message conventions determine which version is released:\n\n1. `fix: ...` or `fix(scope name): ...` prefix in subject: bumps fix version, e.g. `1.2.3` → `1.2.4`\n2. `feat: ...` or `feat(scope name): ...` prefix in subject: bumps feature version, e.g. `1.2.3` → `1.3.0`\n3. `BREAKING CHANGE:` in body: bumps breaking version, e.g. `1.2.3` → `2.0.0`\n\nOnly one version number is bumped at a time, the highest version change trumps the others.\nBesides, publishing a new version to npm, semantic-release also creates a git tag and release\non GitHub, generates changelogs from the commit messages and puts them into the release notes.\n\nBefore the publish it runs the `npm run build` script which creates a `pkg/` folder with distributions for browsers, node and Typescript definitions. The contents of the `pkg/` folder are published to the npm registry.\n\nIf the pull request looks good but does not follow the commit conventions, use the <kbd>Squash & merge</kbd> button.\n\n> ⚠️ making sure the message is semantic-release compliant before clicking <kbd>Confirm squash and merge</kbd>:\n\n![Screenshot of GitHub's Squash and Merge confirm dialog](assets/squash-and-merge-dialog.png)]\n\n## Breaking changes\n\nWhen merging a breaking change using the PR body as specified above, extra care must be taken. Breaking changes must first be merged into the `beta` branch, where further testing may be conducted and additional breaking changes may be combined before cutting a release. The `beta` branch should be created for this purpose and based on `main`. Once the first commit to the branch is landed, a draft PR should be created from `beta` to `main` with the title vX, where X is the next major version. After changes are combined and tested, mark the PR as ready for review, get it reviewed, and merge the `beta` branch into `main` as documented above. `beta` branches are intended to be short-lived.\n\nNote the repository for the change: if it's dependent on other repos where the same change must be made, merge the leaf nodes first before the nodes higher up the tree. Your merge order should look something like:\n\n1. octokit/types (when type changes are required)\n1. endpoint\n1. request\n1. plugins\n1. auth strategies\n1. core\n1. \\*-methods\n1. oauth-app\n1. webhooks\n1. app\n1. octokit/octokit.js\n1. octokit/rest.js\n\n## Maintenance releases\n\n### 0. Requirements\n\n`semantic-release` is configured in the `package.json` of each repository. If `release.branches` is set, make sure that it includes the line for maintenance releases, for example\n\n```js\n  \"release\": {\n    \"branches\": [\n      \"+([0-9]).x\",\n      \"main\",\n      \"beta\"\n    ],\n```\n\n`semantic-release` is run in the`.github/workflows/release.yml` GitHub Action workflow. Make sure it's triggered on push in the `*.x` release branches.\n\n```yml\nname: Release\n\"on\":\n  push:\n    branches:\n      - main\n      - next\n      - beta\n      - \"*.x\"\n```\n\n### 1. Create a branch for the maintenance version\n\nFind the latest version that was released on the maintenance version. For example, if the current version is 3.1, and you want to release maintenance versions for 2.x, then find the latest 2.x version. Say that's 2.10.9. In that example, create a branch based on this tag\n\n```\ngit checkout -b 2.x v2.10.9\n```\n\nThen push the new `2.x` branch to GitHub\n\n```\ngit push -u origin HEAD\n```\n\n### 2. Create a pull request with the changes for the new maintenance release\n\nCheckout a branch based on the latest maintenance branch, for example\n\n```\ngit checkout -b 2.x-my-fix 2.x\n```\n\nCommit your changes, then push the branch to GitHub and create a pull request with the maintenance branch as base.\n\n### 3. Merge the pull request with the correct commit message\n\nNote that maintenance versions only support `fix: ...` and `feat: ...` commits, no breaking versions can be released from a maintenance release.\n\nThe `.github/workflows/release.yml` action should pick up the commit and release the correct version to both GitHub and npm. The npm release will use a `@release-*.x` tag so that the new release is not picked up as `@latest`.\n\n## Troubleshooting\n\n<details>\n  <summary>What can I do if I <i>squashed and merged</i> with a commit message which is not <a href=\"https://github.com/semantic-release/semantic-release\">semantic-release</a> compliant?</summary>\n\n1. After merging, do a follow up on `https://github.com/octokit/<repository name>/actions/workflows/release.yml` to assure your commit is not triggering any release. You can find an example of a commit squashed and merged with a non semantic-release commit message [here](https://github.com/octokit/plugin-throttling.js/runs/5390685684?check_suite_focus=true)\n2. Mention (`@username`) the maintainers of the project in your merged _Pull Request_ to let them know there was an issue with your merged _Pull Request_. We need to make sure no _Pull Request_ is merged until this issue is addressed.\n3. Open a new _Pull Request_ with an [empty commit](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---allow-empty). In the description, link to the previous merged _Pull Request_ to give context to the reviewers and request a Review from the maintainers. This time make sure the message is [semantic-release](https://github.com/semantic-release/semantic-release) compliant.\n\n</details>\n"
  },
  {
    "path": "README.md",
    "content": "# octokit.js\n\n> The all-batteries-included GitHub SDK for Browsers, Node.js, and Deno.\n\nThe `octokit` package integrates the three main Octokit libraries\n\n1. **API client** (REST API requests, GraphQL API queries, Authentication)\n2. **App client** (GitHub App & installations, Webhooks, OAuth)\n3. **Action client** (Pre-authenticated API client for single repository)\n\n## Table of contents <!-- omit in toc -->\n\n<!-- toc -->\n\n- [octokit.js](#octokitjs)\n  - [Features](#features)\n  - [Usage](#usage)\n  - [`Octokit` API Client](#octokit-api-client)\n    - [Constructor options](#constructor-options)\n    - [Authentication](#authentication)\n    - [Proxy Servers (Node.js only)](#proxy-servers-nodejs-only)\n      - [Fetch missing](#fetch-missing)\n    - [REST API](#rest-api)\n      - [`octokit.rest` endpoint methods](#octokitrest-endpoint-methods)\n      - [`octokit.request()`](#octokitrequest)\n      - [Pagination](#pagination)\n      - [Media Type formats](#media-type-formats)\n      - [Request error handling](#request-error-handling)\n    - [GraphQL API queries](#graphql-api-queries)\n      - [Pagination](#pagination-1)\n      - [Schema previews](#schema-previews)\n  - [App client](#app-client)\n    - [GitHub App](#github-app)\n    - [Webhooks](#webhooks)\n    - [OAuth](#oauth)\n    - [App Server](#app-server)\n    - [OAuth for browser apps](#oauth-for-browser-apps)\n  - [Action client](#action-client)\n  - [LICENSE](#license)\n\n<!-- tocstop -->\n\n## Features\n\n- **Complete**. All features of GitHub's platform APIs are covered.\n- **Prescriptive**. All recommended best practices are implemented.\n- **Universal**. Works in all modern browsers, [Node.js](https://nodejs.org/), and [Deno](https://deno.land/).\n- **Tested**. All libraries have a 100% test coverage.\n- **Typed**. All libraries have extensive TypeScript declarations.\n- **Decomposable**. Use only the code you need. You can build your own Octokit in only a few lines of code or use the underlying static methods. Make your own tradeoff between functionality and bundle size.\n- **Extendable**. A feature missing? Add functionalities with plugins, hook into the request or webhook lifecycle or implement your own authentication strategy.\n\n## Usage\n\n<table>\n<tbody valign=top align=left>\n<tr><th>\nBrowsers\n</th><td width=100%>\nLoad <code>octokit</code> directly from <a href=\"https://esm.sh\">esm.sh</a>\n        \n```html\n<script type=\"module\">\nimport { Octokit, App } from \"https://esm.sh/octokit\";\n</script>\n```\n\n</td></tr>\n<tr><th>\nDeno\n</th><td width=100%>\nLoad <code>octokit</code> directly from <a href=\"https://esm.sh\">esm.sh</a>\n        \n```ts\nimport { Octokit, App } from \"https://esm.sh/octokit?dts\";\n```\n\n</td></tr>\n<tr><th>\nNode\n</th><td>\n\nInstall with <code>npm/pnpm install octokit</code>, or <code>yarn add octokit</code>\n\n```js\nimport { Octokit, App } from \"octokit\";\n```\n\n</td></tr>\n</tbody>\n</table>\n\n> [!IMPORTANT]\n> As we use [conditional exports](https://nodejs.org/api/packages.html#conditional-exports), you will need to adapt your `tsconfig.json` by setting `\"moduleResolution\": \"node16\", \"module\": \"node16\"`.\n>\n> See the TypeScript docs on [package.json \"exports\"](https://www.typescriptlang.org/docs/handbook/modules/reference.html#packagejson-exports).<br>\n> See this [helpful guide on transitioning to ESM](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) from [@sindresorhus](https://github.com/sindresorhus)\n\n## `Octokit` API Client\n\n**standalone minimal Octokit**: [`@octokit/core`](https://github.com/octokit/core.js/#readme).\n\nThe `Octokit` client can be used to send requests to [GitHub's REST API](https://docs.github.com/rest/) and queries to [GitHub's GraphQL API](https://docs.github.com/graphql).\n\n**Example**: Get the username for the authenticated user.\n\n```js\n// Create a personal access token at https://github.com/settings/tokens/new?scopes=repo\nconst octokit = new Octokit({ auth: `personal-access-token123` });\n\n// Compare: https://docs.github.com/en/rest/reference/users#get-the-authenticated-user\nconst {\n  data: { login },\n} = await octokit.rest.users.getAuthenticated();\nconsole.log(\"Hello, %s\", login);\n```\n\n### Constructor options\n\nThe most commonly used options are\n\n<table>\n  <thead align=left>\n    <tr>\n      <th>\n        name\n      </th>\n      <th>\n        type\n      </th>\n      <th width=100%>\n        description\n      </th>\n    </tr>\n  </thead>\n  <tbody align=left valign=top>\n    <tr>\n      <th>\n        <code>userAgent</code>\n      </th>\n      <td>\n        <code>String</code>\n      </td>\n      <td>\n\nSetting a user agent is required for all requests sent to GitHub's Platform APIs. The user agent defaults to something like this: `octokit.js/v1.2.3 Node.js/v8.9.4 (macOS High Sierra; x64)`. It is recommend to set your own user agent, which will prepend the default one.\n\n```js\nconst octokit = new Octokit({\n  userAgent: \"my-app/v1.2.3\",\n});\n```\n\n</td>\n    </tr>\n    <tr>\n      <th>\n        <code>authStrategy</code>\n      </th>\n      <td>\n        <code>Function</code>\n      </td>\n      <td>\n\nDefaults to [`@octokit/auth-token`](https://github.com/octokit/auth-token.js#readme).\n\nSee [Authentication](#authentication) below.\n\n</td>\n    </tr>\n    <tr>\n      <th>\n        <code>auth</code>\n      </th>\n      <td>\n        <code>String</code> or <code>Object</code>\n      </td>\n      <td>\n\nSet to a [personal access token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) unless you changed the `authStrategy` option.\n\nSee [Authentication](#authentication) below.\n\n</td>\n    </tr>\n    <tr>\n      <th>\n        <code>baseUrl</code>\n      </th>\n      <td>\n        <code>String</code>\n      </td>\n      <td>\n\nWhen using with GitHub Enterprise Server, set `options.baseUrl` to the root URL of the API. For example, if your GitHub Enterprise Server's hostname is `github.acme-inc.com`, then set `options.baseUrl` to `https://github.acme-inc.com/api/v3`. Example\n\n```js\nconst octokit = new Octokit({\n  baseUrl: \"https://github.acme-inc.com/api/v3\",\n});\n```\n\n</td>\n    </tr>\n  </tbody>\n</table>\n\nAdvanced options\n\n<table>\n  <thead align=left>\n    <tr>\n      <th>\n        name\n      </th>\n      <th>\n        type\n      </th>\n      <th width=100%>\n        description\n      </th>\n    </tr>\n  </thead>\n  <tbody align=left valign=top>\n    <tr>\n      <th>\n        <code>request</code>\n      </th>\n      <td>\n        <code>Object</code>\n      </td>\n      <td>\n\n- `request.signal`: Use an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) instance to cancel a request. [`abort-controller`](https://www.npmjs.com/package/abort-controller) is an implementation for Node.\n- `request.fetch`: Replacement for [built-in fetch method](<https://nodejs.org/en/blog/announcements/v18-release-announce#fetch-(experimental)>).\n\nNode only\n\n- `request.timeout` sets a request timeout, defaults to 0\n\nThe `request` option can also be set on a per-request basis.\n\n</td></tr>\n    <tr>\n      <th>\n        <code>timeZone</code>\n      </th>\n      <td>\n        <code>String</code>\n      </td>\n      <td>\n\nSets the `Time-Zone` header which defines a timezone according to the [list of names from the Olson database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).\n\n```js\nconst octokit = new Octokit({\n  timeZone: \"America/Los_Angeles\",\n});\n```\n\nThe time zone header will determine the timezone used for generating the timestamp when creating commits. See [GitHub's Timezones documentation](https://developer.github.com/v3/#timezones).\n\n</td>\n    </tr>\n    <tr>\n      <th>\n        <code>throttle</code>\n      </th>\n      <td>\n        <code>Object</code>\n      </td>\n      <td>\n\n`Octokit` implements request throttling using [`@octokit/plugin-throttling`](https://github.com/octokit/plugin-throttling.js/#readme)\n\nBy default, requests are retried once and warnings are logged in case of hitting a rate or secondary rate limit.\n\n```js\n{\n  onRateLimit: (retryAfter, options, octokit) => {\n    octokit.log.warn(\n      `Request quota exhausted for request ${options.method} ${options.url}`\n    );\n\n    if (options.request.retryCount === 0) {\n      // only retries once\n      octokit.log.info(`Retrying after ${retryAfter} seconds!`);\n      return true;\n    }\n  },\n  onSecondaryRateLimit: (retryAfter, options, octokit) => {\n    octokit.log.warn(\n      `SecondaryRateLimit detected for request ${options.method} ${options.url}`\n    );\n\n    if (options.request.retryCount === 0) {\n      // only retries once\n      octokit.log.info(`Retrying after ${retryAfter} seconds!`);\n      return true;\n    }\n  },\n};\n```\n\nTo opt-out of this feature:\n\n```js\nnew Octokit({ throttle: { enabled: false } });\n```\n\nThrottling in a cluster is supported using a Redis backend. See [`@octokit/plugin-throttling` Clustering](https://github.com/octokit/plugin-throttling.js/#clustering)\n\n</td>\n  </tr>\n   <tr>\n      <th>\n        <code>retry</code>\n      </th>\n      <td>\n        <code>Object</code>\n      </td>\n      <td>\n\n`Octokit` implements request retries using [`@octokit/plugin-retry`](https://github.com/octokit/plugin-retry.js/#readme)\n\nTo opt-out of this feature:\n\n```js\nnew Octokit({ retry: { enabled: false } });\n```\n\n</td>\n    </tr>\n  </tbody>\n</table>\n\n### Authentication\n\nBy default, the `Octokit` API client supports authentication using a static token.\n\nThere are different means of authentication that are supported by GitHub, that are described in detail at [octokit/authentication-strategies.js](https://github.com/octokit/authentication-strategies.js/#readme). You can set each of them as the `authStrategy` constructor option, and pass the strategy options as the `auth` constructor option.\n\nFor example, in order to authenticate as a GitHub App Installation:\n\n```js\nimport { createAppAuth } from \"@octokit/auth-app\";\nconst octokit = new Octokit({\n  authStrategy: createAppAuth,\n  auth: {\n    appId: 1,\n    privateKey: \"-----BEGIN PRIVATE KEY-----\\n...\",\n    installationId: 123,\n  },\n});\n\n// authenticates as app based on request URLs\nconst {\n  data: { slug },\n} = await octokit.rest.apps.getAuthenticated();\n\n// creates an installation access token as needed\n// assumes that installationId 123 belongs to @octocat, otherwise the request will fail\nawait octokit.rest.issues.create({\n  owner: \"octocat\",\n  repo: \"hello-world\",\n  title: \"Hello world from \" + slug,\n});\n```\n\nYou can use the [`App`](#github-app) or [`OAuthApp`](#oauth-app) SDKs which provide APIs and internal wiring to cover most use cases.\n\nFor example, to implement the above using `App`\n\n```js\nconst app = new App({ appId, privateKey });\nconst { data: slug } = await app.octokit.rest.apps.getAuthenticated();\nconst octokit = await app.getInstallationOctokit(123);\nawait octokit.rest.issues.create({\n  owner: \"octocat\",\n  repo: \"hello-world\",\n  title: \"Hello world from \" + slug,\n});\n```\n\nLearn more about [how authentication strategies work](https://github.com/octokit/authentication-strategies.js/#how-authentication-strategies-work) or how to [create your own](https://github.com/octokit/authentication-strategies.js/#create-your-own-octokit-authentication-strategy-module).\n\n### Proxy Servers (Node.js only)\n\nBy default, the `Octokit` API client does not make use of the standard proxy server environment variables. To add support for proxy servers you will need to provide an https client that supports them such as [`undici.ProxyAgent()`](https://undici.nodejs.org/#/docs/api/ProxyAgent).\n\nFor example, this would use a `ProxyAgent` to make requests through a proxy server:\n\n```js\nimport { fetch as undiciFetch, ProxyAgent } from 'undici';\n\nconst myFetch = (url, options) => {\n  return undiciFetch(url, {\n    ...options,\n    dispatcher: new ProxyAgent(<your_proxy_url>)\n  })\n}\n\nconst octokit = new Octokit({\n  request: {\n     fetch: myFetch\n  },\n});\n```\n\nIf you are writing a module that uses `Octokit` and is designed to be used by other people, you should ensure that consumers can provide an alternative agent for your `Octokit` or as a parameter to specific calls such as:\n\n```js\nimport { fetch as undiciFetch, ProxyAgent } from 'undici';\n\nconst myFetch = (url, options) => {\n  return undiciFetch(url, {\n    ...options,\n    dispatcher: new ProxyAgent(<your_proxy_url>)\n  })\n}\n\noctokit.rest.repos.get({\n  owner,\n  repo,\n  request: {\n    fetch: myFetch\n  },\n});\n```\n\n#### Fetch missing\n\nIf you get the following error:\n\n> fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}).\n\nIt probably means you are trying to run Octokit with an unsupported version of NodeJS. Octokit requires Node 18 or higher, [which includes a native fetch API](<https://nodejs.org/en/blog/announcements/v18-release-announce#fetch-(experimental)>).\n\nTo bypass this problem you can provide your own `fetch` implementation (or a built-in version like `node-fetch`) like this:\n\n```js\nimport fetch from \"node-fetch\";\n\nconst octokit = new Octokit({\n  request: {\n    fetch: fetch,\n  },\n});\n```\n\n### REST API\n\nThere are two ways of using the GitHub REST API, the [`octokit.rest.*` endpoint methods](#octokitrest-endpoint-methods) and [`octokit.request`](#octokitrequest). Both act the same way, the `octokit.rest.*` methods are just added for convenience, they use `octokit.request` internally.\n\nFor example\n\n```js\nawait octokit.rest.issues.create({\n  owner: \"octocat\",\n  repo: \"hello-world\",\n  title: \"Hello, world!\",\n  body: \"I created this issue using Octokit!\",\n});\n```\n\nIs the same as\n\n```js\nawait octokit.request(\"POST /repos/{owner}/{repo}/issues\", {\n  owner: \"octocat\",\n  repo: \"hello-world\",\n  title: \"Hello, world!\",\n  body: \"I created this issue using Octokit!\",\n});\n```\n\nIn both cases a given request is authenticated, retried, and throttled transparently by the `octokit` instance which also manages the `accept` and `user-agent` headers as needed.\n\n`octokit.request` can be used to send requests to other domains by passing a full URL and to send requests to endpoints that are not (yet) documented in [GitHub's REST API documentation](https://docs.github.com/rest).\n\n#### `octokit.rest` endpoint methods\n\nEvery GitHub REST API endpoint has an associated `octokit.rest` endpoint method for better code readability and developer convenience. See [`@octokit/plugin-rest-endpoint-methods`](https://github.com/octokit/plugin-rest-endpoint-methods.js/#readme) for full details.\n\nExample: [Create an issue](https://docs.github.com/en/rest/reference/issues#create-an-issue)\n\n```js\nawait octokit.rest.issues.create({\n  owner: \"octocat\",\n  repo: \"hello-world\",\n  title: \"Hello, world!\",\n  body: \"I created this issue using Octokit!\",\n});\n```\n\nThe `octokit.rest` endpoint methods are generated automatically from [GitHub's OpenAPI specification](https://github.com/github/rest-api-description/). We track operation ID and parameter name changes in order to implement deprecation warnings and reduce the frequency of breaking changes.\n\nUnder the covers, every endpoint method is just `octokit.request` with defaults set, so it supports the same parameters as well as the `.endpoint()` API.\n\n#### `octokit.request()`\n\nYou can call the GitHub REST API directly using `octokit.request`. The `request` API matches GitHub's REST API documentation 1:1 so anything you see there, you can call using `request`. See [`@octokit/request`](https://github.com/octokit/request.js#readme) for all the details.\n\nExample: [Create an issue](https://docs.github.com/en/rest/reference/issues#create-an-issue)\n\n[![Screenshot of REST API reference documentation for Create an issue](assets/create-an-issue-reference.png)](https://docs.github.com/en/rest/reference/issues#create-an-issue)\n\nThe `octokit.request` API call corresponding to that issue creation documentation looks like this:\n\n```js\n// https://docs.github.com/en/rest/reference/issues#create-an-issue\nawait octokit.request(\"POST /repos/{owner}/{repo}/issues\", {\n  owner: \"octocat\",\n  repo: \"hello-world\",\n  title: \"Hello, world!\",\n  body: \"I created this issue using Octokit!\",\n});\n```\n\nThe 1st argument is the REST API route as listed in GitHub's API documentation. The 2nd argument is an object with all parameters, independent of whether they are used in the path, query, or body.\n\n#### Pagination\n\nAll REST API endpoints that paginate return the first 30 items by default. If you want to retrieve all items, you can use the pagination API. The pagination API expects the REST API route as first argument, but you can also pass any of the `octokit.rest.*.list*` methods for convenience and better code readability.\n\nExample: iterate through all issues in a repository\n\n```js\nconst iterator = octokit.paginate.iterator(octokit.rest.issues.listForRepo, {\n  owner: \"octocat\",\n  repo: \"hello-world\",\n  per_page: 100,\n});\n\n// iterate through each response\nfor await (const { data: issues } of iterator) {\n  for (const issue of issues) {\n    console.log(\"Issue #%d: %s\", issue.number, issue.title);\n  }\n}\n```\n\nUsing the [async iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) is the most memory efficient way to iterate through all items. But you can also retrieve all items in a single call\n\n```js\nconst issues = await octokit.paginate(octokit.rest.issues.listForRepo, {\n  owner: \"octocat\",\n  repo: \"hello-world\",\n  per_page: 100,\n});\n```\n\n#### Media Type formats\n\nMedia type formats can be set using `mediaType: { format }` on every request.\n\nExample: retrieve the raw content of a `package.json` file\n\n```js\nconst { data } = await octokit.rest.repos.getContent({\n  mediaType: {\n    format: \"raw\",\n  },\n  owner: \"octocat\",\n  repo: \"hello-world\",\n  path: \"package.json\",\n});\nconsole.log(\"package name: %s\", JSON.parse(data).name);\n```\n\nLearn more about [Media type formats](https://docs.github.com/en/rest/overview/media-types).\n\n#### Request error handling\n\n**Standalone module:** [`@octokit/request-error`](https://github.com/octokit/request-error.js/#readme)\n\nFor request error handling, import `RequestError` and use `try...catch` statement.\n\n```typescript\nimport { RequestError } from \"octokit\";\n```\n\n```typescript\ntry {\n  // your code here that sends at least one Octokit request\n  await octokit.request(\"GET /\");\n} catch (error) {\n  // Octokit errors are instances of RequestError, so they always have an `error.status` property containing the HTTP response code.\n  if (error instanceof RequestError) {\n    // handle Octokit error\n    // error.message; // Oops\n    // error.status; // 500\n    // error.request; // { method, url, headers, body }\n    // error.response; // { url, status, headers, data }\n  } else {\n    // handle all other errors\n    throw error;\n  }\n}\n```\n\n### GraphQL API queries\n\nOctokit also supports GitHub's GraphQL API directly -- you can use the same queries shown in the documentation and available in the GraphQL explorer in your calls with `octokit.graphql`.\n\nExample: get the login of the authenticated user\n\n```js\nconst {\n  viewer: { login },\n} = await octokit.graphql(`{\n  viewer {\n    login\n  }\n}`);\n```\n\nVariables can be passed as 2nd argument\n\n```js\nconst { lastIssues } = await octokit.graphql(\n  `\n    query lastIssues($owner: String!, $repo: String!, $num: Int = 3) {\n      repository(owner: $owner, name: $repo) {\n        issues(last: $num) {\n          edges {\n            node {\n              title\n            }\n          }\n        }\n      }\n    }\n  `,\n  {\n    owner: \"octokit\",\n    repo: \"graphql.js\",\n  },\n);\n```\n\n#### Pagination\n\nGitHub's GraphQL API returns a maximum of 100 items. If you want to retrieve all items, you can use the pagination API.\n\nExample: get all issues\n\n```js\nconst { allIssues } = await octokit.graphql.paginate(\n  `\n    query allIssues($owner: String!, $repo: String!, $num: Int = 10, $cursor: String) {\n      repository(owner: $owner, name: $repo) {\n        issues(first: $num, after: $cursor) {\n          edges {\n            node {\n              title\n            }\n          }\n          pageInfo {\n            hasNextPage\n            endCursor\n          }\n        }\n      }\n    }\n  `,\n  {\n    owner: \"octokit\",\n    repo: \"graphql.js\",\n  },\n);\n```\n\nLearn more about [GitHub's GraphQL Pagination](https://github.com/octokit/plugin-paginate-graphql.js#readme) usage.\n\n#### Schema previews\n\nPreviews can be enabled using the `{mediaType: previews: [] }` option.\n\nExample: create a label\n\n```js\nawait octokit.graphql(\n  `mutation createLabel($repositoryId:ID!,name:String!,color:String!) {\n  createLabel(input:{repositoryId:$repositoryId,name:$name}) {\n    label: {\n      id\n    }\n  }\n}`,\n  {\n    repositoryId: 1,\n    name: \"important\",\n    color: \"cc0000\",\n    mediaType: {\n      previews: [\"bane\"],\n    },\n  },\n);\n```\n\nLearn more about [GitHub's GraphQL schema previews](https://docs.github.com/en/graphql/overview/schema-previews)\n\n## App client\n\nThe `App` client combines features for GitHub Apps, Webhooks, and OAuth\n\n### GitHub App\n\n**Standalone module**: [`@octokit/app`](https://github.com/octokit/app.js/#readme)\n\nFor integrators, GitHub Apps are a means of authentication and authorization. A GitHub app can be registered on a GitHub user or organization account. A GitHub App registration defines a set of permissions and webhooks events it wants to receive and provides a set of credentials in return. Users can grant access to repositories by installing them.\n\nSome API endpoints require the GitHub app to authenticate as itself using a JSON Web Token (JWT). For requests affecting an installation, an installation access token has to be created using the app's credentials and the installation ID.\n\nThe `App` client takes care of all that for you.\n\nExample: Dispatch a repository event in every repository the app is installed on\n\n```js\nimport { App } from \"octokit\";\n\nconst app = new App({ appId, privateKey });\n\nfor await (const { octokit, repository } of app.eachRepository.iterator()) {\n  // https://docs.github.com/en/rest/reference/repos#create-a-repository-dispatch-event\n  await octokit.rest.repos.createDispatchEvent({\n    owner: repository.owner.login,\n    repo: repository.name,\n    event_type: \"my_event\",\n    client_payload: {\n      foo: \"bar\",\n    },\n  });\n  console.log(\"Event dispatched for %s\", repository.full_name);\n}\n```\n\nExample: Get an `octokit` instance authenticated as an installation\n\n```js\nconst octokit = await app.getInstallationOctokit(123);\n```\n\nLearn more about [apps](https://docs.github.com/apps).\n\n### Webhooks\n\n**Standalone module**: [`@octokit/webhooks`](https://github.com/octokit/webhooks.js/#readme)\n\nWhen installing an app, events that the app registration requests will be sent as requests to the webhook URL set in the app's registration.\n\nWebhook event requests are signed using the webhook secret, which is also part of the app's registration. You must verify that secret before handling the request payload.\n\nThe `app.webhooks.*` APIs provide methods to receiving, verifying, and handling webhook events.\n\nExample: create a comment on new issues\n\n```js\nimport { createServer } from \"node:http\";\nimport { App, createNodeMiddleware } from \"octokit\";\n\nconst app = new App({\n  appId,\n  privateKey,\n  webhooks: { secret },\n});\n\napp.webhooks.on(\"issues.opened\", ({ octokit, payload }) => {\n  return octokit.rest.issues.createComment({\n    owner: payload.repository.owner.login,\n    repo: payload.repository.name,\n    issue_number: payload.issue.number,\n    body: \"Hello, World!\",\n  });\n});\n\n// Your app can now receive webhook events at `/api/github/webhooks`\ncreateServer(createNodeMiddleware(app)).listen(3000);\n```\n\nFor serverless environments, you can explicitly verify and receive an event\n\n```js\nawait app.webhooks.verifyAndReceive({\n  id: request.headers[\"x-github-delivery\"],\n  name: request.headers[\"x-github-event\"],\n  signature: request.headers[\"x-hub-signature-256\"],\n  payload: request.body,\n});\n```\n\nLearn more about [GitHub webhooks](https://docs.github.com/webhooks).\n\n### OAuth\n\n**Standalone module:** [`@octokit/oauth-app`](https://github.com/octokit/oauth-app.js/#readme)\n\nBoth OAuth Apps and GitHub Apps support authenticating GitHub users using OAuth, see [Authorizing OAuth Apps](https://docs.github.com/en/developers/apps/authorizing-oauth-apps) and [Identifying and authorizing users for GitHub Apps](https://docs.github.com/en/developers/apps/identifying-and-authorizing-users-for-github-apps).\n\nThere are some differences:\n\n- Only OAuth Apps support scopes. GitHub apps have permissions, and access is granted via installations of the app on repositories.\n- Only GitHub Apps support expiring user tokens\n- Only GitHub Apps support creating a scoped token to reduce the permissions and repository access\n\n`App` is for GitHub Apps. If you need OAuth App-specific functionality, use [`OAuthApp` instead](https://github.com/octokit/oauth-app.js/).\n\nExample: Watch a repository when a user logs in using the OAuth web flow\n\n```js\nimport { createServer } from \"node:http\";\nimport { App, createNodeMiddleware } from \"octokit\";\n\nconst app = new App({\n  oauth: { clientId, clientSecret },\n});\n\napp.oauth.on(\"token.created\", async ({ token, octokit }) => {\n  await octokit.rest.activity.setRepoSubscription({\n    owner: \"octocat\",\n    repo: \"hello-world\",\n    subscribed: true,\n  });\n});\n\n// Your app can receive the OAuth redirect at /api/github/oauth/callback\n// Users can initiate the OAuth web flow by opening /api/github/oauth/login\ncreateServer(createNodeMiddleware(app)).listen(3000);\n```\n\nFor serverless environments, you can explicitly exchange the `code` from the OAuth web flow redirect for an access token.\n`app.oauth.createToken()` returns an authentication object and emits the \"token.created\" event.\n\n```js\nconst { token } = await app.oauth.createToken({\n  code: request.query.code,\n});\n```\n\nExample: create a token using the device flow.\n\n```js\nconst { token } = await app.oauth.createToken({\n  async onVerification(verification) {\n    await sendMessageToUser(\n      request.body.phoneNumber,\n      `Your code is ${verification.user_code}. Enter it at ${verification.verification_uri}`,\n    );\n  },\n});\n```\n\nExample: Create an OAuth App Server with default scopes\n\n```js\nimport { createServer } from \"node:http\";\nimport { OAuthApp, createNodeMiddleware } from \"octokit\";\n\nconst app = new OAuthApp({\n  clientId,\n  clientSecret,\n  defaultScopes: [\"repo\", \"gist\"],\n});\n\napp.oauth.on(\"token\", async ({ token, octokit }) => {\n  await octokit.rest.gists.create({\n    description: \"I created this gist using Octokit!\",\n    public: true,\n    files: {\n      \"example.js\": `/* some code here */`,\n    },\n  });\n});\n\n// Your app can receive the OAuth redirect at /api/github/oauth/callback\n// Users can initiate the OAuth web flow by opening /api/oauth/login\ncreateServer(createNodeMiddleware(app)).listen(3000);\n```\n\n### App Server\n\nAfter registering your GitHub app, you need to create and deploy a server which can retrieve the webhook event requests from GitHub as well as accept redirects from the OAuth user web flow.\n\nThe simplest way to create such a server is to use `createNodeMiddleware()`, it works with both, Node's [`http.createServer()`](https://nodejs.org/api/http.html#http_http_createserver_options_requestlistener) method as well as an [Express middleware](https://expressjs.com/en/guide/using-middleware.html).\n\nThe default routes that the middleware exposes are\n\n| Route                                   | Route Description                                                                                                                                                                                                                                                                                                                                                             |\n| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `POST /api/github/webhooks`             | Endpoint to receive GitHub Webhook Event requests                                                                                                                                                                                                                                                                                                                             |\n| `GET /api/github/oauth/login`           | Redirects to GitHub's authorization endpoint. Accepts optional `?state` and `?scopes` query parameters. `?scopes` is a comma-separated list of [supported OAuth scope names](https://docs.github.com/en/developers/apps/scopes-for-oauth-apps#available-scopes)                                                                                                               |\n| `GET /api/github/oauth/callback`        | The client's redirect endpoint. This is where the `token` event gets triggered                                                                                                                                                                                                                                                                                                |\n| `POST /api/github/oauth/token`          | Exchange an authorization code for an OAuth Access token. If successful, the `token` event gets triggered.                                                                                                                                                                                                                                                                    |\n| `GET /api/github/oauth/token`           | Check if token is valid. Must authenticate using token in `Authorization` header. Uses GitHub's [`POST /applications/{client_id}/token`](https://docs.github.com/en/rest/reference/apps#check-a-token) endpoint                                                                                                                                                               |\n| `PATCH /api/github/oauth/token`         | Resets a token (invalidates current one, returns new token). Must authenticate using token in `Authorization` header. Uses GitHub's [`PATCH /applications/{client_id}/token`](https://docs.github.com/en/rest/reference/apps#reset-a-token) endpoint.                                                                                                                         |\n| `PATCH /api/github/oauth/refresh-token` | Refreshes an expiring token (invalidates current one, returns new access token and refresh token). Must authenticate using token in `Authorization` header. Uses GitHub's [`POST https://github.com/login/oauth/access_token`](https://docs.github.com/en/developers/apps/refreshing-user-to-server-access-tokens#renewing-a-user-token-with-a-refresh-token) OAuth endpoint. |\n| `POST /api/github/oauth/token/scoped`   | Creates a scoped token (does not invalidate the current one). Must authenticate using token in `Authorization` header. Uses GitHub's [`POST /applications/{client_id}/token/scoped`](https://docs.github.com/en/rest/reference/apps#create-a-scoped-access-token) endpoint.                                                                                                   |\n| `DELETE /api/github/oauth/token`        | Invalidates current token, basically the equivalent of a logout. Must authenticate using token in `Authorization` header.                                                                                                                                                                                                                                                     |\n| `DELETE /api/github/oauth/grant`        | Revokes the user's grant, basically the equivalent of an uninstall. must authenticate using token in `Authorization` header.                                                                                                                                                                                                                                                  |\n\nExample: create a GitHub server with express\n\n```js\nimport express from \"express\";\nimport { App, createNodeMiddleware } from \"octokit\";\n\nconst expressApp = express();\nconst octokitApp = new App({\n  appId,\n  privateKey,\n  webhooks: { secret },\n  oauth: { clientId, clientSecret },\n});\n\nexpressApp.use(createNodeMiddleware(app));\n\nexpressApp.listen(3000, () => {\n  console.log(`Example app listening at http://localhost:3000`);\n});\n```\n\n### OAuth for browser apps\n\nYou must not expose your app's client secret to the user, so you cannot use the `App` constructor. Instead, you have to create a server using the `App` constructor which exposes the `/api/github/oauth/*` routes, through which you can safely implement an OAuth login for apps running in a web browser.\n\nIf you set `(User) Authorization callback URL` to your own app, than you need to read out the `?code=...&state=...` query parameters, compare the `state` parameter to the value returned by `app.oauthLoginUrl()` earlier to protect against forgery attacks, then exchange the `code` for an OAuth Authorization token.\n\nIf you run an [app server](#app-server) as described above, the default route to do that is `POST /api/github/oauth/token`.\n\nOnce you successfully retrieved the token, it is also recommended to remove the `?code=...&state=...` query parameters from the browser's URL\n\n```js\nconst code = new URL(location.href).searchParams.get(\"code\");\nif (code) {\n  // remove ?code=... from URL\n  const path =\n    location.pathname +\n    location.search.replace(/\\b(code|state)=\\w+/g, \"\").replace(/[?&]+$/, \"\");\n  history.replaceState({}, \"\", path);\n\n  // exchange the code for a token with your backend.\n  // If you use https://github.com/octokit/oauth-app.js\n  // the exchange would look something like this\n  const response = await fetch(\"/api/github/oauth/token\", {\n    method: \"POST\",\n    headers: {\n      \"content-type\": \"application/json\",\n    },\n    body: JSON.stringify({ code }),\n  });\n  const { token } = await response.json();\n  // `token` is the OAuth Access Token that can be use\n\n  const { Octokit } = await import(\"https://esm.sh/@octokit/core\");\n  const octokit = new Octokit({ auth: token });\n\n  const {\n    data: { login },\n  } = await octokit.request(\"GET /user\");\n  alert(\"Hi there, \" + login);\n}\n```\n\n🚧 We are working on [`@octokit/auth-oauth-user-client`](https://github.com/octokit/auth-oauth-user-client.js#readme) to provide a simple API for all methods related to OAuth user tokens.\n\nThe plan is to add an new `GET /api/github/oauth/octokit.js` route to the node middleware which will return a JavaScript file that can be imported into an HTML file. It will make a pre-authenticated `octokit` Instance available.\n\n## Action client\n\n**standalone module:** [`@octokit/action`](https://github.com/octokit/action.js#readme)\n\n🚧 A fully fledged `Action` client is pending. You can use [`@actions/github`](https://github.com/actions/toolkit/tree/main/packages/github) for the time being\n\n## LICENSE\n\n[MIT](LICENSE)\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\nThanks for helping make GitHub Open Source Software safe for everyone.\n\nGitHub takes the security of our software products and services seriously, including all of the open source code repositories managed through our GitHub organizations, such as [Octokit](https://github.com/octokit).\n\nEven though [open source repositories are outside of the scope of our bug bounty program](https://bounty.github.com/index.html#scope) and therefore not eligible for bounty rewards, we want to make sure that your finding gets passed along to the maintainers of this project for remediation.\n\n## Reporting a Vulnerability\n\nSince this source is part of [Octokit](https://github.com/octokit) (a GitHub organization) we ask that you follow the guidelines [here](https://github.com/github/.github/blob/master/SECURITY.md#reporting-security-issues) to report anything that you might've found.\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"octokit\",\n  \"version\": \"0.0.0-development\",\n  \"type\": \"module\",\n  \"description\": \"The all-batteries-included GitHub SDK for Browsers, Node.js, and Deno\",\n  \"keywords\": [\n    \"github\",\n    \"api\",\n    \"sdk\",\n    \"octokit\"\n  ],\n  \"author\": \"Gregor Martynus (https://github.com/gr2m)\",\n  \"repository\": \"github:octokit/octokit.js\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"build\": \"node scripts/build.mjs && tsc -p tsconfig.json\",\n    \"lint\": \"prettier --check \\\"{src,test,scripts}/**/*.{js,json,ts}\\\" \\\"*.{md,json}\\\"\",\n    \"lint:fix\": \"prettier --write \\\"{src,test,scripts}/**/*.{js,json,ts,mjs}\\\" \\\"*.{md,json}\\\"\",\n    \"pretest\": \"npm run -s lint\",\n    \"test\": \"vitest run --coverage\",\n    \"test:typescript\": \"npx tsc --noEmit --declaration --noUnusedLocals --esModuleInterop --module node16 --strict --allowImportingTsExtensions --exactOptionalPropertyTypes test/typescript-validate.ts\"\n  },\n  \"dependencies\": {\n    \"@octokit/app\": \"^16.1.2\",\n    \"@octokit/core\": \"^7.0.6\",\n    \"@octokit/oauth-app\": \"^8.0.3\",\n    \"@octokit/plugin-paginate-graphql\": \"^6.0.0\",\n    \"@octokit/plugin-paginate-rest\": \"^14.0.0\",\n    \"@octokit/plugin-rest-endpoint-methods\": \"^17.0.0\",\n    \"@octokit/plugin-retry\": \"^8.0.3\",\n    \"@octokit/plugin-throttling\": \"^11.0.3\",\n    \"@octokit/request-error\": \"^7.0.2\",\n    \"@octokit/types\": \"^16.0.0\",\n    \"@octokit/webhooks\": \"^14.0.0\"\n  },\n  \"devDependencies\": {\n    \"@octokit/tsconfig\": \"^4.0.0\",\n    \"@types/node\": \"^24.0.0\",\n    \"@vitest/coverage-v8\": \"^4.0.0\",\n    \"esbuild\": \"^0.27.0\",\n    \"mockdate\": \"^3.0.5\",\n    \"nock\": \"^14.0.10\",\n    \"prettier\": \"3.7.4\",\n    \"semantic-release-plugin-update-version-in-files\": \"^2.0.0\",\n    \"tinyglobby\": \"^0.2.15\",\n    \"typescript\": \"^5.0.0\",\n    \"vitest\": \"^4.0.0\"\n  },\n  \"release\": {\n    \"branches\": [\n      \"+([0-9]).x\",\n      \"main\",\n      \"next\",\n      {\n        \"name\": \"beta\",\n        \"prerelease\": true\n      },\n      {\n        \"name\": \"debug\",\n        \"prerelease\": true\n      }\n    ],\n    \"plugins\": [\n      \"@semantic-release/commit-analyzer\",\n      \"@semantic-release/release-notes-generator\",\n      \"@semantic-release/github\",\n      [\n        \"@semantic-release/npm\",\n        {\n          \"pkgRoot\": \"./pkg\"\n        }\n      ],\n      [\n        \"semantic-release-plugin-update-version-in-files\",\n        {\n          \"files\": [\n            \"pkg/dist-web/*\",\n            \"pkg/dist-node/*\",\n            \"pkg/*/version.*\"\n          ]\n        }\n      ]\n    ]\n  },\n  \"engines\": {\n    \"node\": \">= 20\"\n  },\n  \"publishConfig\": {\n    \"provenance\": true\n  }\n}\n"
  },
  {
    "path": "scripts/build.mjs",
    "content": "// @ts-check\nimport esbuild from \"esbuild\";\nimport { copyFile, readFile, writeFile, rm } from \"node:fs/promises\";\nimport { glob } from \"tinyglobby\";\n\n/**\n * @type {esbuild.BuildOptions}\n */\nconst sharedOptions = {\n  sourcemap: \"external\",\n  sourcesContent: true,\n  minify: false,\n  allowOverwrite: true,\n  packages: \"external\",\n  platform: \"neutral\",\n  format: \"esm\",\n  target: \"es2022\",\n};\n\nasync function main() {\n  // Start with a clean slate\n  await rm(\"pkg\", { recursive: true, force: true });\n  // Build the source code for a neutral platform as ESM\n  await esbuild.build({\n    entryPoints: await glob([\"./src/*.ts\", \"./src/**/*.ts\"]),\n    outdir: \"pkg/dist-src\",\n    bundle: false,\n    ...sharedOptions,\n    sourcemap: false,\n  });\n\n  // Remove the types file from the dist-src folder\n  const typeFiles = await glob([\n    \"./pkg/dist-src/**/types.js.map\",\n    \"./pkg/dist-src/**/types.js\",\n  ]);\n  for (const typeFile of typeFiles) {\n    await rm(typeFile);\n  }\n\n  const entryPoints = [\"./pkg/dist-src/index.js\"];\n\n  // Build an ESM bundle\n  await esbuild.build({\n    entryPoints,\n    outdir: \"pkg/dist-bundle\",\n    bundle: true,\n    ...sharedOptions,\n  });\n\n  // Copy the README, LICENSE to the pkg folder\n  await copyFile(\"LICENSE\", \"pkg/LICENSE\");\n  await copyFile(\"README.md\", \"pkg/README.md\");\n\n  // Handle the package.json\n  let pkg = JSON.parse((await readFile(\"package.json\", \"utf8\")).toString());\n  // Remove unnecessary fields from the package.json\n  delete pkg.scripts;\n  delete pkg.prettier;\n  delete pkg.release;\n  delete pkg.jest;\n  await writeFile(\n    \"pkg/package.json\",\n    JSON.stringify(\n      {\n        ...pkg,\n        files: [\"dist-*/**\", \"bin/**\"],\n        types: \"./dist-types/index.d.ts\",\n        exports: {\n          \".\": {\n            types: \"./dist-types/index.d.ts\",\n            import: \"./dist-bundle/index.js\",\n            default: \"./dist-bundle/index.js\",\n          },\n        },\n        sideEffects: false,\n      },\n      null,\n      2,\n    ),\n  );\n}\nmain();\n"
  },
  {
    "path": "src/app.ts",
    "content": "import { App as DefaultApp } from \"@octokit/app\";\nimport { OAuthApp as DefaultOAuthApp } from \"@octokit/oauth-app\";\n\nimport { Octokit } from \"./octokit.js\";\n\nexport const App = DefaultApp.defaults({ Octokit });\nexport type App = InstanceType<typeof App>;\n\nexport const OAuthApp = DefaultOAuthApp.defaults({ Octokit });\nexport type OAuthApp = InstanceType<typeof OAuthApp>;\n\nexport { createNodeMiddleware } from \"@octokit/app\";\n"
  },
  {
    "path": "src/index.ts",
    "content": "export { Octokit, RequestError } from \"./octokit.js\";\nexport type { PageInfoForward, PageInfoBackward } from \"./octokit.js\";\nexport { App, OAuthApp, createNodeMiddleware } from \"./app.js\";\n"
  },
  {
    "path": "src/octokit.ts",
    "content": "import { Octokit as OctokitCore } from \"@octokit/core\";\nimport { paginateRest } from \"@octokit/plugin-paginate-rest\";\nimport { paginateGraphQL } from \"@octokit/plugin-paginate-graphql\";\nimport { restEndpointMethods } from \"@octokit/plugin-rest-endpoint-methods\";\nimport { retry } from \"@octokit/plugin-retry\";\nimport { throttling } from \"@octokit/plugin-throttling\";\n\nimport { VERSION } from \"./version.js\";\nimport type { EndpointDefaults } from \"@octokit/types\";\n\nexport { RequestError } from \"@octokit/request-error\";\nexport type {\n  PageInfoForward,\n  PageInfoBackward,\n} from \"@octokit/plugin-paginate-graphql\";\n\nexport const Octokit = OctokitCore.plugin(\n  restEndpointMethods,\n  paginateRest,\n  paginateGraphQL,\n  retry,\n  throttling,\n).defaults({\n  userAgent: `octokit.js/${VERSION}`,\n  throttle: {\n    onRateLimit,\n    onSecondaryRateLimit,\n  },\n});\n\nexport type Octokit = InstanceType<typeof Octokit>;\n\n/* v8 ignore next no need to test internals of the throttle plugin -- @preserve */\nfunction onRateLimit(\n  retryAfter: number,\n  options: Required<EndpointDefaults>,\n  octokit: InstanceType<typeof OctokitCore>,\n) {\n  octokit.log.warn(\n    `Request quota exhausted for request ${options.method} ${options.url}`,\n  );\n\n  if (options.request.retryCount === 0) {\n    // only retries once\n    octokit.log.info(`Retrying after ${retryAfter} seconds!`);\n    return true;\n  }\n}\n\n/* v8 ignore next no need to test internals of the throttle plugin -- @preserve */\nfunction onSecondaryRateLimit(\n  retryAfter: number,\n  options: Required<EndpointDefaults>,\n  octokit: InstanceType<typeof OctokitCore>,\n) {\n  octokit.log.warn(\n    `SecondaryRateLimit detected for request ${options.method} ${options.url}`,\n  );\n\n  if (options.request.retryCount === 0) {\n    // only retries once\n    octokit.log.info(`Retrying after ${retryAfter} seconds!`);\n    return true;\n  }\n}\n"
  },
  {
    "path": "src/version.ts",
    "content": "export const VERSION = \"0.0.0-development\";\n"
  },
  {
    "path": "test/app.test.ts",
    "content": "import { beforeEach, describe, expect, test } from \"vitest\";\nimport { createServer } from \"node:http\";\n\nimport nock from \"nock\";\nimport MockDate from \"mockdate\";\n\nimport { App, Octokit, createNodeMiddleware } from \"../src/index.ts\";\n\nconst APP_ID = 1;\nconst PRIVATE_KEY = `-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA1c7+9z5Pad7OejecsQ0bu3aozN3tihPmljnnudb9G3HECdnH\nlWu2/a1gB9JW5TBQ+AVpum9Okx7KfqkfBKL9mcHgSL0yWMdjMfNOqNtrQqKlN4kE\np6RD++7sGbzbfZ9arwrlD/HSDAWGdGGJTSOBM6pHehyLmSC3DJoR/CTu0vTGTWXQ\nrO64Z8tyXQPtVPb/YXrcUhbBp8i72b9Xky0fD6PkEebOy0Ip58XVAn2UPNlNOSPS\nye+Qjtius0Md4Nie4+X8kwVI2Qjk3dSm0sw/720KJkdVDmrayeljtKBx6AtNQsSX\ngzQbeMmiqFFkwrG1+zx6E7H7jqIQ9B6bvWKXGwIDAQABAoIBAD8kBBPL6PPhAqUB\nK1r1/gycfDkUCQRP4DbZHt+458JlFHm8QL6VstKzkrp8mYDRhffY0WJnYJL98tr4\n4tohsDbqFGwmw2mIaHjl24LuWXyyP4xpAGDpl9IcusjXBxLQLp2m4AKXbWpzb0OL\nUlrfc1ZooPck2uz7xlMIZOtLlOPjLz2DuejVe24JcwwHzrQWKOfA11R/9e50DVse\nhnSH/w46Q763y4I0E3BIoUMsolEKzh2ydAAyzkgabGQBUuamZotNfvJoDXeCi1LD\n8yNCWyTlYpJZJDDXooBU5EAsCvhN1sSRoaXWrlMSDB7r/E+aQyKua4KONqvmoJuC\n21vSKeECgYEA7yW6wBkVoNhgXnk8XSZv3W+Q0xtdVpidJeNGBWnczlZrummt4xw3\nxs6zV+rGUDy59yDkKwBKjMMa42Mni7T9Fx8+EKUuhVK3PVQyajoyQqFwT1GORJNz\nc/eYQ6VYOCSC8OyZmsBM2p+0D4FF2/abwSPMmy0NgyFLCUFVc3OECpkCgYEA5OAm\nI3wt5s+clg18qS7BKR2DuOFWrzNVcHYXhjx8vOSWV033Oy3yvdUBAhu9A1LUqpwy\nMa+unIgxmvmUMQEdyHQMcgBsVs10dR/g2xGjMLcwj6kn+xr3JVIZnbRT50YuPhf+\nns1ScdhP6upo9I0/sRsIuN96Gb65JJx94gQ4k9MCgYBO5V6gA2aMQvZAFLUicgzT\nu/vGea+oYv7tQfaW0J8E/6PYwwaX93Y7Q3QNXCoCzJX5fsNnoFf36mIThGHGiHY6\ny5bZPPWFDI3hUMa1Hu/35XS85kYOP6sGJjf4kTLyirEcNKJUWH7CXY+00cwvTkOC\nS4Iz64Aas8AilIhRZ1m3eQKBgQCUW1s9azQRxgeZGFrzC3R340LL530aCeta/6FW\nCQVOJ9nv84DLYohTVqvVowdNDTb+9Epw/JDxtDJ7Y0YU0cVtdxPOHcocJgdUGHrX\nZcJjRIt8w8g/s4X6MhKasBYm9s3owALzCuJjGzUKcDHiO2DKu1xXAb0SzRcTzUCn\n7daCswKBgQDOYPZ2JGmhibqKjjLFm0qzpcQ6RPvPK1/7g0NInmjPMebP0K6eSPx0\n9/49J6WTD++EajN7FhktUSYxukdWaCocAQJTDNYP0K88G4rtC2IYy5JFn9SWz5oh\nx//0u+zd/R/QRUzLOw4N72/Hu+UG6MNt5iDZFCtapRaKt6OvSBwy8w==\n-----END RSA PRIVATE KEY-----`;\nconst CLIENT_ID = \"lv1.1234567890abcdef\";\nconst CLIENT_SECRET = \"1234567890abcdef1234567890abcdef12345678\";\nconst WEBHOOK_SECRET = \"secret\";\n// see https://runkit.com/gr2m/reproducable-jwt\nconst BEARER =\n  \"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOi0zMCwiZXhwIjo1NzAsImlzcyI6MX0.q3foRa78U3WegM5PrWLEh5N0bH1SD62OqW66ZYzArp95JBNiCbo8KAlGtiRENCIfBZT9ibDUWy82cI4g3F09mdTq3bD1xLavIfmTksIQCz5EymTWR5v6gL14LSmQdWY9lSqkgUG0XCFljWUglEP39H4yeHbFgdjvAYg3ifDS12z9oQz2ACdSpvxPiTuCC804HkPVw8Qoy0OSXvCkFU70l7VXCVUxnuhHnk8-oCGcKUspmeP6UdDnXk-Aus-eGwDfJbU2WritxxaXw6B4a3flTPojkYLSkPBr6Pi0H2-mBsW_Nvs0aLPVLKobQd4gqTkosX3967DoAG8luUMhrnxe8Q\";\n\ndescribe(\"App\", () => {\n  let app: InstanceType<typeof App>;\n  const mock = nock(\"https://api.github.com\");\n\n  beforeEach(() => {\n    MockDate.set(0);\n    nock.cleanAll();\n\n    app = new App({\n      appId: APP_ID,\n      privateKey: PRIVATE_KEY,\n      oauth: {\n        clientId: CLIENT_ID,\n        clientSecret: CLIENT_SECRET,\n      },\n      webhooks: {\n        secret: WEBHOOK_SECRET,\n      },\n      Octokit: Octokit.defaults({\n        throttle: { enabled: false },\n      }),\n    });\n  });\n\n  test(\"Readme example: `app.eachRepository.iterator`\", async () => {\n    mock\n      .get(\"/app/installations\", undefined, {\n        reqheaders: { authorization: `bearer ${BEARER}` },\n      })\n      .reply(200, [{ id: 123 }]);\n    mock\n      .post(\"/app/installations/123/access_tokens\", undefined, {\n        reqheaders: { authorization: `bearer ${BEARER}` },\n      })\n      .reply(200, {\n        token: \"secret123\",\n        expires_at: \"1970-01-01T01:00:00.000Z\",\n        permissions: {\n          metadata: \"read\",\n        },\n        repository_selection: \"all\",\n      });\n    mock.get(\"/installation/repositories\").reply(200, {\n      total_count: 1,\n      repositories: [\n        {\n          owner: { login: \"octokit\" },\n          name: \"octokit.js\",\n          full_name: \"octokit/octokit.js\",\n        },\n      ],\n    });\n    mock\n      .post(\"/repos/octokit/octokit.js/dispatches\", {\n        event_type: \"my_event\",\n        client_payload: { foo: \"bar\" },\n      })\n      .reply(204);\n\n    for await (const { octokit, repository } of app.eachRepository.iterator()) {\n      // https://docs.github.com/en/rest/reference/repos#create-a-repository-dispatch-event\n      await octokit.request(\"POST /repos/{owner}/{repo}/dispatches\", {\n        owner: repository.owner.login,\n        repo: repository.name,\n        event_type: \"my_event\",\n        client_payload: {\n          foo: \"bar\",\n        },\n      });\n\n      expect(repository.full_name).toEqual(\"octokit/octokit.js\");\n    }\n\n    expect(mock.isDone()).toBe(true);\n  });\n\n  test(\"README example: app.getInstallationOctokit\", async () => {\n    mock\n      .post(\"/app/installations/123/access_tokens\", undefined, {\n        reqheaders: { authorization: `bearer ${BEARER}` },\n      })\n      .reply(200, {\n        token: \"secret123\",\n        expires_at: \"1970-01-01T01:00:00.000Z\",\n        permissions: {\n          metadata: \"read\",\n        },\n        repository_selection: \"all\",\n      });\n    mock\n      .post(\"/repos/octokit/octokit.js/issues\", { title: \"Hello, world!\" })\n      .reply(201, { id: 1 });\n\n    const octokit = await app.getInstallationOctokit(123);\n\n    // https://docs.github.com/en/rest/reference/issues#create-an-issue\n    await octokit.request(\"POST /repos/{owner}/{repo}/issues\", {\n      owner: \"octokit\",\n      repo: \"octokit.js\",\n      title: \"Hello, world!\",\n    });\n\n    expect(mock.isDone()).toBe(true);\n  });\n\n  test(\"README example: createNodeMiddleware(app)\", async () => {\n    expect.assertions(3);\n\n    mock\n      .post(\"/app/installations/123/access_tokens\", undefined, {\n        reqheaders: { authorization: `bearer ${BEARER}` },\n      })\n      .reply(200, {\n        token: \"secret123\",\n        expires_at: \"1970-01-01T01:00:00.000Z\",\n        permissions: {\n          metadata: \"read\",\n        },\n        repository_selection: \"all\",\n      });\n    mock\n      .post(\"/repos/octokit/octokit.js/issues/1/comments\", {\n        body: \"Hello, World!\",\n      })\n      .reply(200, { body: 1 });\n\n    app.webhooks.on(\"issues.opened\", async ({ octokit, payload }) => {\n      await octokit.rest.issues.createComment({\n        owner: payload.repository.owner.login,\n        repo: payload.repository.name,\n        issue_number: payload.issue.number,\n        body: \"Hello, World!\",\n      });\n\n      expect(mock.isDone()).toBe(true);\n    });\n\n    // Your app can now receive webhook events at `/api/github/webhooks`\n    const server = createServer(createNodeMiddleware(app)).listen();\n\n    // @ts-expect-error - port is typed as undefined\n    const port = server.address().port;\n    const issuePayload = JSON.stringify({\n      repository: {\n        owner: {\n          login: \"octokit\",\n        },\n        name: \"octokit.js\",\n      },\n      action: \"opened\",\n      installation: { id: 123 },\n      issue: { number: 1 },\n    });\n\n    const response = await fetch(\n      `http://localhost:${port}/api/github/webhooks`,\n      {\n        method: \"POST\",\n        headers: {\n          \"content-type\": \"application/json\",\n          \"x-github-event\": \"issues\",\n          \"x-github-delivery\": \"1\",\n          \"x-hub-signature-256\": await app.webhooks.sign(issuePayload),\n        },\n        body: issuePayload,\n      },\n    );\n\n    expect(await response.text()).toEqual(\"ok\\n\");\n    expect(response.status).toEqual(200);\n\n    server.close();\n  });\n});\n"
  },
  {
    "path": "test/smoke.test.ts",
    "content": "import { describe, expect, it } from \"vitest\";\nimport { Octokit, App, OAuthApp, RequestError } from \"../src/index.ts\";\n\ndescribe(\"Smoke tests\", () => {\n  it(\"Octokit is a function\", () => {\n    expect(Octokit).toBeInstanceOf(Function);\n    expect(() => new Octokit()).not.toThrow();\n  });\n\n  it(\"Octokit can be used as a type\", () => {\n    let octokit: Octokit;\n    octokit = new Octokit();\n    expect(octokit.rest.repos.get).toBeInstanceOf(Function);\n  });\n\n  it(\"App is a function\", () => {\n    expect(App).toBeInstanceOf(Function);\n    expect(\n      () =>\n        new App({\n          appId: 123,\n          privateKey: \"private key here\",\n        }),\n    ).not.toThrow();\n  });\n\n  it(\"App can be used as a type\", () => {\n    let app: App;\n    app = new App({\n      appId: 123,\n      privateKey: \"private key here\",\n    });\n\n    expect(app.octokit.request).toBeInstanceOf(Function);\n  });\n\n  it(\"OAuthApp is a function\", () => {\n    expect(OAuthApp).toBeInstanceOf(Function);\n    expect(\n      () =>\n        new OAuthApp({\n          clientId: \"\",\n          clientSecret: \"\",\n        }),\n    ).not.toThrow();\n  });\n\n  it(\"OAuthApp can be used as a type\", () => {\n    let app: OAuthApp;\n    app = new OAuthApp({\n      clientId: \"\",\n      clientSecret: \"\",\n    });\n\n    expect(app.octokit.request).toBeInstanceOf(Function);\n  });\n\n  it(\"RequestError inherits from Error\", () => {\n    const error = new RequestError(\"test\", 123, {\n      request: {\n        method: \"GET\",\n        url: \"https://api.github.com/\",\n        headers: {},\n      },\n    });\n\n    expect(error).toBeInstanceOf(RequestError);\n  });\n});\n"
  },
  {
    "path": "test/tsconfig.test.json",
    "content": "{\n  \"extends\": \"../tsconfig.json\",\n  \"compilerOptions\": {\n    \"emitDeclarationOnly\": false,\n    \"noEmit\": true,\n    \"verbatimModuleSyntax\": false,\n    \"allowImportingTsExtensions\": true\n  },\n  \"include\": [\"src/**/*\"]\n}\n"
  },
  {
    "path": "test/typescript-validate.ts",
    "content": "// ************************************************************\n// THIS CODE IS NOT EXECUTED. IT IS JUST FOR TYPECHECKING\n// ************************************************************\n\nimport { App, OAuthApp, Octokit, RequestError } from \"../src/index.ts\";\n\nfunction expect<T>(what: T) {}\n\nexport async function OctokitTest() {\n  const app = new App({\n    appId: 1,\n    privateKey: \"\",\n  });\n\n  expect<Octokit>(app.octokit);\n\n  const oauthApp = new OAuthApp({\n    clientId: \"\",\n    clientSecret: \"\",\n  });\n\n  expect<Octokit>(oauthApp.octokit);\n\n  const installationOctokit = await app.getInstallationOctokit(1);\n  const issues = await installationOctokit.paginate(\n    installationOctokit.rest.issues.listForRepo,\n    {\n      owner: \"\",\n      repo: \"\",\n    },\n  );\n  expect<number>(issues[0].id);\n\n  const error = new RequestError(\"test\", 123, {\n    request: {\n      method: \"GET\",\n      url: \"https://api.github.com/\",\n      headers: {},\n    },\n  });\n\n  expect<RequestError>(error);\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"extends\": \"@octokit/tsconfig\",\n  \"include\": [\"src/**/*\"],\n  \"compilerOptions\": {\n    \"esModuleInterop\": true,\n    \"declaration\": true,\n    \"outDir\": \"pkg/dist-types\",\n    \"emitDeclarationOnly\": true,\n    \"sourceMap\": true\n  }\n}\n"
  },
  {
    "path": "vite.config.js",
    "content": "import { defineConfig } from \"vite\";\n\nexport default defineConfig({\n  test: {\n    coverage: {\n      include: [\"src/**/*.ts\"],\n      reporter: [\"html\"],\n      thresholds: {\n        100: true,\n      },\n    },\n  },\n});\n"
  }
]