diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 9fe54a78..f282ebda 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -3,14 +3,18 @@ on: push: tags: - '*' + +permissions: + contents: write + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - name: Create a Release - uses: elgohr/Github-Release-Action@v5 - env: - GITHUB_TOKEN: "${{ secrets.RELEASE_TOKEN }}" - with: - title: ${{ github.ref }} + - uses: actions/checkout@v6 + - name: Create a Release + uses: elgohr/Github-Release-Action@v5 + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + with: + title: ${{ github.ref }} diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 19d95359..fa4abf20 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [ master ] +permissions: + contents: read + jobs: build: runs-on: ${{ matrix.os }} @@ -22,12 +25,26 @@ jobs: - name: Install dependencies run: dart pub get - - name: Dart Analyzer - run: dart analyze + + - name: Dart Analyzer (Strict mode) + run: dart analyze --fatal-infos + - name: Check Dart Format if: ${{ matrix.sdk == 'stable' }} run: dart format --set-exit-if-changed -onone . - - name: Unit tests + + - name: Verify Spec Sync Drift + if: ${{ matrix.sdk == 'stable' }} + run: dart run tool/spec_sync.dart --check --offline + + - name: Unit and Contract Tests run: dart test + + - name: Coverage Ratchet Check + if: ${{ matrix.sdk == 'stable' }} + run: | + dart test --coverage=coverage + dart run tool/coverage_check.dart coverage/lcov.info --min=30.0 + - name: Check if Publishable run: dart pub publish --dry-run diff --git a/.github/workflows/publish_demos.yml b/.github/workflows/publish_demos.yml index 7e13bac4..2605b329 100644 --- a/.github/workflows/publish_demos.yml +++ b/.github/workflows/publish_demos.yml @@ -3,6 +3,10 @@ on: push: branches: - master + +permissions: + contents: write + jobs: build-and-deploy: runs-on: ubuntu-latest diff --git a/.github/workflows/spec_sync.yml b/.github/workflows/spec_sync.yml new file mode 100644 index 00000000..49cc8d70 --- /dev/null +++ b/.github/workflows/spec_sync.yml @@ -0,0 +1,98 @@ +name: Weekly GitHub OpenAPI Spec Sync + +on: + schedule: + # Run every Monday at 04:00 UTC + - cron: '0 4 * * 1' + workflow_dispatch: + +permissions: + contents: read + +jobs: + spec-sync: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Setup Dart SDK + uses: dart-lang/setup-dart@v1 + with: + sdk: stable + + - name: Install dependencies + run: dart pub get + + - name: Check for upstream OpenAPI specification updates + id: check_upstream + run: | + mkdir -p .dart_tool + dart run tool/spec_sync.dart --offline --report-json > .dart_tool/spec_report_before.json + echo "Checked current spec baseline." + + - name: Regenerate OpenAPI catalog and docs + id: run_sync + run: | + dart run tool/spec_sync.dart --update + git status --porcelain > .dart_tool/git_status.txt + if [ -s .dart_tool/git_status.txt ]; then + echo "changes_detected=true" >> "$GITHUB_OUTPUT" + else + echo "changes_detected=false" >> "$GITHUB_OUTPUT" + fi + + - name: Validate generated code and contracts + if: steps.run_sync.outputs.changes_detected == 'true' + run: | + dart format --output=none --set-exit-if-changed . + dart analyze --fatal-infos + dart test + dart pub publish --dry-run + + - name: Create or update spec-sync pull request + if: steps.run_sync.outputs.changes_detected == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + BRANCH_NAME="automation/github-openapi-spec-sync" + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git checkout -B "$BRANCH_NAME" + git add lib/src/common/generated/rest_contracts.g.dart docs/api-coverage.md tool/spec/ + git commit -m "chore(spec): synchronize GitHub OpenAPI specification contracts" + git push --force origin "$BRANCH_NAME" + + PR_TITLE="chore(spec): synchronize GitHub OpenAPI specification contracts" + PR_BODY="## GitHub OpenAPI Specification Sync + + This automated pull request synchronizes the GitHub OpenAPI description contracts and coverage reports. + + ### Summary of Changes + - Regenerated \`lib/src/common/generated/rest_contracts.g.dart\` + - Updated API coverage documentation in \`docs/api-coverage.md\` + + ### Validation + - \`dart format\` verified + - \`dart analyze --fatal-infos\` passed + - \`dart test\` passed + - \`dart pub publish --dry-run\` verified + + **Notice**: Review only. Never auto-merged." + + gh pr create \ + --title "$PR_TITLE" \ + --body "$PR_BODY" \ + --base master \ + --head "$BRANCH_NAME" \ + --label "automation,spec-sync" || \ + gh pr edit "$BRANCH_NAME" \ + --title "$PR_TITLE" \ + --body "$PR_BODY" diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index 8b71d9ae..cd49b23a 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -3,6 +3,9 @@ on: issues: types: [opened] +permissions: + issues: write + jobs: assignRob: name: Assign Rob diff --git a/.gitignore b/.gitignore index 43dbe764..68436b40 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ .dart_tool .packages .pub +.dart_pub_cache +tool/spec/.cache packages pubspec.lock + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b574e5a8..b6ea9e48 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,6 +38,20 @@ To regenerate the JSON logic for the models, run: dart run build_runner build -d ``` +## OpenAPI Specification & Contract Sync + +This repository uses an OpenAPI-driven contract verification system pinned to the official GitHub REST API specification. + +- To check that code and documentation match the pinned OpenAPI specification: + ```sh + dart run tool/spec_sync.dart --check --offline + ``` +- To update or regenerate the REST contracts catalog and coverage report: + ```sh + dart run tool/spec_sync.dart --update + ``` +- Automated weekly pull requests (`spec_sync.yml`) monitor upstream API specification releases. Automated PRs are review-only and never auto-merged. + ## Tests `dart test` will only run the unit tests. diff --git a/README.md b/README.md index 08dc8e09..12b8ef09 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,35 @@ We are looking for contributors. If you're interested or have questions, head ov - [Library Demos](https://spinlocklabs.github.io/github.dart/) (based on the [sample code](https://github.com/SpinlockLabs/github.dart/tree/master/example)) - [Pub Package](https://pub.dev/packages/github) +- [API Coverage Report](docs/api-coverage.md) - [Wiki](https://github.com/SpinlockLabs/github.dart/wiki) - [Latest API reference](https://pub.dev/documentation/github/latest/) +## OpenAPI Conformance and Spec Synchronization + +This library tracks the official [GitHub REST API v3 description](https://github.com/github/rest-api-description). +- The OpenAPI specification baseline is pinned in `tool/spec/github-openapi.lock.json`. +- Operation bindings and conformance are tracked in `tool/spec/bindings.yaml`. +- Immutable REST contract metadata is generated into `lib/src/common/generated/rest_contracts.g.dart`. +- Conformance and coverage metrics are documented in `docs/api-coverage.md`. + +To check or update the OpenAPI contracts locally: +```bash +# Verify no drift between specification and codebase +dart run tool/spec_sync.dart --check --offline + +# Regenerate contracts and documentation +dart run tool/spec_sync.dart --update +``` + +A weekly GitHub Actions workflow runs the spec sync check and opens review-only PRs when upstream API descriptions evolve. + +## Security and Best Practices + +- **Credential Boundaries**: Authenticated requests are constrained to the configured API origin (`api.github.com` or custom enterprise endpoint). Cross-origin redirects and pagination links automatically strip credentials. Insecure HTTP authentication is disallowed by default. +- **Webhooks**: Always configure a webhook secret. Webhooks are validated using constant-time HMAC-SHA256 signature verification, enforce configurable payload limits, and support replay attack detection. +- **Browser Authentication**: Token extraction from URL query parameters is disabled by default for security. Tokens should be passed via `Authentication.withToken()` or session storage. + ## Examples See the examples in the example directory to learn how to use some of the features! diff --git a/analysis_options.yaml b/analysis_options.yaml index f2974469..a94d8108 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -2,7 +2,9 @@ include: package:lints/recommended.yaml analyzer: language: - #strict-casts: true + strict-casts: true + strict-inference: true + strict-raw-types: true linter: rules: diff --git a/docs/api-coverage.md b/docs/api-coverage.md new file mode 100644 index 00000000..bcfb1b57 --- /dev/null +++ b/docs/api-coverage.md @@ -0,0 +1,235 @@ +# GitHub REST API Conformance & Coverage + +> Automatically generated from `tool/spec/github-openapi.lock.json` and `tool/spec/bindings.yaml`. + +## Summary + +| Metric | Count | +| --- | --- | +| Total OpenAPI Operations | 1229 | +| Total Bound Operations | 164 | +| Supported Operations | 164 | +| Partial Operations | 0 | +| Deprecated Operations | 0 | +| Conformance Coverage | 13.3% | + +## Coverage by Category (Tags) + +| Category | Total | Bound | Supported | Partial | Coverage % | +| --- | --- | --- | --- | --- | --- | +| actions | 189 | 0 | 0 | 0 | 0.0% | +| activity | 34 | 14 | 14 | 0 | 41.2% | +| agent-tasks | 5 | 0 | 0 | 0 | 0.0% | +| agents | 30 | 0 | 0 | 0 | 0.0% | +| apps | 37 | 0 | 0 | 0 | 0.0% | +| billing | 13 | 0 | 0 | 0 | 0.0% | +| campaigns | 5 | 0 | 0 | 0 | 0.0% | +| checks | 12 | 11 | 11 | 0 | 91.7% | +| classroom | 6 | 0 | 0 | 0 | 0.0% | +| code-quality | 4 | 0 | 0 | 0 | 0.0% | +| code-scanning | 25 | 0 | 0 | 0 | 0.0% | +| code-security | 20 | 0 | 0 | 0 | 0.0% | +| codes-of-conduct | 2 | 0 | 0 | 0 | 0.0% | +| codespaces | 48 | 0 | 0 | 0 | 0.0% | +| copilot | 31 | 0 | 0 | 0 | 0.0% | +| copilot-spaces | 28 | 0 | 0 | 0 | 0.0% | +| credentials | 1 | 0 | 0 | 0 | 0.0% | +| dependabot | 25 | 0 | 0 | 0 | 0.0% | +| dependency-graph | 5 | 0 | 0 | 0 | 0.0% | +| emojis | 1 | 0 | 0 | 0 | 0.0% | +| enterprise-team-memberships | 7 | 0 | 0 | 0 | 0.0% | +| enterprise-team-organizations | 6 | 0 | 0 | 0 | 0.0% | +| enterprise-teams | 5 | 0 | 0 | 0 | 0.0% | +| gists | 20 | 18 | 18 | 0 | 90.0% | +| git | 13 | 12 | 12 | 0 | 92.3% | +| gitignore | 2 | 0 | 0 | 0 | 0.0% | +| hosted-compute | 6 | 0 | 0 | 0 | 0.0% | +| interactions | 16 | 0 | 0 | 0 | 0.0% | +| issues | 58 | 22 | 22 | 0 | 37.9% | +| licenses | 3 | 0 | 0 | 0 | 0.0% | +| markdown | 2 | 0 | 0 | 0 | 0.0% | +| meta | 5 | 1 | 1 | 0 | 20.0% | +| migrations | 22 | 0 | 0 | 0 | 0.0% | +| oidc | 8 | 0 | 0 | 0 | 0.0% | +| orgs | 110 | 3 | 3 | 0 | 2.7% | +| packages | 27 | 0 | 0 | 0 | 0.0% | +| private-registries | 6 | 0 | 0 | 0 | 0.0% | +| projects | 26 | 0 | 0 | 0 | 0.0% | +| pulls | 34 | 10 | 10 | 0 | 29.4% | +| rate-limit | 1 | 1 | 1 | 0 | 100.0% | +| reactions | 15 | 0 | 0 | 0 | 0.0% | +| repos | 203 | 45 | 45 | 0 | 22.2% | +| search | 7 | 4 | 4 | 0 | 57.1% | +| secret-scanning | 17 | 0 | 0 | 0 | 0.0% | +| security-advisories | 10 | 0 | 0 | 0 | 0.0% | +| teams | 32 | 9 | 9 | 0 | 28.1% | +| users | 47 | 14 | 14 | 0 | 29.8% | + +## Bound Operations + +| Operation ID | Method | Path | Service Method | Status | Notes | +| --- | --- | --- | --- | --- | --- | +| `activity/check-repo-is-starred-by-authenticated-user` | `GET` | `/user/starred/{owner}/{repo}` | `ActivityService.isStarred` | supported | | +| `activity/delete-repo-subscription` | `DELETE` | `/repos/{owner}/{repo}/subscription` | `ActivityService.deleteRepositorySubscription` | supported | | +| `activity/get-repo-subscription` | `GET` | `/repos/{owner}/{repo}/subscription` | `ActivityService.isWatched` | supported | | +| `activity/list-events-for-authenticated-user` | `GET` | `/users/{username}/events` | `ActivityService.listUserEvents` | supported | | +| `activity/list-public-events` | `GET` | `/events` | `ActivityService.listEvents` | supported | | +| `activity/list-public-events-for-repo-network` | `GET` | `/networks/{owner}/{repo}/events` | `ActivityService.listNetworkEvents` | supported | | +| `activity/list-public-org-events` | `GET` | `/orgs/{org}/events` | `ActivityService.listOrganizationEvents` | supported | | +| `activity/list-repo-events` | `GET` | `/repos/{owner}/{repo}/events` | `ActivityService.listRepositoryEvents` | supported | | +| `activity/list-repos-starred-by-authenticated-user` | `GET` | `/user/starred` | `ActivityService.listStarredRepositories` | supported | | +| `activity/list-stargazers-for-repo` | `GET` | `/repos/{owner}/{repo}/stargazers` | `ActivityService.listStarGazers` | supported | | +| `activity/list-watchers-for-repo` | `GET` | `/repos/{owner}/{repo}/subscribers` | `ActivityService.listWatches` | supported | | +| `activity/set-repo-subscription` | `PUT` | `/repos/{owner}/{repo}/subscription` | `ActivityService.setRepositorySubscription` | supported | | +| `activity/star-repo-for-authenticated-user` | `PUT` | `/user/starred/{owner}/{repo}` | `ActivityService.star` | supported | | +| `activity/unstar-repo-for-authenticated-user` | `DELETE` | `/user/starred/{owner}/{repo}` | `ActivityService.unstar` | supported | | +| `checks/create` | `POST` | `/repos/{owner}/{repo}/check-runs` | `ChecksService.createCheckRun` | supported | | +| `checks/create-suite` | `POST` | `/repos/{owner}/{repo}/check-suites` | `ChecksService.createCheckSuite` | supported | | +| `checks/get` | `GET` | `/repos/{owner}/{repo}/check-runs/{check_run_id}` | `ChecksService.getCheckRun` | supported | | +| `checks/get-suite` | `GET` | `/repos/{owner}/{repo}/check-suites/{check_suite_id}` | `ChecksService.getCheckSuite` | supported | | +| `checks/list-annotations` | `GET` | `/repos/{owner}/{repo}/check-runs/{check_run_id}/annotations` | `ChecksService.listCheckRunAnnotations` | supported | | +| `checks/list-for-ref` | `GET` | `/repos/{owner}/{repo}/commits/{ref}/check-runs` | `ChecksService.listCheckRunsForRef` | supported | | +| `checks/list-for-suite` | `GET` | `/repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs` | `ChecksService.listCheckRunsInCheckSuite` | supported | | +| `checks/rerequest-run` | `POST` | `/repos/{owner}/{repo}/check-runs/{check_run_id}/rerequest` | `ChecksService.reRequestCheckRun` | supported | | +| `checks/rerequest-suite` | `POST` | `/repos/{owner}/{repo}/check-suites/{check_suite_id}/rerequest` | `ChecksService.reRequestCheckSuite` | supported | | +| `checks/set-suites-preferences` | `PATCH` | `/repos/{owner}/{repo}/check-suites/preferences` | `ChecksService.updatePreferencesForCheckSuites` | supported | | +| `checks/update` | `PATCH` | `/repos/{owner}/{repo}/check-runs/{check_run_id}` | `ChecksService.updateCheckRun` | supported | | +| `gists/check-is-starred` | `GET` | `/gists/{gist_id}/star` | `GistsService.isGistStarred` | supported | | +| `gists/create` | `POST` | `/gists` | `GistsService.createGist` | supported | | +| `gists/create-comment` | `POST` | `/gists/{gist_id}/comments` | `GistsService.createComment` | supported | | +| `gists/delete` | `DELETE` | `/gists/{gist_id}` | `GistsService.deleteGist` | supported | | +| `gists/delete-comment` | `DELETE` | `/gists/{gist_id}/comments/{comment_id}` | `GistsService.deleteComment` | supported | | +| `gists/fork` | `POST` | `/gists/{gist_id}/forks` | `GistsService.forkGist` | supported | | +| `gists/get` | `GET` | `/gists/{gist_id}` | `GistsService.getGist` | supported | | +| `gists/get-comment` | `GET` | `/gists/{gist_id}/comments/{comment_id}` | `GistsService.getComment` | supported | | +| `gists/list` | `GET` | `/gists` | `GistsService.listGists` | supported | | +| `gists/list-comments` | `GET` | `/gists/{gist_id}/comments` | `GistsService.listComments` | supported | | +| `gists/list-for-user` | `GET` | `/users/{username}/gists` | `GistsService.listUserGists` | supported | | +| `gists/list-forks` | `GET` | `/gists/{gist_id}/forks` | `GistsService.listGistForks` | supported | | +| `gists/list-public` | `GET` | `/gists/public` | `GistsService.listPublicGists` | supported | | +| `gists/list-starred` | `GET` | `/gists/starred` | `GistsService.listStarredGists` | supported | | +| `gists/star` | `PUT` | `/gists/{gist_id}/star` | `GistsService.starGist` | supported | | +| `gists/unstar` | `DELETE` | `/gists/{gist_id}/star` | `GistsService.unstarGist` | supported | | +| `gists/update` | `PATCH` | `/gists/{gist_id}` | `GistsService.editGist` | supported | | +| `gists/update-comment` | `PATCH` | `/gists/{gist_id}/comments/{comment_id}` | `GistsService.editComment` | supported | | +| `git/create-blob` | `POST` | `/repos/{owner}/{repo}/git/blobs` | `GitService.createBlob` | supported | | +| `git/create-commit` | `POST` | `/repos/{owner}/{repo}/git/commits` | `GitService.createCommit` | supported | | +| `git/create-ref` | `POST` | `/repos/{owner}/{repo}/git/refs` | `GitService.createReference` | supported | | +| `git/create-tag` | `POST` | `/repos/{owner}/{repo}/git/tags` | `GitService.createTag` | supported | | +| `git/create-tree` | `POST` | `/repos/{owner}/{repo}/git/trees` | `GitService.createTree` | supported | | +| `git/delete-ref` | `DELETE` | `/repos/{owner}/{repo}/git/refs/{ref}` | `GitService.deleteReference` | supported | | +| `git/get-blob` | `GET` | `/repos/{owner}/{repo}/git/blobs/{file_sha}` | `GitService.getBlob` | supported | | +| `git/get-commit` | `GET` | `/repos/{owner}/{repo}/git/commits/{commit_sha}` | `GitService.getCommit` | supported | | +| `git/get-ref` | `GET` | `/repos/{owner}/{repo}/git/ref/{ref}` | `GitService.getReference` | supported | | +| `git/get-tag` | `GET` | `/repos/{owner}/{repo}/git/tags/{tag_sha}` | `GitService.getTag` | supported | | +| `git/get-tree` | `GET` | `/repos/{owner}/{repo}/git/trees/{tree_sha}` | `GitService.getTree` | supported | | +| `git/update-ref` | `PATCH` | `/repos/{owner}/{repo}/git/refs/{ref}` | `GitService.editReference` | supported | | +| `issues/create` | `POST` | `/repos/{owner}/{repo}/issues` | `IssuesService.create` | supported | | +| `issues/create-comment` | `POST` | `/repos/{owner}/{repo}/issues/{issue_number}/comments` | `IssuesService.createComment` | supported | | +| `issues/create-label` | `POST` | `/repos/{owner}/{repo}/labels` | `IssuesService.createLabel` | supported | | +| `issues/create-milestone` | `POST` | `/repos/{owner}/{repo}/milestones` | `IssuesService.createMilestone` | supported | | +| `issues/delete-comment` | `DELETE` | `/repos/{owner}/{repo}/issues/comments/{comment_id}` | `IssuesService.deleteComment` | supported | | +| `issues/delete-label` | `DELETE` | `/repos/{owner}/{repo}/labels/{name}` | `IssuesService.deleteLabel` | supported | | +| `issues/delete-milestone` | `DELETE` | `/repos/{owner}/{repo}/milestones/{milestone_number}` | `IssuesService.deleteMilestone` | supported | | +| `issues/get` | `GET` | `/repos/{owner}/{repo}/issues/{issue_number}` | `IssuesService.get` | supported | | +| `issues/get-comment` | `GET` | `/repos/{owner}/{repo}/issues/comments/{comment_id}` | `IssuesService.getComment` | supported | | +| `issues/get-label` | `GET` | `/repos/{owner}/{repo}/labels/{name}` | `IssuesService.getLabel` | supported | | +| `issues/get-milestone` | `GET` | `/repos/{owner}/{repo}/milestones/{milestone_number}` | `IssuesService.getMilestone` | supported | | +| `issues/list` | `GET` | `/issues` | `IssuesService.listAll` | supported | | +| `issues/list-comments` | `GET` | `/repos/{owner}/{repo}/issues/{issue_number}/comments` | `IssuesService.listCommentsByIssue` | supported | | +| `issues/list-for-authenticated-user` | `GET` | `/user/issues` | `IssuesService.listByUser` | supported | | +| `issues/list-for-org` | `GET` | `/orgs/{org}/issues` | `IssuesService.listByOrg` | supported | | +| `issues/list-for-repo` | `GET` | `/repos/{owner}/{repo}/issues` | `IssuesService.listByRepo` | supported | | +| `issues/list-labels-for-repo` | `GET` | `/repos/{owner}/{repo}/labels` | `IssuesService.listLabels` | supported | | +| `issues/list-milestones` | `GET` | `/repos/{owner}/{repo}/milestones` | `IssuesService.listMilestones` | supported | | +| `issues/update` | `PATCH` | `/repos/{owner}/{repo}/issues/{issue_number}` | `IssuesService.edit` | supported | | +| `issues/update-comment` | `PATCH` | `/repos/{owner}/{repo}/issues/comments/{comment_id}` | `IssuesService.editComment` | supported | | +| `issues/update-label` | `PATCH` | `/repos/{owner}/{repo}/labels/{name}` | `IssuesService.editLabel` | supported | | +| `issues/update-milestone` | `PATCH` | `/repos/{owner}/{repo}/milestones/{milestone_number}` | `IssuesService.editMilestone` | supported | | +| `meta/get-zen` | `GET` | `/zen` | `MiscService.getZen` | supported | | +| `orgs/get` | `GET` | `/orgs/{org}` | `OrganizationsService.get` | supported | | +| `orgs/list` | `GET` | `/organizations` | `OrganizationsService.list` | supported | | +| `orgs/update` | `PATCH` | `/orgs/{org}` | `OrganizationsService.edit` | supported | | +| `pulls/create` | `POST` | `/repos/{owner}/{repo}/pulls` | `PullRequestsService.create` | supported | | +| `pulls/create-review` | `POST` | `/repos/{owner}/{repo}/pulls/{pull_number}/reviews` | `PullRequestsService.createReview` | supported | | +| `pulls/get` | `GET` | `/repos/{owner}/{repo}/pulls/{pull_number}` | `PullRequestsService.get` | supported | | +| `pulls/list` | `GET` | `/repos/{owner}/{repo}/pulls` | `PullRequestsService.list` | supported | | +| `pulls/list-commits` | `GET` | `/repos/{owner}/{repo}/pulls/{pull_number}/commits` | `PullRequestsService.listCommits` | supported | | +| `pulls/list-files` | `GET` | `/repos/{owner}/{repo}/pulls/{pull_number}/files` | `PullRequestsService.listFiles` | supported | | +| `pulls/list-review-comments` | `GET` | `/repos/{owner}/{repo}/pulls/{pull_number}/comments` | `PullRequestsService.listComments` | supported | | +| `pulls/list-reviews` | `GET` | `/repos/{owner}/{repo}/pulls/{pull_number}/reviews` | `PullRequestsService.listReviews` | supported | | +| `pulls/merge` | `PUT` | `/repos/{owner}/{repo}/pulls/{pull_number}/merge` | `PullRequestsService.merge` | supported | | +| `pulls/update` | `PATCH` | `/repos/{owner}/{repo}/pulls/{pull_number}` | `PullRequestsService.edit` | supported | | +| `rate-limit/get` | `GET` | `/rate_limit` | `MiscService.getRateLimit` | supported | | +| `repos/add-collaborator` | `PUT` | `/repos/{owner}/{repo}/collaborators/{username}` | `RepositoriesService.addCollaborator` | supported | | +| `repos/check-collaborator` | `GET` | `/repos/{owner}/{repo}/collaborators/{username}` | `RepositoriesService.isCollaborator` | supported | | +| `repos/create-deploy-key` | `POST` | `/repos/{owner}/{repo}/keys` | `RepositoriesService.createDeployKey` | supported | | +| `repos/create-dispatch-event` | `POST` | `/repos/{owner}/{repo}/dispatches` | `RepositoriesService.createDispatchEvent` | supported | | +| `repos/create-for-authenticated-user` | `POST` | `/user/repos` | `RepositoriesService.createRepository` | supported | | +| `repos/create-in-org` | `POST` | `/orgs/{org}/repos` | `RepositoriesService.createOrganizationRepository` | supported | | +| `repos/create-or-update-file-contents` | `PUT` | `/repos/{owner}/{repo}/contents/{path}` | `RepositoriesService.createFile` | supported | | +| `repos/create-release` | `POST` | `/repos/{owner}/{repo}/releases` | `RepositoriesService.createRelease` | supported | | +| `repos/create-webhook` | `POST` | `/repos/{owner}/{repo}/hooks` | `RepositoriesService.createHook` | supported | | +| `repos/delete` | `DELETE` | `/repos/{owner}/{repo}` | `RepositoriesService.deleteRepository` | supported | | +| `repos/delete-deploy-key` | `DELETE` | `/repos/{owner}/{repo}/keys/{key_id}` | `RepositoriesService.deleteDeployKey` | supported | | +| `repos/delete-file` | `DELETE` | `/repos/{owner}/{repo}/contents/{path}` | `RepositoriesService.deleteFile` | supported | | +| `repos/delete-release` | `DELETE` | `/repos/{owner}/{repo}/releases/{release_id}` | `RepositoriesService.deleteRelease` | supported | | +| `repos/delete-release-asset` | `DELETE` | `/repos/{owner}/{repo}/releases/assets/{asset_id}` | `RepositoriesService.deleteReleaseAsset` | supported | | +| `repos/delete-webhook` | `DELETE` | `/repos/{owner}/{repo}/hooks/{hook_id}` | `RepositoriesService.deleteHook` | supported | | +| `repos/get` | `GET` | `/repos/{owner}/{repo}` | `RepositoriesService.getRepository` | supported | | +| `repos/get-all-topics` | `GET` | `/repos/{owner}/{repo}/topics` | `RepositoriesService.listTopics` | supported | | +| `repos/get-branch` | `GET` | `/repos/{owner}/{repo}/branches/{branch}` | `RepositoriesService.getBranch` | supported | | +| `repos/get-content` | `GET` | `/repos/{owner}/{repo}/contents/{path}` | `RepositoriesService.getContents` | supported | | +| `repos/get-deploy-key` | `GET` | `/repos/{owner}/{repo}/keys/{key_id}` | `RepositoriesService.getDeployKey` | supported | | +| `repos/get-latest-release` | `GET` | `/repos/{owner}/{repo}/releases/latest` | `RepositoriesService.getLatestRelease` | supported | | +| `repos/get-readme` | `GET` | `/repos/{owner}/{repo}/readme` | `RepositoriesService.getReadme` | supported | | +| `repos/get-release` | `GET` | `/repos/{owner}/{repo}/releases/{release_id}` | `RepositoriesService.getReleaseById` | supported | | +| `repos/get-release-asset` | `GET` | `/repos/{owner}/{repo}/releases/assets/{asset_id}` | `RepositoriesService.getReleaseAsset` | supported | | +| `repos/get-release-by-tag` | `GET` | `/repos/{owner}/{repo}/releases/tags/{tag}` | `RepositoriesService.getReleaseByTagName` | supported | | +| `repos/get-webhook` | `GET` | `/repos/{owner}/{repo}/hooks/{hook_id}` | `RepositoriesService.getHook` | supported | | +| `repos/list-branches` | `GET` | `/repos/{owner}/{repo}/branches` | `RepositoriesService.listBranches` | supported | | +| `repos/list-collaborators` | `GET` | `/repos/{owner}/{repo}/collaborators` | `RepositoriesService.listCollaborators` | supported | | +| `repos/list-contributors` | `GET` | `/repos/{owner}/{repo}/contributors` | `RepositoriesService.listContributors` | supported | | +| `repos/list-deploy-keys` | `GET` | `/repos/{owner}/{repo}/keys` | `RepositoriesService.listDeployKeys` | supported | | +| `repos/list-for-authenticated-user` | `GET` | `/user/repos` | `RepositoriesService.listRepositories` | supported | | +| `repos/list-for-org` | `GET` | `/orgs/{org}/repos` | `RepositoriesService.listOrganizationRepositories` | supported | | +| `repos/list-for-user` | `GET` | `/users/{username}/repos` | `RepositoriesService.listUserRepositories` | supported | | +| `repos/list-public` | `GET` | `/repositories` | `RepositoriesService.listPublicRepositories` | supported | | +| `repos/list-release-assets` | `GET` | `/repos/{owner}/{repo}/releases/{release_id}/assets` | `RepositoriesService.listReleaseAssets` | supported | | +| `repos/list-releases` | `GET` | `/repos/{owner}/{repo}/releases` | `RepositoriesService.listReleases` | supported | | +| `repos/list-tags` | `GET` | `/repos/{owner}/{repo}/tags` | `RepositoriesService.listTags` | supported | | +| `repos/list-webhooks` | `GET` | `/repos/{owner}/{repo}/hooks` | `RepositoriesService.listHooks` | supported | | +| `repos/remove-collaborator` | `DELETE` | `/repos/{owner}/{repo}/collaborators/{username}` | `RepositoriesService.removeCollaborator` | supported | | +| `repos/replace-all-topics` | `PUT` | `/repos/{owner}/{repo}/topics` | `RepositoriesService.replaceTopics` | supported | | +| `repos/update` | `PATCH` | `/repos/{owner}/{repo}` | `RepositoriesService.editRepository` | supported | | +| `repos/update-release` | `PATCH` | `/repos/{owner}/{repo}/releases/{release_id}` | `RepositoriesService.editRelease` | supported | | +| `repos/update-release-asset` | `PATCH` | `/repos/{owner}/{repo}/releases/assets/{asset_id}` | `RepositoriesService.editReleaseAsset` | supported | | +| `repos/update-webhook` | `PATCH` | `/repos/{owner}/{repo}/hooks/{hook_id}` | `RepositoriesService.editHook` | supported | | +| `repos/upload-release-asset` | `POST` | `/repos/{owner}/{repo}/releases/{release_id}/assets` | `RepositoriesService.uploadReleaseAssets` | supported | | +| `search/code` | `GET` | `/search/code` | `SearchService.code` | supported | | +| `search/issues-and-pull-requests` | `GET` | `/search/issues` | `SearchService.issues` | supported | | +| `search/repos` | `GET` | `/search/repositories` | `SearchService.repositories` | supported | | +| `search/users` | `GET` | `/search/users` | `SearchService.users` | supported | | +| `teams/add-or-update-membership-for-user-in-org` | `PUT` | `/orgs/{org}/teams/{team_slug}/memberships/{username}` | `OrganizationsService.addOrUpdateTeamMembershipByName` | supported | | +| `teams/delete-in-org` | `DELETE` | `/orgs/{org}/teams/{team_slug}` | `OrganizationsService.deleteTeam` | supported | | +| `teams/get-by-name` | `GET` | `/orgs/{org}/teams/{team_slug}` | `OrganizationsService.getTeam` | supported | | +| `teams/get-membership-for-user-in-org` | `GET` | `/orgs/{org}/teams/{team_slug}/memberships/{username}` | `OrganizationsService.getTeamMembershipByName` | supported | | +| `teams/list` | `GET` | `/orgs/{org}/teams` | `OrganizationsService.listTeams` | supported | | +| `teams/list-members-in-org` | `GET` | `/orgs/{org}/teams/{team_slug}/members` | `OrganizationsService.listTeamMembers` | supported | | +| `teams/list-repos-in-org` | `GET` | `/orgs/{org}/teams/{team_slug}/repos` | `OrganizationsService.listTeamRepos` | supported | | +| `teams/remove-membership-for-user-in-org` | `DELETE` | `/orgs/{org}/teams/{team_slug}/memberships/{username}` | `OrganizationsService.removeTeamMembershipByName` | supported | | +| `teams/update-in-org` | `PATCH` | `/orgs/{org}/teams/{team_slug}` | `OrganizationsService.editTeam` | supported | | +| `users/add-email-for-authenticated-user` | `POST` | `/user/emails` | `UsersService.addEmails` | supported | | +| `users/check-following-for-user` | `GET` | `/users/{username}/following/{target_user}` | `UsersService.isFollowingUser` | supported | | +| `users/create-public-ssh-key-for-authenticated-user` | `POST` | `/user/keys` | `UsersService.createPublicKey` | supported | | +| `users/delete-email-for-authenticated-user` | `DELETE` | `/user/emails` | `UsersService.deleteEmails` | supported | | +| `users/delete-public-ssh-key-for-authenticated-user` | `DELETE` | `/user/keys/{key_id}` | `UsersService.deletePublicKey` | supported | | +| `users/follow` | `PUT` | `/user/following/{username}` | `UsersService.followUser` | supported | | +| `users/get-authenticated` | `GET` | `/user` | `UsersService.getCurrentUser` | supported | | +| `users/get-by-username` | `GET` | `/users/{username}` | `UsersService.getUser` | supported | | +| `users/list` | `GET` | `/users` | `UsersService.listUsers` | supported | | +| `users/list-emails-for-authenticated-user` | `GET` | `/user/emails` | `UsersService.listEmails` | supported | | +| `users/list-gpg-keys-for-authenticated-user` | `GET` | `/user/gpg_keys` | `UsersService.listGpgKeys` | supported | | +| `users/list-public-ssh-keys-for-authenticated-user` | `GET` | `/user/keys` | `UsersService.listPublicKeys` | supported | | +| `users/unfollow` | `DELETE` | `/user/following/{username}` | `UsersService.unfollowUser` | supported | | +| `users/update-authenticated` | `PATCH` | `/user` | `UsersService.editCurrentUser` | supported | | diff --git a/example/languages.dart b/example/languages.dart index aa8b7ec1..faf665ae 100644 --- a/example/languages.dart +++ b/example/languages.dart @@ -52,11 +52,11 @@ String generateMarkdown(int accuracy) { |Name|Bytes|Percentage| |-----|-----|-----| '''); - data.sort((a, b) => b[1].compareTo(a[1])); + data.sort((a, b) => (b[1] as num).compareTo(a[1] as num)); for (final info in data) { - final String? name = info[0]; - final int bytes = info[1]; + final name = info[0] as String?; + final bytes = info[1] as int; final num percentage = (bytes / total) * 100; md.writeln('|$name|$bytes|${percentage.toStringAsFixed(accuracy)}|'); } diff --git a/example/user_info.dart b/example/user_info.dart index 656207b1..b0cce403 100644 --- a/example/user_info.dart +++ b/example/user_info.dart @@ -53,7 +53,7 @@ void loadUser() { append('Created', user.createdAt); document.getElementById('load')!.hidden = true; document.getElementById('token')!.hidden = true; - }).catchError((e) { + }).catchError((Object e) { if (e is AccessForbidden) { window.alert('Invalid Token'); } diff --git a/lib/src/browser/xplat_browser.dart b/lib/src/browser/xplat_browser.dart index c54a2530..78f4ba13 100644 --- a/lib/src/browser/xplat_browser.dart +++ b/lib/src/browser/xplat_browser.dart @@ -5,13 +5,18 @@ import 'package:github/src/common.dart'; import 'package:github/src/common/xplat_common.dart' show findAuthenticationInMap; -/// Looks for GitHub Authentication information from the browser +/// Looks for GitHub Authentication information from the browser. /// -/// Checks for query strings first, then local storage using keys in [COMMON_GITHUB_TOKEN_ENV_KEYS]. -/// If the above fails, the GITHUB_USERNAME and GITHUB_PASSWORD keys will be checked. -Authentication findAuthenticationFromEnvironment() { - // search the query string parameters first - var auth = findAuthenticationInMap(_parseQuery(window.location.href)); +/// NOTE: Passing credentials in query strings is insecure as tokens can be +/// leaked via logs, browser history, screenshots, and Referer headers. +/// Extracting tokens from URL query parameters is disabled by default and deprecated. +/// Explicitly instantiate [Authentication] or use `window.sessionStorage`. +Authentication findAuthenticationFromEnvironment( + {bool allowQueryAuth = false}) { + Authentication? auth; + if (allowQueryAuth) { + auth = findAuthenticationInMap(_parseQuery(window.location.href)); + } auth ??= findAuthenticationInMap(window.sessionStorage); return auth ?? const Authentication.anonymous(); } diff --git a/lib/src/common.dart b/lib/src/common.dart index df783a26..e9874934 100644 --- a/lib/src/common.dart +++ b/lib/src/common.dart @@ -5,6 +5,7 @@ library; export 'package:github/src/common/activity_service.dart'; export 'package:github/src/common/authorizations_service.dart'; export 'package:github/src/common/checks_service.dart'; +export 'package:github/src/common/generated/rest_contracts.g.dart'; export 'package:github/src/common/gists_service.dart'; export 'package:github/src/common/git_service.dart'; export 'package:github/src/common/github.dart'; @@ -40,6 +41,10 @@ export 'package:github/src/common/orgs_service.dart'; export 'package:github/src/common/pulls_service.dart'; export 'package:github/src/common/repos_service.dart'; export 'package:github/src/common/search_service.dart'; +export 'package:github/src/common/transport/error_decoder.dart'; +export 'package:github/src/common/transport/request.dart'; +export 'package:github/src/common/transport/retry_policy.dart'; +export 'package:github/src/common/transport/transport.dart'; export 'package:github/src/common/url_shortener_service.dart'; export 'package:github/src/common/users_service.dart'; export 'package:github/src/common/util/auth.dart'; diff --git a/lib/src/common/activity_service.dart b/lib/src/common/activity_service.dart index f97aefcf..09830823 100644 --- a/lib/src/common/activity_service.dart +++ b/lib/src/common/activity_service.dart @@ -146,7 +146,7 @@ class ActivityService extends Service { /// /// API docs: https://developer.github.com/v3/activity/notifications/#mark-as-read Future markNotificationsRead({DateTime? lastRead}) { - final data = {}; + final data = {}; if (lastRead != null) { data['last_read_at'] = lastRead.toIso8601String(); @@ -167,7 +167,7 @@ class ActivityService extends Service { RepositorySlug slug, { DateTime? lastRead, }) { - final data = {}; + final data = {}; if (lastRead != null) { data['last_read_at'] = lastRead.toIso8601String(); @@ -185,7 +185,7 @@ class ActivityService extends Service { /// /// API docs: https://developer.github.com/v3/activity/notifications/#view-a-single-thread Future getThread(String threadId) => - github.getJSON('/notification/threads/$threadId', + github.getJSON('/notifications/threads/$threadId', statusCode: StatusCodes.OK, convert: Notification.fromJson); /// Mark the specified notification thread as read. @@ -244,21 +244,17 @@ class ActivityService extends Service { /// Stars the specified repository for the currently authenticated user. /// /// API docs: https://developer.github.com/v3/activity/starring/#star-a-repository - Future star(RepositorySlug slug) { - return github.request('PUT', '/user/starred/${slug.fullName}', - headers: {'Content-Length': '0'}).then((response) { - return null; - }); + Future star(RepositorySlug slug) async { + await github.request('PUT', '/user/starred/${slug.fullName}', + statusCode: 204, headers: {'Content-Length': '0'}); } /// Unstars the specified repository for the currently authenticated user. /// /// API docs: https://developer.github.com/v3/activity/starring/#unstar-a-repository - Future unstar(RepositorySlug slug) { - return github.request('DELETE', '/user/starred/${slug.fullName}', - headers: {'Content-Length': '0'}).then((response) { - return null; - }); + Future unstar(RepositorySlug slug) async { + await github.request('DELETE', '/user/starred/${slug.fullName}', + statusCode: 204, headers: {'Content-Length': '0'}); } /// Lists the watchers of the specified repository. @@ -315,10 +311,10 @@ class ActivityService extends Service { /// Deletes a Repository Subscription /// /// API docs: https://developer.github.com/v3/activity/watching/#delete-a-repository-subscription - Future deleteRepositorySubscription(RepositorySlug slug) { + Future deleteRepositorySubscription(RepositorySlug slug) { return github.request('DELETE', '/repos/${slug.fullName}/subscription', headers: {'Content-Length': '0'}).then((response) { - return null; + return; }); } } @@ -355,7 +351,8 @@ class EventPoller { _lastFetched = response.headers['ETag']; - final json = List>.from(jsonDecode(response.body)); + final json = List>.from( + jsonDecode(response.body) as Iterable); if (!(onlyNew && _timer == null)) { for (final item in json) { @@ -399,7 +396,7 @@ class EventPoller { return _controller!.stream; } - Future stop() { + Future stop() { if (_timer == null) { throw Exception('Polling not started.'); } diff --git a/lib/src/common/authorizations_service.dart b/lib/src/common/authorizations_service.dart index 68b80c25..235d292b 100644 --- a/lib/src/common/authorizations_service.dart +++ b/lib/src/common/authorizations_service.dart @@ -2,31 +2,27 @@ import 'dart:async'; import 'package:github/src/common.dart'; -/// The [AuthorizationsService] handles communication with authorizations related methods -/// of the GitHub API. +/// The [AuthorizationsService] handles communication with legacy OAuth authorizations. /// -/// Note: You can only access this API via Basic Authentication using your -/// username and password, not tokens. +/// **Deprecated**: The OAuth Authorizations API was sunset by GitHub. +/// Use modern OAuth web application flows or GitHub Apps instead. /// -/// API docs: https://developer.github.com/v3/oauth_authorizations/ +/// API docs: https://docs.github.com/en/rest/overview/resources-in-the-rest-api#oauth-authorizations-api +@Deprecated( + 'The OAuth Authorizations API has been sunset by GitHub. Use modern OAuth or GitHub Apps.') class AuthorizationsService extends Service { AuthorizationsService(super.github); /// Lists all authorizations. - /// - /// API docs: https://developer.github.com/v3/oauth_authorizations/#list-your-authorizations + @Deprecated('The OAuth Authorizations API has been sunset by GitHub.') Stream listAuthorizations() { return PaginationHelper(github) .objects('GET', '/authorizations', Authorization.fromJson); } /// Fetches an authorization specified by [id]. - /// - /// API docs: https://developer.github.com/v3/oauth_authorizations/#get-a-single-authorization + @Deprecated('The OAuth Authorizations API has been sunset by GitHub.') Future getAuthorization(int id) => github.getJSON('/authorizations/$id', statusCode: 200, convert: Authorization.fromJson); - - // TODO: Implement remaining API methods of authorizations: - // See https://developer.github.com/v3/oauth_authorizations/ } diff --git a/lib/src/common/checks_service.dart b/lib/src/common/checks_service.dart index 21feff81..7763ee7b 100644 --- a/lib/src/common/checks_service.dart +++ b/lib/src/common/checks_service.dart @@ -58,9 +58,18 @@ class CheckRunsService extends Service { CheckRunOutput? output, List? actions, }) async { - assert(conclusion != null || - (completedAt == null && status != CheckRunStatus.completed)); - assert(actions == null || actions.length <= 3); + if (status == CheckRunStatus.completed && conclusion == null) { + throw ArgumentError.value( + conclusion, 'conclusion', 'Required when status is completed'); + } + if (completedAt != null && conclusion == null) { + throw ArgumentError.value( + conclusion, 'conclusion', 'Required when completedAt is provided'); + } + if (actions != null && actions.length > 3) { + throw ArgumentError.value( + actions.length, 'actions', 'A maximum of 3 actions are accepted'); + } return github.postJSON, CheckRun>( '/repos/${slug.fullName}/check-runs', statusCode: StatusCodes.CREATED, @@ -109,9 +118,18 @@ class CheckRunsService extends Service { CheckRunOutput? output, List? actions, }) async { - assert(conclusion != null || - (completedAt == null && status != CheckRunStatus.completed)); - assert(actions == null || actions.length <= 3); + if (status == CheckRunStatus.completed && conclusion == null) { + throw ArgumentError.value( + conclusion, 'conclusion', 'Required when status is completed'); + } + if (completedAt != null && conclusion == null) { + throw ArgumentError.value( + conclusion, 'conclusion', 'Required when completedAt is provided'); + } + if (actions != null && actions.length > 3) { + throw ArgumentError.value( + actions.length, 'actions', 'A maximum of 3 actions are accepted'); + } return github.requestJson, CheckRun>( 'PATCH', '/repos/${slug.fullName}/check-runs/${checkRunToUpdate.id}', diff --git a/lib/src/common/generated/rest_contracts.g.dart b/lib/src/common/generated/rest_contracts.g.dart new file mode 100644 index 00000000..51841456 --- /dev/null +++ b/lib/src/common/generated/rest_contracts.g.dart @@ -0,0 +1,14978 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// Generated from GitHub OpenAPI 2022-11-28 description. + +/// Immutable contract metadata for a GitHub REST API operation. +class RestOperationContract { + final String operationId; + final String method; + final String path; + final List pathParams; + final List queryParams; + final List headerParams; + final bool hasRequestBody; + final List requestMediaTypes; + final List successStatuses; + final bool isMultiSegmentPath; + + const RestOperationContract({ + required this.operationId, + required this.method, + required this.path, + this.pathParams = const [], + this.queryParams = const [], + this.headerParams = const [], + this.hasRequestBody = false, + this.requestMediaTypes = const [], + this.successStatuses = const [200], + this.isMultiSegmentPath = false, + }); +} + +/// Catalog of all 2022-11-28 REST operation contracts. +abstract final class RestContracts { + /// `POST /orgs/{org}/actions/runners/{runner_id}/labels` + /// Add custom labels to a self-hosted runner for an organization + static const actionsAddCustomLabelsToSelfHostedRunnerForOrg = + RestOperationContract( + operationId: 'actions/add-custom-labels-to-self-hosted-runner-for-org', + method: 'POST', + path: '/orgs/{org}/actions/runners/{runner_id}/labels', + pathParams: ['org', 'runner_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/actions/runners/{runner_id}/labels` + /// Add custom labels to a self-hosted runner for a repository + static const actionsAddCustomLabelsToSelfHostedRunnerForRepo = + RestOperationContract( + operationId: 'actions/add-custom-labels-to-self-hosted-runner-for-repo', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/runners/{runner_id}/labels', + pathParams: ['owner', 'repo', 'runner_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories/{repository_id}` + /// Add repository access to a self-hosted runner group in an organization + static const actionsAddRepoAccessToSelfHostedRunnerGroupInOrg = + RestOperationContract( + operationId: 'actions/add-repo-access-to-self-hosted-runner-group-in-org', + method: 'PUT', + path: + '/orgs/{org}/actions/runner-groups/{runner_group_id}/repositories/{repository_id}', + pathParams: ['org', 'repository_id', 'runner_group_id'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}` + /// Add selected repository to an organization secret + static const actionsAddSelectedRepoToOrgSecret = RestOperationContract( + operationId: 'actions/add-selected-repo-to-org-secret', + method: 'PUT', + path: + '/orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}', + pathParams: ['org', 'repository_id', 'secret_name'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/variables/{name}/repositories/{repository_id}` + /// Add selected repository to an organization variable + static const actionsAddSelectedRepoToOrgVariable = RestOperationContract( + operationId: 'actions/add-selected-repo-to-org-variable', + method: 'PUT', + path: '/orgs/{org}/actions/variables/{name}/repositories/{repository_id}', + pathParams: ['name', 'org', 'repository_id'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/runner-groups/{runner_group_id}/runners/{runner_id}` + /// Add a self-hosted runner to a group for an organization + static const actionsAddSelfHostedRunnerToGroupForOrg = RestOperationContract( + operationId: 'actions/add-self-hosted-runner-to-group-for-org', + method: 'PUT', + path: + '/orgs/{org}/actions/runner-groups/{runner_group_id}/runners/{runner_id}', + pathParams: ['org', 'runner_group_id', 'runner_id'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/actions/runs/{run_id}/approve` + /// Approve a workflow run for a fork pull request + static const actionsApproveWorkflowRun = RestOperationContract( + operationId: 'actions/approve-workflow-run', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/approve', + pathParams: ['owner', 'repo', 'run_id'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel` + /// Cancel a workflow run + static const actionsCancelWorkflowRun = RestOperationContract( + operationId: 'actions/cancel-workflow-run', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/cancel', + pathParams: ['owner', 'repo', 'run_id'], + successStatuses: [202], + ); + + /// `POST /repos/{owner}/{repo}/environments/{environment_name}/variables` + /// Create an environment variable + static const actionsCreateEnvironmentVariable = RestOperationContract( + operationId: 'actions/create-environment-variable', + method: 'POST', + path: '/repos/{owner}/{repo}/environments/{environment_name}/variables', + pathParams: ['environment_name', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/actions/hosted-runners` + /// Create a GitHub-hosted runner for an organization + static const actionsCreateHostedRunnerForOrg = RestOperationContract( + operationId: 'actions/create-hosted-runner-for-org', + method: 'POST', + path: '/orgs/{org}/actions/hosted-runners', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `PUT /repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}` + /// Create or update an environment secret + static const actionsCreateOrUpdateEnvironmentSecret = RestOperationContract( + operationId: 'actions/create-or-update-environment-secret', + method: 'PUT', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}', + pathParams: ['environment_name', 'owner', 'repo', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 204], + ); + + /// `PUT /orgs/{org}/actions/secrets/{secret_name}` + /// Create or update an organization secret + static const actionsCreateOrUpdateOrgSecret = RestOperationContract( + operationId: 'actions/create-or-update-org-secret', + method: 'PUT', + path: '/orgs/{org}/actions/secrets/{secret_name}', + pathParams: ['org', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 204], + ); + + /// `PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}` + /// Create or update a repository secret + static const actionsCreateOrUpdateRepoSecret = RestOperationContract( + operationId: 'actions/create-or-update-repo-secret', + method: 'PUT', + path: '/repos/{owner}/{repo}/actions/secrets/{secret_name}', + pathParams: ['owner', 'repo', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 204], + ); + + /// `POST /orgs/{org}/actions/variables` + /// Create an organization variable + static const actionsCreateOrgVariable = RestOperationContract( + operationId: 'actions/create-org-variable', + method: 'POST', + path: '/orgs/{org}/actions/variables', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/actions/runners/registration-token` + /// Create a registration token for an organization + static const actionsCreateRegistrationTokenForOrg = RestOperationContract( + operationId: 'actions/create-registration-token-for-org', + method: 'POST', + path: '/orgs/{org}/actions/runners/registration-token', + pathParams: ['org'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/actions/runners/registration-token` + /// Create a registration token for a repository + static const actionsCreateRegistrationTokenForRepo = RestOperationContract( + operationId: 'actions/create-registration-token-for-repo', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/runners/registration-token', + pathParams: ['owner', 'repo'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/actions/runners/remove-token` + /// Create a remove token for an organization + static const actionsCreateRemoveTokenForOrg = RestOperationContract( + operationId: 'actions/create-remove-token-for-org', + method: 'POST', + path: '/orgs/{org}/actions/runners/remove-token', + pathParams: ['org'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/actions/runners/remove-token` + /// Create a remove token for a repository + static const actionsCreateRemoveTokenForRepo = RestOperationContract( + operationId: 'actions/create-remove-token-for-repo', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/runners/remove-token', + pathParams: ['owner', 'repo'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/actions/variables` + /// Create a repository variable + static const actionsCreateRepoVariable = RestOperationContract( + operationId: 'actions/create-repo-variable', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/variables', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/actions/runner-groups` + /// Create a self-hosted runner group for an organization + static const actionsCreateSelfHostedRunnerGroupForOrg = RestOperationContract( + operationId: 'actions/create-self-hosted-runner-group-for-org', + method: 'POST', + path: '/orgs/{org}/actions/runner-groups', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches` + /// Create a workflow dispatch event + static const actionsCreateWorkflowDispatch = RestOperationContract( + operationId: 'actions/create-workflow-dispatch', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches', + pathParams: ['owner', 'repo', 'workflow_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 204], + ); + + /// `DELETE /repos/{owner}/{repo}/actions/caches/{cache_id}` + /// Delete a GitHub Actions cache for a repository (using a cache ID) + static const actionsDeleteActionsCacheById = RestOperationContract( + operationId: 'actions/delete-actions-cache-by-id', + method: 'DELETE', + path: '/repos/{owner}/{repo}/actions/caches/{cache_id}', + pathParams: ['cache_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/actions/caches` + /// Delete GitHub Actions caches for a repository (using a cache key) + static const actionsDeleteActionsCacheByKey = RestOperationContract( + operationId: 'actions/delete-actions-cache-by-key', + method: 'DELETE', + path: '/repos/{owner}/{repo}/actions/caches', + pathParams: ['owner', 'repo'], + queryParams: ['key', 'ref'], + ); + + /// `DELETE /repos/{owner}/{repo}/actions/artifacts/{artifact_id}` + /// Delete an artifact + static const actionsDeleteArtifact = RestOperationContract( + operationId: 'actions/delete-artifact', + method: 'DELETE', + path: '/repos/{owner}/{repo}/actions/artifacts/{artifact_id}', + pathParams: ['artifact_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}` + /// Delete a custom image from the organization + static const actionsDeleteCustomImageFromOrg = RestOperationContract( + operationId: 'actions/delete-custom-image-from-org', + method: 'DELETE', + path: + '/orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}', + pathParams: ['image_definition_id', 'org'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}/versions/{version}` + /// Delete an image version of custom image from the organization + static const actionsDeleteCustomImageVersionFromOrg = RestOperationContract( + operationId: 'actions/delete-custom-image-version-from-org', + method: 'DELETE', + path: + '/orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}/versions/{version}', + pathParams: ['image_definition_id', 'org', 'version'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}` + /// Delete an environment secret + static const actionsDeleteEnvironmentSecret = RestOperationContract( + operationId: 'actions/delete-environment-secret', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}', + pathParams: ['environment_name', 'owner', 'repo', 'secret_name'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/environments/{environment_name}/variables/{name}` + /// Delete an environment variable + static const actionsDeleteEnvironmentVariable = RestOperationContract( + operationId: 'actions/delete-environment-variable', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/variables/{name}', + pathParams: ['environment_name', 'name', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/actions/hosted-runners/{hosted_runner_id}` + /// Delete a GitHub-hosted runner for an organization + static const actionsDeleteHostedRunnerForOrg = RestOperationContract( + operationId: 'actions/delete-hosted-runner-for-org', + method: 'DELETE', + path: '/orgs/{org}/actions/hosted-runners/{hosted_runner_id}', + pathParams: ['hosted_runner_id', 'org'], + successStatuses: [202], + ); + + /// `DELETE /orgs/{org}/actions/secrets/{secret_name}` + /// Delete an organization secret + static const actionsDeleteOrgSecret = RestOperationContract( + operationId: 'actions/delete-org-secret', + method: 'DELETE', + path: '/orgs/{org}/actions/secrets/{secret_name}', + pathParams: ['org', 'secret_name'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/actions/variables/{name}` + /// Delete an organization variable + static const actionsDeleteOrgVariable = RestOperationContract( + operationId: 'actions/delete-org-variable', + method: 'DELETE', + path: '/orgs/{org}/actions/variables/{name}', + pathParams: ['name', 'org'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/actions/secrets/{secret_name}` + /// Delete a repository secret + static const actionsDeleteRepoSecret = RestOperationContract( + operationId: 'actions/delete-repo-secret', + method: 'DELETE', + path: '/repos/{owner}/{repo}/actions/secrets/{secret_name}', + pathParams: ['owner', 'repo', 'secret_name'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/actions/variables/{name}` + /// Delete a repository variable + static const actionsDeleteRepoVariable = RestOperationContract( + operationId: 'actions/delete-repo-variable', + method: 'DELETE', + path: '/repos/{owner}/{repo}/actions/variables/{name}', + pathParams: ['name', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/actions/runners/{runner_id}` + /// Delete a self-hosted runner from an organization + static const actionsDeleteSelfHostedRunnerFromOrg = RestOperationContract( + operationId: 'actions/delete-self-hosted-runner-from-org', + method: 'DELETE', + path: '/orgs/{org}/actions/runners/{runner_id}', + pathParams: ['org', 'runner_id'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}` + /// Delete a self-hosted runner from a repository + static const actionsDeleteSelfHostedRunnerFromRepo = RestOperationContract( + operationId: 'actions/delete-self-hosted-runner-from-repo', + method: 'DELETE', + path: '/repos/{owner}/{repo}/actions/runners/{runner_id}', + pathParams: ['owner', 'repo', 'runner_id'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/actions/runner-groups/{runner_group_id}` + /// Delete a self-hosted runner group from an organization + static const actionsDeleteSelfHostedRunnerGroupFromOrg = + RestOperationContract( + operationId: 'actions/delete-self-hosted-runner-group-from-org', + method: 'DELETE', + path: '/orgs/{org}/actions/runner-groups/{runner_group_id}', + pathParams: ['org', 'runner_group_id'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/actions/runs/{run_id}` + /// Delete a workflow run + static const actionsDeleteWorkflowRun = RestOperationContract( + operationId: 'actions/delete-workflow-run', + method: 'DELETE', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}', + pathParams: ['owner', 'repo', 'run_id'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/actions/runs/{run_id}/logs` + /// Delete workflow run logs + static const actionsDeleteWorkflowRunLogs = RestOperationContract( + operationId: 'actions/delete-workflow-run-logs', + method: 'DELETE', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/logs', + pathParams: ['owner', 'repo', 'run_id'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/actions/permissions/repositories/{repository_id}` + /// Disable a selected repository for GitHub Actions in an organization + static const actionsDisableSelectedRepositoryGithubActionsOrganization = + RestOperationContract( + operationId: + 'actions/disable-selected-repository-github-actions-organization', + method: 'DELETE', + path: '/orgs/{org}/actions/permissions/repositories/{repository_id}', + pathParams: ['org', 'repository_id'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/actions/permissions/self-hosted-runners/repositories/{repository_id}` + /// Remove a repository from the list of repositories allowed to use self-hosted runners in an organization + static const actionsDisableSelectedRepositorySelfHostedRunnersOrganization = + RestOperationContract( + operationId: + 'actions/disable-selected-repository-self-hosted-runners-organization', + method: 'DELETE', + path: + '/orgs/{org}/actions/permissions/self-hosted-runners/repositories/{repository_id}', + pathParams: ['org', 'repository_id'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/disable` + /// Disable a workflow + static const actionsDisableWorkflow = RestOperationContract( + operationId: 'actions/disable-workflow', + method: 'PUT', + path: '/repos/{owner}/{repo}/actions/workflows/{workflow_id}/disable', + pathParams: ['owner', 'repo', 'workflow_id'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}/{archive_format}` + /// Download an artifact + static const actionsDownloadArtifact = RestOperationContract( + operationId: 'actions/download-artifact', + method: 'GET', + path: + '/repos/{owner}/{repo}/actions/artifacts/{artifact_id}/{archive_format}', + pathParams: ['archive_format', 'artifact_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/actions/jobs/{job_id}/logs` + /// Download job logs for a workflow run + static const actionsDownloadJobLogsForWorkflowRun = RestOperationContract( + operationId: 'actions/download-job-logs-for-workflow-run', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/jobs/{job_id}/logs', + pathParams: ['job_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/logs` + /// Download workflow run attempt logs + static const actionsDownloadWorkflowRunAttemptLogs = RestOperationContract( + operationId: 'actions/download-workflow-run-attempt-logs', + method: 'GET', + path: + '/repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/logs', + pathParams: ['attempt_number', 'owner', 'repo', 'run_id'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs` + /// Download workflow run logs + static const actionsDownloadWorkflowRunLogs = RestOperationContract( + operationId: 'actions/download-workflow-run-logs', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/logs', + pathParams: ['owner', 'repo', 'run_id'], + ); + + /// `PUT /orgs/{org}/actions/permissions/repositories/{repository_id}` + /// Enable a selected repository for GitHub Actions in an organization + static const actionsEnableSelectedRepositoryGithubActionsOrganization = + RestOperationContract( + operationId: + 'actions/enable-selected-repository-github-actions-organization', + method: 'PUT', + path: '/orgs/{org}/actions/permissions/repositories/{repository_id}', + pathParams: ['org', 'repository_id'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/permissions/self-hosted-runners/repositories/{repository_id}` + /// Add a repository to the list of repositories allowed to use self-hosted runners in an organization + static const actionsEnableSelectedRepositorySelfHostedRunnersOrganization = + RestOperationContract( + operationId: + 'actions/enable-selected-repository-self-hosted-runners-organization', + method: 'PUT', + path: + '/orgs/{org}/actions/permissions/self-hosted-runners/repositories/{repository_id}', + pathParams: ['org', 'repository_id'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable` + /// Enable a workflow + static const actionsEnableWorkflow = RestOperationContract( + operationId: 'actions/enable-workflow', + method: 'PUT', + path: '/repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable', + pathParams: ['owner', 'repo', 'workflow_id'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/actions/runs/{run_id}/force-cancel` + /// Force cancel a workflow run + static const actionsForceCancelWorkflowRun = RestOperationContract( + operationId: 'actions/force-cancel-workflow-run', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/force-cancel', + pathParams: ['owner', 'repo', 'run_id'], + successStatuses: [202], + ); + + /// `POST /orgs/{org}/actions/runners/generate-jitconfig` + /// Create configuration for a just-in-time runner for an organization + static const actionsGenerateRunnerJitconfigForOrg = RestOperationContract( + operationId: 'actions/generate-runner-jitconfig-for-org', + method: 'POST', + path: '/orgs/{org}/actions/runners/generate-jitconfig', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/actions/runners/generate-jitconfig` + /// Create configuration for a just-in-time runner for a repository + static const actionsGenerateRunnerJitconfigForRepo = RestOperationContract( + operationId: 'actions/generate-runner-jitconfig-for-repo', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/runners/generate-jitconfig', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `GET /repos/{owner}/{repo}/actions/caches` + /// List GitHub Actions caches for a repository + static const actionsGetActionsCacheList = RestOperationContract( + operationId: 'actions/get-actions-cache-list', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/caches', + pathParams: ['owner', 'repo'], + queryParams: ['direction', 'key', 'page', 'per_page', 'ref', 'sort'], + ); + + /// `GET /enterprises/{enterprise}/actions/cache/retention-limit` + /// Get GitHub Actions cache retention limit for an enterprise + static const actionsGetActionsCacheRetentionLimitForEnterprise = + RestOperationContract( + operationId: 'actions/get-actions-cache-retention-limit-for-enterprise', + method: 'GET', + path: '/enterprises/{enterprise}/actions/cache/retention-limit', + pathParams: ['enterprise'], + ); + + /// `GET /organizations/{org}/actions/cache/retention-limit` + /// Get GitHub Actions cache retention limit for an organization + static const actionsGetActionsCacheRetentionLimitForOrganization = + RestOperationContract( + operationId: 'actions/get-actions-cache-retention-limit-for-organization', + method: 'GET', + path: '/organizations/{org}/actions/cache/retention-limit', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/actions/cache/retention-limit` + /// Get GitHub Actions cache retention limit for a repository + static const actionsGetActionsCacheRetentionLimitForRepository = + RestOperationContract( + operationId: 'actions/get-actions-cache-retention-limit-for-repository', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/cache/retention-limit', + pathParams: ['owner', 'repo'], + ); + + /// `GET /enterprises/{enterprise}/actions/cache/storage-limit` + /// Get GitHub Actions cache storage limit for an enterprise + static const actionsGetActionsCacheStorageLimitForEnterprise = + RestOperationContract( + operationId: 'actions/get-actions-cache-storage-limit-for-enterprise', + method: 'GET', + path: '/enterprises/{enterprise}/actions/cache/storage-limit', + pathParams: ['enterprise'], + ); + + /// `GET /organizations/{org}/actions/cache/storage-limit` + /// Get GitHub Actions cache storage limit for an organization + static const actionsGetActionsCacheStorageLimitForOrganization = + RestOperationContract( + operationId: 'actions/get-actions-cache-storage-limit-for-organization', + method: 'GET', + path: '/organizations/{org}/actions/cache/storage-limit', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/actions/cache/storage-limit` + /// Get GitHub Actions cache storage limit for a repository + static const actionsGetActionsCacheStorageLimitForRepository = + RestOperationContract( + operationId: 'actions/get-actions-cache-storage-limit-for-repository', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/cache/storage-limit', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/actions/cache/usage` + /// Get GitHub Actions cache usage for a repository + static const actionsGetActionsCacheUsage = RestOperationContract( + operationId: 'actions/get-actions-cache-usage', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/cache/usage', + pathParams: ['owner', 'repo'], + ); + + /// `GET /orgs/{org}/actions/cache/usage-by-repository` + /// List repositories with GitHub Actions cache usage for an organization + static const actionsGetActionsCacheUsageByRepoForOrg = RestOperationContract( + operationId: 'actions/get-actions-cache-usage-by-repo-for-org', + method: 'GET', + path: '/orgs/{org}/actions/cache/usage-by-repository', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/cache/usage` + /// Get GitHub Actions cache usage for an organization + static const actionsGetActionsCacheUsageForOrg = RestOperationContract( + operationId: 'actions/get-actions-cache-usage-for-org', + method: 'GET', + path: '/orgs/{org}/actions/cache/usage', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/actions/permissions/selected-actions` + /// Get allowed actions and reusable workflows for an organization + static const actionsGetAllowedActionsOrganization = RestOperationContract( + operationId: 'actions/get-allowed-actions-organization', + method: 'GET', + path: '/orgs/{org}/actions/permissions/selected-actions', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/actions/permissions/selected-actions` + /// Get allowed actions and reusable workflows for a repository + static const actionsGetAllowedActionsRepository = RestOperationContract( + operationId: 'actions/get-allowed-actions-repository', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/permissions/selected-actions', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}` + /// Get an artifact + static const actionsGetArtifact = RestOperationContract( + operationId: 'actions/get-artifact', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/artifacts/{artifact_id}', + pathParams: ['artifact_id', 'owner', 'repo'], + ); + + /// `GET /orgs/{org}/actions/permissions/artifact-and-log-retention` + /// Get artifact and log retention settings for an organization + static const actionsGetArtifactAndLogRetentionSettingsOrganization = + RestOperationContract( + operationId: 'actions/get-artifact-and-log-retention-settings-organization', + method: 'GET', + path: '/orgs/{org}/actions/permissions/artifact-and-log-retention', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/actions/permissions/artifact-and-log-retention` + /// Get artifact and log retention settings for a repository + static const actionsGetArtifactAndLogRetentionSettingsRepository = + RestOperationContract( + operationId: 'actions/get-artifact-and-log-retention-settings-repository', + method: 'GET', + path: + '/repos/{owner}/{repo}/actions/permissions/artifact-and-log-retention', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}` + /// Get a concurrency group for a repository + static const actionsGetConcurrencyGroupForRepository = RestOperationContract( + operationId: 'actions/get-concurrency-group-for-repository', + method: 'GET', + path: + '/repos/{owner}/{repo}/actions/concurrency_groups/{concurrency_group_name}', + pathParams: ['concurrency_group_name', 'owner', 'repo'], + queryParams: ['ahead_of_job', 'ahead_of_run'], + ); + + /// `GET /orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}` + /// Get a custom image definition for GitHub Actions Hosted Runners + static const actionsGetCustomImageForOrg = RestOperationContract( + operationId: 'actions/get-custom-image-for-org', + method: 'GET', + path: + '/orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}', + pathParams: ['image_definition_id', 'org'], + ); + + /// `GET /orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}/versions/{version}` + /// Get an image version of a custom image for GitHub Actions Hosted Runners + static const actionsGetCustomImageVersionForOrg = RestOperationContract( + operationId: 'actions/get-custom-image-version-for-org', + method: 'GET', + path: + '/orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}/versions/{version}', + pathParams: ['image_definition_id', 'org', 'version'], + ); + + /// `GET /repos/{owner}/{repo}/actions/oidc/customization/sub` + /// Get the customization template for an OIDC subject claim for a repository + static const actionsGetCustomOidcSubClaimForRepo = RestOperationContract( + operationId: 'actions/get-custom-oidc-sub-claim-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/oidc/customization/sub', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/environments/{environment_name}/secrets/public-key` + /// Get an environment public key + static const actionsGetEnvironmentPublicKey = RestOperationContract( + operationId: 'actions/get-environment-public-key', + method: 'GET', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/secrets/public-key', + pathParams: ['environment_name', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}` + /// Get an environment secret + static const actionsGetEnvironmentSecret = RestOperationContract( + operationId: 'actions/get-environment-secret', + method: 'GET', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}', + pathParams: ['environment_name', 'owner', 'repo', 'secret_name'], + ); + + /// `GET /repos/{owner}/{repo}/environments/{environment_name}/variables/{name}` + /// Get an environment variable + static const actionsGetEnvironmentVariable = RestOperationContract( + operationId: 'actions/get-environment-variable', + method: 'GET', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/variables/{name}', + pathParams: ['environment_name', 'name', 'owner', 'repo'], + ); + + /// `GET /orgs/{org}/actions/permissions/fork-pr-contributor-approval` + /// Get fork PR contributor approval permissions for an organization + static const actionsGetForkPrContributorApprovalPermissionsOrganization = + RestOperationContract( + operationId: + 'actions/get-fork-pr-contributor-approval-permissions-organization', + method: 'GET', + path: '/orgs/{org}/actions/permissions/fork-pr-contributor-approval', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/actions/permissions/fork-pr-contributor-approval` + /// Get fork PR contributor approval permissions for a repository + static const actionsGetForkPrContributorApprovalPermissionsRepository = + RestOperationContract( + operationId: + 'actions/get-fork-pr-contributor-approval-permissions-repository', + method: 'GET', + path: + '/repos/{owner}/{repo}/actions/permissions/fork-pr-contributor-approval', + pathParams: ['owner', 'repo'], + ); + + /// `GET /orgs/{org}/actions/permissions/workflow` + /// Get default workflow permissions for an organization + static const actionsGetGithubActionsDefaultWorkflowPermissionsOrganization = + RestOperationContract( + operationId: + 'actions/get-github-actions-default-workflow-permissions-organization', + method: 'GET', + path: '/orgs/{org}/actions/permissions/workflow', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/actions/permissions/workflow` + /// Get default workflow permissions for a repository + static const actionsGetGithubActionsDefaultWorkflowPermissionsRepository = + RestOperationContract( + operationId: + 'actions/get-github-actions-default-workflow-permissions-repository', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/permissions/workflow', + pathParams: ['owner', 'repo'], + ); + + /// `GET /orgs/{org}/actions/permissions` + /// Get GitHub Actions permissions for an organization + static const actionsGetGithubActionsPermissionsOrganization = + RestOperationContract( + operationId: 'actions/get-github-actions-permissions-organization', + method: 'GET', + path: '/orgs/{org}/actions/permissions', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/actions/permissions` + /// Get GitHub Actions permissions for a repository + static const actionsGetGithubActionsPermissionsRepository = + RestOperationContract( + operationId: 'actions/get-github-actions-permissions-repository', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/permissions', + pathParams: ['owner', 'repo'], + ); + + /// `GET /orgs/{org}/actions/hosted-runners/{hosted_runner_id}` + /// Get a GitHub-hosted runner for an organization + static const actionsGetHostedRunnerForOrg = RestOperationContract( + operationId: 'actions/get-hosted-runner-for-org', + method: 'GET', + path: '/orgs/{org}/actions/hosted-runners/{hosted_runner_id}', + pathParams: ['hosted_runner_id', 'org'], + ); + + /// `GET /orgs/{org}/actions/hosted-runners/images/github-owned` + /// Get GitHub-owned images for GitHub-hosted runners in an organization + static const actionsGetHostedRunnersGithubOwnedImagesForOrg = + RestOperationContract( + operationId: 'actions/get-hosted-runners-github-owned-images-for-org', + method: 'GET', + path: '/orgs/{org}/actions/hosted-runners/images/github-owned', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/actions/hosted-runners/limits` + /// Get limits on GitHub-hosted runners for an organization + static const actionsGetHostedRunnersLimitsForOrg = RestOperationContract( + operationId: 'actions/get-hosted-runners-limits-for-org', + method: 'GET', + path: '/orgs/{org}/actions/hosted-runners/limits', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/actions/hosted-runners/machine-sizes` + /// Get GitHub-hosted runners machine specs for an organization + static const actionsGetHostedRunnersMachineSpecsForOrg = + RestOperationContract( + operationId: 'actions/get-hosted-runners-machine-specs-for-org', + method: 'GET', + path: '/orgs/{org}/actions/hosted-runners/machine-sizes', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/actions/hosted-runners/images/partner` + /// Get partner images for GitHub-hosted runners in an organization + static const actionsGetHostedRunnersPartnerImagesForOrg = + RestOperationContract( + operationId: 'actions/get-hosted-runners-partner-images-for-org', + method: 'GET', + path: '/orgs/{org}/actions/hosted-runners/images/partner', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/actions/hosted-runners/platforms` + /// Get platforms for GitHub-hosted runners in an organization + static const actionsGetHostedRunnersPlatformsForOrg = RestOperationContract( + operationId: 'actions/get-hosted-runners-platforms-for-org', + method: 'GET', + path: '/orgs/{org}/actions/hosted-runners/platforms', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/actions/jobs/{job_id}` + /// Get a job for a workflow run + static const actionsGetJobForWorkflowRun = RestOperationContract( + operationId: 'actions/get-job-for-workflow-run', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/jobs/{job_id}', + pathParams: ['job_id', 'owner', 'repo'], + ); + + /// `GET /orgs/{org}/actions/secrets/public-key` + /// Get an organization public key + static const actionsGetOrgPublicKey = RestOperationContract( + operationId: 'actions/get-org-public-key', + method: 'GET', + path: '/orgs/{org}/actions/secrets/public-key', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/actions/secrets/{secret_name}` + /// Get an organization secret + static const actionsGetOrgSecret = RestOperationContract( + operationId: 'actions/get-org-secret', + method: 'GET', + path: '/orgs/{org}/actions/secrets/{secret_name}', + pathParams: ['org', 'secret_name'], + ); + + /// `GET /orgs/{org}/actions/variables/{name}` + /// Get an organization variable + static const actionsGetOrgVariable = RestOperationContract( + operationId: 'actions/get-org-variable', + method: 'GET', + path: '/orgs/{org}/actions/variables/{name}', + pathParams: ['name', 'org'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments` + /// Get pending deployments for a workflow run + static const actionsGetPendingDeploymentsForRun = RestOperationContract( + operationId: 'actions/get-pending-deployments-for-run', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments', + pathParams: ['owner', 'repo', 'run_id'], + ); + + /// `GET /orgs/{org}/actions/permissions/fork-pr-workflows-private-repos` + /// Get private repo fork PR workflow settings for an organization + static const actionsGetPrivateRepoForkPrWorkflowsSettingsOrganization = + RestOperationContract( + operationId: + 'actions/get-private-repo-fork-pr-workflows-settings-organization', + method: 'GET', + path: '/orgs/{org}/actions/permissions/fork-pr-workflows-private-repos', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/actions/permissions/fork-pr-workflows-private-repos` + /// Get private repo fork PR workflow settings for a repository + static const actionsGetPrivateRepoForkPrWorkflowsSettingsRepository = + RestOperationContract( + operationId: + 'actions/get-private-repo-fork-pr-workflows-settings-repository', + method: 'GET', + path: + '/repos/{owner}/{repo}/actions/permissions/fork-pr-workflows-private-repos', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/actions/secrets/public-key` + /// Get a repository public key + static const actionsGetRepoPublicKey = RestOperationContract( + operationId: 'actions/get-repo-public-key', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/secrets/public-key', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/actions/secrets/{secret_name}` + /// Get a repository secret + static const actionsGetRepoSecret = RestOperationContract( + operationId: 'actions/get-repo-secret', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/secrets/{secret_name}', + pathParams: ['owner', 'repo', 'secret_name'], + ); + + /// `GET /repos/{owner}/{repo}/actions/variables/{name}` + /// Get a repository variable + static const actionsGetRepoVariable = RestOperationContract( + operationId: 'actions/get-repo-variable', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/variables/{name}', + pathParams: ['name', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runs/{run_id}/approvals` + /// Get the review history for a workflow run + static const actionsGetReviewsForRun = RestOperationContract( + operationId: 'actions/get-reviews-for-run', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/approvals', + pathParams: ['owner', 'repo', 'run_id'], + ); + + /// `GET /orgs/{org}/actions/runners/deprecations/{version}` + /// Get runner version end-of-life schedule for an organization + static const actionsGetRunnerVersionDeprecationForOrg = RestOperationContract( + operationId: 'actions/get-runner-version-deprecation-for-org', + method: 'GET', + path: '/orgs/{org}/actions/runners/deprecations/{version}', + pathParams: ['org', 'version'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runners/deprecations/{version}` + /// Get runner version end-of-life schedule for a repository + static const actionsGetRunnerVersionDeprecationForRepo = + RestOperationContract( + operationId: 'actions/get-runner-version-deprecation-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runners/deprecations/{version}', + pathParams: ['owner', 'repo', 'version'], + ); + + /// `GET /orgs/{org}/actions/runners/{runner_id}` + /// Get a self-hosted runner for an organization + static const actionsGetSelfHostedRunnerForOrg = RestOperationContract( + operationId: 'actions/get-self-hosted-runner-for-org', + method: 'GET', + path: '/orgs/{org}/actions/runners/{runner_id}', + pathParams: ['org', 'runner_id'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runners/{runner_id}` + /// Get a self-hosted runner for a repository + static const actionsGetSelfHostedRunnerForRepo = RestOperationContract( + operationId: 'actions/get-self-hosted-runner-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runners/{runner_id}', + pathParams: ['owner', 'repo', 'runner_id'], + ); + + /// `GET /orgs/{org}/actions/runner-groups/{runner_group_id}` + /// Get a self-hosted runner group for an organization + static const actionsGetSelfHostedRunnerGroupForOrg = RestOperationContract( + operationId: 'actions/get-self-hosted-runner-group-for-org', + method: 'GET', + path: '/orgs/{org}/actions/runner-groups/{runner_group_id}', + pathParams: ['org', 'runner_group_id'], + ); + + /// `GET /orgs/{org}/actions/permissions/self-hosted-runners` + /// Get self-hosted runners settings for an organization + static const actionsGetSelfHostedRunnersPermissionsOrganization = + RestOperationContract( + operationId: 'actions/get-self-hosted-runners-permissions-organization', + method: 'GET', + path: '/orgs/{org}/actions/permissions/self-hosted-runners', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}` + /// Get a workflow + static const actionsGetWorkflow = RestOperationContract( + operationId: 'actions/get-workflow', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/workflows/{workflow_id}', + pathParams: ['owner', 'repo', 'workflow_id'], + ); + + /// `GET /repos/{owner}/{repo}/actions/permissions/access` + /// Get the level of access for workflows outside of the repository + static const actionsGetWorkflowAccessToRepository = RestOperationContract( + operationId: 'actions/get-workflow-access-to-repository', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/permissions/access', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runs/{run_id}` + /// Get a workflow run + static const actionsGetWorkflowRun = RestOperationContract( + operationId: 'actions/get-workflow-run', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}', + pathParams: ['owner', 'repo', 'run_id'], + queryParams: ['exclude_pull_requests'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}` + /// Get a workflow run attempt + static const actionsGetWorkflowRunAttempt = RestOperationContract( + operationId: 'actions/get-workflow-run-attempt', + method: 'GET', + path: + '/repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}', + pathParams: ['attempt_number', 'owner', 'repo', 'run_id'], + queryParams: ['exclude_pull_requests'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runs/{run_id}/timing` + /// Get workflow run usage + static const actionsGetWorkflowRunUsage = RestOperationContract( + operationId: 'actions/get-workflow-run-usage', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/timing', + pathParams: ['owner', 'repo', 'run_id'], + ); + + /// `GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/timing` + /// Get workflow usage + static const actionsGetWorkflowUsage = RestOperationContract( + operationId: 'actions/get-workflow-usage', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/workflows/{workflow_id}/timing', + pathParams: ['owner', 'repo', 'workflow_id'], + ); + + /// `GET /repos/{owner}/{repo}/actions/artifacts` + /// List artifacts for a repository + static const actionsListArtifactsForRepo = RestOperationContract( + operationId: 'actions/list-artifacts-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/artifacts', + pathParams: ['owner', 'repo'], + queryParams: ['name', 'page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/actions/concurrency_groups` + /// List concurrency groups for a repository + static const actionsListConcurrencyGroupsForRepository = + RestOperationContract( + operationId: 'actions/list-concurrency-groups-for-repository', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/concurrency_groups', + pathParams: ['owner', 'repo'], + queryParams: ['after', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups` + /// List concurrency groups for a workflow run + static const actionsListConcurrencyGroupsForWorkflowRun = + RestOperationContract( + operationId: 'actions/list-concurrency-groups-for-workflow-run', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/concurrency_groups', + pathParams: ['owner', 'repo', 'run_id'], + queryParams: ['after', 'before', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}/versions` + /// List image versions of a custom image for an organization + static const actionsListCustomImageVersionsForOrg = RestOperationContract( + operationId: 'actions/list-custom-image-versions-for-org', + method: 'GET', + path: + '/orgs/{org}/actions/hosted-runners/images/custom/{image_definition_id}/versions', + pathParams: ['image_definition_id', 'org'], + ); + + /// `GET /orgs/{org}/actions/hosted-runners/images/custom` + /// List custom images for an organization + static const actionsListCustomImagesForOrg = RestOperationContract( + operationId: 'actions/list-custom-images-for-org', + method: 'GET', + path: '/orgs/{org}/actions/hosted-runners/images/custom', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/environments/{environment_name}/secrets` + /// List environment secrets + static const actionsListEnvironmentSecrets = RestOperationContract( + operationId: 'actions/list-environment-secrets', + method: 'GET', + path: '/repos/{owner}/{repo}/environments/{environment_name}/secrets', + pathParams: ['environment_name', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/environments/{environment_name}/variables` + /// List environment variables + static const actionsListEnvironmentVariables = RestOperationContract( + operationId: 'actions/list-environment-variables', + method: 'GET', + path: '/repos/{owner}/{repo}/environments/{environment_name}/variables', + pathParams: ['environment_name', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/runner-groups/{runner_group_id}/hosted-runners` + /// List GitHub-hosted runners in a group for an organization + static const actionsListGithubHostedRunnersInGroupForOrg = + RestOperationContract( + operationId: 'actions/list-github-hosted-runners-in-group-for-org', + method: 'GET', + path: '/orgs/{org}/actions/runner-groups/{runner_group_id}/hosted-runners', + pathParams: ['org', 'runner_group_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/hosted-runners` + /// List GitHub-hosted runners for an organization + static const actionsListHostedRunnersForOrg = RestOperationContract( + operationId: 'actions/list-hosted-runners-for-org', + method: 'GET', + path: '/orgs/{org}/actions/hosted-runners', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs` + /// List jobs for a workflow run + static const actionsListJobsForWorkflowRun = RestOperationContract( + operationId: 'actions/list-jobs-for-workflow-run', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/jobs', + pathParams: ['owner', 'repo', 'run_id'], + queryParams: ['filter', 'page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs` + /// List jobs for a workflow run attempt + static const actionsListJobsForWorkflowRunAttempt = RestOperationContract( + operationId: 'actions/list-jobs-for-workflow-run-attempt', + method: 'GET', + path: + '/repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs', + pathParams: ['attempt_number', 'owner', 'repo', 'run_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/runners/{runner_id}/labels` + /// List labels for a self-hosted runner for an organization + static const actionsListLabelsForSelfHostedRunnerForOrg = + RestOperationContract( + operationId: 'actions/list-labels-for-self-hosted-runner-for-org', + method: 'GET', + path: '/orgs/{org}/actions/runners/{runner_id}/labels', + pathParams: ['org', 'runner_id'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runners/{runner_id}/labels` + /// List labels for a self-hosted runner for a repository + static const actionsListLabelsForSelfHostedRunnerForRepo = + RestOperationContract( + operationId: 'actions/list-labels-for-self-hosted-runner-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runners/{runner_id}/labels', + pathParams: ['owner', 'repo', 'runner_id'], + ); + + /// `GET /orgs/{org}/actions/secrets` + /// List organization secrets + static const actionsListOrgSecrets = RestOperationContract( + operationId: 'actions/list-org-secrets', + method: 'GET', + path: '/orgs/{org}/actions/secrets', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/variables` + /// List organization variables + static const actionsListOrgVariables = RestOperationContract( + operationId: 'actions/list-org-variables', + method: 'GET', + path: '/orgs/{org}/actions/variables', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories` + /// List repository access to a self-hosted runner group in an organization + static const actionsListRepoAccessToSelfHostedRunnerGroupInOrg = + RestOperationContract( + operationId: 'actions/list-repo-access-to-self-hosted-runner-group-in-org', + method: 'GET', + path: '/orgs/{org}/actions/runner-groups/{runner_group_id}/repositories', + pathParams: ['org', 'runner_group_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/actions/organization-secrets` + /// List repository organization secrets + static const actionsListRepoOrganizationSecrets = RestOperationContract( + operationId: 'actions/list-repo-organization-secrets', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/organization-secrets', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/actions/organization-variables` + /// List repository organization variables + static const actionsListRepoOrganizationVariables = RestOperationContract( + operationId: 'actions/list-repo-organization-variables', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/organization-variables', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/actions/secrets` + /// List repository secrets + static const actionsListRepoSecrets = RestOperationContract( + operationId: 'actions/list-repo-secrets', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/secrets', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/actions/variables` + /// List repository variables + static const actionsListRepoVariables = RestOperationContract( + operationId: 'actions/list-repo-variables', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/variables', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/actions/workflows` + /// List repository workflows + static const actionsListRepoWorkflows = RestOperationContract( + operationId: 'actions/list-repo-workflows', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/workflows', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/runners/downloads` + /// List runner applications for an organization + static const actionsListRunnerApplicationsForOrg = RestOperationContract( + operationId: 'actions/list-runner-applications-for-org', + method: 'GET', + path: '/orgs/{org}/actions/runners/downloads', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runners/downloads` + /// List runner applications for a repository + static const actionsListRunnerApplicationsForRepo = RestOperationContract( + operationId: 'actions/list-runner-applications-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runners/downloads', + pathParams: ['owner', 'repo'], + ); + + /// `GET /orgs/{org}/actions/secrets/{secret_name}/repositories` + /// List selected repositories for an organization secret + static const actionsListSelectedReposForOrgSecret = RestOperationContract( + operationId: 'actions/list-selected-repos-for-org-secret', + method: 'GET', + path: '/orgs/{org}/actions/secrets/{secret_name}/repositories', + pathParams: ['org', 'secret_name'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/variables/{name}/repositories` + /// List selected repositories for an organization variable + static const actionsListSelectedReposForOrgVariable = RestOperationContract( + operationId: 'actions/list-selected-repos-for-org-variable', + method: 'GET', + path: '/orgs/{org}/actions/variables/{name}/repositories', + pathParams: ['name', 'org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/permissions/repositories` + /// List selected repositories enabled for GitHub Actions in an organization + static const actionsListSelectedRepositoriesEnabledGithubActionsOrganization = + RestOperationContract( + operationId: + 'actions/list-selected-repositories-enabled-github-actions-organization', + method: 'GET', + path: '/orgs/{org}/actions/permissions/repositories', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/permissions/self-hosted-runners/repositories` + /// List repositories allowed to use self-hosted runners in an organization + static const actionsListSelectedRepositoriesSelfHostedRunnersOrganization = + RestOperationContract( + operationId: + 'actions/list-selected-repositories-self-hosted-runners-organization', + method: 'GET', + path: '/orgs/{org}/actions/permissions/self-hosted-runners/repositories', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/runner-groups` + /// List self-hosted runner groups for an organization + static const actionsListSelfHostedRunnerGroupsForOrg = RestOperationContract( + operationId: 'actions/list-self-hosted-runner-groups-for-org', + method: 'GET', + path: '/orgs/{org}/actions/runner-groups', + pathParams: ['org'], + queryParams: ['page', 'per_page', 'visible_to_repository'], + ); + + /// `GET /orgs/{org}/actions/runners` + /// List self-hosted runners for an organization + static const actionsListSelfHostedRunnersForOrg = RestOperationContract( + operationId: 'actions/list-self-hosted-runners-for-org', + method: 'GET', + path: '/orgs/{org}/actions/runners', + pathParams: ['org'], + queryParams: ['name', 'page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runners` + /// List self-hosted runners for a repository + static const actionsListSelfHostedRunnersForRepo = RestOperationContract( + operationId: 'actions/list-self-hosted-runners-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runners', + pathParams: ['owner', 'repo'], + queryParams: ['name', 'page', 'per_page'], + ); + + /// `GET /orgs/{org}/actions/runner-groups/{runner_group_id}/runners` + /// List self-hosted runners in a group for an organization + static const actionsListSelfHostedRunnersInGroupForOrg = + RestOperationContract( + operationId: 'actions/list-self-hosted-runners-in-group-for-org', + method: 'GET', + path: '/orgs/{org}/actions/runner-groups/{runner_group_id}/runners', + pathParams: ['org', 'runner_group_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts` + /// List workflow run artifacts + static const actionsListWorkflowRunArtifacts = RestOperationContract( + operationId: 'actions/list-workflow-run-artifacts', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/artifacts', + pathParams: ['owner', 'repo', 'run_id'], + queryParams: ['direction', 'name', 'page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs` + /// List workflow runs for a workflow + static const actionsListWorkflowRuns = RestOperationContract( + operationId: 'actions/list-workflow-runs', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs', + pathParams: ['owner', 'repo', 'workflow_id'], + queryParams: [ + 'actor', + 'branch', + 'check_suite_id', + 'created', + 'event', + 'exclude_pull_requests', + 'head_sha', + 'page', + 'per_page', + 'status' + ], + ); + + /// `GET /repos/{owner}/{repo}/actions/runs` + /// List workflow runs for a repository + static const actionsListWorkflowRunsForRepo = RestOperationContract( + operationId: 'actions/list-workflow-runs-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/actions/runs', + pathParams: ['owner', 'repo'], + queryParams: [ + 'actor', + 'branch', + 'check_suite_id', + 'created', + 'event', + 'exclude_pull_requests', + 'head_sha', + 'page', + 'per_page', + 'status' + ], + ); + + /// `POST /repos/{owner}/{repo}/actions/jobs/{job_id}/rerun` + /// Re-run a job from a workflow run + static const actionsReRunJobForWorkflowRun = RestOperationContract( + operationId: 'actions/re-run-job-for-workflow-run', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/jobs/{job_id}/rerun', + pathParams: ['job_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun` + /// Re-run a workflow + static const actionsReRunWorkflow = RestOperationContract( + operationId: 'actions/re-run-workflow', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/rerun', + pathParams: ['owner', 'repo', 'run_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun-failed-jobs` + /// Re-run failed jobs from a workflow run + static const actionsReRunWorkflowFailedJobs = RestOperationContract( + operationId: 'actions/re-run-workflow-failed-jobs', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/rerun-failed-jobs', + pathParams: ['owner', 'repo', 'run_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /orgs/{org}/actions/runners/{runner_id}/labels` + /// Remove all custom labels from a self-hosted runner for an organization + static const actionsRemoveAllCustomLabelsFromSelfHostedRunnerForOrg = + RestOperationContract( + operationId: + 'actions/remove-all-custom-labels-from-self-hosted-runner-for-org', + method: 'DELETE', + path: '/orgs/{org}/actions/runners/{runner_id}/labels', + pathParams: ['org', 'runner_id'], + ); + + /// `DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}/labels` + /// Remove all custom labels from a self-hosted runner for a repository + static const actionsRemoveAllCustomLabelsFromSelfHostedRunnerForRepo = + RestOperationContract( + operationId: + 'actions/remove-all-custom-labels-from-self-hosted-runner-for-repo', + method: 'DELETE', + path: '/repos/{owner}/{repo}/actions/runners/{runner_id}/labels', + pathParams: ['owner', 'repo', 'runner_id'], + ); + + /// `DELETE /orgs/{org}/actions/runners/{runner_id}/labels/{name}` + /// Remove a custom label from a self-hosted runner for an organization + static const actionsRemoveCustomLabelFromSelfHostedRunnerForOrg = + RestOperationContract( + operationId: 'actions/remove-custom-label-from-self-hosted-runner-for-org', + method: 'DELETE', + path: '/orgs/{org}/actions/runners/{runner_id}/labels/{name}', + pathParams: ['name', 'org', 'runner_id'], + ); + + /// `DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}/labels/{name}` + /// Remove a custom label from a self-hosted runner for a repository + static const actionsRemoveCustomLabelFromSelfHostedRunnerForRepo = + RestOperationContract( + operationId: 'actions/remove-custom-label-from-self-hosted-runner-for-repo', + method: 'DELETE', + path: '/repos/{owner}/{repo}/actions/runners/{runner_id}/labels/{name}', + pathParams: ['name', 'owner', 'repo', 'runner_id'], + ); + + /// `DELETE /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories/{repository_id}` + /// Remove repository access to a self-hosted runner group in an organization + static const actionsRemoveRepoAccessToSelfHostedRunnerGroupInOrg = + RestOperationContract( + operationId: + 'actions/remove-repo-access-to-self-hosted-runner-group-in-org', + method: 'DELETE', + path: + '/orgs/{org}/actions/runner-groups/{runner_group_id}/repositories/{repository_id}', + pathParams: ['org', 'repository_id', 'runner_group_id'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}` + /// Remove selected repository from an organization secret + static const actionsRemoveSelectedRepoFromOrgSecret = RestOperationContract( + operationId: 'actions/remove-selected-repo-from-org-secret', + method: 'DELETE', + path: + '/orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}', + pathParams: ['org', 'repository_id', 'secret_name'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/actions/variables/{name}/repositories/{repository_id}` + /// Remove selected repository from an organization variable + static const actionsRemoveSelectedRepoFromOrgVariable = RestOperationContract( + operationId: 'actions/remove-selected-repo-from-org-variable', + method: 'DELETE', + path: '/orgs/{org}/actions/variables/{name}/repositories/{repository_id}', + pathParams: ['name', 'org', 'repository_id'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/actions/runner-groups/{runner_group_id}/runners/{runner_id}` + /// Remove a self-hosted runner from a group for an organization + static const actionsRemoveSelfHostedRunnerFromGroupForOrg = + RestOperationContract( + operationId: 'actions/remove-self-hosted-runner-from-group-for-org', + method: 'DELETE', + path: + '/orgs/{org}/actions/runner-groups/{runner_group_id}/runners/{runner_id}', + pathParams: ['org', 'runner_group_id', 'runner_id'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/actions/runs/{run_id}/deployment_protection_rule` + /// Review custom deployment protection rules for a workflow run + static const actionsReviewCustomGatesForRun = RestOperationContract( + operationId: 'actions/review-custom-gates-for-run', + method: 'POST', + path: + '/repos/{owner}/{repo}/actions/runs/{run_id}/deployment_protection_rule', + pathParams: ['owner', 'repo', 'run_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments` + /// Review pending deployments for a workflow run + static const actionsReviewPendingDeploymentsForRun = RestOperationContract( + operationId: 'actions/review-pending-deployments-for-run', + method: 'POST', + path: '/repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments', + pathParams: ['owner', 'repo', 'run_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /enterprises/{enterprise}/actions/cache/retention-limit` + /// Set GitHub Actions cache retention limit for an enterprise + static const actionsSetActionsCacheRetentionLimitForEnterprise = + RestOperationContract( + operationId: 'actions/set-actions-cache-retention-limit-for-enterprise', + method: 'PUT', + path: '/enterprises/{enterprise}/actions/cache/retention-limit', + pathParams: ['enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /organizations/{org}/actions/cache/retention-limit` + /// Set GitHub Actions cache retention limit for an organization + static const actionsSetActionsCacheRetentionLimitForOrganization = + RestOperationContract( + operationId: 'actions/set-actions-cache-retention-limit-for-organization', + method: 'PUT', + path: '/organizations/{org}/actions/cache/retention-limit', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/actions/cache/retention-limit` + /// Set GitHub Actions cache retention limit for a repository + static const actionsSetActionsCacheRetentionLimitForRepository = + RestOperationContract( + operationId: 'actions/set-actions-cache-retention-limit-for-repository', + method: 'PUT', + path: '/repos/{owner}/{repo}/actions/cache/retention-limit', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /enterprises/{enterprise}/actions/cache/storage-limit` + /// Set GitHub Actions cache storage limit for an enterprise + static const actionsSetActionsCacheStorageLimitForEnterprise = + RestOperationContract( + operationId: 'actions/set-actions-cache-storage-limit-for-enterprise', + method: 'PUT', + path: '/enterprises/{enterprise}/actions/cache/storage-limit', + pathParams: ['enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /organizations/{org}/actions/cache/storage-limit` + /// Set GitHub Actions cache storage limit for an organization + static const actionsSetActionsCacheStorageLimitForOrganization = + RestOperationContract( + operationId: 'actions/set-actions-cache-storage-limit-for-organization', + method: 'PUT', + path: '/organizations/{org}/actions/cache/storage-limit', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/actions/cache/storage-limit` + /// Set GitHub Actions cache storage limit for a repository + static const actionsSetActionsCacheStorageLimitForRepository = + RestOperationContract( + operationId: 'actions/set-actions-cache-storage-limit-for-repository', + method: 'PUT', + path: '/repos/{owner}/{repo}/actions/cache/storage-limit', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/permissions/selected-actions` + /// Set allowed actions and reusable workflows for an organization + static const actionsSetAllowedActionsOrganization = RestOperationContract( + operationId: 'actions/set-allowed-actions-organization', + method: 'PUT', + path: '/orgs/{org}/actions/permissions/selected-actions', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/actions/permissions/selected-actions` + /// Set allowed actions and reusable workflows for a repository + static const actionsSetAllowedActionsRepository = RestOperationContract( + operationId: 'actions/set-allowed-actions-repository', + method: 'PUT', + path: '/repos/{owner}/{repo}/actions/permissions/selected-actions', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/permissions/artifact-and-log-retention` + /// Set artifact and log retention settings for an organization + static const actionsSetArtifactAndLogRetentionSettingsOrganization = + RestOperationContract( + operationId: 'actions/set-artifact-and-log-retention-settings-organization', + method: 'PUT', + path: '/orgs/{org}/actions/permissions/artifact-and-log-retention', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/actions/permissions/artifact-and-log-retention` + /// Set artifact and log retention settings for a repository + static const actionsSetArtifactAndLogRetentionSettingsRepository = + RestOperationContract( + operationId: 'actions/set-artifact-and-log-retention-settings-repository', + method: 'PUT', + path: + '/repos/{owner}/{repo}/actions/permissions/artifact-and-log-retention', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/runners/{runner_id}/labels` + /// Set custom labels for a self-hosted runner for an organization + static const actionsSetCustomLabelsForSelfHostedRunnerForOrg = + RestOperationContract( + operationId: 'actions/set-custom-labels-for-self-hosted-runner-for-org', + method: 'PUT', + path: '/orgs/{org}/actions/runners/{runner_id}/labels', + pathParams: ['org', 'runner_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/actions/runners/{runner_id}/labels` + /// Set custom labels for a self-hosted runner for a repository + static const actionsSetCustomLabelsForSelfHostedRunnerForRepo = + RestOperationContract( + operationId: 'actions/set-custom-labels-for-self-hosted-runner-for-repo', + method: 'PUT', + path: '/repos/{owner}/{repo}/actions/runners/{runner_id}/labels', + pathParams: ['owner', 'repo', 'runner_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/actions/oidc/customization/sub` + /// Set the customization template for an OIDC subject claim for a repository + static const actionsSetCustomOidcSubClaimForRepo = RestOperationContract( + operationId: 'actions/set-custom-oidc-sub-claim-for-repo', + method: 'PUT', + path: '/repos/{owner}/{repo}/actions/oidc/customization/sub', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `PUT /orgs/{org}/actions/permissions/fork-pr-contributor-approval` + /// Set fork PR contributor approval permissions for an organization + static const actionsSetForkPrContributorApprovalPermissionsOrganization = + RestOperationContract( + operationId: + 'actions/set-fork-pr-contributor-approval-permissions-organization', + method: 'PUT', + path: '/orgs/{org}/actions/permissions/fork-pr-contributor-approval', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/actions/permissions/fork-pr-contributor-approval` + /// Set fork PR contributor approval permissions for a repository + static const actionsSetForkPrContributorApprovalPermissionsRepository = + RestOperationContract( + operationId: + 'actions/set-fork-pr-contributor-approval-permissions-repository', + method: 'PUT', + path: + '/repos/{owner}/{repo}/actions/permissions/fork-pr-contributor-approval', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/permissions/workflow` + /// Set default workflow permissions for an organization + static const actionsSetGithubActionsDefaultWorkflowPermissionsOrganization = + RestOperationContract( + operationId: + 'actions/set-github-actions-default-workflow-permissions-organization', + method: 'PUT', + path: '/orgs/{org}/actions/permissions/workflow', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/actions/permissions/workflow` + /// Set default workflow permissions for a repository + static const actionsSetGithubActionsDefaultWorkflowPermissionsRepository = + RestOperationContract( + operationId: + 'actions/set-github-actions-default-workflow-permissions-repository', + method: 'PUT', + path: '/repos/{owner}/{repo}/actions/permissions/workflow', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/permissions` + /// Set GitHub Actions permissions for an organization + static const actionsSetGithubActionsPermissionsOrganization = + RestOperationContract( + operationId: 'actions/set-github-actions-permissions-organization', + method: 'PUT', + path: '/orgs/{org}/actions/permissions', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/actions/permissions` + /// Set GitHub Actions permissions for a repository + static const actionsSetGithubActionsPermissionsRepository = + RestOperationContract( + operationId: 'actions/set-github-actions-permissions-repository', + method: 'PUT', + path: '/repos/{owner}/{repo}/actions/permissions', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/permissions/fork-pr-workflows-private-repos` + /// Set private repo fork PR workflow settings for an organization + static const actionsSetPrivateRepoForkPrWorkflowsSettingsOrganization = + RestOperationContract( + operationId: + 'actions/set-private-repo-fork-pr-workflows-settings-organization', + method: 'PUT', + path: '/orgs/{org}/actions/permissions/fork-pr-workflows-private-repos', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/actions/permissions/fork-pr-workflows-private-repos` + /// Set private repo fork PR workflow settings for a repository + static const actionsSetPrivateRepoForkPrWorkflowsSettingsRepository = + RestOperationContract( + operationId: + 'actions/set-private-repo-fork-pr-workflows-settings-repository', + method: 'PUT', + path: + '/repos/{owner}/{repo}/actions/permissions/fork-pr-workflows-private-repos', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories` + /// Set repository access for a self-hosted runner group in an organization + static const actionsSetRepoAccessToSelfHostedRunnerGroupInOrg = + RestOperationContract( + operationId: 'actions/set-repo-access-to-self-hosted-runner-group-in-org', + method: 'PUT', + path: '/orgs/{org}/actions/runner-groups/{runner_group_id}/repositories', + pathParams: ['org', 'runner_group_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/secrets/{secret_name}/repositories` + /// Set selected repositories for an organization secret + static const actionsSetSelectedReposForOrgSecret = RestOperationContract( + operationId: 'actions/set-selected-repos-for-org-secret', + method: 'PUT', + path: '/orgs/{org}/actions/secrets/{secret_name}/repositories', + pathParams: ['org', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/variables/{name}/repositories` + /// Set selected repositories for an organization variable + static const actionsSetSelectedReposForOrgVariable = RestOperationContract( + operationId: 'actions/set-selected-repos-for-org-variable', + method: 'PUT', + path: '/orgs/{org}/actions/variables/{name}/repositories', + pathParams: ['name', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/permissions/repositories` + /// Set selected repositories enabled for GitHub Actions in an organization + static const actionsSetSelectedRepositoriesEnabledGithubActionsOrganization = + RestOperationContract( + operationId: + 'actions/set-selected-repositories-enabled-github-actions-organization', + method: 'PUT', + path: '/orgs/{org}/actions/permissions/repositories', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/permissions/self-hosted-runners/repositories` + /// Set repositories allowed to use self-hosted runners in an organization + static const actionsSetSelectedRepositoriesSelfHostedRunnersOrganization = + RestOperationContract( + operationId: + 'actions/set-selected-repositories-self-hosted-runners-organization', + method: 'PUT', + path: '/orgs/{org}/actions/permissions/self-hosted-runners/repositories', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/runner-groups/{runner_group_id}/runners` + /// Set self-hosted runners in a group for an organization + static const actionsSetSelfHostedRunnersInGroupForOrg = RestOperationContract( + operationId: 'actions/set-self-hosted-runners-in-group-for-org', + method: 'PUT', + path: '/orgs/{org}/actions/runner-groups/{runner_group_id}/runners', + pathParams: ['org', 'runner_group_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/actions/permissions/self-hosted-runners` + /// Set self-hosted runners settings for an organization + static const actionsSetSelfHostedRunnersPermissionsOrganization = + RestOperationContract( + operationId: 'actions/set-self-hosted-runners-permissions-organization', + method: 'PUT', + path: '/orgs/{org}/actions/permissions/self-hosted-runners', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/actions/permissions/access` + /// Set the level of access for workflows outside of the repository + static const actionsSetWorkflowAccessToRepository = RestOperationContract( + operationId: 'actions/set-workflow-access-to-repository', + method: 'PUT', + path: '/repos/{owner}/{repo}/actions/permissions/access', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PATCH /repos/{owner}/{repo}/environments/{environment_name}/variables/{name}` + /// Update an environment variable + static const actionsUpdateEnvironmentVariable = RestOperationContract( + operationId: 'actions/update-environment-variable', + method: 'PATCH', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/variables/{name}', + pathParams: ['environment_name', 'name', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PATCH /orgs/{org}/actions/hosted-runners/{hosted_runner_id}` + /// Update a GitHub-hosted runner for an organization + static const actionsUpdateHostedRunnerForOrg = RestOperationContract( + operationId: 'actions/update-hosted-runner-for-org', + method: 'PATCH', + path: '/orgs/{org}/actions/hosted-runners/{hosted_runner_id}', + pathParams: ['hosted_runner_id', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /orgs/{org}/actions/variables/{name}` + /// Update an organization variable + static const actionsUpdateOrgVariable = RestOperationContract( + operationId: 'actions/update-org-variable', + method: 'PATCH', + path: '/orgs/{org}/actions/variables/{name}', + pathParams: ['name', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PATCH /repos/{owner}/{repo}/actions/variables/{name}` + /// Update a repository variable + static const actionsUpdateRepoVariable = RestOperationContract( + operationId: 'actions/update-repo-variable', + method: 'PATCH', + path: '/repos/{owner}/{repo}/actions/variables/{name}', + pathParams: ['name', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PATCH /orgs/{org}/actions/runner-groups/{runner_group_id}` + /// Update a self-hosted runner group for an organization + static const actionsUpdateSelfHostedRunnerGroupForOrg = RestOperationContract( + operationId: 'actions/update-self-hosted-runner-group-for-org', + method: 'PATCH', + path: '/orgs/{org}/actions/runner-groups/{runner_group_id}', + pathParams: ['org', 'runner_group_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /user/starred/{owner}/{repo}` + /// Check if a repository is starred by the authenticated user + static const activityCheckRepoIsStarredByAuthenticatedUser = + RestOperationContract( + operationId: 'activity/check-repo-is-starred-by-authenticated-user', + method: 'GET', + path: '/user/starred/{owner}/{repo}', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/subscription` + /// Delete a repository subscription + static const activityDeleteRepoSubscription = RestOperationContract( + operationId: 'activity/delete-repo-subscription', + method: 'DELETE', + path: '/repos/{owner}/{repo}/subscription', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /notifications/threads/{thread_id}/subscription` + /// Delete a thread subscription + static const activityDeleteThreadSubscription = RestOperationContract( + operationId: 'activity/delete-thread-subscription', + method: 'DELETE', + path: '/notifications/threads/{thread_id}/subscription', + pathParams: ['thread_id'], + successStatuses: [204], + ); + + /// `GET /feeds` + /// Get feeds + static const activityGetFeeds = RestOperationContract( + operationId: 'activity/get-feeds', + method: 'GET', + path: '/feeds', + ); + + /// `GET /repos/{owner}/{repo}/subscription` + /// Get a repository subscription + static const activityGetRepoSubscription = RestOperationContract( + operationId: 'activity/get-repo-subscription', + method: 'GET', + path: '/repos/{owner}/{repo}/subscription', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/stargazers/count` + /// Get stargazer count + static const activityGetStargazerCountForRepo = RestOperationContract( + operationId: 'activity/get-stargazer-count-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/stargazers/count', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/stargazers/history` + /// Get repository star history + static const activityGetStargazerHistoryForRepo = RestOperationContract( + operationId: 'activity/get-stargazer-history-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/stargazers/history', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /notifications/threads/{thread_id}` + /// Get a thread + static const activityGetThread = RestOperationContract( + operationId: 'activity/get-thread', + method: 'GET', + path: '/notifications/threads/{thread_id}', + pathParams: ['thread_id'], + ); + + /// `GET /notifications/threads/{thread_id}/subscription` + /// Get a thread subscription for the authenticated user + static const activityGetThreadSubscriptionForAuthenticatedUser = + RestOperationContract( + operationId: 'activity/get-thread-subscription-for-authenticated-user', + method: 'GET', + path: '/notifications/threads/{thread_id}/subscription', + pathParams: ['thread_id'], + ); + + /// `GET /users/{username}/events` + /// List events for the authenticated user + static const activityListEventsForAuthenticatedUser = RestOperationContract( + operationId: 'activity/list-events-for-authenticated-user', + method: 'GET', + path: '/users/{username}/events', + pathParams: ['username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /notifications` + /// List notifications for the authenticated user + static const activityListNotificationsForAuthenticatedUser = + RestOperationContract( + operationId: 'activity/list-notifications-for-authenticated-user', + method: 'GET', + path: '/notifications', + queryParams: [ + 'all', + 'before', + 'page', + 'participating', + 'per_page', + 'since' + ], + ); + + /// `GET /users/{username}/events/orgs/{org}` + /// List organization events for the authenticated user + static const activityListOrgEventsForAuthenticatedUser = + RestOperationContract( + operationId: 'activity/list-org-events-for-authenticated-user', + method: 'GET', + path: '/users/{username}/events/orgs/{org}', + pathParams: ['org', 'username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /events` + /// List public events + static const activityListPublicEvents = RestOperationContract( + operationId: 'activity/list-public-events', + method: 'GET', + path: '/events', + queryParams: ['page', 'per_page'], + ); + + /// `GET /networks/{owner}/{repo}/events` + /// List public events for a network of repositories + static const activityListPublicEventsForRepoNetwork = RestOperationContract( + operationId: 'activity/list-public-events-for-repo-network', + method: 'GET', + path: '/networks/{owner}/{repo}/events', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /users/{username}/events/public` + /// List public events for a user + static const activityListPublicEventsForUser = RestOperationContract( + operationId: 'activity/list-public-events-for-user', + method: 'GET', + path: '/users/{username}/events/public', + pathParams: ['username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/events` + /// List public organization events + static const activityListPublicOrgEvents = RestOperationContract( + operationId: 'activity/list-public-org-events', + method: 'GET', + path: '/orgs/{org}/events', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /users/{username}/received_events` + /// List events received by the authenticated user + static const activityListReceivedEventsForUser = RestOperationContract( + operationId: 'activity/list-received-events-for-user', + method: 'GET', + path: '/users/{username}/received_events', + pathParams: ['username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /users/{username}/received_events/public` + /// List public events received by a user + static const activityListReceivedPublicEventsForUser = RestOperationContract( + operationId: 'activity/list-received-public-events-for-user', + method: 'GET', + path: '/users/{username}/received_events/public', + pathParams: ['username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/events` + /// List repository events + static const activityListRepoEvents = RestOperationContract( + operationId: 'activity/list-repo-events', + method: 'GET', + path: '/repos/{owner}/{repo}/events', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/notifications` + /// List repository notifications for the authenticated user + static const activityListRepoNotificationsForAuthenticatedUser = + RestOperationContract( + operationId: 'activity/list-repo-notifications-for-authenticated-user', + method: 'GET', + path: '/repos/{owner}/{repo}/notifications', + pathParams: ['owner', 'repo'], + queryParams: [ + 'all', + 'before', + 'page', + 'participating', + 'per_page', + 'since' + ], + ); + + /// `GET /user/starred` + /// List repositories starred by the authenticated user + static const activityListReposStarredByAuthenticatedUser = + RestOperationContract( + operationId: 'activity/list-repos-starred-by-authenticated-user', + method: 'GET', + path: '/user/starred', + queryParams: ['direction', 'page', 'per_page', 'sort'], + ); + + /// `GET /users/{username}/starred` + /// List repositories starred by a user + static const activityListReposStarredByUser = RestOperationContract( + operationId: 'activity/list-repos-starred-by-user', + method: 'GET', + path: '/users/{username}/starred', + pathParams: ['username'], + queryParams: ['direction', 'page', 'per_page', 'sort'], + ); + + /// `GET /users/{username}/subscriptions` + /// List repositories watched by a user + static const activityListReposWatchedByUser = RestOperationContract( + operationId: 'activity/list-repos-watched-by-user', + method: 'GET', + path: '/users/{username}/subscriptions', + pathParams: ['username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/stargazers` + /// List stargazers + static const activityListStargazersForRepo = RestOperationContract( + operationId: 'activity/list-stargazers-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/stargazers', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/subscriptions` + /// List repositories watched by the authenticated user + static const activityListWatchedReposForAuthenticatedUser = + RestOperationContract( + operationId: 'activity/list-watched-repos-for-authenticated-user', + method: 'GET', + path: '/user/subscriptions', + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/subscribers` + /// List watchers + static const activityListWatchersForRepo = RestOperationContract( + operationId: 'activity/list-watchers-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/subscribers', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `PUT /notifications` + /// Mark notifications as read + static const activityMarkNotificationsAsRead = RestOperationContract( + operationId: 'activity/mark-notifications-as-read', + method: 'PUT', + path: '/notifications', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202, 205], + ); + + /// `PUT /repos/{owner}/{repo}/notifications` + /// Mark repository notifications as read + static const activityMarkRepoNotificationsAsRead = RestOperationContract( + operationId: 'activity/mark-repo-notifications-as-read', + method: 'PUT', + path: '/repos/{owner}/{repo}/notifications', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202, 205], + ); + + /// `DELETE /notifications/threads/{thread_id}` + /// Mark a thread as done + static const activityMarkThreadAsDone = RestOperationContract( + operationId: 'activity/mark-thread-as-done', + method: 'DELETE', + path: '/notifications/threads/{thread_id}', + pathParams: ['thread_id'], + successStatuses: [204], + ); + + /// `PATCH /notifications/threads/{thread_id}` + /// Mark a thread as read + static const activityMarkThreadAsRead = RestOperationContract( + operationId: 'activity/mark-thread-as-read', + method: 'PATCH', + path: '/notifications/threads/{thread_id}', + pathParams: ['thread_id'], + successStatuses: [205], + ); + + /// `PUT /repos/{owner}/{repo}/subscription` + /// Set a repository subscription + static const activitySetRepoSubscription = RestOperationContract( + operationId: 'activity/set-repo-subscription', + method: 'PUT', + path: '/repos/{owner}/{repo}/subscription', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /notifications/threads/{thread_id}/subscription` + /// Set a thread subscription + static const activitySetThreadSubscription = RestOperationContract( + operationId: 'activity/set-thread-subscription', + method: 'PUT', + path: '/notifications/threads/{thread_id}/subscription', + pathParams: ['thread_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /user/starred/{owner}/{repo}` + /// Star a repository for the authenticated user + static const activityStarRepoForAuthenticatedUser = RestOperationContract( + operationId: 'activity/star-repo-for-authenticated-user', + method: 'PUT', + path: '/user/starred/{owner}/{repo}', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /user/starred/{owner}/{repo}` + /// Unstar a repository for the authenticated user + static const activityUnstarRepoForAuthenticatedUser = RestOperationContract( + operationId: 'activity/unstar-repo-for-authenticated-user', + method: 'DELETE', + path: '/user/starred/{owner}/{repo}', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `POST /agents/repos/{owner}/{repo}/tasks` + /// Start a task + static const agentTasksCreateTaskInRepo = RestOperationContract( + operationId: 'agent-tasks/create-task-in-repo', + method: 'POST', + path: '/agents/repos/{owner}/{repo}/tasks', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `GET /agents/tasks/{task_id}` + /// Get a task by ID + static const agentTasksGetTaskById = RestOperationContract( + operationId: 'agent-tasks/get-task-by-id', + method: 'GET', + path: '/agents/tasks/{task_id}', + pathParams: ['task_id'], + ); + + /// `GET /agents/repos/{owner}/{repo}/tasks/{task_id}` + /// Get a task by repo + static const agentTasksGetTaskByRepoAndId = RestOperationContract( + operationId: 'agent-tasks/get-task-by-repo-and-id', + method: 'GET', + path: '/agents/repos/{owner}/{repo}/tasks/{task_id}', + pathParams: ['owner', 'repo', 'task_id'], + ); + + /// `GET /agents/tasks` + /// List tasks + static const agentTasksListTasks = RestOperationContract( + operationId: 'agent-tasks/list-tasks', + method: 'GET', + path: '/agents/tasks', + queryParams: [ + 'direction', + 'is_archived', + 'page', + 'per_page', + 'since', + 'sort', + 'state' + ], + ); + + /// `GET /agents/repos/{owner}/{repo}/tasks` + /// List tasks for repository + static const agentTasksListTasksForRepo = RestOperationContract( + operationId: 'agent-tasks/list-tasks-for-repo', + method: 'GET', + path: '/agents/repos/{owner}/{repo}/tasks', + pathParams: ['owner', 'repo'], + queryParams: [ + 'creator_id', + 'direction', + 'is_archived', + 'page', + 'per_page', + 'since', + 'sort', + 'state' + ], + ); + + /// `PUT /orgs/{org}/agents/secrets/{secret_name}/repositories/{repository_id}` + /// Add selected repository to an organization secret + static const agentsAddSelectedRepoToOrgSecret = RestOperationContract( + operationId: 'agents/add-selected-repo-to-org-secret', + method: 'PUT', + path: + '/orgs/{org}/agents/secrets/{secret_name}/repositories/{repository_id}', + pathParams: ['org', 'repository_id', 'secret_name'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/agents/variables/{name}/repositories/{repository_id}` + /// Add selected repository to an organization variable + static const agentsAddSelectedRepoToOrgVariable = RestOperationContract( + operationId: 'agents/add-selected-repo-to-org-variable', + method: 'PUT', + path: '/orgs/{org}/agents/variables/{name}/repositories/{repository_id}', + pathParams: ['name', 'org', 'repository_id'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/agents/secrets/{secret_name}` + /// Create or update an organization secret + static const agentsCreateOrUpdateOrgSecret = RestOperationContract( + operationId: 'agents/create-or-update-org-secret', + method: 'PUT', + path: '/orgs/{org}/agents/secrets/{secret_name}', + pathParams: ['org', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 204], + ); + + /// `PUT /repos/{owner}/{repo}/agents/secrets/{secret_name}` + /// Create or update a repository secret + static const agentsCreateOrUpdateRepoSecret = RestOperationContract( + operationId: 'agents/create-or-update-repo-secret', + method: 'PUT', + path: '/repos/{owner}/{repo}/agents/secrets/{secret_name}', + pathParams: ['owner', 'repo', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 204], + ); + + /// `POST /orgs/{org}/agents/variables` + /// Create an organization variable + static const agentsCreateOrgVariable = RestOperationContract( + operationId: 'agents/create-org-variable', + method: 'POST', + path: '/orgs/{org}/agents/variables', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/agents/variables` + /// Create a repository variable + static const agentsCreateRepoVariable = RestOperationContract( + operationId: 'agents/create-repo-variable', + method: 'POST', + path: '/repos/{owner}/{repo}/agents/variables', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /orgs/{org}/agents/secrets/{secret_name}` + /// Delete an organization secret + static const agentsDeleteOrgSecret = RestOperationContract( + operationId: 'agents/delete-org-secret', + method: 'DELETE', + path: '/orgs/{org}/agents/secrets/{secret_name}', + pathParams: ['org', 'secret_name'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/agents/variables/{name}` + /// Delete an organization variable + static const agentsDeleteOrgVariable = RestOperationContract( + operationId: 'agents/delete-org-variable', + method: 'DELETE', + path: '/orgs/{org}/agents/variables/{name}', + pathParams: ['name', 'org'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/agents/secrets/{secret_name}` + /// Delete a repository secret + static const agentsDeleteRepoSecret = RestOperationContract( + operationId: 'agents/delete-repo-secret', + method: 'DELETE', + path: '/repos/{owner}/{repo}/agents/secrets/{secret_name}', + pathParams: ['owner', 'repo', 'secret_name'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/agents/variables/{name}` + /// Delete a repository variable + static const agentsDeleteRepoVariable = RestOperationContract( + operationId: 'agents/delete-repo-variable', + method: 'DELETE', + path: '/repos/{owner}/{repo}/agents/variables/{name}', + pathParams: ['name', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/agents/secrets/public-key` + /// Get an organization public key + static const agentsGetOrgPublicKey = RestOperationContract( + operationId: 'agents/get-org-public-key', + method: 'GET', + path: '/orgs/{org}/agents/secrets/public-key', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/agents/secrets/{secret_name}` + /// Get an organization secret + static const agentsGetOrgSecret = RestOperationContract( + operationId: 'agents/get-org-secret', + method: 'GET', + path: '/orgs/{org}/agents/secrets/{secret_name}', + pathParams: ['org', 'secret_name'], + ); + + /// `GET /orgs/{org}/agents/variables/{name}` + /// Get an organization variable + static const agentsGetOrgVariable = RestOperationContract( + operationId: 'agents/get-org-variable', + method: 'GET', + path: '/orgs/{org}/agents/variables/{name}', + pathParams: ['name', 'org'], + ); + + /// `GET /repos/{owner}/{repo}/agents/secrets/public-key` + /// Get a repository public key + static const agentsGetRepoPublicKey = RestOperationContract( + operationId: 'agents/get-repo-public-key', + method: 'GET', + path: '/repos/{owner}/{repo}/agents/secrets/public-key', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/agents/secrets/{secret_name}` + /// Get a repository secret + static const agentsGetRepoSecret = RestOperationContract( + operationId: 'agents/get-repo-secret', + method: 'GET', + path: '/repos/{owner}/{repo}/agents/secrets/{secret_name}', + pathParams: ['owner', 'repo', 'secret_name'], + ); + + /// `GET /repos/{owner}/{repo}/agents/variables/{name}` + /// Get a repository variable + static const agentsGetRepoVariable = RestOperationContract( + operationId: 'agents/get-repo-variable', + method: 'GET', + path: '/repos/{owner}/{repo}/agents/variables/{name}', + pathParams: ['name', 'owner', 'repo'], + ); + + /// `GET /orgs/{org}/agents/secrets` + /// List organization secrets + static const agentsListOrgSecrets = RestOperationContract( + operationId: 'agents/list-org-secrets', + method: 'GET', + path: '/orgs/{org}/agents/secrets', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/agents/variables` + /// List organization variables + static const agentsListOrgVariables = RestOperationContract( + operationId: 'agents/list-org-variables', + method: 'GET', + path: '/orgs/{org}/agents/variables', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/agents/organization-secrets` + /// List repository organization secrets + static const agentsListRepoOrganizationSecrets = RestOperationContract( + operationId: 'agents/list-repo-organization-secrets', + method: 'GET', + path: '/repos/{owner}/{repo}/agents/organization-secrets', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/agents/organization-variables` + /// List repository organization variables + static const agentsListRepoOrganizationVariables = RestOperationContract( + operationId: 'agents/list-repo-organization-variables', + method: 'GET', + path: '/repos/{owner}/{repo}/agents/organization-variables', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/agents/secrets` + /// List repository secrets + static const agentsListRepoSecrets = RestOperationContract( + operationId: 'agents/list-repo-secrets', + method: 'GET', + path: '/repos/{owner}/{repo}/agents/secrets', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/agents/variables` + /// List repository variables + static const agentsListRepoVariables = RestOperationContract( + operationId: 'agents/list-repo-variables', + method: 'GET', + path: '/repos/{owner}/{repo}/agents/variables', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/agents/secrets/{secret_name}/repositories` + /// List selected repositories for an organization secret + static const agentsListSelectedReposForOrgSecret = RestOperationContract( + operationId: 'agents/list-selected-repos-for-org-secret', + method: 'GET', + path: '/orgs/{org}/agents/secrets/{secret_name}/repositories', + pathParams: ['org', 'secret_name'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/agents/variables/{name}/repositories` + /// List selected repositories for an organization variable + static const agentsListSelectedReposForOrgVariable = RestOperationContract( + operationId: 'agents/list-selected-repos-for-org-variable', + method: 'GET', + path: '/orgs/{org}/agents/variables/{name}/repositories', + pathParams: ['name', 'org'], + queryParams: ['page', 'per_page'], + ); + + /// `DELETE /orgs/{org}/agents/secrets/{secret_name}/repositories/{repository_id}` + /// Remove selected repository from an organization secret + static const agentsRemoveSelectedRepoFromOrgSecret = RestOperationContract( + operationId: 'agents/remove-selected-repo-from-org-secret', + method: 'DELETE', + path: + '/orgs/{org}/agents/secrets/{secret_name}/repositories/{repository_id}', + pathParams: ['org', 'repository_id', 'secret_name'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/agents/variables/{name}/repositories/{repository_id}` + /// Remove selected repository from an organization variable + static const agentsRemoveSelectedRepoFromOrgVariable = RestOperationContract( + operationId: 'agents/remove-selected-repo-from-org-variable', + method: 'DELETE', + path: '/orgs/{org}/agents/variables/{name}/repositories/{repository_id}', + pathParams: ['name', 'org', 'repository_id'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/agents/secrets/{secret_name}/repositories` + /// Set selected repositories for an organization secret + static const agentsSetSelectedReposForOrgSecret = RestOperationContract( + operationId: 'agents/set-selected-repos-for-org-secret', + method: 'PUT', + path: '/orgs/{org}/agents/secrets/{secret_name}/repositories', + pathParams: ['org', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/agents/variables/{name}/repositories` + /// Set selected repositories for an organization variable + static const agentsSetSelectedReposForOrgVariable = RestOperationContract( + operationId: 'agents/set-selected-repos-for-org-variable', + method: 'PUT', + path: '/orgs/{org}/agents/variables/{name}/repositories', + pathParams: ['name', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PATCH /orgs/{org}/agents/variables/{name}` + /// Update an organization variable + static const agentsUpdateOrgVariable = RestOperationContract( + operationId: 'agents/update-org-variable', + method: 'PATCH', + path: '/orgs/{org}/agents/variables/{name}', + pathParams: ['name', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PATCH /repos/{owner}/{repo}/agents/variables/{name}` + /// Update a repository variable + static const agentsUpdateRepoVariable = RestOperationContract( + operationId: 'agents/update-repo-variable', + method: 'PATCH', + path: '/repos/{owner}/{repo}/agents/variables/{name}', + pathParams: ['name', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/insights/api/route-stats/{actor_type}/{actor_id}` + /// Get route stats by actor + static const apiInsightsGetRouteStatsByActor = RestOperationContract( + operationId: 'api-insights/get-route-stats-by-actor', + method: 'GET', + path: '/orgs/{org}/insights/api/route-stats/{actor_type}/{actor_id}', + pathParams: ['actor_id', 'actor_type', 'org'], + queryParams: [ + 'api_route_substring', + 'direction', + 'max_timestamp', + 'min_timestamp', + 'page', + 'per_page', + 'sort' + ], + ); + + /// `GET /orgs/{org}/insights/api/subject-stats` + /// Get subject stats + static const apiInsightsGetSubjectStats = RestOperationContract( + operationId: 'api-insights/get-subject-stats', + method: 'GET', + path: '/orgs/{org}/insights/api/subject-stats', + pathParams: ['org'], + queryParams: [ + 'direction', + 'max_timestamp', + 'min_timestamp', + 'page', + 'per_page', + 'sort', + 'subject_name_substring' + ], + ); + + /// `GET /orgs/{org}/insights/api/summary-stats` + /// Get summary stats + static const apiInsightsGetSummaryStats = RestOperationContract( + operationId: 'api-insights/get-summary-stats', + method: 'GET', + path: '/orgs/{org}/insights/api/summary-stats', + pathParams: ['org'], + queryParams: ['max_timestamp', 'min_timestamp'], + ); + + /// `GET /orgs/{org}/insights/api/summary-stats/{actor_type}/{actor_id}` + /// Get summary stats by actor + static const apiInsightsGetSummaryStatsByActor = RestOperationContract( + operationId: 'api-insights/get-summary-stats-by-actor', + method: 'GET', + path: '/orgs/{org}/insights/api/summary-stats/{actor_type}/{actor_id}', + pathParams: ['actor_id', 'actor_type', 'org'], + queryParams: ['max_timestamp', 'min_timestamp'], + ); + + /// `GET /orgs/{org}/insights/api/summary-stats/users/{user_id}` + /// Get summary stats by user + static const apiInsightsGetSummaryStatsByUser = RestOperationContract( + operationId: 'api-insights/get-summary-stats-by-user', + method: 'GET', + path: '/orgs/{org}/insights/api/summary-stats/users/{user_id}', + pathParams: ['org', 'user_id'], + queryParams: ['max_timestamp', 'min_timestamp'], + ); + + /// `GET /orgs/{org}/insights/api/time-stats` + /// Get time stats + static const apiInsightsGetTimeStats = RestOperationContract( + operationId: 'api-insights/get-time-stats', + method: 'GET', + path: '/orgs/{org}/insights/api/time-stats', + pathParams: ['org'], + queryParams: ['max_timestamp', 'min_timestamp', 'timestamp_increment'], + ); + + /// `GET /orgs/{org}/insights/api/time-stats/{actor_type}/{actor_id}` + /// Get time stats by actor + static const apiInsightsGetTimeStatsByActor = RestOperationContract( + operationId: 'api-insights/get-time-stats-by-actor', + method: 'GET', + path: '/orgs/{org}/insights/api/time-stats/{actor_type}/{actor_id}', + pathParams: ['actor_id', 'actor_type', 'org'], + queryParams: ['max_timestamp', 'min_timestamp', 'timestamp_increment'], + ); + + /// `GET /orgs/{org}/insights/api/time-stats/users/{user_id}` + /// Get time stats by user + static const apiInsightsGetTimeStatsByUser = RestOperationContract( + operationId: 'api-insights/get-time-stats-by-user', + method: 'GET', + path: '/orgs/{org}/insights/api/time-stats/users/{user_id}', + pathParams: ['org', 'user_id'], + queryParams: ['max_timestamp', 'min_timestamp', 'timestamp_increment'], + ); + + /// `GET /orgs/{org}/insights/api/user-stats/{user_id}` + /// Get user stats + static const apiInsightsGetUserStats = RestOperationContract( + operationId: 'api-insights/get-user-stats', + method: 'GET', + path: '/orgs/{org}/insights/api/user-stats/{user_id}', + pathParams: ['org', 'user_id'], + queryParams: [ + 'actor_name_substring', + 'direction', + 'max_timestamp', + 'min_timestamp', + 'page', + 'per_page', + 'sort' + ], + ); + + /// `PUT /user/installations/{installation_id}/repositories/{repository_id}` + /// Add a repository to an app installation + static const appsAddRepoToInstallationForAuthenticatedUser = + RestOperationContract( + operationId: 'apps/add-repo-to-installation-for-authenticated-user', + method: 'PUT', + path: '/user/installations/{installation_id}/repositories/{repository_id}', + pathParams: ['installation_id', 'repository_id'], + successStatuses: [204], + ); + + /// `POST /applications/{client_id}/token` + /// Check a token + static const appsCheckToken = RestOperationContract( + operationId: 'apps/check-token', + method: 'POST', + path: '/applications/{client_id}/token', + pathParams: ['client_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /app-manifests/{code}/conversions` + /// Create a GitHub App from a manifest + static const appsCreateFromManifest = RestOperationContract( + operationId: 'apps/create-from-manifest', + method: 'POST', + path: '/app-manifests/{code}/conversions', + pathParams: ['code'], + successStatuses: [201], + ); + + /// `POST /app/installations/{installation_id}/access_tokens` + /// Create an installation access token for an app + static const appsCreateInstallationAccessToken = RestOperationContract( + operationId: 'apps/create-installation-access-token', + method: 'POST', + path: '/app/installations/{installation_id}/access_tokens', + pathParams: ['installation_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /applications/{client_id}/grant` + /// Delete an app authorization + static const appsDeleteAuthorization = RestOperationContract( + operationId: 'apps/delete-authorization', + method: 'DELETE', + path: '/applications/{client_id}/grant', + pathParams: ['client_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `DELETE /app/installations/{installation_id}` + /// Delete an installation for the authenticated app + static const appsDeleteInstallation = RestOperationContract( + operationId: 'apps/delete-installation', + method: 'DELETE', + path: '/app/installations/{installation_id}', + pathParams: ['installation_id'], + successStatuses: [204], + ); + + /// `DELETE /applications/{client_id}/token` + /// Delete an app token + static const appsDeleteToken = RestOperationContract( + operationId: 'apps/delete-token', + method: 'DELETE', + path: '/applications/{client_id}/token', + pathParams: ['client_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `GET /app` + /// Get the authenticated app + static const appsGetAuthenticated = RestOperationContract( + operationId: 'apps/get-authenticated', + method: 'GET', + path: '/app', + ); + + /// `GET /apps/{app_slug}` + /// Get an app + static const appsGetBySlug = RestOperationContract( + operationId: 'apps/get-by-slug', + method: 'GET', + path: '/apps/{app_slug}', + pathParams: ['app_slug'], + ); + + /// `GET /app/installations/{installation_id}` + /// Get an installation for the authenticated app + static const appsGetInstallation = RestOperationContract( + operationId: 'apps/get-installation', + method: 'GET', + path: '/app/installations/{installation_id}', + pathParams: ['installation_id'], + ); + + /// `GET /orgs/{org}/installation` + /// Get an organization installation for the authenticated app + static const appsGetOrgInstallation = RestOperationContract( + operationId: 'apps/get-org-installation', + method: 'GET', + path: '/orgs/{org}/installation', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/installation` + /// Get a repository installation for the authenticated app + static const appsGetRepoInstallation = RestOperationContract( + operationId: 'apps/get-repo-installation', + method: 'GET', + path: '/repos/{owner}/{repo}/installation', + pathParams: ['owner', 'repo'], + ); + + /// `GET /marketplace_listing/accounts/{account_id}` + /// Get a subscription plan for an account + static const appsGetSubscriptionPlanForAccount = RestOperationContract( + operationId: 'apps/get-subscription-plan-for-account', + method: 'GET', + path: '/marketplace_listing/accounts/{account_id}', + pathParams: ['account_id'], + ); + + /// `GET /marketplace_listing/stubbed/accounts/{account_id}` + /// Get a subscription plan for an account (stubbed) + static const appsGetSubscriptionPlanForAccountStubbed = RestOperationContract( + operationId: 'apps/get-subscription-plan-for-account-stubbed', + method: 'GET', + path: '/marketplace_listing/stubbed/accounts/{account_id}', + pathParams: ['account_id'], + ); + + /// `GET /users/{username}/installation` + /// Get a user installation for the authenticated app + static const appsGetUserInstallation = RestOperationContract( + operationId: 'apps/get-user-installation', + method: 'GET', + path: '/users/{username}/installation', + pathParams: ['username'], + ); + + /// `GET /app/hook/config` + /// Get a webhook configuration for an app + static const appsGetWebhookConfigForApp = RestOperationContract( + operationId: 'apps/get-webhook-config-for-app', + method: 'GET', + path: '/app/hook/config', + ); + + /// `GET /app/hook/deliveries/{delivery_id}` + /// Get a delivery for an app webhook + static const appsGetWebhookDelivery = RestOperationContract( + operationId: 'apps/get-webhook-delivery', + method: 'GET', + path: '/app/hook/deliveries/{delivery_id}', + pathParams: ['delivery_id'], + ); + + /// `GET /marketplace_listing/plans/{plan_id}/accounts` + /// List accounts for a plan + static const appsListAccountsForPlan = RestOperationContract( + operationId: 'apps/list-accounts-for-plan', + method: 'GET', + path: '/marketplace_listing/plans/{plan_id}/accounts', + pathParams: ['plan_id'], + queryParams: ['direction', 'page', 'per_page', 'sort'], + ); + + /// `GET /marketplace_listing/stubbed/plans/{plan_id}/accounts` + /// List accounts for a plan (stubbed) + static const appsListAccountsForPlanStubbed = RestOperationContract( + operationId: 'apps/list-accounts-for-plan-stubbed', + method: 'GET', + path: '/marketplace_listing/stubbed/plans/{plan_id}/accounts', + pathParams: ['plan_id'], + queryParams: ['direction', 'page', 'per_page', 'sort'], + ); + + /// `GET /user/installations/{installation_id}/repositories` + /// List repositories accessible to the user access token + static const appsListInstallationReposForAuthenticatedUser = + RestOperationContract( + operationId: 'apps/list-installation-repos-for-authenticated-user', + method: 'GET', + path: '/user/installations/{installation_id}/repositories', + pathParams: ['installation_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /app/installation-requests` + /// List installation requests for the authenticated app + static const appsListInstallationRequestsForAuthenticatedApp = + RestOperationContract( + operationId: 'apps/list-installation-requests-for-authenticated-app', + method: 'GET', + path: '/app/installation-requests', + queryParams: ['page', 'per_page'], + ); + + /// `GET /app/installations` + /// List installations for the authenticated app + static const appsListInstallations = RestOperationContract( + operationId: 'apps/list-installations', + method: 'GET', + path: '/app/installations', + queryParams: ['outdated', 'page', 'per_page', 'since'], + ); + + /// `GET /user/installations` + /// List app installations accessible to the user access token + static const appsListInstallationsForAuthenticatedUser = + RestOperationContract( + operationId: 'apps/list-installations-for-authenticated-user', + method: 'GET', + path: '/user/installations', + queryParams: ['page', 'per_page'], + ); + + /// `GET /marketplace_listing/plans` + /// List plans + static const appsListPlans = RestOperationContract( + operationId: 'apps/list-plans', + method: 'GET', + path: '/marketplace_listing/plans', + queryParams: ['page', 'per_page'], + ); + + /// `GET /marketplace_listing/stubbed/plans` + /// List plans (stubbed) + static const appsListPlansStubbed = RestOperationContract( + operationId: 'apps/list-plans-stubbed', + method: 'GET', + path: '/marketplace_listing/stubbed/plans', + queryParams: ['page', 'per_page'], + ); + + /// `GET /installation/repositories` + /// List repositories accessible to the app installation + static const appsListReposAccessibleToInstallation = RestOperationContract( + operationId: 'apps/list-repos-accessible-to-installation', + method: 'GET', + path: '/installation/repositories', + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/marketplace_purchases` + /// List subscriptions for the authenticated user + static const appsListSubscriptionsForAuthenticatedUser = + RestOperationContract( + operationId: 'apps/list-subscriptions-for-authenticated-user', + method: 'GET', + path: '/user/marketplace_purchases', + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/marketplace_purchases/stubbed` + /// List subscriptions for the authenticated user (stubbed) + static const appsListSubscriptionsForAuthenticatedUserStubbed = + RestOperationContract( + operationId: 'apps/list-subscriptions-for-authenticated-user-stubbed', + method: 'GET', + path: '/user/marketplace_purchases/stubbed', + queryParams: ['page', 'per_page'], + ); + + /// `GET /app/hook/deliveries` + /// List deliveries for an app webhook + static const appsListWebhookDeliveries = RestOperationContract( + operationId: 'apps/list-webhook-deliveries', + method: 'GET', + path: '/app/hook/deliveries', + queryParams: ['cursor', 'per_page', 'status'], + ); + + /// `POST /app/hook/deliveries/{delivery_id}/attempts` + /// Redeliver a delivery for an app webhook + static const appsRedeliverWebhookDelivery = RestOperationContract( + operationId: 'apps/redeliver-webhook-delivery', + method: 'POST', + path: '/app/hook/deliveries/{delivery_id}/attempts', + pathParams: ['delivery_id'], + successStatuses: [202], + ); + + /// `DELETE /user/installations/{installation_id}/repositories/{repository_id}` + /// Remove a repository from an app installation + static const appsRemoveRepoFromInstallationForAuthenticatedUser = + RestOperationContract( + operationId: 'apps/remove-repo-from-installation-for-authenticated-user', + method: 'DELETE', + path: '/user/installations/{installation_id}/repositories/{repository_id}', + pathParams: ['installation_id', 'repository_id'], + successStatuses: [204], + ); + + /// `PATCH /applications/{client_id}/token` + /// Reset a token + static const appsResetToken = RestOperationContract( + operationId: 'apps/reset-token', + method: 'PATCH', + path: '/applications/{client_id}/token', + pathParams: ['client_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /installation/token` + /// Revoke an installation access token + static const appsRevokeInstallationAccessToken = RestOperationContract( + operationId: 'apps/revoke-installation-access-token', + method: 'DELETE', + path: '/installation/token', + successStatuses: [204], + ); + + /// `POST /applications/{client_id}/token/scoped` + /// Create a scoped access token + static const appsScopeToken = RestOperationContract( + operationId: 'apps/scope-token', + method: 'POST', + path: '/applications/{client_id}/token/scoped', + pathParams: ['client_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /app/installations/{installation_id}/suspended` + /// Suspend an app installation + static const appsSuspendInstallation = RestOperationContract( + operationId: 'apps/suspend-installation', + method: 'PUT', + path: '/app/installations/{installation_id}/suspended', + pathParams: ['installation_id'], + successStatuses: [204], + ); + + /// `DELETE /app/installations/{installation_id}/suspended` + /// Unsuspend an app installation + static const appsUnsuspendInstallation = RestOperationContract( + operationId: 'apps/unsuspend-installation', + method: 'DELETE', + path: '/app/installations/{installation_id}/suspended', + pathParams: ['installation_id'], + successStatuses: [204], + ); + + /// `PATCH /app/hook/config` + /// Update a webhook configuration for an app + static const appsUpdateWebhookConfigForApp = RestOperationContract( + operationId: 'apps/update-webhook-config-for-app', + method: 'PATCH', + path: '/app/hook/config', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /organizations/{org}/settings/billing/budgets` + /// Create a budget for an organization + static const billingCreateOrganizationBudget = RestOperationContract( + operationId: 'billing/create-organization-budget', + method: 'POST', + path: '/organizations/{org}/settings/billing/budgets', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /organizations/{org}/settings/billing/budgets/{budget_id}` + /// Delete a budget for an organization + static const billingDeleteBudgetOrg = RestOperationContract( + operationId: 'billing/delete-budget-org', + method: 'DELETE', + path: '/organizations/{org}/settings/billing/budgets/{budget_id}', + pathParams: ['budget_id', 'org'], + ); + + /// `GET /organizations/{org}/settings/billing/budgets` + /// Get all budgets for an organization + static const billingGetAllBudgetsOrg = RestOperationContract( + operationId: 'billing/get-all-budgets-org', + method: 'GET', + path: '/organizations/{org}/settings/billing/budgets', + pathParams: ['org'], + queryParams: ['page', 'per_page', 'scope', 'user'], + ); + + /// `GET /organizations/{org}/settings/billing/budgets/{budget_id}` + /// Get a budget by ID for an organization + static const billingGetBudgetOrg = RestOperationContract( + operationId: 'billing/get-budget-org', + method: 'GET', + path: '/organizations/{org}/settings/billing/budgets/{budget_id}', + pathParams: ['budget_id', 'org'], + ); + + /// `GET /organizations/{org}/settings/billing/ai_credit/usage` + /// Get billing AI credit usage report for an organization + static const billingGetGithubBillingAiCreditUsageReportOrg = + RestOperationContract( + operationId: 'billing/get-github-billing-ai-credit-usage-report-org', + method: 'GET', + path: '/organizations/{org}/settings/billing/ai_credit/usage', + pathParams: ['org'], + queryParams: ['day', 'model', 'month', 'product', 'user', 'year'], + ); + + /// `GET /users/{username}/settings/billing/ai_credit/usage` + /// Get billing AI credit usage report for a user + static const billingGetGithubBillingAiCreditUsageReportUser = + RestOperationContract( + operationId: 'billing/get-github-billing-ai-credit-usage-report-user', + method: 'GET', + path: '/users/{username}/settings/billing/ai_credit/usage', + pathParams: ['username'], + queryParams: ['day', 'model', 'month', 'product', 'year'], + ); + + /// `GET /organizations/{org}/settings/billing/premium_request/usage` + /// Get billing premium request usage report for an organization + static const billingGetGithubBillingPremiumRequestUsageReportOrg = + RestOperationContract( + operationId: 'billing/get-github-billing-premium-request-usage-report-org', + method: 'GET', + path: '/organizations/{org}/settings/billing/premium_request/usage', + pathParams: ['org'], + queryParams: ['day', 'model', 'month', 'product', 'user', 'year'], + ); + + /// `GET /users/{username}/settings/billing/premium_request/usage` + /// Get billing premium request usage report for a user + static const billingGetGithubBillingPremiumRequestUsageReportUser = + RestOperationContract( + operationId: 'billing/get-github-billing-premium-request-usage-report-user', + method: 'GET', + path: '/users/{username}/settings/billing/premium_request/usage', + pathParams: ['username'], + queryParams: ['day', 'model', 'month', 'product', 'year'], + ); + + /// `GET /organizations/{org}/settings/billing/usage` + /// Get billing usage report for an organization + static const billingGetGithubBillingUsageReportOrg = RestOperationContract( + operationId: 'billing/get-github-billing-usage-report-org', + method: 'GET', + path: '/organizations/{org}/settings/billing/usage', + pathParams: ['org'], + queryParams: ['day', 'month', 'year'], + ); + + /// `GET /users/{username}/settings/billing/usage` + /// Get billing usage report for a user + static const billingGetGithubBillingUsageReportUser = RestOperationContract( + operationId: 'billing/get-github-billing-usage-report-user', + method: 'GET', + path: '/users/{username}/settings/billing/usage', + pathParams: ['username'], + queryParams: ['day', 'month', 'year'], + ); + + /// `GET /organizations/{org}/settings/billing/usage/summary` + /// Get billing usage summary for an organization + static const billingGetGithubBillingUsageSummaryReportOrg = + RestOperationContract( + operationId: 'billing/get-github-billing-usage-summary-report-org', + method: 'GET', + path: '/organizations/{org}/settings/billing/usage/summary', + pathParams: ['org'], + queryParams: ['day', 'month', 'product', 'repository', 'sku', 'year'], + ); + + /// `GET /users/{username}/settings/billing/usage/summary` + /// Get billing usage summary for a user + static const billingGetGithubBillingUsageSummaryReportUser = + RestOperationContract( + operationId: 'billing/get-github-billing-usage-summary-report-user', + method: 'GET', + path: '/users/{username}/settings/billing/usage/summary', + pathParams: ['username'], + queryParams: ['day', 'month', 'product', 'repository', 'sku', 'year'], + ); + + /// `PATCH /organizations/{org}/settings/billing/budgets/{budget_id}` + /// Update a budget for an organization + static const billingUpdateBudgetOrg = RestOperationContract( + operationId: 'billing/update-budget-org', + method: 'PATCH', + path: '/organizations/{org}/settings/billing/budgets/{budget_id}', + pathParams: ['budget_id', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /orgs/{org}/campaigns` + /// Create a campaign for an organization + static const campaignsCreateCampaign = RestOperationContract( + operationId: 'campaigns/create-campaign', + method: 'POST', + path: '/orgs/{org}/campaigns', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /orgs/{org}/campaigns/{campaign_number}` + /// Delete a campaign for an organization + static const campaignsDeleteCampaign = RestOperationContract( + operationId: 'campaigns/delete-campaign', + method: 'DELETE', + path: '/orgs/{org}/campaigns/{campaign_number}', + pathParams: ['campaign_number', 'org'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/campaigns/{campaign_number}` + /// Get a campaign for an organization + static const campaignsGetCampaignSummary = RestOperationContract( + operationId: 'campaigns/get-campaign-summary', + method: 'GET', + path: '/orgs/{org}/campaigns/{campaign_number}', + pathParams: ['campaign_number', 'org'], + ); + + /// `GET /orgs/{org}/campaigns` + /// List campaigns for an organization + static const campaignsListOrgCampaigns = RestOperationContract( + operationId: 'campaigns/list-org-campaigns', + method: 'GET', + path: '/orgs/{org}/campaigns', + pathParams: ['org'], + queryParams: ['direction', 'page', 'per_page', 'sort', 'state'], + ); + + /// `PATCH /orgs/{org}/campaigns/{campaign_number}` + /// Update a campaign + static const campaignsUpdateCampaign = RestOperationContract( + operationId: 'campaigns/update-campaign', + method: 'PATCH', + path: '/orgs/{org}/campaigns/{campaign_number}', + pathParams: ['campaign_number', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/check-runs` + /// Create a check run + static const checksCreate = RestOperationContract( + operationId: 'checks/create', + method: 'POST', + path: '/repos/{owner}/{repo}/check-runs', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/check-suites` + /// Create a check suite + static const checksCreateSuite = RestOperationContract( + operationId: 'checks/create-suite', + method: 'POST', + path: '/repos/{owner}/{repo}/check-suites', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 201], + ); + + /// `GET /repos/{owner}/{repo}/check-runs/{check_run_id}` + /// Get a check run + static const checksGet = RestOperationContract( + operationId: 'checks/get', + method: 'GET', + path: '/repos/{owner}/{repo}/check-runs/{check_run_id}', + pathParams: ['check_run_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/check-suites/{check_suite_id}` + /// Get a check suite + static const checksGetSuite = RestOperationContract( + operationId: 'checks/get-suite', + method: 'GET', + path: '/repos/{owner}/{repo}/check-suites/{check_suite_id}', + pathParams: ['check_suite_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations` + /// List check run annotations + static const checksListAnnotations = RestOperationContract( + operationId: 'checks/list-annotations', + method: 'GET', + path: '/repos/{owner}/{repo}/check-runs/{check_run_id}/annotations', + pathParams: ['check_run_id', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/commits/{ref}/check-runs` + /// List check runs for a Git reference + static const checksListForRef = RestOperationContract( + operationId: 'checks/list-for-ref', + method: 'GET', + path: '/repos/{owner}/{repo}/commits/{ref}/check-runs', + pathParams: ['owner', 'ref', 'repo'], + queryParams: [ + 'app_id', + 'check_name', + 'filter', + 'page', + 'per_page', + 'status' + ], + ); + + /// `GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs` + /// List check runs in a check suite + static const checksListForSuite = RestOperationContract( + operationId: 'checks/list-for-suite', + method: 'GET', + path: '/repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs', + pathParams: ['check_suite_id', 'owner', 'repo'], + queryParams: ['check_name', 'filter', 'page', 'per_page', 'status'], + ); + + /// `GET /repos/{owner}/{repo}/commits/{ref}/check-suites` + /// List check suites for a Git reference + static const checksListSuitesForRef = RestOperationContract( + operationId: 'checks/list-suites-for-ref', + method: 'GET', + path: '/repos/{owner}/{repo}/commits/{ref}/check-suites', + pathParams: ['owner', 'ref', 'repo'], + queryParams: ['app_id', 'check_name', 'page', 'per_page'], + ); + + /// `POST /repos/{owner}/{repo}/check-runs/{check_run_id}/rerequest` + /// Rerequest a check run + static const checksRerequestRun = RestOperationContract( + operationId: 'checks/rerequest-run', + method: 'POST', + path: '/repos/{owner}/{repo}/check-runs/{check_run_id}/rerequest', + pathParams: ['check_run_id', 'owner', 'repo'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/check-suites/{check_suite_id}/rerequest` + /// Rerequest a check suite + static const checksRerequestSuite = RestOperationContract( + operationId: 'checks/rerequest-suite', + method: 'POST', + path: '/repos/{owner}/{repo}/check-suites/{check_suite_id}/rerequest', + pathParams: ['check_suite_id', 'owner', 'repo'], + successStatuses: [201], + ); + + /// `PATCH /repos/{owner}/{repo}/check-suites/preferences` + /// Update repository preferences for check suites + static const checksSetSuitesPreferences = RestOperationContract( + operationId: 'checks/set-suites-preferences', + method: 'PATCH', + path: '/repos/{owner}/{repo}/check-suites/preferences', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}` + /// Update a check run + static const checksUpdate = RestOperationContract( + operationId: 'checks/update', + method: 'PATCH', + path: '/repos/{owner}/{repo}/check-runs/{check_run_id}', + pathParams: ['check_run_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /classrooms/{classroom_id}` + /// Closed - Get a classroom + static const classroomGetAClassroom = RestOperationContract( + operationId: 'classroom/get-a-classroom', + method: 'GET', + path: '/classrooms/{classroom_id}', + pathParams: ['classroom_id'], + ); + + /// `GET /assignments/{assignment_id}` + /// Closed - Get an assignment + static const classroomGetAnAssignment = RestOperationContract( + operationId: 'classroom/get-an-assignment', + method: 'GET', + path: '/assignments/{assignment_id}', + pathParams: ['assignment_id'], + ); + + /// `GET /assignments/{assignment_id}/grades` + /// Closed - Get assignment grades + static const classroomGetAssignmentGrades = RestOperationContract( + operationId: 'classroom/get-assignment-grades', + method: 'GET', + path: '/assignments/{assignment_id}/grades', + pathParams: ['assignment_id'], + ); + + /// `GET /assignments/{assignment_id}/accepted_assignments` + /// Closed - List accepted assignments for an assignment + static const classroomListAcceptedAssignmentsForAnAssignment = + RestOperationContract( + operationId: 'classroom/list-accepted-assignments-for-an-assignment', + method: 'GET', + path: '/assignments/{assignment_id}/accepted_assignments', + pathParams: ['assignment_id'], + ); + + /// `GET /classrooms/{classroom_id}/assignments` + /// Closed - List assignments for a classroom + static const classroomListAssignmentsForAClassroom = RestOperationContract( + operationId: 'classroom/list-assignments-for-a-classroom', + method: 'GET', + path: '/classrooms/{classroom_id}/assignments', + pathParams: ['classroom_id'], + ); + + /// `GET /classrooms` + /// Closed - List classrooms + static const classroomListClassrooms = RestOperationContract( + operationId: 'classroom/list-classrooms', + method: 'GET', + path: '/classrooms', + ); + + /// `GET /repos/{owner}/{repo}/code-quality/findings/{finding_number}` + /// Get a code quality finding + static const codeQualityGetFinding = RestOperationContract( + operationId: 'code-quality/get-finding', + method: 'GET', + path: '/repos/{owner}/{repo}/code-quality/findings/{finding_number}', + pathParams: ['finding_number', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/code-quality/setup` + /// Get a code quality setup configuration + static const codeQualityGetSetup = RestOperationContract( + operationId: 'code-quality/get-setup', + method: 'GET', + path: '/repos/{owner}/{repo}/code-quality/setup', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/code-quality/findings` + /// List code quality findings for a repository + static const codeQualityListFindingsForRepo = RestOperationContract( + operationId: 'code-quality/list-findings-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/code-quality/findings', + pathParams: ['owner', 'repo'], + queryParams: ['after', 'before', 'direction', 'per_page', 'state'], + ); + + /// `PATCH /repos/{owner}/{repo}/code-quality/setup` + /// Update a code quality setup configuration + static const codeQualityUpdateSetup = RestOperationContract( + operationId: 'code-quality/update-setup', + method: 'PATCH', + path: '/repos/{owner}/{repo}/code-quality/setup', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 202], + ); + + /// `POST /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/autofix/commits` + /// Commit an autofix for a code scanning alert + static const codeScanningCommitAutofix = RestOperationContract( + operationId: 'code-scanning/commit-autofix', + method: 'POST', + path: + '/repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/autofix/commits', + pathParams: ['alert_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/autofix` + /// Create an autofix for a code scanning alert + static const codeScanningCreateAutofix = RestOperationContract( + operationId: 'code-scanning/create-autofix', + method: 'POST', + path: '/repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/autofix', + pathParams: ['alert_number', 'owner', 'repo'], + successStatuses: [200, 202], + ); + + /// `POST /repos/{owner}/{repo}/code-scanning/codeql/variant-analyses` + /// Create a CodeQL variant analysis + static const codeScanningCreateVariantAnalysis = RestOperationContract( + operationId: 'code-scanning/create-variant-analysis', + method: 'POST', + path: '/repos/{owner}/{repo}/code-scanning/codeql/variant-analyses', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /repos/{owner}/{repo}/code-scanning/analyses/{analysis_id}` + /// Delete a code scanning analysis from a repository + static const codeScanningDeleteAnalysis = RestOperationContract( + operationId: 'code-scanning/delete-analysis', + method: 'DELETE', + path: '/repos/{owner}/{repo}/code-scanning/analyses/{analysis_id}', + pathParams: ['analysis_id', 'owner', 'repo'], + queryParams: ['confirm_delete'], + ); + + /// `DELETE /repos/{owner}/{repo}/code-scanning/codeql/databases/{language}` + /// Delete a CodeQL database + static const codeScanningDeleteCodeqlDatabase = RestOperationContract( + operationId: 'code-scanning/delete-codeql-database', + method: 'DELETE', + path: '/repos/{owner}/{repo}/code-scanning/codeql/databases/{language}', + pathParams: ['language', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/ai-scan` + /// Get AI Scan enablement for a repository + static const codeScanningGetAiScanEnablement = RestOperationContract( + operationId: 'code-scanning/get-ai-scan-enablement', + method: 'GET', + path: '/repos/{owner}/{repo}/code-scanning/ai-scan', + pathParams: ['owner', 'repo'], + ); + + /// `GET /orgs/{org}/code-scanning/ai-scan` + /// Get the AI Scan setting for an organization + static const codeScanningGetAiScanEnablementForOrg = RestOperationContract( + operationId: 'code-scanning/get-ai-scan-enablement-for-org', + method: 'GET', + path: '/orgs/{org}/code-scanning/ai-scan', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}` + /// Get a code scanning alert + static const codeScanningGetAlert = RestOperationContract( + operationId: 'code-scanning/get-alert', + method: 'GET', + path: '/repos/{owner}/{repo}/code-scanning/alerts/{alert_number}', + pathParams: ['alert_number', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/analyses/{analysis_id}` + /// Get a code scanning analysis for a repository + static const codeScanningGetAnalysis = RestOperationContract( + operationId: 'code-scanning/get-analysis', + method: 'GET', + path: '/repos/{owner}/{repo}/code-scanning/analyses/{analysis_id}', + pathParams: ['analysis_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/autofix` + /// Get the status of an autofix for a code scanning alert + static const codeScanningGetAutofix = RestOperationContract( + operationId: 'code-scanning/get-autofix', + method: 'GET', + path: '/repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/autofix', + pathParams: ['alert_number', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/codeql/databases/{language}` + /// Get a CodeQL database for a repository + static const codeScanningGetCodeqlDatabase = RestOperationContract( + operationId: 'code-scanning/get-codeql-database', + method: 'GET', + path: '/repos/{owner}/{repo}/code-scanning/codeql/databases/{language}', + pathParams: ['language', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/default-setup` + /// Get a code scanning default setup configuration + static const codeScanningGetDefaultSetup = RestOperationContract( + operationId: 'code-scanning/get-default-setup', + method: 'GET', + path: '/repos/{owner}/{repo}/code-scanning/default-setup', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/sarifs/{sarif_id}` + /// Get information about a SARIF upload + static const codeScanningGetSarif = RestOperationContract( + operationId: 'code-scanning/get-sarif', + method: 'GET', + path: '/repos/{owner}/{repo}/code-scanning/sarifs/{sarif_id}', + pathParams: ['owner', 'repo', 'sarif_id'], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/codeql/variant-analyses/{codeql_variant_analysis_id}` + /// Get the summary of a CodeQL variant analysis + static const codeScanningGetVariantAnalysis = RestOperationContract( + operationId: 'code-scanning/get-variant-analysis', + method: 'GET', + path: + '/repos/{owner}/{repo}/code-scanning/codeql/variant-analyses/{codeql_variant_analysis_id}', + pathParams: ['codeql_variant_analysis_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/codeql/variant-analyses/{codeql_variant_analysis_id}/repos/{repo_owner}/{repo_name}` + /// Get the analysis status of a repository in a CodeQL variant analysis + static const codeScanningGetVariantAnalysisRepoTask = RestOperationContract( + operationId: 'code-scanning/get-variant-analysis-repo-task', + method: 'GET', + path: + '/repos/{owner}/{repo}/code-scanning/codeql/variant-analyses/{codeql_variant_analysis_id}/repos/{repo_owner}/{repo_name}', + pathParams: [ + 'codeql_variant_analysis_id', + 'owner', + 'repo', + 'repo_name', + 'repo_owner' + ], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances` + /// List instances of a code scanning alert + static const codeScanningListAlertInstances = RestOperationContract( + operationId: 'code-scanning/list-alert-instances', + method: 'GET', + path: '/repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances', + pathParams: ['alert_number', 'owner', 'repo'], + queryParams: ['page', 'per_page', 'pr', 'ref'], + ); + + /// `GET /orgs/{org}/code-scanning/alerts` + /// List code scanning alerts for an organization + static const codeScanningListAlertsForOrg = RestOperationContract( + operationId: 'code-scanning/list-alerts-for-org', + method: 'GET', + path: '/orgs/{org}/code-scanning/alerts', + pathParams: ['org'], + queryParams: [ + 'after', + 'assignees', + 'before', + 'direction', + 'page', + 'per_page', + 'severity', + 'sort', + 'state', + 'tool_guid', + 'tool_name' + ], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/alerts` + /// List code scanning alerts for a repository + static const codeScanningListAlertsForRepo = RestOperationContract( + operationId: 'code-scanning/list-alerts-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/code-scanning/alerts', + pathParams: ['owner', 'repo'], + queryParams: [ + 'after', + 'assignees', + 'before', + 'direction', + 'page', + 'per_page', + 'pr', + 'ref', + 'severity', + 'sort', + 'state', + 'tool_guid', + 'tool_name' + ], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/codeql/databases` + /// List CodeQL databases for a repository + static const codeScanningListCodeqlDatabases = RestOperationContract( + operationId: 'code-scanning/list-codeql-databases', + method: 'GET', + path: '/repos/{owner}/{repo}/code-scanning/codeql/databases', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/code-scanning/analyses` + /// List code scanning analyses for a repository + static const codeScanningListRecentAnalyses = RestOperationContract( + operationId: 'code-scanning/list-recent-analyses', + method: 'GET', + path: '/repos/{owner}/{repo}/code-scanning/analyses', + pathParams: ['owner', 'repo'], + queryParams: [ + 'direction', + 'page', + 'per_page', + 'pr', + 'ref', + 'sarif_id', + 'sort', + 'tool_guid', + 'tool_name' + ], + ); + + /// `PATCH /repos/{owner}/{repo}/code-scanning/ai-scan` + /// Update AI Scan enablement for a repository + static const codeScanningUpdateAiScanEnablement = RestOperationContract( + operationId: 'code-scanning/update-ai-scan-enablement', + method: 'PATCH', + path: '/repos/{owner}/{repo}/code-scanning/ai-scan', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /orgs/{org}/code-scanning/ai-scan` + /// Update the AI Scan setting for an organization + static const codeScanningUpdateAiScanEnablementForOrg = RestOperationContract( + operationId: 'code-scanning/update-ai-scan-enablement-for-org', + method: 'PATCH', + path: '/orgs/{org}/code-scanning/ai-scan', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}` + /// Update a code scanning alert + static const codeScanningUpdateAlert = RestOperationContract( + operationId: 'code-scanning/update-alert', + method: 'PATCH', + path: '/repos/{owner}/{repo}/code-scanning/alerts/{alert_number}', + pathParams: ['alert_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/code-scanning/default-setup` + /// Update a code scanning default setup configuration + static const codeScanningUpdateDefaultSetup = RestOperationContract( + operationId: 'code-scanning/update-default-setup', + method: 'PATCH', + path: '/repos/{owner}/{repo}/code-scanning/default-setup', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 202], + ); + + /// `POST /repos/{owner}/{repo}/code-scanning/sarifs` + /// Upload an analysis as SARIF data + static const codeScanningUploadSarif = RestOperationContract( + operationId: 'code-scanning/upload-sarif', + method: 'POST', + path: '/repos/{owner}/{repo}/code-scanning/sarifs', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202], + ); + + /// `POST /orgs/{org}/code-security/configurations/{configuration_id}/attach` + /// Attach a configuration to repositories + static const codeSecurityAttachConfiguration = RestOperationContract( + operationId: 'code-security/attach-configuration', + method: 'POST', + path: '/orgs/{org}/code-security/configurations/{configuration_id}/attach', + pathParams: ['configuration_id', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202], + ); + + /// `POST /enterprises/{enterprise}/code-security/configurations/{configuration_id}/attach` + /// Attach an enterprise configuration to repositories + static const codeSecurityAttachEnterpriseConfiguration = + RestOperationContract( + operationId: 'code-security/attach-enterprise-configuration', + method: 'POST', + path: + '/enterprises/{enterprise}/code-security/configurations/{configuration_id}/attach', + pathParams: ['configuration_id', 'enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202], + ); + + /// `POST /orgs/{org}/code-security/configurations` + /// Create a code security configuration + static const codeSecurityCreateConfiguration = RestOperationContract( + operationId: 'code-security/create-configuration', + method: 'POST', + path: '/orgs/{org}/code-security/configurations', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /enterprises/{enterprise}/code-security/configurations` + /// Create a code security configuration for an enterprise + static const codeSecurityCreateConfigurationForEnterprise = + RestOperationContract( + operationId: 'code-security/create-configuration-for-enterprise', + method: 'POST', + path: '/enterprises/{enterprise}/code-security/configurations', + pathParams: ['enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /orgs/{org}/code-security/configurations/{configuration_id}` + /// Delete a code security configuration + static const codeSecurityDeleteConfiguration = RestOperationContract( + operationId: 'code-security/delete-configuration', + method: 'DELETE', + path: '/orgs/{org}/code-security/configurations/{configuration_id}', + pathParams: ['configuration_id', 'org'], + successStatuses: [204], + ); + + /// `DELETE /enterprises/{enterprise}/code-security/configurations/{configuration_id}` + /// Delete a code security configuration for an enterprise + static const codeSecurityDeleteConfigurationForEnterprise = + RestOperationContract( + operationId: 'code-security/delete-configuration-for-enterprise', + method: 'DELETE', + path: + '/enterprises/{enterprise}/code-security/configurations/{configuration_id}', + pathParams: ['configuration_id', 'enterprise'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/code-security/configurations/detach` + /// Detach configurations from repositories + static const codeSecurityDetachConfiguration = RestOperationContract( + operationId: 'code-security/detach-configuration', + method: 'DELETE', + path: '/orgs/{org}/code-security/configurations/detach', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/code-security/configurations/{configuration_id}` + /// Get a code security configuration + static const codeSecurityGetConfiguration = RestOperationContract( + operationId: 'code-security/get-configuration', + method: 'GET', + path: '/orgs/{org}/code-security/configurations/{configuration_id}', + pathParams: ['configuration_id', 'org'], + ); + + /// `GET /repos/{owner}/{repo}/code-security-configuration` + /// Get the code security configuration associated with a repository + static const codeSecurityGetConfigurationForRepository = + RestOperationContract( + operationId: 'code-security/get-configuration-for-repository', + method: 'GET', + path: '/repos/{owner}/{repo}/code-security-configuration', + pathParams: ['owner', 'repo'], + successStatuses: [200, 204], + ); + + /// `GET /enterprises/{enterprise}/code-security/configurations` + /// Get code security configurations for an enterprise + static const codeSecurityGetConfigurationsForEnterprise = + RestOperationContract( + operationId: 'code-security/get-configurations-for-enterprise', + method: 'GET', + path: '/enterprises/{enterprise}/code-security/configurations', + pathParams: ['enterprise'], + queryParams: ['after', 'before', 'per_page'], + ); + + /// `GET /orgs/{org}/code-security/configurations` + /// Get code security configurations for an organization + static const codeSecurityGetConfigurationsForOrg = RestOperationContract( + operationId: 'code-security/get-configurations-for-org', + method: 'GET', + path: '/orgs/{org}/code-security/configurations', + pathParams: ['org'], + queryParams: ['after', 'before', 'per_page', 'target_type'], + ); + + /// `GET /orgs/{org}/code-security/configurations/defaults` + /// Get default code security configurations + static const codeSecurityGetDefaultConfigurations = RestOperationContract( + operationId: 'code-security/get-default-configurations', + method: 'GET', + path: '/orgs/{org}/code-security/configurations/defaults', + pathParams: ['org'], + ); + + /// `GET /enterprises/{enterprise}/code-security/configurations/defaults` + /// Get default code security configurations for an enterprise + static const codeSecurityGetDefaultConfigurationsForEnterprise = + RestOperationContract( + operationId: 'code-security/get-default-configurations-for-enterprise', + method: 'GET', + path: '/enterprises/{enterprise}/code-security/configurations/defaults', + pathParams: ['enterprise'], + ); + + /// `GET /orgs/{org}/code-security/configurations/{configuration_id}/repositories` + /// Get repositories associated with a code security configuration + static const codeSecurityGetRepositoriesForConfiguration = + RestOperationContract( + operationId: 'code-security/get-repositories-for-configuration', + method: 'GET', + path: + '/orgs/{org}/code-security/configurations/{configuration_id}/repositories', + pathParams: ['configuration_id', 'org'], + queryParams: ['after', 'before', 'per_page', 'status'], + ); + + /// `GET /enterprises/{enterprise}/code-security/configurations/{configuration_id}/repositories` + /// Get repositories associated with an enterprise code security configuration + static const codeSecurityGetRepositoriesForEnterpriseConfiguration = + RestOperationContract( + operationId: 'code-security/get-repositories-for-enterprise-configuration', + method: 'GET', + path: + '/enterprises/{enterprise}/code-security/configurations/{configuration_id}/repositories', + pathParams: ['configuration_id', 'enterprise'], + queryParams: ['after', 'before', 'per_page', 'status'], + ); + + /// `GET /enterprises/{enterprise}/code-security/configurations/{configuration_id}` + /// Retrieve a code security configuration of an enterprise + static const codeSecurityGetSingleConfigurationForEnterprise = + RestOperationContract( + operationId: 'code-security/get-single-configuration-for-enterprise', + method: 'GET', + path: + '/enterprises/{enterprise}/code-security/configurations/{configuration_id}', + pathParams: ['configuration_id', 'enterprise'], + ); + + /// `PUT /orgs/{org}/code-security/configurations/{configuration_id}/defaults` + /// Set a code security configuration as a default for an organization + static const codeSecuritySetConfigurationAsDefault = RestOperationContract( + operationId: 'code-security/set-configuration-as-default', + method: 'PUT', + path: + '/orgs/{org}/code-security/configurations/{configuration_id}/defaults', + pathParams: ['configuration_id', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /enterprises/{enterprise}/code-security/configurations/{configuration_id}/defaults` + /// Set a code security configuration as a default for an enterprise + static const codeSecuritySetConfigurationAsDefaultForEnterprise = + RestOperationContract( + operationId: 'code-security/set-configuration-as-default-for-enterprise', + method: 'PUT', + path: + '/enterprises/{enterprise}/code-security/configurations/{configuration_id}/defaults', + pathParams: ['configuration_id', 'enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /orgs/{org}/code-security/configurations/{configuration_id}` + /// Update a code security configuration + static const codeSecurityUpdateConfiguration = RestOperationContract( + operationId: 'code-security/update-configuration', + method: 'PATCH', + path: '/orgs/{org}/code-security/configurations/{configuration_id}', + pathParams: ['configuration_id', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 204], + ); + + /// `PATCH /enterprises/{enterprise}/code-security/configurations/{configuration_id}` + /// Update a custom code security configuration for an enterprise + static const codeSecurityUpdateEnterpriseConfiguration = + RestOperationContract( + operationId: 'code-security/update-enterprise-configuration', + method: 'PATCH', + path: + '/enterprises/{enterprise}/code-security/configurations/{configuration_id}', + pathParams: ['configuration_id', 'enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /codes_of_conduct` + /// Get all codes of conduct + static const codesOfConductGetAllCodesOfConduct = RestOperationContract( + operationId: 'codes-of-conduct/get-all-codes-of-conduct', + method: 'GET', + path: '/codes_of_conduct', + ); + + /// `GET /codes_of_conduct/{key}` + /// Get a code of conduct + static const codesOfConductGetConductCode = RestOperationContract( + operationId: 'codes-of-conduct/get-conduct-code', + method: 'GET', + path: '/codes_of_conduct/{key}', + pathParams: ['key'], + ); + + /// `PUT /user/codespaces/secrets/{secret_name}/repositories/{repository_id}` + /// Add a selected repository to a user secret + static const codespacesAddRepositoryForSecretForAuthenticatedUser = + RestOperationContract( + operationId: 'codespaces/add-repository-for-secret-for-authenticated-user', + method: 'PUT', + path: '/user/codespaces/secrets/{secret_name}/repositories/{repository_id}', + pathParams: ['repository_id', 'secret_name'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/codespaces/secrets/{secret_name}/repositories/{repository_id}` + /// Add selected repository to an organization secret + static const codespacesAddSelectedRepoToOrgSecret = RestOperationContract( + operationId: 'codespaces/add-selected-repo-to-org-secret', + method: 'PUT', + path: + '/orgs/{org}/codespaces/secrets/{secret_name}/repositories/{repository_id}', + pathParams: ['org', 'repository_id', 'secret_name'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/codespaces/permissions_check` + /// Check if permissions defined by a devcontainer have been accepted by the authenticated user + static const codespacesCheckPermissionsForDevcontainer = + RestOperationContract( + operationId: 'codespaces/check-permissions-for-devcontainer', + method: 'GET', + path: '/repos/{owner}/{repo}/codespaces/permissions_check', + pathParams: ['owner', 'repo'], + queryParams: ['devcontainer_path', 'ref'], + ); + + /// `GET /user/codespaces/{codespace_name}/machines` + /// List machine types for a codespace + static const codespacesCodespaceMachinesForAuthenticatedUser = + RestOperationContract( + operationId: 'codespaces/codespace-machines-for-authenticated-user', + method: 'GET', + path: '/user/codespaces/{codespace_name}/machines', + pathParams: ['codespace_name'], + ); + + /// `POST /user/codespaces` + /// Create a codespace for the authenticated user + static const codespacesCreateForAuthenticatedUser = RestOperationContract( + operationId: 'codespaces/create-for-authenticated-user', + method: 'POST', + path: '/user/codespaces', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 202], + ); + + /// `PUT /orgs/{org}/codespaces/secrets/{secret_name}` + /// Create or update an organization secret + static const codespacesCreateOrUpdateOrgSecret = RestOperationContract( + operationId: 'codespaces/create-or-update-org-secret', + method: 'PUT', + path: '/orgs/{org}/codespaces/secrets/{secret_name}', + pathParams: ['org', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 204], + ); + + /// `PUT /repos/{owner}/{repo}/codespaces/secrets/{secret_name}` + /// Create or update a repository secret + static const codespacesCreateOrUpdateRepoSecret = RestOperationContract( + operationId: 'codespaces/create-or-update-repo-secret', + method: 'PUT', + path: '/repos/{owner}/{repo}/codespaces/secrets/{secret_name}', + pathParams: ['owner', 'repo', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 204], + ); + + /// `PUT /user/codespaces/secrets/{secret_name}` + /// Create or update a secret for the authenticated user + static const codespacesCreateOrUpdateSecretForAuthenticatedUser = + RestOperationContract( + operationId: 'codespaces/create-or-update-secret-for-authenticated-user', + method: 'PUT', + path: '/user/codespaces/secrets/{secret_name}', + pathParams: ['secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 204], + ); + + /// `POST /repos/{owner}/{repo}/pulls/{pull_number}/codespaces` + /// Create a codespace from a pull request + static const codespacesCreateWithPrForAuthenticatedUser = + RestOperationContract( + operationId: 'codespaces/create-with-pr-for-authenticated-user', + method: 'POST', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/codespaces', + pathParams: ['owner', 'pull_number', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 202], + ); + + /// `POST /repos/{owner}/{repo}/codespaces` + /// Create a codespace in a repository + static const codespacesCreateWithRepoForAuthenticatedUser = + RestOperationContract( + operationId: 'codespaces/create-with-repo-for-authenticated-user', + method: 'POST', + path: '/repos/{owner}/{repo}/codespaces', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 202], + ); + + /// `DELETE /orgs/{org}/codespaces/access/selected_users` + /// Remove users from Codespaces access for an organization + static const codespacesDeleteCodespacesAccessUsers = RestOperationContract( + operationId: 'codespaces/delete-codespaces-access-users', + method: 'DELETE', + path: '/orgs/{org}/codespaces/access/selected_users', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `DELETE /user/codespaces/{codespace_name}` + /// Delete a codespace for the authenticated user + static const codespacesDeleteForAuthenticatedUser = RestOperationContract( + operationId: 'codespaces/delete-for-authenticated-user', + method: 'DELETE', + path: '/user/codespaces/{codespace_name}', + pathParams: ['codespace_name'], + successStatuses: [202], + ); + + /// `DELETE /orgs/{org}/members/{username}/codespaces/{codespace_name}` + /// Delete a codespace from the organization + static const codespacesDeleteFromOrganization = RestOperationContract( + operationId: 'codespaces/delete-from-organization', + method: 'DELETE', + path: '/orgs/{org}/members/{username}/codespaces/{codespace_name}', + pathParams: ['codespace_name', 'org', 'username'], + successStatuses: [202], + ); + + /// `DELETE /orgs/{org}/codespaces/secrets/{secret_name}` + /// Delete an organization secret + static const codespacesDeleteOrgSecret = RestOperationContract( + operationId: 'codespaces/delete-org-secret', + method: 'DELETE', + path: '/orgs/{org}/codespaces/secrets/{secret_name}', + pathParams: ['org', 'secret_name'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/codespaces/secrets/{secret_name}` + /// Delete a repository secret + static const codespacesDeleteRepoSecret = RestOperationContract( + operationId: 'codespaces/delete-repo-secret', + method: 'DELETE', + path: '/repos/{owner}/{repo}/codespaces/secrets/{secret_name}', + pathParams: ['owner', 'repo', 'secret_name'], + successStatuses: [204], + ); + + /// `DELETE /user/codespaces/secrets/{secret_name}` + /// Delete a secret for the authenticated user + static const codespacesDeleteSecretForAuthenticatedUser = + RestOperationContract( + operationId: 'codespaces/delete-secret-for-authenticated-user', + method: 'DELETE', + path: '/user/codespaces/secrets/{secret_name}', + pathParams: ['secret_name'], + successStatuses: [204], + ); + + /// `POST /user/codespaces/{codespace_name}/exports` + /// Export a codespace for the authenticated user + static const codespacesExportForAuthenticatedUser = RestOperationContract( + operationId: 'codespaces/export-for-authenticated-user', + method: 'POST', + path: '/user/codespaces/{codespace_name}/exports', + pathParams: ['codespace_name'], + successStatuses: [202], + ); + + /// `GET /orgs/{org}/members/{username}/codespaces` + /// List codespaces for a user in organization + static const codespacesGetCodespacesForUserInOrg = RestOperationContract( + operationId: 'codespaces/get-codespaces-for-user-in-org', + method: 'GET', + path: '/orgs/{org}/members/{username}/codespaces', + pathParams: ['org', 'username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/codespaces/{codespace_name}/exports/{export_id}` + /// Get details about a codespace export + static const codespacesGetExportDetailsForAuthenticatedUser = + RestOperationContract( + operationId: 'codespaces/get-export-details-for-authenticated-user', + method: 'GET', + path: '/user/codespaces/{codespace_name}/exports/{export_id}', + pathParams: ['codespace_name', 'export_id'], + ); + + /// `GET /user/codespaces/{codespace_name}` + /// Get a codespace for the authenticated user + static const codespacesGetForAuthenticatedUser = RestOperationContract( + operationId: 'codespaces/get-for-authenticated-user', + method: 'GET', + path: '/user/codespaces/{codespace_name}', + pathParams: ['codespace_name'], + ); + + /// `GET /orgs/{org}/codespaces/secrets/public-key` + /// Get an organization public key + static const codespacesGetOrgPublicKey = RestOperationContract( + operationId: 'codespaces/get-org-public-key', + method: 'GET', + path: '/orgs/{org}/codespaces/secrets/public-key', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/codespaces/secrets/{secret_name}` + /// Get an organization secret + static const codespacesGetOrgSecret = RestOperationContract( + operationId: 'codespaces/get-org-secret', + method: 'GET', + path: '/orgs/{org}/codespaces/secrets/{secret_name}', + pathParams: ['org', 'secret_name'], + ); + + /// `GET /user/codespaces/secrets/public-key` + /// Get public key for the authenticated user + static const codespacesGetPublicKeyForAuthenticatedUser = + RestOperationContract( + operationId: 'codespaces/get-public-key-for-authenticated-user', + method: 'GET', + path: '/user/codespaces/secrets/public-key', + ); + + /// `GET /repos/{owner}/{repo}/codespaces/secrets/public-key` + /// Get a repository public key + static const codespacesGetRepoPublicKey = RestOperationContract( + operationId: 'codespaces/get-repo-public-key', + method: 'GET', + path: '/repos/{owner}/{repo}/codespaces/secrets/public-key', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/codespaces/secrets/{secret_name}` + /// Get a repository secret + static const codespacesGetRepoSecret = RestOperationContract( + operationId: 'codespaces/get-repo-secret', + method: 'GET', + path: '/repos/{owner}/{repo}/codespaces/secrets/{secret_name}', + pathParams: ['owner', 'repo', 'secret_name'], + ); + + /// `GET /user/codespaces/secrets/{secret_name}` + /// Get a secret for the authenticated user + static const codespacesGetSecretForAuthenticatedUser = RestOperationContract( + operationId: 'codespaces/get-secret-for-authenticated-user', + method: 'GET', + path: '/user/codespaces/secrets/{secret_name}', + pathParams: ['secret_name'], + ); + + /// `GET /repos/{owner}/{repo}/codespaces/devcontainers` + /// List devcontainer configurations in a repository for the authenticated user + static const codespacesListDevcontainersInRepositoryForAuthenticatedUser = + RestOperationContract( + operationId: + 'codespaces/list-devcontainers-in-repository-for-authenticated-user', + method: 'GET', + path: '/repos/{owner}/{repo}/codespaces/devcontainers', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/codespaces` + /// List codespaces for the authenticated user + static const codespacesListForAuthenticatedUser = RestOperationContract( + operationId: 'codespaces/list-for-authenticated-user', + method: 'GET', + path: '/user/codespaces', + queryParams: ['page', 'per_page', 'repository_id'], + ); + + /// `GET /orgs/{org}/codespaces` + /// List codespaces for the organization + static const codespacesListInOrganization = RestOperationContract( + operationId: 'codespaces/list-in-organization', + method: 'GET', + path: '/orgs/{org}/codespaces', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/codespaces` + /// List codespaces in a repository for the authenticated user + static const codespacesListInRepositoryForAuthenticatedUser = + RestOperationContract( + operationId: 'codespaces/list-in-repository-for-authenticated-user', + method: 'GET', + path: '/repos/{owner}/{repo}/codespaces', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/codespaces/secrets` + /// List organization secrets + static const codespacesListOrgSecrets = RestOperationContract( + operationId: 'codespaces/list-org-secrets', + method: 'GET', + path: '/orgs/{org}/codespaces/secrets', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/codespaces/secrets` + /// List repository secrets + static const codespacesListRepoSecrets = RestOperationContract( + operationId: 'codespaces/list-repo-secrets', + method: 'GET', + path: '/repos/{owner}/{repo}/codespaces/secrets', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/codespaces/secrets/{secret_name}/repositories` + /// List selected repositories for a user secret + static const codespacesListRepositoriesForSecretForAuthenticatedUser = + RestOperationContract( + operationId: + 'codespaces/list-repositories-for-secret-for-authenticated-user', + method: 'GET', + path: '/user/codespaces/secrets/{secret_name}/repositories', + pathParams: ['secret_name'], + ); + + /// `GET /user/codespaces/secrets` + /// List secrets for the authenticated user + static const codespacesListSecretsForAuthenticatedUser = + RestOperationContract( + operationId: 'codespaces/list-secrets-for-authenticated-user', + method: 'GET', + path: '/user/codespaces/secrets', + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/codespaces/secrets/{secret_name}/repositories` + /// List selected repositories for an organization secret + static const codespacesListSelectedReposForOrgSecret = RestOperationContract( + operationId: 'codespaces/list-selected-repos-for-org-secret', + method: 'GET', + path: '/orgs/{org}/codespaces/secrets/{secret_name}/repositories', + pathParams: ['org', 'secret_name'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/codespaces/new` + /// Get default attributes for a codespace + static const codespacesPreFlightWithRepoForAuthenticatedUser = + RestOperationContract( + operationId: 'codespaces/pre-flight-with-repo-for-authenticated-user', + method: 'GET', + path: '/repos/{owner}/{repo}/codespaces/new', + pathParams: ['owner', 'repo'], + queryParams: ['client_ip', 'ref'], + ); + + /// `POST /user/codespaces/{codespace_name}/publish` + /// Create a repository from an unpublished codespace + static const codespacesPublishForAuthenticatedUser = RestOperationContract( + operationId: 'codespaces/publish-for-authenticated-user', + method: 'POST', + path: '/user/codespaces/{codespace_name}/publish', + pathParams: ['codespace_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /user/codespaces/secrets/{secret_name}/repositories/{repository_id}` + /// Remove a selected repository from a user secret + static const codespacesRemoveRepositoryForSecretForAuthenticatedUser = + RestOperationContract( + operationId: + 'codespaces/remove-repository-for-secret-for-authenticated-user', + method: 'DELETE', + path: '/user/codespaces/secrets/{secret_name}/repositories/{repository_id}', + pathParams: ['repository_id', 'secret_name'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/codespaces/secrets/{secret_name}/repositories/{repository_id}` + /// Remove selected repository from an organization secret + static const codespacesRemoveSelectedRepoFromOrgSecret = + RestOperationContract( + operationId: 'codespaces/remove-selected-repo-from-org-secret', + method: 'DELETE', + path: + '/orgs/{org}/codespaces/secrets/{secret_name}/repositories/{repository_id}', + pathParams: ['org', 'repository_id', 'secret_name'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/codespaces/machines` + /// List available machine types for a repository + static const codespacesRepoMachinesForAuthenticatedUser = + RestOperationContract( + operationId: 'codespaces/repo-machines-for-authenticated-user', + method: 'GET', + path: '/repos/{owner}/{repo}/codespaces/machines', + pathParams: ['owner', 'repo'], + queryParams: ['client_ip', 'location', 'ref'], + ); + + /// `PUT /orgs/{org}/codespaces/access` + /// Manage access control for organization codespaces + static const codespacesSetCodespacesAccess = RestOperationContract( + operationId: 'codespaces/set-codespaces-access', + method: 'PUT', + path: '/orgs/{org}/codespaces/access', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `POST /orgs/{org}/codespaces/access/selected_users` + /// Add users to Codespaces access for an organization + static const codespacesSetCodespacesAccessUsers = RestOperationContract( + operationId: 'codespaces/set-codespaces-access-users', + method: 'POST', + path: '/orgs/{org}/codespaces/access/selected_users', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /user/codespaces/secrets/{secret_name}/repositories` + /// Set selected repositories for a user secret + static const codespacesSetRepositoriesForSecretForAuthenticatedUser = + RestOperationContract( + operationId: + 'codespaces/set-repositories-for-secret-for-authenticated-user', + method: 'PUT', + path: '/user/codespaces/secrets/{secret_name}/repositories', + pathParams: ['secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/codespaces/secrets/{secret_name}/repositories` + /// Set selected repositories for an organization secret + static const codespacesSetSelectedReposForOrgSecret = RestOperationContract( + operationId: 'codespaces/set-selected-repos-for-org-secret', + method: 'PUT', + path: '/orgs/{org}/codespaces/secrets/{secret_name}/repositories', + pathParams: ['org', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `POST /user/codespaces/{codespace_name}/start` + /// Start a codespace for the authenticated user + static const codespacesStartForAuthenticatedUser = RestOperationContract( + operationId: 'codespaces/start-for-authenticated-user', + method: 'POST', + path: '/user/codespaces/{codespace_name}/start', + pathParams: ['codespace_name'], + ); + + /// `POST /user/codespaces/{codespace_name}/stop` + /// Stop a codespace for the authenticated user + static const codespacesStopForAuthenticatedUser = RestOperationContract( + operationId: 'codespaces/stop-for-authenticated-user', + method: 'POST', + path: '/user/codespaces/{codespace_name}/stop', + pathParams: ['codespace_name'], + ); + + /// `POST /orgs/{org}/members/{username}/codespaces/{codespace_name}/stop` + /// Stop a codespace for an organization user + static const codespacesStopInOrganization = RestOperationContract( + operationId: 'codespaces/stop-in-organization', + method: 'POST', + path: '/orgs/{org}/members/{username}/codespaces/{codespace_name}/stop', + pathParams: ['codespace_name', 'org', 'username'], + ); + + /// `PATCH /user/codespaces/{codespace_name}` + /// Update a codespace for the authenticated user + static const codespacesUpdateForAuthenticatedUser = RestOperationContract( + operationId: 'codespaces/update-for-authenticated-user', + method: 'PATCH', + path: '/user/codespaces/{codespace_name}', + pathParams: ['codespace_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /orgs/{org}/copilot-spaces/{space_number}/collaborators` + /// Add a collaborator to an organization Copilot Space + static const copilotSpacesAddCollaboratorForOrg = RestOperationContract( + operationId: 'copilot-spaces/add-collaborator-for-org', + method: 'POST', + path: '/orgs/{org}/copilot-spaces/{space_number}/collaborators', + pathParams: ['org', 'space_number'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /users/{username}/copilot-spaces/{space_number}/collaborators` + /// Add a collaborator to a Copilot Space for a user + static const copilotSpacesAddCollaboratorForUser = RestOperationContract( + operationId: 'copilot-spaces/add-collaborator-for-user', + method: 'POST', + path: '/users/{username}/copilot-spaces/{space_number}/collaborators', + pathParams: ['space_number', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/copilot-spaces` + /// Create an organization Copilot Space + static const copilotSpacesCreateForOrg = RestOperationContract( + operationId: 'copilot-spaces/create-for-org', + method: 'POST', + path: '/orgs/{org}/copilot-spaces', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /users/{username}/copilot-spaces` + /// Create a Copilot Space for a user + static const copilotSpacesCreateForUser = RestOperationContract( + operationId: 'copilot-spaces/create-for-user', + method: 'POST', + path: '/users/{username}/copilot-spaces', + pathParams: ['username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/copilot-spaces/{space_number}/resources` + /// Create a resource for an organization Copilot Space + static const copilotSpacesCreateResourceForOrg = RestOperationContract( + operationId: 'copilot-spaces/create-resource-for-org', + method: 'POST', + path: '/orgs/{org}/copilot-spaces/{space_number}/resources', + pathParams: ['org', 'space_number'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 201], + ); + + /// `POST /users/{username}/copilot-spaces/{space_number}/resources` + /// Create a resource for a Copilot Space for a user + static const copilotSpacesCreateResourceForUser = RestOperationContract( + operationId: 'copilot-spaces/create-resource-for-user', + method: 'POST', + path: '/users/{username}/copilot-spaces/{space_number}/resources', + pathParams: ['space_number', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 201], + ); + + /// `DELETE /orgs/{org}/copilot-spaces/{space_number}` + /// Delete an organization Copilot Space + static const copilotSpacesDeleteForOrg = RestOperationContract( + operationId: 'copilot-spaces/delete-for-org', + method: 'DELETE', + path: '/orgs/{org}/copilot-spaces/{space_number}', + pathParams: ['org', 'space_number'], + successStatuses: [204], + ); + + /// `DELETE /users/{username}/copilot-spaces/{space_number}` + /// Delete a Copilot Space for a user + static const copilotSpacesDeleteForUser = RestOperationContract( + operationId: 'copilot-spaces/delete-for-user', + method: 'DELETE', + path: '/users/{username}/copilot-spaces/{space_number}', + pathParams: ['space_number', 'username'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}` + /// Delete a resource from an organization Copilot Space + static const copilotSpacesDeleteResourceForOrg = RestOperationContract( + operationId: 'copilot-spaces/delete-resource-for-org', + method: 'DELETE', + path: + '/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}', + pathParams: ['org', 'space_number', 'space_resource_id'], + successStatuses: [204], + ); + + /// `DELETE /users/{username}/copilot-spaces/{space_number}/resources/{space_resource_id}` + /// Delete a resource from a Copilot Space for a user + static const copilotSpacesDeleteResourceForUser = RestOperationContract( + operationId: 'copilot-spaces/delete-resource-for-user', + method: 'DELETE', + path: + '/users/{username}/copilot-spaces/{space_number}/resources/{space_resource_id}', + pathParams: ['space_number', 'space_resource_id', 'username'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/copilot-spaces/{space_number}` + /// Get an organization Copilot Space + static const copilotSpacesGetForOrg = RestOperationContract( + operationId: 'copilot-spaces/get-for-org', + method: 'GET', + path: '/orgs/{org}/copilot-spaces/{space_number}', + pathParams: ['org', 'space_number'], + ); + + /// `GET /users/{username}/copilot-spaces/{space_number}` + /// Get a Copilot Space for a user + static const copilotSpacesGetForUser = RestOperationContract( + operationId: 'copilot-spaces/get-for-user', + method: 'GET', + path: '/users/{username}/copilot-spaces/{space_number}', + pathParams: ['space_number', 'username'], + ); + + /// `GET /orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}` + /// Get a resource for an organization Copilot Space + static const copilotSpacesGetResourceForOrg = RestOperationContract( + operationId: 'copilot-spaces/get-resource-for-org', + method: 'GET', + path: + '/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}', + pathParams: ['org', 'space_number', 'space_resource_id'], + ); + + /// `GET /users/{username}/copilot-spaces/{space_number}/resources/{space_resource_id}` + /// Get a resource for a Copilot Space for a user + static const copilotSpacesGetResourceForUser = RestOperationContract( + operationId: 'copilot-spaces/get-resource-for-user', + method: 'GET', + path: + '/users/{username}/copilot-spaces/{space_number}/resources/{space_resource_id}', + pathParams: ['space_number', 'space_resource_id', 'username'], + ); + + /// `GET /orgs/{org}/copilot-spaces/{space_number}/collaborators` + /// List collaborators for an organization Copilot Space + static const copilotSpacesListCollaboratorsForOrg = RestOperationContract( + operationId: 'copilot-spaces/list-collaborators-for-org', + method: 'GET', + path: '/orgs/{org}/copilot-spaces/{space_number}/collaborators', + pathParams: ['org', 'space_number'], + ); + + /// `GET /users/{username}/copilot-spaces/{space_number}/collaborators` + /// List collaborators for a Copilot Space for a user + static const copilotSpacesListCollaboratorsForUser = RestOperationContract( + operationId: 'copilot-spaces/list-collaborators-for-user', + method: 'GET', + path: '/users/{username}/copilot-spaces/{space_number}/collaborators', + pathParams: ['space_number', 'username'], + ); + + /// `GET /orgs/{org}/copilot-spaces` + /// List organization Copilot Spaces + static const copilotSpacesListForOrg = RestOperationContract( + operationId: 'copilot-spaces/list-for-org', + method: 'GET', + path: '/orgs/{org}/copilot-spaces', + pathParams: ['org'], + queryParams: ['after', 'before', 'per_page'], + ); + + /// `GET /users/{username}/copilot-spaces` + /// List Copilot Spaces for a user + static const copilotSpacesListForUser = RestOperationContract( + operationId: 'copilot-spaces/list-for-user', + method: 'GET', + path: '/users/{username}/copilot-spaces', + pathParams: ['username'], + queryParams: ['after', 'before', 'per_page'], + ); + + /// `GET /orgs/{org}/copilot-spaces/{space_number}/resources` + /// List resources for an organization Copilot Space + static const copilotSpacesListResourcesForOrg = RestOperationContract( + operationId: 'copilot-spaces/list-resources-for-org', + method: 'GET', + path: '/orgs/{org}/copilot-spaces/{space_number}/resources', + pathParams: ['org', 'space_number'], + ); + + /// `GET /users/{username}/copilot-spaces/{space_number}/resources` + /// List resources for a Copilot Space for a user + static const copilotSpacesListResourcesForUser = RestOperationContract( + operationId: 'copilot-spaces/list-resources-for-user', + method: 'GET', + path: '/users/{username}/copilot-spaces/{space_number}/resources', + pathParams: ['space_number', 'username'], + ); + + /// `DELETE /orgs/{org}/copilot-spaces/{space_number}/collaborators/{actor_type}/{actor_identifier}` + /// Remove a collaborator from an organization Copilot Space + static const copilotSpacesRemoveCollaboratorForOrg = RestOperationContract( + operationId: 'copilot-spaces/remove-collaborator-for-org', + method: 'DELETE', + path: + '/orgs/{org}/copilot-spaces/{space_number}/collaborators/{actor_type}/{actor_identifier}', + pathParams: ['actor_identifier', 'actor_type', 'org', 'space_number'], + successStatuses: [204], + ); + + /// `DELETE /users/{username}/copilot-spaces/{space_number}/collaborators/{actor_type}/{actor_identifier}` + /// Remove a collaborator from a Copilot Space for a user + static const copilotSpacesRemoveCollaboratorForUser = RestOperationContract( + operationId: 'copilot-spaces/remove-collaborator-for-user', + method: 'DELETE', + path: + '/users/{username}/copilot-spaces/{space_number}/collaborators/{actor_type}/{actor_identifier}', + pathParams: ['actor_identifier', 'actor_type', 'space_number', 'username'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/copilot-spaces/{space_number}/collaborators/{actor_type}/{actor_identifier}` + /// Set a collaborator role for an organization Copilot Space + static const copilotSpacesUpdateCollaboratorForOrg = RestOperationContract( + operationId: 'copilot-spaces/update-collaborator-for-org', + method: 'PUT', + path: + '/orgs/{org}/copilot-spaces/{space_number}/collaborators/{actor_type}/{actor_identifier}', + pathParams: ['actor_identifier', 'actor_type', 'org', 'space_number'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 204], + ); + + /// `PUT /users/{username}/copilot-spaces/{space_number}/collaborators/{actor_type}/{actor_identifier}` + /// Set a collaborator role for a Copilot Space for a user + static const copilotSpacesUpdateCollaboratorForUser = RestOperationContract( + operationId: 'copilot-spaces/update-collaborator-for-user', + method: 'PUT', + path: + '/users/{username}/copilot-spaces/{space_number}/collaborators/{actor_type}/{actor_identifier}', + pathParams: ['actor_identifier', 'actor_type', 'space_number', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 204], + ); + + /// `PUT /orgs/{org}/copilot-spaces/{space_number}` + /// Set an organization Copilot Space + static const copilotSpacesUpdateForOrg = RestOperationContract( + operationId: 'copilot-spaces/update-for-org', + method: 'PUT', + path: '/orgs/{org}/copilot-spaces/{space_number}', + pathParams: ['org', 'space_number'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /users/{username}/copilot-spaces/{space_number}` + /// Set a Copilot Space for a user + static const copilotSpacesUpdateForUser = RestOperationContract( + operationId: 'copilot-spaces/update-for-user', + method: 'PUT', + path: '/users/{username}/copilot-spaces/{space_number}', + pathParams: ['space_number', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}` + /// Set a resource for an organization Copilot Space + static const copilotSpacesUpdateResourceForOrg = RestOperationContract( + operationId: 'copilot-spaces/update-resource-for-org', + method: 'PUT', + path: + '/orgs/{org}/copilot-spaces/{space_number}/resources/{space_resource_id}', + pathParams: ['org', 'space_number', 'space_resource_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /users/{username}/copilot-spaces/{space_number}/resources/{space_resource_id}` + /// Set a resource for a Copilot Space for a user + static const copilotSpacesUpdateResourceForUser = RestOperationContract( + operationId: 'copilot-spaces/update-resource-for-user', + method: 'PUT', + path: + '/users/{username}/copilot-spaces/{space_number}/resources/{space_resource_id}', + pathParams: ['space_number', 'space_resource_id', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /orgs/{org}/copilot/billing/selected_teams` + /// Add teams to the Copilot subscription for an organization + static const copilotAddCopilotSeatsForTeams = RestOperationContract( + operationId: 'copilot/add-copilot-seats-for-teams', + method: 'POST', + path: '/orgs/{org}/copilot/billing/selected_teams', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/copilot/billing/selected_users` + /// Add users to the Copilot subscription for an organization + static const copilotAddCopilotSeatsForUsers = RestOperationContract( + operationId: 'copilot/add-copilot-seats-for-users', + method: 'POST', + path: '/orgs/{org}/copilot/billing/selected_users', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /enterprises/{enterprise}/copilot/policies/coding_agent/organizations` + /// Add organizations to the enterprise coding agent policy + static const copilotAddOrganizationsToEnterpriseCodingAgentPolicy = + RestOperationContract( + operationId: 'copilot/add-organizations-to-enterprise-coding-agent-policy', + method: 'POST', + path: + '/enterprises/{enterprise}/copilot/policies/coding_agent/organizations', + pathParams: ['enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/copilot/billing/selected_teams` + /// Remove teams from the Copilot subscription for an organization + static const copilotCancelCopilotSeatAssignmentForTeams = + RestOperationContract( + operationId: 'copilot/cancel-copilot-seat-assignment-for-teams', + method: 'DELETE', + path: '/orgs/{org}/copilot/billing/selected_teams', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /orgs/{org}/copilot/billing/selected_users` + /// Remove users from the Copilot subscription for an organization + static const copilotCancelCopilotSeatAssignmentForUsers = + RestOperationContract( + operationId: 'copilot/cancel-copilot-seat-assignment-for-users', + method: 'DELETE', + path: '/orgs/{org}/copilot/billing/selected_users', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /orgs/{org}/copilot/content_exclusion` + /// Get Copilot content exclusion rules for an organization + static const copilotCopilotContentExclusionForOrganization = + RestOperationContract( + operationId: 'copilot/copilot-content-exclusion-for-organization', + method: 'GET', + path: '/orgs/{org}/copilot/content_exclusion', + pathParams: ['org'], + ); + + /// `GET /enterprises/{enterprise}/copilot/metrics/reports/enterprise-1-day` + /// Get Copilot enterprise usage metrics for a specific day + static const copilotCopilotEnterpriseOneDayUsageMetrics = + RestOperationContract( + operationId: 'copilot/copilot-enterprise-one-day-usage-metrics', + method: 'GET', + path: '/enterprises/{enterprise}/copilot/metrics/reports/enterprise-1-day', + pathParams: ['enterprise'], + queryParams: ['day'], + ); + + /// `GET /enterprises/{enterprise}/copilot/metrics/reports/repos-1-day` + /// Get Copilot enterprise repository report for a specific day + static const copilotCopilotEnterpriseReposOneDayReport = + RestOperationContract( + operationId: 'copilot/copilot-enterprise-repos-one-day-report', + method: 'GET', + path: '/enterprises/{enterprise}/copilot/metrics/reports/repos-1-day', + pathParams: ['enterprise'], + queryParams: ['day'], + successStatuses: [200, 204], + ); + + /// `GET /enterprises/{enterprise}/copilot/metrics/reports/enterprise-28-day/latest` + /// Get Copilot enterprise usage metrics + static const copilotCopilotEnterpriseUsageMetrics = RestOperationContract( + operationId: 'copilot/copilot-enterprise-usage-metrics', + method: 'GET', + path: + '/enterprises/{enterprise}/copilot/metrics/reports/enterprise-28-day/latest', + pathParams: ['enterprise'], + ); + + /// `GET /enterprises/{enterprise}/copilot/metrics/reports/user-teams-1-day` + /// Get Copilot enterprise user-teams report for a specific day + static const copilotCopilotEnterpriseUserTeamsOneDayReport = + RestOperationContract( + operationId: 'copilot/copilot-enterprise-user-teams-one-day-report', + method: 'GET', + path: '/enterprises/{enterprise}/copilot/metrics/reports/user-teams-1-day', + pathParams: ['enterprise'], + queryParams: ['day'], + ); + + /// `GET /orgs/{org}/copilot/metrics/reports/organization-1-day` + /// Get Copilot organization usage metrics for a specific day + static const copilotCopilotOrganizationOneDayUsageMetrics = + RestOperationContract( + operationId: 'copilot/copilot-organization-one-day-usage-metrics', + method: 'GET', + path: '/orgs/{org}/copilot/metrics/reports/organization-1-day', + pathParams: ['org'], + queryParams: ['day'], + successStatuses: [200, 204], + ); + + /// `GET /orgs/{org}/copilot/metrics/reports/repos-1-day` + /// Get Copilot organization repository report for a specific day + static const copilotCopilotOrganizationReposOneDayReport = + RestOperationContract( + operationId: 'copilot/copilot-organization-repos-one-day-report', + method: 'GET', + path: '/orgs/{org}/copilot/metrics/reports/repos-1-day', + pathParams: ['org'], + queryParams: ['day'], + successStatuses: [200, 204], + ); + + /// `GET /orgs/{org}/copilot/metrics/reports/organization-28-day/latest` + /// Get Copilot organization usage metrics + static const copilotCopilotOrganizationUsageMetrics = RestOperationContract( + operationId: 'copilot/copilot-organization-usage-metrics', + method: 'GET', + path: '/orgs/{org}/copilot/metrics/reports/organization-28-day/latest', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/copilot/metrics/reports/user-teams-1-day` + /// Get Copilot organization user-teams report for a specific day + static const copilotCopilotOrganizationUserTeamsOneDayReport = + RestOperationContract( + operationId: 'copilot/copilot-organization-user-teams-one-day-report', + method: 'GET', + path: '/orgs/{org}/copilot/metrics/reports/user-teams-1-day', + pathParams: ['org'], + queryParams: ['day'], + successStatuses: [200, 204], + ); + + /// `GET /orgs/{org}/copilot/metrics/reports/users-1-day` + /// Get Copilot organization users usage metrics for a specific day + static const copilotCopilotOrganizationUsersOneDayUsageMetrics = + RestOperationContract( + operationId: 'copilot/copilot-organization-users-one-day-usage-metrics', + method: 'GET', + path: '/orgs/{org}/copilot/metrics/reports/users-1-day', + pathParams: ['org'], + queryParams: ['day'], + successStatuses: [200, 204], + ); + + /// `GET /orgs/{org}/copilot/metrics/reports/users-28-day/latest` + /// Get Copilot organization users usage metrics + static const copilotCopilotOrganizationUsersUsageMetrics = + RestOperationContract( + operationId: 'copilot/copilot-organization-users-usage-metrics', + method: 'GET', + path: '/orgs/{org}/copilot/metrics/reports/users-28-day/latest', + pathParams: ['org'], + ); + + /// `GET /enterprises/{enterprise}/copilot/metrics/reports/users-1-day` + /// Get Copilot users usage metrics for a specific day + static const copilotCopilotUsersOneDayUsageMetrics = RestOperationContract( + operationId: 'copilot/copilot-users-one-day-usage-metrics', + method: 'GET', + path: '/enterprises/{enterprise}/copilot/metrics/reports/users-1-day', + pathParams: ['enterprise'], + queryParams: ['day'], + ); + + /// `GET /enterprises/{enterprise}/copilot/metrics/reports/users-28-day/latest` + /// Get Copilot users usage metrics + static const copilotCopilotUsersUsageMetrics = RestOperationContract( + operationId: 'copilot/copilot-users-usage-metrics', + method: 'GET', + path: + '/enterprises/{enterprise}/copilot/metrics/reports/users-28-day/latest', + pathParams: ['enterprise'], + ); + + /// `DELETE /orgs/{org}/copilot/coding-agent/permissions/repositories/{repository_id}` + /// Disable a repository for Copilot cloud agent in an organization + static const copilotDisableCopilotCodingAgentForRepositoryInOrganization = + RestOperationContract( + operationId: + 'copilot/disable-copilot-coding-agent-for-repository-in-organization', + method: 'DELETE', + path: + '/orgs/{org}/copilot/coding-agent/permissions/repositories/{repository_id}', + pathParams: ['org', 'repository_id'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/copilot/coding-agent/permissions/repositories/{repository_id}` + /// Enable a repository for Copilot cloud agent in an organization + static const copilotEnableCopilotCodingAgentForRepositoryInOrganization = + RestOperationContract( + operationId: + 'copilot/enable-copilot-coding-agent-for-repository-in-organization', + method: 'PUT', + path: + '/orgs/{org}/copilot/coding-agent/permissions/repositories/{repository_id}', + pathParams: ['org', 'repository_id'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/copilot/cloud-agent/configuration` + /// Get Copilot cloud agent configuration for a repository + static const copilotGetCopilotCloudAgentConfiguration = RestOperationContract( + operationId: 'copilot/get-copilot-cloud-agent-configuration', + method: 'GET', + path: '/repos/{owner}/{repo}/copilot/cloud-agent/configuration', + pathParams: ['owner', 'repo'], + ); + + /// `GET /orgs/{org}/copilot/coding-agent/permissions` + /// Get Copilot cloud agent permissions for an organization + static const copilotGetCopilotCodingAgentPermissionsOrganization = + RestOperationContract( + operationId: 'copilot/get-copilot-coding-agent-permissions-organization', + method: 'GET', + path: '/orgs/{org}/copilot/coding-agent/permissions', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/copilot/billing` + /// Get Copilot seat information and settings for an organization + static const copilotGetCopilotOrganizationDetails = RestOperationContract( + operationId: 'copilot/get-copilot-organization-details', + method: 'GET', + path: '/orgs/{org}/copilot/billing', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/members/{username}/copilot` + /// Get Copilot seat assignment details for a user + static const copilotGetCopilotSeatDetailsForUser = RestOperationContract( + operationId: 'copilot/get-copilot-seat-details-for-user', + method: 'GET', + path: '/orgs/{org}/members/{username}/copilot', + pathParams: ['org', 'username'], + ); + + /// `GET /orgs/{org}/copilot/coding-agent/permissions/repositories` + /// List repositories enabled for Copilot cloud agent in an organization + static const copilotListCopilotCodingAgentSelectedRepositoriesForOrganization = + RestOperationContract( + operationId: + 'copilot/list-copilot-coding-agent-selected-repositories-for-organization', + method: 'GET', + path: '/orgs/{org}/copilot/coding-agent/permissions/repositories', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/copilot/billing/seats` + /// List all Copilot seat assignments for an organization + static const copilotListCopilotSeats = RestOperationContract( + operationId: 'copilot/list-copilot-seats', + method: 'GET', + path: '/orgs/{org}/copilot/billing/seats', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `DELETE /enterprises/{enterprise}/copilot/policies/coding_agent/organizations` + /// Remove organizations from the enterprise coding agent policy + static const copilotRemoveOrganizationsFromEnterpriseCodingAgentPolicy = + RestOperationContract( + operationId: + 'copilot/remove-organizations-from-enterprise-coding-agent-policy', + method: 'DELETE', + path: + '/enterprises/{enterprise}/copilot/policies/coding_agent/organizations', + pathParams: ['enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/copilot/coding-agent/permissions` + /// Set Copilot cloud agent permissions for an organization + static const copilotSetCopilotCodingAgentPermissionsOrganization = + RestOperationContract( + operationId: 'copilot/set-copilot-coding-agent-permissions-organization', + method: 'PUT', + path: '/orgs/{org}/copilot/coding-agent/permissions', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/copilot/coding-agent/permissions/repositories` + /// Set selected repositories for Copilot cloud agent in an organization + static const copilotSetCopilotCodingAgentSelectedRepositoriesForOrganization = + RestOperationContract( + operationId: + 'copilot/set-copilot-coding-agent-selected-repositories-for-organization', + method: 'PUT', + path: '/orgs/{org}/copilot/coding-agent/permissions/repositories', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/copilot/content_exclusion` + /// Set Copilot content exclusion rules for an organization + static const copilotSetCopilotContentExclusionForOrganization = + RestOperationContract( + operationId: 'copilot/set-copilot-content-exclusion-for-organization', + method: 'PUT', + path: '/orgs/{org}/copilot/content_exclusion', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /enterprises/{enterprise}/copilot/policies/coding_agent` + /// Set the coding agent policy for an enterprise + static const copilotSetEnterpriseCodingAgentPolicy = RestOperationContract( + operationId: 'copilot/set-enterprise-coding-agent-policy', + method: 'PUT', + path: '/enterprises/{enterprise}/copilot/policies/coding_agent', + pathParams: ['enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `POST /credentials/revoke` + /// Revoke a list of credentials + static const credentialsRevoke = RestOperationContract( + operationId: 'credentials/revoke', + method: 'POST', + path: '/credentials/revoke', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202], + ); + + /// `PUT /orgs/{org}/dependabot/secrets/{secret_name}/repositories/{repository_id}` + /// Add selected repository to an organization secret + static const dependabotAddSelectedRepoToOrgSecret = RestOperationContract( + operationId: 'dependabot/add-selected-repo-to-org-secret', + method: 'PUT', + path: + '/orgs/{org}/dependabot/secrets/{secret_name}/repositories/{repository_id}', + pathParams: ['org', 'repository_id', 'secret_name'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/dependabot/secrets/{secret_name}` + /// Create or update an organization secret + static const dependabotCreateOrUpdateOrgSecret = RestOperationContract( + operationId: 'dependabot/create-or-update-org-secret', + method: 'PUT', + path: '/orgs/{org}/dependabot/secrets/{secret_name}', + pathParams: ['org', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 204], + ); + + /// `PUT /repos/{owner}/{repo}/dependabot/secrets/{secret_name}` + /// Create or update a repository secret + static const dependabotCreateOrUpdateRepoSecret = RestOperationContract( + operationId: 'dependabot/create-or-update-repo-secret', + method: 'PUT', + path: '/repos/{owner}/{repo}/dependabot/secrets/{secret_name}', + pathParams: ['owner', 'repo', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 204], + ); + + /// `DELETE /orgs/{org}/dependabot/secrets/{secret_name}` + /// Delete an organization secret + static const dependabotDeleteOrgSecret = RestOperationContract( + operationId: 'dependabot/delete-org-secret', + method: 'DELETE', + path: '/orgs/{org}/dependabot/secrets/{secret_name}', + pathParams: ['org', 'secret_name'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/dependabot/secrets/{secret_name}` + /// Delete a repository secret + static const dependabotDeleteRepoSecret = RestOperationContract( + operationId: 'dependabot/delete-repo-secret', + method: 'DELETE', + path: '/repos/{owner}/{repo}/dependabot/secrets/{secret_name}', + pathParams: ['owner', 'repo', 'secret_name'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/dependabot/alerts/{alert_number}` + /// Get a Dependabot alert + static const dependabotGetAlert = RestOperationContract( + operationId: 'dependabot/get-alert', + method: 'GET', + path: '/repos/{owner}/{repo}/dependabot/alerts/{alert_number}', + pathParams: ['alert_number', 'owner', 'repo'], + ); + + /// `GET /orgs/{org}/dependabot/secrets/public-key` + /// Get an organization public key + static const dependabotGetOrgPublicKey = RestOperationContract( + operationId: 'dependabot/get-org-public-key', + method: 'GET', + path: '/orgs/{org}/dependabot/secrets/public-key', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/dependabot/secrets/{secret_name}` + /// Get an organization secret + static const dependabotGetOrgSecret = RestOperationContract( + operationId: 'dependabot/get-org-secret', + method: 'GET', + path: '/orgs/{org}/dependabot/secrets/{secret_name}', + pathParams: ['org', 'secret_name'], + ); + + /// `GET /repos/{owner}/{repo}/dependabot/secrets/public-key` + /// Get a repository public key + static const dependabotGetRepoPublicKey = RestOperationContract( + operationId: 'dependabot/get-repo-public-key', + method: 'GET', + path: '/repos/{owner}/{repo}/dependabot/secrets/public-key', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/dependabot/secrets/{secret_name}` + /// Get a repository secret + static const dependabotGetRepoSecret = RestOperationContract( + operationId: 'dependabot/get-repo-secret', + method: 'GET', + path: '/repos/{owner}/{repo}/dependabot/secrets/{secret_name}', + pathParams: ['owner', 'repo', 'secret_name'], + ); + + /// `GET /enterprises/{enterprise}/dependabot/alerts` + /// List Dependabot alerts for an enterprise + static const dependabotListAlertsForEnterprise = RestOperationContract( + operationId: 'dependabot/list-alerts-for-enterprise', + method: 'GET', + path: '/enterprises/{enterprise}/dependabot/alerts', + pathParams: ['enterprise'], + queryParams: [ + 'after', + 'assignee', + 'before', + 'classification', + 'direction', + 'ecosystem', + 'epss_percentage', + 'has', + 'package', + 'per_page', + 'relationship', + 'scope', + 'severity', + 'sort', + 'state' + ], + ); + + /// `GET /orgs/{org}/dependabot/alerts` + /// List Dependabot alerts for an organization + static const dependabotListAlertsForOrg = RestOperationContract( + operationId: 'dependabot/list-alerts-for-org', + method: 'GET', + path: '/orgs/{org}/dependabot/alerts', + pathParams: ['org'], + queryParams: [ + 'after', + 'artifact_registry', + 'artifact_registry_url', + 'assignee', + 'before', + 'classification', + 'direction', + 'ecosystem', + 'epss_percentage', + 'has', + 'package', + 'per_page', + 'relationship', + 'runtime_risk', + 'scope', + 'severity', + 'sort', + 'state' + ], + ); + + /// `GET /repos/{owner}/{repo}/dependabot/alerts` + /// List Dependabot alerts for a repository + static const dependabotListAlertsForRepo = RestOperationContract( + operationId: 'dependabot/list-alerts-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/dependabot/alerts', + pathParams: ['owner', 'repo'], + queryParams: [ + 'after', + 'assignee', + 'before', + 'classification', + 'direction', + 'ecosystem', + 'epss_percentage', + 'has', + 'manifest', + 'package', + 'per_page', + 'relationship', + 'scope', + 'severity', + 'sort', + 'state' + ], + ); + + /// `GET /orgs/{org}/dependabot/secrets` + /// List organization secrets + static const dependabotListOrgSecrets = RestOperationContract( + operationId: 'dependabot/list-org-secrets', + method: 'GET', + path: '/orgs/{org}/dependabot/secrets', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/dependabot/secrets` + /// List repository secrets + static const dependabotListRepoSecrets = RestOperationContract( + operationId: 'dependabot/list-repo-secrets', + method: 'GET', + path: '/repos/{owner}/{repo}/dependabot/secrets', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/dependabot/secrets/{secret_name}/repositories` + /// List selected repositories for an organization secret + static const dependabotListSelectedReposForOrgSecret = RestOperationContract( + operationId: 'dependabot/list-selected-repos-for-org-secret', + method: 'GET', + path: '/orgs/{org}/dependabot/secrets/{secret_name}/repositories', + pathParams: ['org', 'secret_name'], + queryParams: ['page', 'per_page'], + ); + + /// `DELETE /orgs/{org}/dependabot/secrets/{secret_name}/repositories/{repository_id}` + /// Remove selected repository from an organization secret + static const dependabotRemoveSelectedRepoFromOrgSecret = + RestOperationContract( + operationId: 'dependabot/remove-selected-repo-from-org-secret', + method: 'DELETE', + path: + '/orgs/{org}/dependabot/secrets/{secret_name}/repositories/{repository_id}', + pathParams: ['org', 'repository_id', 'secret_name'], + successStatuses: [204], + ); + + /// `GET /enterprises/{enterprise}/dependabot/repository-access` + /// Lists the repositories Dependabot can access in an enterprise + static const dependabotRepositoryAccessForEnterprise = RestOperationContract( + operationId: 'dependabot/repository-access-for-enterprise', + method: 'GET', + path: '/enterprises/{enterprise}/dependabot/repository-access', + pathParams: ['enterprise'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/dependabot/repository-access` + /// Lists the repositories Dependabot can access in an organization + static const dependabotRepositoryAccessForOrg = RestOperationContract( + operationId: 'dependabot/repository-access-for-org', + method: 'GET', + path: '/orgs/{org}/dependabot/repository-access', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `PUT /orgs/{org}/dependabot/repository-access/default-level` + /// Set the default repository access level for Dependabot + static const dependabotSetRepositoryAccessDefaultLevel = + RestOperationContract( + operationId: 'dependabot/set-repository-access-default-level', + method: 'PUT', + path: '/orgs/{org}/dependabot/repository-access/default-level', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /enterprises/{enterprise}/dependabot/repository-access/default-level` + /// Set the default repository access level for Dependabot in an enterprise + static const dependabotSetRepositoryAccessDefaultLevelForEnterprise = + RestOperationContract( + operationId: + 'dependabot/set-repository-access-default-level-for-enterprise', + method: 'PUT', + path: + '/enterprises/{enterprise}/dependabot/repository-access/default-level', + pathParams: ['enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/dependabot/secrets/{secret_name}/repositories` + /// Set selected repositories for an organization secret + static const dependabotSetSelectedReposForOrgSecret = RestOperationContract( + operationId: 'dependabot/set-selected-repos-for-org-secret', + method: 'PUT', + path: '/orgs/{org}/dependabot/secrets/{secret_name}/repositories', + pathParams: ['org', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PATCH /repos/{owner}/{repo}/dependabot/alerts/{alert_number}` + /// Update a Dependabot alert + static const dependabotUpdateAlert = RestOperationContract( + operationId: 'dependabot/update-alert', + method: 'PATCH', + path: '/repos/{owner}/{repo}/dependabot/alerts/{alert_number}', + pathParams: ['alert_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /enterprises/{enterprise}/dependabot/repository-access` + /// Updates Dependabot's repository access list for an enterprise + static const dependabotUpdateRepositoryAccessForEnterprise = + RestOperationContract( + operationId: 'dependabot/update-repository-access-for-enterprise', + method: 'PATCH', + path: '/enterprises/{enterprise}/dependabot/repository-access', + pathParams: ['enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PATCH /orgs/{org}/dependabot/repository-access` + /// Updates Dependabot's repository access list for an organization + static const dependabotUpdateRepositoryAccessForOrg = RestOperationContract( + operationId: 'dependabot/update-repository-access-for-org', + method: 'PATCH', + path: '/orgs/{org}/dependabot/repository-access', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/dependency-graph/snapshots` + /// Create a snapshot of dependencies for a repository + static const dependencyGraphCreateRepositorySnapshot = RestOperationContract( + operationId: 'dependency-graph/create-repository-snapshot', + method: 'POST', + path: '/repos/{owner}/{repo}/dependency-graph/snapshots', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `GET /repos/{owner}/{repo}/dependency-graph/compare/{basehead}` + /// Get a diff of the dependencies between commits + static const dependencyGraphDiffRange = RestOperationContract( + operationId: 'dependency-graph/diff-range', + method: 'GET', + path: '/repos/{owner}/{repo}/dependency-graph/compare/{basehead}', + pathParams: ['basehead', 'owner', 'repo'], + queryParams: ['name'], + ); + + /// `GET /repos/{owner}/{repo}/dependency-graph/sbom` + /// Export a software bill of materials (SBOM) for a repository. + static const dependencyGraphExportSbom = RestOperationContract( + operationId: 'dependency-graph/export-sbom', + method: 'GET', + path: '/repos/{owner}/{repo}/dependency-graph/sbom', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/dependency-graph/sbom/fetch-report/{sbom_uuid}` + /// Fetch a software bill of materials (SBOM) for a repository. + static const dependencyGraphFetchSbomReport = RestOperationContract( + operationId: 'dependency-graph/fetch-sbom-report', + method: 'GET', + path: + '/repos/{owner}/{repo}/dependency-graph/sbom/fetch-report/{sbom_uuid}', + pathParams: ['owner', 'repo', 'sbom_uuid'], + successStatuses: [202], + ); + + /// `GET /repos/{owner}/{repo}/dependency-graph/sbom/generate-report` + /// Request generation of a software bill of materials (SBOM) for a repository. + static const dependencyGraphGenerateSbomReport = RestOperationContract( + operationId: 'dependency-graph/generate-sbom-report', + method: 'GET', + path: '/repos/{owner}/{repo}/dependency-graph/sbom/generate-report', + pathParams: ['owner', 'repo'], + successStatuses: [201], + ); + + /// `GET /emojis` + /// Get emojis + static const emojisGet = RestOperationContract( + operationId: 'emojis/get', + method: 'GET', + path: '/emojis', + ); + + /// `PUT /enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username}` + /// Add team member + static const enterpriseTeamMembershipsAdd = RestOperationContract( + operationId: 'enterprise-team-memberships/add', + method: 'PUT', + path: + '/enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username}', + pathParams: ['enterprise', 'enterprise-team', 'username'], + successStatuses: [201], + ); + + /// `POST /enterprises/{enterprise}/teams/{enterprise-team}/memberships/add` + /// Bulk add team members + static const enterpriseTeamMembershipsBulkAdd = RestOperationContract( + operationId: 'enterprise-team-memberships/bulk-add', + method: 'POST', + path: '/enterprises/{enterprise}/teams/{enterprise-team}/memberships/add', + pathParams: ['enterprise', 'enterprise-team'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /enterprises/{enterprise}/teams/{enterprise-team}/memberships/remove` + /// Bulk remove team members + static const enterpriseTeamMembershipsBulkRemove = RestOperationContract( + operationId: 'enterprise-team-memberships/bulk-remove', + method: 'POST', + path: + '/enterprises/{enterprise}/teams/{enterprise-team}/memberships/remove', + pathParams: ['enterprise', 'enterprise-team'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username}` + /// Get enterprise team membership + static const enterpriseTeamMembershipsGet = RestOperationContract( + operationId: 'enterprise-team-memberships/get', + method: 'GET', + path: + '/enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username}', + pathParams: ['enterprise', 'enterprise-team', 'username'], + ); + + /// `GET /enterprises/{enterprise}/teams/{enterprise-team}/memberships` + /// List members in an enterprise team + static const enterpriseTeamMembershipsList = RestOperationContract( + operationId: 'enterprise-team-memberships/list', + method: 'GET', + path: '/enterprises/{enterprise}/teams/{enterprise-team}/memberships', + pathParams: ['enterprise', 'enterprise-team'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /enterprises/{enterprise}/members/{username}/teams` + /// List enterprise teams for a user + static const enterpriseTeamMembershipsListTeamsForUser = + RestOperationContract( + operationId: 'enterprise-team-memberships/list-teams-for-user', + method: 'GET', + path: '/enterprises/{enterprise}/members/{username}/teams', + pathParams: ['enterprise', 'username'], + queryParams: ['page', 'per_page'], + ); + + /// `DELETE /enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username}` + /// Remove team membership + static const enterpriseTeamMembershipsRemove = RestOperationContract( + operationId: 'enterprise-team-memberships/remove', + method: 'DELETE', + path: + '/enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username}', + pathParams: ['enterprise', 'enterprise-team', 'username'], + successStatuses: [204], + ); + + /// `PUT /enterprises/{enterprise}/teams/{enterprise-team}/organizations/{org}` + /// Add an organization assignment + static const enterpriseTeamOrganizationsAdd = RestOperationContract( + operationId: 'enterprise-team-organizations/add', + method: 'PUT', + path: + '/enterprises/{enterprise}/teams/{enterprise-team}/organizations/{org}', + pathParams: ['enterprise', 'enterprise-team', 'org'], + successStatuses: [201], + ); + + /// `POST /enterprises/{enterprise}/teams/{enterprise-team}/organizations/add` + /// Add organization assignments + static const enterpriseTeamOrganizationsBulkAdd = RestOperationContract( + operationId: 'enterprise-team-organizations/bulk-add', + method: 'POST', + path: '/enterprises/{enterprise}/teams/{enterprise-team}/organizations/add', + pathParams: ['enterprise', 'enterprise-team'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /enterprises/{enterprise}/teams/{enterprise-team}/organizations/remove` + /// Remove organization assignments + static const enterpriseTeamOrganizationsBulkRemove = RestOperationContract( + operationId: 'enterprise-team-organizations/bulk-remove', + method: 'POST', + path: + '/enterprises/{enterprise}/teams/{enterprise-team}/organizations/remove', + pathParams: ['enterprise', 'enterprise-team'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `DELETE /enterprises/{enterprise}/teams/{enterprise-team}/organizations/{org}` + /// Delete an organization assignment + static const enterpriseTeamOrganizationsDelete = RestOperationContract( + operationId: 'enterprise-team-organizations/delete', + method: 'DELETE', + path: + '/enterprises/{enterprise}/teams/{enterprise-team}/organizations/{org}', + pathParams: ['enterprise', 'enterprise-team', 'org'], + successStatuses: [204], + ); + + /// `GET /enterprises/{enterprise}/teams/{enterprise-team}/organizations/{org}` + /// Get organization assignment + static const enterpriseTeamOrganizationsGetAssignment = RestOperationContract( + operationId: 'enterprise-team-organizations/get-assignment', + method: 'GET', + path: + '/enterprises/{enterprise}/teams/{enterprise-team}/organizations/{org}', + pathParams: ['enterprise', 'enterprise-team', 'org'], + ); + + /// `GET /enterprises/{enterprise}/teams/{enterprise-team}/organizations` + /// Get organization assignments + static const enterpriseTeamOrganizationsGetAssignments = + RestOperationContract( + operationId: 'enterprise-team-organizations/get-assignments', + method: 'GET', + path: '/enterprises/{enterprise}/teams/{enterprise-team}/organizations', + pathParams: ['enterprise', 'enterprise-team'], + queryParams: ['page', 'per_page'], + ); + + /// `POST /enterprises/{enterprise}/teams` + /// Create an enterprise team + static const enterpriseTeamsCreate = RestOperationContract( + operationId: 'enterprise-teams/create', + method: 'POST', + path: '/enterprises/{enterprise}/teams', + pathParams: ['enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /enterprises/{enterprise}/teams/{team_slug}` + /// Delete an enterprise team + static const enterpriseTeamsDelete = RestOperationContract( + operationId: 'enterprise-teams/delete', + method: 'DELETE', + path: '/enterprises/{enterprise}/teams/{team_slug}', + pathParams: ['enterprise', 'team_slug'], + successStatuses: [204], + ); + + /// `GET /enterprises/{enterprise}/teams/{team_slug}` + /// Get an enterprise team + static const enterpriseTeamsGet = RestOperationContract( + operationId: 'enterprise-teams/get', + method: 'GET', + path: '/enterprises/{enterprise}/teams/{team_slug}', + pathParams: ['enterprise', 'team_slug'], + ); + + /// `GET /enterprises/{enterprise}/teams` + /// List enterprise teams + static const enterpriseTeamsList = RestOperationContract( + operationId: 'enterprise-teams/list', + method: 'GET', + path: '/enterprises/{enterprise}/teams', + pathParams: ['enterprise'], + queryParams: ['page', 'per_page'], + ); + + /// `PATCH /enterprises/{enterprise}/teams/{team_slug}` + /// Update an enterprise team + static const enterpriseTeamsUpdate = RestOperationContract( + operationId: 'enterprise-teams/update', + method: 'PATCH', + path: '/enterprises/{enterprise}/teams/{team_slug}', + pathParams: ['enterprise', 'team_slug'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /gists/{gist_id}/star` + /// Check if a gist is starred + static const gistsCheckIsStarred = RestOperationContract( + operationId: 'gists/check-is-starred', + method: 'GET', + path: '/gists/{gist_id}/star', + pathParams: ['gist_id'], + successStatuses: [204], + ); + + /// `POST /gists` + /// Create a gist + static const gistsCreate = RestOperationContract( + operationId: 'gists/create', + method: 'POST', + path: '/gists', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /gists/{gist_id}/comments` + /// Create a gist comment + static const gistsCreateComment = RestOperationContract( + operationId: 'gists/create-comment', + method: 'POST', + path: '/gists/{gist_id}/comments', + pathParams: ['gist_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /gists/{gist_id}` + /// Delete a gist + static const gistsDelete = RestOperationContract( + operationId: 'gists/delete', + method: 'DELETE', + path: '/gists/{gist_id}', + pathParams: ['gist_id'], + successStatuses: [204], + ); + + /// `DELETE /gists/{gist_id}/comments/{comment_id}` + /// Delete a gist comment + static const gistsDeleteComment = RestOperationContract( + operationId: 'gists/delete-comment', + method: 'DELETE', + path: '/gists/{gist_id}/comments/{comment_id}', + pathParams: ['comment_id', 'gist_id'], + successStatuses: [204], + ); + + /// `POST /gists/{gist_id}/forks` + /// Fork a gist + static const gistsFork = RestOperationContract( + operationId: 'gists/fork', + method: 'POST', + path: '/gists/{gist_id}/forks', + pathParams: ['gist_id'], + successStatuses: [201], + ); + + /// `GET /gists/{gist_id}` + /// Get a gist + static const gistsGet = RestOperationContract( + operationId: 'gists/get', + method: 'GET', + path: '/gists/{gist_id}', + pathParams: ['gist_id'], + ); + + /// `GET /gists/{gist_id}/comments/{comment_id}` + /// Get a gist comment + static const gistsGetComment = RestOperationContract( + operationId: 'gists/get-comment', + method: 'GET', + path: '/gists/{gist_id}/comments/{comment_id}', + pathParams: ['comment_id', 'gist_id'], + ); + + /// `GET /gists/{gist_id}/{sha}` + /// Get a gist revision + static const gistsGetRevision = RestOperationContract( + operationId: 'gists/get-revision', + method: 'GET', + path: '/gists/{gist_id}/{sha}', + pathParams: ['gist_id', 'sha'], + ); + + /// `GET /gists` + /// List gists for the authenticated user + static const gistsList = RestOperationContract( + operationId: 'gists/list', + method: 'GET', + path: '/gists', + queryParams: ['page', 'per_page', 'since'], + ); + + /// `GET /gists/{gist_id}/comments` + /// List gist comments + static const gistsListComments = RestOperationContract( + operationId: 'gists/list-comments', + method: 'GET', + path: '/gists/{gist_id}/comments', + pathParams: ['gist_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /gists/{gist_id}/commits` + /// List gist commits + static const gistsListCommits = RestOperationContract( + operationId: 'gists/list-commits', + method: 'GET', + path: '/gists/{gist_id}/commits', + pathParams: ['gist_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /users/{username}/gists` + /// List gists for a user + static const gistsListForUser = RestOperationContract( + operationId: 'gists/list-for-user', + method: 'GET', + path: '/users/{username}/gists', + pathParams: ['username'], + queryParams: ['page', 'per_page', 'since'], + ); + + /// `GET /gists/{gist_id}/forks` + /// List gist forks + static const gistsListForks = RestOperationContract( + operationId: 'gists/list-forks', + method: 'GET', + path: '/gists/{gist_id}/forks', + pathParams: ['gist_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /gists/public` + /// List public gists + static const gistsListPublic = RestOperationContract( + operationId: 'gists/list-public', + method: 'GET', + path: '/gists/public', + queryParams: ['page', 'per_page', 'since'], + ); + + /// `GET /gists/starred` + /// List starred gists + static const gistsListStarred = RestOperationContract( + operationId: 'gists/list-starred', + method: 'GET', + path: '/gists/starred', + queryParams: ['page', 'per_page', 'since'], + ); + + /// `PUT /gists/{gist_id}/star` + /// Star a gist + static const gistsStar = RestOperationContract( + operationId: 'gists/star', + method: 'PUT', + path: '/gists/{gist_id}/star', + pathParams: ['gist_id'], + successStatuses: [204], + ); + + /// `DELETE /gists/{gist_id}/star` + /// Unstar a gist + static const gistsUnstar = RestOperationContract( + operationId: 'gists/unstar', + method: 'DELETE', + path: '/gists/{gist_id}/star', + pathParams: ['gist_id'], + successStatuses: [204], + ); + + /// `PATCH /gists/{gist_id}` + /// Update a gist + static const gistsUpdate = RestOperationContract( + operationId: 'gists/update', + method: 'PATCH', + path: '/gists/{gist_id}', + pathParams: ['gist_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /gists/{gist_id}/comments/{comment_id}` + /// Update a gist comment + static const gistsUpdateComment = RestOperationContract( + operationId: 'gists/update-comment', + method: 'PATCH', + path: '/gists/{gist_id}/comments/{comment_id}', + pathParams: ['comment_id', 'gist_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/git/blobs` + /// Create a blob + static const gitCreateBlob = RestOperationContract( + operationId: 'git/create-blob', + method: 'POST', + path: '/repos/{owner}/{repo}/git/blobs', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/git/commits` + /// Create a commit + static const gitCreateCommit = RestOperationContract( + operationId: 'git/create-commit', + method: 'POST', + path: '/repos/{owner}/{repo}/git/commits', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/git/refs` + /// Create a reference + static const gitCreateRef = RestOperationContract( + operationId: 'git/create-ref', + method: 'POST', + path: '/repos/{owner}/{repo}/git/refs', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/git/tags` + /// Create a tag object + static const gitCreateTag = RestOperationContract( + operationId: 'git/create-tag', + method: 'POST', + path: '/repos/{owner}/{repo}/git/tags', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/git/trees` + /// Create a tree + static const gitCreateTree = RestOperationContract( + operationId: 'git/create-tree', + method: 'POST', + path: '/repos/{owner}/{repo}/git/trees', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /repos/{owner}/{repo}/git/refs/{ref}` + /// Delete a reference + static const gitDeleteRef = RestOperationContract( + operationId: 'git/delete-ref', + method: 'DELETE', + path: '/repos/{owner}/{repo}/git/refs/{ref}', + pathParams: ['owner', 'ref', 'repo'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/git/blobs/{file_sha}` + /// Get a blob + static const gitGetBlob = RestOperationContract( + operationId: 'git/get-blob', + method: 'GET', + path: '/repos/{owner}/{repo}/git/blobs/{file_sha}', + pathParams: ['file_sha', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/git/commits/{commit_sha}` + /// Get a commit object + static const gitGetCommit = RestOperationContract( + operationId: 'git/get-commit', + method: 'GET', + path: '/repos/{owner}/{repo}/git/commits/{commit_sha}', + pathParams: ['commit_sha', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/git/ref/{ref}` + /// Get a reference + static const gitGetRef = RestOperationContract( + operationId: 'git/get-ref', + method: 'GET', + path: '/repos/{owner}/{repo}/git/ref/{ref}', + pathParams: ['owner', 'ref', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/git/tags/{tag_sha}` + /// Get a tag + static const gitGetTag = RestOperationContract( + operationId: 'git/get-tag', + method: 'GET', + path: '/repos/{owner}/{repo}/git/tags/{tag_sha}', + pathParams: ['owner', 'repo', 'tag_sha'], + ); + + /// `GET /repos/{owner}/{repo}/git/trees/{tree_sha}` + /// Get a tree + static const gitGetTree = RestOperationContract( + operationId: 'git/get-tree', + method: 'GET', + path: '/repos/{owner}/{repo}/git/trees/{tree_sha}', + pathParams: ['owner', 'repo', 'tree_sha'], + queryParams: ['recursive'], + ); + + /// `GET /repos/{owner}/{repo}/git/matching-refs/{ref}` + /// List matching references + static const gitListMatchingRefs = RestOperationContract( + operationId: 'git/list-matching-refs', + method: 'GET', + path: '/repos/{owner}/{repo}/git/matching-refs/{ref}', + pathParams: ['owner', 'ref', 'repo'], + ); + + /// `PATCH /repos/{owner}/{repo}/git/refs/{ref}` + /// Update a reference + static const gitUpdateRef = RestOperationContract( + operationId: 'git/update-ref', + method: 'PATCH', + path: '/repos/{owner}/{repo}/git/refs/{ref}', + pathParams: ['owner', 'ref', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /gitignore/templates` + /// Get all gitignore templates + static const gitignoreGetAllTemplates = RestOperationContract( + operationId: 'gitignore/get-all-templates', + method: 'GET', + path: '/gitignore/templates', + ); + + /// `GET /gitignore/templates/{name}` + /// Get a gitignore template + static const gitignoreGetTemplate = RestOperationContract( + operationId: 'gitignore/get-template', + method: 'GET', + path: '/gitignore/templates/{name}', + pathParams: ['name'], + ); + + /// `POST /orgs/{org}/settings/network-configurations` + /// Create a hosted compute network configuration for an organization + static const hostedComputeCreateNetworkConfigurationForOrg = + RestOperationContract( + operationId: 'hosted-compute/create-network-configuration-for-org', + method: 'POST', + path: '/orgs/{org}/settings/network-configurations', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /orgs/{org}/settings/network-configurations/{network_configuration_id}` + /// Delete a hosted compute network configuration from an organization + static const hostedComputeDeleteNetworkConfigurationFromOrg = + RestOperationContract( + operationId: 'hosted-compute/delete-network-configuration-from-org', + method: 'DELETE', + path: + '/orgs/{org}/settings/network-configurations/{network_configuration_id}', + pathParams: ['network_configuration_id', 'org'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/settings/network-configurations/{network_configuration_id}` + /// Get a hosted compute network configuration for an organization + static const hostedComputeGetNetworkConfigurationForOrg = + RestOperationContract( + operationId: 'hosted-compute/get-network-configuration-for-org', + method: 'GET', + path: + '/orgs/{org}/settings/network-configurations/{network_configuration_id}', + pathParams: ['network_configuration_id', 'org'], + ); + + /// `GET /orgs/{org}/settings/network-settings/{network_settings_id}` + /// Get a hosted compute network settings resource for an organization + static const hostedComputeGetNetworkSettingsForOrg = RestOperationContract( + operationId: 'hosted-compute/get-network-settings-for-org', + method: 'GET', + path: '/orgs/{org}/settings/network-settings/{network_settings_id}', + pathParams: ['network_settings_id', 'org'], + ); + + /// `GET /orgs/{org}/settings/network-configurations` + /// List hosted compute network configurations for an organization + static const hostedComputeListNetworkConfigurationsForOrg = + RestOperationContract( + operationId: 'hosted-compute/list-network-configurations-for-org', + method: 'GET', + path: '/orgs/{org}/settings/network-configurations', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `PATCH /orgs/{org}/settings/network-configurations/{network_configuration_id}` + /// Update a hosted compute network configuration for an organization + static const hostedComputeUpdateNetworkConfigurationForOrg = + RestOperationContract( + operationId: 'hosted-compute/update-network-configuration-for-org', + method: 'PATCH', + path: + '/orgs/{org}/settings/network-configurations/{network_configuration_id}', + pathParams: ['network_configuration_id', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /repos/{owner}/{repo}/interaction-limits/pulls/bypass-list` + /// Get pull request creation cap bypass list for a repository + static const interactionsGetPullRequestBypassListForRepo = + RestOperationContract( + operationId: 'interactions/get-pull-request-bypass-list-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/interaction-limits/pulls/bypass-list', + pathParams: ['owner', 'repo'], + ); + + /// `GET /orgs/{org}/interaction-limits/pulls/creation-cap` + /// Get pull request creation cap for an org + static const interactionsGetPullRequestCreationCapForOrg = + RestOperationContract( + operationId: 'interactions/get-pull-request-creation-cap-for-org', + method: 'GET', + path: '/orgs/{org}/interaction-limits/pulls/creation-cap', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/interaction-limits/pulls/creation-cap` + /// Get pull request creation cap for a repository + static const interactionsGetPullRequestCreationCapForRepo = + RestOperationContract( + operationId: 'interactions/get-pull-request-creation-cap-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/interaction-limits/pulls/creation-cap', + pathParams: ['owner', 'repo'], + ); + + /// `GET /user/interaction-limits` + /// Get interaction restrictions for your public repositories + static const interactionsGetRestrictionsForAuthenticatedUser = + RestOperationContract( + operationId: 'interactions/get-restrictions-for-authenticated-user', + method: 'GET', + path: '/user/interaction-limits', + successStatuses: [200, 204], + ); + + /// `GET /orgs/{org}/interaction-limits` + /// Get interaction restrictions for an organization + static const interactionsGetRestrictionsForOrg = RestOperationContract( + operationId: 'interactions/get-restrictions-for-org', + method: 'GET', + path: '/orgs/{org}/interaction-limits', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/interaction-limits` + /// Get interaction restrictions for a repository + static const interactionsGetRestrictionsForRepo = RestOperationContract( + operationId: 'interactions/get-restrictions-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/interaction-limits', + pathParams: ['owner', 'repo'], + ); + + /// `DELETE /repos/{owner}/{repo}/interaction-limits/pulls/bypass-list` + /// Remove users from the pull request creation cap bypass list for a repository + static const interactionsRemovePullRequestBypassListForRepo = + RestOperationContract( + operationId: 'interactions/remove-pull-request-bypass-list-for-repo', + method: 'DELETE', + path: '/repos/{owner}/{repo}/interaction-limits/pulls/bypass-list', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `DELETE /user/interaction-limits` + /// Remove interaction restrictions from your public repositories + static const interactionsRemoveRestrictionsForAuthenticatedUser = + RestOperationContract( + operationId: 'interactions/remove-restrictions-for-authenticated-user', + method: 'DELETE', + path: '/user/interaction-limits', + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/interaction-limits` + /// Remove interaction restrictions for an organization + static const interactionsRemoveRestrictionsForOrg = RestOperationContract( + operationId: 'interactions/remove-restrictions-for-org', + method: 'DELETE', + path: '/orgs/{org}/interaction-limits', + pathParams: ['org'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/interaction-limits` + /// Remove interaction restrictions for a repository + static const interactionsRemoveRestrictionsForRepo = RestOperationContract( + operationId: 'interactions/remove-restrictions-for-repo', + method: 'DELETE', + path: '/repos/{owner}/{repo}/interaction-limits', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/interaction-limits/pulls/bypass-list` + /// Add users to the pull request creation cap bypass list for a repository + static const interactionsSetPullRequestBypassListForRepo = + RestOperationContract( + operationId: 'interactions/set-pull-request-bypass-list-for-repo', + method: 'PUT', + path: '/repos/{owner}/{repo}/interaction-limits/pulls/bypass-list', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /user/interaction-limits` + /// Set interaction restrictions for your public repositories + static const interactionsSetRestrictionsForAuthenticatedUser = + RestOperationContract( + operationId: 'interactions/set-restrictions-for-authenticated-user', + method: 'PUT', + path: '/user/interaction-limits', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /orgs/{org}/interaction-limits` + /// Set interaction restrictions for an organization + static const interactionsSetRestrictionsForOrg = RestOperationContract( + operationId: 'interactions/set-restrictions-for-org', + method: 'PUT', + path: '/orgs/{org}/interaction-limits', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/interaction-limits` + /// Set interaction restrictions for a repository + static const interactionsSetRestrictionsForRepo = RestOperationContract( + operationId: 'interactions/set-restrictions-for-repo', + method: 'PUT', + path: '/repos/{owner}/{repo}/interaction-limits', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /orgs/{org}/interaction-limits/pulls/creation-cap` + /// Update pull request creation cap for an org + static const interactionsUpdatePullRequestCreationCapForOrg = + RestOperationContract( + operationId: 'interactions/update-pull-request-creation-cap-for-org', + method: 'PATCH', + path: '/orgs/{org}/interaction-limits/pulls/creation-cap', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/interaction-limits/pulls/creation-cap` + /// Update pull request creation cap for a repository + static const interactionsUpdatePullRequestCreationCapForRepo = + RestOperationContract( + operationId: 'interactions/update-pull-request-creation-cap-for-repo', + method: 'PATCH', + path: '/repos/{owner}/{repo}/interaction-limits/pulls/creation-cap', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/issues/{issue_number}/assignees` + /// Add assignees to an issue + static const issuesAddAssignees = RestOperationContract( + operationId: 'issues/add-assignees', + method: 'POST', + path: '/repos/{owner}/{repo}/issues/{issue_number}/assignees', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by` + /// Add a dependency an issue is blocked by + static const issuesAddBlockedByDependency = RestOperationContract( + operationId: 'issues/add-blocked-by-dependency', + method: 'POST', + path: '/repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/issues/{issue_number}/issue-field-values` + /// Add issue field values to an issue + static const issuesAddIssueFieldValues = RestOperationContract( + operationId: 'issues/add-issue-field-values', + method: 'POST', + path: '/repos/{owner}/{repo}/issues/{issue_number}/issue-field-values', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/issues/{issue_number}/labels` + /// Add labels to an issue + static const issuesAddLabels = RestOperationContract( + operationId: 'issues/add-labels', + method: 'POST', + path: '/repos/{owner}/{repo}/issues/{issue_number}/labels', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/issues/{issue_number}/sub_issues` + /// Add sub-issue + static const issuesAddSubIssue = RestOperationContract( + operationId: 'issues/add-sub-issue', + method: 'POST', + path: '/repos/{owner}/{repo}/issues/{issue_number}/sub_issues', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/issues/{issue_number}/suggestions/{suggestion_id}/approve` + /// Approve an issue suggestion + static const issuesApproveSuggestion = RestOperationContract( + operationId: 'issues/approve-suggestion', + method: 'POST', + path: + '/repos/{owner}/{repo}/issues/{issue_number}/suggestions/{suggestion_id}/approve', + pathParams: ['issue_number', 'owner', 'repo', 'suggestion_id'], + ); + + /// `GET /repos/{owner}/{repo}/assignees/{assignee}` + /// Check if a user can be assigned + static const issuesCheckUserCanBeAssigned = RestOperationContract( + operationId: 'issues/check-user-can-be-assigned', + method: 'GET', + path: '/repos/{owner}/{repo}/assignees/{assignee}', + pathParams: ['assignee', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}/assignees/{assignee}` + /// Check if a user can be assigned to a issue + static const issuesCheckUserCanBeAssignedToIssue = RestOperationContract( + operationId: 'issues/check-user-can-be-assigned-to-issue', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}/assignees/{assignee}', + pathParams: ['assignee', 'issue_number', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/issues` + /// Create an issue + static const issuesCreate = RestOperationContract( + operationId: 'issues/create', + method: 'POST', + path: '/repos/{owner}/{repo}/issues', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/issues/{issue_number}/comments` + /// Create an issue comment + static const issuesCreateComment = RestOperationContract( + operationId: 'issues/create-comment', + method: 'POST', + path: '/repos/{owner}/{repo}/issues/{issue_number}/comments', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/labels` + /// Create a label + static const issuesCreateLabel = RestOperationContract( + operationId: 'issues/create-label', + method: 'POST', + path: '/repos/{owner}/{repo}/labels', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/milestones` + /// Create a milestone + static const issuesCreateMilestone = RestOperationContract( + operationId: 'issues/create-milestone', + method: 'POST', + path: '/repos/{owner}/{repo}/milestones', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}` + /// Delete an issue comment + static const issuesDeleteComment = RestOperationContract( + operationId: 'issues/delete-comment', + method: 'DELETE', + path: '/repos/{owner}/{repo}/issues/comments/{comment_id}', + pathParams: ['comment_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/issues/{issue_number}/issue-field-values/{issue_field_id}` + /// Delete an issue field value from an issue + static const issuesDeleteIssueFieldValue = RestOperationContract( + operationId: 'issues/delete-issue-field-value', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/issues/{issue_number}/issue-field-values/{issue_field_id}', + pathParams: ['issue_field_id', 'issue_number', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/labels/{name}` + /// Delete a label + static const issuesDeleteLabel = RestOperationContract( + operationId: 'issues/delete-label', + method: 'DELETE', + path: '/repos/{owner}/{repo}/labels/{name}', + pathParams: ['name', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/milestones/{milestone_number}` + /// Delete a milestone + static const issuesDeleteMilestone = RestOperationContract( + operationId: 'issues/delete-milestone', + method: 'DELETE', + path: '/repos/{owner}/{repo}/milestones/{milestone_number}', + pathParams: ['milestone_number', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/issues/{issue_number}/suggestions/{suggestion_id}/dismiss` + /// Dismiss an issue suggestion + static const issuesDismissSuggestion = RestOperationContract( + operationId: 'issues/dismiss-suggestion', + method: 'POST', + path: + '/repos/{owner}/{repo}/issues/{issue_number}/suggestions/{suggestion_id}/dismiss', + pathParams: ['issue_number', 'owner', 'repo', 'suggestion_id'], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}` + /// Get an issue + static const issuesGet = RestOperationContract( + operationId: 'issues/get', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}', + pathParams: ['issue_number', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/issues/comments/{comment_id}` + /// Get an issue comment + static const issuesGetComment = RestOperationContract( + operationId: 'issues/get-comment', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/comments/{comment_id}', + pathParams: ['comment_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/issues/events/{event_id}` + /// Get an issue event + static const issuesGetEvent = RestOperationContract( + operationId: 'issues/get-event', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/events/{event_id}', + pathParams: ['event_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/labels/{name}` + /// Get a label + static const issuesGetLabel = RestOperationContract( + operationId: 'issues/get-label', + method: 'GET', + path: '/repos/{owner}/{repo}/labels/{name}', + pathParams: ['name', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/milestones/{milestone_number}` + /// Get a milestone + static const issuesGetMilestone = RestOperationContract( + operationId: 'issues/get-milestone', + method: 'GET', + path: '/repos/{owner}/{repo}/milestones/{milestone_number}', + pathParams: ['milestone_number', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}/parent` + /// Get parent issue + static const issuesGetParent = RestOperationContract( + operationId: 'issues/get-parent', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}/parent', + pathParams: ['issue_number', 'owner', 'repo'], + ); + + /// `GET /issues` + /// List issues assigned to the authenticated user + static const issuesList = RestOperationContract( + operationId: 'issues/list', + method: 'GET', + path: '/issues', + queryParams: [ + 'collab', + 'direction', + 'filter', + 'labels', + 'orgs', + 'owned', + 'page', + 'per_page', + 'pulls', + 'since', + 'sort', + 'state' + ], + ); + + /// `GET /repos/{owner}/{repo}/assignees` + /// List assignees + static const issuesListAssignees = RestOperationContract( + operationId: 'issues/list-assignees', + method: 'GET', + path: '/repos/{owner}/{repo}/assignees', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}/comments` + /// List issue comments + static const issuesListComments = RestOperationContract( + operationId: 'issues/list-comments', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}/comments', + pathParams: ['issue_number', 'owner', 'repo'], + queryParams: ['page', 'per_page', 'since'], + ); + + /// `GET /repos/{owner}/{repo}/issues/comments` + /// List issue comments for a repository + static const issuesListCommentsForRepo = RestOperationContract( + operationId: 'issues/list-comments-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/comments', + pathParams: ['owner', 'repo'], + queryParams: ['direction', 'page', 'per_page', 'since', 'sort'], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by` + /// List dependencies an issue is blocked by + static const issuesListDependenciesBlockedBy = RestOperationContract( + operationId: 'issues/list-dependencies-blocked-by', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by', + pathParams: ['issue_number', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocking` + /// List dependencies an issue is blocking + static const issuesListDependenciesBlocking = RestOperationContract( + operationId: 'issues/list-dependencies-blocking', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocking', + pathParams: ['issue_number', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}/events` + /// List issue events + static const issuesListEvents = RestOperationContract( + operationId: 'issues/list-events', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}/events', + pathParams: ['issue_number', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/issues/events` + /// List issue events for a repository + static const issuesListEventsForRepo = RestOperationContract( + operationId: 'issues/list-events-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/events', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}/timeline` + /// List timeline events for an issue + static const issuesListEventsForTimeline = RestOperationContract( + operationId: 'issues/list-events-for-timeline', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}/timeline', + pathParams: ['issue_number', 'owner', 'repo'], + queryParams: ['exclude', 'page', 'per_page'], + ); + + /// `GET /user/issues` + /// List user account issues assigned to the authenticated user + static const issuesListForAuthenticatedUser = RestOperationContract( + operationId: 'issues/list-for-authenticated-user', + method: 'GET', + path: '/user/issues', + queryParams: [ + 'direction', + 'filter', + 'labels', + 'page', + 'per_page', + 'since', + 'sort', + 'state' + ], + ); + + /// `GET /orgs/{org}/issues` + /// List organization issues assigned to the authenticated user + static const issuesListForOrg = RestOperationContract( + operationId: 'issues/list-for-org', + method: 'GET', + path: '/orgs/{org}/issues', + pathParams: ['org'], + queryParams: [ + 'direction', + 'filter', + 'labels', + 'page', + 'per_page', + 'since', + 'sort', + 'state', + 'type' + ], + ); + + /// `GET /repos/{owner}/{repo}/issues` + /// List repository issues + static const issuesListForRepo = RestOperationContract( + operationId: 'issues/list-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/issues', + pathParams: ['owner', 'repo'], + queryParams: [ + 'assignee', + 'creator', + 'direction', + 'issue_field_values', + 'labels', + 'mentioned', + 'milestone', + 'page', + 'per_page', + 'since', + 'sort', + 'state', + 'type' + ], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}/issue-field-values` + /// List issue field values for an issue + static const issuesListIssueFieldValuesForIssue = RestOperationContract( + operationId: 'issues/list-issue-field-values-for-issue', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}/issue-field-values', + pathParams: ['issue_number', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels` + /// List labels for issues in a milestone + static const issuesListLabelsForMilestone = RestOperationContract( + operationId: 'issues/list-labels-for-milestone', + method: 'GET', + path: '/repos/{owner}/{repo}/milestones/{milestone_number}/labels', + pathParams: ['milestone_number', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/labels` + /// List labels for a repository + static const issuesListLabelsForRepo = RestOperationContract( + operationId: 'issues/list-labels-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/labels', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}/labels` + /// List labels for an issue + static const issuesListLabelsOnIssue = RestOperationContract( + operationId: 'issues/list-labels-on-issue', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}/labels', + pathParams: ['issue_number', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/milestones` + /// List milestones + static const issuesListMilestones = RestOperationContract( + operationId: 'issues/list-milestones', + method: 'GET', + path: '/repos/{owner}/{repo}/milestones', + pathParams: ['owner', 'repo'], + queryParams: ['direction', 'page', 'per_page', 'sort', 'state'], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}/sub_issues` + /// List sub-issues + static const issuesListSubIssues = RestOperationContract( + operationId: 'issues/list-sub-issues', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}/sub_issues', + pathParams: ['issue_number', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}/suggestions` + /// List issue suggestions + static const issuesListSuggestions = RestOperationContract( + operationId: 'issues/list-suggestions', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}/suggestions', + pathParams: ['issue_number', 'owner', 'repo'], + queryParams: ['action', 'page', 'per_page', 'state'], + ); + + /// `PUT /repos/{owner}/{repo}/issues/{issue_number}/lock` + /// Lock an issue + static const issuesLock = RestOperationContract( + operationId: 'issues/lock', + method: 'PUT', + path: '/repos/{owner}/{repo}/issues/{issue_number}/lock', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/issues/comments/{comment_id}/pin` + /// Pin an issue comment + static const issuesPinComment = RestOperationContract( + operationId: 'issues/pin-comment', + method: 'PUT', + path: '/repos/{owner}/{repo}/issues/comments/{comment_id}/pin', + pathParams: ['comment_id', 'owner', 'repo'], + ); + + /// `DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels` + /// Remove all labels from an issue + static const issuesRemoveAllLabels = RestOperationContract( + operationId: 'issues/remove-all-labels', + method: 'DELETE', + path: '/repos/{owner}/{repo}/issues/{issue_number}/labels', + pathParams: ['issue_number', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/issues/{issue_number}/assignees` + /// Remove assignees from an issue + static const issuesRemoveAssignees = RestOperationContract( + operationId: 'issues/remove-assignees', + method: 'DELETE', + path: '/repos/{owner}/{repo}/issues/{issue_number}/assignees', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by/{issue_id}` + /// Remove dependency an issue is blocked by + static const issuesRemoveDependencyBlockedBy = RestOperationContract( + operationId: 'issues/remove-dependency-blocked-by', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by/{issue_id}', + pathParams: ['issue_id', 'issue_number', 'owner', 'repo'], + ); + + /// `DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}` + /// Remove a label from an issue + static const issuesRemoveLabel = RestOperationContract( + operationId: 'issues/remove-label', + method: 'DELETE', + path: '/repos/{owner}/{repo}/issues/{issue_number}/labels/{name}', + pathParams: ['issue_number', 'name', 'owner', 'repo'], + ); + + /// `DELETE /repos/{owner}/{repo}/issues/{issue_number}/sub_issue` + /// Remove sub-issue + static const issuesRemoveSubIssue = RestOperationContract( + operationId: 'issues/remove-sub-issue', + method: 'DELETE', + path: '/repos/{owner}/{repo}/issues/{issue_number}/sub_issue', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/issues/{issue_number}/sub_issues/priority` + /// Reprioritize sub-issue + static const issuesReprioritizeSubIssue = RestOperationContract( + operationId: 'issues/reprioritize-sub-issue', + method: 'PATCH', + path: '/repos/{owner}/{repo}/issues/{issue_number}/sub_issues/priority', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/issues/{issue_number}/issue-field-values` + /// Set issue field values for an issue + static const issuesSetIssueFieldValues = RestOperationContract( + operationId: 'issues/set-issue-field-values', + method: 'PUT', + path: '/repos/{owner}/{repo}/issues/{issue_number}/issue-field-values', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/issues/{issue_number}/labels` + /// Set labels for an issue + static const issuesSetLabels = RestOperationContract( + operationId: 'issues/set-labels', + method: 'PUT', + path: '/repos/{owner}/{repo}/issues/{issue_number}/labels', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /repos/{owner}/{repo}/issues/{issue_number}/lock` + /// Unlock an issue + static const issuesUnlock = RestOperationContract( + operationId: 'issues/unlock', + method: 'DELETE', + path: '/repos/{owner}/{repo}/issues/{issue_number}/lock', + pathParams: ['issue_number', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}/pin` + /// Unpin an issue comment + static const issuesUnpinComment = RestOperationContract( + operationId: 'issues/unpin-comment', + method: 'DELETE', + path: '/repos/{owner}/{repo}/issues/comments/{comment_id}/pin', + pathParams: ['comment_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `PATCH /repos/{owner}/{repo}/issues/{issue_number}` + /// Update an issue + static const issuesUpdate = RestOperationContract( + operationId: 'issues/update', + method: 'PATCH', + path: '/repos/{owner}/{repo}/issues/{issue_number}', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}` + /// Update an issue comment + static const issuesUpdateComment = RestOperationContract( + operationId: 'issues/update-comment', + method: 'PATCH', + path: '/repos/{owner}/{repo}/issues/comments/{comment_id}', + pathParams: ['comment_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/labels/{name}` + /// Update a label + static const issuesUpdateLabel = RestOperationContract( + operationId: 'issues/update-label', + method: 'PATCH', + path: '/repos/{owner}/{repo}/labels/{name}', + pathParams: ['name', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/milestones/{milestone_number}` + /// Update a milestone + static const issuesUpdateMilestone = RestOperationContract( + operationId: 'issues/update-milestone', + method: 'PATCH', + path: '/repos/{owner}/{repo}/milestones/{milestone_number}', + pathParams: ['milestone_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /licenses/{license}` + /// Get a license + static const licensesGet = RestOperationContract( + operationId: 'licenses/get', + method: 'GET', + path: '/licenses/{license}', + pathParams: ['license'], + ); + + /// `GET /licenses` + /// Get all commonly used licenses + static const licensesGetAllCommonlyUsed = RestOperationContract( + operationId: 'licenses/get-all-commonly-used', + method: 'GET', + path: '/licenses', + queryParams: ['featured', 'page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/license` + /// Get the license for a repository + static const licensesGetForRepo = RestOperationContract( + operationId: 'licenses/get-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/license', + pathParams: ['owner', 'repo'], + queryParams: ['ref'], + ); + + /// `POST /markdown` + /// Render a Markdown document + static const markdownRender = RestOperationContract( + operationId: 'markdown/render', + method: 'POST', + path: '/markdown', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /markdown/raw` + /// Render a Markdown document in raw mode + static const markdownRenderRaw = RestOperationContract( + operationId: 'markdown/render-raw', + method: 'POST', + path: '/markdown/raw', + hasRequestBody: true, + requestMediaTypes: ['text/plain', 'text/x-markdown'], + ); + + /// `GET /meta` + /// Get GitHub meta information + static const metaGet = RestOperationContract( + operationId: 'meta/get', + method: 'GET', + path: '/meta', + ); + + /// `GET /versions` + /// Get all API versions + static const metaGetAllVersions = RestOperationContract( + operationId: 'meta/get-all-versions', + method: 'GET', + path: '/versions', + ); + + /// `GET /octocat` + /// Get Octocat + static const metaGetOctocat = RestOperationContract( + operationId: 'meta/get-octocat', + method: 'GET', + path: '/octocat', + queryParams: ['s'], + ); + + /// `GET /zen` + /// Get the Zen of GitHub + static const metaGetZen = RestOperationContract( + operationId: 'meta/get-zen', + method: 'GET', + path: '/zen', + ); + + /// `GET /` + /// GitHub API Root + static const metaRoot = RestOperationContract( + operationId: 'meta/root', + method: 'GET', + path: '/', + ); + + /// `DELETE /repos/{owner}/{repo}/import` + /// Cancel an import + static const migrationsCancelImport = RestOperationContract( + operationId: 'migrations/cancel-import', + method: 'DELETE', + path: '/repos/{owner}/{repo}/import', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /user/migrations/{migration_id}/archive` + /// Delete a user migration archive + static const migrationsDeleteArchiveForAuthenticatedUser = + RestOperationContract( + operationId: 'migrations/delete-archive-for-authenticated-user', + method: 'DELETE', + path: '/user/migrations/{migration_id}/archive', + pathParams: ['migration_id'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/migrations/{migration_id}/archive` + /// Delete an organization migration archive + static const migrationsDeleteArchiveForOrg = RestOperationContract( + operationId: 'migrations/delete-archive-for-org', + method: 'DELETE', + path: '/orgs/{org}/migrations/{migration_id}/archive', + pathParams: ['migration_id', 'org'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/migrations/{migration_id}/archive` + /// Download an organization migration archive + static const migrationsDownloadArchiveForOrg = RestOperationContract( + operationId: 'migrations/download-archive-for-org', + method: 'GET', + path: '/orgs/{org}/migrations/{migration_id}/archive', + pathParams: ['migration_id', 'org'], + ); + + /// `GET /user/migrations/{migration_id}/archive` + /// Download a user migration archive + static const migrationsGetArchiveForAuthenticatedUser = RestOperationContract( + operationId: 'migrations/get-archive-for-authenticated-user', + method: 'GET', + path: '/user/migrations/{migration_id}/archive', + pathParams: ['migration_id'], + ); + + /// `GET /repos/{owner}/{repo}/import/authors` + /// Get commit authors + static const migrationsGetCommitAuthors = RestOperationContract( + operationId: 'migrations/get-commit-authors', + method: 'GET', + path: '/repos/{owner}/{repo}/import/authors', + pathParams: ['owner', 'repo'], + queryParams: ['since'], + ); + + /// `GET /repos/{owner}/{repo}/import` + /// Get an import status + static const migrationsGetImportStatus = RestOperationContract( + operationId: 'migrations/get-import-status', + method: 'GET', + path: '/repos/{owner}/{repo}/import', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/import/large_files` + /// Get large files + static const migrationsGetLargeFiles = RestOperationContract( + operationId: 'migrations/get-large-files', + method: 'GET', + path: '/repos/{owner}/{repo}/import/large_files', + pathParams: ['owner', 'repo'], + ); + + /// `GET /user/migrations/{migration_id}` + /// Get a user migration status + static const migrationsGetStatusForAuthenticatedUser = RestOperationContract( + operationId: 'migrations/get-status-for-authenticated-user', + method: 'GET', + path: '/user/migrations/{migration_id}', + pathParams: ['migration_id'], + queryParams: ['exclude'], + ); + + /// `GET /orgs/{org}/migrations/{migration_id}` + /// Get an organization migration status + static const migrationsGetStatusForOrg = RestOperationContract( + operationId: 'migrations/get-status-for-org', + method: 'GET', + path: '/orgs/{org}/migrations/{migration_id}', + pathParams: ['migration_id', 'org'], + queryParams: ['exclude'], + ); + + /// `GET /user/migrations` + /// List user migrations + static const migrationsListForAuthenticatedUser = RestOperationContract( + operationId: 'migrations/list-for-authenticated-user', + method: 'GET', + path: '/user/migrations', + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/migrations` + /// List organization migrations + static const migrationsListForOrg = RestOperationContract( + operationId: 'migrations/list-for-org', + method: 'GET', + path: '/orgs/{org}/migrations', + pathParams: ['org'], + queryParams: ['exclude', 'page', 'per_page'], + ); + + /// `GET /user/migrations/{migration_id}/repositories` + /// List repositories for a user migration + static const migrationsListReposForAuthenticatedUser = RestOperationContract( + operationId: 'migrations/list-repos-for-authenticated-user', + method: 'GET', + path: '/user/migrations/{migration_id}/repositories', + pathParams: ['migration_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/migrations/{migration_id}/repositories` + /// List repositories in an organization migration + static const migrationsListReposForOrg = RestOperationContract( + operationId: 'migrations/list-repos-for-org', + method: 'GET', + path: '/orgs/{org}/migrations/{migration_id}/repositories', + pathParams: ['migration_id', 'org'], + queryParams: ['page', 'per_page'], + ); + + /// `PATCH /repos/{owner}/{repo}/import/authors/{author_id}` + /// Map a commit author + static const migrationsMapCommitAuthor = RestOperationContract( + operationId: 'migrations/map-commit-author', + method: 'PATCH', + path: '/repos/{owner}/{repo}/import/authors/{author_id}', + pathParams: ['author_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/import/lfs` + /// Update Git LFS preference + static const migrationsSetLfsPreference = RestOperationContract( + operationId: 'migrations/set-lfs-preference', + method: 'PATCH', + path: '/repos/{owner}/{repo}/import/lfs', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /user/migrations` + /// Start a user migration + static const migrationsStartForAuthenticatedUser = RestOperationContract( + operationId: 'migrations/start-for-authenticated-user', + method: 'POST', + path: '/user/migrations', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/migrations` + /// Start an organization migration + static const migrationsStartForOrg = RestOperationContract( + operationId: 'migrations/start-for-org', + method: 'POST', + path: '/orgs/{org}/migrations', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `PUT /repos/{owner}/{repo}/import` + /// Start an import + static const migrationsStartImport = RestOperationContract( + operationId: 'migrations/start-import', + method: 'PUT', + path: '/repos/{owner}/{repo}/import', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /user/migrations/{migration_id}/repos/{repo_name}/lock` + /// Unlock a user repository + static const migrationsUnlockRepoForAuthenticatedUser = RestOperationContract( + operationId: 'migrations/unlock-repo-for-authenticated-user', + method: 'DELETE', + path: '/user/migrations/{migration_id}/repos/{repo_name}/lock', + pathParams: ['migration_id', 'repo_name'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/migrations/{migration_id}/repos/{repo_name}/lock` + /// Unlock an organization repository + static const migrationsUnlockRepoForOrg = RestOperationContract( + operationId: 'migrations/unlock-repo-for-org', + method: 'DELETE', + path: '/orgs/{org}/migrations/{migration_id}/repos/{repo_name}/lock', + pathParams: ['migration_id', 'org', 'repo_name'], + successStatuses: [204], + ); + + /// `PATCH /repos/{owner}/{repo}/import` + /// Update an import + static const migrationsUpdateImport = RestOperationContract( + operationId: 'migrations/update-import', + method: 'PATCH', + path: '/repos/{owner}/{repo}/import', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /enterprises/{enterprise}/actions/oidc/customization/properties/repo` + /// Create an OIDC custom property inclusion for an enterprise + static const oidcCreateOidcCustomPropertyInclusionForEnterprise = + RestOperationContract( + operationId: 'oidc/create-oidc-custom-property-inclusion-for-enterprise', + method: 'POST', + path: + '/enterprises/{enterprise}/actions/oidc/customization/properties/repo', + pathParams: ['enterprise'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/actions/oidc/customization/properties/repo` + /// Create an OIDC custom property inclusion for an organization + static const oidcCreateOidcCustomPropertyInclusionForOrg = + RestOperationContract( + operationId: 'oidc/create-oidc-custom-property-inclusion-for-org', + method: 'POST', + path: '/orgs/{org}/actions/oidc/customization/properties/repo', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /enterprises/{enterprise}/actions/oidc/customization/properties/repo/{custom_property_name}` + /// Delete an OIDC custom property inclusion for an enterprise + static const oidcDeleteOidcCustomPropertyInclusionForEnterprise = + RestOperationContract( + operationId: 'oidc/delete-oidc-custom-property-inclusion-for-enterprise', + method: 'DELETE', + path: + '/enterprises/{enterprise}/actions/oidc/customization/properties/repo/{custom_property_name}', + pathParams: ['custom_property_name', 'enterprise'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/actions/oidc/customization/properties/repo/{custom_property_name}` + /// Delete an OIDC custom property inclusion for an organization + static const oidcDeleteOidcCustomPropertyInclusionForOrg = + RestOperationContract( + operationId: 'oidc/delete-oidc-custom-property-inclusion-for-org', + method: 'DELETE', + path: + '/orgs/{org}/actions/oidc/customization/properties/repo/{custom_property_name}', + pathParams: ['custom_property_name', 'org'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/actions/oidc/customization/sub` + /// Get the customization template for an OIDC subject claim for an organization + static const oidcGetOidcCustomSubTemplateForOrg = RestOperationContract( + operationId: 'oidc/get-oidc-custom-sub-template-for-org', + method: 'GET', + path: '/orgs/{org}/actions/oidc/customization/sub', + pathParams: ['org'], + ); + + /// `GET /enterprises/{enterprise}/actions/oidc/customization/properties/repo` + /// List OIDC custom property inclusions for an enterprise + static const oidcListOidcCustomPropertyInclusionsForEnterprise = + RestOperationContract( + operationId: 'oidc/list-oidc-custom-property-inclusions-for-enterprise', + method: 'GET', + path: + '/enterprises/{enterprise}/actions/oidc/customization/properties/repo', + pathParams: ['enterprise'], + ); + + /// `GET /orgs/{org}/actions/oidc/customization/properties/repo` + /// List OIDC custom property inclusions for an organization + static const oidcListOidcCustomPropertyInclusionsForOrg = + RestOperationContract( + operationId: 'oidc/list-oidc-custom-property-inclusions-for-org', + method: 'GET', + path: '/orgs/{org}/actions/oidc/customization/properties/repo', + pathParams: ['org'], + ); + + /// `PUT /orgs/{org}/actions/oidc/customization/sub` + /// Set the customization template for an OIDC subject claim for an organization + static const oidcUpdateOidcCustomSubTemplateForOrg = RestOperationContract( + operationId: 'oidc/update-oidc-custom-sub-template-for-org', + method: 'PUT', + path: '/orgs/{org}/actions/oidc/customization/sub', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `PUT /orgs/{org}/security-managers/teams/{team_slug}` + /// Add a security manager team + static const orgsAddSecurityManagerTeam = RestOperationContract( + operationId: 'orgs/add-security-manager-team', + method: 'PUT', + path: '/orgs/{org}/security-managers/teams/{team_slug}', + pathParams: ['org', 'team_slug'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/organization-roles/teams/{team_slug}/{role_id}` + /// Assign an organization role to a team + static const orgsAssignTeamToOrgRole = RestOperationContract( + operationId: 'orgs/assign-team-to-org-role', + method: 'PUT', + path: '/orgs/{org}/organization-roles/teams/{team_slug}/{role_id}', + pathParams: ['org', 'role_id', 'team_slug'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/organization-roles/users/{username}/{role_id}` + /// Assign an organization role to a user + static const orgsAssignUserToOrgRole = RestOperationContract( + operationId: 'orgs/assign-user-to-org-role', + method: 'PUT', + path: '/orgs/{org}/organization-roles/users/{username}/{role_id}', + pathParams: ['org', 'role_id', 'username'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/blocks/{username}` + /// Block a user from an organization + static const orgsBlockUser = RestOperationContract( + operationId: 'orgs/block-user', + method: 'PUT', + path: '/orgs/{org}/blocks/{username}', + pathParams: ['org', 'username'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/invitations/{invitation_id}` + /// Cancel an organization invitation + static const orgsCancelInvitation = RestOperationContract( + operationId: 'orgs/cancel-invitation', + method: 'DELETE', + path: '/orgs/{org}/invitations/{invitation_id}', + pathParams: ['invitation_id', 'org'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/blocks/{username}` + /// Check if a user is blocked by an organization + static const orgsCheckBlockedUser = RestOperationContract( + operationId: 'orgs/check-blocked-user', + method: 'GET', + path: '/orgs/{org}/blocks/{username}', + pathParams: ['org', 'username'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/members/{username}` + /// Check organization membership for a user + static const orgsCheckMembershipForUser = RestOperationContract( + operationId: 'orgs/check-membership-for-user', + method: 'GET', + path: '/orgs/{org}/members/{username}', + pathParams: ['org', 'username'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/public_members/{username}` + /// Check public organization membership for a user + static const orgsCheckPublicMembershipForUser = RestOperationContract( + operationId: 'orgs/check-public-membership-for-user', + method: 'GET', + path: '/orgs/{org}/public_members/{username}', + pathParams: ['org', 'username'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/outside_collaborators/{username}` + /// Convert an organization member to outside collaborator + static const orgsConvertMemberToOutsideCollaborator = RestOperationContract( + operationId: 'orgs/convert-member-to-outside-collaborator', + method: 'PUT', + path: '/orgs/{org}/outside_collaborators/{username}', + pathParams: ['org', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202, 204], + ); + + /// `POST /orgs/{org}/artifacts/metadata/deployment-record` + /// Create an artifact deployment record + static const orgsCreateArtifactDeploymentRecord = RestOperationContract( + operationId: 'orgs/create-artifact-deployment-record', + method: 'POST', + path: '/orgs/{org}/artifacts/metadata/deployment-record', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /orgs/{org}/artifacts/metadata/storage-record` + /// Create artifact metadata storage record + static const orgsCreateArtifactStorageRecord = RestOperationContract( + operationId: 'orgs/create-artifact-storage-record', + method: 'POST', + path: '/orgs/{org}/artifacts/metadata/storage-record', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /orgs/{org}/artifacts/metadata/deployment-record/cluster/{cluster}/jobs` + /// Create a cluster deployment records job + static const orgsCreateClusterDeploymentRecordsJob = RestOperationContract( + operationId: 'orgs/create-cluster-deployment-records-job', + method: 'POST', + path: + '/orgs/{org}/artifacts/metadata/deployment-record/cluster/{cluster}/jobs', + pathParams: ['cluster', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202], + ); + + /// `POST /orgs/{org}/invitations` + /// Create an organization invitation + static const orgsCreateInvitation = RestOperationContract( + operationId: 'orgs/create-invitation', + method: 'POST', + path: '/orgs/{org}/invitations', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/issue-fields` + /// Create issue field for an organization + static const orgsCreateIssueField = RestOperationContract( + operationId: 'orgs/create-issue-field', + method: 'POST', + path: '/orgs/{org}/issue-fields', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /orgs/{org}/issue-types` + /// Create issue type for an organization + static const orgsCreateIssueType = RestOperationContract( + operationId: 'orgs/create-issue-type', + method: 'POST', + path: '/orgs/{org}/issue-types', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /orgs/{org}/hooks` + /// Create an organization webhook + static const orgsCreateWebhook = RestOperationContract( + operationId: 'orgs/create-webhook', + method: 'POST', + path: '/orgs/{org}/hooks', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `PUT /orgs/{org}/properties/schema/{custom_property_name}` + /// Create or update a custom property for an organization + static const orgsCustomPropertiesForReposCreateOrUpdateOrganizationDefinition = + RestOperationContract( + operationId: + 'orgs/custom-properties-for-repos-create-or-update-organization-definition', + method: 'PUT', + path: '/orgs/{org}/properties/schema/{custom_property_name}', + pathParams: ['custom_property_name', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /orgs/{org}/properties/schema` + /// Create or update custom properties for an organization + static const orgsCustomPropertiesForReposCreateOrUpdateOrganizationDefinitions = + RestOperationContract( + operationId: + 'orgs/custom-properties-for-repos-create-or-update-organization-definitions', + method: 'PATCH', + path: '/orgs/{org}/properties/schema', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /orgs/{org}/properties/values` + /// Create or update custom property values for organization repositories + static const orgsCustomPropertiesForReposCreateOrUpdateOrganizationValues = + RestOperationContract( + operationId: + 'orgs/custom-properties-for-repos-create-or-update-organization-values', + method: 'PATCH', + path: '/orgs/{org}/properties/values', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/properties/schema/{custom_property_name}` + /// Remove a custom property for an organization + static const orgsCustomPropertiesForReposDeleteOrganizationDefinition = + RestOperationContract( + operationId: + 'orgs/custom-properties-for-repos-delete-organization-definition', + method: 'DELETE', + path: '/orgs/{org}/properties/schema/{custom_property_name}', + pathParams: ['custom_property_name', 'org'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/properties/schema/{custom_property_name}` + /// Get a custom property for an organization + static const orgsCustomPropertiesForReposGetOrganizationDefinition = + RestOperationContract( + operationId: 'orgs/custom-properties-for-repos-get-organization-definition', + method: 'GET', + path: '/orgs/{org}/properties/schema/{custom_property_name}', + pathParams: ['custom_property_name', 'org'], + ); + + /// `GET /orgs/{org}/properties/schema` + /// Get all custom properties for an organization + static const orgsCustomPropertiesForReposGetOrganizationDefinitions = + RestOperationContract( + operationId: + 'orgs/custom-properties-for-repos-get-organization-definitions', + method: 'GET', + path: '/orgs/{org}/properties/schema', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/properties/values` + /// List custom property values for organization repositories + static const orgsCustomPropertiesForReposGetOrganizationValues = + RestOperationContract( + operationId: 'orgs/custom-properties-for-repos-get-organization-values', + method: 'GET', + path: '/orgs/{org}/properties/values', + pathParams: ['org'], + queryParams: ['page', 'per_page', 'repository_query'], + ); + + /// `DELETE /orgs/{org}` + /// Delete an organization + static const orgsDelete = RestOperationContract( + operationId: 'orgs/delete', + method: 'DELETE', + path: '/orgs/{org}', + pathParams: ['org'], + successStatuses: [202], + ); + + /// `POST /orgs/{org}/attestations/delete-request` + /// Delete attestations in bulk + static const orgsDeleteAttestationsBulk = RestOperationContract( + operationId: 'orgs/delete-attestations-bulk', + method: 'POST', + path: '/orgs/{org}/attestations/delete-request', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /orgs/{org}/attestations/{attestation_id}` + /// Delete attestations by ID + static const orgsDeleteAttestationsById = RestOperationContract( + operationId: 'orgs/delete-attestations-by-id', + method: 'DELETE', + path: '/orgs/{org}/attestations/{attestation_id}', + pathParams: ['attestation_id', 'org'], + successStatuses: [200, 204], + ); + + /// `DELETE /orgs/{org}/attestations/digest/{subject_digest}` + /// Delete attestations by subject digest + static const orgsDeleteAttestationsBySubjectDigest = RestOperationContract( + operationId: 'orgs/delete-attestations-by-subject-digest', + method: 'DELETE', + path: '/orgs/{org}/attestations/digest/{subject_digest}', + pathParams: ['org', 'subject_digest'], + successStatuses: [200, 204], + ); + + /// `DELETE /orgs/{org}/issue-fields/{issue_field_id}` + /// Delete issue field for an organization + static const orgsDeleteIssueField = RestOperationContract( + operationId: 'orgs/delete-issue-field', + method: 'DELETE', + path: '/orgs/{org}/issue-fields/{issue_field_id}', + pathParams: ['issue_field_id', 'org'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/issue-types/{issue_type_id}` + /// Delete issue type for an organization + static const orgsDeleteIssueType = RestOperationContract( + operationId: 'orgs/delete-issue-type', + method: 'DELETE', + path: '/orgs/{org}/issue-types/{issue_type_id}', + pathParams: ['issue_type_id', 'org'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/hooks/{hook_id}` + /// Delete an organization webhook + static const orgsDeleteWebhook = RestOperationContract( + operationId: 'orgs/delete-webhook', + method: 'DELETE', + path: '/orgs/{org}/hooks/{hook_id}', + pathParams: ['hook_id', 'org'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/settings/immutable-releases/repositories/{repository_id}` + /// Disable a selected repository for immutable releases in an organization + static const orgsDisableSelectedRepositoryImmutableReleasesOrganization = + RestOperationContract( + operationId: + 'orgs/disable-selected-repository-immutable-releases-organization', + method: 'DELETE', + path: + '/orgs/{org}/settings/immutable-releases/repositories/{repository_id}', + pathParams: ['org', 'repository_id'], + successStatuses: [204], + ); + + /// `POST /orgs/{org}/{security_product}/{enablement}` + /// Enable or disable a security feature for an organization + static const orgsEnableOrDisableSecurityProductOnAllOrgRepos = + RestOperationContract( + operationId: 'orgs/enable-or-disable-security-product-on-all-org-repos', + method: 'POST', + path: '/orgs/{org}/{security_product}/{enablement}', + pathParams: ['enablement', 'org', 'security_product'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/settings/immutable-releases/repositories/{repository_id}` + /// Enable a selected repository for immutable releases in an organization + static const orgsEnableSelectedRepositoryImmutableReleasesOrganization = + RestOperationContract( + operationId: + 'orgs/enable-selected-repository-immutable-releases-organization', + method: 'PUT', + path: + '/orgs/{org}/settings/immutable-releases/repositories/{repository_id}', + pathParams: ['org', 'repository_id'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}` + /// Get an organization + static const orgsGet = RestOperationContract( + operationId: 'orgs/get', + method: 'GET', + path: '/orgs/{org}', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/artifacts/metadata/deployment-record/cluster/{cluster}/jobs/{job_id}` + /// Get cluster deployment records job status + static const orgsGetClusterDeploymentRecordsJob = RestOperationContract( + operationId: 'orgs/get-cluster-deployment-records-job', + method: 'GET', + path: + '/orgs/{org}/artifacts/metadata/deployment-record/cluster/{cluster}/jobs/{job_id}', + pathParams: ['cluster', 'job_id', 'org'], + ); + + /// `GET /orgs/{org}/settings/immutable-releases` + /// Get immutable releases settings for an organization + static const orgsGetImmutableReleasesSettings = RestOperationContract( + operationId: 'orgs/get-immutable-releases-settings', + method: 'GET', + path: '/orgs/{org}/settings/immutable-releases', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/settings/immutable-releases/repositories` + /// List selected repositories for immutable releases enforcement + static const orgsGetImmutableReleasesSettingsRepositories = + RestOperationContract( + operationId: 'orgs/get-immutable-releases-settings-repositories', + method: 'GET', + path: '/orgs/{org}/settings/immutable-releases/repositories', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/memberships/orgs/{org}` + /// Get an organization membership for the authenticated user + static const orgsGetMembershipForAuthenticatedUser = RestOperationContract( + operationId: 'orgs/get-membership-for-authenticated-user', + method: 'GET', + path: '/user/memberships/orgs/{org}', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/memberships/{username}` + /// Get organization membership for a user + static const orgsGetMembershipForUser = RestOperationContract( + operationId: 'orgs/get-membership-for-user', + method: 'GET', + path: '/orgs/{org}/memberships/{username}', + pathParams: ['org', 'username'], + ); + + /// `GET /orgs/{org}/organization-roles/{role_id}` + /// Get an organization role + static const orgsGetOrgRole = RestOperationContract( + operationId: 'orgs/get-org-role', + method: 'GET', + path: '/orgs/{org}/organization-roles/{role_id}', + pathParams: ['org', 'role_id'], + ); + + /// `GET /orgs/{org}/rulesets/{ruleset_id}/history` + /// Get organization ruleset history + static const orgsGetOrgRulesetHistory = RestOperationContract( + operationId: 'orgs/get-org-ruleset-history', + method: 'GET', + path: '/orgs/{org}/rulesets/{ruleset_id}/history', + pathParams: ['org', 'ruleset_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/rulesets/{ruleset_id}/history/{version_id}` + /// Get organization ruleset version + static const orgsGetOrgRulesetVersion = RestOperationContract( + operationId: 'orgs/get-org-ruleset-version', + method: 'GET', + path: '/orgs/{org}/rulesets/{ruleset_id}/history/{version_id}', + pathParams: ['org', 'ruleset_id', 'version_id'], + ); + + /// `GET /orgs/{org}/hooks/{hook_id}` + /// Get an organization webhook + static const orgsGetWebhook = RestOperationContract( + operationId: 'orgs/get-webhook', + method: 'GET', + path: '/orgs/{org}/hooks/{hook_id}', + pathParams: ['hook_id', 'org'], + ); + + /// `GET /orgs/{org}/hooks/{hook_id}/config` + /// Get a webhook configuration for an organization + static const orgsGetWebhookConfigForOrg = RestOperationContract( + operationId: 'orgs/get-webhook-config-for-org', + method: 'GET', + path: '/orgs/{org}/hooks/{hook_id}/config', + pathParams: ['hook_id', 'org'], + ); + + /// `GET /orgs/{org}/hooks/{hook_id}/deliveries/{delivery_id}` + /// Get a webhook delivery for an organization webhook + static const orgsGetWebhookDelivery = RestOperationContract( + operationId: 'orgs/get-webhook-delivery', + method: 'GET', + path: '/orgs/{org}/hooks/{hook_id}/deliveries/{delivery_id}', + pathParams: ['delivery_id', 'hook_id', 'org'], + ); + + /// `GET /organizations` + /// List organizations + static const orgsList = RestOperationContract( + operationId: 'orgs/list', + method: 'GET', + path: '/organizations', + queryParams: ['per_page', 'since'], + ); + + /// `GET /orgs/{org}/installations` + /// List app installations for an organization + static const orgsListAppInstallations = RestOperationContract( + operationId: 'orgs/list-app-installations', + method: 'GET', + path: '/orgs/{org}/installations', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/artifacts/{subject_digest}/metadata/deployment-records` + /// List artifact deployment records + static const orgsListArtifactDeploymentRecords = RestOperationContract( + operationId: 'orgs/list-artifact-deployment-records', + method: 'GET', + path: '/orgs/{org}/artifacts/{subject_digest}/metadata/deployment-records', + pathParams: ['org', 'subject_digest'], + ); + + /// `GET /orgs/{org}/artifacts/{subject_digest}/metadata/storage-records` + /// List artifact storage records + static const orgsListArtifactStorageRecords = RestOperationContract( + operationId: 'orgs/list-artifact-storage-records', + method: 'GET', + path: '/orgs/{org}/artifacts/{subject_digest}/metadata/storage-records', + pathParams: ['org', 'subject_digest'], + ); + + /// `GET /orgs/{org}/attestations/repositories` + /// List attestation repositories + static const orgsListAttestationRepositories = RestOperationContract( + operationId: 'orgs/list-attestation-repositories', + method: 'GET', + path: '/orgs/{org}/attestations/repositories', + pathParams: ['org'], + queryParams: ['after', 'before', 'per_page', 'predicate_type'], + ); + + /// `GET /orgs/{org}/attestations/{subject_digest}` + /// List attestations + static const orgsListAttestations = RestOperationContract( + operationId: 'orgs/list-attestations', + method: 'GET', + path: '/orgs/{org}/attestations/{subject_digest}', + pathParams: ['org', 'subject_digest'], + queryParams: ['after', 'before', 'per_page', 'predicate_type'], + ); + + /// `POST /orgs/{org}/attestations/bulk-list` + /// List attestations by bulk subject digests + static const orgsListAttestationsBulk = RestOperationContract( + operationId: 'orgs/list-attestations-bulk', + method: 'POST', + path: '/orgs/{org}/attestations/bulk-list', + pathParams: ['org'], + queryParams: ['after', 'before', 'per_page'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /orgs/{org}/blocks` + /// List users blocked by an organization + static const orgsListBlockedUsers = RestOperationContract( + operationId: 'orgs/list-blocked-users', + method: 'GET', + path: '/orgs/{org}/blocks', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/failed_invitations` + /// List failed organization invitations + static const orgsListFailedInvitations = RestOperationContract( + operationId: 'orgs/list-failed-invitations', + method: 'GET', + path: '/orgs/{org}/failed_invitations', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/orgs` + /// List organizations for the authenticated user + static const orgsListForAuthenticatedUser = RestOperationContract( + operationId: 'orgs/list-for-authenticated-user', + method: 'GET', + path: '/user/orgs', + queryParams: ['page', 'per_page'], + ); + + /// `GET /users/{username}/orgs` + /// List organizations for a user + static const orgsListForUser = RestOperationContract( + operationId: 'orgs/list-for-user', + method: 'GET', + path: '/users/{username}/orgs', + pathParams: ['username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/invitations/{invitation_id}/teams` + /// List organization invitation teams + static const orgsListInvitationTeams = RestOperationContract( + operationId: 'orgs/list-invitation-teams', + method: 'GET', + path: '/orgs/{org}/invitations/{invitation_id}/teams', + pathParams: ['invitation_id', 'org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/issue-fields` + /// List issue fields for an organization + static const orgsListIssueFields = RestOperationContract( + operationId: 'orgs/list-issue-fields', + method: 'GET', + path: '/orgs/{org}/issue-fields', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/issue-types` + /// List issue types for an organization + static const orgsListIssueTypes = RestOperationContract( + operationId: 'orgs/list-issue-types', + method: 'GET', + path: '/orgs/{org}/issue-types', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/members` + /// List organization members + static const orgsListMembers = RestOperationContract( + operationId: 'orgs/list-members', + method: 'GET', + path: '/orgs/{org}/members', + pathParams: ['org'], + queryParams: ['filter', 'page', 'per_page', 'role'], + ); + + /// `GET /user/memberships/orgs` + /// List organization memberships for the authenticated user + static const orgsListMembershipsForAuthenticatedUser = RestOperationContract( + operationId: 'orgs/list-memberships-for-authenticated-user', + method: 'GET', + path: '/user/memberships/orgs', + queryParams: ['page', 'per_page', 'state'], + ); + + /// `GET /orgs/{org}/organization-roles/{role_id}/teams` + /// List teams that are assigned to an organization role + static const orgsListOrgRoleTeams = RestOperationContract( + operationId: 'orgs/list-org-role-teams', + method: 'GET', + path: '/orgs/{org}/organization-roles/{role_id}/teams', + pathParams: ['org', 'role_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/organization-roles/{role_id}/users` + /// List users that are assigned to an organization role + static const orgsListOrgRoleUsers = RestOperationContract( + operationId: 'orgs/list-org-role-users', + method: 'GET', + path: '/orgs/{org}/organization-roles/{role_id}/users', + pathParams: ['org', 'role_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/organization-roles` + /// Get all organization roles for an organization + static const orgsListOrgRoles = RestOperationContract( + operationId: 'orgs/list-org-roles', + method: 'GET', + path: '/orgs/{org}/organization-roles', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/outside_collaborators` + /// List outside collaborators for an organization + static const orgsListOutsideCollaborators = RestOperationContract( + operationId: 'orgs/list-outside-collaborators', + method: 'GET', + path: '/orgs/{org}/outside_collaborators', + pathParams: ['org'], + queryParams: ['filter', 'page', 'per_page'], + ); + + /// `GET /orgs/{org}/personal-access-tokens/{pat_id}/repositories` + /// List repositories a fine-grained personal access token has access to + static const orgsListPatGrantRepositories = RestOperationContract( + operationId: 'orgs/list-pat-grant-repositories', + method: 'GET', + path: '/orgs/{org}/personal-access-tokens/{pat_id}/repositories', + pathParams: ['org', 'pat_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/personal-access-token-requests/{pat_request_id}/repositories` + /// List repositories requested to be accessed by a fine-grained personal access token + static const orgsListPatGrantRequestRepositories = RestOperationContract( + operationId: 'orgs/list-pat-grant-request-repositories', + method: 'GET', + path: + '/orgs/{org}/personal-access-token-requests/{pat_request_id}/repositories', + pathParams: ['org', 'pat_request_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/personal-access-token-requests` + /// List requests to access organization resources with fine-grained personal access tokens + static const orgsListPatGrantRequests = RestOperationContract( + operationId: 'orgs/list-pat-grant-requests', + method: 'GET', + path: '/orgs/{org}/personal-access-token-requests', + pathParams: ['org'], + queryParams: [ + 'direction', + 'last_used_after', + 'last_used_before', + 'owner', + 'page', + 'per_page', + 'permission', + 'repository', + 'sort', + 'token_id' + ], + ); + + /// `GET /orgs/{org}/personal-access-tokens` + /// List fine-grained personal access tokens with access to organization resources + static const orgsListPatGrants = RestOperationContract( + operationId: 'orgs/list-pat-grants', + method: 'GET', + path: '/orgs/{org}/personal-access-tokens', + pathParams: ['org'], + queryParams: [ + 'direction', + 'last_used_after', + 'last_used_before', + 'owner', + 'page', + 'per_page', + 'permission', + 'repository', + 'sort', + 'token_id' + ], + ); + + /// `GET /orgs/{org}/invitations` + /// List pending organization invitations + static const orgsListPendingInvitations = RestOperationContract( + operationId: 'orgs/list-pending-invitations', + method: 'GET', + path: '/orgs/{org}/invitations', + pathParams: ['org'], + queryParams: ['invitation_source', 'page', 'per_page', 'role'], + ); + + /// `GET /orgs/{org}/public_members` + /// List public organization members + static const orgsListPublicMembers = RestOperationContract( + operationId: 'orgs/list-public-members', + method: 'GET', + path: '/orgs/{org}/public_members', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/security-managers` + /// List security manager teams + static const orgsListSecurityManagerTeams = RestOperationContract( + operationId: 'orgs/list-security-manager-teams', + method: 'GET', + path: '/orgs/{org}/security-managers', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/hooks/{hook_id}/deliveries` + /// List deliveries for an organization webhook + static const orgsListWebhookDeliveries = RestOperationContract( + operationId: 'orgs/list-webhook-deliveries', + method: 'GET', + path: '/orgs/{org}/hooks/{hook_id}/deliveries', + pathParams: ['hook_id', 'org'], + queryParams: ['cursor', 'per_page', 'status'], + ); + + /// `GET /orgs/{org}/hooks` + /// List organization webhooks + static const orgsListWebhooks = RestOperationContract( + operationId: 'orgs/list-webhooks', + method: 'GET', + path: '/orgs/{org}/hooks', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `POST /orgs/{org}/hooks/{hook_id}/pings` + /// Ping an organization webhook + static const orgsPingWebhook = RestOperationContract( + operationId: 'orgs/ping-webhook', + method: 'POST', + path: '/orgs/{org}/hooks/{hook_id}/pings', + pathParams: ['hook_id', 'org'], + successStatuses: [204], + ); + + /// `POST /orgs/{org}/hooks/{hook_id}/deliveries/{delivery_id}/attempts` + /// Redeliver a delivery for an organization webhook + static const orgsRedeliverWebhookDelivery = RestOperationContract( + operationId: 'orgs/redeliver-webhook-delivery', + method: 'POST', + path: '/orgs/{org}/hooks/{hook_id}/deliveries/{delivery_id}/attempts', + pathParams: ['delivery_id', 'hook_id', 'org'], + successStatuses: [202], + ); + + /// `DELETE /orgs/{org}/members/{username}` + /// Remove an organization member + static const orgsRemoveMember = RestOperationContract( + operationId: 'orgs/remove-member', + method: 'DELETE', + path: '/orgs/{org}/members/{username}', + pathParams: ['org', 'username'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/memberships/{username}` + /// Remove organization membership for a user + static const orgsRemoveMembershipForUser = RestOperationContract( + operationId: 'orgs/remove-membership-for-user', + method: 'DELETE', + path: '/orgs/{org}/memberships/{username}', + pathParams: ['org', 'username'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/outside_collaborators/{username}` + /// Remove outside collaborator from an organization + static const orgsRemoveOutsideCollaborator = RestOperationContract( + operationId: 'orgs/remove-outside-collaborator', + method: 'DELETE', + path: '/orgs/{org}/outside_collaborators/{username}', + pathParams: ['org', 'username'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/public_members/{username}` + /// Remove public organization membership for the authenticated user + static const orgsRemovePublicMembershipForAuthenticatedUser = + RestOperationContract( + operationId: 'orgs/remove-public-membership-for-authenticated-user', + method: 'DELETE', + path: '/orgs/{org}/public_members/{username}', + pathParams: ['org', 'username'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/security-managers/teams/{team_slug}` + /// Remove a security manager team + static const orgsRemoveSecurityManagerTeam = RestOperationContract( + operationId: 'orgs/remove-security-manager-team', + method: 'DELETE', + path: '/orgs/{org}/security-managers/teams/{team_slug}', + pathParams: ['org', 'team_slug'], + successStatuses: [204], + ); + + /// `POST /orgs/{org}/personal-access-token-requests/{pat_request_id}` + /// Review a request to access organization resources with a fine-grained personal access token + static const orgsReviewPatGrantRequest = RestOperationContract( + operationId: 'orgs/review-pat-grant-request', + method: 'POST', + path: '/orgs/{org}/personal-access-token-requests/{pat_request_id}', + pathParams: ['org', 'pat_request_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `POST /orgs/{org}/personal-access-token-requests` + /// Review requests to access organization resources with fine-grained personal access tokens + static const orgsReviewPatGrantRequestsInBulk = RestOperationContract( + operationId: 'orgs/review-pat-grant-requests-in-bulk', + method: 'POST', + path: '/orgs/{org}/personal-access-token-requests', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202], + ); + + /// `DELETE /orgs/{org}/organization-roles/teams/{team_slug}` + /// Remove all organization roles for a team + static const orgsRevokeAllOrgRolesTeam = RestOperationContract( + operationId: 'orgs/revoke-all-org-roles-team', + method: 'DELETE', + path: '/orgs/{org}/organization-roles/teams/{team_slug}', + pathParams: ['org', 'team_slug'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/organization-roles/users/{username}` + /// Remove all organization roles for a user + static const orgsRevokeAllOrgRolesUser = RestOperationContract( + operationId: 'orgs/revoke-all-org-roles-user', + method: 'DELETE', + path: '/orgs/{org}/organization-roles/users/{username}', + pathParams: ['org', 'username'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/organization-roles/teams/{team_slug}/{role_id}` + /// Remove an organization role from a team + static const orgsRevokeOrgRoleTeam = RestOperationContract( + operationId: 'orgs/revoke-org-role-team', + method: 'DELETE', + path: '/orgs/{org}/organization-roles/teams/{team_slug}/{role_id}', + pathParams: ['org', 'role_id', 'team_slug'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/organization-roles/users/{username}/{role_id}` + /// Remove an organization role from a user + static const orgsRevokeOrgRoleUser = RestOperationContract( + operationId: 'orgs/revoke-org-role-user', + method: 'DELETE', + path: '/orgs/{org}/organization-roles/users/{username}/{role_id}', + pathParams: ['org', 'role_id', 'username'], + successStatuses: [204], + ); + + /// `POST /orgs/{org}/artifacts/metadata/deployment-record/cluster/{cluster}` + /// Set cluster deployment records + static const orgsSetClusterDeploymentRecords = RestOperationContract( + operationId: 'orgs/set-cluster-deployment-records', + method: 'POST', + path: '/orgs/{org}/artifacts/metadata/deployment-record/cluster/{cluster}', + pathParams: ['cluster', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 207], + ); + + /// `PUT /orgs/{org}/settings/immutable-releases` + /// Set immutable releases settings for an organization + static const orgsSetImmutableReleasesSettings = RestOperationContract( + operationId: 'orgs/set-immutable-releases-settings', + method: 'PUT', + path: '/orgs/{org}/settings/immutable-releases', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/settings/immutable-releases/repositories` + /// Set selected repositories for immutable releases enforcement + static const orgsSetImmutableReleasesSettingsRepositories = + RestOperationContract( + operationId: 'orgs/set-immutable-releases-settings-repositories', + method: 'PUT', + path: '/orgs/{org}/settings/immutable-releases/repositories', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/memberships/{username}` + /// Set organization membership for a user + static const orgsSetMembershipForUser = RestOperationContract( + operationId: 'orgs/set-membership-for-user', + method: 'PUT', + path: '/orgs/{org}/memberships/{username}', + pathParams: ['org', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /orgs/{org}/public_members/{username}` + /// Set public organization membership for the authenticated user + static const orgsSetPublicMembershipForAuthenticatedUser = + RestOperationContract( + operationId: 'orgs/set-public-membership-for-authenticated-user', + method: 'PUT', + path: '/orgs/{org}/public_members/{username}', + pathParams: ['org', 'username'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/blocks/{username}` + /// Unblock a user from an organization + static const orgsUnblockUser = RestOperationContract( + operationId: 'orgs/unblock-user', + method: 'DELETE', + path: '/orgs/{org}/blocks/{username}', + pathParams: ['org', 'username'], + successStatuses: [204], + ); + + /// `PATCH /orgs/{org}` + /// Update an organization + static const orgsUpdate = RestOperationContract( + operationId: 'orgs/update', + method: 'PATCH', + path: '/orgs/{org}', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /orgs/{org}/issue-fields/{issue_field_id}` + /// Update issue field for an organization + static const orgsUpdateIssueField = RestOperationContract( + operationId: 'orgs/update-issue-field', + method: 'PATCH', + path: '/orgs/{org}/issue-fields/{issue_field_id}', + pathParams: ['issue_field_id', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /orgs/{org}/issue-types/{issue_type_id}` + /// Update issue type for an organization + static const orgsUpdateIssueType = RestOperationContract( + operationId: 'orgs/update-issue-type', + method: 'PUT', + path: '/orgs/{org}/issue-types/{issue_type_id}', + pathParams: ['issue_type_id', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /user/memberships/orgs/{org}` + /// Update an organization membership for the authenticated user + static const orgsUpdateMembershipForAuthenticatedUser = RestOperationContract( + operationId: 'orgs/update-membership-for-authenticated-user', + method: 'PATCH', + path: '/user/memberships/orgs/{org}', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 202], + ); + + /// `POST /orgs/{org}/personal-access-tokens/{pat_id}` + /// Update the access a fine-grained personal access token has to organization resources + static const orgsUpdatePatAccess = RestOperationContract( + operationId: 'orgs/update-pat-access', + method: 'POST', + path: '/orgs/{org}/personal-access-tokens/{pat_id}', + pathParams: ['org', 'pat_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `POST /orgs/{org}/personal-access-tokens` + /// Update the access to organization resources via fine-grained personal access tokens + static const orgsUpdatePatAccesses = RestOperationContract( + operationId: 'orgs/update-pat-accesses', + method: 'POST', + path: '/orgs/{org}/personal-access-tokens', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202], + ); + + /// `PATCH /orgs/{org}/hooks/{hook_id}` + /// Update an organization webhook + static const orgsUpdateWebhook = RestOperationContract( + operationId: 'orgs/update-webhook', + method: 'PATCH', + path: '/orgs/{org}/hooks/{hook_id}', + pathParams: ['hook_id', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /orgs/{org}/hooks/{hook_id}/config` + /// Update a webhook configuration for an organization + static const orgsUpdateWebhookConfigForOrg = RestOperationContract( + operationId: 'orgs/update-webhook-config-for-org', + method: 'PATCH', + path: '/orgs/{org}/hooks/{hook_id}/config', + pathParams: ['hook_id', 'org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /user/packages/{package_type}/{package_name}` + /// Delete a package for the authenticated user + static const packagesDeletePackageForAuthenticatedUser = + RestOperationContract( + operationId: 'packages/delete-package-for-authenticated-user', + method: 'DELETE', + path: '/user/packages/{package_type}/{package_name}', + pathParams: ['package_name', 'package_type'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/packages/{package_type}/{package_name}` + /// Delete a package for an organization + static const packagesDeletePackageForOrg = RestOperationContract( + operationId: 'packages/delete-package-for-org', + method: 'DELETE', + path: '/orgs/{org}/packages/{package_type}/{package_name}', + pathParams: ['org', 'package_name', 'package_type'], + successStatuses: [204], + ); + + /// `DELETE /users/{username}/packages/{package_type}/{package_name}` + /// Delete a package for a user + static const packagesDeletePackageForUser = RestOperationContract( + operationId: 'packages/delete-package-for-user', + method: 'DELETE', + path: '/users/{username}/packages/{package_type}/{package_name}', + pathParams: ['package_name', 'package_type', 'username'], + successStatuses: [204], + ); + + /// `DELETE /user/packages/{package_type}/{package_name}/versions/{package_version_id}` + /// Delete a package version for the authenticated user + static const packagesDeletePackageVersionForAuthenticatedUser = + RestOperationContract( + operationId: 'packages/delete-package-version-for-authenticated-user', + method: 'DELETE', + path: + '/user/packages/{package_type}/{package_name}/versions/{package_version_id}', + pathParams: ['package_name', 'package_type', 'package_version_id'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}` + /// Delete package version for an organization + static const packagesDeletePackageVersionForOrg = RestOperationContract( + operationId: 'packages/delete-package-version-for-org', + method: 'DELETE', + path: + '/orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}', + pathParams: ['org', 'package_name', 'package_type', 'package_version_id'], + successStatuses: [204], + ); + + /// `DELETE /users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}` + /// Delete package version for a user + static const packagesDeletePackageVersionForUser = RestOperationContract( + operationId: 'packages/delete-package-version-for-user', + method: 'DELETE', + path: + '/users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}', + pathParams: [ + 'package_name', + 'package_type', + 'package_version_id', + 'username' + ], + successStatuses: [204], + ); + + /// `GET /user/packages/{package_type}/{package_name}/versions` + /// List package versions for a package owned by the authenticated user + static const packagesGetAllPackageVersionsForPackageOwnedByAuthenticatedUser = + RestOperationContract( + operationId: + 'packages/get-all-package-versions-for-package-owned-by-authenticated-user', + method: 'GET', + path: '/user/packages/{package_type}/{package_name}/versions', + pathParams: ['package_name', 'package_type'], + queryParams: ['page', 'per_page', 'state'], + ); + + /// `GET /orgs/{org}/packages/{package_type}/{package_name}/versions` + /// List package versions for a package owned by an organization + static const packagesGetAllPackageVersionsForPackageOwnedByOrg = + RestOperationContract( + operationId: 'packages/get-all-package-versions-for-package-owned-by-org', + method: 'GET', + path: '/orgs/{org}/packages/{package_type}/{package_name}/versions', + pathParams: ['org', 'package_name', 'package_type'], + queryParams: ['page', 'per_page', 'state'], + ); + + /// `GET /users/{username}/packages/{package_type}/{package_name}/versions` + /// List package versions for a package owned by a user + static const packagesGetAllPackageVersionsForPackageOwnedByUser = + RestOperationContract( + operationId: 'packages/get-all-package-versions-for-package-owned-by-user', + method: 'GET', + path: '/users/{username}/packages/{package_type}/{package_name}/versions', + pathParams: ['package_name', 'package_type', 'username'], + ); + + /// `GET /user/packages/{package_type}/{package_name}` + /// Get a package for the authenticated user + static const packagesGetPackageForAuthenticatedUser = RestOperationContract( + operationId: 'packages/get-package-for-authenticated-user', + method: 'GET', + path: '/user/packages/{package_type}/{package_name}', + pathParams: ['package_name', 'package_type'], + ); + + /// `GET /orgs/{org}/packages/{package_type}/{package_name}` + /// Get a package for an organization + static const packagesGetPackageForOrganization = RestOperationContract( + operationId: 'packages/get-package-for-organization', + method: 'GET', + path: '/orgs/{org}/packages/{package_type}/{package_name}', + pathParams: ['org', 'package_name', 'package_type'], + ); + + /// `GET /users/{username}/packages/{package_type}/{package_name}` + /// Get a package for a user + static const packagesGetPackageForUser = RestOperationContract( + operationId: 'packages/get-package-for-user', + method: 'GET', + path: '/users/{username}/packages/{package_type}/{package_name}', + pathParams: ['package_name', 'package_type', 'username'], + ); + + /// `GET /user/packages/{package_type}/{package_name}/versions/{package_version_id}` + /// Get a package version for the authenticated user + static const packagesGetPackageVersionForAuthenticatedUser = + RestOperationContract( + operationId: 'packages/get-package-version-for-authenticated-user', + method: 'GET', + path: + '/user/packages/{package_type}/{package_name}/versions/{package_version_id}', + pathParams: ['package_name', 'package_type', 'package_version_id'], + ); + + /// `GET /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}` + /// Get a package version for an organization + static const packagesGetPackageVersionForOrganization = RestOperationContract( + operationId: 'packages/get-package-version-for-organization', + method: 'GET', + path: + '/orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}', + pathParams: ['org', 'package_name', 'package_type', 'package_version_id'], + ); + + /// `GET /users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}` + /// Get a package version for a user + static const packagesGetPackageVersionForUser = RestOperationContract( + operationId: 'packages/get-package-version-for-user', + method: 'GET', + path: + '/users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}', + pathParams: [ + 'package_name', + 'package_type', + 'package_version_id', + 'username' + ], + ); + + /// `GET /user/docker/conflicts` + /// Get list of conflicting packages during Docker migration for authenticated-user + static const packagesListDockerMigrationConflictingPackagesForAuthenticatedUser = + RestOperationContract( + operationId: + 'packages/list-docker-migration-conflicting-packages-for-authenticated-user', + method: 'GET', + path: '/user/docker/conflicts', + ); + + /// `GET /orgs/{org}/docker/conflicts` + /// Get list of conflicting packages during Docker migration for organization + static const packagesListDockerMigrationConflictingPackagesForOrganization = + RestOperationContract( + operationId: + 'packages/list-docker-migration-conflicting-packages-for-organization', + method: 'GET', + path: '/orgs/{org}/docker/conflicts', + pathParams: ['org'], + ); + + /// `GET /users/{username}/docker/conflicts` + /// Get list of conflicting packages during Docker migration for user + static const packagesListDockerMigrationConflictingPackagesForUser = + RestOperationContract( + operationId: 'packages/list-docker-migration-conflicting-packages-for-user', + method: 'GET', + path: '/users/{username}/docker/conflicts', + pathParams: ['username'], + ); + + /// `GET /user/packages` + /// List packages for the authenticated user's namespace + static const packagesListPackagesForAuthenticatedUser = RestOperationContract( + operationId: 'packages/list-packages-for-authenticated-user', + method: 'GET', + path: '/user/packages', + queryParams: ['package_type', 'page', 'per_page', 'visibility'], + ); + + /// `GET /orgs/{org}/packages` + /// List packages for an organization + static const packagesListPackagesForOrganization = RestOperationContract( + operationId: 'packages/list-packages-for-organization', + method: 'GET', + path: '/orgs/{org}/packages', + pathParams: ['org'], + queryParams: ['package_type', 'page', 'per_page', 'visibility'], + ); + + /// `GET /users/{username}/packages` + /// List packages for a user + static const packagesListPackagesForUser = RestOperationContract( + operationId: 'packages/list-packages-for-user', + method: 'GET', + path: '/users/{username}/packages', + pathParams: ['username'], + queryParams: ['package_type', 'page', 'per_page', 'visibility'], + ); + + /// `POST /user/packages/{package_type}/{package_name}/restore` + /// Restore a package for the authenticated user + static const packagesRestorePackageForAuthenticatedUser = + RestOperationContract( + operationId: 'packages/restore-package-for-authenticated-user', + method: 'POST', + path: '/user/packages/{package_type}/{package_name}/restore', + pathParams: ['package_name', 'package_type'], + queryParams: ['token'], + successStatuses: [204], + ); + + /// `POST /orgs/{org}/packages/{package_type}/{package_name}/restore` + /// Restore a package for an organization + static const packagesRestorePackageForOrg = RestOperationContract( + operationId: 'packages/restore-package-for-org', + method: 'POST', + path: '/orgs/{org}/packages/{package_type}/{package_name}/restore', + pathParams: ['org', 'package_name', 'package_type'], + queryParams: ['token'], + successStatuses: [204], + ); + + /// `POST /users/{username}/packages/{package_type}/{package_name}/restore` + /// Restore a package for a user + static const packagesRestorePackageForUser = RestOperationContract( + operationId: 'packages/restore-package-for-user', + method: 'POST', + path: '/users/{username}/packages/{package_type}/{package_name}/restore', + pathParams: ['package_name', 'package_type', 'username'], + queryParams: ['token'], + successStatuses: [204], + ); + + /// `POST /user/packages/{package_type}/{package_name}/versions/{package_version_id}/restore` + /// Restore a package version for the authenticated user + static const packagesRestorePackageVersionForAuthenticatedUser = + RestOperationContract( + operationId: 'packages/restore-package-version-for-authenticated-user', + method: 'POST', + path: + '/user/packages/{package_type}/{package_name}/versions/{package_version_id}/restore', + pathParams: ['package_name', 'package_type', 'package_version_id'], + successStatuses: [204], + ); + + /// `POST /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore` + /// Restore package version for an organization + static const packagesRestorePackageVersionForOrg = RestOperationContract( + operationId: 'packages/restore-package-version-for-org', + method: 'POST', + path: + '/orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore', + pathParams: ['org', 'package_name', 'package_type', 'package_version_id'], + successStatuses: [204], + ); + + /// `POST /users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore` + /// Restore package version for a user + static const packagesRestorePackageVersionForUser = RestOperationContract( + operationId: 'packages/restore-package-version-for-user', + method: 'POST', + path: + '/users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore', + pathParams: [ + 'package_name', + 'package_type', + 'package_version_id', + 'username' + ], + successStatuses: [204], + ); + + /// `POST /orgs/{org}/private-registries` + /// Create a private registry for an organization + static const privateRegistriesCreateOrgPrivateRegistry = + RestOperationContract( + operationId: 'private-registries/create-org-private-registry', + method: 'POST', + path: '/orgs/{org}/private-registries', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /orgs/{org}/private-registries/{secret_name}` + /// Delete a private registry for an organization + static const privateRegistriesDeleteOrgPrivateRegistry = + RestOperationContract( + operationId: 'private-registries/delete-org-private-registry', + method: 'DELETE', + path: '/orgs/{org}/private-registries/{secret_name}', + pathParams: ['org', 'secret_name'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/private-registries/{secret_name}` + /// Get a private registry for an organization + static const privateRegistriesGetOrgPrivateRegistry = RestOperationContract( + operationId: 'private-registries/get-org-private-registry', + method: 'GET', + path: '/orgs/{org}/private-registries/{secret_name}', + pathParams: ['org', 'secret_name'], + ); + + /// `GET /orgs/{org}/private-registries/public-key` + /// Get private registries public key for an organization + static const privateRegistriesGetOrgPublicKey = RestOperationContract( + operationId: 'private-registries/get-org-public-key', + method: 'GET', + path: '/orgs/{org}/private-registries/public-key', + pathParams: ['org'], + ); + + /// `GET /orgs/{org}/private-registries` + /// List private registries for an organization + static const privateRegistriesListOrgPrivateRegistries = + RestOperationContract( + operationId: 'private-registries/list-org-private-registries', + method: 'GET', + path: '/orgs/{org}/private-registries', + pathParams: ['org'], + queryParams: ['page', 'per_page'], + ); + + /// `PATCH /orgs/{org}/private-registries/{secret_name}` + /// Update a private registry for an organization + static const privateRegistriesUpdateOrgPrivateRegistry = + RestOperationContract( + operationId: 'private-registries/update-org-private-registry', + method: 'PATCH', + path: '/orgs/{org}/private-registries/{secret_name}', + pathParams: ['org', 'secret_name'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `POST /orgs/{org}/projectsV2/{project_number}/fields` + /// Add a field to an organization-owned project. + static const projectsAddFieldForOrg = RestOperationContract( + operationId: 'projects/add-field-for-org', + method: 'POST', + path: '/orgs/{org}/projectsV2/{project_number}/fields', + pathParams: ['org', 'project_number'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /users/{username}/projectsV2/{project_number}/fields` + /// Add field to user owned project + static const projectsAddFieldForUser = RestOperationContract( + operationId: 'projects/add-field-for-user', + method: 'POST', + path: '/users/{username}/projectsV2/{project_number}/fields', + pathParams: ['project_number', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/projectsV2/{project_number}/items` + /// Add item to organization owned project + static const projectsAddItemForOrg = RestOperationContract( + operationId: 'projects/add-item-for-org', + method: 'POST', + path: '/orgs/{org}/projectsV2/{project_number}/items', + pathParams: ['org', 'project_number'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /users/{username}/projectsV2/{project_number}/items` + /// Add item to user owned project + static const projectsAddItemForUser = RestOperationContract( + operationId: 'projects/add-item-for-user', + method: 'POST', + path: '/users/{username}/projectsV2/{project_number}/items', + pathParams: ['project_number', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /user/{user_id}/projectsV2/{project_number}/drafts` + /// Create draft item for user owned project + static const projectsCreateDraftItemForAuthenticatedUser = + RestOperationContract( + operationId: 'projects/create-draft-item-for-authenticated-user', + method: 'POST', + path: '/user/{user_id}/projectsV2/{project_number}/drafts', + pathParams: ['project_number', 'user_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/projectsV2/{project_number}/drafts` + /// Create draft item for organization owned project + static const projectsCreateDraftItemForOrg = RestOperationContract( + operationId: 'projects/create-draft-item-for-org', + method: 'POST', + path: '/orgs/{org}/projectsV2/{project_number}/drafts', + pathParams: ['org', 'project_number'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /orgs/{org}/projectsV2/{project_number}/views` + /// Create a view for an organization-owned project + static const projectsCreateViewForOrg = RestOperationContract( + operationId: 'projects/create-view-for-org', + method: 'POST', + path: '/orgs/{org}/projectsV2/{project_number}/views', + pathParams: ['org', 'project_number'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /users/{user_id}/projectsV2/{project_number}/views` + /// Create a view for a user-owned project + static const projectsCreateViewForUser = RestOperationContract( + operationId: 'projects/create-view-for-user', + method: 'POST', + path: '/users/{user_id}/projectsV2/{project_number}/views', + pathParams: ['project_number', 'user_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /orgs/{org}/projectsV2/{project_number}/items/{item_id}` + /// Delete project item for organization + static const projectsDeleteItemForOrg = RestOperationContract( + operationId: 'projects/delete-item-for-org', + method: 'DELETE', + path: '/orgs/{org}/projectsV2/{project_number}/items/{item_id}', + pathParams: ['item_id', 'org', 'project_number'], + successStatuses: [204], + ); + + /// `DELETE /users/{username}/projectsV2/{project_number}/items/{item_id}` + /// Delete project item for user + static const projectsDeleteItemForUser = RestOperationContract( + operationId: 'projects/delete-item-for-user', + method: 'DELETE', + path: '/users/{username}/projectsV2/{project_number}/items/{item_id}', + pathParams: ['item_id', 'project_number', 'username'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/projectsV2/{project_number}/fields/{field_id}` + /// Get project field for organization + static const projectsGetFieldForOrg = RestOperationContract( + operationId: 'projects/get-field-for-org', + method: 'GET', + path: '/orgs/{org}/projectsV2/{project_number}/fields/{field_id}', + pathParams: ['field_id', 'org', 'project_number'], + ); + + /// `GET /users/{username}/projectsV2/{project_number}/fields/{field_id}` + /// Get project field for user + static const projectsGetFieldForUser = RestOperationContract( + operationId: 'projects/get-field-for-user', + method: 'GET', + path: '/users/{username}/projectsV2/{project_number}/fields/{field_id}', + pathParams: ['field_id', 'project_number', 'username'], + ); + + /// `GET /orgs/{org}/projectsV2/{project_number}` + /// Get project for organization + static const projectsGetForOrg = RestOperationContract( + operationId: 'projects/get-for-org', + method: 'GET', + path: '/orgs/{org}/projectsV2/{project_number}', + pathParams: ['org', 'project_number'], + ); + + /// `GET /users/{username}/projectsV2/{project_number}` + /// Get project for user + static const projectsGetForUser = RestOperationContract( + operationId: 'projects/get-for-user', + method: 'GET', + path: '/users/{username}/projectsV2/{project_number}', + pathParams: ['project_number', 'username'], + ); + + /// `GET /orgs/{org}/projectsV2/{project_number}/items/{item_id}` + /// Get an item for an organization owned project + static const projectsGetOrgItem = RestOperationContract( + operationId: 'projects/get-org-item', + method: 'GET', + path: '/orgs/{org}/projectsV2/{project_number}/items/{item_id}', + pathParams: ['item_id', 'org', 'project_number'], + queryParams: ['fields'], + ); + + /// `GET /users/{username}/projectsV2/{project_number}/items/{item_id}` + /// Get an item for a user owned project + static const projectsGetUserItem = RestOperationContract( + operationId: 'projects/get-user-item', + method: 'GET', + path: '/users/{username}/projectsV2/{project_number}/items/{item_id}', + pathParams: ['item_id', 'project_number', 'username'], + queryParams: ['fields'], + ); + + /// `GET /orgs/{org}/projectsV2/{project_number}/fields` + /// List project fields for organization + static const projectsListFieldsForOrg = RestOperationContract( + operationId: 'projects/list-fields-for-org', + method: 'GET', + path: '/orgs/{org}/projectsV2/{project_number}/fields', + pathParams: ['org', 'project_number'], + queryParams: ['after', 'before', 'per_page'], + ); + + /// `GET /users/{username}/projectsV2/{project_number}/fields` + /// List project fields for user + static const projectsListFieldsForUser = RestOperationContract( + operationId: 'projects/list-fields-for-user', + method: 'GET', + path: '/users/{username}/projectsV2/{project_number}/fields', + pathParams: ['project_number', 'username'], + queryParams: ['after', 'before', 'per_page'], + ); + + /// `GET /orgs/{org}/projectsV2` + /// List projects for organization + static const projectsListForOrg = RestOperationContract( + operationId: 'projects/list-for-org', + method: 'GET', + path: '/orgs/{org}/projectsV2', + pathParams: ['org'], + queryParams: ['after', 'before', 'per_page', 'q'], + ); + + /// `GET /users/{username}/projectsV2` + /// List projects for user + static const projectsListForUser = RestOperationContract( + operationId: 'projects/list-for-user', + method: 'GET', + path: '/users/{username}/projectsV2', + pathParams: ['username'], + queryParams: ['after', 'before', 'per_page', 'q'], + ); + + /// `GET /orgs/{org}/projectsV2/{project_number}/items` + /// List items for an organization owned project + static const projectsListItemsForOrg = RestOperationContract( + operationId: 'projects/list-items-for-org', + method: 'GET', + path: '/orgs/{org}/projectsV2/{project_number}/items', + pathParams: ['org', 'project_number'], + queryParams: ['after', 'before', 'fields', 'per_page', 'q'], + ); + + /// `GET /users/{username}/projectsV2/{project_number}/items` + /// List items for a user owned project + static const projectsListItemsForUser = RestOperationContract( + operationId: 'projects/list-items-for-user', + method: 'GET', + path: '/users/{username}/projectsV2/{project_number}/items', + pathParams: ['project_number', 'username'], + queryParams: ['after', 'before', 'fields', 'per_page', 'q'], + ); + + /// `GET /orgs/{org}/projectsV2/{project_number}/views/{view_number}/items` + /// List items for an organization project view + static const projectsListViewItemsForOrg = RestOperationContract( + operationId: 'projects/list-view-items-for-org', + method: 'GET', + path: '/orgs/{org}/projectsV2/{project_number}/views/{view_number}/items', + pathParams: ['org', 'project_number', 'view_number'], + queryParams: ['after', 'before', 'fields', 'per_page'], + ); + + /// `GET /users/{username}/projectsV2/{project_number}/views/{view_number}/items` + /// List items for a user project view + static const projectsListViewItemsForUser = RestOperationContract( + operationId: 'projects/list-view-items-for-user', + method: 'GET', + path: + '/users/{username}/projectsV2/{project_number}/views/{view_number}/items', + pathParams: ['project_number', 'username', 'view_number'], + queryParams: ['after', 'before', 'fields', 'per_page'], + ); + + /// `PATCH /orgs/{org}/projectsV2/{project_number}/items/{item_id}` + /// Update project item for organization + static const projectsUpdateItemForOrg = RestOperationContract( + operationId: 'projects/update-item-for-org', + method: 'PATCH', + path: '/orgs/{org}/projectsV2/{project_number}/items/{item_id}', + pathParams: ['item_id', 'org', 'project_number'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /users/{username}/projectsV2/{project_number}/items/{item_id}` + /// Update project item for user + static const projectsUpdateItemForUser = RestOperationContract( + operationId: 'projects/update-item-for-user', + method: 'PATCH', + path: '/users/{username}/projectsV2/{project_number}/items/{item_id}', + pathParams: ['item_id', 'project_number', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/stacks/{stack_number}/add` + /// Add pull requests to a pull request stack + static const pullRequestStacksAdd = RestOperationContract( + operationId: 'pull-request-stacks/add', + method: 'POST', + path: '/repos/{owner}/{repo}/stacks/{stack_number}/add', + pathParams: ['owner', 'repo', 'stack_number'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/stacks` + /// Create a pull request stack + static const pullRequestStacksCreate = RestOperationContract( + operationId: 'pull-request-stacks/create', + method: 'POST', + path: '/repos/{owner}/{repo}/stacks', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `GET /repos/{owner}/{repo}/stacks/{stack_number}` + /// Get a pull request stack + static const pullRequestStacksGet = RestOperationContract( + operationId: 'pull-request-stacks/get', + method: 'GET', + path: '/repos/{owner}/{repo}/stacks/{stack_number}', + pathParams: ['owner', 'repo', 'stack_number'], + ); + + /// `GET /repos/{owner}/{repo}/stacks` + /// List pull request stacks + static const pullRequestStacksList = RestOperationContract( + operationId: 'pull-request-stacks/list', + method: 'GET', + path: '/repos/{owner}/{repo}/stacks', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page', 'pull_request'], + ); + + /// `POST /repos/{owner}/{repo}/stacks/{stack_number}/unstack` + /// Remove pull requests from a pull request stack + static const pullRequestStacksUnstack = RestOperationContract( + operationId: 'pull-request-stacks/unstack', + method: 'POST', + path: '/repos/{owner}/{repo}/stacks/{stack_number}/unstack', + pathParams: ['owner', 'repo', 'stack_number'], + successStatuses: [200, 204], + ); + + /// `GET /repos/{owner}/{repo}/pulls/{pull_number}/merge` + /// Check if a pull request has been merged + static const pullsCheckIfMerged = RestOperationContract( + operationId: 'pulls/check-if-merged', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/merge', + pathParams: ['owner', 'pull_number', 'repo'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/pulls` + /// Create a pull request + static const pullsCreate = RestOperationContract( + operationId: 'pulls/create', + method: 'POST', + path: '/repos/{owner}/{repo}/pulls', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies` + /// Create a reply for a review comment + static const pullsCreateReplyForReviewComment = RestOperationContract( + operationId: 'pulls/create-reply-for-review-comment', + method: 'POST', + path: + '/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies', + pathParams: ['comment_id', 'owner', 'pull_number', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews` + /// Create a review for a pull request + static const pullsCreateReview = RestOperationContract( + operationId: 'pulls/create-review', + method: 'POST', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/reviews', + pathParams: ['owner', 'pull_number', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/pulls/{pull_number}/comments` + /// Create a review comment for a pull request + static const pullsCreateReviewComment = RestOperationContract( + operationId: 'pulls/create-review-comment', + method: 'POST', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/comments', + pathParams: ['owner', 'pull_number', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}` + /// Delete a pending review for a pull request + static const pullsDeletePendingReview = RestOperationContract( + operationId: 'pulls/delete-pending-review', + method: 'DELETE', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}', + pathParams: ['owner', 'pull_number', 'repo', 'review_id'], + ); + + /// `DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}` + /// Delete a review comment for a pull request + static const pullsDeleteReviewComment = RestOperationContract( + operationId: 'pulls/delete-review-comment', + method: 'DELETE', + path: '/repos/{owner}/{repo}/pulls/comments/{comment_id}', + pathParams: ['comment_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/dismissals` + /// Dismiss a review for a pull request + static const pullsDismissReview = RestOperationContract( + operationId: 'pulls/dismiss-review', + method: 'PUT', + path: + '/repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/dismissals', + pathParams: ['owner', 'pull_number', 'repo', 'review_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /repos/{owner}/{repo}/pulls/{pull_number}` + /// Get a pull request + static const pullsGet = RestOperationContract( + operationId: 'pulls/get', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls/{pull_number}', + pathParams: ['owner', 'pull_number', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/pulls/{pull_number}/merge-async/{uuid}` + /// Get the result of an asynchronous merge + static const pullsGetMergeAsyncResult = RestOperationContract( + operationId: 'pulls/get-merge-async-result', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/merge-async/{uuid}', + pathParams: ['owner', 'pull_number', 'repo', 'uuid'], + ); + + /// `GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}` + /// Get a review for a pull request + static const pullsGetReview = RestOperationContract( + operationId: 'pulls/get-review', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}', + pathParams: ['owner', 'pull_number', 'repo', 'review_id'], + ); + + /// `GET /repos/{owner}/{repo}/pulls/comments/{comment_id}` + /// Get a review comment for a pull request + static const pullsGetReviewComment = RestOperationContract( + operationId: 'pulls/get-review-comment', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls/comments/{comment_id}', + pathParams: ['comment_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/pulls` + /// List pull requests + static const pullsList = RestOperationContract( + operationId: 'pulls/list', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls', + pathParams: ['owner', 'repo'], + queryParams: [ + 'base', + 'direction', + 'head', + 'page', + 'per_page', + 'sort', + 'state' + ], + ); + + /// `GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments` + /// List comments for a pull request review + static const pullsListCommentsForReview = RestOperationContract( + operationId: 'pulls/list-comments-for-review', + method: 'GET', + path: + '/repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments', + pathParams: ['owner', 'pull_number', 'repo', 'review_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/pulls/{pull_number}/commits` + /// List commits on a pull request + static const pullsListCommits = RestOperationContract( + operationId: 'pulls/list-commits', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/commits', + pathParams: ['owner', 'pull_number', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/pulls/{pull_number}/files` + /// List pull requests files + static const pullsListFiles = RestOperationContract( + operationId: 'pulls/list-files', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/files', + pathParams: ['owner', 'pull_number', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers` + /// Get all requested reviewers for a pull request + static const pullsListRequestedReviewers = RestOperationContract( + operationId: 'pulls/list-requested-reviewers', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers', + pathParams: ['owner', 'pull_number', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/pulls/{pull_number}/comments` + /// List review comments on a pull request + static const pullsListReviewComments = RestOperationContract( + operationId: 'pulls/list-review-comments', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/comments', + pathParams: ['owner', 'pull_number', 'repo'], + queryParams: ['direction', 'page', 'per_page', 'since', 'sort'], + ); + + /// `GET /repos/{owner}/{repo}/pulls/comments` + /// List review comments in a repository + static const pullsListReviewCommentsForRepo = RestOperationContract( + operationId: 'pulls/list-review-comments-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls/comments', + pathParams: ['owner', 'repo'], + queryParams: ['direction', 'page', 'per_page', 'since', 'sort'], + ); + + /// `GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews` + /// List reviews for a pull request + static const pullsListReviews = RestOperationContract( + operationId: 'pulls/list-reviews', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/reviews', + pathParams: ['owner', 'pull_number', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge` + /// Merge a pull request + static const pullsMerge = RestOperationContract( + operationId: 'pulls/merge', + method: 'PUT', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/merge', + pathParams: ['owner', 'pull_number', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge-async` + /// Merge a pull request asynchronously + static const pullsMergeAsync = RestOperationContract( + operationId: 'pulls/merge-async', + method: 'PUT', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/merge-async', + pathParams: ['owner', 'pull_number', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 202], + ); + + /// `DELETE /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers` + /// Remove requested reviewers from a pull request + static const pullsRemoveRequestedReviewers = RestOperationContract( + operationId: 'pulls/remove-requested-reviewers', + method: 'DELETE', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers', + pathParams: ['owner', 'pull_number', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers` + /// Request reviewers for a pull request + static const pullsRequestReviewers = RestOperationContract( + operationId: 'pulls/request-reviewers', + method: 'POST', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers', + pathParams: ['owner', 'pull_number', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/events` + /// Submit a review for a pull request + static const pullsSubmitReview = RestOperationContract( + operationId: 'pulls/submit-review', + method: 'POST', + path: + '/repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/events', + pathParams: ['owner', 'pull_number', 'repo', 'review_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/pulls/{pull_number}` + /// Update a pull request + static const pullsUpdate = RestOperationContract( + operationId: 'pulls/update', + method: 'PATCH', + path: '/repos/{owner}/{repo}/pulls/{pull_number}', + pathParams: ['owner', 'pull_number', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/pulls/{pull_number}/update-branch` + /// Update a pull request branch + static const pullsUpdateBranch = RestOperationContract( + operationId: 'pulls/update-branch', + method: 'PUT', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/update-branch', + pathParams: ['owner', 'pull_number', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202], + ); + + /// `PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}` + /// Update a review for a pull request + static const pullsUpdateReview = RestOperationContract( + operationId: 'pulls/update-review', + method: 'PUT', + path: '/repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}', + pathParams: ['owner', 'pull_number', 'repo', 'review_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}` + /// Update a review comment for a pull request + static const pullsUpdateReviewComment = RestOperationContract( + operationId: 'pulls/update-review-comment', + method: 'PATCH', + path: '/repos/{owner}/{repo}/pulls/comments/{comment_id}', + pathParams: ['comment_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /rate_limit` + /// Get rate limit status for the authenticated user + static const rateLimitGet = RestOperationContract( + operationId: 'rate-limit/get', + method: 'GET', + path: '/rate_limit', + ); + + /// `POST /repos/{owner}/{repo}/comments/{comment_id}/reactions` + /// Create reaction for a commit comment + static const reactionsCreateForCommitComment = RestOperationContract( + operationId: 'reactions/create-for-commit-comment', + method: 'POST', + path: '/repos/{owner}/{repo}/comments/{comment_id}/reactions', + pathParams: ['comment_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 201], + ); + + /// `POST /repos/{owner}/{repo}/issues/{issue_number}/reactions` + /// Create reaction for an issue + static const reactionsCreateForIssue = RestOperationContract( + operationId: 'reactions/create-for-issue', + method: 'POST', + path: '/repos/{owner}/{repo}/issues/{issue_number}/reactions', + pathParams: ['issue_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 201], + ); + + /// `POST /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions` + /// Create reaction for an issue comment + static const reactionsCreateForIssueComment = RestOperationContract( + operationId: 'reactions/create-for-issue-comment', + method: 'POST', + path: '/repos/{owner}/{repo}/issues/comments/{comment_id}/reactions', + pathParams: ['comment_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 201], + ); + + /// `POST /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions` + /// Create reaction for a pull request review comment + static const reactionsCreateForPullRequestReviewComment = + RestOperationContract( + operationId: 'reactions/create-for-pull-request-review-comment', + method: 'POST', + path: '/repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions', + pathParams: ['comment_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 201], + ); + + /// `POST /repos/{owner}/{repo}/releases/{release_id}/reactions` + /// Create reaction for a release + static const reactionsCreateForRelease = RestOperationContract( + operationId: 'reactions/create-for-release', + method: 'POST', + path: '/repos/{owner}/{repo}/releases/{release_id}/reactions', + pathParams: ['owner', 'release_id', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 201], + ); + + /// `DELETE /repos/{owner}/{repo}/comments/{comment_id}/reactions/{reaction_id}` + /// Delete a commit comment reaction + static const reactionsDeleteForCommitComment = RestOperationContract( + operationId: 'reactions/delete-for-commit-comment', + method: 'DELETE', + path: '/repos/{owner}/{repo}/comments/{comment_id}/reactions/{reaction_id}', + pathParams: ['comment_id', 'owner', 'reaction_id', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/issues/{issue_number}/reactions/{reaction_id}` + /// Delete an issue reaction + static const reactionsDeleteForIssue = RestOperationContract( + operationId: 'reactions/delete-for-issue', + method: 'DELETE', + path: '/repos/{owner}/{repo}/issues/{issue_number}/reactions/{reaction_id}', + pathParams: ['issue_number', 'owner', 'reaction_id', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions/{reaction_id}` + /// Delete an issue comment reaction + static const reactionsDeleteForIssueComment = RestOperationContract( + operationId: 'reactions/delete-for-issue-comment', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/issues/comments/{comment_id}/reactions/{reaction_id}', + pathParams: ['comment_id', 'owner', 'reaction_id', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions/{reaction_id}` + /// Delete a pull request comment reaction + static const reactionsDeleteForPullRequestComment = RestOperationContract( + operationId: 'reactions/delete-for-pull-request-comment', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions/{reaction_id}', + pathParams: ['comment_id', 'owner', 'reaction_id', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/releases/{release_id}/reactions/{reaction_id}` + /// Delete a release reaction + static const reactionsDeleteForRelease = RestOperationContract( + operationId: 'reactions/delete-for-release', + method: 'DELETE', + path: '/repos/{owner}/{repo}/releases/{release_id}/reactions/{reaction_id}', + pathParams: ['owner', 'reaction_id', 'release_id', 'repo'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/comments/{comment_id}/reactions` + /// List reactions for a commit comment + static const reactionsListForCommitComment = RestOperationContract( + operationId: 'reactions/list-for-commit-comment', + method: 'GET', + path: '/repos/{owner}/{repo}/comments/{comment_id}/reactions', + pathParams: ['comment_id', 'owner', 'repo'], + queryParams: ['content', 'page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/issues/{issue_number}/reactions` + /// List reactions for an issue + static const reactionsListForIssue = RestOperationContract( + operationId: 'reactions/list-for-issue', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/{issue_number}/reactions', + pathParams: ['issue_number', 'owner', 'repo'], + queryParams: ['content', 'page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions` + /// List reactions for an issue comment + static const reactionsListForIssueComment = RestOperationContract( + operationId: 'reactions/list-for-issue-comment', + method: 'GET', + path: '/repos/{owner}/{repo}/issues/comments/{comment_id}/reactions', + pathParams: ['comment_id', 'owner', 'repo'], + queryParams: ['content', 'page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions` + /// List reactions for a pull request review comment + static const reactionsListForPullRequestReviewComment = RestOperationContract( + operationId: 'reactions/list-for-pull-request-review-comment', + method: 'GET', + path: '/repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions', + pathParams: ['comment_id', 'owner', 'repo'], + queryParams: ['content', 'page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/releases/{release_id}/reactions` + /// List reactions for a release + static const reactionsListForRelease = RestOperationContract( + operationId: 'reactions/list-for-release', + method: 'GET', + path: '/repos/{owner}/{repo}/releases/{release_id}/reactions', + pathParams: ['owner', 'release_id', 'repo'], + queryParams: ['content', 'page', 'per_page'], + ); + + /// `PATCH /user/repository_invitations/{invitation_id}` + /// Accept a repository invitation + static const reposAcceptInvitationForAuthenticatedUser = + RestOperationContract( + operationId: 'repos/accept-invitation-for-authenticated-user', + method: 'PATCH', + path: '/user/repository_invitations/{invitation_id}', + pathParams: ['invitation_id'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps` + /// Add app access restrictions + static const reposAddAppAccessRestrictions = RestOperationContract( + operationId: 'repos/add-app-access-restrictions', + method: 'POST', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/collaborators/{username}` + /// Add a repository collaborator + static const reposAddCollaborator = RestOperationContract( + operationId: 'repos/add-collaborator', + method: 'PUT', + path: '/repos/{owner}/{repo}/collaborators/{username}', + pathParams: ['owner', 'repo', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 204], + ); + + /// `POST /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts` + /// Add status check contexts + static const reposAddStatusCheckContexts = RestOperationContract( + operationId: 'repos/add-status-check-contexts', + method: 'POST', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams` + /// Add team access restrictions + static const reposAddTeamAccessRestrictions = RestOperationContract( + operationId: 'repos/add-team-access-restrictions', + method: 'POST', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users` + /// Add user access restrictions + static const reposAddUserAccessRestrictions = RestOperationContract( + operationId: 'repos/add-user-access-restrictions', + method: 'POST', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/pages/deployments/{pages_deployment_id}/cancel` + /// Cancel a GitHub Pages deployment + static const reposCancelPagesDeployment = RestOperationContract( + operationId: 'repos/cancel-pages-deployment', + method: 'POST', + path: + '/repos/{owner}/{repo}/pages/deployments/{pages_deployment_id}/cancel', + pathParams: ['owner', 'pages_deployment_id', 'repo'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/automated-security-fixes` + /// Check if Dependabot security updates are enabled for a repository + static const reposCheckAutomatedSecurityFixes = RestOperationContract( + operationId: 'repos/check-automated-security-fixes', + method: 'GET', + path: '/repos/{owner}/{repo}/automated-security-fixes', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/collaborators/{username}` + /// Check if a user is a repository collaborator + static const reposCheckCollaborator = RestOperationContract( + operationId: 'repos/check-collaborator', + method: 'GET', + path: '/repos/{owner}/{repo}/collaborators/{username}', + pathParams: ['owner', 'repo', 'username'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/immutable-releases` + /// Check if immutable releases are enabled for a repository + static const reposCheckImmutableReleases = RestOperationContract( + operationId: 'repos/check-immutable-releases', + method: 'GET', + path: '/repos/{owner}/{repo}/immutable-releases', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/private-vulnerability-reporting` + /// Check if private vulnerability reporting is enabled for a repository + static const reposCheckPrivateVulnerabilityReporting = RestOperationContract( + operationId: 'repos/check-private-vulnerability-reporting', + method: 'GET', + path: '/repos/{owner}/{repo}/private-vulnerability-reporting', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/vulnerability-alerts` + /// Check if vulnerability alerts are enabled for a repository + static const reposCheckVulnerabilityAlerts = RestOperationContract( + operationId: 'repos/check-vulnerability-alerts', + method: 'GET', + path: '/repos/{owner}/{repo}/vulnerability-alerts', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/codeowners/errors` + /// List CODEOWNERS errors + static const reposCodeownersErrors = RestOperationContract( + operationId: 'repos/codeowners-errors', + method: 'GET', + path: '/repos/{owner}/{repo}/codeowners/errors', + pathParams: ['owner', 'repo'], + queryParams: ['ref'], + ); + + /// `GET /repos/{owner}/{repo}/compare/{basehead}` + /// Compare two commits + static const reposCompareCommits = RestOperationContract( + operationId: 'repos/compare-commits', + method: 'GET', + path: '/repos/{owner}/{repo}/compare/{basehead}', + pathParams: ['basehead', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `POST /repos/{owner}/{repo}/attestations` + /// Create an attestation + static const reposCreateAttestation = RestOperationContract( + operationId: 'repos/create-attestation', + method: 'POST', + path: '/repos/{owner}/{repo}/attestations', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/autolinks` + /// Create an autolink reference for a repository + static const reposCreateAutolink = RestOperationContract( + operationId: 'repos/create-autolink', + method: 'POST', + path: '/repos/{owner}/{repo}/autolinks', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/commits/{commit_sha}/comments` + /// Create a commit comment + static const reposCreateCommitComment = RestOperationContract( + operationId: 'repos/create-commit-comment', + method: 'POST', + path: '/repos/{owner}/{repo}/commits/{commit_sha}/comments', + pathParams: ['commit_sha', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures` + /// Create commit signature protection + static const reposCreateCommitSignatureProtection = RestOperationContract( + operationId: 'repos/create-commit-signature-protection', + method: 'POST', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_signatures', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `POST /repos/{owner}/{repo}/statuses/{sha}` + /// Create a commit status + static const reposCreateCommitStatus = RestOperationContract( + operationId: 'repos/create-commit-status', + method: 'POST', + path: '/repos/{owner}/{repo}/statuses/{sha}', + pathParams: ['owner', 'repo', 'sha'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/keys` + /// Create a deploy key + static const reposCreateDeployKey = RestOperationContract( + operationId: 'repos/create-deploy-key', + method: 'POST', + path: '/repos/{owner}/{repo}/keys', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/deployments` + /// Create a deployment + static const reposCreateDeployment = RestOperationContract( + operationId: 'repos/create-deployment', + method: 'POST', + path: '/repos/{owner}/{repo}/deployments', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 202], + ); + + /// `POST /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies` + /// Create a deployment branch policy + static const reposCreateDeploymentBranchPolicy = RestOperationContract( + operationId: 'repos/create-deployment-branch-policy', + method: 'POST', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies', + pathParams: ['environment_name', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules` + /// Create a custom deployment protection rule on an environment + static const reposCreateDeploymentProtectionRule = RestOperationContract( + operationId: 'repos/create-deployment-protection-rule', + method: 'POST', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules', + pathParams: ['environment_name', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses` + /// Create a deployment status + static const reposCreateDeploymentStatus = RestOperationContract( + operationId: 'repos/create-deployment-status', + method: 'POST', + path: '/repos/{owner}/{repo}/deployments/{deployment_id}/statuses', + pathParams: ['deployment_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/dispatches` + /// Create a repository dispatch event + static const reposCreateDispatchEvent = RestOperationContract( + operationId: 'repos/create-dispatch-event', + method: 'POST', + path: '/repos/{owner}/{repo}/dispatches', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `POST /user/repos` + /// Create a repository for the authenticated user + static const reposCreateForAuthenticatedUser = RestOperationContract( + operationId: 'repos/create-for-authenticated-user', + method: 'POST', + path: '/user/repos', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/forks` + /// Create a fork + static const reposCreateFork = RestOperationContract( + operationId: 'repos/create-fork', + method: 'POST', + path: '/repos/{owner}/{repo}/forks', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202], + ); + + /// `POST /orgs/{org}/repos` + /// Create an organization repository + static const reposCreateInOrg = RestOperationContract( + operationId: 'repos/create-in-org', + method: 'POST', + path: '/orgs/{org}/repos', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `PUT /repos/{owner}/{repo}/environments/{environment_name}` + /// Create or update an environment + static const reposCreateOrUpdateEnvironment = RestOperationContract( + operationId: 'repos/create-or-update-environment', + method: 'PUT', + path: '/repos/{owner}/{repo}/environments/{environment_name}', + pathParams: ['environment_name', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/contents/{path}` + /// Create or update file contents + static const reposCreateOrUpdateFileContents = RestOperationContract( + operationId: 'repos/create-or-update-file-contents', + method: 'PUT', + path: '/repos/{owner}/{repo}/contents/{path}', + pathParams: ['owner', 'path', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 201], + ); + + /// `POST /orgs/{org}/rulesets` + /// Create an organization repository ruleset + static const reposCreateOrgRuleset = RestOperationContract( + operationId: 'repos/create-org-ruleset', + method: 'POST', + path: '/orgs/{org}/rulesets', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/pages/deployments` + /// Create a GitHub Pages deployment + static const reposCreatePagesDeployment = RestOperationContract( + operationId: 'repos/create-pages-deployment', + method: 'POST', + path: '/repos/{owner}/{repo}/pages/deployments', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/pages` + /// Create a GitHub Pages site + static const reposCreatePagesSite = RestOperationContract( + operationId: 'repos/create-pages-site', + method: 'POST', + path: '/repos/{owner}/{repo}/pages', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/releases` + /// Create a release + static const reposCreateRelease = RestOperationContract( + operationId: 'repos/create-release', + method: 'POST', + path: '/repos/{owner}/{repo}/releases', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/rulesets` + /// Create a repository ruleset + static const reposCreateRepoRuleset = RestOperationContract( + operationId: 'repos/create-repo-ruleset', + method: 'POST', + path: '/repos/{owner}/{repo}/rulesets', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{template_owner}/{template_repo}/generate` + /// Create a repository using a template + static const reposCreateUsingTemplate = RestOperationContract( + operationId: 'repos/create-using-template', + method: 'POST', + path: '/repos/{template_owner}/{template_repo}/generate', + pathParams: ['template_owner', 'template_repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/hooks` + /// Create a repository webhook + static const reposCreateWebhook = RestOperationContract( + operationId: 'repos/create-webhook', + method: 'POST', + path: '/repos/{owner}/{repo}/hooks', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `PATCH /repos/{owner}/{repo}/properties/values` + /// Create or update custom property values for a repository + static const reposCustomPropertiesForReposCreateOrUpdateRepositoryValues = + RestOperationContract( + operationId: + 'repos/custom-properties-for-repos-create-or-update-repository-values', + method: 'PATCH', + path: '/repos/{owner}/{repo}/properties/values', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/properties/values` + /// Get all custom property values for a repository + static const reposCustomPropertiesForReposGetRepositoryValues = + RestOperationContract( + operationId: 'repos/custom-properties-for-repos-get-repository-values', + method: 'GET', + path: '/repos/{owner}/{repo}/properties/values', + pathParams: ['owner', 'repo'], + ); + + /// `DELETE /user/repository_invitations/{invitation_id}` + /// Decline a repository invitation + static const reposDeclineInvitationForAuthenticatedUser = + RestOperationContract( + operationId: 'repos/decline-invitation-for-authenticated-user', + method: 'DELETE', + path: '/user/repository_invitations/{invitation_id}', + pathParams: ['invitation_id'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}` + /// Delete a repository + static const reposDelete = RestOperationContract( + operationId: 'repos/delete', + method: 'DELETE', + path: '/repos/{owner}/{repo}', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions` + /// Delete access restrictions + static const reposDeleteAccessRestrictions = RestOperationContract( + operationId: 'repos/delete-access-restrictions', + method: 'DELETE', + path: '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions', + pathParams: ['branch', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins` + /// Delete admin branch protection + static const reposDeleteAdminBranchProtection = RestOperationContract( + operationId: 'repos/delete-admin-branch-protection', + method: 'DELETE', + path: '/repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins', + pathParams: ['branch', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/environments/{environment_name}` + /// Delete an environment + static const reposDeleteAnEnvironment = RestOperationContract( + operationId: 'repos/delete-an-environment', + method: 'DELETE', + path: '/repos/{owner}/{repo}/environments/{environment_name}', + pathParams: ['environment_name', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/autolinks/{autolink_id}` + /// Delete an autolink reference from a repository + static const reposDeleteAutolink = RestOperationContract( + operationId: 'repos/delete-autolink', + method: 'DELETE', + path: '/repos/{owner}/{repo}/autolinks/{autolink_id}', + pathParams: ['autolink_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/branches/{branch}/protection` + /// Delete branch protection + static const reposDeleteBranchProtection = RestOperationContract( + operationId: 'repos/delete-branch-protection', + method: 'DELETE', + path: '/repos/{owner}/{repo}/branches/{branch}/protection', + pathParams: ['branch', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/comments/{comment_id}` + /// Delete a commit comment + static const reposDeleteCommitComment = RestOperationContract( + operationId: 'repos/delete-commit-comment', + method: 'DELETE', + path: '/repos/{owner}/{repo}/comments/{comment_id}', + pathParams: ['comment_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures` + /// Delete commit signature protection + static const reposDeleteCommitSignatureProtection = RestOperationContract( + operationId: 'repos/delete-commit-signature-protection', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_signatures', + pathParams: ['branch', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/keys/{key_id}` + /// Delete a deploy key + static const reposDeleteDeployKey = RestOperationContract( + operationId: 'repos/delete-deploy-key', + method: 'DELETE', + path: '/repos/{owner}/{repo}/keys/{key_id}', + pathParams: ['key_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/deployments/{deployment_id}` + /// Delete a deployment + static const reposDeleteDeployment = RestOperationContract( + operationId: 'repos/delete-deployment', + method: 'DELETE', + path: '/repos/{owner}/{repo}/deployments/{deployment_id}', + pathParams: ['deployment_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies/{branch_policy_id}` + /// Delete a deployment branch policy + static const reposDeleteDeploymentBranchPolicy = RestOperationContract( + operationId: 'repos/delete-deployment-branch-policy', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies/{branch_policy_id}', + pathParams: ['branch_policy_id', 'environment_name', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/contents/{path}` + /// Delete a file + static const reposDeleteFile = RestOperationContract( + operationId: 'repos/delete-file', + method: 'DELETE', + path: '/repos/{owner}/{repo}/contents/{path}', + pathParams: ['owner', 'path', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /repos/{owner}/{repo}/invitations/{invitation_id}` + /// Delete a repository invitation + static const reposDeleteInvitation = RestOperationContract( + operationId: 'repos/delete-invitation', + method: 'DELETE', + path: '/repos/{owner}/{repo}/invitations/{invitation_id}', + pathParams: ['invitation_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/rulesets/{ruleset_id}` + /// Delete an organization repository ruleset + static const reposDeleteOrgRuleset = RestOperationContract( + operationId: 'repos/delete-org-ruleset', + method: 'DELETE', + path: '/orgs/{org}/rulesets/{ruleset_id}', + pathParams: ['org', 'ruleset_id'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/pages` + /// Delete a GitHub Pages site + static const reposDeletePagesSite = RestOperationContract( + operationId: 'repos/delete-pages-site', + method: 'DELETE', + path: '/repos/{owner}/{repo}/pages', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews` + /// Delete pull request review protection + static const reposDeletePullRequestReviewProtection = RestOperationContract( + operationId: 'repos/delete-pull-request-review-protection', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews', + pathParams: ['branch', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/releases/{release_id}` + /// Delete a release + static const reposDeleteRelease = RestOperationContract( + operationId: 'repos/delete-release', + method: 'DELETE', + path: '/repos/{owner}/{repo}/releases/{release_id}', + pathParams: ['owner', 'release_id', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/releases/assets/{asset_id}` + /// Delete a release asset + static const reposDeleteReleaseAsset = RestOperationContract( + operationId: 'repos/delete-release-asset', + method: 'DELETE', + path: '/repos/{owner}/{repo}/releases/assets/{asset_id}', + pathParams: ['asset_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/rulesets/{ruleset_id}` + /// Delete a repository ruleset + static const reposDeleteRepoRuleset = RestOperationContract( + operationId: 'repos/delete-repo-ruleset', + method: 'DELETE', + path: '/repos/{owner}/{repo}/rulesets/{ruleset_id}', + pathParams: ['owner', 'repo', 'ruleset_id'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/hooks/{hook_id}` + /// Delete a repository webhook + static const reposDeleteWebhook = RestOperationContract( + operationId: 'repos/delete-webhook', + method: 'DELETE', + path: '/repos/{owner}/{repo}/hooks/{hook_id}', + pathParams: ['hook_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/automated-security-fixes` + /// Disable Dependabot security updates + static const reposDisableAutomatedSecurityFixes = RestOperationContract( + operationId: 'repos/disable-automated-security-fixes', + method: 'DELETE', + path: '/repos/{owner}/{repo}/automated-security-fixes', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/{protection_rule_id}` + /// Disable a custom protection rule for an environment + static const reposDisableDeploymentProtectionRule = RestOperationContract( + operationId: 'repos/disable-deployment-protection-rule', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/{protection_rule_id}', + pathParams: ['environment_name', 'owner', 'protection_rule_id', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/immutable-releases` + /// Disable immutable releases + static const reposDisableImmutableReleases = RestOperationContract( + operationId: 'repos/disable-immutable-releases', + method: 'DELETE', + path: '/repos/{owner}/{repo}/immutable-releases', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/private-vulnerability-reporting` + /// Disable private vulnerability reporting for a repository + static const reposDisablePrivateVulnerabilityReporting = + RestOperationContract( + operationId: 'repos/disable-private-vulnerability-reporting', + method: 'DELETE', + path: '/repos/{owner}/{repo}/private-vulnerability-reporting', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/vulnerability-alerts` + /// Disable vulnerability alerts + static const reposDisableVulnerabilityAlerts = RestOperationContract( + operationId: 'repos/disable-vulnerability-alerts', + method: 'DELETE', + path: '/repos/{owner}/{repo}/vulnerability-alerts', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `GET /repos/{owner}/{repo}/tarball/{ref}` + /// Download a repository archive (tar) + static const reposDownloadTarballArchive = RestOperationContract( + operationId: 'repos/download-tarball-archive', + method: 'GET', + path: '/repos/{owner}/{repo}/tarball/{ref}', + pathParams: ['owner', 'ref', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/zipball/{ref}` + /// Download a repository archive (zip) + static const reposDownloadZipballArchive = RestOperationContract( + operationId: 'repos/download-zipball-archive', + method: 'GET', + path: '/repos/{owner}/{repo}/zipball/{ref}', + pathParams: ['owner', 'ref', 'repo'], + ); + + /// `PUT /repos/{owner}/{repo}/automated-security-fixes` + /// Enable Dependabot security updates + static const reposEnableAutomatedSecurityFixes = RestOperationContract( + operationId: 'repos/enable-automated-security-fixes', + method: 'PUT', + path: '/repos/{owner}/{repo}/automated-security-fixes', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/immutable-releases` + /// Enable immutable releases + static const reposEnableImmutableReleases = RestOperationContract( + operationId: 'repos/enable-immutable-releases', + method: 'PUT', + path: '/repos/{owner}/{repo}/immutable-releases', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/private-vulnerability-reporting` + /// Enable private vulnerability reporting for a repository + static const reposEnablePrivateVulnerabilityReporting = RestOperationContract( + operationId: 'repos/enable-private-vulnerability-reporting', + method: 'PUT', + path: '/repos/{owner}/{repo}/private-vulnerability-reporting', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `PUT /repos/{owner}/{repo}/vulnerability-alerts` + /// Enable vulnerability alerts + static const reposEnableVulnerabilityAlerts = RestOperationContract( + operationId: 'repos/enable-vulnerability-alerts', + method: 'PUT', + path: '/repos/{owner}/{repo}/vulnerability-alerts', + pathParams: ['owner', 'repo'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/releases/generate-notes` + /// Generate release notes content for a release + static const reposGenerateReleaseNotes = RestOperationContract( + operationId: 'repos/generate-release-notes', + method: 'POST', + path: '/repos/{owner}/{repo}/releases/generate-notes', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /repos/{owner}/{repo}` + /// Get a repository + static const reposGet = RestOperationContract( + operationId: 'repos/get', + method: 'GET', + path: '/repos/{owner}/{repo}', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions` + /// Get access restrictions + static const reposGetAccessRestrictions = RestOperationContract( + operationId: 'repos/get-access-restrictions', + method: 'GET', + path: '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins` + /// Get admin branch protection + static const reposGetAdminBranchProtection = RestOperationContract( + operationId: 'repos/get-admin-branch-protection', + method: 'GET', + path: '/repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules` + /// Get all deployment protection rules for an environment + static const reposGetAllDeploymentProtectionRules = RestOperationContract( + operationId: 'repos/get-all-deployment-protection-rules', + method: 'GET', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules', + pathParams: ['environment_name', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/environments` + /// List environments + static const reposGetAllEnvironments = RestOperationContract( + operationId: 'repos/get-all-environments', + method: 'GET', + path: '/repos/{owner}/{repo}/environments', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts` + /// Get all status check contexts + static const reposGetAllStatusCheckContexts = RestOperationContract( + operationId: 'repos/get-all-status-check-contexts', + method: 'GET', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/topics` + /// Get all repository topics + static const reposGetAllTopics = RestOperationContract( + operationId: 'repos/get-all-topics', + method: 'GET', + path: '/repos/{owner}/{repo}/topics', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps` + /// Get apps with access to the protected branch + static const reposGetAppsWithAccessToProtectedBranch = RestOperationContract( + operationId: 'repos/get-apps-with-access-to-protected-branch', + method: 'GET', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/autolinks/{autolink_id}` + /// Get an autolink reference of a repository + static const reposGetAutolink = RestOperationContract( + operationId: 'repos/get-autolink', + method: 'GET', + path: '/repos/{owner}/{repo}/autolinks/{autolink_id}', + pathParams: ['autolink_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/branches/{branch}` + /// Get a branch + static const reposGetBranch = RestOperationContract( + operationId: 'repos/get-branch', + method: 'GET', + path: '/repos/{owner}/{repo}/branches/{branch}', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/branches/{branch}/protection` + /// Get branch protection + static const reposGetBranchProtection = RestOperationContract( + operationId: 'repos/get-branch-protection', + method: 'GET', + path: '/repos/{owner}/{repo}/branches/{branch}/protection', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/rules/branches/{branch}` + /// Get rules for a branch + static const reposGetBranchRules = RestOperationContract( + operationId: 'repos/get-branch-rules', + method: 'GET', + path: '/repos/{owner}/{repo}/rules/branches/{branch}', + pathParams: ['branch', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/traffic/clones` + /// Get repository clones + static const reposGetClones = RestOperationContract( + operationId: 'repos/get-clones', + method: 'GET', + path: '/repos/{owner}/{repo}/traffic/clones', + pathParams: ['owner', 'repo'], + queryParams: ['per'], + ); + + /// `GET /repos/{owner}/{repo}/stats/code_frequency` + /// Get the weekly commit activity + static const reposGetCodeFrequencyStats = RestOperationContract( + operationId: 'repos/get-code-frequency-stats', + method: 'GET', + path: '/repos/{owner}/{repo}/stats/code_frequency', + pathParams: ['owner', 'repo'], + successStatuses: [200, 202, 204], + ); + + /// `GET /repos/{owner}/{repo}/collaborators/{username}/permission` + /// Get repository permissions for a user + static const reposGetCollaboratorPermissionLevel = RestOperationContract( + operationId: 'repos/get-collaborator-permission-level', + method: 'GET', + path: '/repos/{owner}/{repo}/collaborators/{username}/permission', + pathParams: ['owner', 'repo', 'username'], + ); + + /// `GET /repos/{owner}/{repo}/commits/{ref}/status` + /// Get the combined status for a specific reference + static const reposGetCombinedStatusForRef = RestOperationContract( + operationId: 'repos/get-combined-status-for-ref', + method: 'GET', + path: '/repos/{owner}/{repo}/commits/{ref}/status', + pathParams: ['owner', 'ref', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/commits/{ref}` + /// Get a commit + static const reposGetCommit = RestOperationContract( + operationId: 'repos/get-commit', + method: 'GET', + path: '/repos/{owner}/{repo}/commits/{ref}', + pathParams: ['owner', 'ref', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/stats/commit_activity` + /// Get the last year of commit activity + static const reposGetCommitActivityStats = RestOperationContract( + operationId: 'repos/get-commit-activity-stats', + method: 'GET', + path: '/repos/{owner}/{repo}/stats/commit_activity', + pathParams: ['owner', 'repo'], + successStatuses: [200, 202, 204], + ); + + /// `GET /repos/{owner}/{repo}/comments/{comment_id}` + /// Get a commit comment + static const reposGetCommitComment = RestOperationContract( + operationId: 'repos/get-commit-comment', + method: 'GET', + path: '/repos/{owner}/{repo}/comments/{comment_id}', + pathParams: ['comment_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures` + /// Get commit signature protection + static const reposGetCommitSignatureProtection = RestOperationContract( + operationId: 'repos/get-commit-signature-protection', + method: 'GET', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_signatures', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/community/profile` + /// Get community profile metrics + static const reposGetCommunityProfileMetrics = RestOperationContract( + operationId: 'repos/get-community-profile-metrics', + method: 'GET', + path: '/repos/{owner}/{repo}/community/profile', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/contents/{path}` + /// Get repository content + static const reposGetContent = RestOperationContract( + operationId: 'repos/get-content', + method: 'GET', + path: '/repos/{owner}/{repo}/contents/{path}', + pathParams: ['owner', 'path', 'repo'], + queryParams: ['ref'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /repos/{owner}/{repo}/stats/contributors` + /// Get all contributor commit activity + static const reposGetContributorsStats = RestOperationContract( + operationId: 'repos/get-contributors-stats', + method: 'GET', + path: '/repos/{owner}/{repo}/stats/contributors', + pathParams: ['owner', 'repo'], + successStatuses: [200, 202, 204], + ); + + /// `GET /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/{protection_rule_id}` + /// Get a custom deployment protection rule + static const reposGetCustomDeploymentProtectionRule = RestOperationContract( + operationId: 'repos/get-custom-deployment-protection-rule', + method: 'GET', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/{protection_rule_id}', + pathParams: ['environment_name', 'owner', 'protection_rule_id', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/keys/{key_id}` + /// Get a deploy key + static const reposGetDeployKey = RestOperationContract( + operationId: 'repos/get-deploy-key', + method: 'GET', + path: '/repos/{owner}/{repo}/keys/{key_id}', + pathParams: ['key_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/deployments/{deployment_id}` + /// Get a deployment + static const reposGetDeployment = RestOperationContract( + operationId: 'repos/get-deployment', + method: 'GET', + path: '/repos/{owner}/{repo}/deployments/{deployment_id}', + pathParams: ['deployment_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies/{branch_policy_id}` + /// Get a deployment branch policy + static const reposGetDeploymentBranchPolicy = RestOperationContract( + operationId: 'repos/get-deployment-branch-policy', + method: 'GET', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies/{branch_policy_id}', + pathParams: ['branch_policy_id', 'environment_name', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses/{status_id}` + /// Get a deployment status + static const reposGetDeploymentStatus = RestOperationContract( + operationId: 'repos/get-deployment-status', + method: 'GET', + path: + '/repos/{owner}/{repo}/deployments/{deployment_id}/statuses/{status_id}', + pathParams: ['deployment_id', 'owner', 'repo', 'status_id'], + ); + + /// `GET /repos/{owner}/{repo}/environments/{environment_name}` + /// Get an environment + static const reposGetEnvironment = RestOperationContract( + operationId: 'repos/get-environment', + method: 'GET', + path: '/repos/{owner}/{repo}/environments/{environment_name}', + pathParams: ['environment_name', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/hash-algorithm` + /// Get the hash algorithm for a repository + static const reposGetHashAlgorithm = RestOperationContract( + operationId: 'repos/get-hash-algorithm', + method: 'GET', + path: '/repos/{owner}/{repo}/hash-algorithm', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/pages/builds/latest` + /// Get latest Pages build + static const reposGetLatestPagesBuild = RestOperationContract( + operationId: 'repos/get-latest-pages-build', + method: 'GET', + path: '/repos/{owner}/{repo}/pages/builds/latest', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/releases/latest` + /// Get the latest release + static const reposGetLatestRelease = RestOperationContract( + operationId: 'repos/get-latest-release', + method: 'GET', + path: '/repos/{owner}/{repo}/releases/latest', + pathParams: ['owner', 'repo'], + ); + + /// `GET /orgs/{org}/rulesets/rule-suites/{rule_suite_id}` + /// Get an organization rule suite + static const reposGetOrgRuleSuite = RestOperationContract( + operationId: 'repos/get-org-rule-suite', + method: 'GET', + path: '/orgs/{org}/rulesets/rule-suites/{rule_suite_id}', + pathParams: ['org', 'rule_suite_id'], + ); + + /// `GET /orgs/{org}/rulesets/rule-suites` + /// List organization rule suites + static const reposGetOrgRuleSuites = RestOperationContract( + operationId: 'repos/get-org-rule-suites', + method: 'GET', + path: '/orgs/{org}/rulesets/rule-suites', + pathParams: ['org'], + queryParams: [ + 'actor_name', + 'evaluate_status', + 'page', + 'per_page', + 'ref', + 'repository_name', + 'rule_suite_result', + 'time_period' + ], + ); + + /// `GET /orgs/{org}/rulesets/{ruleset_id}` + /// Get an organization repository ruleset + static const reposGetOrgRuleset = RestOperationContract( + operationId: 'repos/get-org-ruleset', + method: 'GET', + path: '/orgs/{org}/rulesets/{ruleset_id}', + pathParams: ['org', 'ruleset_id'], + ); + + /// `GET /orgs/{org}/rulesets` + /// Get all organization repository rulesets + static const reposGetOrgRulesets = RestOperationContract( + operationId: 'repos/get-org-rulesets', + method: 'GET', + path: '/orgs/{org}/rulesets', + pathParams: ['org'], + queryParams: ['page', 'per_page', 'targets'], + ); + + /// `GET /repos/{owner}/{repo}/pages` + /// Get a GitHub Pages site + static const reposGetPages = RestOperationContract( + operationId: 'repos/get-pages', + method: 'GET', + path: '/repos/{owner}/{repo}/pages', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/pages/builds/{build_id}` + /// Get GitHub Pages build + static const reposGetPagesBuild = RestOperationContract( + operationId: 'repos/get-pages-build', + method: 'GET', + path: '/repos/{owner}/{repo}/pages/builds/{build_id}', + pathParams: ['build_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/pages/deployments/{pages_deployment_id}` + /// Get the status of a GitHub Pages deployment + static const reposGetPagesDeployment = RestOperationContract( + operationId: 'repos/get-pages-deployment', + method: 'GET', + path: '/repos/{owner}/{repo}/pages/deployments/{pages_deployment_id}', + pathParams: ['owner', 'pages_deployment_id', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/pages/health` + /// Get a DNS health check for GitHub Pages + static const reposGetPagesHealthCheck = RestOperationContract( + operationId: 'repos/get-pages-health-check', + method: 'GET', + path: '/repos/{owner}/{repo}/pages/health', + pathParams: ['owner', 'repo'], + successStatuses: [200, 202], + ); + + /// `GET /repos/{owner}/{repo}/stats/participation` + /// Get the weekly commit count + static const reposGetParticipationStats = RestOperationContract( + operationId: 'repos/get-participation-stats', + method: 'GET', + path: '/repos/{owner}/{repo}/stats/participation', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews` + /// Get pull request review protection + static const reposGetPullRequestReviewProtection = RestOperationContract( + operationId: 'repos/get-pull-request-review-protection', + method: 'GET', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/stats/punch_card` + /// Get the hourly commit count for each day + static const reposGetPunchCardStats = RestOperationContract( + operationId: 'repos/get-punch-card-stats', + method: 'GET', + path: '/repos/{owner}/{repo}/stats/punch_card', + pathParams: ['owner', 'repo'], + successStatuses: [200, 204], + ); + + /// `GET /repos/{owner}/{repo}/readme` + /// Get a repository README + static const reposGetReadme = RestOperationContract( + operationId: 'repos/get-readme', + method: 'GET', + path: '/repos/{owner}/{repo}/readme', + pathParams: ['owner', 'repo'], + queryParams: ['ref'], + ); + + /// `GET /repos/{owner}/{repo}/readme/{dir}` + /// Get a repository README for a directory + static const reposGetReadmeInDirectory = RestOperationContract( + operationId: 'repos/get-readme-in-directory', + method: 'GET', + path: '/repos/{owner}/{repo}/readme/{dir}', + pathParams: ['dir', 'owner', 'repo'], + queryParams: ['ref'], + ); + + /// `GET /repos/{owner}/{repo}/releases/{release_id}` + /// Get a release + static const reposGetRelease = RestOperationContract( + operationId: 'repos/get-release', + method: 'GET', + path: '/repos/{owner}/{repo}/releases/{release_id}', + pathParams: ['owner', 'release_id', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/releases/assets/{asset_id}` + /// Get a release asset + static const reposGetReleaseAsset = RestOperationContract( + operationId: 'repos/get-release-asset', + method: 'GET', + path: '/repos/{owner}/{repo}/releases/assets/{asset_id}', + pathParams: ['asset_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/releases/tags/{tag}` + /// Get a release by tag name + static const reposGetReleaseByTag = RestOperationContract( + operationId: 'repos/get-release-by-tag', + method: 'GET', + path: '/repos/{owner}/{repo}/releases/tags/{tag}', + pathParams: ['owner', 'repo', 'tag'], + ); + + /// `GET /repos/{owner}/{repo}/rulesets/rule-suites/{rule_suite_id}` + /// Get a repository rule suite + static const reposGetRepoRuleSuite = RestOperationContract( + operationId: 'repos/get-repo-rule-suite', + method: 'GET', + path: '/repos/{owner}/{repo}/rulesets/rule-suites/{rule_suite_id}', + pathParams: ['owner', 'repo', 'rule_suite_id'], + ); + + /// `GET /repos/{owner}/{repo}/rulesets/rule-suites` + /// List repository rule suites + static const reposGetRepoRuleSuites = RestOperationContract( + operationId: 'repos/get-repo-rule-suites', + method: 'GET', + path: '/repos/{owner}/{repo}/rulesets/rule-suites', + pathParams: ['owner', 'repo'], + queryParams: [ + 'actor_name', + 'evaluate_status', + 'page', + 'per_page', + 'ref', + 'rule_suite_result', + 'time_period' + ], + ); + + /// `GET /repos/{owner}/{repo}/rulesets/{ruleset_id}` + /// Get a repository ruleset + static const reposGetRepoRuleset = RestOperationContract( + operationId: 'repos/get-repo-ruleset', + method: 'GET', + path: '/repos/{owner}/{repo}/rulesets/{ruleset_id}', + pathParams: ['owner', 'repo', 'ruleset_id'], + queryParams: ['includes_parents'], + ); + + /// `GET /repos/{owner}/{repo}/rulesets/{ruleset_id}/history` + /// Get repository ruleset history + static const reposGetRepoRulesetHistory = RestOperationContract( + operationId: 'repos/get-repo-ruleset-history', + method: 'GET', + path: '/repos/{owner}/{repo}/rulesets/{ruleset_id}/history', + pathParams: ['owner', 'repo', 'ruleset_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/rulesets/{ruleset_id}/history/{version_id}` + /// Get repository ruleset version + static const reposGetRepoRulesetVersion = RestOperationContract( + operationId: 'repos/get-repo-ruleset-version', + method: 'GET', + path: '/repos/{owner}/{repo}/rulesets/{ruleset_id}/history/{version_id}', + pathParams: ['owner', 'repo', 'ruleset_id', 'version_id'], + ); + + /// `GET /repos/{owner}/{repo}/rulesets` + /// Get all repository rulesets + static const reposGetRepoRulesets = RestOperationContract( + operationId: 'repos/get-repo-rulesets', + method: 'GET', + path: '/repos/{owner}/{repo}/rulesets', + pathParams: ['owner', 'repo'], + queryParams: ['includes_parents', 'page', 'per_page', 'targets'], + ); + + /// `GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks` + /// Get status checks protection + static const reposGetStatusChecksProtection = RestOperationContract( + operationId: 'repos/get-status-checks-protection', + method: 'GET', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams` + /// Get teams with access to the protected branch + static const reposGetTeamsWithAccessToProtectedBranch = RestOperationContract( + operationId: 'repos/get-teams-with-access-to-protected-branch', + method: 'GET', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/traffic/popular/paths` + /// Get top referral paths + static const reposGetTopPaths = RestOperationContract( + operationId: 'repos/get-top-paths', + method: 'GET', + path: '/repos/{owner}/{repo}/traffic/popular/paths', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/traffic/popular/referrers` + /// Get top referral sources + static const reposGetTopReferrers = RestOperationContract( + operationId: 'repos/get-top-referrers', + method: 'GET', + path: '/repos/{owner}/{repo}/traffic/popular/referrers', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users` + /// Get users with access to the protected branch + static const reposGetUsersWithAccessToProtectedBranch = RestOperationContract( + operationId: 'repos/get-users-with-access-to-protected-branch', + method: 'GET', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/traffic/views` + /// Get page views + static const reposGetViews = RestOperationContract( + operationId: 'repos/get-views', + method: 'GET', + path: '/repos/{owner}/{repo}/traffic/views', + pathParams: ['owner', 'repo'], + queryParams: ['per'], + ); + + /// `GET /repos/{owner}/{repo}/hooks/{hook_id}` + /// Get a repository webhook + static const reposGetWebhook = RestOperationContract( + operationId: 'repos/get-webhook', + method: 'GET', + path: '/repos/{owner}/{repo}/hooks/{hook_id}', + pathParams: ['hook_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/hooks/{hook_id}/config` + /// Get a webhook configuration for a repository + static const reposGetWebhookConfigForRepo = RestOperationContract( + operationId: 'repos/get-webhook-config-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/hooks/{hook_id}/config', + pathParams: ['hook_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries/{delivery_id}` + /// Get a delivery for a repository webhook + static const reposGetWebhookDelivery = RestOperationContract( + operationId: 'repos/get-webhook-delivery', + method: 'GET', + path: '/repos/{owner}/{repo}/hooks/{hook_id}/deliveries/{delivery_id}', + pathParams: ['delivery_id', 'hook_id', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/activity` + /// List repository activities + static const reposListActivities = RestOperationContract( + operationId: 'repos/list-activities', + method: 'GET', + path: '/repos/{owner}/{repo}/activity', + pathParams: ['owner', 'repo'], + queryParams: [ + 'activity_type', + 'actor', + 'after', + 'before', + 'direction', + 'per_page', + 'ref', + 'time_period' + ], + ); + + /// `GET /repos/{owner}/{repo}/attestations/{subject_digest}` + /// List attestations + static const reposListAttestations = RestOperationContract( + operationId: 'repos/list-attestations', + method: 'GET', + path: '/repos/{owner}/{repo}/attestations/{subject_digest}', + pathParams: ['owner', 'repo', 'subject_digest'], + queryParams: ['after', 'before', 'per_page', 'predicate_type'], + ); + + /// `GET /repos/{owner}/{repo}/autolinks` + /// Get all autolinks of a repository + static const reposListAutolinks = RestOperationContract( + operationId: 'repos/list-autolinks', + method: 'GET', + path: '/repos/{owner}/{repo}/autolinks', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/branches` + /// List branches + static const reposListBranches = RestOperationContract( + operationId: 'repos/list-branches', + method: 'GET', + path: '/repos/{owner}/{repo}/branches', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page', 'protected'], + ); + + /// `GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head` + /// List branches for HEAD commit + static const reposListBranchesForHeadCommit = RestOperationContract( + operationId: 'repos/list-branches-for-head-commit', + method: 'GET', + path: '/repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head', + pathParams: ['commit_sha', 'owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/collaborators` + /// List repository collaborators + static const reposListCollaborators = RestOperationContract( + operationId: 'repos/list-collaborators', + method: 'GET', + path: '/repos/{owner}/{repo}/collaborators', + pathParams: ['owner', 'repo'], + queryParams: ['affiliation', 'page', 'per_page', 'permission'], + ); + + /// `GET /repos/{owner}/{repo}/commits/{commit_sha}/comments` + /// List commit comments + static const reposListCommentsForCommit = RestOperationContract( + operationId: 'repos/list-comments-for-commit', + method: 'GET', + path: '/repos/{owner}/{repo}/commits/{commit_sha}/comments', + pathParams: ['commit_sha', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/comments` + /// List commit comments for a repository + static const reposListCommitCommentsForRepo = RestOperationContract( + operationId: 'repos/list-commit-comments-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/comments', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/commits/{ref}/statuses` + /// List commit statuses for a reference + static const reposListCommitStatusesForRef = RestOperationContract( + operationId: 'repos/list-commit-statuses-for-ref', + method: 'GET', + path: '/repos/{owner}/{repo}/commits/{ref}/statuses', + pathParams: ['owner', 'ref', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/commits` + /// List commits + static const reposListCommits = RestOperationContract( + operationId: 'repos/list-commits', + method: 'GET', + path: '/repos/{owner}/{repo}/commits', + pathParams: ['owner', 'repo'], + queryParams: [ + 'author', + 'committer', + 'page', + 'path', + 'per_page', + 'sha', + 'since', + 'until' + ], + ); + + /// `GET /repos/{owner}/{repo}/contributors` + /// List repository contributors + static const reposListContributors = RestOperationContract( + operationId: 'repos/list-contributors', + method: 'GET', + path: '/repos/{owner}/{repo}/contributors', + pathParams: ['owner', 'repo'], + queryParams: ['anon', 'page', 'per_page'], + successStatuses: [200, 204], + ); + + /// `GET /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/apps` + /// List custom deployment rule integrations available for an environment + static const reposListCustomDeploymentRuleIntegrations = + RestOperationContract( + operationId: 'repos/list-custom-deployment-rule-integrations', + method: 'GET', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/apps', + pathParams: ['environment_name', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/keys` + /// List deploy keys + static const reposListDeployKeys = RestOperationContract( + operationId: 'repos/list-deploy-keys', + method: 'GET', + path: '/repos/{owner}/{repo}/keys', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies` + /// List deployment branch policies + static const reposListDeploymentBranchPolicies = RestOperationContract( + operationId: 'repos/list-deployment-branch-policies', + method: 'GET', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies', + pathParams: ['environment_name', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses` + /// List deployment statuses + static const reposListDeploymentStatuses = RestOperationContract( + operationId: 'repos/list-deployment-statuses', + method: 'GET', + path: '/repos/{owner}/{repo}/deployments/{deployment_id}/statuses', + pathParams: ['deployment_id', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/deployments` + /// List deployments + static const reposListDeployments = RestOperationContract( + operationId: 'repos/list-deployments', + method: 'GET', + path: '/repos/{owner}/{repo}/deployments', + pathParams: ['owner', 'repo'], + queryParams: ['environment', 'page', 'per_page', 'ref', 'sha', 'task'], + ); + + /// `GET /user/repos` + /// List repositories for the authenticated user + static const reposListForAuthenticatedUser = RestOperationContract( + operationId: 'repos/list-for-authenticated-user', + method: 'GET', + path: '/user/repos', + queryParams: [ + 'affiliation', + 'before', + 'direction', + 'page', + 'per_page', + 'since', + 'sort', + 'type', + 'visibility' + ], + ); + + /// `GET /orgs/{org}/repos` + /// List organization repositories + static const reposListForOrg = RestOperationContract( + operationId: 'repos/list-for-org', + method: 'GET', + path: '/orgs/{org}/repos', + pathParams: ['org'], + queryParams: ['direction', 'page', 'per_page', 'sort', 'type'], + ); + + /// `GET /users/{username}/repos` + /// List repositories for a user + static const reposListForUser = RestOperationContract( + operationId: 'repos/list-for-user', + method: 'GET', + path: '/users/{username}/repos', + pathParams: ['username'], + queryParams: ['direction', 'page', 'per_page', 'sort', 'type'], + ); + + /// `GET /repos/{owner}/{repo}/forks` + /// List forks + static const reposListForks = RestOperationContract( + operationId: 'repos/list-forks', + method: 'GET', + path: '/repos/{owner}/{repo}/forks', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page', 'sort'], + ); + + /// `GET /repos/{owner}/{repo}/invitations` + /// List repository invitations + static const reposListInvitations = RestOperationContract( + operationId: 'repos/list-invitations', + method: 'GET', + path: '/repos/{owner}/{repo}/invitations', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/repository_invitations` + /// List repository invitations for the authenticated user + static const reposListInvitationsForAuthenticatedUser = RestOperationContract( + operationId: 'repos/list-invitations-for-authenticated-user', + method: 'GET', + path: '/user/repository_invitations', + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/issue-types` + /// List issue types for a repository + static const reposListIssueTypes = RestOperationContract( + operationId: 'repos/list-issue-types', + method: 'GET', + path: '/repos/{owner}/{repo}/issue-types', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/languages` + /// List repository languages + static const reposListLanguages = RestOperationContract( + operationId: 'repos/list-languages', + method: 'GET', + path: '/repos/{owner}/{repo}/languages', + pathParams: ['owner', 'repo'], + ); + + /// `GET /repos/{owner}/{repo}/pages/builds` + /// List GitHub Pages builds + static const reposListPagesBuilds = RestOperationContract( + operationId: 'repos/list-pages-builds', + method: 'GET', + path: '/repos/{owner}/{repo}/pages/builds', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repositories` + /// List public repositories + static const reposListPublic = RestOperationContract( + operationId: 'repos/list-public', + method: 'GET', + path: '/repositories', + queryParams: ['since'], + ); + + /// `GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls` + /// List pull requests associated with a commit + static const reposListPullRequestsAssociatedWithCommit = + RestOperationContract( + operationId: 'repos/list-pull-requests-associated-with-commit', + method: 'GET', + path: '/repos/{owner}/{repo}/commits/{commit_sha}/pulls', + pathParams: ['commit_sha', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/releases/{release_id}/assets` + /// List release assets + static const reposListReleaseAssets = RestOperationContract( + operationId: 'repos/list-release-assets', + method: 'GET', + path: '/repos/{owner}/{repo}/releases/{release_id}/assets', + pathParams: ['owner', 'release_id', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/releases` + /// List releases + static const reposListReleases = RestOperationContract( + operationId: 'repos/list-releases', + method: 'GET', + path: '/repos/{owner}/{repo}/releases', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/tags` + /// List repository tags + static const reposListTags = RestOperationContract( + operationId: 'repos/list-tags', + method: 'GET', + path: '/repos/{owner}/{repo}/tags', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/teams` + /// List repository teams + static const reposListTeams = RestOperationContract( + operationId: 'repos/list-teams', + method: 'GET', + path: '/repos/{owner}/{repo}/teams', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries` + /// List deliveries for a repository webhook + static const reposListWebhookDeliveries = RestOperationContract( + operationId: 'repos/list-webhook-deliveries', + method: 'GET', + path: '/repos/{owner}/{repo}/hooks/{hook_id}/deliveries', + pathParams: ['hook_id', 'owner', 'repo'], + queryParams: ['cursor', 'per_page', 'status'], + ); + + /// `GET /repos/{owner}/{repo}/hooks` + /// List repository webhooks + static const reposListWebhooks = RestOperationContract( + operationId: 'repos/list-webhooks', + method: 'GET', + path: '/repos/{owner}/{repo}/hooks', + pathParams: ['owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `POST /repos/{owner}/{repo}/merges` + /// Merge a branch + static const reposMerge = RestOperationContract( + operationId: 'repos/merge', + method: 'POST', + path: '/repos/{owner}/{repo}/merges', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201, 204], + ); + + /// `POST /repos/{owner}/{repo}/merge-upstream` + /// Sync a fork branch with the upstream repository + static const reposMergeUpstream = RestOperationContract( + operationId: 'repos/merge-upstream', + method: 'POST', + path: '/repos/{owner}/{repo}/merge-upstream', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/hooks/{hook_id}/pings` + /// Ping a repository webhook + static const reposPingWebhook = RestOperationContract( + operationId: 'repos/ping-webhook', + method: 'POST', + path: '/repos/{owner}/{repo}/hooks/{hook_id}/pings', + pathParams: ['hook_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/hooks/{hook_id}/deliveries/{delivery_id}/attempts` + /// Redeliver a delivery for a repository webhook + static const reposRedeliverWebhookDelivery = RestOperationContract( + operationId: 'repos/redeliver-webhook-delivery', + method: 'POST', + path: + '/repos/{owner}/{repo}/hooks/{hook_id}/deliveries/{delivery_id}/attempts', + pathParams: ['delivery_id', 'hook_id', 'owner', 'repo'], + successStatuses: [202], + ); + + /// `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps` + /// Remove app access restrictions + static const reposRemoveAppAccessRestrictions = RestOperationContract( + operationId: 'repos/remove-app-access-restrictions', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /repos/{owner}/{repo}/collaborators/{username}` + /// Remove a repository collaborator + static const reposRemoveCollaborator = RestOperationContract( + operationId: 'repos/remove-collaborator', + method: 'DELETE', + path: '/repos/{owner}/{repo}/collaborators/{username}', + pathParams: ['owner', 'repo', 'username'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts` + /// Remove status check contexts + static const reposRemoveStatusCheckContexts = RestOperationContract( + operationId: 'repos/remove-status-check-contexts', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks` + /// Remove status check protection + static const reposRemoveStatusCheckProtection = RestOperationContract( + operationId: 'repos/remove-status-check-protection', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks', + pathParams: ['branch', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams` + /// Remove team access restrictions + static const reposRemoveTeamAccessRestrictions = RestOperationContract( + operationId: 'repos/remove-team-access-restrictions', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users` + /// Remove user access restrictions + static const reposRemoveUserAccessRestrictions = RestOperationContract( + operationId: 'repos/remove-user-access-restrictions', + method: 'DELETE', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/branches/{branch}/rename` + /// Rename a branch + static const reposRenameBranch = RestOperationContract( + operationId: 'repos/rename-branch', + method: 'POST', + path: '/repos/{owner}/{repo}/branches/{branch}/rename', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `PUT /repos/{owner}/{repo}/topics` + /// Replace all repository topics + static const reposReplaceAllTopics = RestOperationContract( + operationId: 'repos/replace-all-topics', + method: 'PUT', + path: '/repos/{owner}/{repo}/topics', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/pages/builds` + /// Request a GitHub Pages build + static const reposRequestPagesBuild = RestOperationContract( + operationId: 'repos/request-pages-build', + method: 'POST', + path: '/repos/{owner}/{repo}/pages/builds', + pathParams: ['owner', 'repo'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins` + /// Set admin branch protection + static const reposSetAdminBranchProtection = RestOperationContract( + operationId: 'repos/set-admin-branch-protection', + method: 'POST', + path: '/repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins', + pathParams: ['branch', 'owner', 'repo'], + ); + + /// `PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps` + /// Set app access restrictions + static const reposSetAppAccessRestrictions = RestOperationContract( + operationId: 'repos/set-app-access-restrictions', + method: 'PUT', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts` + /// Set status check contexts + static const reposSetStatusCheckContexts = RestOperationContract( + operationId: 'repos/set-status-check-contexts', + method: 'PUT', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams` + /// Set team access restrictions + static const reposSetTeamAccessRestrictions = RestOperationContract( + operationId: 'repos/set-team-access-restrictions', + method: 'PUT', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users` + /// Set user access restrictions + static const reposSetUserAccessRestrictions = RestOperationContract( + operationId: 'repos/set-user-access-restrictions', + method: 'PUT', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/hooks/{hook_id}/tests` + /// Test the push repository webhook + static const reposTestPushWebhook = RestOperationContract( + operationId: 'repos/test-push-webhook', + method: 'POST', + path: '/repos/{owner}/{repo}/hooks/{hook_id}/tests', + pathParams: ['hook_id', 'owner', 'repo'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/transfer` + /// Transfer a repository + static const reposTransfer = RestOperationContract( + operationId: 'repos/transfer', + method: 'POST', + path: '/repos/{owner}/{repo}/transfer', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [202], + ); + + /// `PATCH /repos/{owner}/{repo}` + /// Update a repository + static const reposUpdate = RestOperationContract( + operationId: 'repos/update', + method: 'PATCH', + path: '/repos/{owner}/{repo}', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/branches/{branch}/protection` + /// Update branch protection + static const reposUpdateBranchProtection = RestOperationContract( + operationId: 'repos/update-branch-protection', + method: 'PUT', + path: '/repos/{owner}/{repo}/branches/{branch}/protection', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/comments/{comment_id}` + /// Update a commit comment + static const reposUpdateCommitComment = RestOperationContract( + operationId: 'repos/update-commit-comment', + method: 'PATCH', + path: '/repos/{owner}/{repo}/comments/{comment_id}', + pathParams: ['comment_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies/{branch_policy_id}` + /// Update a deployment branch policy + static const reposUpdateDeploymentBranchPolicy = RestOperationContract( + operationId: 'repos/update-deployment-branch-policy', + method: 'PUT', + path: + '/repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies/{branch_policy_id}', + pathParams: ['branch_policy_id', 'environment_name', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/pages` + /// Update information about a GitHub Pages site + static const reposUpdateInformationAboutPagesSite = RestOperationContract( + operationId: 'repos/update-information-about-pages-site', + method: 'PUT', + path: '/repos/{owner}/{repo}/pages', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PATCH /repos/{owner}/{repo}/invitations/{invitation_id}` + /// Update a repository invitation + static const reposUpdateInvitation = RestOperationContract( + operationId: 'repos/update-invitation', + method: 'PATCH', + path: '/repos/{owner}/{repo}/invitations/{invitation_id}', + pathParams: ['invitation_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /orgs/{org}/rulesets/{ruleset_id}` + /// Update an organization repository ruleset + static const reposUpdateOrgRuleset = RestOperationContract( + operationId: 'repos/update-org-ruleset', + method: 'PUT', + path: '/orgs/{org}/rulesets/{ruleset_id}', + pathParams: ['org', 'ruleset_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews` + /// Update pull request review protection + static const reposUpdatePullRequestReviewProtection = RestOperationContract( + operationId: 'repos/update-pull-request-review-protection', + method: 'PATCH', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/releases/{release_id}` + /// Update a release + static const reposUpdateRelease = RestOperationContract( + operationId: 'repos/update-release', + method: 'PATCH', + path: '/repos/{owner}/{repo}/releases/{release_id}', + pathParams: ['owner', 'release_id', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}` + /// Update a release asset + static const reposUpdateReleaseAsset = RestOperationContract( + operationId: 'repos/update-release-asset', + method: 'PATCH', + path: '/repos/{owner}/{repo}/releases/assets/{asset_id}', + pathParams: ['asset_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /repos/{owner}/{repo}/rulesets/{ruleset_id}` + /// Update a repository ruleset + static const reposUpdateRepoRuleset = RestOperationContract( + operationId: 'repos/update-repo-ruleset', + method: 'PUT', + path: '/repos/{owner}/{repo}/rulesets/{ruleset_id}', + pathParams: ['owner', 'repo', 'ruleset_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks` + /// Update status check protection + static const reposUpdateStatusCheckProtection = RestOperationContract( + operationId: 'repos/update-status-check-protection', + method: 'PATCH', + path: + '/repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks', + pathParams: ['branch', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/hooks/{hook_id}` + /// Update a repository webhook + static const reposUpdateWebhook = RestOperationContract( + operationId: 'repos/update-webhook', + method: 'PATCH', + path: '/repos/{owner}/{repo}/hooks/{hook_id}', + pathParams: ['hook_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config` + /// Update a webhook configuration for a repository + static const reposUpdateWebhookConfigForRepo = RestOperationContract( + operationId: 'repos/update-webhook-config-for-repo', + method: 'PATCH', + path: '/repos/{owner}/{repo}/hooks/{hook_id}/config', + pathParams: ['hook_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/releases/{release_id}/assets` + /// Upload a release asset + static const reposUploadReleaseAsset = RestOperationContract( + operationId: 'repos/upload-release-asset', + method: 'POST', + path: '/repos/{owner}/{repo}/releases/{release_id}/assets', + pathParams: ['owner', 'release_id', 'repo'], + queryParams: ['label', 'name'], + hasRequestBody: true, + requestMediaTypes: ['application/octet-stream'], + successStatuses: [201], + ); + + /// `GET /search/code` + /// Search code + static const searchCode = RestOperationContract( + operationId: 'search/code', + method: 'GET', + path: '/search/code', + queryParams: ['order', 'page', 'per_page', 'q', 'sort'], + ); + + /// `GET /search/commits` + /// Search commits + static const searchCommits = RestOperationContract( + operationId: 'search/commits', + method: 'GET', + path: '/search/commits', + queryParams: ['order', 'page', 'per_page', 'q', 'sort'], + ); + + /// `GET /search/issues` + /// Search issues and pull requests + static const searchIssuesAndPullRequests = RestOperationContract( + operationId: 'search/issues-and-pull-requests', + method: 'GET', + path: '/search/issues', + queryParams: [ + 'advanced_search', + 'order', + 'page', + 'per_page', + 'q', + 'search_type', + 'sort' + ], + ); + + /// `GET /search/labels` + /// Search labels + static const searchLabels = RestOperationContract( + operationId: 'search/labels', + method: 'GET', + path: '/search/labels', + queryParams: ['order', 'page', 'per_page', 'q', 'repository_id', 'sort'], + ); + + /// `GET /search/repositories` + /// Search repositories + static const searchRepos = RestOperationContract( + operationId: 'search/repos', + method: 'GET', + path: '/search/repositories', + queryParams: ['order', 'page', 'per_page', 'q', 'sort'], + ); + + /// `GET /search/topics` + /// Search topics + static const searchTopics = RestOperationContract( + operationId: 'search/topics', + method: 'GET', + path: '/search/topics', + queryParams: ['page', 'per_page', 'q'], + ); + + /// `GET /search/users` + /// Search users + static const searchUsers = RestOperationContract( + operationId: 'search/users', + method: 'GET', + path: '/search/users', + queryParams: ['order', 'page', 'per_page', 'q', 'sort'], + ); + + /// `POST /orgs/{org}/secret-scanning/custom-patterns` + /// Bulk create organization custom patterns + static const secretScanningBulkCreateOrgCustomPatterns = + RestOperationContract( + operationId: 'secret-scanning/bulk-create-org-custom-patterns', + method: 'POST', + path: '/orgs/{org}/secret-scanning/custom-patterns', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/secret-scanning/custom-patterns` + /// Bulk create repository custom patterns + static const secretScanningBulkCreateRepoCustomPatterns = + RestOperationContract( + operationId: 'secret-scanning/bulk-create-repo-custom-patterns', + method: 'POST', + path: '/repos/{owner}/{repo}/secret-scanning/custom-patterns', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /orgs/{org}/secret-scanning/custom-patterns` + /// Bulk delete organization custom patterns + static const secretScanningBulkDeleteOrgCustomPatterns = + RestOperationContract( + operationId: 'secret-scanning/bulk-delete-org-custom-patterns', + method: 'DELETE', + path: '/orgs/{org}/secret-scanning/custom-patterns', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `DELETE /repos/{owner}/{repo}/secret-scanning/custom-patterns` + /// Bulk delete repository custom patterns + static const secretScanningBulkDeleteRepoCustomPatterns = + RestOperationContract( + operationId: 'secret-scanning/bulk-delete-repo-custom-patterns', + method: 'DELETE', + path: '/repos/{owner}/{repo}/secret-scanning/custom-patterns', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `POST /repos/{owner}/{repo}/secret-scanning/push-protection-bypasses` + /// Create a push protection bypass + static const secretScanningCreatePushProtectionBypass = RestOperationContract( + operationId: 'secret-scanning/create-push-protection-bypass', + method: 'POST', + path: '/repos/{owner}/{repo}/secret-scanning/push-protection-bypasses', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}` + /// Get a secret scanning alert + static const secretScanningGetAlert = RestOperationContract( + operationId: 'secret-scanning/get-alert', + method: 'GET', + path: '/repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}', + pathParams: ['alert_number', 'owner', 'repo'], + queryParams: ['hide_secret'], + ); + + /// `GET /repos/{owner}/{repo}/secret-scanning/scan-history` + /// Get secret scanning scan history for a repository + static const secretScanningGetScanHistory = RestOperationContract( + operationId: 'secret-scanning/get-scan-history', + method: 'GET', + path: '/repos/{owner}/{repo}/secret-scanning/scan-history', + pathParams: ['owner', 'repo'], + ); + + /// `GET /orgs/{org}/secret-scanning/alerts` + /// List secret scanning alerts for an organization + static const secretScanningListAlertsForOrg = RestOperationContract( + operationId: 'secret-scanning/list-alerts-for-org', + method: 'GET', + path: '/orgs/{org}/secret-scanning/alerts', + pathParams: ['org'], + queryParams: [ + 'after', + 'assignee', + 'before', + 'direction', + 'exclude_providers', + 'exclude_secret_types', + 'hide_secret', + 'included_metadata', + 'is_bypassed', + 'is_multi_repo', + 'is_publicly_leaked', + 'owner_email_hash', + 'page', + 'per_page', + 'providers', + 'resolution', + 'secret_type', + 'sort', + 'state', + 'validity' + ], + ); + + /// `GET /repos/{owner}/{repo}/secret-scanning/alerts` + /// List secret scanning alerts for a repository + static const secretScanningListAlertsForRepo = RestOperationContract( + operationId: 'secret-scanning/list-alerts-for-repo', + method: 'GET', + path: '/repos/{owner}/{repo}/secret-scanning/alerts', + pathParams: ['owner', 'repo'], + queryParams: [ + 'after', + 'assignee', + 'before', + 'direction', + 'exclude_providers', + 'exclude_secret_types', + 'hide_secret', + 'included_metadata', + 'is_bypassed', + 'is_multi_repo', + 'is_publicly_leaked', + 'owner_email_hash', + 'page', + 'per_page', + 'providers', + 'resolution', + 'secret_type', + 'sort', + 'state', + 'validity' + ], + ); + + /// `GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations` + /// List locations for a secret scanning alert + static const secretScanningListLocationsForAlert = RestOperationContract( + operationId: 'secret-scanning/list-locations-for-alert', + method: 'GET', + path: + '/repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations', + pathParams: ['alert_number', 'owner', 'repo'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/secret-scanning/custom-patterns` + /// List organization custom patterns + static const secretScanningListOrgCustomPatterns = RestOperationContract( + operationId: 'secret-scanning/list-org-custom-patterns', + method: 'GET', + path: '/orgs/{org}/secret-scanning/custom-patterns', + pathParams: ['org'], + queryParams: [ + 'after', + 'before', + 'direction', + 'push_protection', + 'sort', + 'state' + ], + ); + + /// `GET /orgs/{org}/secret-scanning/pattern-configurations` + /// List organization pattern configurations + static const secretScanningListOrgPatternConfigs = RestOperationContract( + operationId: 'secret-scanning/list-org-pattern-configs', + method: 'GET', + path: '/orgs/{org}/secret-scanning/pattern-configurations', + pathParams: ['org'], + ); + + /// `GET /repos/{owner}/{repo}/secret-scanning/custom-patterns` + /// List repository custom patterns + static const secretScanningListRepoCustomPatterns = RestOperationContract( + operationId: 'secret-scanning/list-repo-custom-patterns', + method: 'GET', + path: '/repos/{owner}/{repo}/secret-scanning/custom-patterns', + pathParams: ['owner', 'repo'], + queryParams: [ + 'after', + 'before', + 'direction', + 'push_protection', + 'sort', + 'state' + ], + ); + + /// `PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}` + /// Update a secret scanning alert + static const secretScanningUpdateAlert = RestOperationContract( + operationId: 'secret-scanning/update-alert', + method: 'PATCH', + path: '/repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}', + pathParams: ['alert_number', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /orgs/{org}/secret-scanning/custom-patterns/{pattern_id}` + /// Update an organization custom pattern + static const secretScanningUpdateOrgCustomPattern = RestOperationContract( + operationId: 'secret-scanning/update-org-custom-pattern', + method: 'PATCH', + path: '/orgs/{org}/secret-scanning/custom-patterns/{pattern_id}', + pathParams: ['org', 'pattern_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /orgs/{org}/secret-scanning/pattern-configurations` + /// Update organization pattern configurations + static const secretScanningUpdateOrgPatternConfigs = RestOperationContract( + operationId: 'secret-scanning/update-org-pattern-configs', + method: 'PATCH', + path: '/orgs/{org}/secret-scanning/pattern-configurations', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PATCH /repos/{owner}/{repo}/secret-scanning/custom-patterns/{pattern_id}` + /// Update a repository custom pattern + static const secretScanningUpdateRepoCustomPattern = RestOperationContract( + operationId: 'secret-scanning/update-repo-custom-pattern', + method: 'PATCH', + path: '/repos/{owner}/{repo}/secret-scanning/custom-patterns/{pattern_id}', + pathParams: ['owner', 'pattern_id', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `POST /repos/{owner}/{repo}/security-advisories/{ghsa_id}/forks` + /// Create a temporary private fork + static const securityAdvisoriesCreateFork = RestOperationContract( + operationId: 'security-advisories/create-fork', + method: 'POST', + path: '/repos/{owner}/{repo}/security-advisories/{ghsa_id}/forks', + pathParams: ['ghsa_id', 'owner', 'repo'], + successStatuses: [202], + ); + + /// `POST /repos/{owner}/{repo}/security-advisories/reports` + /// Privately report a security vulnerability + static const securityAdvisoriesCreatePrivateVulnerabilityReport = + RestOperationContract( + operationId: 'security-advisories/create-private-vulnerability-report', + method: 'POST', + path: '/repos/{owner}/{repo}/security-advisories/reports', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/security-advisories` + /// Create a repository security advisory + static const securityAdvisoriesCreateRepositoryAdvisory = + RestOperationContract( + operationId: 'security-advisories/create-repository-advisory', + method: 'POST', + path: '/repos/{owner}/{repo}/security-advisories', + pathParams: ['owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /repos/{owner}/{repo}/security-advisories/{ghsa_id}/cve` + /// Request a CVE for a repository security advisory + static const securityAdvisoriesCreateRepositoryAdvisoryCveRequest = + RestOperationContract( + operationId: 'security-advisories/create-repository-advisory-cve-request', + method: 'POST', + path: '/repos/{owner}/{repo}/security-advisories/{ghsa_id}/cve', + pathParams: ['ghsa_id', 'owner', 'repo'], + successStatuses: [202], + ); + + /// `GET /advisories/{ghsa_id}` + /// Get a global security advisory + static const securityAdvisoriesGetGlobalAdvisory = RestOperationContract( + operationId: 'security-advisories/get-global-advisory', + method: 'GET', + path: '/advisories/{ghsa_id}', + pathParams: ['ghsa_id'], + ); + + /// `GET /repos/{owner}/{repo}/security-advisories/{ghsa_id}` + /// Get a repository security advisory + static const securityAdvisoriesGetRepositoryAdvisory = RestOperationContract( + operationId: 'security-advisories/get-repository-advisory', + method: 'GET', + path: '/repos/{owner}/{repo}/security-advisories/{ghsa_id}', + pathParams: ['ghsa_id', 'owner', 'repo'], + ); + + /// `GET /advisories` + /// List global security advisories + static const securityAdvisoriesListGlobalAdvisories = RestOperationContract( + operationId: 'security-advisories/list-global-advisories', + method: 'GET', + path: '/advisories', + queryParams: [ + 'affects', + 'after', + 'before', + 'cve_id', + 'cwes', + 'direction', + 'ecosystem', + 'epss_percentage', + 'epss_percentile', + 'ghsa_id', + 'is_withdrawn', + 'modified', + 'per_page', + 'published', + 'severity', + 'sort', + 'type', + 'updated' + ], + ); + + /// `GET /orgs/{org}/security-advisories` + /// List repository security advisories for an organization + static const securityAdvisoriesListOrgRepositoryAdvisories = + RestOperationContract( + operationId: 'security-advisories/list-org-repository-advisories', + method: 'GET', + path: '/orgs/{org}/security-advisories', + pathParams: ['org'], + queryParams: ['after', 'before', 'direction', 'per_page', 'sort', 'state'], + ); + + /// `GET /repos/{owner}/{repo}/security-advisories` + /// List repository security advisories + static const securityAdvisoriesListRepositoryAdvisories = + RestOperationContract( + operationId: 'security-advisories/list-repository-advisories', + method: 'GET', + path: '/repos/{owner}/{repo}/security-advisories', + pathParams: ['owner', 'repo'], + queryParams: ['after', 'before', 'direction', 'per_page', 'sort', 'state'], + ); + + /// `PATCH /repos/{owner}/{repo}/security-advisories/{ghsa_id}` + /// Update a repository security advisory + static const securityAdvisoriesUpdateRepositoryAdvisory = + RestOperationContract( + operationId: 'security-advisories/update-repository-advisory', + method: 'PATCH', + path: '/repos/{owner}/{repo}/security-advisories/{ghsa_id}', + pathParams: ['ghsa_id', 'owner', 'repo'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /teams/{team_id}/members/{username}` + /// Add team member (Legacy) + static const teamsAddMemberLegacy = RestOperationContract( + operationId: 'teams/add-member-legacy', + method: 'PUT', + path: '/teams/{team_id}/members/{username}', + pathParams: ['team_id', 'username'], + successStatuses: [204], + ); + + /// `PUT /orgs/{org}/teams/{team_slug}/memberships/{username}` + /// Add or update team membership for a user + static const teamsAddOrUpdateMembershipForUserInOrg = RestOperationContract( + operationId: 'teams/add-or-update-membership-for-user-in-org', + method: 'PUT', + path: '/orgs/{org}/teams/{team_slug}/memberships/{username}', + pathParams: ['org', 'team_slug', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /teams/{team_id}/memberships/{username}` + /// Add or update team membership for a user (Legacy) + static const teamsAddOrUpdateMembershipForUserLegacy = RestOperationContract( + operationId: 'teams/add-or-update-membership-for-user-legacy', + method: 'PUT', + path: '/teams/{team_id}/memberships/{username}', + pathParams: ['team_id', 'username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}` + /// Add or update team repository permissions + static const teamsAddOrUpdateRepoPermissionsInOrg = RestOperationContract( + operationId: 'teams/add-or-update-repo-permissions-in-org', + method: 'PUT', + path: '/orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}', + pathParams: ['org', 'owner', 'repo', 'team_slug'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `PUT /teams/{team_id}/repos/{owner}/{repo}` + /// Add or update team repository permissions (Legacy) + static const teamsAddOrUpdateRepoPermissionsLegacy = RestOperationContract( + operationId: 'teams/add-or-update-repo-permissions-legacy', + method: 'PUT', + path: '/teams/{team_id}/repos/{owner}/{repo}', + pathParams: ['owner', 'repo', 'team_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}` + /// Check team permissions for a repository + static const teamsCheckPermissionsForRepoInOrg = RestOperationContract( + operationId: 'teams/check-permissions-for-repo-in-org', + method: 'GET', + path: '/orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}', + pathParams: ['org', 'owner', 'repo', 'team_slug'], + successStatuses: [200, 204], + ); + + /// `GET /teams/{team_id}/repos/{owner}/{repo}` + /// Check team permissions for a repository (Legacy) + static const teamsCheckPermissionsForRepoLegacy = RestOperationContract( + operationId: 'teams/check-permissions-for-repo-legacy', + method: 'GET', + path: '/teams/{team_id}/repos/{owner}/{repo}', + pathParams: ['owner', 'repo', 'team_id'], + successStatuses: [200, 204], + ); + + /// `POST /orgs/{org}/teams` + /// Create a team + static const teamsCreate = RestOperationContract( + operationId: 'teams/create', + method: 'POST', + path: '/orgs/{org}/teams', + pathParams: ['org'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `DELETE /orgs/{org}/teams/{team_slug}` + /// Delete a team + static const teamsDeleteInOrg = RestOperationContract( + operationId: 'teams/delete-in-org', + method: 'DELETE', + path: '/orgs/{org}/teams/{team_slug}', + pathParams: ['org', 'team_slug'], + successStatuses: [204], + ); + + /// `DELETE /teams/{team_id}` + /// Delete a team (Legacy) + static const teamsDeleteLegacy = RestOperationContract( + operationId: 'teams/delete-legacy', + method: 'DELETE', + path: '/teams/{team_id}', + pathParams: ['team_id'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/teams/{team_slug}` + /// Get a team by name + static const teamsGetByName = RestOperationContract( + operationId: 'teams/get-by-name', + method: 'GET', + path: '/orgs/{org}/teams/{team_slug}', + pathParams: ['org', 'team_slug'], + ); + + /// `GET /teams/{team_id}` + /// Get a team (Legacy) + static const teamsGetLegacy = RestOperationContract( + operationId: 'teams/get-legacy', + method: 'GET', + path: '/teams/{team_id}', + pathParams: ['team_id'], + ); + + /// `GET /teams/{team_id}/members/{username}` + /// Get team member (Legacy) + static const teamsGetMemberLegacy = RestOperationContract( + operationId: 'teams/get-member-legacy', + method: 'GET', + path: '/teams/{team_id}/members/{username}', + pathParams: ['team_id', 'username'], + successStatuses: [204], + ); + + /// `GET /orgs/{org}/teams/{team_slug}/memberships/{username}` + /// Get team membership for a user + static const teamsGetMembershipForUserInOrg = RestOperationContract( + operationId: 'teams/get-membership-for-user-in-org', + method: 'GET', + path: '/orgs/{org}/teams/{team_slug}/memberships/{username}', + pathParams: ['org', 'team_slug', 'username'], + ); + + /// `GET /teams/{team_id}/memberships/{username}` + /// Get team membership for a user (Legacy) + static const teamsGetMembershipForUserLegacy = RestOperationContract( + operationId: 'teams/get-membership-for-user-legacy', + method: 'GET', + path: '/teams/{team_id}/memberships/{username}', + pathParams: ['team_id', 'username'], + ); + + /// `GET /orgs/{org}/teams` + /// List teams + static const teamsList = RestOperationContract( + operationId: 'teams/list', + method: 'GET', + path: '/orgs/{org}/teams', + pathParams: ['org'], + queryParams: ['page', 'per_page', 'team_type'], + ); + + /// `GET /orgs/{org}/teams/{team_slug}/teams` + /// List child teams + static const teamsListChildInOrg = RestOperationContract( + operationId: 'teams/list-child-in-org', + method: 'GET', + path: '/orgs/{org}/teams/{team_slug}/teams', + pathParams: ['org', 'team_slug'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /teams/{team_id}/teams` + /// List child teams (Legacy) + static const teamsListChildLegacy = RestOperationContract( + operationId: 'teams/list-child-legacy', + method: 'GET', + path: '/teams/{team_id}/teams', + pathParams: ['team_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/teams` + /// List teams for the authenticated user + static const teamsListForAuthenticatedUser = RestOperationContract( + operationId: 'teams/list-for-authenticated-user', + method: 'GET', + path: '/user/teams', + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/teams/{team_slug}/members` + /// List team members + static const teamsListMembersInOrg = RestOperationContract( + operationId: 'teams/list-members-in-org', + method: 'GET', + path: '/orgs/{org}/teams/{team_slug}/members', + pathParams: ['org', 'team_slug'], + queryParams: ['page', 'per_page', 'role'], + ); + + /// `GET /teams/{team_id}/members` + /// List team members (Legacy) + static const teamsListMembersLegacy = RestOperationContract( + operationId: 'teams/list-members-legacy', + method: 'GET', + path: '/teams/{team_id}/members', + pathParams: ['team_id'], + queryParams: ['page', 'per_page', 'role'], + ); + + /// `GET /orgs/{org}/teams/{team_slug}/invitations` + /// List pending team invitations + static const teamsListPendingInvitationsInOrg = RestOperationContract( + operationId: 'teams/list-pending-invitations-in-org', + method: 'GET', + path: '/orgs/{org}/teams/{team_slug}/invitations', + pathParams: ['org', 'team_slug'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /teams/{team_id}/invitations` + /// List pending team invitations (Legacy) + static const teamsListPendingInvitationsLegacy = RestOperationContract( + operationId: 'teams/list-pending-invitations-legacy', + method: 'GET', + path: '/teams/{team_id}/invitations', + pathParams: ['team_id'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /orgs/{org}/teams/{team_slug}/repos` + /// List team repositories + static const teamsListReposInOrg = RestOperationContract( + operationId: 'teams/list-repos-in-org', + method: 'GET', + path: '/orgs/{org}/teams/{team_slug}/repos', + pathParams: ['org', 'team_slug'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /teams/{team_id}/repos` + /// List team repositories (Legacy) + static const teamsListReposLegacy = RestOperationContract( + operationId: 'teams/list-repos-legacy', + method: 'GET', + path: '/teams/{team_id}/repos', + pathParams: ['team_id'], + queryParams: ['page', 'per_page'], + ); + + /// `DELETE /teams/{team_id}/members/{username}` + /// Remove team member (Legacy) + static const teamsRemoveMemberLegacy = RestOperationContract( + operationId: 'teams/remove-member-legacy', + method: 'DELETE', + path: '/teams/{team_id}/members/{username}', + pathParams: ['team_id', 'username'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}` + /// Remove team membership for a user + static const teamsRemoveMembershipForUserInOrg = RestOperationContract( + operationId: 'teams/remove-membership-for-user-in-org', + method: 'DELETE', + path: '/orgs/{org}/teams/{team_slug}/memberships/{username}', + pathParams: ['org', 'team_slug', 'username'], + successStatuses: [204], + ); + + /// `DELETE /teams/{team_id}/memberships/{username}` + /// Remove team membership for a user (Legacy) + static const teamsRemoveMembershipForUserLegacy = RestOperationContract( + operationId: 'teams/remove-membership-for-user-legacy', + method: 'DELETE', + path: '/teams/{team_id}/memberships/{username}', + pathParams: ['team_id', 'username'], + successStatuses: [204], + ); + + /// `DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}` + /// Remove a repository from a team + static const teamsRemoveRepoInOrg = RestOperationContract( + operationId: 'teams/remove-repo-in-org', + method: 'DELETE', + path: '/orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}', + pathParams: ['org', 'owner', 'repo', 'team_slug'], + successStatuses: [204], + ); + + /// `DELETE /teams/{team_id}/repos/{owner}/{repo}` + /// Remove a repository from a team (Legacy) + static const teamsRemoveRepoLegacy = RestOperationContract( + operationId: 'teams/remove-repo-legacy', + method: 'DELETE', + path: '/teams/{team_id}/repos/{owner}/{repo}', + pathParams: ['owner', 'repo', 'team_id'], + successStatuses: [204], + ); + + /// `PATCH /orgs/{org}/teams/{team_slug}` + /// Update a team + static const teamsUpdateInOrg = RestOperationContract( + operationId: 'teams/update-in-org', + method: 'PATCH', + path: '/orgs/{org}/teams/{team_slug}', + pathParams: ['org', 'team_slug'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 201], + ); + + /// `PATCH /teams/{team_id}` + /// Update a team (Legacy) + static const teamsUpdateLegacy = RestOperationContract( + operationId: 'teams/update-legacy', + method: 'PATCH', + path: '/teams/{team_id}', + pathParams: ['team_id'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [200, 201], + ); + + /// `POST /user/emails` + /// Add an email address for the authenticated user + static const usersAddEmailForAuthenticatedUser = RestOperationContract( + operationId: 'users/add-email-for-authenticated-user', + method: 'POST', + path: '/user/emails', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /user/social_accounts` + /// Add social accounts for the authenticated user + static const usersAddSocialAccountForAuthenticatedUser = + RestOperationContract( + operationId: 'users/add-social-account-for-authenticated-user', + method: 'POST', + path: '/user/social_accounts', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `PUT /user/blocks/{username}` + /// Block a user + static const usersBlock = RestOperationContract( + operationId: 'users/block', + method: 'PUT', + path: '/user/blocks/{username}', + pathParams: ['username'], + successStatuses: [204], + ); + + /// `GET /user/blocks/{username}` + /// Check if a user is blocked by the authenticated user + static const usersCheckBlocked = RestOperationContract( + operationId: 'users/check-blocked', + method: 'GET', + path: '/user/blocks/{username}', + pathParams: ['username'], + successStatuses: [204], + ); + + /// `GET /users/{username}/following/{target_user}` + /// Check if a user follows another user + static const usersCheckFollowingForUser = RestOperationContract( + operationId: 'users/check-following-for-user', + method: 'GET', + path: '/users/{username}/following/{target_user}', + pathParams: ['target_user', 'username'], + successStatuses: [204], + ); + + /// `GET /user/following/{username}` + /// Check if a person is followed by the authenticated user + static const usersCheckPersonIsFollowedByAuthenticated = + RestOperationContract( + operationId: 'users/check-person-is-followed-by-authenticated', + method: 'GET', + path: '/user/following/{username}', + pathParams: ['username'], + successStatuses: [204], + ); + + /// `POST /user/gpg_keys` + /// Create a GPG key for the authenticated user + static const usersCreateGpgKeyForAuthenticatedUser = RestOperationContract( + operationId: 'users/create-gpg-key-for-authenticated-user', + method: 'POST', + path: '/user/gpg_keys', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /user/keys` + /// Create a public SSH key for the authenticated user + static const usersCreatePublicSshKeyForAuthenticatedUser = + RestOperationContract( + operationId: 'users/create-public-ssh-key-for-authenticated-user', + method: 'POST', + path: '/user/keys', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /user/ssh_signing_keys` + /// Create a SSH signing key for the authenticated user + static const usersCreateSshSigningKeyForAuthenticatedUser = + RestOperationContract( + operationId: 'users/create-ssh-signing-key-for-authenticated-user', + method: 'POST', + path: '/user/ssh_signing_keys', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [201], + ); + + /// `POST /users/{username}/attestations/delete-request` + /// Delete attestations in bulk + static const usersDeleteAttestationsBulk = RestOperationContract( + operationId: 'users/delete-attestations-bulk', + method: 'POST', + path: '/users/{username}/attestations/delete-request', + pathParams: ['username'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /users/{username}/attestations/{attestation_id}` + /// Delete attestations by ID + static const usersDeleteAttestationsById = RestOperationContract( + operationId: 'users/delete-attestations-by-id', + method: 'DELETE', + path: '/users/{username}/attestations/{attestation_id}', + pathParams: ['attestation_id', 'username'], + successStatuses: [200, 204], + ); + + /// `DELETE /users/{username}/attestations/digest/{subject_digest}` + /// Delete attestations by subject digest + static const usersDeleteAttestationsBySubjectDigest = RestOperationContract( + operationId: 'users/delete-attestations-by-subject-digest', + method: 'DELETE', + path: '/users/{username}/attestations/digest/{subject_digest}', + pathParams: ['subject_digest', 'username'], + successStatuses: [200, 204], + ); + + /// `DELETE /user/emails` + /// Delete an email address for the authenticated user + static const usersDeleteEmailForAuthenticatedUser = RestOperationContract( + operationId: 'users/delete-email-for-authenticated-user', + method: 'DELETE', + path: '/user/emails', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `DELETE /user/gpg_keys/{gpg_key_id}` + /// Delete a GPG key for the authenticated user + static const usersDeleteGpgKeyForAuthenticatedUser = RestOperationContract( + operationId: 'users/delete-gpg-key-for-authenticated-user', + method: 'DELETE', + path: '/user/gpg_keys/{gpg_key_id}', + pathParams: ['gpg_key_id'], + successStatuses: [204], + ); + + /// `DELETE /user/keys/{key_id}` + /// Delete a public SSH key for the authenticated user + static const usersDeletePublicSshKeyForAuthenticatedUser = + RestOperationContract( + operationId: 'users/delete-public-ssh-key-for-authenticated-user', + method: 'DELETE', + path: '/user/keys/{key_id}', + pathParams: ['key_id'], + successStatuses: [204], + ); + + /// `DELETE /user/social_accounts` + /// Delete social accounts for the authenticated user + static const usersDeleteSocialAccountForAuthenticatedUser = + RestOperationContract( + operationId: 'users/delete-social-account-for-authenticated-user', + method: 'DELETE', + path: '/user/social_accounts', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + successStatuses: [204], + ); + + /// `DELETE /user/ssh_signing_keys/{ssh_signing_key_id}` + /// Delete an SSH signing key for the authenticated user + static const usersDeleteSshSigningKeyForAuthenticatedUser = + RestOperationContract( + operationId: 'users/delete-ssh-signing-key-for-authenticated-user', + method: 'DELETE', + path: '/user/ssh_signing_keys/{ssh_signing_key_id}', + pathParams: ['ssh_signing_key_id'], + successStatuses: [204], + ); + + /// `PUT /user/following/{username}` + /// Follow a user + static const usersFollow = RestOperationContract( + operationId: 'users/follow', + method: 'PUT', + path: '/user/following/{username}', + pathParams: ['username'], + successStatuses: [204], + ); + + /// `GET /user` + /// Get the authenticated user + static const usersGetAuthenticated = RestOperationContract( + operationId: 'users/get-authenticated', + method: 'GET', + path: '/user', + ); + + /// `GET /user/{account_id}` + /// Get a user using their ID + static const usersGetById = RestOperationContract( + operationId: 'users/get-by-id', + method: 'GET', + path: '/user/{account_id}', + pathParams: ['account_id'], + ); + + /// `GET /users/{username}` + /// Get a user + static const usersGetByUsername = RestOperationContract( + operationId: 'users/get-by-username', + method: 'GET', + path: '/users/{username}', + pathParams: ['username'], + ); + + /// `GET /users/{username}/hovercard` + /// Get contextual information for a user + static const usersGetContextForUser = RestOperationContract( + operationId: 'users/get-context-for-user', + method: 'GET', + path: '/users/{username}/hovercard', + pathParams: ['username'], + queryParams: ['subject_id', 'subject_type'], + ); + + /// `GET /user/gpg_keys/{gpg_key_id}` + /// Get a GPG key for the authenticated user + static const usersGetGpgKeyForAuthenticatedUser = RestOperationContract( + operationId: 'users/get-gpg-key-for-authenticated-user', + method: 'GET', + path: '/user/gpg_keys/{gpg_key_id}', + pathParams: ['gpg_key_id'], + ); + + /// `GET /user/keys/{key_id}` + /// Get a public SSH key for the authenticated user + static const usersGetPublicSshKeyForAuthenticatedUser = RestOperationContract( + operationId: 'users/get-public-ssh-key-for-authenticated-user', + method: 'GET', + path: '/user/keys/{key_id}', + pathParams: ['key_id'], + ); + + /// `GET /user/ssh_signing_keys/{ssh_signing_key_id}` + /// Get an SSH signing key for the authenticated user + static const usersGetSshSigningKeyForAuthenticatedUser = + RestOperationContract( + operationId: 'users/get-ssh-signing-key-for-authenticated-user', + method: 'GET', + path: '/user/ssh_signing_keys/{ssh_signing_key_id}', + pathParams: ['ssh_signing_key_id'], + ); + + /// `GET /users` + /// List users + static const usersList = RestOperationContract( + operationId: 'users/list', + method: 'GET', + path: '/users', + queryParams: ['per_page', 'since'], + ); + + /// `GET /users/{username}/attestations/{subject_digest}` + /// List attestations + static const usersListAttestations = RestOperationContract( + operationId: 'users/list-attestations', + method: 'GET', + path: '/users/{username}/attestations/{subject_digest}', + pathParams: ['subject_digest', 'username'], + queryParams: ['after', 'before', 'per_page', 'predicate_type'], + successStatuses: [200, 201, 204], + ); + + /// `POST /users/{username}/attestations/bulk-list` + /// List attestations by bulk subject digests + static const usersListAttestationsBulk = RestOperationContract( + operationId: 'users/list-attestations-bulk', + method: 'POST', + path: '/users/{username}/attestations/bulk-list', + pathParams: ['username'], + queryParams: ['after', 'before', 'per_page'], + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `GET /user/blocks` + /// List users blocked by the authenticated user + static const usersListBlockedByAuthenticatedUser = RestOperationContract( + operationId: 'users/list-blocked-by-authenticated-user', + method: 'GET', + path: '/user/blocks', + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/emails` + /// List email addresses for the authenticated user + static const usersListEmailsForAuthenticatedUser = RestOperationContract( + operationId: 'users/list-emails-for-authenticated-user', + method: 'GET', + path: '/user/emails', + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/following` + /// List the people the authenticated user follows + static const usersListFollowedByAuthenticatedUser = RestOperationContract( + operationId: 'users/list-followed-by-authenticated-user', + method: 'GET', + path: '/user/following', + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/followers` + /// List followers of the authenticated user + static const usersListFollowersForAuthenticatedUser = RestOperationContract( + operationId: 'users/list-followers-for-authenticated-user', + method: 'GET', + path: '/user/followers', + queryParams: ['page', 'per_page'], + ); + + /// `GET /users/{username}/followers` + /// List followers of a user + static const usersListFollowersForUser = RestOperationContract( + operationId: 'users/list-followers-for-user', + method: 'GET', + path: '/users/{username}/followers', + pathParams: ['username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /users/{username}/following` + /// List the people a user follows + static const usersListFollowingForUser = RestOperationContract( + operationId: 'users/list-following-for-user', + method: 'GET', + path: '/users/{username}/following', + pathParams: ['username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/gpg_keys` + /// List GPG keys for the authenticated user + static const usersListGpgKeysForAuthenticatedUser = RestOperationContract( + operationId: 'users/list-gpg-keys-for-authenticated-user', + method: 'GET', + path: '/user/gpg_keys', + queryParams: ['page', 'per_page'], + ); + + /// `GET /users/{username}/gpg_keys` + /// List GPG keys for a user + static const usersListGpgKeysForUser = RestOperationContract( + operationId: 'users/list-gpg-keys-for-user', + method: 'GET', + path: '/users/{username}/gpg_keys', + pathParams: ['username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/public_emails` + /// List public email addresses for the authenticated user + static const usersListPublicEmailsForAuthenticatedUser = + RestOperationContract( + operationId: 'users/list-public-emails-for-authenticated-user', + method: 'GET', + path: '/user/public_emails', + queryParams: ['page', 'per_page'], + ); + + /// `GET /users/{username}/keys` + /// List public keys for a user + static const usersListPublicKeysForUser = RestOperationContract( + operationId: 'users/list-public-keys-for-user', + method: 'GET', + path: '/users/{username}/keys', + pathParams: ['username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/keys` + /// List public SSH keys for the authenticated user + static const usersListPublicSshKeysForAuthenticatedUser = + RestOperationContract( + operationId: 'users/list-public-ssh-keys-for-authenticated-user', + method: 'GET', + path: '/user/keys', + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/social_accounts` + /// List social accounts for the authenticated user + static const usersListSocialAccountsForAuthenticatedUser = + RestOperationContract( + operationId: 'users/list-social-accounts-for-authenticated-user', + method: 'GET', + path: '/user/social_accounts', + queryParams: ['page', 'per_page'], + ); + + /// `GET /users/{username}/social_accounts` + /// List social accounts for a user + static const usersListSocialAccountsForUser = RestOperationContract( + operationId: 'users/list-social-accounts-for-user', + method: 'GET', + path: '/users/{username}/social_accounts', + pathParams: ['username'], + queryParams: ['page', 'per_page'], + ); + + /// `GET /user/ssh_signing_keys` + /// List SSH signing keys for the authenticated user + static const usersListSshSigningKeysForAuthenticatedUser = + RestOperationContract( + operationId: 'users/list-ssh-signing-keys-for-authenticated-user', + method: 'GET', + path: '/user/ssh_signing_keys', + queryParams: ['page', 'per_page'], + ); + + /// `GET /users/{username}/ssh_signing_keys` + /// List SSH signing keys for a user + static const usersListSshSigningKeysForUser = RestOperationContract( + operationId: 'users/list-ssh-signing-keys-for-user', + method: 'GET', + path: '/users/{username}/ssh_signing_keys', + pathParams: ['username'], + queryParams: ['page', 'per_page'], + ); + + /// `PATCH /user/email/visibility` + /// Set primary email visibility for the authenticated user + static const usersSetPrimaryEmailVisibilityForAuthenticatedUser = + RestOperationContract( + operationId: 'users/set-primary-email-visibility-for-authenticated-user', + method: 'PATCH', + path: '/user/email/visibility', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// `DELETE /user/blocks/{username}` + /// Unblock a user + static const usersUnblock = RestOperationContract( + operationId: 'users/unblock', + method: 'DELETE', + path: '/user/blocks/{username}', + pathParams: ['username'], + successStatuses: [204], + ); + + /// `DELETE /user/following/{username}` + /// Unfollow a user + static const usersUnfollow = RestOperationContract( + operationId: 'users/unfollow', + method: 'DELETE', + path: '/user/following/{username}', + pathParams: ['username'], + successStatuses: [204], + ); + + /// `PATCH /user` + /// Update the authenticated user + static const usersUpdateAuthenticated = RestOperationContract( + operationId: 'users/update-authenticated', + method: 'PATCH', + path: '/user', + hasRequestBody: true, + requestMediaTypes: ['application/json'], + ); + + /// Map of all operations indexed by operationId. + static const Map all = { + 'actions/add-custom-labels-to-self-hosted-runner-for-org': + actionsAddCustomLabelsToSelfHostedRunnerForOrg, + 'actions/add-custom-labels-to-self-hosted-runner-for-repo': + actionsAddCustomLabelsToSelfHostedRunnerForRepo, + 'actions/add-repo-access-to-self-hosted-runner-group-in-org': + actionsAddRepoAccessToSelfHostedRunnerGroupInOrg, + 'actions/add-selected-repo-to-org-secret': + actionsAddSelectedRepoToOrgSecret, + 'actions/add-selected-repo-to-org-variable': + actionsAddSelectedRepoToOrgVariable, + 'actions/add-self-hosted-runner-to-group-for-org': + actionsAddSelfHostedRunnerToGroupForOrg, + 'actions/approve-workflow-run': actionsApproveWorkflowRun, + 'actions/cancel-workflow-run': actionsCancelWorkflowRun, + 'actions/create-environment-variable': actionsCreateEnvironmentVariable, + 'actions/create-hosted-runner-for-org': actionsCreateHostedRunnerForOrg, + 'actions/create-or-update-environment-secret': + actionsCreateOrUpdateEnvironmentSecret, + 'actions/create-or-update-org-secret': actionsCreateOrUpdateOrgSecret, + 'actions/create-or-update-repo-secret': actionsCreateOrUpdateRepoSecret, + 'actions/create-org-variable': actionsCreateOrgVariable, + 'actions/create-registration-token-for-org': + actionsCreateRegistrationTokenForOrg, + 'actions/create-registration-token-for-repo': + actionsCreateRegistrationTokenForRepo, + 'actions/create-remove-token-for-org': actionsCreateRemoveTokenForOrg, + 'actions/create-remove-token-for-repo': actionsCreateRemoveTokenForRepo, + 'actions/create-repo-variable': actionsCreateRepoVariable, + 'actions/create-self-hosted-runner-group-for-org': + actionsCreateSelfHostedRunnerGroupForOrg, + 'actions/create-workflow-dispatch': actionsCreateWorkflowDispatch, + 'actions/delete-actions-cache-by-id': actionsDeleteActionsCacheById, + 'actions/delete-actions-cache-by-key': actionsDeleteActionsCacheByKey, + 'actions/delete-artifact': actionsDeleteArtifact, + 'actions/delete-custom-image-from-org': actionsDeleteCustomImageFromOrg, + 'actions/delete-custom-image-version-from-org': + actionsDeleteCustomImageVersionFromOrg, + 'actions/delete-environment-secret': actionsDeleteEnvironmentSecret, + 'actions/delete-environment-variable': actionsDeleteEnvironmentVariable, + 'actions/delete-hosted-runner-for-org': actionsDeleteHostedRunnerForOrg, + 'actions/delete-org-secret': actionsDeleteOrgSecret, + 'actions/delete-org-variable': actionsDeleteOrgVariable, + 'actions/delete-repo-secret': actionsDeleteRepoSecret, + 'actions/delete-repo-variable': actionsDeleteRepoVariable, + 'actions/delete-self-hosted-runner-from-org': + actionsDeleteSelfHostedRunnerFromOrg, + 'actions/delete-self-hosted-runner-from-repo': + actionsDeleteSelfHostedRunnerFromRepo, + 'actions/delete-self-hosted-runner-group-from-org': + actionsDeleteSelfHostedRunnerGroupFromOrg, + 'actions/delete-workflow-run': actionsDeleteWorkflowRun, + 'actions/delete-workflow-run-logs': actionsDeleteWorkflowRunLogs, + 'actions/disable-selected-repository-github-actions-organization': + actionsDisableSelectedRepositoryGithubActionsOrganization, + 'actions/disable-selected-repository-self-hosted-runners-organization': + actionsDisableSelectedRepositorySelfHostedRunnersOrganization, + 'actions/disable-workflow': actionsDisableWorkflow, + 'actions/download-artifact': actionsDownloadArtifact, + 'actions/download-job-logs-for-workflow-run': + actionsDownloadJobLogsForWorkflowRun, + 'actions/download-workflow-run-attempt-logs': + actionsDownloadWorkflowRunAttemptLogs, + 'actions/download-workflow-run-logs': actionsDownloadWorkflowRunLogs, + 'actions/enable-selected-repository-github-actions-organization': + actionsEnableSelectedRepositoryGithubActionsOrganization, + 'actions/enable-selected-repository-self-hosted-runners-organization': + actionsEnableSelectedRepositorySelfHostedRunnersOrganization, + 'actions/enable-workflow': actionsEnableWorkflow, + 'actions/force-cancel-workflow-run': actionsForceCancelWorkflowRun, + 'actions/generate-runner-jitconfig-for-org': + actionsGenerateRunnerJitconfigForOrg, + 'actions/generate-runner-jitconfig-for-repo': + actionsGenerateRunnerJitconfigForRepo, + 'actions/get-actions-cache-list': actionsGetActionsCacheList, + 'actions/get-actions-cache-retention-limit-for-enterprise': + actionsGetActionsCacheRetentionLimitForEnterprise, + 'actions/get-actions-cache-retention-limit-for-organization': + actionsGetActionsCacheRetentionLimitForOrganization, + 'actions/get-actions-cache-retention-limit-for-repository': + actionsGetActionsCacheRetentionLimitForRepository, + 'actions/get-actions-cache-storage-limit-for-enterprise': + actionsGetActionsCacheStorageLimitForEnterprise, + 'actions/get-actions-cache-storage-limit-for-organization': + actionsGetActionsCacheStorageLimitForOrganization, + 'actions/get-actions-cache-storage-limit-for-repository': + actionsGetActionsCacheStorageLimitForRepository, + 'actions/get-actions-cache-usage': actionsGetActionsCacheUsage, + 'actions/get-actions-cache-usage-by-repo-for-org': + actionsGetActionsCacheUsageByRepoForOrg, + 'actions/get-actions-cache-usage-for-org': + actionsGetActionsCacheUsageForOrg, + 'actions/get-allowed-actions-organization': + actionsGetAllowedActionsOrganization, + 'actions/get-allowed-actions-repository': + actionsGetAllowedActionsRepository, + 'actions/get-artifact': actionsGetArtifact, + 'actions/get-artifact-and-log-retention-settings-organization': + actionsGetArtifactAndLogRetentionSettingsOrganization, + 'actions/get-artifact-and-log-retention-settings-repository': + actionsGetArtifactAndLogRetentionSettingsRepository, + 'actions/get-concurrency-group-for-repository': + actionsGetConcurrencyGroupForRepository, + 'actions/get-custom-image-for-org': actionsGetCustomImageForOrg, + 'actions/get-custom-image-version-for-org': + actionsGetCustomImageVersionForOrg, + 'actions/get-custom-oidc-sub-claim-for-repo': + actionsGetCustomOidcSubClaimForRepo, + 'actions/get-environment-public-key': actionsGetEnvironmentPublicKey, + 'actions/get-environment-secret': actionsGetEnvironmentSecret, + 'actions/get-environment-variable': actionsGetEnvironmentVariable, + 'actions/get-fork-pr-contributor-approval-permissions-organization': + actionsGetForkPrContributorApprovalPermissionsOrganization, + 'actions/get-fork-pr-contributor-approval-permissions-repository': + actionsGetForkPrContributorApprovalPermissionsRepository, + 'actions/get-github-actions-default-workflow-permissions-organization': + actionsGetGithubActionsDefaultWorkflowPermissionsOrganization, + 'actions/get-github-actions-default-workflow-permissions-repository': + actionsGetGithubActionsDefaultWorkflowPermissionsRepository, + 'actions/get-github-actions-permissions-organization': + actionsGetGithubActionsPermissionsOrganization, + 'actions/get-github-actions-permissions-repository': + actionsGetGithubActionsPermissionsRepository, + 'actions/get-hosted-runner-for-org': actionsGetHostedRunnerForOrg, + 'actions/get-hosted-runners-github-owned-images-for-org': + actionsGetHostedRunnersGithubOwnedImagesForOrg, + 'actions/get-hosted-runners-limits-for-org': + actionsGetHostedRunnersLimitsForOrg, + 'actions/get-hosted-runners-machine-specs-for-org': + actionsGetHostedRunnersMachineSpecsForOrg, + 'actions/get-hosted-runners-partner-images-for-org': + actionsGetHostedRunnersPartnerImagesForOrg, + 'actions/get-hosted-runners-platforms-for-org': + actionsGetHostedRunnersPlatformsForOrg, + 'actions/get-job-for-workflow-run': actionsGetJobForWorkflowRun, + 'actions/get-org-public-key': actionsGetOrgPublicKey, + 'actions/get-org-secret': actionsGetOrgSecret, + 'actions/get-org-variable': actionsGetOrgVariable, + 'actions/get-pending-deployments-for-run': + actionsGetPendingDeploymentsForRun, + 'actions/get-private-repo-fork-pr-workflows-settings-organization': + actionsGetPrivateRepoForkPrWorkflowsSettingsOrganization, + 'actions/get-private-repo-fork-pr-workflows-settings-repository': + actionsGetPrivateRepoForkPrWorkflowsSettingsRepository, + 'actions/get-repo-public-key': actionsGetRepoPublicKey, + 'actions/get-repo-secret': actionsGetRepoSecret, + 'actions/get-repo-variable': actionsGetRepoVariable, + 'actions/get-reviews-for-run': actionsGetReviewsForRun, + 'actions/get-runner-version-deprecation-for-org': + actionsGetRunnerVersionDeprecationForOrg, + 'actions/get-runner-version-deprecation-for-repo': + actionsGetRunnerVersionDeprecationForRepo, + 'actions/get-self-hosted-runner-for-org': actionsGetSelfHostedRunnerForOrg, + 'actions/get-self-hosted-runner-for-repo': + actionsGetSelfHostedRunnerForRepo, + 'actions/get-self-hosted-runner-group-for-org': + actionsGetSelfHostedRunnerGroupForOrg, + 'actions/get-self-hosted-runners-permissions-organization': + actionsGetSelfHostedRunnersPermissionsOrganization, + 'actions/get-workflow': actionsGetWorkflow, + 'actions/get-workflow-access-to-repository': + actionsGetWorkflowAccessToRepository, + 'actions/get-workflow-run': actionsGetWorkflowRun, + 'actions/get-workflow-run-attempt': actionsGetWorkflowRunAttempt, + 'actions/get-workflow-run-usage': actionsGetWorkflowRunUsage, + 'actions/get-workflow-usage': actionsGetWorkflowUsage, + 'actions/list-artifacts-for-repo': actionsListArtifactsForRepo, + 'actions/list-concurrency-groups-for-repository': + actionsListConcurrencyGroupsForRepository, + 'actions/list-concurrency-groups-for-workflow-run': + actionsListConcurrencyGroupsForWorkflowRun, + 'actions/list-custom-image-versions-for-org': + actionsListCustomImageVersionsForOrg, + 'actions/list-custom-images-for-org': actionsListCustomImagesForOrg, + 'actions/list-environment-secrets': actionsListEnvironmentSecrets, + 'actions/list-environment-variables': actionsListEnvironmentVariables, + 'actions/list-github-hosted-runners-in-group-for-org': + actionsListGithubHostedRunnersInGroupForOrg, + 'actions/list-hosted-runners-for-org': actionsListHostedRunnersForOrg, + 'actions/list-jobs-for-workflow-run': actionsListJobsForWorkflowRun, + 'actions/list-jobs-for-workflow-run-attempt': + actionsListJobsForWorkflowRunAttempt, + 'actions/list-labels-for-self-hosted-runner-for-org': + actionsListLabelsForSelfHostedRunnerForOrg, + 'actions/list-labels-for-self-hosted-runner-for-repo': + actionsListLabelsForSelfHostedRunnerForRepo, + 'actions/list-org-secrets': actionsListOrgSecrets, + 'actions/list-org-variables': actionsListOrgVariables, + 'actions/list-repo-access-to-self-hosted-runner-group-in-org': + actionsListRepoAccessToSelfHostedRunnerGroupInOrg, + 'actions/list-repo-organization-secrets': + actionsListRepoOrganizationSecrets, + 'actions/list-repo-organization-variables': + actionsListRepoOrganizationVariables, + 'actions/list-repo-secrets': actionsListRepoSecrets, + 'actions/list-repo-variables': actionsListRepoVariables, + 'actions/list-repo-workflows': actionsListRepoWorkflows, + 'actions/list-runner-applications-for-org': + actionsListRunnerApplicationsForOrg, + 'actions/list-runner-applications-for-repo': + actionsListRunnerApplicationsForRepo, + 'actions/list-selected-repos-for-org-secret': + actionsListSelectedReposForOrgSecret, + 'actions/list-selected-repos-for-org-variable': + actionsListSelectedReposForOrgVariable, + 'actions/list-selected-repositories-enabled-github-actions-organization': + actionsListSelectedRepositoriesEnabledGithubActionsOrganization, + 'actions/list-selected-repositories-self-hosted-runners-organization': + actionsListSelectedRepositoriesSelfHostedRunnersOrganization, + 'actions/list-self-hosted-runner-groups-for-org': + actionsListSelfHostedRunnerGroupsForOrg, + 'actions/list-self-hosted-runners-for-org': + actionsListSelfHostedRunnersForOrg, + 'actions/list-self-hosted-runners-for-repo': + actionsListSelfHostedRunnersForRepo, + 'actions/list-self-hosted-runners-in-group-for-org': + actionsListSelfHostedRunnersInGroupForOrg, + 'actions/list-workflow-run-artifacts': actionsListWorkflowRunArtifacts, + 'actions/list-workflow-runs': actionsListWorkflowRuns, + 'actions/list-workflow-runs-for-repo': actionsListWorkflowRunsForRepo, + 'actions/re-run-job-for-workflow-run': actionsReRunJobForWorkflowRun, + 'actions/re-run-workflow': actionsReRunWorkflow, + 'actions/re-run-workflow-failed-jobs': actionsReRunWorkflowFailedJobs, + 'actions/remove-all-custom-labels-from-self-hosted-runner-for-org': + actionsRemoveAllCustomLabelsFromSelfHostedRunnerForOrg, + 'actions/remove-all-custom-labels-from-self-hosted-runner-for-repo': + actionsRemoveAllCustomLabelsFromSelfHostedRunnerForRepo, + 'actions/remove-custom-label-from-self-hosted-runner-for-org': + actionsRemoveCustomLabelFromSelfHostedRunnerForOrg, + 'actions/remove-custom-label-from-self-hosted-runner-for-repo': + actionsRemoveCustomLabelFromSelfHostedRunnerForRepo, + 'actions/remove-repo-access-to-self-hosted-runner-group-in-org': + actionsRemoveRepoAccessToSelfHostedRunnerGroupInOrg, + 'actions/remove-selected-repo-from-org-secret': + actionsRemoveSelectedRepoFromOrgSecret, + 'actions/remove-selected-repo-from-org-variable': + actionsRemoveSelectedRepoFromOrgVariable, + 'actions/remove-self-hosted-runner-from-group-for-org': + actionsRemoveSelfHostedRunnerFromGroupForOrg, + 'actions/review-custom-gates-for-run': actionsReviewCustomGatesForRun, + 'actions/review-pending-deployments-for-run': + actionsReviewPendingDeploymentsForRun, + 'actions/set-actions-cache-retention-limit-for-enterprise': + actionsSetActionsCacheRetentionLimitForEnterprise, + 'actions/set-actions-cache-retention-limit-for-organization': + actionsSetActionsCacheRetentionLimitForOrganization, + 'actions/set-actions-cache-retention-limit-for-repository': + actionsSetActionsCacheRetentionLimitForRepository, + 'actions/set-actions-cache-storage-limit-for-enterprise': + actionsSetActionsCacheStorageLimitForEnterprise, + 'actions/set-actions-cache-storage-limit-for-organization': + actionsSetActionsCacheStorageLimitForOrganization, + 'actions/set-actions-cache-storage-limit-for-repository': + actionsSetActionsCacheStorageLimitForRepository, + 'actions/set-allowed-actions-organization': + actionsSetAllowedActionsOrganization, + 'actions/set-allowed-actions-repository': + actionsSetAllowedActionsRepository, + 'actions/set-artifact-and-log-retention-settings-organization': + actionsSetArtifactAndLogRetentionSettingsOrganization, + 'actions/set-artifact-and-log-retention-settings-repository': + actionsSetArtifactAndLogRetentionSettingsRepository, + 'actions/set-custom-labels-for-self-hosted-runner-for-org': + actionsSetCustomLabelsForSelfHostedRunnerForOrg, + 'actions/set-custom-labels-for-self-hosted-runner-for-repo': + actionsSetCustomLabelsForSelfHostedRunnerForRepo, + 'actions/set-custom-oidc-sub-claim-for-repo': + actionsSetCustomOidcSubClaimForRepo, + 'actions/set-fork-pr-contributor-approval-permissions-organization': + actionsSetForkPrContributorApprovalPermissionsOrganization, + 'actions/set-fork-pr-contributor-approval-permissions-repository': + actionsSetForkPrContributorApprovalPermissionsRepository, + 'actions/set-github-actions-default-workflow-permissions-organization': + actionsSetGithubActionsDefaultWorkflowPermissionsOrganization, + 'actions/set-github-actions-default-workflow-permissions-repository': + actionsSetGithubActionsDefaultWorkflowPermissionsRepository, + 'actions/set-github-actions-permissions-organization': + actionsSetGithubActionsPermissionsOrganization, + 'actions/set-github-actions-permissions-repository': + actionsSetGithubActionsPermissionsRepository, + 'actions/set-private-repo-fork-pr-workflows-settings-organization': + actionsSetPrivateRepoForkPrWorkflowsSettingsOrganization, + 'actions/set-private-repo-fork-pr-workflows-settings-repository': + actionsSetPrivateRepoForkPrWorkflowsSettingsRepository, + 'actions/set-repo-access-to-self-hosted-runner-group-in-org': + actionsSetRepoAccessToSelfHostedRunnerGroupInOrg, + 'actions/set-selected-repos-for-org-secret': + actionsSetSelectedReposForOrgSecret, + 'actions/set-selected-repos-for-org-variable': + actionsSetSelectedReposForOrgVariable, + 'actions/set-selected-repositories-enabled-github-actions-organization': + actionsSetSelectedRepositoriesEnabledGithubActionsOrganization, + 'actions/set-selected-repositories-self-hosted-runners-organization': + actionsSetSelectedRepositoriesSelfHostedRunnersOrganization, + 'actions/set-self-hosted-runners-in-group-for-org': + actionsSetSelfHostedRunnersInGroupForOrg, + 'actions/set-self-hosted-runners-permissions-organization': + actionsSetSelfHostedRunnersPermissionsOrganization, + 'actions/set-workflow-access-to-repository': + actionsSetWorkflowAccessToRepository, + 'actions/update-environment-variable': actionsUpdateEnvironmentVariable, + 'actions/update-hosted-runner-for-org': actionsUpdateHostedRunnerForOrg, + 'actions/update-org-variable': actionsUpdateOrgVariable, + 'actions/update-repo-variable': actionsUpdateRepoVariable, + 'actions/update-self-hosted-runner-group-for-org': + actionsUpdateSelfHostedRunnerGroupForOrg, + 'activity/check-repo-is-starred-by-authenticated-user': + activityCheckRepoIsStarredByAuthenticatedUser, + 'activity/delete-repo-subscription': activityDeleteRepoSubscription, + 'activity/delete-thread-subscription': activityDeleteThreadSubscription, + 'activity/get-feeds': activityGetFeeds, + 'activity/get-repo-subscription': activityGetRepoSubscription, + 'activity/get-stargazer-count-for-repo': activityGetStargazerCountForRepo, + 'activity/get-stargazer-history-for-repo': + activityGetStargazerHistoryForRepo, + 'activity/get-thread': activityGetThread, + 'activity/get-thread-subscription-for-authenticated-user': + activityGetThreadSubscriptionForAuthenticatedUser, + 'activity/list-events-for-authenticated-user': + activityListEventsForAuthenticatedUser, + 'activity/list-notifications-for-authenticated-user': + activityListNotificationsForAuthenticatedUser, + 'activity/list-org-events-for-authenticated-user': + activityListOrgEventsForAuthenticatedUser, + 'activity/list-public-events': activityListPublicEvents, + 'activity/list-public-events-for-repo-network': + activityListPublicEventsForRepoNetwork, + 'activity/list-public-events-for-user': activityListPublicEventsForUser, + 'activity/list-public-org-events': activityListPublicOrgEvents, + 'activity/list-received-events-for-user': activityListReceivedEventsForUser, + 'activity/list-received-public-events-for-user': + activityListReceivedPublicEventsForUser, + 'activity/list-repo-events': activityListRepoEvents, + 'activity/list-repo-notifications-for-authenticated-user': + activityListRepoNotificationsForAuthenticatedUser, + 'activity/list-repos-starred-by-authenticated-user': + activityListReposStarredByAuthenticatedUser, + 'activity/list-repos-starred-by-user': activityListReposStarredByUser, + 'activity/list-repos-watched-by-user': activityListReposWatchedByUser, + 'activity/list-stargazers-for-repo': activityListStargazersForRepo, + 'activity/list-watched-repos-for-authenticated-user': + activityListWatchedReposForAuthenticatedUser, + 'activity/list-watchers-for-repo': activityListWatchersForRepo, + 'activity/mark-notifications-as-read': activityMarkNotificationsAsRead, + 'activity/mark-repo-notifications-as-read': + activityMarkRepoNotificationsAsRead, + 'activity/mark-thread-as-done': activityMarkThreadAsDone, + 'activity/mark-thread-as-read': activityMarkThreadAsRead, + 'activity/set-repo-subscription': activitySetRepoSubscription, + 'activity/set-thread-subscription': activitySetThreadSubscription, + 'activity/star-repo-for-authenticated-user': + activityStarRepoForAuthenticatedUser, + 'activity/unstar-repo-for-authenticated-user': + activityUnstarRepoForAuthenticatedUser, + 'agent-tasks/create-task-in-repo': agentTasksCreateTaskInRepo, + 'agent-tasks/get-task-by-id': agentTasksGetTaskById, + 'agent-tasks/get-task-by-repo-and-id': agentTasksGetTaskByRepoAndId, + 'agent-tasks/list-tasks': agentTasksListTasks, + 'agent-tasks/list-tasks-for-repo': agentTasksListTasksForRepo, + 'agents/add-selected-repo-to-org-secret': agentsAddSelectedRepoToOrgSecret, + 'agents/add-selected-repo-to-org-variable': + agentsAddSelectedRepoToOrgVariable, + 'agents/create-or-update-org-secret': agentsCreateOrUpdateOrgSecret, + 'agents/create-or-update-repo-secret': agentsCreateOrUpdateRepoSecret, + 'agents/create-org-variable': agentsCreateOrgVariable, + 'agents/create-repo-variable': agentsCreateRepoVariable, + 'agents/delete-org-secret': agentsDeleteOrgSecret, + 'agents/delete-org-variable': agentsDeleteOrgVariable, + 'agents/delete-repo-secret': agentsDeleteRepoSecret, + 'agents/delete-repo-variable': agentsDeleteRepoVariable, + 'agents/get-org-public-key': agentsGetOrgPublicKey, + 'agents/get-org-secret': agentsGetOrgSecret, + 'agents/get-org-variable': agentsGetOrgVariable, + 'agents/get-repo-public-key': agentsGetRepoPublicKey, + 'agents/get-repo-secret': agentsGetRepoSecret, + 'agents/get-repo-variable': agentsGetRepoVariable, + 'agents/list-org-secrets': agentsListOrgSecrets, + 'agents/list-org-variables': agentsListOrgVariables, + 'agents/list-repo-organization-secrets': agentsListRepoOrganizationSecrets, + 'agents/list-repo-organization-variables': + agentsListRepoOrganizationVariables, + 'agents/list-repo-secrets': agentsListRepoSecrets, + 'agents/list-repo-variables': agentsListRepoVariables, + 'agents/list-selected-repos-for-org-secret': + agentsListSelectedReposForOrgSecret, + 'agents/list-selected-repos-for-org-variable': + agentsListSelectedReposForOrgVariable, + 'agents/remove-selected-repo-from-org-secret': + agentsRemoveSelectedRepoFromOrgSecret, + 'agents/remove-selected-repo-from-org-variable': + agentsRemoveSelectedRepoFromOrgVariable, + 'agents/set-selected-repos-for-org-secret': + agentsSetSelectedReposForOrgSecret, + 'agents/set-selected-repos-for-org-variable': + agentsSetSelectedReposForOrgVariable, + 'agents/update-org-variable': agentsUpdateOrgVariable, + 'agents/update-repo-variable': agentsUpdateRepoVariable, + 'api-insights/get-route-stats-by-actor': apiInsightsGetRouteStatsByActor, + 'api-insights/get-subject-stats': apiInsightsGetSubjectStats, + 'api-insights/get-summary-stats': apiInsightsGetSummaryStats, + 'api-insights/get-summary-stats-by-actor': + apiInsightsGetSummaryStatsByActor, + 'api-insights/get-summary-stats-by-user': apiInsightsGetSummaryStatsByUser, + 'api-insights/get-time-stats': apiInsightsGetTimeStats, + 'api-insights/get-time-stats-by-actor': apiInsightsGetTimeStatsByActor, + 'api-insights/get-time-stats-by-user': apiInsightsGetTimeStatsByUser, + 'api-insights/get-user-stats': apiInsightsGetUserStats, + 'apps/add-repo-to-installation-for-authenticated-user': + appsAddRepoToInstallationForAuthenticatedUser, + 'apps/check-token': appsCheckToken, + 'apps/create-from-manifest': appsCreateFromManifest, + 'apps/create-installation-access-token': appsCreateInstallationAccessToken, + 'apps/delete-authorization': appsDeleteAuthorization, + 'apps/delete-installation': appsDeleteInstallation, + 'apps/delete-token': appsDeleteToken, + 'apps/get-authenticated': appsGetAuthenticated, + 'apps/get-by-slug': appsGetBySlug, + 'apps/get-installation': appsGetInstallation, + 'apps/get-org-installation': appsGetOrgInstallation, + 'apps/get-repo-installation': appsGetRepoInstallation, + 'apps/get-subscription-plan-for-account': appsGetSubscriptionPlanForAccount, + 'apps/get-subscription-plan-for-account-stubbed': + appsGetSubscriptionPlanForAccountStubbed, + 'apps/get-user-installation': appsGetUserInstallation, + 'apps/get-webhook-config-for-app': appsGetWebhookConfigForApp, + 'apps/get-webhook-delivery': appsGetWebhookDelivery, + 'apps/list-accounts-for-plan': appsListAccountsForPlan, + 'apps/list-accounts-for-plan-stubbed': appsListAccountsForPlanStubbed, + 'apps/list-installation-repos-for-authenticated-user': + appsListInstallationReposForAuthenticatedUser, + 'apps/list-installation-requests-for-authenticated-app': + appsListInstallationRequestsForAuthenticatedApp, + 'apps/list-installations': appsListInstallations, + 'apps/list-installations-for-authenticated-user': + appsListInstallationsForAuthenticatedUser, + 'apps/list-plans': appsListPlans, + 'apps/list-plans-stubbed': appsListPlansStubbed, + 'apps/list-repos-accessible-to-installation': + appsListReposAccessibleToInstallation, + 'apps/list-subscriptions-for-authenticated-user': + appsListSubscriptionsForAuthenticatedUser, + 'apps/list-subscriptions-for-authenticated-user-stubbed': + appsListSubscriptionsForAuthenticatedUserStubbed, + 'apps/list-webhook-deliveries': appsListWebhookDeliveries, + 'apps/redeliver-webhook-delivery': appsRedeliverWebhookDelivery, + 'apps/remove-repo-from-installation-for-authenticated-user': + appsRemoveRepoFromInstallationForAuthenticatedUser, + 'apps/reset-token': appsResetToken, + 'apps/revoke-installation-access-token': appsRevokeInstallationAccessToken, + 'apps/scope-token': appsScopeToken, + 'apps/suspend-installation': appsSuspendInstallation, + 'apps/unsuspend-installation': appsUnsuspendInstallation, + 'apps/update-webhook-config-for-app': appsUpdateWebhookConfigForApp, + 'billing/create-organization-budget': billingCreateOrganizationBudget, + 'billing/delete-budget-org': billingDeleteBudgetOrg, + 'billing/get-all-budgets-org': billingGetAllBudgetsOrg, + 'billing/get-budget-org': billingGetBudgetOrg, + 'billing/get-github-billing-ai-credit-usage-report-org': + billingGetGithubBillingAiCreditUsageReportOrg, + 'billing/get-github-billing-ai-credit-usage-report-user': + billingGetGithubBillingAiCreditUsageReportUser, + 'billing/get-github-billing-premium-request-usage-report-org': + billingGetGithubBillingPremiumRequestUsageReportOrg, + 'billing/get-github-billing-premium-request-usage-report-user': + billingGetGithubBillingPremiumRequestUsageReportUser, + 'billing/get-github-billing-usage-report-org': + billingGetGithubBillingUsageReportOrg, + 'billing/get-github-billing-usage-report-user': + billingGetGithubBillingUsageReportUser, + 'billing/get-github-billing-usage-summary-report-org': + billingGetGithubBillingUsageSummaryReportOrg, + 'billing/get-github-billing-usage-summary-report-user': + billingGetGithubBillingUsageSummaryReportUser, + 'billing/update-budget-org': billingUpdateBudgetOrg, + 'campaigns/create-campaign': campaignsCreateCampaign, + 'campaigns/delete-campaign': campaignsDeleteCampaign, + 'campaigns/get-campaign-summary': campaignsGetCampaignSummary, + 'campaigns/list-org-campaigns': campaignsListOrgCampaigns, + 'campaigns/update-campaign': campaignsUpdateCampaign, + 'checks/create': checksCreate, + 'checks/create-suite': checksCreateSuite, + 'checks/get': checksGet, + 'checks/get-suite': checksGetSuite, + 'checks/list-annotations': checksListAnnotations, + 'checks/list-for-ref': checksListForRef, + 'checks/list-for-suite': checksListForSuite, + 'checks/list-suites-for-ref': checksListSuitesForRef, + 'checks/rerequest-run': checksRerequestRun, + 'checks/rerequest-suite': checksRerequestSuite, + 'checks/set-suites-preferences': checksSetSuitesPreferences, + 'checks/update': checksUpdate, + 'classroom/get-a-classroom': classroomGetAClassroom, + 'classroom/get-an-assignment': classroomGetAnAssignment, + 'classroom/get-assignment-grades': classroomGetAssignmentGrades, + 'classroom/list-accepted-assignments-for-an-assignment': + classroomListAcceptedAssignmentsForAnAssignment, + 'classroom/list-assignments-for-a-classroom': + classroomListAssignmentsForAClassroom, + 'classroom/list-classrooms': classroomListClassrooms, + 'code-quality/get-finding': codeQualityGetFinding, + 'code-quality/get-setup': codeQualityGetSetup, + 'code-quality/list-findings-for-repo': codeQualityListFindingsForRepo, + 'code-quality/update-setup': codeQualityUpdateSetup, + 'code-scanning/commit-autofix': codeScanningCommitAutofix, + 'code-scanning/create-autofix': codeScanningCreateAutofix, + 'code-scanning/create-variant-analysis': codeScanningCreateVariantAnalysis, + 'code-scanning/delete-analysis': codeScanningDeleteAnalysis, + 'code-scanning/delete-codeql-database': codeScanningDeleteCodeqlDatabase, + 'code-scanning/get-ai-scan-enablement': codeScanningGetAiScanEnablement, + 'code-scanning/get-ai-scan-enablement-for-org': + codeScanningGetAiScanEnablementForOrg, + 'code-scanning/get-alert': codeScanningGetAlert, + 'code-scanning/get-analysis': codeScanningGetAnalysis, + 'code-scanning/get-autofix': codeScanningGetAutofix, + 'code-scanning/get-codeql-database': codeScanningGetCodeqlDatabase, + 'code-scanning/get-default-setup': codeScanningGetDefaultSetup, + 'code-scanning/get-sarif': codeScanningGetSarif, + 'code-scanning/get-variant-analysis': codeScanningGetVariantAnalysis, + 'code-scanning/get-variant-analysis-repo-task': + codeScanningGetVariantAnalysisRepoTask, + 'code-scanning/list-alert-instances': codeScanningListAlertInstances, + 'code-scanning/list-alerts-for-org': codeScanningListAlertsForOrg, + 'code-scanning/list-alerts-for-repo': codeScanningListAlertsForRepo, + 'code-scanning/list-codeql-databases': codeScanningListCodeqlDatabases, + 'code-scanning/list-recent-analyses': codeScanningListRecentAnalyses, + 'code-scanning/update-ai-scan-enablement': + codeScanningUpdateAiScanEnablement, + 'code-scanning/update-ai-scan-enablement-for-org': + codeScanningUpdateAiScanEnablementForOrg, + 'code-scanning/update-alert': codeScanningUpdateAlert, + 'code-scanning/update-default-setup': codeScanningUpdateDefaultSetup, + 'code-scanning/upload-sarif': codeScanningUploadSarif, + 'code-security/attach-configuration': codeSecurityAttachConfiguration, + 'code-security/attach-enterprise-configuration': + codeSecurityAttachEnterpriseConfiguration, + 'code-security/create-configuration': codeSecurityCreateConfiguration, + 'code-security/create-configuration-for-enterprise': + codeSecurityCreateConfigurationForEnterprise, + 'code-security/delete-configuration': codeSecurityDeleteConfiguration, + 'code-security/delete-configuration-for-enterprise': + codeSecurityDeleteConfigurationForEnterprise, + 'code-security/detach-configuration': codeSecurityDetachConfiguration, + 'code-security/get-configuration': codeSecurityGetConfiguration, + 'code-security/get-configuration-for-repository': + codeSecurityGetConfigurationForRepository, + 'code-security/get-configurations-for-enterprise': + codeSecurityGetConfigurationsForEnterprise, + 'code-security/get-configurations-for-org': + codeSecurityGetConfigurationsForOrg, + 'code-security/get-default-configurations': + codeSecurityGetDefaultConfigurations, + 'code-security/get-default-configurations-for-enterprise': + codeSecurityGetDefaultConfigurationsForEnterprise, + 'code-security/get-repositories-for-configuration': + codeSecurityGetRepositoriesForConfiguration, + 'code-security/get-repositories-for-enterprise-configuration': + codeSecurityGetRepositoriesForEnterpriseConfiguration, + 'code-security/get-single-configuration-for-enterprise': + codeSecurityGetSingleConfigurationForEnterprise, + 'code-security/set-configuration-as-default': + codeSecuritySetConfigurationAsDefault, + 'code-security/set-configuration-as-default-for-enterprise': + codeSecuritySetConfigurationAsDefaultForEnterprise, + 'code-security/update-configuration': codeSecurityUpdateConfiguration, + 'code-security/update-enterprise-configuration': + codeSecurityUpdateEnterpriseConfiguration, + 'codes-of-conduct/get-all-codes-of-conduct': + codesOfConductGetAllCodesOfConduct, + 'codes-of-conduct/get-conduct-code': codesOfConductGetConductCode, + 'codespaces/add-repository-for-secret-for-authenticated-user': + codespacesAddRepositoryForSecretForAuthenticatedUser, + 'codespaces/add-selected-repo-to-org-secret': + codespacesAddSelectedRepoToOrgSecret, + 'codespaces/check-permissions-for-devcontainer': + codespacesCheckPermissionsForDevcontainer, + 'codespaces/codespace-machines-for-authenticated-user': + codespacesCodespaceMachinesForAuthenticatedUser, + 'codespaces/create-for-authenticated-user': + codespacesCreateForAuthenticatedUser, + 'codespaces/create-or-update-org-secret': codespacesCreateOrUpdateOrgSecret, + 'codespaces/create-or-update-repo-secret': + codespacesCreateOrUpdateRepoSecret, + 'codespaces/create-or-update-secret-for-authenticated-user': + codespacesCreateOrUpdateSecretForAuthenticatedUser, + 'codespaces/create-with-pr-for-authenticated-user': + codespacesCreateWithPrForAuthenticatedUser, + 'codespaces/create-with-repo-for-authenticated-user': + codespacesCreateWithRepoForAuthenticatedUser, + 'codespaces/delete-codespaces-access-users': + codespacesDeleteCodespacesAccessUsers, + 'codespaces/delete-for-authenticated-user': + codespacesDeleteForAuthenticatedUser, + 'codespaces/delete-from-organization': codespacesDeleteFromOrganization, + 'codespaces/delete-org-secret': codespacesDeleteOrgSecret, + 'codespaces/delete-repo-secret': codespacesDeleteRepoSecret, + 'codespaces/delete-secret-for-authenticated-user': + codespacesDeleteSecretForAuthenticatedUser, + 'codespaces/export-for-authenticated-user': + codespacesExportForAuthenticatedUser, + 'codespaces/get-codespaces-for-user-in-org': + codespacesGetCodespacesForUserInOrg, + 'codespaces/get-export-details-for-authenticated-user': + codespacesGetExportDetailsForAuthenticatedUser, + 'codespaces/get-for-authenticated-user': codespacesGetForAuthenticatedUser, + 'codespaces/get-org-public-key': codespacesGetOrgPublicKey, + 'codespaces/get-org-secret': codespacesGetOrgSecret, + 'codespaces/get-public-key-for-authenticated-user': + codespacesGetPublicKeyForAuthenticatedUser, + 'codespaces/get-repo-public-key': codespacesGetRepoPublicKey, + 'codespaces/get-repo-secret': codespacesGetRepoSecret, + 'codespaces/get-secret-for-authenticated-user': + codespacesGetSecretForAuthenticatedUser, + 'codespaces/list-devcontainers-in-repository-for-authenticated-user': + codespacesListDevcontainersInRepositoryForAuthenticatedUser, + 'codespaces/list-for-authenticated-user': + codespacesListForAuthenticatedUser, + 'codespaces/list-in-organization': codespacesListInOrganization, + 'codespaces/list-in-repository-for-authenticated-user': + codespacesListInRepositoryForAuthenticatedUser, + 'codespaces/list-org-secrets': codespacesListOrgSecrets, + 'codespaces/list-repo-secrets': codespacesListRepoSecrets, + 'codespaces/list-repositories-for-secret-for-authenticated-user': + codespacesListRepositoriesForSecretForAuthenticatedUser, + 'codespaces/list-secrets-for-authenticated-user': + codespacesListSecretsForAuthenticatedUser, + 'codespaces/list-selected-repos-for-org-secret': + codespacesListSelectedReposForOrgSecret, + 'codespaces/pre-flight-with-repo-for-authenticated-user': + codespacesPreFlightWithRepoForAuthenticatedUser, + 'codespaces/publish-for-authenticated-user': + codespacesPublishForAuthenticatedUser, + 'codespaces/remove-repository-for-secret-for-authenticated-user': + codespacesRemoveRepositoryForSecretForAuthenticatedUser, + 'codespaces/remove-selected-repo-from-org-secret': + codespacesRemoveSelectedRepoFromOrgSecret, + 'codespaces/repo-machines-for-authenticated-user': + codespacesRepoMachinesForAuthenticatedUser, + 'codespaces/set-codespaces-access': codespacesSetCodespacesAccess, + 'codespaces/set-codespaces-access-users': + codespacesSetCodespacesAccessUsers, + 'codespaces/set-repositories-for-secret-for-authenticated-user': + codespacesSetRepositoriesForSecretForAuthenticatedUser, + 'codespaces/set-selected-repos-for-org-secret': + codespacesSetSelectedReposForOrgSecret, + 'codespaces/start-for-authenticated-user': + codespacesStartForAuthenticatedUser, + 'codespaces/stop-for-authenticated-user': + codespacesStopForAuthenticatedUser, + 'codespaces/stop-in-organization': codespacesStopInOrganization, + 'codespaces/update-for-authenticated-user': + codespacesUpdateForAuthenticatedUser, + 'copilot-spaces/add-collaborator-for-org': + copilotSpacesAddCollaboratorForOrg, + 'copilot-spaces/add-collaborator-for-user': + copilotSpacesAddCollaboratorForUser, + 'copilot-spaces/create-for-org': copilotSpacesCreateForOrg, + 'copilot-spaces/create-for-user': copilotSpacesCreateForUser, + 'copilot-spaces/create-resource-for-org': copilotSpacesCreateResourceForOrg, + 'copilot-spaces/create-resource-for-user': + copilotSpacesCreateResourceForUser, + 'copilot-spaces/delete-for-org': copilotSpacesDeleteForOrg, + 'copilot-spaces/delete-for-user': copilotSpacesDeleteForUser, + 'copilot-spaces/delete-resource-for-org': copilotSpacesDeleteResourceForOrg, + 'copilot-spaces/delete-resource-for-user': + copilotSpacesDeleteResourceForUser, + 'copilot-spaces/get-for-org': copilotSpacesGetForOrg, + 'copilot-spaces/get-for-user': copilotSpacesGetForUser, + 'copilot-spaces/get-resource-for-org': copilotSpacesGetResourceForOrg, + 'copilot-spaces/get-resource-for-user': copilotSpacesGetResourceForUser, + 'copilot-spaces/list-collaborators-for-org': + copilotSpacesListCollaboratorsForOrg, + 'copilot-spaces/list-collaborators-for-user': + copilotSpacesListCollaboratorsForUser, + 'copilot-spaces/list-for-org': copilotSpacesListForOrg, + 'copilot-spaces/list-for-user': copilotSpacesListForUser, + 'copilot-spaces/list-resources-for-org': copilotSpacesListResourcesForOrg, + 'copilot-spaces/list-resources-for-user': copilotSpacesListResourcesForUser, + 'copilot-spaces/remove-collaborator-for-org': + copilotSpacesRemoveCollaboratorForOrg, + 'copilot-spaces/remove-collaborator-for-user': + copilotSpacesRemoveCollaboratorForUser, + 'copilot-spaces/update-collaborator-for-org': + copilotSpacesUpdateCollaboratorForOrg, + 'copilot-spaces/update-collaborator-for-user': + copilotSpacesUpdateCollaboratorForUser, + 'copilot-spaces/update-for-org': copilotSpacesUpdateForOrg, + 'copilot-spaces/update-for-user': copilotSpacesUpdateForUser, + 'copilot-spaces/update-resource-for-org': copilotSpacesUpdateResourceForOrg, + 'copilot-spaces/update-resource-for-user': + copilotSpacesUpdateResourceForUser, + 'copilot/add-copilot-seats-for-teams': copilotAddCopilotSeatsForTeams, + 'copilot/add-copilot-seats-for-users': copilotAddCopilotSeatsForUsers, + 'copilot/add-organizations-to-enterprise-coding-agent-policy': + copilotAddOrganizationsToEnterpriseCodingAgentPolicy, + 'copilot/cancel-copilot-seat-assignment-for-teams': + copilotCancelCopilotSeatAssignmentForTeams, + 'copilot/cancel-copilot-seat-assignment-for-users': + copilotCancelCopilotSeatAssignmentForUsers, + 'copilot/copilot-content-exclusion-for-organization': + copilotCopilotContentExclusionForOrganization, + 'copilot/copilot-enterprise-one-day-usage-metrics': + copilotCopilotEnterpriseOneDayUsageMetrics, + 'copilot/copilot-enterprise-repos-one-day-report': + copilotCopilotEnterpriseReposOneDayReport, + 'copilot/copilot-enterprise-usage-metrics': + copilotCopilotEnterpriseUsageMetrics, + 'copilot/copilot-enterprise-user-teams-one-day-report': + copilotCopilotEnterpriseUserTeamsOneDayReport, + 'copilot/copilot-organization-one-day-usage-metrics': + copilotCopilotOrganizationOneDayUsageMetrics, + 'copilot/copilot-organization-repos-one-day-report': + copilotCopilotOrganizationReposOneDayReport, + 'copilot/copilot-organization-usage-metrics': + copilotCopilotOrganizationUsageMetrics, + 'copilot/copilot-organization-user-teams-one-day-report': + copilotCopilotOrganizationUserTeamsOneDayReport, + 'copilot/copilot-organization-users-one-day-usage-metrics': + copilotCopilotOrganizationUsersOneDayUsageMetrics, + 'copilot/copilot-organization-users-usage-metrics': + copilotCopilotOrganizationUsersUsageMetrics, + 'copilot/copilot-users-one-day-usage-metrics': + copilotCopilotUsersOneDayUsageMetrics, + 'copilot/copilot-users-usage-metrics': copilotCopilotUsersUsageMetrics, + 'copilot/disable-copilot-coding-agent-for-repository-in-organization': + copilotDisableCopilotCodingAgentForRepositoryInOrganization, + 'copilot/enable-copilot-coding-agent-for-repository-in-organization': + copilotEnableCopilotCodingAgentForRepositoryInOrganization, + 'copilot/get-copilot-cloud-agent-configuration': + copilotGetCopilotCloudAgentConfiguration, + 'copilot/get-copilot-coding-agent-permissions-organization': + copilotGetCopilotCodingAgentPermissionsOrganization, + 'copilot/get-copilot-organization-details': + copilotGetCopilotOrganizationDetails, + 'copilot/get-copilot-seat-details-for-user': + copilotGetCopilotSeatDetailsForUser, + 'copilot/list-copilot-coding-agent-selected-repositories-for-organization': + copilotListCopilotCodingAgentSelectedRepositoriesForOrganization, + 'copilot/list-copilot-seats': copilotListCopilotSeats, + 'copilot/remove-organizations-from-enterprise-coding-agent-policy': + copilotRemoveOrganizationsFromEnterpriseCodingAgentPolicy, + 'copilot/set-copilot-coding-agent-permissions-organization': + copilotSetCopilotCodingAgentPermissionsOrganization, + 'copilot/set-copilot-coding-agent-selected-repositories-for-organization': + copilotSetCopilotCodingAgentSelectedRepositoriesForOrganization, + 'copilot/set-copilot-content-exclusion-for-organization': + copilotSetCopilotContentExclusionForOrganization, + 'copilot/set-enterprise-coding-agent-policy': + copilotSetEnterpriseCodingAgentPolicy, + 'credentials/revoke': credentialsRevoke, + 'dependabot/add-selected-repo-to-org-secret': + dependabotAddSelectedRepoToOrgSecret, + 'dependabot/create-or-update-org-secret': dependabotCreateOrUpdateOrgSecret, + 'dependabot/create-or-update-repo-secret': + dependabotCreateOrUpdateRepoSecret, + 'dependabot/delete-org-secret': dependabotDeleteOrgSecret, + 'dependabot/delete-repo-secret': dependabotDeleteRepoSecret, + 'dependabot/get-alert': dependabotGetAlert, + 'dependabot/get-org-public-key': dependabotGetOrgPublicKey, + 'dependabot/get-org-secret': dependabotGetOrgSecret, + 'dependabot/get-repo-public-key': dependabotGetRepoPublicKey, + 'dependabot/get-repo-secret': dependabotGetRepoSecret, + 'dependabot/list-alerts-for-enterprise': dependabotListAlertsForEnterprise, + 'dependabot/list-alerts-for-org': dependabotListAlertsForOrg, + 'dependabot/list-alerts-for-repo': dependabotListAlertsForRepo, + 'dependabot/list-org-secrets': dependabotListOrgSecrets, + 'dependabot/list-repo-secrets': dependabotListRepoSecrets, + 'dependabot/list-selected-repos-for-org-secret': + dependabotListSelectedReposForOrgSecret, + 'dependabot/remove-selected-repo-from-org-secret': + dependabotRemoveSelectedRepoFromOrgSecret, + 'dependabot/repository-access-for-enterprise': + dependabotRepositoryAccessForEnterprise, + 'dependabot/repository-access-for-org': dependabotRepositoryAccessForOrg, + 'dependabot/set-repository-access-default-level': + dependabotSetRepositoryAccessDefaultLevel, + 'dependabot/set-repository-access-default-level-for-enterprise': + dependabotSetRepositoryAccessDefaultLevelForEnterprise, + 'dependabot/set-selected-repos-for-org-secret': + dependabotSetSelectedReposForOrgSecret, + 'dependabot/update-alert': dependabotUpdateAlert, + 'dependabot/update-repository-access-for-enterprise': + dependabotUpdateRepositoryAccessForEnterprise, + 'dependabot/update-repository-access-for-org': + dependabotUpdateRepositoryAccessForOrg, + 'dependency-graph/create-repository-snapshot': + dependencyGraphCreateRepositorySnapshot, + 'dependency-graph/diff-range': dependencyGraphDiffRange, + 'dependency-graph/export-sbom': dependencyGraphExportSbom, + 'dependency-graph/fetch-sbom-report': dependencyGraphFetchSbomReport, + 'dependency-graph/generate-sbom-report': dependencyGraphGenerateSbomReport, + 'emojis/get': emojisGet, + 'enterprise-team-memberships/add': enterpriseTeamMembershipsAdd, + 'enterprise-team-memberships/bulk-add': enterpriseTeamMembershipsBulkAdd, + 'enterprise-team-memberships/bulk-remove': + enterpriseTeamMembershipsBulkRemove, + 'enterprise-team-memberships/get': enterpriseTeamMembershipsGet, + 'enterprise-team-memberships/list': enterpriseTeamMembershipsList, + 'enterprise-team-memberships/list-teams-for-user': + enterpriseTeamMembershipsListTeamsForUser, + 'enterprise-team-memberships/remove': enterpriseTeamMembershipsRemove, + 'enterprise-team-organizations/add': enterpriseTeamOrganizationsAdd, + 'enterprise-team-organizations/bulk-add': + enterpriseTeamOrganizationsBulkAdd, + 'enterprise-team-organizations/bulk-remove': + enterpriseTeamOrganizationsBulkRemove, + 'enterprise-team-organizations/delete': enterpriseTeamOrganizationsDelete, + 'enterprise-team-organizations/get-assignment': + enterpriseTeamOrganizationsGetAssignment, + 'enterprise-team-organizations/get-assignments': + enterpriseTeamOrganizationsGetAssignments, + 'enterprise-teams/create': enterpriseTeamsCreate, + 'enterprise-teams/delete': enterpriseTeamsDelete, + 'enterprise-teams/get': enterpriseTeamsGet, + 'enterprise-teams/list': enterpriseTeamsList, + 'enterprise-teams/update': enterpriseTeamsUpdate, + 'gists/check-is-starred': gistsCheckIsStarred, + 'gists/create': gistsCreate, + 'gists/create-comment': gistsCreateComment, + 'gists/delete': gistsDelete, + 'gists/delete-comment': gistsDeleteComment, + 'gists/fork': gistsFork, + 'gists/get': gistsGet, + 'gists/get-comment': gistsGetComment, + 'gists/get-revision': gistsGetRevision, + 'gists/list': gistsList, + 'gists/list-comments': gistsListComments, + 'gists/list-commits': gistsListCommits, + 'gists/list-for-user': gistsListForUser, + 'gists/list-forks': gistsListForks, + 'gists/list-public': gistsListPublic, + 'gists/list-starred': gistsListStarred, + 'gists/star': gistsStar, + 'gists/unstar': gistsUnstar, + 'gists/update': gistsUpdate, + 'gists/update-comment': gistsUpdateComment, + 'git/create-blob': gitCreateBlob, + 'git/create-commit': gitCreateCommit, + 'git/create-ref': gitCreateRef, + 'git/create-tag': gitCreateTag, + 'git/create-tree': gitCreateTree, + 'git/delete-ref': gitDeleteRef, + 'git/get-blob': gitGetBlob, + 'git/get-commit': gitGetCommit, + 'git/get-ref': gitGetRef, + 'git/get-tag': gitGetTag, + 'git/get-tree': gitGetTree, + 'git/list-matching-refs': gitListMatchingRefs, + 'git/update-ref': gitUpdateRef, + 'gitignore/get-all-templates': gitignoreGetAllTemplates, + 'gitignore/get-template': gitignoreGetTemplate, + 'hosted-compute/create-network-configuration-for-org': + hostedComputeCreateNetworkConfigurationForOrg, + 'hosted-compute/delete-network-configuration-from-org': + hostedComputeDeleteNetworkConfigurationFromOrg, + 'hosted-compute/get-network-configuration-for-org': + hostedComputeGetNetworkConfigurationForOrg, + 'hosted-compute/get-network-settings-for-org': + hostedComputeGetNetworkSettingsForOrg, + 'hosted-compute/list-network-configurations-for-org': + hostedComputeListNetworkConfigurationsForOrg, + 'hosted-compute/update-network-configuration-for-org': + hostedComputeUpdateNetworkConfigurationForOrg, + 'interactions/get-pull-request-bypass-list-for-repo': + interactionsGetPullRequestBypassListForRepo, + 'interactions/get-pull-request-creation-cap-for-org': + interactionsGetPullRequestCreationCapForOrg, + 'interactions/get-pull-request-creation-cap-for-repo': + interactionsGetPullRequestCreationCapForRepo, + 'interactions/get-restrictions-for-authenticated-user': + interactionsGetRestrictionsForAuthenticatedUser, + 'interactions/get-restrictions-for-org': interactionsGetRestrictionsForOrg, + 'interactions/get-restrictions-for-repo': + interactionsGetRestrictionsForRepo, + 'interactions/remove-pull-request-bypass-list-for-repo': + interactionsRemovePullRequestBypassListForRepo, + 'interactions/remove-restrictions-for-authenticated-user': + interactionsRemoveRestrictionsForAuthenticatedUser, + 'interactions/remove-restrictions-for-org': + interactionsRemoveRestrictionsForOrg, + 'interactions/remove-restrictions-for-repo': + interactionsRemoveRestrictionsForRepo, + 'interactions/set-pull-request-bypass-list-for-repo': + interactionsSetPullRequestBypassListForRepo, + 'interactions/set-restrictions-for-authenticated-user': + interactionsSetRestrictionsForAuthenticatedUser, + 'interactions/set-restrictions-for-org': interactionsSetRestrictionsForOrg, + 'interactions/set-restrictions-for-repo': + interactionsSetRestrictionsForRepo, + 'interactions/update-pull-request-creation-cap-for-org': + interactionsUpdatePullRequestCreationCapForOrg, + 'interactions/update-pull-request-creation-cap-for-repo': + interactionsUpdatePullRequestCreationCapForRepo, + 'issues/add-assignees': issuesAddAssignees, + 'issues/add-blocked-by-dependency': issuesAddBlockedByDependency, + 'issues/add-issue-field-values': issuesAddIssueFieldValues, + 'issues/add-labels': issuesAddLabels, + 'issues/add-sub-issue': issuesAddSubIssue, + 'issues/approve-suggestion': issuesApproveSuggestion, + 'issues/check-user-can-be-assigned': issuesCheckUserCanBeAssigned, + 'issues/check-user-can-be-assigned-to-issue': + issuesCheckUserCanBeAssignedToIssue, + 'issues/create': issuesCreate, + 'issues/create-comment': issuesCreateComment, + 'issues/create-label': issuesCreateLabel, + 'issues/create-milestone': issuesCreateMilestone, + 'issues/delete-comment': issuesDeleteComment, + 'issues/delete-issue-field-value': issuesDeleteIssueFieldValue, + 'issues/delete-label': issuesDeleteLabel, + 'issues/delete-milestone': issuesDeleteMilestone, + 'issues/dismiss-suggestion': issuesDismissSuggestion, + 'issues/get': issuesGet, + 'issues/get-comment': issuesGetComment, + 'issues/get-event': issuesGetEvent, + 'issues/get-label': issuesGetLabel, + 'issues/get-milestone': issuesGetMilestone, + 'issues/get-parent': issuesGetParent, + 'issues/list': issuesList, + 'issues/list-assignees': issuesListAssignees, + 'issues/list-comments': issuesListComments, + 'issues/list-comments-for-repo': issuesListCommentsForRepo, + 'issues/list-dependencies-blocked-by': issuesListDependenciesBlockedBy, + 'issues/list-dependencies-blocking': issuesListDependenciesBlocking, + 'issues/list-events': issuesListEvents, + 'issues/list-events-for-repo': issuesListEventsForRepo, + 'issues/list-events-for-timeline': issuesListEventsForTimeline, + 'issues/list-for-authenticated-user': issuesListForAuthenticatedUser, + 'issues/list-for-org': issuesListForOrg, + 'issues/list-for-repo': issuesListForRepo, + 'issues/list-issue-field-values-for-issue': + issuesListIssueFieldValuesForIssue, + 'issues/list-labels-for-milestone': issuesListLabelsForMilestone, + 'issues/list-labels-for-repo': issuesListLabelsForRepo, + 'issues/list-labels-on-issue': issuesListLabelsOnIssue, + 'issues/list-milestones': issuesListMilestones, + 'issues/list-sub-issues': issuesListSubIssues, + 'issues/list-suggestions': issuesListSuggestions, + 'issues/lock': issuesLock, + 'issues/pin-comment': issuesPinComment, + 'issues/remove-all-labels': issuesRemoveAllLabels, + 'issues/remove-assignees': issuesRemoveAssignees, + 'issues/remove-dependency-blocked-by': issuesRemoveDependencyBlockedBy, + 'issues/remove-label': issuesRemoveLabel, + 'issues/remove-sub-issue': issuesRemoveSubIssue, + 'issues/reprioritize-sub-issue': issuesReprioritizeSubIssue, + 'issues/set-issue-field-values': issuesSetIssueFieldValues, + 'issues/set-labels': issuesSetLabels, + 'issues/unlock': issuesUnlock, + 'issues/unpin-comment': issuesUnpinComment, + 'issues/update': issuesUpdate, + 'issues/update-comment': issuesUpdateComment, + 'issues/update-label': issuesUpdateLabel, + 'issues/update-milestone': issuesUpdateMilestone, + 'licenses/get': licensesGet, + 'licenses/get-all-commonly-used': licensesGetAllCommonlyUsed, + 'licenses/get-for-repo': licensesGetForRepo, + 'markdown/render': markdownRender, + 'markdown/render-raw': markdownRenderRaw, + 'meta/get': metaGet, + 'meta/get-all-versions': metaGetAllVersions, + 'meta/get-octocat': metaGetOctocat, + 'meta/get-zen': metaGetZen, + 'meta/root': metaRoot, + 'migrations/cancel-import': migrationsCancelImport, + 'migrations/delete-archive-for-authenticated-user': + migrationsDeleteArchiveForAuthenticatedUser, + 'migrations/delete-archive-for-org': migrationsDeleteArchiveForOrg, + 'migrations/download-archive-for-org': migrationsDownloadArchiveForOrg, + 'migrations/get-archive-for-authenticated-user': + migrationsGetArchiveForAuthenticatedUser, + 'migrations/get-commit-authors': migrationsGetCommitAuthors, + 'migrations/get-import-status': migrationsGetImportStatus, + 'migrations/get-large-files': migrationsGetLargeFiles, + 'migrations/get-status-for-authenticated-user': + migrationsGetStatusForAuthenticatedUser, + 'migrations/get-status-for-org': migrationsGetStatusForOrg, + 'migrations/list-for-authenticated-user': + migrationsListForAuthenticatedUser, + 'migrations/list-for-org': migrationsListForOrg, + 'migrations/list-repos-for-authenticated-user': + migrationsListReposForAuthenticatedUser, + 'migrations/list-repos-for-org': migrationsListReposForOrg, + 'migrations/map-commit-author': migrationsMapCommitAuthor, + 'migrations/set-lfs-preference': migrationsSetLfsPreference, + 'migrations/start-for-authenticated-user': + migrationsStartForAuthenticatedUser, + 'migrations/start-for-org': migrationsStartForOrg, + 'migrations/start-import': migrationsStartImport, + 'migrations/unlock-repo-for-authenticated-user': + migrationsUnlockRepoForAuthenticatedUser, + 'migrations/unlock-repo-for-org': migrationsUnlockRepoForOrg, + 'migrations/update-import': migrationsUpdateImport, + 'oidc/create-oidc-custom-property-inclusion-for-enterprise': + oidcCreateOidcCustomPropertyInclusionForEnterprise, + 'oidc/create-oidc-custom-property-inclusion-for-org': + oidcCreateOidcCustomPropertyInclusionForOrg, + 'oidc/delete-oidc-custom-property-inclusion-for-enterprise': + oidcDeleteOidcCustomPropertyInclusionForEnterprise, + 'oidc/delete-oidc-custom-property-inclusion-for-org': + oidcDeleteOidcCustomPropertyInclusionForOrg, + 'oidc/get-oidc-custom-sub-template-for-org': + oidcGetOidcCustomSubTemplateForOrg, + 'oidc/list-oidc-custom-property-inclusions-for-enterprise': + oidcListOidcCustomPropertyInclusionsForEnterprise, + 'oidc/list-oidc-custom-property-inclusions-for-org': + oidcListOidcCustomPropertyInclusionsForOrg, + 'oidc/update-oidc-custom-sub-template-for-org': + oidcUpdateOidcCustomSubTemplateForOrg, + 'orgs/add-security-manager-team': orgsAddSecurityManagerTeam, + 'orgs/assign-team-to-org-role': orgsAssignTeamToOrgRole, + 'orgs/assign-user-to-org-role': orgsAssignUserToOrgRole, + 'orgs/block-user': orgsBlockUser, + 'orgs/cancel-invitation': orgsCancelInvitation, + 'orgs/check-blocked-user': orgsCheckBlockedUser, + 'orgs/check-membership-for-user': orgsCheckMembershipForUser, + 'orgs/check-public-membership-for-user': orgsCheckPublicMembershipForUser, + 'orgs/convert-member-to-outside-collaborator': + orgsConvertMemberToOutsideCollaborator, + 'orgs/create-artifact-deployment-record': + orgsCreateArtifactDeploymentRecord, + 'orgs/create-artifact-storage-record': orgsCreateArtifactStorageRecord, + 'orgs/create-cluster-deployment-records-job': + orgsCreateClusterDeploymentRecordsJob, + 'orgs/create-invitation': orgsCreateInvitation, + 'orgs/create-issue-field': orgsCreateIssueField, + 'orgs/create-issue-type': orgsCreateIssueType, + 'orgs/create-webhook': orgsCreateWebhook, + 'orgs/custom-properties-for-repos-create-or-update-organization-definition': + orgsCustomPropertiesForReposCreateOrUpdateOrganizationDefinition, + 'orgs/custom-properties-for-repos-create-or-update-organization-definitions': + orgsCustomPropertiesForReposCreateOrUpdateOrganizationDefinitions, + 'orgs/custom-properties-for-repos-create-or-update-organization-values': + orgsCustomPropertiesForReposCreateOrUpdateOrganizationValues, + 'orgs/custom-properties-for-repos-delete-organization-definition': + orgsCustomPropertiesForReposDeleteOrganizationDefinition, + 'orgs/custom-properties-for-repos-get-organization-definition': + orgsCustomPropertiesForReposGetOrganizationDefinition, + 'orgs/custom-properties-for-repos-get-organization-definitions': + orgsCustomPropertiesForReposGetOrganizationDefinitions, + 'orgs/custom-properties-for-repos-get-organization-values': + orgsCustomPropertiesForReposGetOrganizationValues, + 'orgs/delete': orgsDelete, + 'orgs/delete-attestations-bulk': orgsDeleteAttestationsBulk, + 'orgs/delete-attestations-by-id': orgsDeleteAttestationsById, + 'orgs/delete-attestations-by-subject-digest': + orgsDeleteAttestationsBySubjectDigest, + 'orgs/delete-issue-field': orgsDeleteIssueField, + 'orgs/delete-issue-type': orgsDeleteIssueType, + 'orgs/delete-webhook': orgsDeleteWebhook, + 'orgs/disable-selected-repository-immutable-releases-organization': + orgsDisableSelectedRepositoryImmutableReleasesOrganization, + 'orgs/enable-or-disable-security-product-on-all-org-repos': + orgsEnableOrDisableSecurityProductOnAllOrgRepos, + 'orgs/enable-selected-repository-immutable-releases-organization': + orgsEnableSelectedRepositoryImmutableReleasesOrganization, + 'orgs/get': orgsGet, + 'orgs/get-cluster-deployment-records-job': + orgsGetClusterDeploymentRecordsJob, + 'orgs/get-immutable-releases-settings': orgsGetImmutableReleasesSettings, + 'orgs/get-immutable-releases-settings-repositories': + orgsGetImmutableReleasesSettingsRepositories, + 'orgs/get-membership-for-authenticated-user': + orgsGetMembershipForAuthenticatedUser, + 'orgs/get-membership-for-user': orgsGetMembershipForUser, + 'orgs/get-org-role': orgsGetOrgRole, + 'orgs/get-org-ruleset-history': orgsGetOrgRulesetHistory, + 'orgs/get-org-ruleset-version': orgsGetOrgRulesetVersion, + 'orgs/get-webhook': orgsGetWebhook, + 'orgs/get-webhook-config-for-org': orgsGetWebhookConfigForOrg, + 'orgs/get-webhook-delivery': orgsGetWebhookDelivery, + 'orgs/list': orgsList, + 'orgs/list-app-installations': orgsListAppInstallations, + 'orgs/list-artifact-deployment-records': orgsListArtifactDeploymentRecords, + 'orgs/list-artifact-storage-records': orgsListArtifactStorageRecords, + 'orgs/list-attestation-repositories': orgsListAttestationRepositories, + 'orgs/list-attestations': orgsListAttestations, + 'orgs/list-attestations-bulk': orgsListAttestationsBulk, + 'orgs/list-blocked-users': orgsListBlockedUsers, + 'orgs/list-failed-invitations': orgsListFailedInvitations, + 'orgs/list-for-authenticated-user': orgsListForAuthenticatedUser, + 'orgs/list-for-user': orgsListForUser, + 'orgs/list-invitation-teams': orgsListInvitationTeams, + 'orgs/list-issue-fields': orgsListIssueFields, + 'orgs/list-issue-types': orgsListIssueTypes, + 'orgs/list-members': orgsListMembers, + 'orgs/list-memberships-for-authenticated-user': + orgsListMembershipsForAuthenticatedUser, + 'orgs/list-org-role-teams': orgsListOrgRoleTeams, + 'orgs/list-org-role-users': orgsListOrgRoleUsers, + 'orgs/list-org-roles': orgsListOrgRoles, + 'orgs/list-outside-collaborators': orgsListOutsideCollaborators, + 'orgs/list-pat-grant-repositories': orgsListPatGrantRepositories, + 'orgs/list-pat-grant-request-repositories': + orgsListPatGrantRequestRepositories, + 'orgs/list-pat-grant-requests': orgsListPatGrantRequests, + 'orgs/list-pat-grants': orgsListPatGrants, + 'orgs/list-pending-invitations': orgsListPendingInvitations, + 'orgs/list-public-members': orgsListPublicMembers, + 'orgs/list-security-manager-teams': orgsListSecurityManagerTeams, + 'orgs/list-webhook-deliveries': orgsListWebhookDeliveries, + 'orgs/list-webhooks': orgsListWebhooks, + 'orgs/ping-webhook': orgsPingWebhook, + 'orgs/redeliver-webhook-delivery': orgsRedeliverWebhookDelivery, + 'orgs/remove-member': orgsRemoveMember, + 'orgs/remove-membership-for-user': orgsRemoveMembershipForUser, + 'orgs/remove-outside-collaborator': orgsRemoveOutsideCollaborator, + 'orgs/remove-public-membership-for-authenticated-user': + orgsRemovePublicMembershipForAuthenticatedUser, + 'orgs/remove-security-manager-team': orgsRemoveSecurityManagerTeam, + 'orgs/review-pat-grant-request': orgsReviewPatGrantRequest, + 'orgs/review-pat-grant-requests-in-bulk': orgsReviewPatGrantRequestsInBulk, + 'orgs/revoke-all-org-roles-team': orgsRevokeAllOrgRolesTeam, + 'orgs/revoke-all-org-roles-user': orgsRevokeAllOrgRolesUser, + 'orgs/revoke-org-role-team': orgsRevokeOrgRoleTeam, + 'orgs/revoke-org-role-user': orgsRevokeOrgRoleUser, + 'orgs/set-cluster-deployment-records': orgsSetClusterDeploymentRecords, + 'orgs/set-immutable-releases-settings': orgsSetImmutableReleasesSettings, + 'orgs/set-immutable-releases-settings-repositories': + orgsSetImmutableReleasesSettingsRepositories, + 'orgs/set-membership-for-user': orgsSetMembershipForUser, + 'orgs/set-public-membership-for-authenticated-user': + orgsSetPublicMembershipForAuthenticatedUser, + 'orgs/unblock-user': orgsUnblockUser, + 'orgs/update': orgsUpdate, + 'orgs/update-issue-field': orgsUpdateIssueField, + 'orgs/update-issue-type': orgsUpdateIssueType, + 'orgs/update-membership-for-authenticated-user': + orgsUpdateMembershipForAuthenticatedUser, + 'orgs/update-pat-access': orgsUpdatePatAccess, + 'orgs/update-pat-accesses': orgsUpdatePatAccesses, + 'orgs/update-webhook': orgsUpdateWebhook, + 'orgs/update-webhook-config-for-org': orgsUpdateWebhookConfigForOrg, + 'packages/delete-package-for-authenticated-user': + packagesDeletePackageForAuthenticatedUser, + 'packages/delete-package-for-org': packagesDeletePackageForOrg, + 'packages/delete-package-for-user': packagesDeletePackageForUser, + 'packages/delete-package-version-for-authenticated-user': + packagesDeletePackageVersionForAuthenticatedUser, + 'packages/delete-package-version-for-org': + packagesDeletePackageVersionForOrg, + 'packages/delete-package-version-for-user': + packagesDeletePackageVersionForUser, + 'packages/get-all-package-versions-for-package-owned-by-authenticated-user': + packagesGetAllPackageVersionsForPackageOwnedByAuthenticatedUser, + 'packages/get-all-package-versions-for-package-owned-by-org': + packagesGetAllPackageVersionsForPackageOwnedByOrg, + 'packages/get-all-package-versions-for-package-owned-by-user': + packagesGetAllPackageVersionsForPackageOwnedByUser, + 'packages/get-package-for-authenticated-user': + packagesGetPackageForAuthenticatedUser, + 'packages/get-package-for-organization': packagesGetPackageForOrganization, + 'packages/get-package-for-user': packagesGetPackageForUser, + 'packages/get-package-version-for-authenticated-user': + packagesGetPackageVersionForAuthenticatedUser, + 'packages/get-package-version-for-organization': + packagesGetPackageVersionForOrganization, + 'packages/get-package-version-for-user': packagesGetPackageVersionForUser, + 'packages/list-docker-migration-conflicting-packages-for-authenticated-user': + packagesListDockerMigrationConflictingPackagesForAuthenticatedUser, + 'packages/list-docker-migration-conflicting-packages-for-organization': + packagesListDockerMigrationConflictingPackagesForOrganization, + 'packages/list-docker-migration-conflicting-packages-for-user': + packagesListDockerMigrationConflictingPackagesForUser, + 'packages/list-packages-for-authenticated-user': + packagesListPackagesForAuthenticatedUser, + 'packages/list-packages-for-organization': + packagesListPackagesForOrganization, + 'packages/list-packages-for-user': packagesListPackagesForUser, + 'packages/restore-package-for-authenticated-user': + packagesRestorePackageForAuthenticatedUser, + 'packages/restore-package-for-org': packagesRestorePackageForOrg, + 'packages/restore-package-for-user': packagesRestorePackageForUser, + 'packages/restore-package-version-for-authenticated-user': + packagesRestorePackageVersionForAuthenticatedUser, + 'packages/restore-package-version-for-org': + packagesRestorePackageVersionForOrg, + 'packages/restore-package-version-for-user': + packagesRestorePackageVersionForUser, + 'private-registries/create-org-private-registry': + privateRegistriesCreateOrgPrivateRegistry, + 'private-registries/delete-org-private-registry': + privateRegistriesDeleteOrgPrivateRegistry, + 'private-registries/get-org-private-registry': + privateRegistriesGetOrgPrivateRegistry, + 'private-registries/get-org-public-key': privateRegistriesGetOrgPublicKey, + 'private-registries/list-org-private-registries': + privateRegistriesListOrgPrivateRegistries, + 'private-registries/update-org-private-registry': + privateRegistriesUpdateOrgPrivateRegistry, + 'projects/add-field-for-org': projectsAddFieldForOrg, + 'projects/add-field-for-user': projectsAddFieldForUser, + 'projects/add-item-for-org': projectsAddItemForOrg, + 'projects/add-item-for-user': projectsAddItemForUser, + 'projects/create-draft-item-for-authenticated-user': + projectsCreateDraftItemForAuthenticatedUser, + 'projects/create-draft-item-for-org': projectsCreateDraftItemForOrg, + 'projects/create-view-for-org': projectsCreateViewForOrg, + 'projects/create-view-for-user': projectsCreateViewForUser, + 'projects/delete-item-for-org': projectsDeleteItemForOrg, + 'projects/delete-item-for-user': projectsDeleteItemForUser, + 'projects/get-field-for-org': projectsGetFieldForOrg, + 'projects/get-field-for-user': projectsGetFieldForUser, + 'projects/get-for-org': projectsGetForOrg, + 'projects/get-for-user': projectsGetForUser, + 'projects/get-org-item': projectsGetOrgItem, + 'projects/get-user-item': projectsGetUserItem, + 'projects/list-fields-for-org': projectsListFieldsForOrg, + 'projects/list-fields-for-user': projectsListFieldsForUser, + 'projects/list-for-org': projectsListForOrg, + 'projects/list-for-user': projectsListForUser, + 'projects/list-items-for-org': projectsListItemsForOrg, + 'projects/list-items-for-user': projectsListItemsForUser, + 'projects/list-view-items-for-org': projectsListViewItemsForOrg, + 'projects/list-view-items-for-user': projectsListViewItemsForUser, + 'projects/update-item-for-org': projectsUpdateItemForOrg, + 'projects/update-item-for-user': projectsUpdateItemForUser, + 'pull-request-stacks/add': pullRequestStacksAdd, + 'pull-request-stacks/create': pullRequestStacksCreate, + 'pull-request-stacks/get': pullRequestStacksGet, + 'pull-request-stacks/list': pullRequestStacksList, + 'pull-request-stacks/unstack': pullRequestStacksUnstack, + 'pulls/check-if-merged': pullsCheckIfMerged, + 'pulls/create': pullsCreate, + 'pulls/create-reply-for-review-comment': pullsCreateReplyForReviewComment, + 'pulls/create-review': pullsCreateReview, + 'pulls/create-review-comment': pullsCreateReviewComment, + 'pulls/delete-pending-review': pullsDeletePendingReview, + 'pulls/delete-review-comment': pullsDeleteReviewComment, + 'pulls/dismiss-review': pullsDismissReview, + 'pulls/get': pullsGet, + 'pulls/get-merge-async-result': pullsGetMergeAsyncResult, + 'pulls/get-review': pullsGetReview, + 'pulls/get-review-comment': pullsGetReviewComment, + 'pulls/list': pullsList, + 'pulls/list-comments-for-review': pullsListCommentsForReview, + 'pulls/list-commits': pullsListCommits, + 'pulls/list-files': pullsListFiles, + 'pulls/list-requested-reviewers': pullsListRequestedReviewers, + 'pulls/list-review-comments': pullsListReviewComments, + 'pulls/list-review-comments-for-repo': pullsListReviewCommentsForRepo, + 'pulls/list-reviews': pullsListReviews, + 'pulls/merge': pullsMerge, + 'pulls/merge-async': pullsMergeAsync, + 'pulls/remove-requested-reviewers': pullsRemoveRequestedReviewers, + 'pulls/request-reviewers': pullsRequestReviewers, + 'pulls/submit-review': pullsSubmitReview, + 'pulls/update': pullsUpdate, + 'pulls/update-branch': pullsUpdateBranch, + 'pulls/update-review': pullsUpdateReview, + 'pulls/update-review-comment': pullsUpdateReviewComment, + 'rate-limit/get': rateLimitGet, + 'reactions/create-for-commit-comment': reactionsCreateForCommitComment, + 'reactions/create-for-issue': reactionsCreateForIssue, + 'reactions/create-for-issue-comment': reactionsCreateForIssueComment, + 'reactions/create-for-pull-request-review-comment': + reactionsCreateForPullRequestReviewComment, + 'reactions/create-for-release': reactionsCreateForRelease, + 'reactions/delete-for-commit-comment': reactionsDeleteForCommitComment, + 'reactions/delete-for-issue': reactionsDeleteForIssue, + 'reactions/delete-for-issue-comment': reactionsDeleteForIssueComment, + 'reactions/delete-for-pull-request-comment': + reactionsDeleteForPullRequestComment, + 'reactions/delete-for-release': reactionsDeleteForRelease, + 'reactions/list-for-commit-comment': reactionsListForCommitComment, + 'reactions/list-for-issue': reactionsListForIssue, + 'reactions/list-for-issue-comment': reactionsListForIssueComment, + 'reactions/list-for-pull-request-review-comment': + reactionsListForPullRequestReviewComment, + 'reactions/list-for-release': reactionsListForRelease, + 'repos/accept-invitation-for-authenticated-user': + reposAcceptInvitationForAuthenticatedUser, + 'repos/add-app-access-restrictions': reposAddAppAccessRestrictions, + 'repos/add-collaborator': reposAddCollaborator, + 'repos/add-status-check-contexts': reposAddStatusCheckContexts, + 'repos/add-team-access-restrictions': reposAddTeamAccessRestrictions, + 'repos/add-user-access-restrictions': reposAddUserAccessRestrictions, + 'repos/cancel-pages-deployment': reposCancelPagesDeployment, + 'repos/check-automated-security-fixes': reposCheckAutomatedSecurityFixes, + 'repos/check-collaborator': reposCheckCollaborator, + 'repos/check-immutable-releases': reposCheckImmutableReleases, + 'repos/check-private-vulnerability-reporting': + reposCheckPrivateVulnerabilityReporting, + 'repos/check-vulnerability-alerts': reposCheckVulnerabilityAlerts, + 'repos/codeowners-errors': reposCodeownersErrors, + 'repos/compare-commits': reposCompareCommits, + 'repos/create-attestation': reposCreateAttestation, + 'repos/create-autolink': reposCreateAutolink, + 'repos/create-commit-comment': reposCreateCommitComment, + 'repos/create-commit-signature-protection': + reposCreateCommitSignatureProtection, + 'repos/create-commit-status': reposCreateCommitStatus, + 'repos/create-deploy-key': reposCreateDeployKey, + 'repos/create-deployment': reposCreateDeployment, + 'repos/create-deployment-branch-policy': reposCreateDeploymentBranchPolicy, + 'repos/create-deployment-protection-rule': + reposCreateDeploymentProtectionRule, + 'repos/create-deployment-status': reposCreateDeploymentStatus, + 'repos/create-dispatch-event': reposCreateDispatchEvent, + 'repos/create-for-authenticated-user': reposCreateForAuthenticatedUser, + 'repos/create-fork': reposCreateFork, + 'repos/create-in-org': reposCreateInOrg, + 'repos/create-or-update-environment': reposCreateOrUpdateEnvironment, + 'repos/create-or-update-file-contents': reposCreateOrUpdateFileContents, + 'repos/create-org-ruleset': reposCreateOrgRuleset, + 'repos/create-pages-deployment': reposCreatePagesDeployment, + 'repos/create-pages-site': reposCreatePagesSite, + 'repos/create-release': reposCreateRelease, + 'repos/create-repo-ruleset': reposCreateRepoRuleset, + 'repos/create-using-template': reposCreateUsingTemplate, + 'repos/create-webhook': reposCreateWebhook, + 'repos/custom-properties-for-repos-create-or-update-repository-values': + reposCustomPropertiesForReposCreateOrUpdateRepositoryValues, + 'repos/custom-properties-for-repos-get-repository-values': + reposCustomPropertiesForReposGetRepositoryValues, + 'repos/decline-invitation-for-authenticated-user': + reposDeclineInvitationForAuthenticatedUser, + 'repos/delete': reposDelete, + 'repos/delete-access-restrictions': reposDeleteAccessRestrictions, + 'repos/delete-admin-branch-protection': reposDeleteAdminBranchProtection, + 'repos/delete-an-environment': reposDeleteAnEnvironment, + 'repos/delete-autolink': reposDeleteAutolink, + 'repos/delete-branch-protection': reposDeleteBranchProtection, + 'repos/delete-commit-comment': reposDeleteCommitComment, + 'repos/delete-commit-signature-protection': + reposDeleteCommitSignatureProtection, + 'repos/delete-deploy-key': reposDeleteDeployKey, + 'repos/delete-deployment': reposDeleteDeployment, + 'repos/delete-deployment-branch-policy': reposDeleteDeploymentBranchPolicy, + 'repos/delete-file': reposDeleteFile, + 'repos/delete-invitation': reposDeleteInvitation, + 'repos/delete-org-ruleset': reposDeleteOrgRuleset, + 'repos/delete-pages-site': reposDeletePagesSite, + 'repos/delete-pull-request-review-protection': + reposDeletePullRequestReviewProtection, + 'repos/delete-release': reposDeleteRelease, + 'repos/delete-release-asset': reposDeleteReleaseAsset, + 'repos/delete-repo-ruleset': reposDeleteRepoRuleset, + 'repos/delete-webhook': reposDeleteWebhook, + 'repos/disable-automated-security-fixes': + reposDisableAutomatedSecurityFixes, + 'repos/disable-deployment-protection-rule': + reposDisableDeploymentProtectionRule, + 'repos/disable-immutable-releases': reposDisableImmutableReleases, + 'repos/disable-private-vulnerability-reporting': + reposDisablePrivateVulnerabilityReporting, + 'repos/disable-vulnerability-alerts': reposDisableVulnerabilityAlerts, + 'repos/download-tarball-archive': reposDownloadTarballArchive, + 'repos/download-zipball-archive': reposDownloadZipballArchive, + 'repos/enable-automated-security-fixes': reposEnableAutomatedSecurityFixes, + 'repos/enable-immutable-releases': reposEnableImmutableReleases, + 'repos/enable-private-vulnerability-reporting': + reposEnablePrivateVulnerabilityReporting, + 'repos/enable-vulnerability-alerts': reposEnableVulnerabilityAlerts, + 'repos/generate-release-notes': reposGenerateReleaseNotes, + 'repos/get': reposGet, + 'repos/get-access-restrictions': reposGetAccessRestrictions, + 'repos/get-admin-branch-protection': reposGetAdminBranchProtection, + 'repos/get-all-deployment-protection-rules': + reposGetAllDeploymentProtectionRules, + 'repos/get-all-environments': reposGetAllEnvironments, + 'repos/get-all-status-check-contexts': reposGetAllStatusCheckContexts, + 'repos/get-all-topics': reposGetAllTopics, + 'repos/get-apps-with-access-to-protected-branch': + reposGetAppsWithAccessToProtectedBranch, + 'repos/get-autolink': reposGetAutolink, + 'repos/get-branch': reposGetBranch, + 'repos/get-branch-protection': reposGetBranchProtection, + 'repos/get-branch-rules': reposGetBranchRules, + 'repos/get-clones': reposGetClones, + 'repos/get-code-frequency-stats': reposGetCodeFrequencyStats, + 'repos/get-collaborator-permission-level': + reposGetCollaboratorPermissionLevel, + 'repos/get-combined-status-for-ref': reposGetCombinedStatusForRef, + 'repos/get-commit': reposGetCommit, + 'repos/get-commit-activity-stats': reposGetCommitActivityStats, + 'repos/get-commit-comment': reposGetCommitComment, + 'repos/get-commit-signature-protection': reposGetCommitSignatureProtection, + 'repos/get-community-profile-metrics': reposGetCommunityProfileMetrics, + 'repos/get-content': reposGetContent, + 'repos/get-contributors-stats': reposGetContributorsStats, + 'repos/get-custom-deployment-protection-rule': + reposGetCustomDeploymentProtectionRule, + 'repos/get-deploy-key': reposGetDeployKey, + 'repos/get-deployment': reposGetDeployment, + 'repos/get-deployment-branch-policy': reposGetDeploymentBranchPolicy, + 'repos/get-deployment-status': reposGetDeploymentStatus, + 'repos/get-environment': reposGetEnvironment, + 'repos/get-hash-algorithm': reposGetHashAlgorithm, + 'repos/get-latest-pages-build': reposGetLatestPagesBuild, + 'repos/get-latest-release': reposGetLatestRelease, + 'repos/get-org-rule-suite': reposGetOrgRuleSuite, + 'repos/get-org-rule-suites': reposGetOrgRuleSuites, + 'repos/get-org-ruleset': reposGetOrgRuleset, + 'repos/get-org-rulesets': reposGetOrgRulesets, + 'repos/get-pages': reposGetPages, + 'repos/get-pages-build': reposGetPagesBuild, + 'repos/get-pages-deployment': reposGetPagesDeployment, + 'repos/get-pages-health-check': reposGetPagesHealthCheck, + 'repos/get-participation-stats': reposGetParticipationStats, + 'repos/get-pull-request-review-protection': + reposGetPullRequestReviewProtection, + 'repos/get-punch-card-stats': reposGetPunchCardStats, + 'repos/get-readme': reposGetReadme, + 'repos/get-readme-in-directory': reposGetReadmeInDirectory, + 'repos/get-release': reposGetRelease, + 'repos/get-release-asset': reposGetReleaseAsset, + 'repos/get-release-by-tag': reposGetReleaseByTag, + 'repos/get-repo-rule-suite': reposGetRepoRuleSuite, + 'repos/get-repo-rule-suites': reposGetRepoRuleSuites, + 'repos/get-repo-ruleset': reposGetRepoRuleset, + 'repos/get-repo-ruleset-history': reposGetRepoRulesetHistory, + 'repos/get-repo-ruleset-version': reposGetRepoRulesetVersion, + 'repos/get-repo-rulesets': reposGetRepoRulesets, + 'repos/get-status-checks-protection': reposGetStatusChecksProtection, + 'repos/get-teams-with-access-to-protected-branch': + reposGetTeamsWithAccessToProtectedBranch, + 'repos/get-top-paths': reposGetTopPaths, + 'repos/get-top-referrers': reposGetTopReferrers, + 'repos/get-users-with-access-to-protected-branch': + reposGetUsersWithAccessToProtectedBranch, + 'repos/get-views': reposGetViews, + 'repos/get-webhook': reposGetWebhook, + 'repos/get-webhook-config-for-repo': reposGetWebhookConfigForRepo, + 'repos/get-webhook-delivery': reposGetWebhookDelivery, + 'repos/list-activities': reposListActivities, + 'repos/list-attestations': reposListAttestations, + 'repos/list-autolinks': reposListAutolinks, + 'repos/list-branches': reposListBranches, + 'repos/list-branches-for-head-commit': reposListBranchesForHeadCommit, + 'repos/list-collaborators': reposListCollaborators, + 'repos/list-comments-for-commit': reposListCommentsForCommit, + 'repos/list-commit-comments-for-repo': reposListCommitCommentsForRepo, + 'repos/list-commit-statuses-for-ref': reposListCommitStatusesForRef, + 'repos/list-commits': reposListCommits, + 'repos/list-contributors': reposListContributors, + 'repos/list-custom-deployment-rule-integrations': + reposListCustomDeploymentRuleIntegrations, + 'repos/list-deploy-keys': reposListDeployKeys, + 'repos/list-deployment-branch-policies': reposListDeploymentBranchPolicies, + 'repos/list-deployment-statuses': reposListDeploymentStatuses, + 'repos/list-deployments': reposListDeployments, + 'repos/list-for-authenticated-user': reposListForAuthenticatedUser, + 'repos/list-for-org': reposListForOrg, + 'repos/list-for-user': reposListForUser, + 'repos/list-forks': reposListForks, + 'repos/list-invitations': reposListInvitations, + 'repos/list-invitations-for-authenticated-user': + reposListInvitationsForAuthenticatedUser, + 'repos/list-issue-types': reposListIssueTypes, + 'repos/list-languages': reposListLanguages, + 'repos/list-pages-builds': reposListPagesBuilds, + 'repos/list-public': reposListPublic, + 'repos/list-pull-requests-associated-with-commit': + reposListPullRequestsAssociatedWithCommit, + 'repos/list-release-assets': reposListReleaseAssets, + 'repos/list-releases': reposListReleases, + 'repos/list-tags': reposListTags, + 'repos/list-teams': reposListTeams, + 'repos/list-webhook-deliveries': reposListWebhookDeliveries, + 'repos/list-webhooks': reposListWebhooks, + 'repos/merge': reposMerge, + 'repos/merge-upstream': reposMergeUpstream, + 'repos/ping-webhook': reposPingWebhook, + 'repos/redeliver-webhook-delivery': reposRedeliverWebhookDelivery, + 'repos/remove-app-access-restrictions': reposRemoveAppAccessRestrictions, + 'repos/remove-collaborator': reposRemoveCollaborator, + 'repos/remove-status-check-contexts': reposRemoveStatusCheckContexts, + 'repos/remove-status-check-protection': reposRemoveStatusCheckProtection, + 'repos/remove-team-access-restrictions': reposRemoveTeamAccessRestrictions, + 'repos/remove-user-access-restrictions': reposRemoveUserAccessRestrictions, + 'repos/rename-branch': reposRenameBranch, + 'repos/replace-all-topics': reposReplaceAllTopics, + 'repos/request-pages-build': reposRequestPagesBuild, + 'repos/set-admin-branch-protection': reposSetAdminBranchProtection, + 'repos/set-app-access-restrictions': reposSetAppAccessRestrictions, + 'repos/set-status-check-contexts': reposSetStatusCheckContexts, + 'repos/set-team-access-restrictions': reposSetTeamAccessRestrictions, + 'repos/set-user-access-restrictions': reposSetUserAccessRestrictions, + 'repos/test-push-webhook': reposTestPushWebhook, + 'repos/transfer': reposTransfer, + 'repos/update': reposUpdate, + 'repos/update-branch-protection': reposUpdateBranchProtection, + 'repos/update-commit-comment': reposUpdateCommitComment, + 'repos/update-deployment-branch-policy': reposUpdateDeploymentBranchPolicy, + 'repos/update-information-about-pages-site': + reposUpdateInformationAboutPagesSite, + 'repos/update-invitation': reposUpdateInvitation, + 'repos/update-org-ruleset': reposUpdateOrgRuleset, + 'repos/update-pull-request-review-protection': + reposUpdatePullRequestReviewProtection, + 'repos/update-release': reposUpdateRelease, + 'repos/update-release-asset': reposUpdateReleaseAsset, + 'repos/update-repo-ruleset': reposUpdateRepoRuleset, + 'repos/update-status-check-protection': reposUpdateStatusCheckProtection, + 'repos/update-webhook': reposUpdateWebhook, + 'repos/update-webhook-config-for-repo': reposUpdateWebhookConfigForRepo, + 'repos/upload-release-asset': reposUploadReleaseAsset, + 'search/code': searchCode, + 'search/commits': searchCommits, + 'search/issues-and-pull-requests': searchIssuesAndPullRequests, + 'search/labels': searchLabels, + 'search/repos': searchRepos, + 'search/topics': searchTopics, + 'search/users': searchUsers, + 'secret-scanning/bulk-create-org-custom-patterns': + secretScanningBulkCreateOrgCustomPatterns, + 'secret-scanning/bulk-create-repo-custom-patterns': + secretScanningBulkCreateRepoCustomPatterns, + 'secret-scanning/bulk-delete-org-custom-patterns': + secretScanningBulkDeleteOrgCustomPatterns, + 'secret-scanning/bulk-delete-repo-custom-patterns': + secretScanningBulkDeleteRepoCustomPatterns, + 'secret-scanning/create-push-protection-bypass': + secretScanningCreatePushProtectionBypass, + 'secret-scanning/get-alert': secretScanningGetAlert, + 'secret-scanning/get-scan-history': secretScanningGetScanHistory, + 'secret-scanning/list-alerts-for-org': secretScanningListAlertsForOrg, + 'secret-scanning/list-alerts-for-repo': secretScanningListAlertsForRepo, + 'secret-scanning/list-locations-for-alert': + secretScanningListLocationsForAlert, + 'secret-scanning/list-org-custom-patterns': + secretScanningListOrgCustomPatterns, + 'secret-scanning/list-org-pattern-configs': + secretScanningListOrgPatternConfigs, + 'secret-scanning/list-repo-custom-patterns': + secretScanningListRepoCustomPatterns, + 'secret-scanning/update-alert': secretScanningUpdateAlert, + 'secret-scanning/update-org-custom-pattern': + secretScanningUpdateOrgCustomPattern, + 'secret-scanning/update-org-pattern-configs': + secretScanningUpdateOrgPatternConfigs, + 'secret-scanning/update-repo-custom-pattern': + secretScanningUpdateRepoCustomPattern, + 'security-advisories/create-fork': securityAdvisoriesCreateFork, + 'security-advisories/create-private-vulnerability-report': + securityAdvisoriesCreatePrivateVulnerabilityReport, + 'security-advisories/create-repository-advisory': + securityAdvisoriesCreateRepositoryAdvisory, + 'security-advisories/create-repository-advisory-cve-request': + securityAdvisoriesCreateRepositoryAdvisoryCveRequest, + 'security-advisories/get-global-advisory': + securityAdvisoriesGetGlobalAdvisory, + 'security-advisories/get-repository-advisory': + securityAdvisoriesGetRepositoryAdvisory, + 'security-advisories/list-global-advisories': + securityAdvisoriesListGlobalAdvisories, + 'security-advisories/list-org-repository-advisories': + securityAdvisoriesListOrgRepositoryAdvisories, + 'security-advisories/list-repository-advisories': + securityAdvisoriesListRepositoryAdvisories, + 'security-advisories/update-repository-advisory': + securityAdvisoriesUpdateRepositoryAdvisory, + 'teams/add-member-legacy': teamsAddMemberLegacy, + 'teams/add-or-update-membership-for-user-in-org': + teamsAddOrUpdateMembershipForUserInOrg, + 'teams/add-or-update-membership-for-user-legacy': + teamsAddOrUpdateMembershipForUserLegacy, + 'teams/add-or-update-repo-permissions-in-org': + teamsAddOrUpdateRepoPermissionsInOrg, + 'teams/add-or-update-repo-permissions-legacy': + teamsAddOrUpdateRepoPermissionsLegacy, + 'teams/check-permissions-for-repo-in-org': + teamsCheckPermissionsForRepoInOrg, + 'teams/check-permissions-for-repo-legacy': + teamsCheckPermissionsForRepoLegacy, + 'teams/create': teamsCreate, + 'teams/delete-in-org': teamsDeleteInOrg, + 'teams/delete-legacy': teamsDeleteLegacy, + 'teams/get-by-name': teamsGetByName, + 'teams/get-legacy': teamsGetLegacy, + 'teams/get-member-legacy': teamsGetMemberLegacy, + 'teams/get-membership-for-user-in-org': teamsGetMembershipForUserInOrg, + 'teams/get-membership-for-user-legacy': teamsGetMembershipForUserLegacy, + 'teams/list': teamsList, + 'teams/list-child-in-org': teamsListChildInOrg, + 'teams/list-child-legacy': teamsListChildLegacy, + 'teams/list-for-authenticated-user': teamsListForAuthenticatedUser, + 'teams/list-members-in-org': teamsListMembersInOrg, + 'teams/list-members-legacy': teamsListMembersLegacy, + 'teams/list-pending-invitations-in-org': teamsListPendingInvitationsInOrg, + 'teams/list-pending-invitations-legacy': teamsListPendingInvitationsLegacy, + 'teams/list-repos-in-org': teamsListReposInOrg, + 'teams/list-repos-legacy': teamsListReposLegacy, + 'teams/remove-member-legacy': teamsRemoveMemberLegacy, + 'teams/remove-membership-for-user-in-org': + teamsRemoveMembershipForUserInOrg, + 'teams/remove-membership-for-user-legacy': + teamsRemoveMembershipForUserLegacy, + 'teams/remove-repo-in-org': teamsRemoveRepoInOrg, + 'teams/remove-repo-legacy': teamsRemoveRepoLegacy, + 'teams/update-in-org': teamsUpdateInOrg, + 'teams/update-legacy': teamsUpdateLegacy, + 'users/add-email-for-authenticated-user': usersAddEmailForAuthenticatedUser, + 'users/add-social-account-for-authenticated-user': + usersAddSocialAccountForAuthenticatedUser, + 'users/block': usersBlock, + 'users/check-blocked': usersCheckBlocked, + 'users/check-following-for-user': usersCheckFollowingForUser, + 'users/check-person-is-followed-by-authenticated': + usersCheckPersonIsFollowedByAuthenticated, + 'users/create-gpg-key-for-authenticated-user': + usersCreateGpgKeyForAuthenticatedUser, + 'users/create-public-ssh-key-for-authenticated-user': + usersCreatePublicSshKeyForAuthenticatedUser, + 'users/create-ssh-signing-key-for-authenticated-user': + usersCreateSshSigningKeyForAuthenticatedUser, + 'users/delete-attestations-bulk': usersDeleteAttestationsBulk, + 'users/delete-attestations-by-id': usersDeleteAttestationsById, + 'users/delete-attestations-by-subject-digest': + usersDeleteAttestationsBySubjectDigest, + 'users/delete-email-for-authenticated-user': + usersDeleteEmailForAuthenticatedUser, + 'users/delete-gpg-key-for-authenticated-user': + usersDeleteGpgKeyForAuthenticatedUser, + 'users/delete-public-ssh-key-for-authenticated-user': + usersDeletePublicSshKeyForAuthenticatedUser, + 'users/delete-social-account-for-authenticated-user': + usersDeleteSocialAccountForAuthenticatedUser, + 'users/delete-ssh-signing-key-for-authenticated-user': + usersDeleteSshSigningKeyForAuthenticatedUser, + 'users/follow': usersFollow, + 'users/get-authenticated': usersGetAuthenticated, + 'users/get-by-id': usersGetById, + 'users/get-by-username': usersGetByUsername, + 'users/get-context-for-user': usersGetContextForUser, + 'users/get-gpg-key-for-authenticated-user': + usersGetGpgKeyForAuthenticatedUser, + 'users/get-public-ssh-key-for-authenticated-user': + usersGetPublicSshKeyForAuthenticatedUser, + 'users/get-ssh-signing-key-for-authenticated-user': + usersGetSshSigningKeyForAuthenticatedUser, + 'users/list': usersList, + 'users/list-attestations': usersListAttestations, + 'users/list-attestations-bulk': usersListAttestationsBulk, + 'users/list-blocked-by-authenticated-user': + usersListBlockedByAuthenticatedUser, + 'users/list-emails-for-authenticated-user': + usersListEmailsForAuthenticatedUser, + 'users/list-followed-by-authenticated-user': + usersListFollowedByAuthenticatedUser, + 'users/list-followers-for-authenticated-user': + usersListFollowersForAuthenticatedUser, + 'users/list-followers-for-user': usersListFollowersForUser, + 'users/list-following-for-user': usersListFollowingForUser, + 'users/list-gpg-keys-for-authenticated-user': + usersListGpgKeysForAuthenticatedUser, + 'users/list-gpg-keys-for-user': usersListGpgKeysForUser, + 'users/list-public-emails-for-authenticated-user': + usersListPublicEmailsForAuthenticatedUser, + 'users/list-public-keys-for-user': usersListPublicKeysForUser, + 'users/list-public-ssh-keys-for-authenticated-user': + usersListPublicSshKeysForAuthenticatedUser, + 'users/list-social-accounts-for-authenticated-user': + usersListSocialAccountsForAuthenticatedUser, + 'users/list-social-accounts-for-user': usersListSocialAccountsForUser, + 'users/list-ssh-signing-keys-for-authenticated-user': + usersListSshSigningKeysForAuthenticatedUser, + 'users/list-ssh-signing-keys-for-user': usersListSshSigningKeysForUser, + 'users/set-primary-email-visibility-for-authenticated-user': + usersSetPrimaryEmailVisibilityForAuthenticatedUser, + 'users/unblock': usersUnblock, + 'users/unfollow': usersUnfollow, + 'users/update-authenticated': usersUpdateAuthenticated, + }; +} diff --git a/lib/src/common/gists_service.dart b/lib/src/common/gists_service.dart index 05ac62bd..5af7e4a8 100644 --- a/lib/src/common/gists_service.dart +++ b/lib/src/common/gists_service.dart @@ -56,7 +56,7 @@ class GistsService extends Service { String? description, bool public = false, }) { - final map = {'files': {}}; + final map = {'files': {}}; if (description != null) { map['description'] = description; @@ -64,7 +64,7 @@ class GistsService extends Service { map['public'] = public; - final f = {}; + final f = {}; for (final key in files.keys) { f[key] = {'content': files[key]}; @@ -111,7 +111,8 @@ class GistsService extends Service { map['files'] = f; } - return github.postJSON( + return github.requestJson, Gist>( + 'PATCH', '/gists/$id', statusCode: 200, body: GitHubJson.encode(map), @@ -125,7 +126,9 @@ class GistsService extends Service { /// /// API docs: https://developer.github.com/v3/gists/#star-a-gist Future starGist(String id) { - return github.request('POST', '/gists/$id/star').then((response) { + return github + .request('PUT', '/gists/$id/star', statusCode: 204) + .then((response) { return response.statusCode == 204; }); } @@ -176,7 +179,9 @@ class GistsService extends Service { /// API docs: https://developer.github.com/v3/gists/comments/#create-a-comment Future createComment(String gistId, CreateGistComment request) { return github.postJSON('/gists/$gistId/comments', - body: GitHubJson.encode(request), convert: GistComment.fromJson); + body: GitHubJson.encode(request), + convert: GistComment.fromJson, + statusCode: 201); } // TODO: Implement editComment: https://developer.github.com/v3/gists/comments/#edit-a-comment diff --git a/lib/src/common/git_service.dart b/lib/src/common/git_service.dart index 338dbeba..32e75f6c 100644 --- a/lib/src/common/git_service.dart +++ b/lib/src/common/git_service.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:convert'; import 'package:github/src/common.dart'; @@ -77,10 +76,11 @@ class GitService extends Service { /// API docs: https://developer.github.com/v3/git/refs/#create-a-reference Future createReference( RepositorySlug slug, String ref, String? sha) { + final formattedRef = ref.startsWith('refs/') ? ref : 'refs/$ref'; return github.postJSON('/repos/${slug.fullName}/git/refs', convert: GitReference.fromJson, statusCode: StatusCodes.CREATED, - body: GitHubJson.encode({'ref': ref, 'sha': sha})); + body: GitHubJson.encode({'ref': formattedRef, 'sha': sha})); } /// Updates a reference in a repository. @@ -92,25 +92,25 @@ class GitService extends Service { String? sha, { bool force = false, }) { + final formattedRef = ref.startsWith('refs/') ? ref.substring(5) : ref; final body = GitHubJson.encode({'sha': sha, 'force': force}); - // Somehow the reference updates PATCH request needs a valid content-length. - final headers = {'content-length': body.length.toString()}; - - return github - .request('PATCH', '/repos/${slug.fullName}/git/refs/$ref', - body: body, headers: headers) - .then((response) { - return GitReference.fromJson( - jsonDecode(response.body) as Map); - }); + return github.requestJson, GitReference>( + 'PATCH', + '/repos/${slug.fullName}/git/refs/$formattedRef', + statusCode: StatusCodes.OK, + body: body, + convert: GitReference.fromJson, + ); } /// Deletes a reference. /// /// API docs: https://developer.github.com/v3/git/refs/#delete-a-reference Future deleteReference(RepositorySlug slug, String ref) { + final formattedRef = ref.startsWith('refs/') ? ref.substring(5) : ref; return github - .request('DELETE', '/repos/${slug.fullName}/git/refs/$ref') + .request('DELETE', '/repos/${slug.fullName}/git/refs/$formattedRef', + statusCode: StatusCodes.NO_CONTENT) .then((response) => response.statusCode == StatusCodes.NO_CONTENT); } @@ -138,13 +138,12 @@ class GitService extends Service { /// and https://developer.github.com/v3/git/trees/#get-a-tree-recursively Future getTree(RepositorySlug slug, String? sha, {bool recursive = false}) { - var path = '/repos/${slug.fullName}/git/trees/$sha'; - if (recursive) { - path += '?recursive=1'; - } - - return github.getJSON(path, - convert: GitTree.fromJson, statusCode: StatusCodes.OK); + return github.getJSON( + '/repos/${slug.fullName}/git/trees/$sha', + params: recursive ? {'recursive': '1'} : const {}, + convert: GitTree.fromJson, + statusCode: StatusCodes.OK, + ); } /// Creates a new tree in a repository. diff --git a/lib/src/common/github.dart b/lib/src/common/github.dart index e6ba64cb..807daa41 100644 --- a/lib/src/common/github.dart +++ b/lib/src/common/github.dart @@ -23,7 +23,48 @@ class GitHub { this.endpoint = 'https://api.github.com', this.version = '2022-11-28', http.Client? client, - }) : client = client ?? http.Client(); + Set? trustedOrigins, + this.allowInsecureAuth = false, + this.retryPolicy = const RetryPolicy(), + HttpTransport? transport, + }) : client = client ?? http.Client(), + trustedOrigins = trustedOrigins ?? _defaultTrustedOrigins(endpoint), + _transport = transport; + + static Set _defaultTrustedOrigins(String endpoint) { + final origins = {}; + final uri = Uri.tryParse(endpoint); + if (uri != null && uri.hasScheme && uri.hasAuthority) { + origins.add(uri.origin); + } else { + origins.add('https://api.github.com'); + } + origins.add('https://uploads.github.com'); + return origins; + } + + /// Policy governing retries, exponential backoff, and rate limits. + final RetryPolicy retryPolicy; + + /// Underlying injectable HTTP transport. + HttpTransport get transport => _transport ??= HttpTransport( + github: this, + client: client, + retryPolicy: retryPolicy, + trustedOrigins: trustedOrigins, + allowInsecureAuth: allowInsecureAuth, + endpoint: endpoint, + ); + HttpTransport? _transport; + + /// Set of trusted origins permitted to receive authentication credentials. + /// Defaults to the origin of [endpoint] (e.g. `https://api.github.com`) and + /// `https://uploads.github.com`. + final Set trustedOrigins; + + /// Whether to allow sending credentials over unencrypted HTTP. + /// Defaults to `false` for security. Set to `true` only for local test servers. + final bool allowInsecureAuth; static const _ratelimitLimitHeader = 'x-ratelimit-limit'; static const _ratelimitResetHeader = 'x-ratelimit-reset'; @@ -51,6 +92,7 @@ class GitHub { final http.Client client; ActivityService? _activity; + // ignore: deprecated_member_use_from_same_package AuthorizationsService? _authorizations; GistsService? _gists; GitService? _git; @@ -60,6 +102,7 @@ class GitHub { PullRequestsService? _pullRequests; RepositoriesService? _repositories; SearchService? _search; + // ignore: deprecated_member_use_from_same_package UrlShortenerService? _urlShortener; UsersService? _users; ChecksService? _checks; @@ -98,7 +141,9 @@ class GitHub { /// /// Note: You can only access this API via Basic Authentication using your /// username and password, not tokens. + // ignore: deprecated_member_use_from_same_package AuthorizationsService get authorizations => + // ignore: deprecated_member_use_from_same_package _authorizations ??= AuthorizationsService(this); /// Service for gist related methods of the GitHub API. @@ -129,7 +174,9 @@ class GitHub { SearchService get search => _search ??= SearchService(this); /// Service to provide a handy method to access GitHub's url shortener. + // ignore: deprecated_member_use_from_same_package UrlShortenerService get urlShortener => + // ignore: deprecated_member_use_from_same_package _urlShortener ??= UrlShortenerService(this); /// Service for user related methods of the GitHub API. @@ -330,10 +377,16 @@ class GitHub { fail: fail, ); + if (response.statusCode == 204 || response.body.isEmpty) { + return null as T; + } + final json = jsonDecode(response.body); - final returnValue = convert(json) as T; - _applyExpandos(returnValue, response); + final returnValue = convert(json as S) as T; + if (returnValue != null) { + _applyExpandos(returnValue, response); + } return returnValue; } @@ -355,135 +408,27 @@ class GitHub { void Function(http.Response response)? fail, String? preview, }) async { - if (rateLimitRemaining != null && rateLimitRemaining! <= 0) { - assert(rateLimitReset != null); - final now = DateTime.now(); - final waitTime = rateLimitReset!.difference(now); - await Future.delayed(waitTime); - } - headers ??= {}; if (preview != null) { headers['Accept'] = preview; } - final authHeaderValue = auth.authorizationHeaderValue(); - if (authHeaderValue != null) { - headers.putIfAbsent('Authorization', () => authHeaderValue); - } - - // See https://docs.github.com/en/rest/overview/resources-in-the-rest-api?apiVersion=2022-11-28#user-agent-required - headers.putIfAbsent('User-Agent', () => auth.username ?? 'github.dart'); - - if (method == 'PUT' && body == null) { - headers.putIfAbsent('Content-Length', () => '0'); - } - - var queryString = ''; - - if (params != null) { - queryString = buildQueryString(params); - } - - final url = StringBuffer(); - - if (path.startsWith('http://') || path.startsWith('https://')) { - url.write(path); - url.write(queryString); - } else { - url.write(endpoint); - if (!path.startsWith('/')) { - url.write('/'); - } - url.write(path); - url.write(queryString); - } - - final request = http.Request(method, Uri.parse(url.toString())); - request.headers.addAll(headers); - if (body != null) { - if (body is List) { - request.bodyBytes = body; - } else { - request.body = body.toString(); - } - } - - final streamedResponse = await client.send(request); - - final response = await http.Response.fromStream(streamedResponse); + final apiRequest = ApiRequest( + method: method, + path: path, + headers: headers, + params: params ?? const {}, + body: body, + successStatuses: statusCode != null ? {statusCode} : null, + ); - _updateRateLimit(response.headers); - if (statusCode != null && statusCode != response.statusCode) { - if (fail != null) { - fail(response); - } - handleStatusCode(response); - } else { - return response; - } + return transport.execute(apiRequest, fail: fail); } - /// /// Internal method to handle status codes - /// Never handleStatusCode(http.Response response) { - String? message = ''; - List>? errors; - if (response.headers['content-type']!.contains('application/json')) { - try { - final json = jsonDecode(response.body); - message = json['message']; - if (json['errors'] != null) { - try { - errors = List>.from(json['errors']); - } catch (_) { - errors = [ - {'code': json['errors'].toString()} - ]; - } - } - } catch (ex) { - throw UnknownError(this, ex.toString()); - } - } - switch (response.statusCode) { - case 404: - throw NotFound(this, 'Requested Resource was Not Found'); - case 401: - throw AccessForbidden(this); - case 400: - if (message == 'Problems parsing JSON') { - throw InvalidJSON(this, message); - } else if (message == 'Body should be a JSON Hash') { - throw InvalidJSON(this, message); - } else { - throw BadRequest(this); - } - case 422: - final buff = StringBuffer(); - buff.writeln(); - buff.writeln(' Message: $message'); - if (errors != null) { - buff.writeln(' Errors:'); - for (final error in errors) { - final resource = error['resource']; - final field = error['field']; - final code = error['code']; - buff - ..writeln(' Resource: $resource') - ..writeln(' Field $field') - ..write(' Code: $code'); - } - } - throw ValidationFailed(this, buff.toString()); - case 500: - case 502: - case 504: - throw ServerError(this, response.statusCode, message); - } - throw UnknownError(this, message); + ErrorDecoder.decode(this, response); } /// Disposes of this GitHub Instance. @@ -493,16 +438,21 @@ class GitHub { client.close(); } - void _updateRateLimit(Map headers) { + /// Updates rate limit fields from HTTP response [headers]. + void updateRateLimit(Map headers) { if (headers.containsKey(_ratelimitLimitHeader)) { - _rateLimitLimit = int.parse(headers[_ratelimitLimitHeader]!); - _rateLimitRemaining = int.parse(headers[_ratelimitRemainingHeader]!); - _rateLimitReset = int.parse(headers[_ratelimitResetHeader]!); + _rateLimitLimit = int.tryParse(headers[_ratelimitLimitHeader] ?? ''); + _rateLimitRemaining = + int.tryParse(headers[_ratelimitRemainingHeader] ?? ''); + _rateLimitReset = int.tryParse(headers[_ratelimitResetHeader] ?? ''); } } } -void _applyExpandos(dynamic target, http.Response response) { +void _applyExpandos(Object? target, http.Response response) { + if (target == null || target is String || target is num || target is bool) { + return; + } _etagExpando[target] = response.headers['etag']; if (response.headers['date'] != null) { _dateExpando[target] = http_parser.parseHttpDate(response.headers['date']!); diff --git a/lib/src/common/issues_service.dart b/lib/src/common/issues_service.dart index 6b6878dc..02b658a1 100644 --- a/lib/src/common/issues_service.dart +++ b/lib/src/common/issues_service.dart @@ -174,19 +174,13 @@ class IssuesService extends Service { /// Create an issue. /// /// API docs: https://developer.github.com/v3/issues/#create-an-issue - Future create(RepositorySlug slug, IssueRequest issue) async { - final response = await github.request( - 'POST', + Future create(RepositorySlug slug, IssueRequest issue) { + return github.postJSON, Issue>( '/repos/${slug.fullName}/issues', + statusCode: StatusCodes.CREATED, body: GitHubJson.encode(issue), + convert: Issue.fromJson, ); - - if (StatusCodes.isClientError(response.statusCode)) { - //TODO: throw a more friendly error – better this than silent failure - throw GitHubError(github, response.body); - } - - return Issue.fromJson(jsonDecode(response.body) as Map); } /// Lists all available assignees (owners and collaborators) to which issues @@ -201,9 +195,9 @@ class IssuesService extends Service { /// Checks if a user is an assignee for the specified repository. /// /// API docs: https://developer.github.com/v3/issues/assignees/#check-assignee - Future isAssignee(RepositorySlug slug, String repoName) { + Future isAssignee(RepositorySlug slug, String assignee) { return github - .request('GET', '/repos/${slug.fullName}/assignees/$repoName') + .request('GET', '/repos/${slug.fullName}/assignees/$assignee') .then((response) => response.statusCode == StatusCodes.NO_CONTENT); } @@ -373,12 +367,14 @@ class IssuesService extends Service { /// API docs: https://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue Future> replaceLabelsForIssue( RepositorySlug slug, int issueNumber, List labels) { - return github - .request('PUT', '/repos/${slug.fullName}/issues/$issueNumber/labels', - body: GitHubJson.encode(labels)) - .then((response) { - return jsonDecode(response.body).map(IssueLabel.fromJson); - }); + return github.requestJson, List>( + 'PUT', + '/repos/${slug.fullName}/issues/$issueNumber/labels', + statusCode: StatusCodes.OK, + body: GitHubJson.encode(labels), + convert: (input) => + input.cast>().map(IssueLabel.fromJson).toList(), + ); } /// Removes a label for an issue. @@ -457,8 +453,12 @@ class IssuesService extends Service { } else { body = '{}'; } - await github.postJSON('/repos/${slug.fullName}/issues/$number/lock', - body: body, statusCode: 204); + await github.request( + 'PUT', + '/repos/${slug.fullName}/issues/$number/lock', + body: body, + statusCode: 204, + ); } /// Unlock an issue. diff --git a/lib/src/common/misc_service.dart b/lib/src/common/misc_service.dart index 30385a18..213dc712 100644 --- a/lib/src/common/misc_service.dart +++ b/lib/src/common/misc_service.dart @@ -14,10 +14,10 @@ class MiscService extends Service { /// /// API docs: https://developer.github.com/v3/emojis/ Future> listEmojis() { - final r = github.getJSON>( + final r = github.getJSON, Map>( '/emojis', statusCode: StatusCodes.OK, - convert: (Map json) => json.cast(), + convert: (Map json) => json.cast(), ); return r; } @@ -26,7 +26,10 @@ class MiscService extends Service { /// /// API docs: https://developer.github.com/v3/gitignore/#listing-available-templates Future> listGitignoreTemplates() { - return github.getJSON('/gitignore/templates') as Future>; + return github.getJSON, List>( + '/gitignore/templates', + convert: List.from, + ); } /// Gets a .gitignore template by [name]. @@ -63,7 +66,8 @@ class MiscService extends Service { /// API docs: https://developer.github.com/v3/rate_limit/ Future getRateLimit() { return github.request('GET', '/rate_limit').then((response) { - return RateLimit.fromRateLimitResponse(jsonDecode(response.body)); + return RateLimit.fromRateLimitResponse( + jsonDecode(response.body) as Map); }); } diff --git a/lib/src/common/model/checks.dart b/lib/src/common/model/checks.dart index b7666579..e5852953 100644 --- a/lib/src/common/model/checks.dart +++ b/lib/src/common/model/checks.dart @@ -20,8 +20,7 @@ class CheckRunAnnotationLevel extends EnumWithValue { case 'failure': return failure; default: - throw Exception( - 'This level of check run annotation is unimplemented: $value.'); + return CheckRunAnnotationLevel._(value ?? 'notice'); } } @@ -70,8 +69,7 @@ class CheckRunConclusion extends EnumWithValue { return level; } } - throw Exception( - 'This level of check run conclusion is unimplemented: $value.'); + return CheckRunConclusion._(value); } } @@ -124,16 +122,19 @@ class CheckRun { break; } } + final checkSuite = input['check_suite'] as Map?; return CheckRun._( - name: input['name'], - id: input['id'], - externalId: input['external_id'], + name: input['name'] as String?, + id: input['id'] as int?, + externalId: input['external_id'] as String?, status: status, - headSha: input['head_sha'], - checkSuiteId: input['check_suite']['id'], - detailsUrl: input['details_url'], - startedAt: DateTime.parse(input['started_at']), - conclusion: CheckRunConclusion._fromValue(input['conclusion']), + headSha: input['head_sha'] as String?, + checkSuiteId: checkSuite?['id'] as int?, + detailsUrl: input['details_url'] as String?, + startedAt: input['started_at'] != null + ? (DateTime.tryParse(input['started_at'] as String) ?? DateTime.now()) + : DateTime.now(), + conclusion: CheckRunConclusion._fromValue(input['conclusion'] as String?), ); } @@ -143,7 +144,7 @@ class CheckRun { 'id': id, 'external_id': externalId, 'status': status, - 'head_sha': externalId, + 'head_sha': headSha, 'check_suite': { 'id': checkSuiteId, }, @@ -273,16 +274,16 @@ class CheckRunAnnotation { factory CheckRunAnnotation.fromJSON(Map input) { return CheckRunAnnotation( - path: input['path'], - startLine: input['start_line'], - endLine: input['end_line'], - startColumn: input['start_column'], - endColumn: input['end_column'], - annotationLevel: - CheckRunAnnotationLevel._fromValue(input['annotation_level']), - title: input['title'], - message: input['message'], - rawDetails: input['raw_details'], + path: input['path'] as String, + startLine: input['start_line'] as int, + endLine: input['end_line'] as int, + startColumn: input['start_column'] as int?, + endColumn: input['end_column'] as int?, + annotationLevel: CheckRunAnnotationLevel._fromValue( + input['annotation_level'] as String?), + title: (input['title'] as String?) ?? '', + message: (input['message'] as String?) ?? '', + rawDetails: (input['raw_details'] ?? input['rax_details']) as String?, ); } @@ -296,7 +297,7 @@ class CheckRunAnnotation { 'annotation_level': annotationLevel.toString(), 'message': message, 'title': title, - 'rax_details': rawDetails, + 'raw_details': rawDetails, }); } } @@ -376,16 +377,16 @@ class CheckSuite { }); factory CheckSuite.fromJson(Map input) { - var pullRequestsJson = input['pull_requests'] as List; + var pullRequestsJson = (input['pull_requests'] as List?) ?? const []; var pullRequests = pullRequestsJson .map((dynamic json) => PullRequest.fromJson(json as Map)) .toList(); return CheckSuite( - conclusion: CheckRunConclusion._fromValue(input['conclusion']), - headBranch: input['head_branch'], - headSha: input['head_sha'], - id: input['id'], + conclusion: CheckRunConclusion._fromValue(input['conclusion'] as String?), + headBranch: input['head_branch'] as String?, + headSha: input['head_sha'] as String?, + id: input['id'] as int?, pullRequests: pullRequests, ); } @@ -414,8 +415,8 @@ class AutoTriggerChecks { factory AutoTriggerChecks.fromJson(Map input) { return AutoTriggerChecks( - appId: input['app_id'], - setting: input['setting'], + appId: input['app_id'] as int, + setting: input['setting'] as bool?, ); } diff --git a/lib/src/common/model/misc.dart b/lib/src/common/model/misc.dart index 18fc0a54..7ac457d7 100644 --- a/lib/src/common/model/misc.dart +++ b/lib/src/common/model/misc.dart @@ -51,7 +51,7 @@ class RateLimit { final remaining = rateJson?['remaining'] as int?; final resets = rateJson?['reset'] == null ? null - : DateTime.fromMillisecondsSinceEpoch(rateJson?['reset']); + : DateTime.fromMillisecondsSinceEpoch(rateJson!['reset'] as int); return RateLimit(limit, remaining, resets); } diff --git a/lib/src/common/model/reaction.dart b/lib/src/common/model/reaction.dart index a9b73d7f..2eacb82e 100644 --- a/lib/src/common/model/reaction.dart +++ b/lib/src/common/model/reaction.dart @@ -70,7 +70,12 @@ class ReactionType { ':eyes:': eyes, }; - static ReactionType? fromString(String? content) => _types[content!]; + static ReactionType? fromString(String? content) { + if (content == null) { + return null; + } + return _types[content] ?? ReactionType._(content, content); + } } @JsonSerializable() diff --git a/lib/src/common/model/repos.dart b/lib/src/common/model/repos.dart index d09c1a7e..3382106c 100644 --- a/lib/src/common/model/repos.dart +++ b/lib/src/common/model/repos.dart @@ -684,9 +684,12 @@ class LanguageBreakdown { /// The Primary Language String get primary { - final list = mapToList(_data); + if (_data.isEmpty) { + return ''; + } + final list = _data.entries.toList(); list.sort((a, b) { - return a.value.compareTo(b.value); + return b.value.compareTo(a.value); }); return list.first.key; } diff --git a/lib/src/common/model/repos_releases.dart b/lib/src/common/model/repos_releases.dart index 30a80172..0feffd9a 100644 --- a/lib/src/common/model/repos_releases.dart +++ b/lib/src/common/model/repos_releases.dart @@ -86,7 +86,7 @@ class Release { /// Release Assets List? assets; - List? errors; + List? errors; factory Release.fromJson(Map input) => _$ReleaseFromJson(input); diff --git a/lib/src/common/model/users.dart b/lib/src/common/model/users.dart index f66fd395..0df17bcb 100644 --- a/lib/src/common/model/users.dart +++ b/lib/src/common/model/users.dart @@ -43,7 +43,7 @@ class User { }); @JsonKey(includeToJson: false, includeFromJson: false) - Map? json; // TODO remove + Map? json; // TODO remove /// User's Username String? login; diff --git a/lib/src/common/orgs_service.dart b/lib/src/common/orgs_service.dart index b2ca7b26..50917a23 100644 --- a/lib/src/common/orgs_service.dart +++ b/lib/src/common/orgs_service.dart @@ -133,6 +133,8 @@ class OrganizationsService extends Service { /// Edits a Team. /// + /// Edits a team (Legacy endpoint). + /// /// API docs: https://developer.github.com/v3/orgs/teams/#edit-team Future editTeam( int teamId, @@ -146,7 +148,8 @@ class OrganizationsService extends Service { 'permission': permission, }); - return github.postJSON( + return github.requestJson, Team>( + 'PATCH', '/teams/$teamId', statusCode: StatusCodes.OK, convert: Team.fromJson, @@ -154,6 +157,35 @@ class OrganizationsService extends Service { ); } + /// Updates a team in an organization. + /// + /// API docs: https://docs.github.com/en/rest/teams/teams#update-a-team + Future editTeamInOrg( + String org, + String teamSlug, { + String? name, + String? description, + String? permission, + String? privacy, + String? notificationSetting, + }) { + final map = createNonNullMap({ + 'name': name, + 'description': description, + 'permission': permission, + 'privacy': privacy, + 'notification_setting': notificationSetting, + }); + + return github.requestJson, Team>( + 'PATCH', + '/orgs/$org/teams/$teamSlug', + statusCode: StatusCodes.OK, + convert: Team.fromJson, + body: GitHubJson.encode(map), + ); + } + /// Deletes the team specified by the [teamId] /// /// API docs: https://developer.github.com/v3/orgs/teams/#delete-team @@ -175,9 +207,10 @@ class OrganizationsService extends Service { } Future getTeamMemberStatus(int teamId, String user) { - return github.getJSON('/teams/$teamId/memberships/$user').then((json) { - return json['state']; - }); + return github.getJSON, bool>( + '/teams/$teamId/memberships/$user', + convert: (Map json) => json['state'] == 'active', + ); } /// Returns the membership status for a [user] in a team with [teamId]. @@ -190,8 +223,8 @@ class OrganizationsService extends Service { return github.getJSON( '/teams/$teamId/memberships/$user', statusCode: StatusCodes.OK, - convert: (dynamic json) => TeamMembershipState( - json['state'], + convert: (Map json) => TeamMembershipState( + json['state'] as String?, ), ); } @@ -209,8 +242,8 @@ class OrganizationsService extends Service { return github.getJSON( '/orgs/$orgName/teams/$teamName/memberships/$user', statusCode: StatusCodes.OK, - convert: (dynamic json) => TeamMembershipState( - json['state'], + convert: (Map json) => TeamMembershipState( + json['state'] as String?, ), ); } @@ -227,21 +260,24 @@ class OrganizationsService extends Service { '/teams/$teamId/memberships/$user', statusCode: StatusCodes.OK, ); - return TeamMembershipState(jsonDecode(response.body)['state']); + final map = jsonDecode(response.body) as Map; + return TeamMembershipState(map['state'] as String?); } /// Removes a user from the specified team. /// /// API docs: https://developer.github.com/v3/orgs/teams/#get-team-membership - Future removeTeamMembership( + Future removeTeamMembership( int teamId, String user, ) { - return github.request( - 'DELETE', - '/teams/$teamId/memberships/$user', - statusCode: StatusCodes.NO_CONTENT, - ); + return github + .request( + 'DELETE', + '/teams/$teamId/memberships/$user', + statusCode: StatusCodes.NO_CONTENT, + ) + .then((_) => null); } /// Lists the repositories that the specified team has access to. @@ -332,8 +368,11 @@ class OrganizationsService extends Service { /// /// API docs: https://developer.github.com/v3/orgs/hooks/#list-hooks Stream listHooks(String org) { - return PaginationHelper(github).objects('GET', '/orgs/$org/hooks', - (dynamic i) => Hook.fromJson(i)..repoName = org); + return PaginationHelper(github).objects( + 'GET', + '/orgs/$org/hooks', + (dynamic i) => + Hook.fromJson(i as Map)..repoName = org); } /// Fetches a single hook by [id]. @@ -344,7 +383,8 @@ class OrganizationsService extends Service { int id, ) => github.getJSON('/orgs/$org/hooks/$id', - convert: (dynamic i) => Hook.fromJson(i)..repoName = org); + convert: (Map i) => + Hook.fromJson(i)..repoName = org); /// Creates an organization hook based on the specified [hook]. /// diff --git a/lib/src/common/repos_service.dart b/lib/src/common/repos_service.dart index 83fa5ef0..12b7c9f4 100644 --- a/lib/src/common/repos_service.dart +++ b/lib/src/common/repos_service.dart @@ -163,20 +163,21 @@ class RepositoriesService extends Service { bool? hasWiki, bool? hasDownloads}) async { ArgumentError.checkNotNull(slug); - final data = createNonNullMap({ - 'name': name!, - 'description': description!, - 'homepage': homepage!, - 'private': private!, - 'has_issues': hasIssues!, - 'has_wiki': hasWiki!, - 'has_downloads': hasDownloads!, - 'default_branch': 'defaultBranch' + final data = createNonNullMap({ + 'name': name, + 'description': description, + 'homepage': homepage, + 'private': private, + 'has_issues': hasIssues, + 'has_wiki': hasWiki, + 'has_downloads': hasDownloads, }); - return github.postJSON( + return github.requestJson, Repository>( + 'PATCH', '/repos/${slug.fullName}', body: GitHubJson.encode(data), - statusCode: 200, + statusCode: StatusCodes.OK, + convert: Repository.fromJson, ); } @@ -594,8 +595,8 @@ class RepositoriesService extends Service { // it was likely a 404 – but we don't have the status code here // But we can guess an the JSON content if (input.containsKey('message')) { - throw GitHubError(github, input['message'], - apiUrl: input['documentation_url']); + throw GitHubError(github, input['message'] as String?, + apiUrl: input['documentation_url'] as String?); } contents.file = GitHubFile.fromJson(input as Map); } else { @@ -1180,6 +1181,7 @@ class RepositoriesService extends Service { createReleaseAsset.label, ), headers: headers, + statusCode: StatusCodes.CREATED, body: createReleaseAsset.assetData, convert: ReleaseAsset.fromJson); releaseAssets.add(releaseAsset); @@ -1323,4 +1325,50 @@ class RepositoriesService extends Service { convert: ReleaseNotes.fromJson, ); } + + /// Creates a repository dispatch event. + /// + /// API docs: https://docs.github.com/en/rest/repos/repos#create-a-repository-dispatch-event + Future createDispatchEvent( + RepositorySlug slug, + String eventType, { + Map? clientPayload, + }) async { + final body = { + 'event_type': eventType, + if (clientPayload != null) 'client_payload': clientPayload, + }; + + await github.request( + 'POST', + '/repos/${slug.fullName}/dispatches', + body: GitHubJson.encode(body), + statusCode: 204, + ); + } + + /// Lists all topics for a repository. + /// + /// API docs: https://docs.github.com/en/rest/repos/repos#get-all-repository-topics + Future> listTopics(RepositorySlug slug) async { + return github.getJSON, List>( + '/repos/${slug.fullName}/topics', + convert: (json) => List.from(json['names'] as List? ?? []), + ); + } + + /// Replaces all topics for a repository. + /// + /// API docs: https://docs.github.com/en/rest/repos/repos#replace-all-repository-topics + Future> replaceTopics( + RepositorySlug slug, + List topics, + ) async { + return github.requestJson, List>( + 'PUT', + '/repos/${slug.fullName}/topics', + body: GitHubJson.encode({'names': topics}), + convert: (json) => List.from(json['names'] as List? ?? []), + ); + } } diff --git a/lib/src/common/search_service.dart b/lib/src/common/search_service.dart index 27cf6eef..64fc8761 100644 --- a/lib/src/common/search_service.dart +++ b/lib/src/common/search_service.dart @@ -22,20 +22,14 @@ class SearchService extends Service { final controller = StreamController(); - var isFirst = true; - PaginationHelper(github) .fetchStreamed('GET', '/search/repositories', params: params, pages: pages) .listen((response) { - if (response.statusCode == 403 && - response.body.contains('rate limit') && - isFirst) { - throw RateLimitHit(github); + if (response.statusCode != 200) { + github.handleStatusCode(response); } - isFirst = false; - final input = jsonDecode(response.body); if (input['items'] == null) { @@ -120,7 +114,13 @@ class SearchService extends Service { return PaginationHelper(github) .fetchStreamed('GET', '/search/code', params: params, pages: pages) - .map((r) => CodeSearchResults.fromJson(json.decode(r.body))); + .map((r) { + if (r.statusCode != 200) { + github.handleStatusCode(r); + } + return CodeSearchResults.fromJson( + json.decode(r.body) as Map); + }); } String _searchQualifier(String key, String? value) { @@ -141,19 +141,13 @@ class SearchService extends Service { final controller = StreamController(); - var isFirst = true; - PaginationHelper(github) .fetchStreamed('GET', '/search/issues', params: params, pages: pages) .listen((response) { - if (response.statusCode == 403 && - response.body.contains('rate limit') && - isFirst) { - throw RateLimitHit(github); + if (response.statusCode != 200) { + github.handleStatusCode(response); } - isFirst = false; - final input = jsonDecode(response.body); if (input['items'] == null) { @@ -191,19 +185,13 @@ class SearchService extends Service { final controller = StreamController(); - var isFirst = true; - PaginationHelper(github) .fetchStreamed('GET', '/search/users', params: params, pages: pages) .listen((response) { - if (response.statusCode == 403 && - response.body.contains('rate limit') && - isFirst) { - throw RateLimitHit(github); + if (response.statusCode != 200) { + github.handleStatusCode(response); } - isFirst = false; - final input = jsonDecode(response.body); if (input['items'] == null) { diff --git a/lib/src/common/transport/error_decoder.dart b/lib/src/common/transport/error_decoder.dart new file mode 100644 index 00000000..67eae034 --- /dev/null +++ b/lib/src/common/transport/error_decoder.dart @@ -0,0 +1,233 @@ +// ignore_for_file: avoid_classes_with_only_static_members + +import 'dart:convert'; +import 'package:http/http.dart' as http; +import '../github.dart'; +import '../util/errors.dart'; + +/// Helper to parse, redact, and construct typed GitHub exceptions from HTTP error responses. +class ErrorDecoder { + static final RegExp _tokenRegex = RegExp( + r'(?:gh[pousr]_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,})', + ); + static final RegExp _authHeaderRegex = RegExp( + r'((?:bearer|token)\s+)[A-Za-z0-9_\-\.]+', + caseSensitive: false, + ); + + static const int maxBodyLength = 2000; + + /// Redacts sensitive authentication tokens from [input]. + static String redact(String input) { + return input + .replaceAll(_tokenRegex, '[REDACTED_TOKEN]') + .replaceAllMapped(_authHeaderRegex, (m) => '${m.group(1)}[REDACTED]'); + } + + /// Truncates [body] safely and redacts credentials. + static String sanitizeBody(String body) { + var truncated = body; + if (truncated.length > maxBodyLength) { + truncated = '${truncated.substring(0, maxBodyLength)}... [TRUNCATED]'; + } + return redact(truncated); + } + + /// Safely decodes an HTTP response into a typed [GitHubError] and throws it. + static Never decode( + GitHub github, + http.Response response, { + String? requestUrl, + }) { + final sanitizedBody = sanitizeBody(response.body); + final contentType = response.headers['content-type'] ?? ''; + final requestId = response.headers['x-github-request-id']; + + String? message; + List>? errors; + + if (contentType.contains('application/json') || + response.body.trim().startsWith('{')) { + try { + final decoded = jsonDecode(response.body); + if (decoded is Map) { + message = decoded['message']?.toString(); + if (decoded['errors'] != null) { + final rawErrors = decoded['errors']; + if (rawErrors is List) { + errors = rawErrors.map((e) { + if (e is Map) { + return Map.from(e); + } else if (e is Map) { + return e.map((k, v) => MapEntry(k.toString(), v)); + } + return {'message': e.toString()}; + }).toList(); + } else if (rawErrors is Map) { + errors = [ + rawErrors.map((k, v) => MapEntry(k.toString(), v)), + ]; + } else { + errors = [ + {'code': rawErrors.toString()}, + ]; + } + } + } + } catch (_) { + // Fall back gracefully on malformed JSON without crashing + } + } + + if (message != null) { + message = redact(message); + } + + final effectiveMessage = message ?? + (sanitizedBody.isNotEmpty + ? sanitizedBody + : 'HTTP ${response.statusCode}'); + + final rateRemaining = response.headers['x-ratelimit-remaining']; + final isRateLimitExceeded = response.statusCode == 429 || + (response.statusCode == 403 && + ((rateRemaining != null && rateRemaining == '0') || + effectiveMessage.toLowerCase().contains('rate limit'))); + + if (isRateLimitExceeded) { + DateTime? resetDate; + final resetHeader = response.headers['x-ratelimit-reset']; + if (resetHeader != null) { + final resetEpoch = int.tryParse(resetHeader.trim()); + if (resetEpoch != null) { + resetDate = DateTime.fromMillisecondsSinceEpoch(resetEpoch * 1000); + } + } + final limit = int.tryParse(response.headers['x-ratelimit-limit'] ?? ''); + final remaining = int.tryParse(rateRemaining ?? ''); + + throw RateLimitHit( + github, + message: effectiveMessage, + reset: resetDate, + limit: limit, + remaining: remaining, + apiUrl: requestUrl, + statusCode: response.statusCode, + responseBody: sanitizedBody, + responseHeaders: response.headers, + requestId: requestId, + ); + } + + switch (response.statusCode) { + case 400: + if (message == 'Problems parsing JSON' || + message == 'Body should be a JSON Hash') { + throw InvalidJSON( + github, + message, + requestUrl, + response.headers, + sanitizedBody, + ); + } + throw BadRequest( + github, + effectiveMessage, + requestUrl, + response.headers, + sanitizedBody, + ); + case 401: + throw NotAuthenticated( + github, + effectiveMessage, + requestUrl, + response.headers, + sanitizedBody, + ); + case 403: + throw AccessForbidden( + github, + effectiveMessage, + requestUrl, + response.headers, + sanitizedBody, + ); + case 404: + throw NotFound( + github, + effectiveMessage.isNotEmpty + ? effectiveMessage + : 'Requested Resource was Not Found', + apiUrl: requestUrl, + responseBody: sanitizedBody, + responseHeaders: response.headers, + requestId: requestId, + ); + case 409: + throw Conflict( + github, + effectiveMessage, + requestUrl, + response.headers, + sanitizedBody, + ); + case 422: + final buff = StringBuffer(); + buff.writeln(); + buff.writeln(' Message: $effectiveMessage'); + if (errors != null) { + buff.writeln(' Errors:'); + for (final error in errors) { + final resource = error['resource']; + final field = error['field']; + final code = error['code']; + final errMessage = error['message']; + buff.writeln( + ' ${resource != null ? 'Resource: $resource ' : ''}${field != null ? 'Field: $field ' : ''}${code != null ? 'Code: $code ' : ''}${errMessage != null ? 'Message: $errMessage' : ''}' + .trimRight()); + } + } + throw ValidationFailed( + github, + buff.toString().trim(), + errors, + requestUrl, + response.headers, + sanitizedBody, + ); + case 500: + case 502: + case 504: + throw ServerError( + github, + response.statusCode, + message, + apiUrl: requestUrl, + responseHeaders: response.headers, + responseBody: sanitizedBody, + requestId: requestId, + ); + case 503: + throw ServiceUnavailable( + github, + message, + requestUrl, + response.headers, + sanitizedBody, + requestId, + ); + default: + throw UnknownError( + github, + effectiveMessage, + requestUrl, + response.headers, + sanitizedBody, + response.statusCode, + ); + } + } +} diff --git a/lib/src/common/transport/request.dart b/lib/src/common/transport/request.dart new file mode 100644 index 00000000..8d749f83 --- /dev/null +++ b/lib/src/common/transport/request.dart @@ -0,0 +1,46 @@ +import '../generated/rest_contracts.g.dart'; + +/// A structured, type-safe API request description. +class ApiRequest { + /// HTTP method (e.g. 'GET', 'POST', 'PATCH', 'PUT', 'DELETE'). + final String method; + + /// Request path or absolute URL. + final String path; + + /// HTTP headers to send with the request. + final Map headers; + + /// Query parameters to encode into the URL. + final Map params; + + /// Request body (JSON-encodable Object, `List` bytes, or `null`). + final Object? body; + + /// Set of accepted HTTP status codes considered successful. + /// If `null`, any status code is returned without error decoding. + final Set? successStatuses; + + /// Associated OpenAPI operation contract, if known. + final RestOperationContract? contract; + + /// Optional per-request timeout. + final Duration? timeout; + + const ApiRequest({ + required this.method, + required this.path, + this.headers = const {}, + this.params = const {}, + this.body, + this.successStatuses = const {200}, + this.contract, + this.timeout, + }); + + /// True if the HTTP method is idempotent according to RFC 9110. + bool get isIdempotent { + final m = method.toUpperCase(); + return m == 'GET' || m == 'HEAD' || m == 'PUT' || m == 'DELETE'; + } +} diff --git a/lib/src/common/transport/retry_policy.dart b/lib/src/common/transport/retry_policy.dart new file mode 100644 index 00000000..9d28516d --- /dev/null +++ b/lib/src/common/transport/retry_policy.dart @@ -0,0 +1,148 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:math' as math; +import 'package:http/http.dart' as http; +import 'request.dart'; + +typedef Sleeper = Future Function(Duration duration); +typedef Clock = DateTime Function(); +typedef RandomGenerator = double Function(); + +/// Policy governing request retries, exponential backoff, and rate-limit delays. +class RetryPolicy { + /// Maximum number of retry attempts for idempotent operations. + final int maxRetries; + + /// Initial backoff delay for the first retry. + final Duration initialDelay; + + /// Maximum backoff delay allowed between retries. + final Duration maxDelay; + + /// Multiplier for exponential backoff calculation. + final double backoffMultiplier; + + /// Whether to retry requests that hit HTTP 429 or secondary rate limits. + final bool retryOnRateLimit; + + /// Injectable sleeper function (defaults to `Future.delayed`). + final Sleeper sleeper; + + /// Injectable clock function (defaults to `DateTime.now`). + final Clock clock; + + /// Injectable random generator for jitter (returns value in [0.0, 1.0)). + final RandomGenerator? random; + + const RetryPolicy({ + this.maxRetries = 3, + this.initialDelay = const Duration(milliseconds: 250), + this.maxDelay = const Duration(seconds: 30), + this.backoffMultiplier = 2.0, + this.retryOnRateLimit = true, + this.sleeper = Future.delayed, + this.clock = DateTime.now, + this.random, + }); + + /// No-retry policy for tests or callers desiring fail-fast behavior. + static const RetryPolicy noRetries = RetryPolicy(maxRetries: 0); + + /// Determines whether [error] or [response] warrants a retry on [attempt] (0-indexed). + bool shouldRetry({ + required ApiRequest request, + required int attempt, + http.Response? response, + Object? error, + }) { + if (attempt >= maxRetries) { + return false; + } + + // By default, retry only idempotent requests + if (!request.isIdempotent) { + return false; + } + + if (error != null) { + if (error is TimeoutException || + error is SocketException || + error is http.ClientException) { + return true; + } + return false; + } + + if (response != null) { + final code = response.statusCode; + if (code == 502 || code == 503 || code == 504) { + return true; + } + if (retryOnRateLimit && + (code == 429 || _isSecondaryRateLimit(response))) { + return true; + } + } + + return false; + } + + /// Calculates delay before attempt [attempt] (0-indexed), honoring `Retry-After` if present. + Duration delayFor({ + required int attempt, + http.Response? response, + }) { + if (response != null) { + final retryAfterHeader = response.headers['retry-after']; + if (retryAfterHeader != null) { + final seconds = int.tryParse(retryAfterHeader.trim()); + if (seconds != null) { + final d = Duration(seconds: seconds); + return d > maxDelay ? maxDelay : d; + } + try { + final date = HttpDate.parse(retryAfterHeader); + final diff = date.difference(clock()); + if (diff > Duration.zero) { + return diff > maxDelay ? maxDelay : diff; + } + } catch (_) {} + } + + // Check x-ratelimit-reset if 429 or secondary rate limit + if (response.statusCode == 429 || _isSecondaryRateLimit(response)) { + final resetHeader = response.headers['x-ratelimit-reset']; + if (resetHeader != null) { + final resetEpoch = int.tryParse(resetHeader.trim()); + if (resetEpoch != null) { + final resetDate = + DateTime.fromMillisecondsSinceEpoch(resetEpoch * 1000); + final diff = resetDate.difference(clock()); + if (diff > Duration.zero && diff <= maxDelay) { + return diff; + } + } + } + } + } + + // Exponential backoff with ±20% jitter + final exponentialMs = + initialDelay.inMilliseconds * math.pow(backoffMultiplier, attempt); + final jitterFactor = + 0.8 + ((random?.call() ?? math.Random().nextDouble()) * 0.4); + final delayMs = (exponentialMs * jitterFactor).round(); + + final capped = math.min(delayMs, maxDelay.inMilliseconds); + return Duration(milliseconds: capped); + } + + bool _isSecondaryRateLimit(http.Response response) { + if (response.statusCode != 403) { + return false; + } + final body = response.body.toLowerCase(); + return body.contains('secondary rate limit') || + body.contains('rate limit exceeded'); + } +} diff --git a/lib/src/common/transport/transport.dart b/lib/src/common/transport/transport.dart new file mode 100644 index 00000000..693e2ed3 --- /dev/null +++ b/lib/src/common/transport/transport.dart @@ -0,0 +1,280 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:http/http.dart' as http; +import '../github.dart'; +import '../util/auth.dart'; +import '../util/errors.dart'; +import '../util/json.dart'; +import 'error_decoder.dart'; +import 'request.dart'; +import 'retry_policy.dart'; + +typedef ResponseCallback = void Function(http.Response response); + +/// High-level transport orchestrating URI construction, credential boundary checks, +/// serialization, retry loops, rate-limit tracking, and typed error decoding. +class HttpTransport { + final GitHub github; + final http.Client client; + final RetryPolicy retryPolicy; + final Set trustedOrigins; + final bool allowInsecureAuth; + final String endpoint; + + HttpTransport({ + required this.github, + required this.client, + required this.trustedOrigins, + this.retryPolicy = const RetryPolicy(), + this.allowInsecureAuth = false, + this.endpoint = 'https://api.github.com', + }); + + /// Resolves an [ApiRequest] into an absolute, normalized [Uri]. + Uri resolveUri( + String rawPath, { + Map params = const {}, + Map pathParams = const {}, + Set multiSegmentParams = const {}, + }) { + var expandedPath = rawPath; + + // Substitute path parameters e.g. {owner}, {repo}, {+path} + for (final entry in pathParams.entries) { + final key = entry.key; + final value = entry.value; + final isMultiSegment = + multiSegmentParams.contains(key) || key.startsWith('+'); + final encoded = + isMultiSegment ? Uri.encodeFull(value) : Uri.encodeComponent(value); + expandedPath = expandedPath + .replaceAll('{$key}', encoded) + .replaceAll('{+$key}', encoded); + } + + Uri targetUri; + if (expandedPath.startsWith('http://') || + expandedPath.startsWith('https://')) { + targetUri = Uri.parse(expandedPath); + } else { + final normalizedEndpoint = endpoint.endsWith('/') + ? endpoint.substring(0, endpoint.length - 1) + : endpoint; + final normalizedPath = + expandedPath.startsWith('/') ? expandedPath : '/$expandedPath'; + + targetUri = Uri.parse('$normalizedEndpoint$normalizedPath'); + } + + // Merge query parameters + if (params.isNotEmpty) { + final currentQuery = + Map>.from(targetUri.queryParametersAll); + for (final entry in params.entries) { + if (entry.value == null) { + continue; + } + final key = entry.key; + final value = entry.value; + if (value is Iterable) { + final list = currentQuery.putIfAbsent(key, () => []); + for (final item in value) { + if (item != null) { + list.add(item is Enum ? item.name : item.toString()); + } + } + } else { + final list = currentQuery.putIfAbsent(key, () => []); + list.add(value is Enum ? value.name : value.toString()); + } + } + + targetUri = targetUri.replace( + queryParameters: currentQuery.isEmpty ? null : currentQuery); + } + + return targetUri; + } + + /// Validates security constraints against [targetUri]. + void validateSecurityBoundaries(Uri targetUri, Authentication auth) { + if (targetUri.scheme != 'https' && + !allowInsecureAuth && + !auth.isAnonymous) { + throw GitHubError( + github, + 'Insecure HTTP authentication is disallowed by default. ' + 'Set allowInsecureAuth: true only for local testing.', + ); + } + } + + /// Prepares the headers map for [request], injecting User-Agent and Authorization. + Map prepareHeaders( + ApiRequest request, + Uri targetUri, + Authentication auth, + ) { + final headers = Map.from(request.headers); + + // Apply GitHub required User-Agent + headers.putIfAbsent('User-Agent', () => auth.username ?? 'github.dart'); + + // Apply Authorization if origin is trusted + if (trustedOrigins.contains(targetUri.origin)) { + final authHeader = auth.authorizationHeaderValue(); + if (authHeader != null) { + headers.putIfAbsent('Authorization', () => authHeader); + } + } + + // Content length for empty PUT/POST + if ((request.method == 'PUT' || request.method == 'POST') && + request.body == null) { + headers.putIfAbsent('Content-Length', () => '0'); + } + + return headers; + } + + /// Executes [request], performing retries and typed error handling. + Future execute( + ApiRequest request, { + ResponseCallback? fail, + }) async { + // If rate limit remaining is 0, wait for reset window if within reasonable max delay + if (github.rateLimitRemaining != null && + github.rateLimitRemaining! <= 0 && + github.rateLimitReset != null) { + final now = retryPolicy.clock(); + if (github.rateLimitReset!.isAfter(now)) { + final waitTime = github.rateLimitReset!.difference(now); + if (waitTime <= retryPolicy.maxDelay) { + await retryPolicy.sleeper(waitTime); + } + } + } + + final auth = github.auth; + final targetUri = resolveUri( + request.path, + params: request.params, + ); + + validateSecurityBoundaries(targetUri, auth); + final headers = prepareHeaders(request, targetUri, auth); + + http.Response? lastResponse; + Object? lastError; + + for (var attempt = 0; attempt <= retryPolicy.maxRetries; attempt++) { + try { + final httpRequest = http.Request(request.method, targetUri); + httpRequest.headers.addAll(headers); + + if (request.body != null) { + final body = request.body; + if (body is List) { + httpRequest.bodyBytes = body; + } else if (body is String) { + httpRequest.body = body; + } else { + httpRequest.headers.putIfAbsent( + 'Content-Type', () => 'application/json; charset=utf-8'); + httpRequest.body = jsonEncode(body); + } + } + + var sendFuture = client.send(httpRequest); + if (request.timeout != null) { + sendFuture = sendFuture.timeout(request.timeout!); + } + + final streamed = await sendFuture; + final response = await http.Response.fromStream(streamed); + lastResponse = response; + + // Update rate limit metadata on parent github instance + github.updateRateLimit(response.headers); + + // Check if status is accepted + if (request.successStatuses == null || + request.successStatuses!.contains(response.statusCode)) { + return response; + } + + // Check if retry policy triggers on this response + if (retryPolicy.shouldRetry( + request: request, + attempt: attempt, + response: response, + )) { + final delay = + retryPolicy.delayFor(attempt: attempt, response: response); + await retryPolicy.sleeper(delay); + continue; + } + + // Failed status without retry + if (fail != null) { + fail(response); + } + ErrorDecoder.decode(github, response, requestUrl: targetUri.toString()); + } catch (e) { + lastError = e; + if (e is GitHubError) { + rethrow; + } + + if (retryPolicy.shouldRetry( + request: request, + attempt: attempt, + error: e, + )) { + final delay = retryPolicy.delayFor(attempt: attempt); + await retryPolicy.sleeper(delay); + continue; + } + + throw GitHubError( + github, + 'Network request failed: $e', + apiUrl: targetUri.toString(), + source: e, + ); + } + } + + if (lastResponse != null) { + if (fail != null) { + fail(lastResponse); + } + ErrorDecoder.decode(github, lastResponse, + requestUrl: targetUri.toString()); + } + + throw GitHubError( + github, + 'Request failed after ${retryPolicy.maxRetries} retries: $lastError', + apiUrl: targetUri.toString(), + source: lastError, + ); + } + + /// Convenience method to execute a request and decode the JSON body. + Future executeJson( + ApiRequest request, { + JSONConverter? convert, + ResponseCallback? fail, + }) async { + final response = await execute(request, fail: fail); + if (response.statusCode == 204 || response.body.isEmpty) { + return null as T; + } + final decoded = jsonDecode(response.body); + if (convert != null) { + return convert(decoded) as T; + } + return decoded as T; + } +} diff --git a/lib/src/common/url_shortener_service.dart b/lib/src/common/url_shortener_service.dart index 60db2958..9fb20b11 100644 --- a/lib/src/common/url_shortener_service.dart +++ b/lib/src/common/url_shortener_service.dart @@ -1,15 +1,20 @@ import 'dart:async'; import 'package:github/src/common.dart'; -/// The [UrlShortenerService] provides a handy method to access GitHub's -/// url shortener. +/// The [UrlShortenerService] provides a method to access GitHub's +/// legacy git.io url shortener. /// -/// API docs: https://github.com/blog/985-git-io-github-url-shortener +/// NOTE: The git.io service was deprecated and discontinued by GitHub in 2022. +/// This service is retained for backwards compatibility only. +@Deprecated( + 'git.io was discontinued by GitHub in 2022 and is no longer operational.') class UrlShortenerService extends Service { UrlShortenerService(super.github); /// Shortens the provided [url]. An optional [code] can be provided to create /// your own vanity URL. + @Deprecated( + 'git.io was discontinued by GitHub in 2022 and is no longer operational.') Future shortenUrl(String url, {String? code}) { final params = {}; @@ -19,14 +24,19 @@ class UrlShortenerService extends Service { params['code'] = code; } - return github - .request('POST', 'http://git.io/', params: params) - .then((response) { + // Never send authentication credentials to git.io; use HTTPS. + return github.request('POST', 'https://git.io/', + params: params, headers: {}).then((response) { if (response.statusCode != StatusCodes.CREATED) { throw GitHubError(github, 'Failed to create shortened url!'); } - return response.headers['Location']!.split('/').last; + final location = + response.headers['location'] ?? response.headers['Location']; + if (location == null) { + throw GitHubError(github, 'Missing Location header in response'); + } + return location.split('/').last; }); } } diff --git a/lib/src/common/util/errors.dart b/lib/src/common/util/errors.dart index 14625a6c..2c6529cf 100644 --- a/lib/src/common/util/errors.dart +++ b/lib/src/common/util/errors.dart @@ -6,8 +6,21 @@ class GitHubError implements Exception { final String? apiUrl; final GitHub github; final Object? source; + final int? statusCode; + final String? responseBody; + final Map? responseHeaders; + final String? requestId; - const GitHubError(this.github, this.message, {this.apiUrl, this.source}); + const GitHubError( + this.github, + this.message, { + this.apiUrl, + this.source, + this.statusCode, + this.responseBody, + this.responseHeaders, + this.requestId, + }); @override String toString() => 'GitHub Error: $message'; @@ -26,12 +39,29 @@ class NotReady extends GitHubError { class NotFound extends GitHubError { const NotFound( super.github, - String super.msg, - ); + String super.msg, { + super.apiUrl, + super.source, + super.statusCode = 404, + super.responseBody, + super.responseHeaders, + super.requestId, + }); } class BadRequest extends GitHubError { - const BadRequest(super.github, [super.msg = 'Not Found']); + const BadRequest( + super.github, [ + super.message = 'Bad Request', + String? apiUrl, + Map? responseHeaders, + String? responseBody, + ]) : super( + apiUrl: apiUrl, + statusCode: 400, + responseBody: responseBody, + responseHeaders: responseHeaders, + ); } /// GitHub Repository was not found @@ -64,39 +94,166 @@ class TeamNotFound extends NotFound { : super(github, 'Team Not Found: $id'); } -/// Access was forbidden to a resource +/// Access was forbidden to a resource (HTTP 403) class AccessForbidden extends GitHubError { - const AccessForbidden(GitHub github) : super(github, 'Access Forbidden'); + const AccessForbidden( + super.github, [ + super.message = 'Access Forbidden', + String? apiUrl, + Map? responseHeaders, + String? responseBody, + ]) : super( + apiUrl: apiUrl, + statusCode: 403, + responseBody: responseBody, + responseHeaders: responseHeaders, + ); } -/// Client hit the rate limit. +/// Client hit the rate limit (HTTP 429 or HTTP 403 rate limit exceeded). class RateLimitHit extends GitHubError { - const RateLimitHit(GitHub github) : super(github, 'Rate Limit Hit'); + final DateTime? reset; + final int? limit; + final int? remaining; + + const RateLimitHit( + GitHub github, { + String? message, + this.reset, + this.limit, + this.remaining, + String? apiUrl, + int statusCode = 429, + String? responseBody, + Map? responseHeaders, + String? requestId, + }) : super( + github, + message ?? 'Rate Limit Hit', + apiUrl: apiUrl, + statusCode: statusCode, + responseBody: responseBody, + responseHeaders: responseHeaders, + requestId: requestId, + ); } -/// A GitHub Server Error +/// Resource conflict (HTTP 409) +class Conflict extends GitHubError { + const Conflict( + super.github, [ + super.message = 'Conflict', + String? apiUrl, + Map? responseHeaders, + String? responseBody, + ]) : super( + apiUrl: apiUrl, + statusCode: 409, + responseBody: responseBody, + responseHeaders: responseHeaders, + ); +} + +/// A GitHub Server Error (HTTP 500, 502, 504) class ServerError extends GitHubError { - ServerError(GitHub github, int statusCode, String? message) - : super(github, '${message ?? 'Server Error'} ($statusCode)'); + ServerError( + GitHub github, + int statusCode, + String? message, { + String? apiUrl, + Map? responseHeaders, + String? responseBody, + String? requestId, + }) : super( + github, + '${message ?? 'Server Error'} ($statusCode)', + statusCode: statusCode, + apiUrl: apiUrl, + responseHeaders: responseHeaders, + responseBody: responseBody, + requestId: requestId, + ); +} + +/// Service Unavailable (HTTP 503) +class ServiceUnavailable extends ServerError { + ServiceUnavailable( + GitHub github, [ + String? message, + String? apiUrl, + Map? responseHeaders, + String? responseBody, + String? requestId, + ]) : super( + github, + 503, + message ?? 'Service Unavailable', + apiUrl: apiUrl, + responseHeaders: responseHeaders, + responseBody: responseBody, + requestId: requestId, + ); } /// An Unknown Error class UnknownError extends GitHubError { - const UnknownError(GitHub github, [String? message]) - : super(github, message ?? 'Unknown Error'); + const UnknownError( + GitHub github, [ + String? message, + String? apiUrl, + Map? responseHeaders, + String? responseBody, + int? statusCode, + ]) : super( + github, + message ?? 'Unknown Error', + apiUrl: apiUrl, + statusCode: statusCode, + responseHeaders: responseHeaders, + responseBody: responseBody, + ); } -/// GitHub Client was not authenticated +/// GitHub Client was not authenticated (HTTP 401) class NotAuthenticated extends GitHubError { - const NotAuthenticated(GitHub github) - : super(github, 'Client not Authenticated'); + const NotAuthenticated( + super.github, [ + super.message = 'Client not Authenticated', + String? apiUrl, + Map? responseHeaders, + String? responseBody, + ]) : super( + apiUrl: apiUrl, + statusCode: 401, + responseBody: responseBody, + responseHeaders: responseHeaders, + ); } class InvalidJSON extends BadRequest { - const InvalidJSON(super.github, [super.message = 'Invalid JSON']); + const InvalidJSON( + super.github, [ + super.message = 'Invalid JSON', + super.apiUrl, + super.responseHeaders, + super.responseBody, + ]); } class ValidationFailed extends GitHubError { - const ValidationFailed(super.github, - [String super.message = 'Validation Failed']); + final List>? errors; + + const ValidationFailed( + super.github, [ + super.message = 'Validation Failed', + this.errors, + String? apiUrl, + Map? responseHeaders, + String? responseBody, + ]) : super( + apiUrl: apiUrl, + statusCode: 422, + responseHeaders: responseHeaders, + responseBody: responseBody, + ); } diff --git a/lib/src/common/util/oauth2.dart b/lib/src/common/util/oauth2.dart index 9333d606..dd98cc61 100644 --- a/lib/src/common/util/oauth2.dart +++ b/lib/src/common/util/oauth2.dart @@ -87,8 +87,11 @@ class OAuth2Flow { if (json['error'] != null) { throw Exception(json['error']); } - return ExchangeResponse(json['access_token'], json['token_type'], - (json['scope'] as String).split(',')); + return ExchangeResponse( + json['access_token'] as String?, + json['token_type'] as String?, + ((json['scope'] as String?) ?? '').split(','), + ); }); } } diff --git a/lib/src/common/util/pagination.dart b/lib/src/common/util/pagination.dart index 93f3a0d7..b53aa623 100644 --- a/lib/src/common/util/pagination.dart +++ b/lib/src/common/util/pagination.dart @@ -41,7 +41,7 @@ class PaginationHelper { if (serverErrors >= maxServerErrors) { break; } - await Future.delayed(serverErrorBackOff); + await Future.delayed(serverErrorBackOff); continue; } @@ -98,12 +98,15 @@ class PaginationHelper { body: body, statusCode: statusCode, )) { + final decoded = jsonDecode(response.body); final json = arrayKey == null - ? jsonDecode(response.body) as List? - : (jsonDecode(response.body) as Map)[arrayKey]; + ? (decoded as List?) + : ((decoded as Map)[arrayKey] as List?); - for (final item in json) { - yield (item as T?)!; + if (json != null) { + for (final item in json) { + yield (item as T?)!; + } } } } diff --git a/lib/src/common/util/utils.dart b/lib/src/common/util/utils.dart index 5c690774..45b90f47 100644 --- a/lib/src/common/util/utils.dart +++ b/lib/src/common/util/utils.dart @@ -99,32 +99,41 @@ final RegExp githubDateRemoveRegExp = RegExp(r'\.\d*'); const v3ApiMimeType = 'application/vnd.github.v3+json'; -String buildQueryString(Map params) { - final queryString = StringBuffer(); - - if (params.isNotEmpty && !params.values.every((value) => value == null)) { - queryString.write('?'); - } - - var i = 0; - for (final key in params.keys) { - i++; - if (params[key] == null) { +String buildQueryString(Map params, + {bool prefixQuestionMark = true}) { + final queryParts = []; + for (final entry in params.entries) { + final key = entry.key; + final value = entry.value; + if (value == null) { continue; } - queryString.write('$key=${Uri.encodeComponent(params[key].toString())}'); - if (i != params.keys.length) { - queryString.write('&'); + + final encodedKey = Uri.encodeQueryComponent(key); + if (value is Iterable) { + for (final item in value) { + if (item != null) { + final itemStr = item is Enum ? item.name : item.toString(); + queryParts.add('$encodedKey=${Uri.encodeQueryComponent(itemStr)}'); + } + } + } else { + final valueStr = value is Enum ? value.name : value.toString(); + queryParts.add('$encodedKey=${Uri.encodeQueryComponent(valueStr)}'); } } - return queryString.toString(); + + if (queryParts.isEmpty) { + return ''; + } + return prefixQuestionMark ? '?${queryParts.join('&')}' : queryParts.join('&'); } dynamic copyOf(dynamic input) { if (input is Iterable) { - return List.from(input); + return List.from(input); } else if (input is Map) { - return Map.from(input); + return Map.from(input); } else { throw Exception('type could not be copied'); } diff --git a/lib/src/common/xplat_common.dart b/lib/src/common/xplat_common.dart index 1c60f906..16a51a20 100644 --- a/lib/src/common/xplat_common.dart +++ b/lib/src/common/xplat_common.dart @@ -2,28 +2,29 @@ import 'package:github/src/common.dart'; /// Looks for GitHub Authentication information from the current environment. /// -/// If in a browser context, it will look through query string parameters first -/// and then sessionStorage. +/// If in a browser context, it will check sessionStorage (and optionally query strings +/// if [allowQueryAuth] is explicitly set to true, which is deprecated). /// /// If in a server, command line or Flutter context it will use the system environment variables. /// /// In both contexts it delegates to [findAuthenticationInMap] to find the /// github token or username and password. -Authentication findAuthenticationFromEnvironment() => +Authentication findAuthenticationFromEnvironment( + {bool allowQueryAuth = false}) => const Authentication.anonymous(); /// Checks the passed in map for keys in [COMMON_GITHUB_TOKEN_ENV_KEYS]. /// The first one that exists is used as the github token to call [Authentication.withToken] with. /// If the above fails, the GITHUB_USERNAME and GITHUB_PASSWORD keys will be checked. /// If those keys both exist, then [Authentication.basic] will be used. -Authentication? findAuthenticationInMap(Map map) { +Authentication? findAuthenticationInMap(Map map) { for (final key in COMMON_GITHUB_TOKEN_ENV_KEYS) { if (map.containsKey(key)) { - return Authentication.withToken(map[key]); + return Authentication.withToken(map[key] as String?); } if (map['GITHUB_USERNAME'] is String && map['GITHUB_PASSWORD'] is String) { return Authentication.basic( - map['GITHUB_USERNAME'], map['GITHUB_PASSWORD']); + map['GITHUB_USERNAME'] as String?, map['GITHUB_PASSWORD'] as String?); } } return null; diff --git a/lib/src/server/hooks.dart b/lib/src/server/hooks.dart index ae3fa0bf..b7941e2a 100644 --- a/lib/src/server/hooks.dart +++ b/lib/src/server/hooks.dart @@ -1,7 +1,9 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'dart:typed_data'; +import 'package:crypto/crypto.dart'; import 'package:json_annotation/json_annotation.dart'; import '../common.dart'; @@ -9,63 +11,231 @@ import '../common/model/changes.dart'; part 'hooks.g.dart'; +/// Middleware for processing GitHub webhooks securely. class HookMiddleware { - // TODO: Close this, but where? + /// Webhook secret for HMAC-SHA256 signature verification. + /// If provided, all incoming requests must have a valid `X-Hub-Signature-256` header. + final String? secret; + + /// Maximum allowed payload size in bytes. Defaults to 10 MB. + final int maxBodySize; + + /// Optional hook for replay attack detection based on delivery ID. + /// Returns `true` if the delivery ID is fresh/acceptable, or `false` if it is a replay. + final bool Function(String deliveryId)? onReplayCheck; + final StreamController _eventController = - StreamController(); + StreamController.broadcast(); + Stream get onEvent => _eventController.stream; - void handleHookRequest(HttpRequest request) { + HookMiddleware({ + this.secret, + this.maxBodySize = 10 * 1024 * 1024, + this.onReplayCheck, + }); + + /// Closes the webhook event stream and releases resources. + Future close() => _eventController.close(); + + /// Constant-time string equality check to prevent timing attacks. + static bool constantTimeEquals(String a, String b) { + if (a.length != b.length) { + return false; + } + var result = 0; + for (var i = 0; i < a.length; i++) { + result |= a.codeUnitAt(i) ^ b.codeUnitAt(i); + } + return result == 0; + } + + /// Verifies an incoming webhook HMAC-SHA256 signature. + static bool verifySignature( + String secret, List payloadBytes, String? signatureHeader) { + if (signatureHeader == null || !signatureHeader.startsWith('sha256=')) { + return false; + } + final expectedHex = signatureHeader.substring(7); + final hmac = Hmac(sha256, utf8.encode(secret)); + final calculated = hmac.convert(payloadBytes).toString(); + return constantTimeEquals( + calculated.toLowerCase(), expectedHex.toLowerCase()); + } + + /// Handles an incoming webhook HTTP request. + Future handleHookRequest(HttpRequest request) async { if (request.method != 'POST') { request.response - ..write('Only POST is Supported') + ..statusCode = HttpStatus.methodNotAllowed + ..headers.contentType = ContentType.json + ..write(jsonEncode({ + 'error': 'Method Not Allowed', + 'message': 'Only POST is Supported' + })) ..close(); return; } - if (request.headers.value('X-GitHub-Event') == null) { + final eventHeader = request.headers.value('X-GitHub-Event'); + if (eventHeader == null || eventHeader.trim().isEmpty) { request.response - ..write('X-GitHub-Event must be specified.') + ..statusCode = HttpStatus.badRequest + ..headers.contentType = ContentType.json + ..write(jsonEncode({ + 'error': 'Bad Request', + 'message': 'X-GitHub-Event must be specified.' + })) ..close(); return; } - const Utf8Decoder().bind(request).join().then((content) { - _eventController.add(HookEvent.fromJson( - request.headers.value('X-GitHub-Event'), - jsonDecode(content) as Map?)); + final deliveryId = request.headers.value('X-GitHub-Delivery'); + if (deliveryId != null && onReplayCheck != null) { + final isFresh = onReplayCheck!(deliveryId); + if (!isFresh) { + request.response + ..statusCode = HttpStatus.conflict + ..headers.contentType = ContentType.json + ..write(jsonEncode( + {'error': 'Conflict', 'message': 'Duplicate delivery'})) + ..close(); + return; + } + } + + final builder = BytesBuilder(copy: false); + var bytesReceived = 0; + + try { + await for (final chunk in request) { + bytesReceived += chunk.length; + if (bytesReceived > maxBodySize) { + request.response + ..statusCode = HttpStatus.requestEntityTooLarge + ..headers.contentType = ContentType.json + ..write(jsonEncode({ + 'error': 'Payload Too Large', + 'message': + 'Payload exceeds maximum allowed size of $maxBodySize bytes' + })) + ..close(); + return; + } + builder.add(chunk); + } + } catch (_) { request.response - ..write(GitHubJson.encode({'handled': _eventController.hasListener})) + ..statusCode = HttpStatus.badRequest + ..headers.contentType = ContentType.json + ..write(jsonEncode( + {'error': 'Bad Request', 'message': 'Failed to read request body'})) ..close(); - }); + return; + } + + final rawBytes = builder.takeBytes(); + + if (secret != null) { + final signatureHeader = request.headers.value('X-Hub-Signature-256'); + if (!verifySignature(secret!, rawBytes, signatureHeader)) { + request.response + ..statusCode = HttpStatus.unauthorized + ..headers.contentType = ContentType.json + ..write(jsonEncode( + {'error': 'Unauthorized', 'message': 'Invalid signature'})) + ..close(); + return; + } + } + + Map? bodyJson; + try { + final text = utf8.decode(rawBytes); + if (text.isNotEmpty) { + final decoded = jsonDecode(text); + if (decoded is Map) { + bodyJson = decoded; + } else if (decoded is Map) { + bodyJson = decoded.cast(); + } + } + } catch (_) { + request.response + ..statusCode = HttpStatus.badRequest + ..headers.contentType = ContentType.json + ..write(jsonEncode( + {'error': 'Bad Request', 'message': 'Invalid JSON body'})) + ..close(); + return; + } + + _eventController.add(HookEvent.fromJson(eventHeader, bodyJson)); + request.response + ..statusCode = HttpStatus.ok + ..headers.contentType = ContentType.json + ..write(GitHubJson.encode({'handled': _eventController.hasListener})) + ..close(); } } +/// A standalone HTTP server for receiving GitHub webhooks. class HookServer extends HookMiddleware { final String host; final int port; - late HttpServer _server; - - HookServer(this.port, [this.host = '0.0.0.0']); + HttpServer? _server; + + HookServer( + this.port, [ + this.host = '127.0.0.1', + String? secret, + int maxBodySize = 10 * 1024 * 1024, + bool Function(String deliveryId)? onReplayCheck, + ]) : super( + secret: secret, + maxBodySize: maxBodySize, + onReplayCheck: onReplayCheck, + ); + + HookServer.options({ + required this.port, + this.host = '127.0.0.1', + super.secret, + super.maxBodySize, + super.onReplayCheck, + }); - void start() { - HttpServer.bind(host, port).then((HttpServer server) { - _server = server; - server.listen((request) { + /// Starts the HTTP server and returns the bound [HttpServer] instance. + Future start() async { + final server = await HttpServer.bind(host, port); + _server = server; + server.listen((request) async { + try { if (request.uri.path == '/hook') { - handleHookRequest(request); + await handleHookRequest(request); } else { request.response - ..statusCode = 404 + ..statusCode = HttpStatus.notFound ..write('404 - Not Found') ..close(); } - }); + } catch (_) { + try { + request.response + ..statusCode = HttpStatus.internalServerError + ..close(); + } catch (_) {} + } }); + return server; } - Future stop() => _server.close(); + /// Stops the HTTP server and closes the webhook event stream. + Future stop() async { + await _server?.close(force: true); + await close(); + } } class HookEvent { diff --git a/lib/src/server/xplat_server.dart b/lib/src/server/xplat_server.dart index a6c85d02..3ddc8968 100644 --- a/lib/src/server/xplat_server.dart +++ b/lib/src/server/xplat_server.dart @@ -9,7 +9,8 @@ export 'hooks.dart'; /// /// Checks all the environment variables in [COMMON_GITHUB_TOKEN_ENV_KEYS] for tokens. /// If the above fails, the GITHUB_USERNAME and GITHUB_PASSWORD keys will be checked. -Authentication findAuthenticationFromEnvironment() { +Authentication findAuthenticationFromEnvironment( + {bool allowQueryAuth = false}) { if (Platform.isMacOS) { final result = Process.runSync( 'security', const ['find-internet-password', '-g', '-s', 'github.com']); diff --git a/plans/github-api-conformance_2445b567.plan.md b/plans/github-api-conformance_2445b567.plan.md new file mode 100644 index 00000000..d3965e26 --- /dev/null +++ b/plans/github-api-conformance_2445b567.plan.md @@ -0,0 +1,145 @@ +--- +name: github-api-conformance +overview: Harden github.dart’s transport and webhook surfaces, correct verified REST contract defects, and add a reproducible OpenAPI-based conformance system that continuously raises tested coverage without breaking the current public API. A scheduled workflow will detect upstream specification changes, regenerate deterministic artifacts, run all gates, and open review-only update PRs. +todos: + - id: secure-boundaries + content: Add regression tests and fix cross-origin credential leakage, URL shortener behavior, webhook verification/limits, and browser query-token loading. + status: completed + - id: spec-baseline + content: Implement the pinned OpenAPI lock, deterministic normalized operation catalog, bindings manifest, semantic diff, and coverage report. + status: completed + - id: typed-transport + content: Refactor requests into an injectable URI/body/status/error/retry transport while retaining compatibility wrappers. + status: completed + - id: repair-services + content: Generate contract tests for every bound operation and fix all method, path, parameter, body, status, header, pagination, and decoder mismatches. + status: completed + - id: schema-models + content: Correct wire-model defects and incrementally add schema-aware DTOs, required/nullability semantics, forward-compatible enums, and strict analyzer settings. + status: completed + - id: test-pyramid + content: Add transport, service-contract, model, webhook, browser, scenario, and safe live-smoke tests with a coverage ratchet. + status: completed + - id: spec-sync-prs + content: Create the weekly idempotent spec-sync workflow that verifies upstream provenance, regenerates artifacts, classifies changes, validates, and opens review-only PRs. + status: completed + - id: ci-release-docs + content: Pin and minimize Actions permissions, add drift/security/browser gates, harden release credentials, and document compatibility and maintenance workflows. + status: completed +isProject: false +--- + +# GitHub REST API Conformance and Quality Plan + +> **For agentic workers:** Implement each workstream test-first and review each independently; preserve the current public API unless a security fix requires deprecation. + +**Goal:** Make existing github.dart operations demonstrably conform to GitHub REST API v3, harden security and error behavior, improve cross-platform testability, and continuously track the stable GitHub OpenAPI description. + +**Architecture:** Use the stable bundled OpenAPI 3.0 artifact for API version `2022-11-28` as a versioned oracle, not as a big-bang replacement for the handwritten API. Generate a compact operation catalog and conformance tests; keep current services as compatibility adapters over a typed, injectable transport. At audit time the upstream artifact was 12,886,008 bytes, described 1,229 operations, and came from `github/rest-api-description` main SHA `022b4dc2d10306c8c583368af92e3296598c6ce3`; the checked-in lock must pin whatever revision is intentionally adopted. + +**Source of truth:** [GitHub REST API description](https://github.com/github/rest-api-description), specifically `descriptions/api.github.com/api.github.com.2022-11-28.json`. Do not consume `descriptions-next` because GitHub documents it as the breaking-change OpenAPI 3.1 stream. + +## Audit findings to address + +### Critical/high security +- [`lib/src/common/github.dart`](lib/src/common/github.dart) accepts any absolute HTTP(S) URL and adds the configured `Authorization` header before sending it. [`lib/src/common/url_shortener_service.dart`](lib/src/common/url_shortener_service.dart) exercises this path against plain-text `http://git.io/`, allowing credential disclosure to another host and over an unencrypted connection. Git.io is outside the REST contract and should be removed/deprecated; authentication must be scoped to trusted origins. +- [`lib/src/server/hooks.dart`](lib/src/server/hooks.dart) binds to `0.0.0.0`, accepts webhook bodies without `X-Hub-Signature-256` verification, has no body-size limit, and does not reliably close the response on malformed JSON/stream errors. This enables spoofed events and resource exhaustion when exposed. +- [`lib/src/browser/xplat_browser.dart`](lib/src/browser/xplat_browser.dart) imports credentials directly from `window.location.href` query parameters. Tokens can persist in history, logs, screenshots, and referrer data; query-string discovery should be disabled by default and deprecated. +- GitHub Actions in [`.github/workflows`](.github/workflows) use mutable major/version tags rather than immutable commit SHAs. [`create_release.yml`](.github/workflows/create_release.yml) also uses a long-lived `RELEASE_TOKEN`; workflows lack a consistent explicit least-privilege permission policy. + +### Verified REST-contract defects +- Updates use `POST` where the OpenAPI contract requires `PATCH`: [`UsersService.editCurrentUser`](lib/src/common/users_service.dart), [`PullRequestsService.edit`](lib/src/common/pulls_service.dart), repository update/release update/release-asset update in [`repos_service.dart`](lib/src/common/repos_service.dart), gist update in [`gists_service.dart`](lib/src/common/gists_service.dart), and organization/team update in [`orgs_service.dart`](lib/src/common/orgs_service.dart). The recent issue-comment POST-to-PATCH fix shows this is a systemic class of defect. +- [`GistsService.starGist`](lib/src/common/gists_service.dart) sends `POST`; the contract requires `PUT`. +- [`RepositoriesService.getReleaseAsset`](lib/src/common/repos_service.dart) sends `POST`; the contract requires `GET`. +- [`CheckSuitesService.createCheckSuite`](lib/src/common/checks_service.dart) sends required `head_sha` as a query parameter instead of a JSON request body. `updatePreferencesForCheckSuites` supplies a Dart `Map` body, but [`GitHub.request`](lib/src/common/github.dart) serializes non-byte bodies with `.toString()`, producing invalid JSON. +- [`UsersService.createPublicKey`](lib/src/common/users_service.dart) omits `convert: PublicKey.fromJson` and casts the resulting future, causing a runtime type failure. +- Numerous methods still depend on obsolete `developer.github.com/v3` documentation and preview media types even though the operations are generally available. + +### Transport and correctness defects +- [`GitHub.request`](lib/src/common/github.dart) treats every response as successful when callers omit `statusCode`; many service methods therefore attempt to deserialize error payloads as success models. Exact single-status matching also cannot express valid response sets. +- Error handling dereferences a missing `content-type`, maps only a small subset of REST statuses, treats 401 as `AccessForbidden`, omits 403/409/429/503 and secondary-rate-limit semantics, and can replace the original error with parsing/cast failures. +- [`requestJson`](lib/src/common/github.dart) always decodes a JSON body, so empty/204 responses and non-JSON media require inconsistent bypasses. +- [`buildQueryString`](lib/src/common/util/utils.dart) can leave trailing separators, does not encode keys, stringifies lists/enums ad hoc, and appends a second `?` to URLs that already contain a query. Paths and continuation links are string-concatenated rather than built as `Uri` values. +- Pagination in [`pagination.dart`](lib/src/common/util/pagination.dart) retries server errors ten times with a fixed delay, drops the final error by ending the stream, is not cancellation-aware, uses a fragile Link parser, and follows absolute links through the credential-leaking transport. +- Rate-limit waiting uses wall-clock time and uninjectable `Future.delayed`, can receive a negative duration, and does not model primary versus secondary limits or `Retry-After`. +- Assertions enforce request validity in [`checks_service.dart`](lib/src/common/checks_service.dart); production builds can disable them, so invalid payloads can be sent. + +### Models and generation +- [`lib/src/common/model/users.dart`](lib/src/common/model/users.dart) models GitHub’s `hireable` field as `hirable` without a `JsonKey`, so it neither reads nor writes the specified field. +- Most generated models make required OpenAPI properties nullable and mutable. Strict casts are disabled in [`analysis_options.yaml`](analysis_options.yaml), increasing runtime failures and hiding type drift. +- [`tool/process_github_schema.dart`](tool/process_github_schema.dart) is not a complete OpenAPI generator: it ignores `$ref`, required properties, enums, formats, additional properties, discriminators, constraints, operation definitions, and general unions; it maps unions to `Object` and cannot safely establish conformance. +- Checked-in `*.g.dart` output has no CI regeneration/diff gate. Only a small fraction of the 26 model files has focused serialization tests, and strict generated casts are brittle when GitHub adds enum values or varies integer representations. + +### Tests and maintainability +- The repository has only 16 conventional `*_test.dart` files across transport, services, hooks, and models. Users, pulls, gists, activity, search, OAuth, pagination, and URL-shortener behavior lack adequate focused coverage. +- [`test/scenarios_test.dart`](test/scenarios_test.dart) has 22 scenarios, 21 skipped placeholders, and only one substantive scenario. Default CI does not run the scenario preset. +- [`test/helper/http.dart`](test/helper/http.dart) contains invalid decoded-map casts and calls `jsonDecode` on an already decoded Map/List, making fixture behavior unreliable. +- CI tests VM behavior but not the browser support claimed by [`README.md`](README.md); it has no coverage ratchet, OpenAPI contract gate, generated-code drift check, or dependency vulnerability scan. +- Public models/utilities expose legacy helpers and stale TODOs, while docs and examples do not state supported-operation coverage or compatibility guarantees. + +## Implementation workstreams + +### 1. Establish a reproducible specification baseline +- Create [`tool/spec/github-openapi.lock.json`](tool/spec/github-openapi.lock.json) containing repository, API calendar version, upstream commit SHA, artifact path, SHA-256, OpenAPI version, and generator schema version. Do not commit the 12.9 MB upstream artifact. +- Add focused code under [`tool/src/openapi`](tool/src/openapi) for download/cache loading, `$ref` resolution, deterministic normalization, semantic diffing, and report rendering; expose it through [`tool/spec_sync.dart`](tool/spec_sync.dart) with `--check`, `--update`, `--offline`, and `--report-json` modes. +- Commit a compact generated catalog at [`lib/src/common/generated/rest_contracts.g.dart`](lib/src/common/generated/rest_contracts.g.dart) containing operation ID, method, URI template, parameter locations, request media types, and successful/error response codes. +- Add [`tool/spec/bindings.yaml`](tool/spec/bindings.yaml), mapping every currently supported public method to an OpenAPI `operationId`; explicit states are `supported`, `partial`, `deprecated`, and `unsupported`. Generate [`docs/api-coverage.md`](docs/api-coverage.md) with per-tag totals, mapped operations, known partials, and drift. Coverage is measured, not inferred from the roughly 150 current request call sites. +- Reject duplicate operation bindings, unknown operation IDs, unpinned downloads, digest mismatches, unresolved references needed by bound operations, and nondeterministic output. + +### 2. Fix credential and webhook security first +- Refactor [`GitHub.request`](lib/src/common/github.dart) to send credentials only to the configured API origin and explicitly configured upload origins. Reject insecure HTTP for authenticated requests unless an opt-in enterprise-development policy is supplied; strip auth on cross-origin redirects and pagination links. +- Deprecate/remove [`UrlShortenerService`](lib/src/common/url_shortener_service.dart) and ensure no compatibility shim sends GitHub credentials or uses HTTP. +- Add a webhook configuration/verifier under [`lib/src/server`](lib/src/server) requiring a secret, constant-time HMAC-SHA256 validation, configurable maximum body size, content-type/event/delivery validation, structured 400/401/405/413 responses, and awaitable start/close lifecycle. Add replay-detection hooks without forcing storage policy on consumers. +- Deprecate query-string credential loading in [`xplat_browser.dart`](lib/src/browser/xplat_browser.dart); retain explicit token construction and, if needed, session storage only behind opt-in APIs with warnings. +- Add threat-model regression tests proving tokens are absent on arbitrary URLs, redirects, untrusted Link headers, URL-shortener requests, exception strings, and logs. + +### 3. Introduce a typed, injectable transport behind compatibility APIs +- Split request concerns from [`github.dart`](lib/src/common/github.dart) into focused internal units such as [`request.dart`](lib/src/common/transport/request.dart), [`transport.dart`](lib/src/common/transport/transport.dart), [`error_decoder.dart`](lib/src/common/transport/error_decoder.dart), and [`retry_policy.dart`](lib/src/common/transport/retry_policy.dart). +- Define request descriptors with method, URI template/parameters, encoded JSON or bytes body, accepted success statuses, media type, authentication policy, and response decoder. Build URLs with `Uri`, preserving GitHub’s `x-multi-segment` path behavior where the spec marks it. +- Inject `http.Client`, clock, delay/sleeper, retry policy, and randomness. Keep existing `getJSON`/`postJSON`/`request` wrappers, but route them through the new implementation and deprecate unsafe dynamic-body/full-URL forms. +- Replace assertions with runtime `ArgumentError`/domain validation. Add typed errors preserving status, method, URI, request ID, rate-limit metadata, parsed GitHub message/errors, and a safely truncated response body with credentials redacted. +- Retry only idempotent operations by default; honor `Retry-After` and rate-limit headers, use bounded exponential backoff with jitter, propagate the final error, and support cancellation/timeouts. + +### 4. Repair all bound service operations against generated contracts +- First land table-driven failing tests for every currently bound service method, then correct HTTP method, path, parameter location/name, required body, content type, success set, pagination shape, and decoder. +- Include all verified defects listed above and run a generated audit over every service in [`lib/src/common`](lib/src/common), not only the known examples. Every service call must reference its generated operation descriptor or be explicitly marked as non-REST/deprecated. +- Replace stale documentation links with URLs derived from operation IDs. Remove obsolete preview headers only when the pinned contract confirms general availability. +- Preserve method signatures where possible. Add deprecations and compatibility adapters where corrected types or behavior would otherwise break callers; collect unavoidable breaking changes for a separately reviewed next-major proposal. + +### 5. Make models schema-aware and forward-compatible +- Fix verified wire-name/type defects, beginning with `hireable`, and add golden round-trip tests from official schema examples/fixtures. +- Generate schema metadata and serializers only for bound operations initially. Represent required versus optional versus explicitly nullable distinctly; retain unknown enum values and, where valuable, unknown response fields for forward compatibility. +- Keep hand-authored ergonomic domain classes where they add value, with explicit adapters to generated wire DTOs. Do not replace the complete public model layer in one release. +- Enable `strict-casts`, then `strict-inference`/`strict-raw-types` in staged PRs. Add per-model fixes rather than broad ignores. +- Add a build-runner drift gate and retire or sharply narrow [`process_github_schema.dart`](tool/process_github_schema.dart) after the new parser covers its legitimate use cases. + +### 6. Build a contract-driven test pyramid +- Add transport unit tests under [`test/unit/transport`](test/unit/transport) for URI encoding, body formats, headers, status sets, redaction, retries, rate limits, redirects, cancellation, empty bodies, malformed/non-JSON errors, and cross-origin auth. +- Add generated operation contract tests under [`test/contract`](test/contract) that capture each service request and compare it with the pinned descriptor. Generate valid/minimal and edge-case schema fixtures for bound operations; keep deterministic snapshots reviewable. +- Add serialization tests under [`test/unit/common/model`](test/unit/common/model), webhook security tests under [`test/server`](test/server), and browser authentication tests compiled/run on Chrome. +- Repair [`test/helper/http.dart`](test/helper/http.dart). Replace skipped scenario placeholders with executable fixtures in prioritized service batches; keep a small opt-in live smoke suite that never deletes user resources and uses a dedicated repository. +- Measure line/branch coverage, establish the current baseline, require no decrease globally, and set higher floors for new transport/spec-sync code. Avoid arbitrary sleep-based tests by using injected clocks/schedulers. + +### 7. Add continuous spec-sync PR automation +- Add [`.github/workflows/spec_sync.yml`](.github/workflows/spec_sync.yml), scheduled weekly and manually dispatchable. It resolves upstream `main`, downloads only the stable bundled artifact, verifies its digest/shape/size limits, and treats all upstream descriptions as untrusted data—never executable templates or commands. +- On no semantic or source-revision change, exit successfully without commits. On change, update the lock, catalog, coverage report, generated tests/models, and a machine-readable semantic diff classifying additions, removals, method/path changes, parameter/body changes, response changes, and schema compatibility risk. +- Run `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos`, VM and browser tests, contract checks, build-runner drift checks, vulnerability scanning, and `dart pub publish --dry-run` before pushing. +- Maintain one idempotent `automation/github-openapi-2022-11-28` branch/PR. The PR body must include old/new upstream SHAs and digests, categorized API changes, generated-file summary, coverage delta, failing/manual bindings, and reproduction commands. Label breaking/removal/ambiguous changes for mandatory maintainer review; never auto-merge or auto-publish. +- Prefer the repository `GITHUB_TOKEN` with explicit `contents: write` and `pull-requests: write` only if pre-PR validation is sufficient. If required checks must run on the PR head, use a dedicated least-privilege GitHub App; do not introduce a broad PAT or `pull_request_target` execution. + +### 8. Harden CI, releases, and documentation +- Update [`dart.yml`](.github/workflows/dart.yml) to include minimum/stable Dart, VM/browser checks, generated/spec drift, coverage ratchet, and dependency/OSV scanning. Give every workflow explicit minimal permissions, pin third-party actions by full commit SHA, and add Dependabot coverage for workflow and Dart dependencies. +- Replace the long-lived release token in [`create_release.yml`](.github/workflows/create_release.yml) with least-privilege `GITHUB_TOKEN`/OIDC-supported flows and gate tags/releases on the same full validation suite. +- Update [`README.md`](README.md), [`CONTRIBUTING.md`](CONTRIBUTING.md), and [`test/README.md`](test/README.md) with the compatibility policy, measured support matrix, local spec-sync commands, fixture/live-test safety, generated-file ownership, security reporting, and automated-PR review procedure. + +## Verification and acceptance gates +- A test proves authenticated requests cannot leak credentials to `git.io`, arbitrary absolute URLs, redirects, or untrusted pagination links. +- Signed webhooks succeed; unsigned, invalid, oversized, malformed, and replay-flagged deliveries fail deterministically and close responses. +- Every supported public service method has a unique valid OpenAPI operation binding and a passing request/response contract test; partial operations are visible in the coverage report. +- All known HTTP-method/body-location/decoder defects are reproduced by failing tests before fixes and pass afterward. +- `dart run tool/spec_sync.dart --check --offline` is deterministic and leaves no diff; changing the pinned artifact produces a categorized semantic report. +- Scheduled sync is idempotent, opens or updates one review-only PR, no-ops when unchanged, and cannot publish a package. +- VM, Chrome, analyzer strictness, formatting, generated drift, coverage ratchet, vulnerability scan, and publish dry-run all pass on the minimum supported Dart and stable Dart. + +## Delivery sequence +Land separate reviewable PRs in this order: (1) security regressions and fixes, (2) OpenAPI lock/catalog/report tooling, (3) typed transport, (4) service contract repairs by service group, (5) model/serializer migration by bound operation, (6) browser/scenario coverage, (7) spec-sync automation, and (8) release/docs hardening. Each PR must preserve a green compatibility suite and may raise—but never silently lower—the conformance baseline. \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index b04944df..258bd20f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,6 +7,7 @@ environment: sdk: ^3.5.0 dependencies: + crypto: ^3.0.3 http: ^1.0.0 http_parser: ^4.0.0 json_annotation: ^4.9.0 @@ -17,6 +18,7 @@ dev_dependencies: build_test: ">=2.1.2 <4.0.0" build_web_compilers: '>=3.2.6 < 5.0.0' collection: ^1.15.0 + dart_style: ^3.0.0 dependency_validator: ">=3.0.0 <6.0.0" json_serializable: ^6.6.1 lints: ">=5.0.0 <7.0.0" diff --git a/test/README.md b/test/README.md index c05bf247..00eb1f60 100644 --- a/test/README.md +++ b/test/README.md @@ -1,9 +1,25 @@ -# Integration Tests +# Integration and Live Tests -The integration tests will run against the live GitHub API. These tests will -verify that the library is properly coded against the actual behavior of the -GitHub API. +## Unit and Contract Tests +All unit tests, contract tests, security tests, and model tests run offline without external dependencies: + +```bash +dart test +``` + +## Safe Live Smoke Tests + +Safe read-only smoke tests are located in `test/live/smoke_test.dart`. +These tests only perform safe, non-destructive read operations against public GitHub endpoints: + +```bash +GITHUB_LIVE_SMOKE=1 dart test test/live/smoke_test.dart +``` + +## Destructive Integration Tests + +The legacy integration tests run against the live GitHub API with write operations. To run these tests a GitHub repository and OAuth token will need to be defined in the `config/config.dart` file. diff --git a/test/common/github_test.dart b/test/common/github_test.dart index 97ce2930..326fe5d7 100644 --- a/test/common/github_test.dart +++ b/test/common/github_test.dart @@ -15,7 +15,8 @@ void main() { }); final github = GitHub(client: client); - await github.getJSON(''); // Make HTTP request + await github.getJSON, Map>( + ''); // Make HTTP request expect(request, isNotNull); expect(request!.headers.containsKey(GitHub.versionHeader), isTrue); @@ -31,7 +32,8 @@ void main() { }); final github = GitHub(client: client); - await github.getJSON(''); // Make HTTP request + await github.getJSON, Map>( + ''); // Make HTTP request expect(request, isNotNull); expect(request!.headers.containsKey('User-Agent'), isTrue); @@ -50,7 +52,8 @@ void main() { client: client, auth: const Authentication.anonymous(), ); - await github.getJSON(''); // Make HTTP request + await github.getJSON, Map>( + ''); // Make HTTP request expect(request, isNotNull); expect(request!.headers.containsKey('Authorization'), isFalse); diff --git a/test/contract/service_contracts_test.dart b/test/contract/service_contracts_test.dart new file mode 100644 index 00000000..dbab2869 --- /dev/null +++ b/test/contract/service_contracts_test.dart @@ -0,0 +1,339 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:github/github.dart'; +import 'package:http/http.dart' as http; +import 'package:http/testing.dart'; +import 'package:test/test.dart'; +import 'package:yaml/yaml.dart'; + +void main() { + group('OpenAPI Bindings Manifest Integrity', () { + test('all bindings in bindings.yaml resolve to valid RestContracts', () { + final file = File('tool/spec/bindings.yaml'); + expect(file.existsSync(), isTrue); + + final yaml = loadYaml(file.readAsStringSync()) as Map; + final bindings = yaml['bindings'] as List; + expect(bindings, isNotEmpty); + + for (final binding in bindings) { + final opId = binding['operationId'] as String; + final contract = RestContracts.all[opId]; + expect( + contract, + isNotNull, + reason: 'Binding operationId "$opId" must exist in RestContracts.all', + ); + } + }); + }); + + group('Service Method Contract Conformance', () { + late http.Request lastRequest; + late GitHub github; + + void interceptWithResponse(http.Response response) { + github = GitHub( + client: MockClient((req) async { + lastRequest = req; + return response; + }), + ); + } + + tearDown(() { + github.dispose(); + }); + + test('activity star conforms to activity/star-repo-for-authenticated-user', + () async { + final contract = + RestContracts.all['activity/star-repo-for-authenticated-user']!; + interceptWithResponse(http.Response('', 204)); + + await github.activity.star(RepositorySlug('octocat', 'hello-world')); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.url.path, equals('/user/starred/octocat/hello-world')); + expect(contract.successStatuses, contains(204)); + }); + + test( + 'activity unstar conforms to activity/unstar-repo-for-authenticated-user', + () async { + final contract = + RestContracts.all['activity/unstar-repo-for-authenticated-user']!; + interceptWithResponse(http.Response('', 204)); + + await github.activity.unstar(RepositorySlug('octocat', 'hello-world')); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.url.path, equals('/user/starred/octocat/hello-world')); + }); + + test('activity getThread conforms to activity/get-thread', () async { + final contract = RestContracts.all['activity/get-thread']!; + interceptWithResponse(http.Response( + jsonEncode({'id': '123', 'unread': false}), + 200, + headers: {'content-type': 'application/json'}, + )); + + await github.activity.getThread('123'); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.url.path, equals('/notifications/threads/123')); + }); + + test('gists star conforms to gists/star', () async { + final contract = RestContracts.all['gists/star']!; + interceptWithResponse(http.Response('', 204)); + + final res = await github.gists.starGist('g123'); + expect(res, isTrue); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.url.path, equals('/gists/g123/star')); + }); + + test('gists update conforms to gists/update (PATCH)', () async { + final contract = RestContracts.all['gists/update']!; + interceptWithResponse(http.Response( + jsonEncode({'id': 'g123', 'description': 'Updated'}), + 200, + headers: {'content-type': 'application/json'}, + )); + + await github.gists.editGist('g123', description: 'Updated'); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.method, equals('PATCH')); + expect(lastRequest.url.path, equals('/gists/g123')); + }); + + test('gists createComment conforms to gists/create-comment (201)', + () async { + final contract = RestContracts.all['gists/create-comment']!; + interceptWithResponse(http.Response( + jsonEncode({'id': 1, 'body': 'test comment'}), + 201, + headers: {'content-type': 'application/json'}, + )); + + await github.gists + .createComment('g123', CreateGistComment('test comment')); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.url.path, equals('/gists/g123/comments')); + expect(contract.successStatuses, contains(201)); + }); + + test('git updateRef conforms to git/update-ref (PATCH)', () async { + final contract = RestContracts.all['git/update-ref']!; + interceptWithResponse(http.Response( + jsonEncode({ + 'ref': 'refs/heads/master', + 'object': {'sha': 'abc'} + }), + 200, + headers: {'content-type': 'application/json'}, + )); + + await github.git.editReference( + RepositorySlug('octocat', 'hello-world'), + 'refs/heads/master', + 'abc', + ); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.method, equals('PATCH')); + expect(lastRequest.url.path, + equals('/repos/octocat/hello-world/git/refs/heads/master')); + }); + + test('git getTree with recursive query conforms to git/get-tree', () async { + final contract = RestContracts.all['git/get-tree']!; + interceptWithResponse(http.Response( + jsonEncode({'sha': 'sha123', 'tree': [], 'truncated': false}), + 200, + headers: {'content-type': 'application/json'}, + )); + + await github.git.getTree( + RepositorySlug('octocat', 'hello-world'), + 'sha123', + recursive: true, + ); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.url.path, + equals('/repos/octocat/hello-world/git/trees/sha123')); + expect(lastRequest.url.queryParameters['recursive'], equals('1')); + }); + + test('issues lock conforms to issues/lock (PUT / lock reason)', () async { + final contract = RestContracts.all['issues/lock']!; + interceptWithResponse(http.Response('', 204)); + + await github.issues.lock( + RepositorySlug('octocat', 'hello-world'), + 42, + lockReason: 'resolved', + ); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.method, equals('PUT')); + expect(lastRequest.url.path, + equals('/repos/octocat/hello-world/issues/42/lock')); + final body = jsonDecode(lastRequest.body) as Map; + expect(body['lock_reason'], equals('resolved')); + }); + + test('issues isAssignee conforms to issues/check-user-can-be-assigned', + () async { + final contract = RestContracts.all['issues/check-user-can-be-assigned']!; + interceptWithResponse(http.Response('', 204)); + + final res = await github.issues + .isAssignee(RepositorySlug('octocat', 'hello-world'), 'octocat'); + expect(res, isTrue); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.url.path, + equals('/repos/octocat/hello-world/assignees/octocat')); + }); + + test('issues replaceLabelsForIssue returns List', () async { + final contract = RestContracts.all['issues/set-labels']!; + interceptWithResponse(http.Response( + jsonEncode([ + {'name': 'bug', 'color': 'f29513'} + ]), + 200, + headers: {'content-type': 'application/json'}, + )); + + final labels = await github.issues.replaceLabelsForIssue( + RepositorySlug('octocat', 'hello-world'), + 42, + ['bug'], + ); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.method, equals('PUT')); + expect(lastRequest.url.path, + equals('/repos/octocat/hello-world/issues/42/labels')); + expect(labels, isA>()); + expect(labels.length, equals(1)); + expect(labels.first.name, equals('bug')); + }); + + test('teams editTeam conforms to teams/update-legacy (PATCH)', () async { + final contract = RestContracts.all['teams/update-legacy']!; + interceptWithResponse(http.Response( + jsonEncode({'id': 123, 'name': 'Core Team'}), + 200, + headers: {'content-type': 'application/json'}, + )); + + await github.organizations.editTeam(123, 'Core Team'); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.method, equals('PATCH')); + expect(lastRequest.url.path, equals('/teams/123')); + }); + + test('teams editTeamInOrg conforms to teams/update-in-org (PATCH)', + () async { + final contract = RestContracts.all['teams/update-in-org']!; + interceptWithResponse(http.Response( + jsonEncode({'id': 123, 'name': 'Core Team', 'slug': 'core-team'}), + 200, + headers: {'content-type': 'application/json'}, + )); + + await github.organizations + .editTeamInOrg('my-org', 'core-team', name: 'Core Team'); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.method, equals('PATCH')); + expect(lastRequest.url.path, equals('/orgs/my-org/teams/core-team')); + }); + + test( + 'repos createDispatchEvent conforms to repos/create-dispatch-event (204)', + () async { + final contract = RestContracts.all['repos/create-dispatch-event']!; + interceptWithResponse(http.Response('', 204)); + + await github.repositories.createDispatchEvent( + RepositorySlug('octocat', 'hello-world'), + 'custom_event', + clientPayload: {'run_id': 123}, + ); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.url.path, + equals('/repos/octocat/hello-world/dispatches')); + final body = jsonDecode(lastRequest.body) as Map; + expect(body['event_type'], equals('custom_event')); + expect(body['client_payload']['run_id'], equals(123)); + }); + + test('repos listTopics conforms to repos/get-all-topics', () async { + final contract = RestContracts.all['repos/get-all-topics']!; + interceptWithResponse(http.Response( + jsonEncode({ + 'names': ['dart', 'github-api'] + }), + 200, + headers: {'content-type': 'application/json'}, + )); + + final topics = await github.repositories + .listTopics(RepositorySlug('octocat', 'hello-world')); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.url.path, equals('/repos/octocat/hello-world/topics')); + expect(topics, equals(['dart', 'github-api'])); + }); + + test('repos replaceTopics conforms to repos/replace-all-topics', () async { + final contract = RestContracts.all['repos/replace-all-topics']!; + interceptWithResponse(http.Response( + jsonEncode({ + 'names': ['dart', 'api'] + }), + 200, + headers: {'content-type': 'application/json'}, + )); + + final topics = await github.repositories.replaceTopics( + RepositorySlug('octocat', 'hello-world'), + ['dart', 'api'], + ); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.method, equals('PUT')); + expect(lastRequest.url.path, equals('/repos/octocat/hello-world/topics')); + expect(topics, equals(['dart', 'api'])); + }); + + test('misc listGitignoreTemplates conforms to gitignore/get-all-templates', + () async { + final contract = RestContracts.all['gitignore/get-all-templates']!; + interceptWithResponse(http.Response( + jsonEncode(['Dart', 'Go', 'Rust']), + 200, + headers: {'content-type': 'application/json'}, + )); + + final templates = await github.misc.listGitignoreTemplates(); + + expect(lastRequest.method, equals(contract.method)); + expect(lastRequest.url.path, equals('/gitignore/templates')); + expect(templates, equals(['Dart', 'Go', 'Rust'])); + }); + }); +} diff --git a/test/data_object_test.dart b/test/data_object_test.dart index f1d1d5db..df5607ba 100644 --- a/test/data_object_test.dart +++ b/test/data_object_test.dart @@ -41,4 +41,4 @@ void main() { }); } -String _prettyEncode(obj) => GitHubJson.encode(obj, indent: ' '); +String _prettyEncode(Object obj) => GitHubJson.encode(obj, indent: ' '); diff --git a/test/experiment/org_hooks.dart b/test/experiment/org_hooks.dart index 9e0d79f8..0598a014 100644 --- a/test/experiment/org_hooks.dart +++ b/test/experiment/org_hooks.dart @@ -1,7 +1,7 @@ import 'dart:async'; import '../helper.dart'; -Future main() async { +Future main() async { const org = 'IOT-DSA'; final hooks = await github.organizations.listHooks(org).toList(); diff --git a/test/experiment/orglist.dart b/test/experiment/orglist.dart index 01aa4c6c..d0a18105 100644 --- a/test/experiment/orglist.dart +++ b/test/experiment/orglist.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:github/github.dart'; -Future main() async { +Future main() async { final github = GitHub(); final repos = await github.repositories.listUserRepositories('dart-lang').toList(); diff --git a/test/git_test.dart b/test/git_test.dart index e95ef5d6..6f145b26 100644 --- a/test/git_test.dart +++ b/test/git_test.dart @@ -11,7 +11,8 @@ GitHub createGithub() { return GitHub( endpoint: fakeApiUrl, auth: const Authentication.withToken( - '0000000000000000000000000000000000000001')); + '0000000000000000000000000000000000000001'), + allowInsecureAuth: true); } void main() { @@ -96,8 +97,9 @@ void main() { }); test('deleteReference()', () async { - nock(fakeApiUrl).delete('/repos/o/n/git/refs/heads/b').reply(200, '{}'); - await git.deleteReference(repo, 'heads/b'); + nock(fakeApiUrl).delete('/repos/o/n/git/refs/heads/b').reply(204, ''); + final res = await git.deleteReference(repo, 'heads/b'); + expect(res, isTrue); }); test('getTag()', () async { diff --git a/test/helper/http.dart b/test/helper/http.dart index ffed40d4..8b576526 100644 --- a/test/helper/http.dart +++ b/test/helper/http.dart @@ -32,16 +32,16 @@ class MockResponse extends http.Response { final responseData = jsonDecode(asset('responses/$name.json').readAsStringSync()) as Map; - final headers = responseData['headers'] as Map; + final headers = (responseData['headers'] as Map).cast(); final dynamic body = responseData['body']; - final int statusCode = responseData['statusCode']; + final statusCode = responseData['statusCode'] as int; String? actualBody; if (body is Map || body is List) { - actualBody = jsonDecode(body); + actualBody = jsonEncode(body); } else { actualBody = body.toString(); } - return MockResponse(actualBody!, headers, statusCode); + return MockResponse(actualBody, headers, statusCode); } } diff --git a/test/live/smoke_test.dart b/test/live/smoke_test.dart new file mode 100644 index 00000000..8fe46813 --- /dev/null +++ b/test/live/smoke_test.dart @@ -0,0 +1,57 @@ +import 'dart:io'; + +import 'package:github/github.dart'; +import 'package:test/test.dart'; + +/// Opt-in safe live smoke test suite. +/// +/// Runs only when GITHUB_TOKEN or GITHUB_LIVE_SMOKE=1 is set in the environment. +/// Executes only safe, non-destructive read operations against public GitHub endpoints. +void main() { + final hasToken = Platform.environment.containsKey('GITHUB_TOKEN') || + Platform.environment['GITHUB_LIVE_SMOKE'] == '1'; + + group('Live GitHub API Smoke Tests (Read-Only)', () { + late GitHub github; + + setUp(() { + final token = Platform.environment['GITHUB_TOKEN']; + github = GitHub( + auth: token != null + ? Authentication.withToken(token) + : const Authentication.anonymous(), + ); + }); + + tearDown(() { + github.dispose(); + }); + + test('fetches public repository metadata', () async { + final repo = await github.repositories + .getRepository(RepositorySlug('octocat', 'Hello-World')); + + expect(repo.name, equals('Hello-World')); + expect(repo.owner?.login, equals('octocat')); + }); + + test('fetches API status from status endpoint', () async { + final status = await github.misc.getApiStatus(); + expect(status.status, isNotNull); + expect(status.status?.indicator, isNotNull); + }); + + test('fetches zen message', () async { + final zen = await github.misc.getZen(); + expect(zen, isNotEmpty); + }); + + test('fetches gitignore templates list', () async { + final templates = await github.misc.listGitignoreTemplates(); + expect(templates, contains('Dart')); + }); + }, + skip: !hasToken + ? 'Skipped: Set GITHUB_TOKEN or GITHUB_LIVE_SMOKE=1 to run safe live tests.' + : null); +} diff --git a/test/scenarios_test.dart b/test/scenarios_test.dart index fb453845..5d59b274 100644 --- a/test/scenarios_test.dart +++ b/test/scenarios_test.dart @@ -26,11 +26,12 @@ Future createGithubWithScenario(String scenario, throw Exception( 'Error loading scenario: $scenario\n${resp.statusCode}\n${resp.body}'); } - var j = json.decode(resp.body); + var j = json.decode(resp.body) as Map; return GitHub( - endpoint: j['url'], + endpoint: j['url'] as String, auth: const Authentication.withToken( - '0000000000000000000000000000000000000001')); + '0000000000000000000000000000000000000001'), + allowInsecureAuth: true); } /// Run scenario tests against ockokits fixtures-server diff --git a/test/unit/browser_auth_test.dart b/test/unit/browser_auth_test.dart new file mode 100644 index 00000000..3f45ca61 --- /dev/null +++ b/test/unit/browser_auth_test.dart @@ -0,0 +1,37 @@ +@TestOn('chrome') +library; + +// ignore: deprecated_member_use +import 'dart:html'; + +import 'package:github/src/browser/xplat_browser.dart'; +import 'package:test/test.dart'; + +void main() { + group('Browser Authentication', () { + tearDown(() { + window.sessionStorage.clear(); + }); + + test('loads token from sessionStorage by default', () { + window.sessionStorage['GITHUB_TOKEN'] = 'session-pat-12345'; + final auth = findAuthenticationFromEnvironment(); + expect(auth.isAnonymous, isFalse); + expect(auth.token, equals('session-pat-12345')); + }); + + test('ignores query string by default even if present in URL', () { + // By default allowQueryAuth is false + final auth = findAuthenticationFromEnvironment(); + // Unless present in sessionStorage, it should default to anonymous + expect(auth.isAnonymous, isTrue); + }); + + test('returns anonymous auth when neither sessionStorage nor query present', + () { + window.sessionStorage.clear(); + final auth = findAuthenticationFromEnvironment(); + expect(auth.isAnonymous, isTrue); + }); + }); +} diff --git a/test/unit/checks_test.dart b/test/unit/checks_test.dart index 2eb7e6c4..222a7683 100644 --- a/test/unit/checks_test.dart +++ b/test/unit/checks_test.dart @@ -98,7 +98,7 @@ const checkRunJson = '''{ }'''; const String expectedToString = - '{"name":"mighty_readme","id":4,"external_id":"","status":"completed","head_sha":"","check_suite":{"id":5},"details_url":"https://example.com","started_at":"2018-05-04T01:14:52.000Z","conclusion":"neutral"}'; + '{"name":"mighty_readme","id":4,"external_id":"","status":"completed","head_sha":"ce587453ced02b1526dfb4cb910479d431683101","check_suite":{"id":5},"details_url":"https://example.com","started_at":"2018-05-04T01:14:52.000Z","conclusion":"neutral"}'; const String newCheckRun = '{"name":"New CheckRun","id":12345,"external_id":"","status":"queued","head_sha":"","check_suite":{"id":123456},"details_url":"https://example.com","started_at":"2024-12-05T01:05:24.000Z","conclusion":"null"}'; @@ -106,7 +106,8 @@ const String newCheckRun = void main() { group('Check run', () { test('CheckRun fromJson', () { - final checkRun = CheckRun.fromJson(jsonDecode(checkRunJson)); + final checkRun = + CheckRun.fromJson(jsonDecode(checkRunJson) as Map); expect(checkRun.id, 4); expect(checkRun.name, 'mighty_readme'); @@ -114,7 +115,8 @@ void main() { }); test('CheckRun from freshly created and encoded', () { - final checkRun = CheckRun.fromJson(jsonDecode(newCheckRun)); + final checkRun = + CheckRun.fromJson(jsonDecode(newCheckRun) as Map); expect(checkRun.id, 12345); expect(checkRun.name, 'New CheckRun'); @@ -215,7 +217,8 @@ void main() { } ] }'''; - final checkRun = CheckRun.fromJson(jsonDecode(checkRunJson)); + final checkRun = + CheckRun.fromJson(jsonDecode(checkRunJson) as Map); expect(checkRun.id, 10); expect(checkRun.name, 'mighty_readme'); @@ -224,7 +227,8 @@ void main() { test('CheckRun toString', () { // indirectly tests the toJson method as well. - final checkRun = CheckRun.fromJson(jsonDecode(checkRunJson)); + final checkRun = + CheckRun.fromJson(jsonDecode(checkRunJson) as Map); expect(checkRun, isNotNull); final checkRunString = checkRun.toString(); expect(checkRunString, isNotNull); diff --git a/test/unit/checksuite_test.dart b/test/unit/checksuite_test.dart index d9571bc9..c3911e1c 100644 --- a/test/unit/checksuite_test.dart +++ b/test/unit/checksuite_test.dart @@ -45,7 +45,8 @@ const String expectedToString = void main() { group('Check suite', () { test('CheckSuite fromJson', () { - final checkSuite = CheckSuite.fromJson(jsonDecode(checkSuiteJson)); + final checkSuite = CheckSuite.fromJson( + jsonDecode(checkSuiteJson) as Map); expect(checkSuite.id, 5); expect(checkSuite.headBranch, 'main'); @@ -90,7 +91,8 @@ void main() { } ] }'''; - final checkSuite = CheckSuite.fromJson(jsonDecode(checkSuiteJson)); + final checkSuite = CheckSuite.fromJson( + jsonDecode(checkSuiteJson) as Map); expect(checkSuite.id, 10); expect(checkSuite.headBranch, 'master'); @@ -111,7 +113,8 @@ void main() { "conclusion": "skipped", "pull_requests": [] }'''; - final checkSuite = CheckSuite.fromJson(jsonDecode(checkSuiteJson)); + final checkSuite = CheckSuite.fromJson( + jsonDecode(checkSuiteJson) as Map); expect(checkSuite.id, 10); expect(checkSuite.headBranch, null); diff --git a/test/unit/common/model/misc_test.dart b/test/unit/common/model/misc_test.dart index a7cbf3c2..c529d5da 100644 --- a/test/unit/common/model/misc_test.dart +++ b/test/unit/common/model/misc_test.dart @@ -47,8 +47,8 @@ void main() { "used": 1 } }'''; - final rateLimit = - RateLimit.fromRateLimitResponse(jsonDecode(rateLimitJson)); + final rateLimit = RateLimit.fromRateLimitResponse( + jsonDecode(rateLimitJson) as Map); expect(rateLimit.limit, 5000); expect(rateLimit.remaining, 4999); diff --git a/test/unit/common/model/pulls_test.dart b/test/unit/common/model/pulls_test.dart index f4d5fe65..0a1fce44 100644 --- a/test/unit/common/model/pulls_test.dart +++ b/test/unit/common/model/pulls_test.dart @@ -238,7 +238,8 @@ const String samplePullRequest = ''' void main() { group('Pull Request fromJson', () { test('Node ID is collected', () { - final pullRequest = PullRequest.fromJson(jsonDecode(samplePullRequest)); + final pullRequest = PullRequest.fromJson( + jsonDecode(samplePullRequest) as Map); expect(pullRequest, isNotNull); expect(pullRequest.nodeId, "PR_kwDOA8VHis5QItg_"); }); diff --git a/test/unit/issues_test.dart b/test/unit/issues_test.dart index 512d83a3..9bc222ef 100644 --- a/test/unit/issues_test.dart +++ b/test/unit/issues_test.dart @@ -53,8 +53,8 @@ const String testIssueCommentJson = ''' void main() { group('Issue Comments', () { test('IssueComment from Json', () { - final issueComment = - IssueComment.fromJson(jsonDecode(testIssueCommentJson)); + final issueComment = IssueComment.fromJson( + jsonDecode(testIssueCommentJson) as Map); expect(1352355796, issueComment.id); expect('MEMBER', issueComment.authorAssociation); expect('CaseyHillers', issueComment.user!.login); diff --git a/test/unit/security_test.dart b/test/unit/security_test.dart new file mode 100644 index 00000000..84f6677c --- /dev/null +++ b/test/unit/security_test.dart @@ -0,0 +1,305 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:crypto/crypto.dart'; +import 'package:github/github.dart'; +import 'package:github/hooks.dart'; +import 'package:http/http.dart' as http; +import 'package:http/testing.dart'; +import 'package:test/test.dart'; + +void main() { + group('Security - Credential boundaries', () { + test('does not send Authorization header to untrusted absolute URL', + () async { + http.Request? capturedRequest; + final mockClient = MockClient((r) async { + capturedRequest = r; + return http.Response('{}', 200, + headers: {'content-type': 'application/json'}); + }); + + final gh = GitHub( + auth: const Authentication.withToken('super-secret-token'), + client: mockClient, + ); + + await gh.request('GET', 'https://attacker.example.com/exfiltrate'); + expect(capturedRequest, isNotNull); + expect(capturedRequest!.headers.containsKey('Authorization'), isFalse); + }); + + test('sends Authorization header to trusted endpoint origin', () async { + http.Request? capturedRequest; + final mockClient = MockClient((r) async { + capturedRequest = r; + return http.Response('{}', 200, + headers: {'content-type': 'application/json'}); + }); + + final gh = GitHub( + auth: const Authentication.withToken('super-secret-token'), + client: mockClient, + ); + + await gh.request('GET', '/user'); + expect(capturedRequest, isNotNull); + expect(capturedRequest!.headers['Authorization'], + 'token super-secret-token'); + }); + + test('sends Authorization header to trusted uploads origin', () async { + http.Request? capturedRequest; + final mockClient = MockClient((r) async { + capturedRequest = r; + return http.Response('{}', 200, + headers: {'content-type': 'application/json'}); + }); + + final gh = GitHub( + auth: const Authentication.withToken('super-secret-token'), + client: mockClient, + ); + + await gh.request('POST', + 'https://uploads.github.com/repos/org/repo/releases/1/assets'); + expect(capturedRequest, isNotNull); + expect(capturedRequest!.headers['Authorization'], + 'token super-secret-token'); + }); + + test('disallows authenticated requests over insecure HTTP by default', + () async { + final mockClient = MockClient((r) async => http.Response('{}', 200)); + + final gh = GitHub( + endpoint: 'http://api.github.com', + auth: const Authentication.withToken('super-secret-token'), + client: mockClient, + ); + + expect( + () => gh.request('GET', '/user'), + throwsA(isA().having( + (e) => e.message, + 'message', + contains('Insecure HTTP authentication is disallowed by default'), + )), + ); + }); + + test( + 'allows authenticated requests over HTTP when allowInsecureAuth is true', + () async { + http.Request? capturedRequest; + final mockClient = MockClient((r) async { + capturedRequest = r; + return http.Response('{}', 200, + headers: {'content-type': 'application/json'}); + }); + + final gh = GitHub( + endpoint: 'http://localhost:3000', + auth: const Authentication.withToken('local-token'), + client: mockClient, + allowInsecureAuth: true, + ); + + await gh.request('GET', '/user'); + expect(capturedRequest, isNotNull); + expect(capturedRequest!.headers['Authorization'], 'token local-token'); + }); + + test('UrlShortenerService does not leak GitHub credentials and uses HTTPS', + () async { + http.Request? capturedRequest; + final mockClient = MockClient((r) async { + capturedRequest = r; + return http.Response('{}', 201, headers: { + 'location': 'https://git.io/abcd', + 'content-type': 'application/json' + }); + }); + + final gh = GitHub( + auth: const Authentication.withToken('super-secret-token'), + client: mockClient, + ); + + // ignore: deprecated_member_use_from_same_package + final shortener = UrlShortenerService(gh); + final code = + // ignore: deprecated_member_use_from_same_package + await shortener.shortenUrl('https://github.com/SpinlockLabs'); + + expect(code, 'abcd'); + expect(capturedRequest, isNotNull); + expect(capturedRequest!.url.scheme, 'https'); + expect(capturedRequest!.url.host, 'git.io'); + expect(capturedRequest!.headers.containsKey('Authorization'), isFalse); + }); + }); + + group('Security - Webhook verification and hardening', () { + late HookServer server; + late int port; + + setUp(() async { + final socket = await ServerSocket.bind('127.0.0.1', 0); + port = socket.port; + await socket.close(); + }); + + tearDown(() async { + await server.stop(); + }); + + test('rejects non-POST methods with 405', () async { + server = HookServer(port, '127.0.0.1'); + await server.start(); + + final client = HttpClient(); + final req = await client.getUrl(Uri.parse('http://127.0.0.1:$port/hook')); + final res = await req.close(); + expect(res.statusCode, HttpStatus.methodNotAllowed); + final body = await utf8.decoder.bind(res).join(); + expect(jsonDecode(body)['error'], 'Method Not Allowed'); + client.close(); + }); + + test('rejects requests missing X-GitHub-Event header with 400', () async { + server = HookServer(port, '127.0.0.1'); + await server.start(); + + final client = HttpClient(); + final req = + await client.postUrl(Uri.parse('http://127.0.0.1:$port/hook')); + req.headers.contentType = ContentType.json; + req.write(jsonEncode({'action': 'created'})); + final res = await req.close(); + expect(res.statusCode, HttpStatus.badRequest); + final body = await utf8.decoder.bind(res).join(); + expect(jsonDecode(body)['error'], 'Bad Request'); + client.close(); + }); + + test( + 'rejects requests when secret configured and signature missing or invalid', + () async { + server = HookServer(port, '127.0.0.1', 'webhook-secret-key'); + await server.start(); + + final client = HttpClient(); + + // Missing signature + var req = await client.postUrl(Uri.parse('http://127.0.0.1:$port/hook')); + req.headers.set('X-GitHub-Event', 'issues'); + req.headers.contentType = ContentType.json; + req.write(jsonEncode({'action': 'opened'})); + var res = await req.close(); + expect(res.statusCode, HttpStatus.unauthorized); + + // Invalid signature + req = await client.postUrl(Uri.parse('http://127.0.0.1:$port/hook')); + req.headers.set('X-GitHub-Event', 'issues'); + req.headers.set('X-Hub-Signature-256', 'sha256=invalidhex0000'); + req.headers.contentType = ContentType.json; + req.write(jsonEncode({'action': 'opened'})); + res = await req.close(); + expect(res.statusCode, HttpStatus.unauthorized); + + client.close(); + }); + + test('accepts requests with valid HMAC-SHA256 signature', () async { + const secret = 'my-webhook-secret'; + server = HookServer(port, '127.0.0.1', secret); + await server.start(); + + HookEvent? receivedEvent; + server.onEvent.listen((e) => receivedEvent = e); + + final payload = jsonEncode({'action': 'opened'}); + final payloadBytes = utf8.encode(payload); + final hmac = Hmac(sha256, utf8.encode(secret)); + final signature = 'sha256=${hmac.convert(payloadBytes)}'; + + final client = HttpClient(); + final req = + await client.postUrl(Uri.parse('http://127.0.0.1:$port/hook')); + req.headers.set('X-GitHub-Event', 'issues'); + req.headers.set('X-Hub-Signature-256', signature); + req.headers.contentType = ContentType.json; + req.add(payloadBytes); + final res = await req.close(); + + expect(res.statusCode, HttpStatus.ok); + await Future.delayed(const Duration(milliseconds: 20)); + expect(receivedEvent, isA()); + expect((receivedEvent as IssueEvent).action, 'opened'); + client.close(); + }); + + test('rejects requests exceeding maxBodySize with 413', () async { + server = HookServer(port, '127.0.0.1', null, 50); // max 50 bytes + await server.start(); + + final client = HttpClient(); + final req = + await client.postUrl(Uri.parse('http://127.0.0.1:$port/hook')); + req.headers.set('X-GitHub-Event', 'issues'); + req.headers.contentType = ContentType.json; + req.write(jsonEncode({'action': 'a' * 100})); + final res = await req.close(); + + expect(res.statusCode, HttpStatus.requestEntityTooLarge); + client.close(); + }); + + test('rejects malformed JSON with 400', () async { + server = HookServer(port, '127.0.0.1'); + await server.start(); + + final client = HttpClient(); + final req = + await client.postUrl(Uri.parse('http://127.0.0.1:$port/hook')); + req.headers.set('X-GitHub-Event', 'issues'); + req.headers.contentType = ContentType.json; + req.write('{malformed json string...'); + final res = await req.close(); + + expect(res.statusCode, HttpStatus.badRequest); + client.close(); + }); + + test('detects replay attack when onReplayCheck returns false', () async { + final seenDeliveries = {}; + server = + HookServer(port, '127.0.0.1', null, 1024 * 1024, seenDeliveries.add); + await server.start(); + + final client = HttpClient(); + + // First delivery: succeeds + var req = await client.postUrl(Uri.parse('http://127.0.0.1:$port/hook')); + req.headers.set('X-GitHub-Event', 'issues'); + req.headers.set('X-GitHub-Delivery', 'delivery-uuid-1'); + req.headers.contentType = ContentType.json; + req.write(jsonEncode({'action': 'opened'})); + var res = await req.close(); + expect(res.statusCode, HttpStatus.ok); + + // Replay of same delivery ID: rejected with 409 + req = await client.postUrl(Uri.parse('http://127.0.0.1:$port/hook')); + req.headers.set('X-GitHub-Event', 'issues'); + req.headers.set('X-GitHub-Delivery', 'delivery-uuid-1'); + req.headers.contentType = ContentType.json; + req.write(jsonEncode({'action': 'opened'})); + res = await req.close(); + expect(res.statusCode, HttpStatus.conflict); + + client.close(); + }); + }); +} diff --git a/test/unit/spec_sync_test.dart b/test/unit/spec_sync_test.dart new file mode 100644 index 00000000..bb404d90 --- /dev/null +++ b/test/unit/spec_sync_test.dart @@ -0,0 +1,90 @@ +import 'dart:io'; + +import 'package:test/test.dart'; +import '../../tool/src/openapi/bindings_manifest.dart'; +import '../../tool/src/openapi/catalog_generator.dart'; +import '../../tool/src/openapi/coverage_reporter.dart'; +import '../../tool/src/openapi/semantic_diff.dart'; +import '../../tool/src/openapi/spec_loader.dart'; + +void main() { + group('Spec baseline & OpenAPI catalog', () { + test('loads pinned OpenAPI spec and resolves operations', () async { + final loader = await SpecLoader.loadFromLock(); + final operations = await loader.loadOperations(offline: true); + expect(operations.length, 1229); + + final opMap = {for (final op in operations) op.operationId: op}; + expect(opMap.containsKey('users/get-authenticated'), isTrue); + expect(opMap.containsKey('repos/get'), isTrue); + expect(opMap.containsKey('pulls/update'), isTrue); + expect(opMap['pulls/update']!.method, 'PATCH'); + }); + + test('validates bindings.yaml manifest against spec', () async { + final loader = await SpecLoader.loadFromLock(); + final operations = await loader.loadOperations(offline: true); + final validOperationIds = operations.map((o) => o.operationId).toSet(); + + final manifest = await BindingsManifest.loadFromFile(); + expect(manifest.bindings, isNotEmpty); + expect(() => manifest.validate(validOperationIds), returnsNormally); + }); + + test('detects semantic differences between specs', () async { + final loader = await SpecLoader.loadFromLock(); + final operations = await loader.loadOperations(offline: true); + + final diff = SemanticDiff.between(operations, operations); + expect(diff.hasChanges, isFalse); + expect(diff.isBreaking, isFalse); + }); + + test('catalog generation is deterministic', () async { + final loader = await SpecLoader.loadFromLock(); + final operations = await loader.loadOperations(offline: true); + + final gen = CatalogGenerator(operations); + final out1 = gen.generate(); + final out2 = gen.generate(); + expect(out1, equals(out2)); + }); + + test('catalog on disk matches generated catalog', () async { + final loader = await SpecLoader.loadFromLock(); + final operations = await loader.loadOperations(offline: true); + + final gen = CatalogGenerator(operations); + final generated = gen.generate(); + final file = File('lib/src/common/generated/rest_contracts.g.dart'); + expect(file.existsSync(), isTrue); + final onDisk = file.readAsStringSync(); + + final tempFile = File( + '.dart_tool/test_expected_catalog_${DateTime.now().millisecondsSinceEpoch}.dart'); + try { + tempFile.writeAsStringSync(generated); + Process.runSync(Platform.resolvedExecutable, ['format', tempFile.path]); + final formattedExpected = tempFile.readAsStringSync(); + expect(onDisk, equals(formattedExpected)); + } finally { + if (tempFile.existsSync()) { + tempFile.deleteSync(); + } + } + }); + + test('api coverage markdown on disk matches reporter', () async { + final loader = await SpecLoader.loadFromLock(); + final operations = await loader.loadOperations(offline: true); + final manifest = await BindingsManifest.loadFromFile(); + + final reporter = + CoverageReporter(operations: operations, manifest: manifest); + final expectedMarkdown = reporter.generateMarkdown(); + final file = File('docs/api-coverage.md'); + expect(file.existsSync(), isTrue); + expect(file.readAsStringSync(), equals(expectedMarkdown)); + }); + }); +} diff --git a/test/unit/transport_test.dart b/test/unit/transport_test.dart new file mode 100644 index 00000000..ef71128f --- /dev/null +++ b/test/unit/transport_test.dart @@ -0,0 +1,445 @@ +import 'dart:convert'; +import 'package:github/github.dart'; +import 'package:http/http.dart' as http; +import 'package:http/testing.dart'; +import 'package:test/test.dart'; + +void main() { + group('HttpTransport URI and Query Resolution', () { + late GitHub github; + + setUp(() { + github = GitHub(); + }); + + tearDown(() { + github.dispose(); + }); + + test('resolves relative path against default endpoint', () { + final uri = github.transport.resolveUri('/user'); + expect(uri.toString(), equals('https://api.github.com/user')); + }); + + test('preserves absolute URLs', () { + final uri = github.transport + .resolveUri('https://uploads.github.com/repos/o/r/releases/1/assets'); + expect(uri.toString(), + equals('https://uploads.github.com/repos/o/r/releases/1/assets')); + }); + + test('expands standard and multi-segment path parameters', () { + final uri = github.transport.resolveUri( + '/repos/{owner}/{repo}/contents/{+path}', + pathParams: { + 'owner': 'octocat', + 'repo': 'hello-world', + 'path': 'src/nested/file.txt', + }, + multiSegmentParams: {'path'}, + ); + expect( + uri.toString(), + equals( + 'https://api.github.com/repos/octocat/hello-world/contents/src/nested/file.txt'), + ); + }); + + test('encodes query parameters, skipping nulls and expanding lists', () { + final uri = github.transport.resolveUri( + '/repos/o/r/issues', + params: { + 'state': 'open', + 'labels': ['bug', 'help wanted'], + 'sort': null, + 'page': 2, + }, + ); + expect( + uri.toString(), + equals( + 'https://api.github.com/repos/o/r/issues?state=open&labels=bug&labels=help+wanted&page=2'), + ); + }); + + test('merges params with existing query without duplicate ?', () { + final uri = github.transport.resolveUri( + '/repos/o/r/issues?direction=asc', + params: {'page': 1}, + ); + expect( + uri.toString(), + equals('https://api.github.com/repos/o/r/issues?direction=asc&page=1'), + ); + }); + }); + + group('buildQueryString', () { + test('handles empty or all-null map', () { + expect(buildQueryString({}), equals('')); + expect(buildQueryString({'a': null, 'b': null}), equals('')); + }); + + test('properly encodes keys and values', () { + expect( + buildQueryString({'user name': 'john doe', 'q': 'a&b=c'}), + equals('?user+name=john+doe&q=a%26b%3Dc'), + ); + }); + + test('handles without leading question mark', () { + expect( + buildQueryString({'page': 1}, prefixQuestionMark: false), + equals('page=1'), + ); + }); + }); + + group('HttpTransport Security Boundaries', () { + test('disallows insecure HTTP auth when allowInsecureAuth is false', + () async { + final client = MockClient((request) async => http.Response('{}', 200)); + final gh = GitHub( + auth: const Authentication.withToken('secret-token'), + endpoint: 'http://insecure-api.local', + client: client, + allowInsecureAuth: false, + ); + + expect( + () => gh.transport.execute( + const ApiRequest(method: 'GET', path: '/user'), + ), + throwsA(isA().having( + (e) => e.message, + 'message', + contains('Insecure HTTP authentication is disallowed'), + )), + ); + gh.dispose(); + }); + + test('allows insecure HTTP auth when explicitly enabled', () async { + final client = MockClient((request) async { + expect(request.headers['Authorization'], equals('token secret-token')); + return http.Response('{"login":"test"}', 200, + headers: {'content-type': 'application/json'}); + }); + final gh = GitHub( + auth: const Authentication.withToken('secret-token'), + endpoint: 'http://insecure-api.local', + client: client, + allowInsecureAuth: true, + ); + + final res = await gh.transport.execute( + const ApiRequest(method: 'GET', path: '/user'), + ); + expect(res.statusCode, equals(200)); + gh.dispose(); + }); + + test('strips authorization header when requesting untrusted origins', + () async { + String? sentAuth; + final client = MockClient((request) async { + sentAuth = request.headers['Authorization']; + return http.Response('{}', 200); + }); + final gh = GitHub( + auth: const Authentication.withToken('secret-token'), + client: client, + ); + + await gh.transport.execute( + const ApiRequest( + method: 'GET', path: 'https://attacker.com/leak-token'), + ); + expect(sentAuth, isNull); + gh.dispose(); + }); + }); + + group('RetryPolicy and Retries', () { + test('retries idempotent requests on 502/503/504 up to maxRetries', + () async { + var callCount = 0; + final client = MockClient((request) async { + callCount++; + if (callCount < 3) { + return http.Response('Bad Gateway', 502); + } + return http.Response('{"ok":true}', 200, + headers: {'content-type': 'application/json'}); + }); + + final delays = []; + final gh = GitHub( + client: client, + retryPolicy: RetryPolicy( + maxRetries: 3, + initialDelay: const Duration(milliseconds: 10), + sleeper: (d) async => delays.add(d), + random: () => 0.5, + ), + ); + + final res = await gh.transport.execute( + const ApiRequest(method: 'GET', path: '/repos/o/r'), + ); + expect(res.statusCode, equals(200)); + expect(callCount, equals(3)); + expect(delays.length, equals(2)); + gh.dispose(); + }); + + test('does NOT retry non-idempotent POST requests on 502', () async { + var callCount = 0; + final client = MockClient((request) async { + callCount++; + return http.Response('Bad Gateway', 502); + }); + + final gh = GitHub( + client: client, + retryPolicy: const RetryPolicy(maxRetries: 3), + ); + + await expectLater( + () => gh.transport.execute( + const ApiRequest(method: 'POST', path: '/repos/o/r/issues'), + ), + throwsA(isA()), + ); + expect(callCount, equals(1)); + gh.dispose(); + }); + + test('honors Retry-After integer header', () { + const policy = RetryPolicy(); + final res = http.Response('Too many requests', 429, headers: { + 'retry-after': '5', + }); + final delay = policy.delayFor(attempt: 0, response: res); + expect(delay, equals(const Duration(seconds: 5))); + }); + + test('honors Retry-After HTTP-Date header', () { + final now = DateTime.utc(2026, 9, 15, 12, 0, 0); + final policy = RetryPolicy(clock: () => now); + final res = http.Response('Too many requests', 429, headers: { + 'retry-after': 'Tue, 15 Sep 2026 12:00:10 GMT', + }); + final delay = policy.delayFor(attempt: 0, response: res); + expect(delay, equals(const Duration(seconds: 10))); + }); + }); + + group('ErrorDecoder and Redaction', () { + late GitHub github; + + setUp(() { + github = GitHub(); + }); + + tearDown(() { + github.dispose(); + }); + + test('redacts classic tokens and fine-grained PATs in messages and body', + () { + const raw = + 'Error with token ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 and pat github_pat_11AAAAAAA0123456789abcdef_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdef'; + final redacted = ErrorDecoder.redact(raw); + expect(redacted, isNot(contains('ghp_'))); + expect(redacted, isNot(contains('github_pat_'))); + expect(redacted, contains('[REDACTED_TOKEN]')); + }); + + test('redacts Bearer authorization header values', () { + const raw = + 'Failed request with Authorization: Bearer secret_bearer_token'; + final redacted = ErrorDecoder.redact(raw); + expect(redacted, contains('Bearer [REDACTED]')); + expect(redacted, isNot(contains('secret_bearer_token'))); + }); + + test('safely truncates long bodies over 2000 characters', () { + final longBody = 'A' * 3000; + final sanitized = ErrorDecoder.sanitizeBody(longBody); + expect(sanitized.length, lessThan(2100)); + expect(sanitized, contains('... [TRUNCATED]')); + }); + + test('decodes 401 as NotAuthenticated', () { + final res = http.Response( + jsonEncode({'message': 'Bad credentials'}), + 401, + headers: {'content-type': 'application/json'}, + ); + expect( + () => ErrorDecoder.decode(github, res), + throwsA(isA() + .having((e) => e.statusCode, 'statusCode', 401) + .having((e) => e.message, 'message', contains('Bad credentials'))), + ); + }); + + test('decodes 403 secondary rate limit as RateLimitHit', () { + final res = http.Response( + jsonEncode({ + 'message': + 'You have exceeded a secondary rate limit. Please wait a few minutes.', + }), + 403, + headers: { + 'content-type': 'application/json', + 'x-ratelimit-remaining': '0', + 'x-ratelimit-reset': '1700000000', + }, + ); + expect( + () => ErrorDecoder.decode(github, res), + throwsA(isA() + .having((e) => e.remaining, 'remaining', 0) + .having((e) => e.reset, 'reset', isNotNull)), + ); + }); + + test('decodes 403 standard as AccessForbidden', () { + final res = http.Response( + jsonEncode({'message': 'Resource not accessible by integration'}), + 403, + headers: {'content-type': 'application/json'}, + ); + expect( + () => ErrorDecoder.decode(github, res), + throwsA(isA()), + ); + }); + + test('decodes 404 as NotFound', () { + final res = http.Response( + jsonEncode({'message': 'Not Found'}), + 404, + headers: {'content-type': 'application/json'}, + ); + expect( + () => ErrorDecoder.decode(github, res), + throwsA(isA()), + ); + }); + + test('decodes 409 as Conflict', () { + final res = http.Response( + jsonEncode({'message': 'Merge conflict'}), + 409, + headers: {'content-type': 'application/json'}, + ); + expect( + () => ErrorDecoder.decode(github, res), + throwsA(isA()), + ); + }); + + test('decodes 422 as ValidationFailed with structured errors', () { + final res = http.Response( + jsonEncode({ + 'message': 'Validation Failed', + 'errors': [ + { + 'resource': 'Issue', + 'field': 'title', + 'code': 'missing_field', + } + ] + }), + 422, + headers: {'content-type': 'application/json'}, + ); + expect( + () => ErrorDecoder.decode(github, res), + throwsA(isA() + .having((e) => e.errors, 'errors', isNotEmpty) + .having((e) => e.message, 'message', contains('Field: title'))), + ); + }); + + test('decodes 503 as ServiceUnavailable', () { + final res = http.Response( + 'Service Unavailable', + 503, + headers: {'content-type': 'text/plain'}, + ); + expect( + () => ErrorDecoder.decode(github, res), + throwsA(isA()), + ); + }); + + test('safely handles missing content-type and HTML error bodies', () { + final res = http.Response( + '500 Internal Server Error', + 500, + ); + expect( + () => ErrorDecoder.decode(github, res), + throwsA(isA()), + ); + }); + }); + + group('GitHub Compatibility Wrappers', () { + test( + 'request with statusCode: null returns response without throwing on 404', + () async { + final client = MockClient((request) async { + return http.Response('Not Found', 404); + }); + final gh = GitHub(client: client); + final response = await gh.request('GET', '/user/following/nonexistent'); + expect(response.statusCode, equals(404)); + gh.dispose(); + }); + + test( + 'requestJson handles 204 No Content returning null without FormatException', + () async { + final client = MockClient((request) async { + return http.Response('', 204); + }); + final gh = GitHub(client: client); + final result = await gh.requestJson, dynamic>( + 'DELETE', '/repos/o/r'); + expect(result, isNull); + gh.dispose(); + }); + + test('getJSON and postJSON execute through transport', () async { + final client = MockClient((request) async { + if (request.method == 'GET') { + return http.Response('{"name":"repo"}', 200, + headers: {'content-type': 'application/json'}); + } else if (request.method == 'POST') { + return http.Response('{"created":true}', 201, + headers: {'content-type': 'application/json'}); + } + return http.Response('Not Found', 404); + }); + final gh = GitHub(client: client); + + final getResult = await gh.getJSON, String>( + '/repos/o/r', + convert: (m) => m['name'] as String); + expect(getResult, equals('repo')); + + final postResult = await gh.postJSON, bool>( + '/repos/o/r/issues', + statusCode: 201, + body: {'title': 'New Issue'}, + convert: (m) => m['created'] as bool); + expect(postResult, isTrue); + gh.dispose(); + }); + }); +} diff --git a/tool/coverage_check.dart b/tool/coverage_check.dart new file mode 100644 index 00000000..bbff09d9 --- /dev/null +++ b/tool/coverage_check.dart @@ -0,0 +1,55 @@ +import 'dart:io'; + +/// Validates that test coverage meets or exceeds the required floor. +/// +/// Usage: dart run tool/coverage_check.dart [coverage_file_or_dir] [--min=percentage] +void main(List args) { + var minCoverage = 50.0; + String? targetPath; + + for (final arg in args) { + if (arg.startsWith('--min=')) { + minCoverage = double.parse(arg.substring(6)); + } else if (!arg.startsWith('--')) { + targetPath = arg; + } + } + + targetPath ??= 'coverage/lcov.info'; + final file = File(targetPath); + + if (!file.existsSync()) { + print('Coverage file not found at $targetPath. Skipping coverage check.'); + exit(0); + } + + final lines = file.readAsLinesSync(); + var linesFound = 0; + var linesHit = 0; + + for (final line in lines) { + if (line.startsWith('LF:')) { + linesFound += int.tryParse(line.substring(3).trim()) ?? 0; + } else if (line.startsWith('LH:')) { + linesHit += int.tryParse(line.substring(3).trim()) ?? 0; + } + } + + if (linesFound == 0) { + print('No executable lines found in $targetPath.'); + exit(0); + } + + final percentage = (linesHit / linesFound) * 100.0; + print( + 'Test line coverage: ${percentage.toStringAsFixed(2)}% ($linesHit / $linesFound lines hit)'); + print('Required coverage floor: ${minCoverage.toStringAsFixed(2)}%'); + + if (percentage < minCoverage) { + print( + 'Error: Coverage ${percentage.toStringAsFixed(2)}% is below required floor of ${minCoverage.toStringAsFixed(2)}%!'); + exit(1); + } + + print('Coverage check passed successfully.'); +} diff --git a/tool/process_github_schema.dart b/tool/process_github_schema.dart index 14994289..c947571b 100644 --- a/tool/process_github_schema.dart +++ b/tool/process_github_schema.dart @@ -602,7 +602,8 @@ void main(List arguments) { 'Command must be run with one argument, the file name of the schema to process.'); exit(1); } - Object schema = json.decode(File(arguments.single).readAsStringSync()); + final schema = + json.decode(File(arguments.single).readAsStringSync()) as Object; assure(schema is Map, () => 'schema is not a JSON object'); var rootType = process(schema as Map); rootType.visit((GenType type) { diff --git a/tool/spec/bindings.yaml b/tool/spec/bindings.yaml new file mode 100644 index 00000000..27c274a1 --- /dev/null +++ b/tool/spec/bindings.yaml @@ -0,0 +1,658 @@ +schemaVersion: 1.0.0 +bindings: + - operationId: activity/check-repo-is-starred-by-authenticated-user + service: ActivityService + method: isStarred + status: supported + - operationId: activity/delete-repo-subscription + service: ActivityService + method: deleteRepositorySubscription + status: supported + - operationId: activity/get-repo-subscription + service: ActivityService + method: isWatched + status: supported + - operationId: activity/list-events-for-authenticated-user + service: ActivityService + method: listUserEvents + status: supported + - operationId: activity/list-public-events + service: ActivityService + method: listEvents + status: supported + - operationId: activity/list-public-events-for-repo-network + service: ActivityService + method: listNetworkEvents + status: supported + - operationId: activity/list-public-org-events + service: ActivityService + method: listOrganizationEvents + status: supported + - operationId: activity/list-repo-events + service: ActivityService + method: listRepositoryEvents + status: supported + - operationId: activity/list-repos-starred-by-authenticated-user + service: ActivityService + method: listStarredRepositories + status: supported + - operationId: activity/list-stargazers-for-repo + service: ActivityService + method: listStarGazers + status: supported + - operationId: activity/list-watchers-for-repo + service: ActivityService + method: listWatches + status: supported + - operationId: activity/set-repo-subscription + service: ActivityService + method: setRepositorySubscription + status: supported + - operationId: activity/star-repo-for-authenticated-user + service: ActivityService + method: star + status: supported + - operationId: activity/unstar-repo-for-authenticated-user + service: ActivityService + method: unstar + status: supported + - operationId: checks/create + service: ChecksService + method: createCheckRun + status: supported + - operationId: checks/create-suite + service: ChecksService + method: createCheckSuite + status: supported + - operationId: checks/get + service: ChecksService + method: getCheckRun + status: supported + - operationId: checks/get-suite + service: ChecksService + method: getCheckSuite + status: supported + - operationId: checks/list-annotations + service: ChecksService + method: listCheckRunAnnotations + status: supported + - operationId: checks/list-for-ref + service: ChecksService + method: listCheckRunsForRef + status: supported + - operationId: checks/list-for-suite + service: ChecksService + method: listCheckRunsInCheckSuite + status: supported + - operationId: checks/rerequest-run + service: ChecksService + method: reRequestCheckRun + status: supported + - operationId: checks/rerequest-suite + service: ChecksService + method: reRequestCheckSuite + status: supported + - operationId: checks/set-suites-preferences + service: ChecksService + method: updatePreferencesForCheckSuites + status: supported + - operationId: checks/update + service: ChecksService + method: updateCheckRun + status: supported + - operationId: gists/check-is-starred + service: GistsService + method: isGistStarred + status: supported + - operationId: gists/create + service: GistsService + method: createGist + status: supported + - operationId: gists/create-comment + service: GistsService + method: createComment + status: supported + - operationId: gists/delete + service: GistsService + method: deleteGist + status: supported + - operationId: gists/delete-comment + service: GistsService + method: deleteComment + status: supported + - operationId: gists/fork + service: GistsService + method: forkGist + status: supported + - operationId: gists/get + service: GistsService + method: getGist + status: supported + - operationId: gists/get-comment + service: GistsService + method: getComment + status: supported + - operationId: gists/list + service: GistsService + method: listGists + status: supported + - operationId: gists/list-comments + service: GistsService + method: listComments + status: supported + - operationId: gists/list-forks + service: GistsService + method: listGistForks + status: supported + - operationId: gists/list-public + service: GistsService + method: listPublicGists + status: supported + - operationId: gists/list-starred + service: GistsService + method: listStarredGists + status: supported + - operationId: gists/list-for-user + service: GistsService + method: listUserGists + status: supported + - operationId: gists/star + service: GistsService + method: starGist + status: supported + - operationId: gists/unstar + service: GistsService + method: unstarGist + status: supported + - operationId: gists/update + service: GistsService + method: editGist + status: supported + - operationId: gists/update-comment + service: GistsService + method: editComment + status: supported + - operationId: git/create-blob + service: GitService + method: createBlob + status: supported + - operationId: git/create-commit + service: GitService + method: createCommit + status: supported + - operationId: git/create-ref + service: GitService + method: createReference + status: supported + - operationId: git/create-tag + service: GitService + method: createTag + status: supported + - operationId: git/create-tree + service: GitService + method: createTree + status: supported + - operationId: git/delete-ref + service: GitService + method: deleteReference + status: supported + - operationId: git/get-blob + service: GitService + method: getBlob + status: supported + - operationId: git/get-commit + service: GitService + method: getCommit + status: supported + - operationId: git/get-ref + service: GitService + method: getReference + status: supported + - operationId: git/get-tag + service: GitService + method: getTag + status: supported + - operationId: git/get-tree + service: GitService + method: getTree + status: supported + - operationId: git/update-ref + service: GitService + method: editReference + status: supported + - operationId: issues/create + service: IssuesService + method: create + status: supported + - operationId: issues/create-comment + service: IssuesService + method: createComment + status: supported + - operationId: issues/create-label + service: IssuesService + method: createLabel + status: supported + - operationId: issues/create-milestone + service: IssuesService + method: createMilestone + status: supported + - operationId: issues/delete-comment + service: IssuesService + method: deleteComment + status: supported + - operationId: issues/delete-label + service: IssuesService + method: deleteLabel + status: supported + - operationId: issues/delete-milestone + service: IssuesService + method: deleteMilestone + status: supported + - operationId: issues/get + service: IssuesService + method: get + status: supported + - operationId: issues/get-comment + service: IssuesService + method: getComment + status: supported + - operationId: issues/get-label + service: IssuesService + method: getLabel + status: supported + - operationId: issues/get-milestone + service: IssuesService + method: getMilestone + status: supported + - operationId: issues/list + service: IssuesService + method: listAll + status: supported + - operationId: issues/list-comments + service: IssuesService + method: listCommentsByIssue + status: supported + - operationId: issues/list-for-authenticated-user + service: IssuesService + method: listByUser + status: supported + - operationId: issues/list-for-org + service: IssuesService + method: listByOrg + status: supported + - operationId: issues/list-for-repo + service: IssuesService + method: listByRepo + status: supported + - operationId: issues/list-labels-for-repo + service: IssuesService + method: listLabels + status: supported + - operationId: issues/list-milestones + service: IssuesService + method: listMilestones + status: supported + - operationId: issues/update + service: IssuesService + method: edit + status: supported + - operationId: issues/update-comment + service: IssuesService + method: editComment + status: supported + - operationId: issues/update-label + service: IssuesService + method: editLabel + status: supported + - operationId: issues/update-milestone + service: IssuesService + method: editMilestone + status: supported + - operationId: meta/get-zen + service: MiscService + method: getZen + status: supported + - operationId: orgs/get + service: OrganizationsService + method: get + status: supported + - operationId: orgs/list + service: OrganizationsService + method: list + status: supported + - operationId: orgs/update + service: OrganizationsService + method: edit + status: supported + - operationId: pulls/create + service: PullRequestsService + method: create + status: supported + - operationId: pulls/create-review + service: PullRequestsService + method: createReview + status: supported + - operationId: pulls/get + service: PullRequestsService + method: get + status: supported + - operationId: pulls/list + service: PullRequestsService + method: list + status: supported + - operationId: pulls/list-commits + service: PullRequestsService + method: listCommits + status: supported + - operationId: pulls/list-files + service: PullRequestsService + method: listFiles + status: supported + - operationId: pulls/list-review-comments + service: PullRequestsService + method: listComments + status: supported + - operationId: pulls/list-reviews + service: PullRequestsService + method: listReviews + status: supported + - operationId: pulls/merge + service: PullRequestsService + method: merge + status: supported + - operationId: pulls/update + service: PullRequestsService + method: edit + status: supported + - operationId: rate-limit/get + service: MiscService + method: getRateLimit + status: supported + - operationId: repos/add-collaborator + service: RepositoriesService + method: addCollaborator + status: supported + - operationId: repos/check-collaborator + service: RepositoriesService + method: isCollaborator + status: supported + - operationId: repos/create-deploy-key + service: RepositoriesService + method: createDeployKey + status: supported + - operationId: repos/create-for-authenticated-user + service: RepositoriesService + method: createRepository + status: supported + - operationId: repos/create-in-org + service: RepositoriesService + method: createOrganizationRepository + status: supported + - operationId: repos/create-or-update-file-contents + service: RepositoriesService + method: createFile + status: supported + - operationId: repos/create-release + service: RepositoriesService + method: createRelease + status: supported + - operationId: repos/create-webhook + service: RepositoriesService + method: createHook + status: supported + - operationId: repos/delete + service: RepositoriesService + method: deleteRepository + status: supported + - operationId: repos/delete-deploy-key + service: RepositoriesService + method: deleteDeployKey + status: supported + - operationId: repos/delete-file + service: RepositoriesService + method: deleteFile + status: supported + - operationId: repos/delete-release + service: RepositoriesService + method: deleteRelease + status: supported + - operationId: repos/delete-release-asset + service: RepositoriesService + method: deleteReleaseAsset + status: supported + - operationId: repos/delete-webhook + service: RepositoriesService + method: deleteHook + status: supported + - operationId: repos/get + service: RepositoriesService + method: getRepository + status: supported + - operationId: repos/get-branch + service: RepositoriesService + method: getBranch + status: supported + - operationId: repos/get-content + service: RepositoriesService + method: getContents + status: supported + - operationId: repos/get-deploy-key + service: RepositoriesService + method: getDeployKey + status: supported + - operationId: repos/get-latest-release + service: RepositoriesService + method: getLatestRelease + status: supported + - operationId: repos/get-readme + service: RepositoriesService + method: getReadme + status: supported + - operationId: repos/get-release + service: RepositoriesService + method: getReleaseById + status: supported + - operationId: repos/get-release-asset + service: RepositoriesService + method: getReleaseAsset + status: supported + - operationId: repos/get-release-by-tag + service: RepositoriesService + method: getReleaseByTagName + status: supported + - operationId: repos/get-webhook + service: RepositoriesService + method: getHook + status: supported + - operationId: repos/list-branches + service: RepositoriesService + method: listBranches + status: supported + - operationId: repos/list-collaborators + service: RepositoriesService + method: listCollaborators + status: supported + - operationId: repos/list-contributors + service: RepositoriesService + method: listContributors + status: supported + - operationId: repos/list-deploy-keys + service: RepositoriesService + method: listDeployKeys + status: supported + - operationId: repos/list-for-authenticated-user + service: RepositoriesService + method: listRepositories + status: supported + - operationId: repos/list-for-org + service: RepositoriesService + method: listOrganizationRepositories + status: supported + - operationId: repos/list-for-user + service: RepositoriesService + method: listUserRepositories + status: supported + - operationId: repos/list-public + service: RepositoriesService + method: listPublicRepositories + status: supported + - operationId: repos/list-release-assets + service: RepositoriesService + method: listReleaseAssets + status: supported + - operationId: repos/list-releases + service: RepositoriesService + method: listReleases + status: supported + - operationId: repos/list-tags + service: RepositoriesService + method: listTags + status: supported + - operationId: repos/list-webhooks + service: RepositoriesService + method: listHooks + status: supported + - operationId: repos/remove-collaborator + service: RepositoriesService + method: removeCollaborator + status: supported + - operationId: repos/update + service: RepositoriesService + method: editRepository + status: supported + - operationId: repos/update-release + service: RepositoriesService + method: editRelease + status: supported + - operationId: repos/update-release-asset + service: RepositoriesService + method: editReleaseAsset + status: supported + - operationId: repos/update-webhook + service: RepositoriesService + method: editHook + status: supported + - operationId: repos/create-dispatch-event + service: RepositoriesService + method: createDispatchEvent + status: supported + - operationId: repos/get-all-topics + service: RepositoriesService + method: listTopics + status: supported + - operationId: repos/replace-all-topics + service: RepositoriesService + method: replaceTopics + status: supported + - operationId: repos/upload-release-asset + service: RepositoriesService + method: uploadReleaseAssets + status: supported + - operationId: search/code + service: SearchService + method: code + status: supported + - operationId: search/issues-and-pull-requests + service: SearchService + method: issues + status: supported + - operationId: search/repos + service: SearchService + method: repositories + status: supported + - operationId: search/users + service: SearchService + method: users + status: supported + - operationId: teams/add-or-update-membership-for-user-in-org + service: OrganizationsService + method: addOrUpdateTeamMembershipByName + status: supported + - operationId: teams/delete-in-org + service: OrganizationsService + method: deleteTeam + status: supported + - operationId: teams/get-by-name + service: OrganizationsService + method: getTeam + status: supported + - operationId: teams/get-membership-for-user-in-org + service: OrganizationsService + method: getTeamMembershipByName + status: supported + - operationId: teams/list + service: OrganizationsService + method: listTeams + status: supported + - operationId: teams/list-members-in-org + service: OrganizationsService + method: listTeamMembers + status: supported + - operationId: teams/list-repos-in-org + service: OrganizationsService + method: listTeamRepos + status: supported + - operationId: teams/remove-membership-for-user-in-org + service: OrganizationsService + method: removeTeamMembershipByName + status: supported + - operationId: teams/update-in-org + service: OrganizationsService + method: editTeam + status: supported + - operationId: users/add-email-for-authenticated-user + service: UsersService + method: addEmails + status: supported + - operationId: users/check-following-for-user + service: UsersService + method: isFollowingUser + status: supported + - operationId: users/create-public-ssh-key-for-authenticated-user + service: UsersService + method: createPublicKey + status: supported + - operationId: users/delete-email-for-authenticated-user + service: UsersService + method: deleteEmails + status: supported + - operationId: users/delete-public-ssh-key-for-authenticated-user + service: UsersService + method: deletePublicKey + status: supported + - operationId: users/follow + service: UsersService + method: followUser + status: supported + - operationId: users/get-authenticated + service: UsersService + method: getCurrentUser + status: supported + - operationId: users/get-by-username + service: UsersService + method: getUser + status: supported + - operationId: users/list + service: UsersService + method: listUsers + status: supported + - operationId: users/list-emails-for-authenticated-user + service: UsersService + method: listEmails + status: supported + - operationId: users/list-gpg-keys-for-authenticated-user + service: UsersService + method: listGpgKeys + status: supported + - operationId: users/list-public-ssh-keys-for-authenticated-user + service: UsersService + method: listPublicKeys + status: supported + - operationId: users/unfollow + service: UsersService + method: unfollowUser + status: supported + - operationId: users/update-authenticated + service: UsersService + method: editCurrentUser + status: supported diff --git a/tool/spec/github-openapi.lock.json b/tool/spec/github-openapi.lock.json new file mode 100644 index 00000000..199ac1f1 --- /dev/null +++ b/tool/spec/github-openapi.lock.json @@ -0,0 +1,10 @@ +{ + "repository": "github/rest-api-description", + "apiVersion": "2022-11-28", + "upstreamCommit": "022b4dc2d10306c8c583368af92e3296598c6ce3", + "artifactPath": "descriptions/api.github.com/api.github.com.2022-11-28.json", + "sha256": "586f4271c3f587dfb07200b5cb4edab7edc39c605c0db04baa82a52ec859d7cb", + "openApiVersion": "3.0.3", + "infoVersion": "1.1.4", + "generatorSchemaVersion": "1.0.0" +} diff --git a/tool/spec_sync.dart b/tool/spec_sync.dart new file mode 100644 index 00000000..4a796673 --- /dev/null +++ b/tool/spec_sync.dart @@ -0,0 +1,117 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'src/openapi/bindings_manifest.dart'; +import 'src/openapi/catalog_generator.dart'; +import 'src/openapi/coverage_reporter.dart'; +import 'src/openapi/spec_loader.dart'; + +void main(List args) async { + final checkMode = args.contains('--check'); + final updateMode = args.contains('--update'); + final offlineMode = args.contains('--offline'); + final reportJsonMode = args.contains('--report-json'); + + try { + final loader = await SpecLoader.loadFromLock(); + final operations = await loader.loadOperations(offline: offlineMode); + + final validOperationIds = operations.map((o) => o.operationId).toSet(); + final manifest = await BindingsManifest.loadFromFile(); + manifest.validate(validOperationIds); + + final catalogGen = CatalogGenerator(operations); + final expectedCatalog = catalogGen.generate(); + + final reporter = + CoverageReporter(operations: operations, manifest: manifest); + final expectedCoverage = reporter.generateMarkdown(); + + if (checkMode) { + var hasDrift = false; + + final catalogFile = + File('lib/src/common/generated/rest_contracts.g.dart'); + if (!catalogFile.existsSync()) { + stderr.writeln( + 'DRIFT: lib/src/common/generated/rest_contracts.g.dart does not exist.'); + hasDrift = true; + } else { + final currentCatalog = await catalogFile.readAsString(); + final tempFile = File( + '.dart_tool/expected_catalog_${DateTime.now().millisecondsSinceEpoch}.dart'); + try { + tempFile.writeAsStringSync(expectedCatalog); + Process.runSync( + Platform.resolvedExecutable, ['format', tempFile.path]); + final formattedExpected = tempFile.readAsStringSync(); + if (currentCatalog != formattedExpected) { + stderr.writeln( + 'DRIFT: lib/src/common/generated/rest_contracts.g.dart has uncommitted changes.'); + hasDrift = true; + } + } finally { + if (tempFile.existsSync()) { + tempFile.deleteSync(); + } + } + } + + final coverageFile = File('docs/api-coverage.md'); + if (!coverageFile.existsSync()) { + stderr.writeln('DRIFT: docs/api-coverage.md does not exist.'); + hasDrift = true; + } else { + final currentCoverage = await coverageFile.readAsString(); + if (currentCoverage != expectedCoverage) { + stderr + .writeln('DRIFT: docs/api-coverage.md has uncommitted changes.'); + hasDrift = true; + } + } + + if (hasDrift) { + stderr.writeln( + 'Spec sync check failed. Run: dart run tool/spec_sync.dart --update'); + exit(1); + } else { + stdout.writeln('Spec sync check passed: No drift detected.'); + if (reportJsonMode) { + stdout.writeln(jsonEncode({ + 'status': 'clean', + 'operationsCount': operations.length, + 'boundCount': manifest.bindings.length, + })); + } + exit(0); + } + } + + if (updateMode || (!checkMode && !reportJsonMode)) { + await catalogGen.writeToFile(); + await reporter.writeToFile(); + stdout.writeln( + 'Updated rest_contracts.g.dart (${operations.length} operations) and docs/api-coverage.md (${manifest.bindings.length} bound).'); + } + + if (reportJsonMode) { + final summary = { + 'totalOperations': operations.length, + 'totalBound': manifest.bindings.length, + 'supported': manifest.bindings + .where((b) => b.status == BindingStatus.supported) + .length, + 'partial': manifest.bindings + .where((b) => b.status == BindingStatus.partial) + .length, + 'deprecated': manifest.bindings + .where((b) => b.status == BindingStatus.deprecated) + .length, + }; + stdout.writeln(jsonEncode(summary)); + } + } catch (e, st) { + stderr.writeln('Error during spec_sync: $e\n$st'); + exit(1); + } +} diff --git a/tool/src/openapi/bindings_manifest.dart b/tool/src/openapi/bindings_manifest.dart new file mode 100644 index 00000000..c7f92c5f --- /dev/null +++ b/tool/src/openapi/bindings_manifest.dart @@ -0,0 +1,141 @@ +import 'dart:io'; + +import 'package:yaml/yaml.dart'; + +enum BindingStatus { + supported, + partial, + deprecated, + unsupported, +} + +class OperationBinding { + final String operationId; + final String service; + final String method; + final BindingStatus status; + final String notes; + + const OperationBinding({ + required this.operationId, + required this.service, + required this.method, + required this.status, + this.notes = '', + }); + + Map toJson() => { + 'operationId': operationId, + 'service': service, + 'method': method, + 'status': status.name, + 'notes': notes, + }; +} + +class BindingsManifest { + final String schemaVersion; + final List bindings; + + BindingsManifest({ + required this.bindings, + this.schemaVersion = '1.0.0', + }); + + static Future loadFromFile([ + String filePath = 'tool/spec/bindings.yaml', + ]) async { + final file = File(filePath); + if (!file.existsSync()) { + return BindingsManifest(bindings: []); + } + final content = await file.readAsString(); + final doc = loadYaml(content); + if (doc is! Map) { + return BindingsManifest(bindings: []); + } + + final schemaVersion = doc['schemaVersion'] as String? ?? '1.0.0'; + final rawBindings = doc['bindings'] as List? ?? []; + final bindings = []; + + for (final b in rawBindings) { + if (b is! Map) { + continue; + } + final opId = b['operationId'] as String; + final service = b['service'] as String? ?? ''; + final method = b['method'] as String? ?? ''; + final statusStr = b['status'] as String? ?? 'supported'; + final notes = b['notes'] as String? ?? ''; + + final status = BindingStatus.values.firstWhere( + (e) => e.name == statusStr, + orElse: () => BindingStatus.supported, + ); + + bindings.add(OperationBinding( + operationId: opId, + service: service, + method: method, + status: status, + notes: notes, + )); + } + + return BindingsManifest( + schemaVersion: schemaVersion, + bindings: bindings, + ); + } + + /// Validates the manifest against the specification's operation IDs. + void validate(Set validOperationIds) { + final seenOps = {}; + final seenMethods = {}; + + for (final b in bindings) { + if (!validOperationIds.contains(b.operationId)) { + throw StateError( + 'bindings.yaml references unknown OpenAPI operationId: "${b.operationId}"', + ); + } + if (!seenOps.add(b.operationId)) { + throw StateError( + 'Duplicate binding for operationId "${b.operationId}" in bindings.yaml', + ); + } + final methodKey = '${b.service}.${b.method}'; + if (b.service.isNotEmpty && b.method.isNotEmpty) { + if (!seenMethods.add(methodKey)) { + throw StateError( + 'Duplicate binding for service method "$methodKey" in bindings.yaml', + ); + } + } + } + } + + Future saveToFile([ + String filePath = 'tool/spec/bindings.yaml', + ]) async { + final file = File(filePath); + final sorted = [...bindings] + ..sort((a, b) => a.operationId.compareTo(b.operationId)); + + final sb = StringBuffer(); + sb.writeln('schemaVersion: $schemaVersion'); + sb.writeln('bindings:'); + for (final b in sorted) { + sb.writeln(' - operationId: ${b.operationId}'); + sb.writeln(' service: ${b.service}'); + sb.writeln(' method: ${b.method}'); + sb.writeln(' status: ${b.status.name}'); + if (b.notes.isNotEmpty) { + sb.writeln(' notes: "${b.notes.replaceAll('"', r'\"')}"'); + } + } + + await file.writeAsString(sb.toString()); + } +} diff --git a/tool/src/openapi/catalog_generator.dart b/tool/src/openapi/catalog_generator.dart new file mode 100644 index 00000000..aef4b06d --- /dev/null +++ b/tool/src/openapi/catalog_generator.dart @@ -0,0 +1,140 @@ +import 'dart:io'; + +import 'package:dart_style/dart_style.dart'; +import 'package:pub_semver/pub_semver.dart'; + +import 'openapi_model.dart'; + +/// Generates the compact `RestContracts` catalog at lib/src/common/generated/rest_contracts.g.dart. +class CatalogGenerator { + final List operations; + + CatalogGenerator(this.operations); + + String generate() { + final buffer = StringBuffer(); + buffer.writeln('// GENERATED CODE - DO NOT MODIFY BY HAND'); + buffer.writeln('// Generated from GitHub OpenAPI 2022-11-28 description.'); + buffer.writeln(); + buffer.writeln( + '/// Immutable contract metadata for a GitHub REST API operation.'); + buffer.writeln('class RestOperationContract {'); + buffer.writeln(' final String operationId;'); + buffer.writeln(' final String method;'); + buffer.writeln(' final String path;'); + buffer.writeln(' final List pathParams;'); + buffer.writeln(' final List queryParams;'); + buffer.writeln(' final List headerParams;'); + buffer.writeln(' final bool hasRequestBody;'); + buffer.writeln(' final List requestMediaTypes;'); + buffer.writeln(' final List successStatuses;'); + buffer.writeln(' final bool isMultiSegmentPath;'); + buffer.writeln(); + buffer.writeln(' const RestOperationContract({'); + buffer.writeln(' required this.operationId,'); + buffer.writeln(' required this.method,'); + buffer.writeln(' required this.path,'); + buffer.writeln(' this.pathParams = const [],'); + buffer.writeln(' this.queryParams = const [],'); + buffer.writeln(' this.headerParams = const [],'); + buffer.writeln(' this.hasRequestBody = false,'); + buffer.writeln(' this.requestMediaTypes = const [],'); + buffer.writeln(' this.successStatuses = const [200],'); + buffer.writeln(' this.isMultiSegmentPath = false,'); + buffer.writeln(' });'); + buffer.writeln('}'); + buffer.writeln(); + buffer.writeln('/// Catalog of all 2022-11-28 REST operation contracts.'); + buffer.writeln('abstract final class RestContracts {'); + + for (final op in operations) { + final safeIdentifier = _toIdentifier(op.operationId); + buffer.writeln(' /// `${op.method} ${op.path}`'); + if (op.summary.isNotEmpty) { + buffer.writeln(' /// ${op.summary.replaceAll('\n', ' ')}'); + } + buffer.writeln(' static const $safeIdentifier = RestOperationContract('); + buffer.writeln(' operationId: \'${op.operationId}\','); + buffer.writeln(' method: \'${op.method}\','); + buffer.writeln(' path: \'${op.path}\','); + if (op.pathParams.isNotEmpty) { + buffer.writeln( + ' pathParams: [${op.pathParams.map((p) => '\'$p\'').join(', ')}],'); + } + if (op.queryParams.isNotEmpty) { + buffer.writeln( + ' queryParams: [${op.queryParams.map((p) => '\'$p\'').join(', ')}],'); + } + if (op.headerParams.isNotEmpty) { + buffer.writeln( + ' headerParams: [${op.headerParams.map((p) => '\'$p\'').join(', ')}],'); + } + if (op.hasRequestBody) { + buffer.writeln(' hasRequestBody: true,'); + } + if (op.requestMediaTypes.isNotEmpty) { + buffer.writeln( + ' requestMediaTypes: [${op.requestMediaTypes.map((m) => '\'$m\'').join(', ')}],'); + } + if (op.successStatuses.isNotEmpty && + !(op.successStatuses.length == 1 && + op.successStatuses.first == 200)) { + buffer.writeln( + ' successStatuses: [${op.successStatuses.join(', ')}],'); + } + if (op.isMultiSegmentPath) { + buffer.writeln(' isMultiSegmentPath: true,'); + } + buffer.writeln(' );'); + buffer.writeln(); + } + + buffer.writeln(' /// Map of all operations indexed by operationId.'); + buffer.writeln(' static const Map all = {'); + for (final op in operations) { + final safeIdentifier = _toIdentifier(op.operationId); + buffer.writeln(' \'${op.operationId}\': $safeIdentifier,'); + } + buffer.writeln(' };'); + buffer.writeln('}'); + + final code = buffer.toString(); + try { + return DartFormatter(languageVersion: Version(3, 5, 0)).format(code); + } catch (_) { + return code; + } + } + + static String _toIdentifier(String operationId) { + final cleaned = operationId + .replaceAll('/', '_') + .replaceAll('-', '_') + .replaceAll('.', '_'); + final parts = cleaned.split('_'); + final sb = StringBuffer(parts.first); + for (var i = 1; i < parts.length; i++) { + final part = parts[i]; + if (part.isEmpty) { + continue; + } + sb.write(part[0].toUpperCase()); + if (part.length > 1) { + sb.write(part.substring(1)); + } + } + return sb.toString(); + } + + Future writeToFile([ + String outputPath = 'lib/src/common/generated/rest_contracts.g.dart', + ]) async { + final file = File(outputPath); + final parent = file.parent; + if (!parent.existsSync()) { + await parent.create(recursive: true); + } + await file.writeAsString(generate()); + Process.runSync(Platform.resolvedExecutable, ['format', outputPath]); + } +} diff --git a/tool/src/openapi/coverage_reporter.dart b/tool/src/openapi/coverage_reporter.dart new file mode 100644 index 00000000..78e0c156 --- /dev/null +++ b/tool/src/openapi/coverage_reporter.dart @@ -0,0 +1,129 @@ +import 'dart:io'; + +import 'bindings_manifest.dart'; +import 'openapi_model.dart'; + +/// Generates `docs/api-coverage.md` detailing measured GitHub REST API conformance. +class CoverageReporter { + final List operations; + final BindingsManifest manifest; + + CoverageReporter({ + required this.operations, + required this.manifest, + }); + + String generateMarkdown() { + final opMap = {for (final op in operations) op.operationId: op}; + final bindingMap = { + for (final b in manifest.bindings) b.operationId: b, + }; + + final totalOps = operations.length; + final totalBound = manifest.bindings.length; + final supportedCount = manifest.bindings + .where((b) => b.status == BindingStatus.supported) + .length; + final partialCount = manifest.bindings + .where((b) => b.status == BindingStatus.partial) + .length; + final deprecatedCount = manifest.bindings + .where((b) => b.status == BindingStatus.deprecated) + .length; + + final overallPercent = totalOps == 0 + ? 0.0 + : ((supportedCount + partialCount) / totalOps) * 100; + + // Group by primary tag + final tagGroups = >{}; + for (final op in operations) { + final tag = op.tags.isNotEmpty ? op.tags.first : 'other'; + tagGroups.putIfAbsent(tag, () => []).add(op); + } + + final sortedTags = tagGroups.keys.toList()..sort(); + + final buffer = StringBuffer(); + buffer.writeln('# GitHub REST API Conformance & Coverage'); + buffer.writeln(); + buffer.writeln( + '> Automatically generated from `tool/spec/github-openapi.lock.json` and `tool/spec/bindings.yaml`.'); + buffer.writeln(); + buffer.writeln('## Summary'); + buffer.writeln(); + buffer.writeln('| Metric | Count |'); + buffer.writeln('| --- | --- |'); + buffer.writeln('| Total OpenAPI Operations | $totalOps |'); + buffer.writeln('| Total Bound Operations | $totalBound |'); + buffer.writeln('| Supported Operations | $supportedCount |'); + buffer.writeln('| Partial Operations | $partialCount |'); + buffer.writeln('| Deprecated Operations | $deprecatedCount |'); + buffer.writeln( + '| Conformance Coverage | ${overallPercent.toStringAsFixed(1)}% |'); + buffer.writeln(); + + buffer.writeln('## Coverage by Category (Tags)'); + buffer.writeln(); + buffer.writeln( + '| Category | Total | Bound | Supported | Partial | Coverage % |'); + buffer.writeln('| --- | --- | --- | --- | --- | --- |'); + + for (final tag in sortedTags) { + final ops = tagGroups[tag]!; + var tagBound = 0; + var tagSupported = 0; + var tagPartial = 0; + + for (final op in ops) { + final b = bindingMap[op.operationId]; + if (b != null) { + tagBound++; + if (b.status == BindingStatus.supported) { + tagSupported++; + } + if (b.status == BindingStatus.partial) { + tagPartial++; + } + } + } + + final tagPercent = + ops.isEmpty ? 0.0 : ((tagSupported + tagPartial) / ops.length) * 100; + + buffer.writeln( + '| $tag | ${ops.length} | $tagBound | $tagSupported | $tagPartial | ${tagPercent.toStringAsFixed(1)}% |'); + } + + buffer.writeln(); + buffer.writeln('## Bound Operations'); + buffer.writeln(); + buffer.writeln( + '| Operation ID | Method | Path | Service Method | Status | Notes |'); + buffer.writeln('| --- | --- | --- | --- | --- | --- |'); + + final sortedBindings = [...manifest.bindings] + ..sort((a, b) => a.operationId.compareTo(b.operationId)); + + for (final b in sortedBindings) { + final op = opMap[b.operationId]; + final method = op?.method ?? 'UNKNOWN'; + final path = op?.path ?? 'UNKNOWN'; + final serviceMethod = + b.service.isNotEmpty ? '`${b.service}.${b.method}`' : '-'; + buffer.writeln( + '| `${b.operationId}` | `$method` | `$path` | $serviceMethod | ${b.status.name} | ${b.notes} |'); + } + + return buffer.toString(); + } + + Future writeToFile([String outputPath = 'docs/api-coverage.md']) async { + final file = File(outputPath); + final parent = file.parent; + if (!parent.existsSync()) { + await parent.create(recursive: true); + } + await file.writeAsString(generateMarkdown()); + } +} diff --git a/tool/src/openapi/openapi_model.dart b/tool/src/openapi/openapi_model.dart new file mode 100644 index 00000000..173bd8e8 --- /dev/null +++ b/tool/src/openapi/openapi_model.dart @@ -0,0 +1,76 @@ +/// Representation of an OpenAPI operation normalized for REST contract verification. +class RestOperation { + final String operationId; + final String summary; + final String description; + final String method; + final String path; + final List tags; + final List pathParams; + final List queryParams; + final List headerParams; + final bool hasRequestBody; + final List requestMediaTypes; + final List successStatuses; + final List errorStatuses; + final bool deprecated; + final bool isMultiSegmentPath; + + const RestOperation({ + required this.operationId, + required this.method, + required this.path, + this.summary = '', + this.description = '', + this.tags = const [], + this.pathParams = const [], + this.queryParams = const [], + this.headerParams = const [], + this.hasRequestBody = false, + this.requestMediaTypes = const [], + this.successStatuses = const [200], + this.errorStatuses = const [], + this.deprecated = false, + this.isMultiSegmentPath = false, + }); + + Map toJson() => { + 'operationId': operationId, + 'summary': summary, + 'description': description, + 'method': method, + 'path': path, + 'tags': tags, + 'pathParams': pathParams, + 'queryParams': queryParams, + 'headerParams': headerParams, + 'hasRequestBody': hasRequestBody, + 'requestMediaTypes': requestMediaTypes, + 'successStatuses': successStatuses, + 'errorStatuses': errorStatuses, + 'deprecated': deprecated, + 'isMultiSegmentPath': isMultiSegmentPath, + }; + + factory RestOperation.fromJson(Map json) => RestOperation( + operationId: json['operationId'] as String, + method: json['method'] as String, + path: json['path'] as String, + summary: json['summary'] as String? ?? '', + description: json['description'] as String? ?? '', + tags: (json['tags'] as List?)?.cast() ?? const [], + pathParams: (json['pathParams'] as List?)?.cast() ?? const [], + queryParams: (json['queryParams'] as List?)?.cast() ?? const [], + headerParams: + (json['headerParams'] as List?)?.cast() ?? const [], + hasRequestBody: json['hasRequestBody'] as bool? ?? false, + requestMediaTypes: + (json['requestMediaTypes'] as List?)?.cast() ?? const [], + successStatuses: + (json['successStatuses'] as List?)?.cast() ?? const [200], + errorStatuses: + (json['errorStatuses'] as List?)?.cast() ?? const [], + deprecated: json['deprecated'] as bool? ?? false, + isMultiSegmentPath: json['isMultiSegmentPath'] as bool? ?? false, + ); +} diff --git a/tool/src/openapi/semantic_diff.dart b/tool/src/openapi/semantic_diff.dart new file mode 100644 index 00000000..2d3c8f74 --- /dev/null +++ b/tool/src/openapi/semantic_diff.dart @@ -0,0 +1,173 @@ +import 'openapi_model.dart'; + +/// Categorized semantic differences between two OpenAPI specifications. +class SemanticDiff { + final List addedOperationIds; + final List removedOperationIds; + final List modifiedOperations; + final List breakingChangeNotes; + + SemanticDiff({ + this.addedOperationIds = const [], + this.removedOperationIds = const [], + this.modifiedOperations = const [], + this.breakingChangeNotes = const [], + }); + + bool get hasChanges => + addedOperationIds.isNotEmpty || + removedOperationIds.isNotEmpty || + modifiedOperations.isNotEmpty; + + bool get isBreaking => + removedOperationIds.isNotEmpty || breakingChangeNotes.isNotEmpty; + + Map toJson() => { + 'hasChanges': hasChanges, + 'isBreaking': isBreaking, + 'addedOperationsCount': addedOperationIds.length, + 'removedOperationsCount': removedOperationIds.length, + 'modifiedOperationsCount': modifiedOperations.length, + 'addedOperations': addedOperationIds, + 'removedOperations': removedOperationIds, + 'modifiedOperations': + modifiedOperations.map((m) => m.toJson()).toList(), + 'breakingChangeNotes': breakingChangeNotes, + }; + + factory SemanticDiff.between( + List oldOps, + List newOps, + ) { + final oldMap = {for (final op in oldOps) op.operationId: op}; + final newMap = {for (final op in newOps) op.operationId: op}; + + final added = []; + final removed = []; + final modified = []; + final breakingNotes = []; + + for (final newId in newMap.keys) { + if (!oldMap.containsKey(newId)) { + added.add(newId); + } + } + + for (final oldId in oldMap.keys) { + if (!newMap.containsKey(oldId)) { + removed.add(oldId); + breakingNotes.add('Operation removed: $oldId'); + } + } + + for (final opId in oldMap.keys) { + if (!newMap.containsKey(opId)) { + continue; + } + final oldOp = oldMap[opId]!; + final newOp = newMap[opId]!; + + final methodChanged = oldOp.method != newOp.method; + final pathChanged = oldOp.path != newOp.path; + final addedPathParams = + newOp.pathParams.where((p) => !oldOp.pathParams.contains(p)).toList(); + final removedPathParams = + oldOp.pathParams.where((p) => !newOp.pathParams.contains(p)).toList(); + final addedQueryParams = newOp.queryParams + .where((p) => !oldOp.queryParams.contains(p)) + .toList(); + final removedQueryParams = oldOp.queryParams + .where((p) => !newOp.queryParams.contains(p)) + .toList(); + final requestBodyChanged = oldOp.hasRequestBody != newOp.hasRequestBody; + + final isModified = methodChanged || + pathChanged || + addedPathParams.isNotEmpty || + removedPathParams.isNotEmpty || + addedQueryParams.isNotEmpty || + removedQueryParams.isNotEmpty || + requestBodyChanged; + + if (isModified) { + if (methodChanged) { + breakingNotes.add( + '$opId: Method changed from ${oldOp.method} to ${newOp.method}'); + } + if (pathChanged) { + breakingNotes + .add('$opId: Path changed from ${oldOp.path} to ${newOp.path}'); + } + if (addedPathParams.isNotEmpty) { + breakingNotes.add( + '$opId: Added required path parameters: ${addedPathParams.join(', ')}'); + } + + modified.add(OperationModification( + operationId: opId, + oldMethod: oldOp.method, + newMethod: newOp.method, + oldPath: oldOp.path, + newPath: newOp.path, + addedPathParams: addedPathParams, + removedPathParams: removedPathParams, + addedQueryParams: addedQueryParams, + removedQueryParams: removedQueryParams, + requestBodyChanged: requestBodyChanged, + )); + } + } + + added.sort(); + removed.sort(); + modified.sort((a, b) => a.operationId.compareTo(b.operationId)); + + return SemanticDiff( + addedOperationIds: added, + removedOperationIds: removed, + modifiedOperations: modified, + breakingChangeNotes: breakingNotes, + ); + } +} + +class OperationModification { + final String operationId; + final String oldMethod; + final String newMethod; + final String oldPath; + final String newPath; + final List addedPathParams; + final List removedPathParams; + final List addedQueryParams; + final List removedQueryParams; + final bool requestBodyChanged; + + OperationModification({ + required this.operationId, + required this.oldMethod, + required this.newMethod, + required this.oldPath, + required this.newPath, + this.addedPathParams = const [], + this.removedPathParams = const [], + this.addedQueryParams = const [], + this.removedQueryParams = const [], + this.requestBodyChanged = false, + }); + + Map toJson() => { + 'operationId': operationId, + 'method': oldMethod == newMethod + ? oldMethod + : {'old': oldMethod, 'new': newMethod}, + 'path': oldPath == newPath ? oldPath : {'old': oldPath, 'new': newPath}, + if (addedPathParams.isNotEmpty) 'addedPathParams': addedPathParams, + if (removedPathParams.isNotEmpty) + 'removedPathParams': removedPathParams, + if (addedQueryParams.isNotEmpty) 'addedQueryParams': addedQueryParams, + if (removedQueryParams.isNotEmpty) + 'removedQueryParams': removedQueryParams, + if (requestBodyChanged) 'requestBodyChanged': true, + }; +} diff --git a/tool/src/openapi/spec_loader.dart b/tool/src/openapi/spec_loader.dart new file mode 100644 index 00000000..4973e246 --- /dev/null +++ b/tool/src/openapi/spec_loader.dart @@ -0,0 +1,263 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:crypto/crypto.dart'; + +import 'openapi_model.dart'; + +/// Loads, validates, resolves $refs, and normalizes GitHub OpenAPI descriptions. +class SpecLoader { + final Map lockData; + final String cacheDirectory; + + SpecLoader({ + required this.lockData, + this.cacheDirectory = 'tool/spec/.cache', + }); + + static Future loadFromLock([ + String lockFilePath = 'tool/spec/github-openapi.lock.json', + String cacheDir = 'tool/spec/.cache', + ]) async { + final lockFile = File(lockFilePath); + if (!lockFile.existsSync()) { + throw StateError('Lock file not found at $lockFilePath'); + } + final lockContent = await lockFile.readAsString(); + final lockJson = jsonDecode(lockContent) as Map; + return SpecLoader(lockData: lockJson, cacheDirectory: cacheDir); + } + + /// Ensures the spec artifact is downloaded and matches the lock SHA-256. + Future ensureArtifact({bool offline = false}) async { + final cacheDir = Directory(cacheDirectory); + if (!cacheDir.existsSync()) { + await cacheDir.create(recursive: true); + } + + final artifactName = (lockData['artifactPath'] as String).split('/').last; + final cachedFile = File('$cacheDirectory/$artifactName'); + final expectedSha = lockData['sha256'] as String; + + if (cachedFile.existsSync()) { + final bytes = await cachedFile.readAsBytes(); + final actualSha = sha256.convert(bytes).toString(); + if (actualSha == expectedSha) { + return cachedFile; + } + if (offline) { + throw StateError( + 'Cached spec SHA-256 ($actualSha) does not match lock ($expectedSha) in offline mode.', + ); + } + } + + if (offline) { + throw StateError( + 'OpenAPI spec artifact not found at ${cachedFile.path} in offline mode.', + ); + } + + // Download from GitHub raw + final repo = lockData['repository'] as String; + final commit = lockData['upstreamCommit'] as String; + final artifactPath = lockData['artifactPath'] as String; + final url = Uri.parse( + 'https://raw.githubusercontent.com/$repo/$commit/$artifactPath'); + + final client = HttpClient(); + try { + final req = await client.getUrl(url); + final res = await req.close(); + if (res.statusCode != 200) { + throw HttpException( + 'Failed to download spec from $url: HTTP ${res.statusCode}', + uri: url, + ); + } + final sink = cachedFile.openWrite(); + await res.pipe(sink); + } finally { + client.close(); + } + + // Verify downloaded SHA-256 + final downloadedBytes = await cachedFile.readAsBytes(); + final downloadedSha = sha256.convert(downloadedBytes).toString(); + if (downloadedSha != expectedSha) { + await cachedFile.delete(); + throw StateError( + 'Downloaded spec SHA-256 ($downloadedSha) does not match expected lock ($expectedSha).', + ); + } + + return cachedFile; + } + + /// Parses the spec and returns normalized [RestOperation]s. + Future> loadOperations({bool offline = false}) async { + final file = await ensureArtifact(offline: offline); + final rawText = await file.readAsString(); + final root = jsonDecode(rawText) as Map; + + dynamic resolveRef(dynamic item) { + if (item is! Map) { + return item; + } + if (!item.containsKey(r'$ref')) { + return item; + } + + final ref = item[r'$ref'] as String; + if (!ref.startsWith('#/')) { + throw UnsupportedError('External $ref not supported: $ref'); + } + + final parts = ref.substring(2).split('/'); + dynamic current = root; + for (final part in parts) { + final decodedPart = part.replaceAll('~1', '/').replaceAll('~0', '~'); + if (current is Map) { + current = current[decodedPart]; + } else if (current is List && int.tryParse(decodedPart) != null) { + current = current[int.parse(decodedPart)]; + } else { + throw StateError('Unresolvable $ref at $part'); + } + } + return resolveRef(current); + } + + final paths = root['paths'] as Map? ?? {}; + final operations = []; + + final sortedPaths = paths.keys.toList()..sort(); + + for (final path in sortedPaths) { + final pathItemRaw = paths[path]; + final pathItem = resolveRef(pathItemRaw) as Map; + + final commonParams = >[]; + if (pathItem.containsKey('parameters')) { + for (final p in pathItem['parameters'] as List) { + commonParams.add(resolveRef(p) as Map); + } + } + + for (final method in ['get', 'post', 'put', 'delete', 'patch', 'head']) { + if (!pathItem.containsKey(method)) { + continue; + } + + final opRaw = pathItem[method]; + final op = resolveRef(opRaw) as Map; + + final operationId = op['operationId'] as String?; + if (operationId == null) { + continue; + } + + final tags = (op['tags'] as List?)?.cast() ?? []; + final summary = op['summary'] as String? ?? ''; + final description = op['description'] as String? ?? ''; + final deprecated = op['deprecated'] as bool? ?? false; + + // Combine parameters + final allParams = >[...commonParams]; + if (op.containsKey('parameters')) { + for (final p in op['parameters'] as List) { + allParams.add(resolveRef(p) as Map); + } + } + + final pathParams = []; + final queryParams = []; + final headerParams = []; + + for (final param in allParams) { + final inLocation = param['in'] as String?; + final name = param['name'] as String?; + if (name == null) { + continue; + } + + if (inLocation == 'path') { + if (!pathParams.contains(name)) { + pathParams.add(name); + } + } else if (inLocation == 'query') { + if (!queryParams.contains(name)) { + queryParams.add(name); + } + } else if (inLocation == 'header') { + if (!headerParams.contains(name)) { + headerParams.add(name); + } + } + } + pathParams.sort(); + queryParams.sort(); + headerParams.sort(); + + // Request body + var hasRequestBody = false; + final requestMediaTypes = []; + if (op.containsKey('requestBody')) { + hasRequestBody = true; + final reqBody = resolveRef(op['requestBody']) as Map; + final content = reqBody['content'] as Map?; + if (content != null) { + requestMediaTypes.addAll(content.keys); + requestMediaTypes.sort(); + } + } + + // Response status codes + final successStatuses = []; + final errorStatuses = []; + if (op.containsKey('responses')) { + final responses = resolveRef(op['responses']) as Map; + for (final codeStr in responses.keys) { + final code = int.tryParse(codeStr); + if (code != null) { + if (code >= 200 && code < 300) { + successStatuses.add(code); + } else { + errorStatuses.add(code); + } + } + } + } + successStatuses.sort(); + errorStatuses.sort(); + + final isMultiSegmentPath = path.contains('{+path}') || + path.contains('{path*}') || + (op['x-multi-segment'] == true); + + operations.add(RestOperation( + operationId: operationId, + method: method.toUpperCase(), + path: path, + summary: summary, + description: description, + tags: tags, + pathParams: pathParams, + queryParams: queryParams, + headerParams: headerParams, + hasRequestBody: hasRequestBody, + requestMediaTypes: requestMediaTypes, + successStatuses: + successStatuses.isEmpty ? const [200] : successStatuses, + errorStatuses: errorStatuses, + deprecated: deprecated, + isMultiSegmentPath: isMultiSegmentPath, + )); + } + } + + // Sort deterministically by operationId + operations.sort((a, b) => a.operationId.compareTo(b.operationId)); + return operations; + } +}