packages feed

github 0.19 → 0.30.0.2

raw patch · 131 files changed

Files

CHANGELOG.md view
@@ -1,42 +1,287 @@+## Changes for 0.30.0.2++_2026-03-12, Andreas Abel_++- Fixed issue [#531](https://github.com/haskell-github/github/issues/531)+  (Norfairking, PR [#532](https://github.com/haskell-github/github/pull/532)).+- Allow `http-client-tls-0.4`.++Tested with GHC 8.2 - 9.14.1.++## Changes for 0.30.0.1++_2025-08-27, Andreas Abel_++- Drop dependencies `deepseq-generics` and `transformers-compat`.+- Remove obsolete `deriving Typeable`.++Tested with GHC 8.2 - 9.14 alpha1.++## Changes for 0.30++_2025-05-09, Andreas Abel, Peace edition_++- Organization membership endpoint (Domen Kožar, PR [#487](https://github.com/haskell-github/github/pull/487)).+- Allow JWT as an authentication method (Tom Sydney Kerckhove, PR [#497](https://github.com/haskell-github/github/pull/497)).+- Support pagination (Tom McLaughlin, PR [#503](https://github.com/haskell-github/github/pull/503)).+- Initial subset of Reactions endpoints (Dan Rijks, PR [#509](https://github.com/haskell-github/github/pull/509)).+- Fix `getNotifications` (maralorn, PR [#511](https://github.com/haskell-github/github/pull/511)).+- Add missing `name` field to `WorkflowJobs` `Job` type (Hugh Davidson, PR [#518](https://github.com/haskell-github/github/pull/518)).+- Add `StateReasonDuplicate` to `IssueStateReason` (PR [#523](https://github.com/haskell-github/github/pull/523)).+- Drop support for GHC 8.0 and below.+- Drop dependency `time-compat`.++Tested with GHC 8.2 - 9.12.2.+++## Changes for 0.29++_2023-06-24, Andreas Abel, Midsommar edition_++- Support for the GitHub Actions API+  (PR [#459](https://github.com/haskell-github/github/pull/459)):+  * New endpoint modules `GitHub.EndPoints.Actions.Artifacts`, `.Cache`,+    `.Secrets`, `.Workflows`, `.WorkflowRuns`, `.WorkflowJobs`.+  * Matching data structure modules `GitHub.Data.Actions.*`.++- Add field `issueStateReason` of type `Maybe IssueStateReason` to `Issue`+  with possible values `completed`, `not_planned` and `reopened`+  (PR [#496](https://github.com/haskell-github/github/pull/496)).++Tested with GHC 7.8 - 9.6.2++## Changes for 0.28.0.1++_2022-07-23, Andreas Abel_++Tested with GHC 7.8 - 9.4.1 alpha3++- Drop unused dependency `vector-instances`.+- Allow latest: `aeson-2.1`, `mtl-2.3`, `vector-0.13`, `transformers-0.6`.++## Changes for 0.28++_2022-04-30, Andreas Abel, Valborg edition_++Tested with GHC 7.8 - 9.2.2++- Add constructors to `IssueRepoMod` that allow filtering issues by+  milestone, assignee, creator, mentioned user:+  `GitHub.Data.Options.options{Milestone,Assignee,Creator,Mentioned}`+  (PR [#470](https://github.com/haskell-github/github/pull/470))++- Add permissions field to `Repo`.+  This adds record `RepoPermissions` and field `Repo.repoPermissions`+  in module `GitHub.Data.Repos`.+  (PR [#476](https://github.com/haskell-github/github/pull/476))++- Add unwatch request `GitHub.Endpoints.Activity.Watching.unwatchRepoR`+  (PR [#473](https://github.com/haskell-github/github/pull/473))++Breaking change:++- Make searches paginated+  (PR [#474](https://github.com/haskell-github/github/pull/474)):+  * Adds record `GitHub.Data.Repos.CodeSearchRepo`.+  * Adds argument `FetchCount`+    to `GitHub.Endpoints.Search.search{Repos,Code,Issues,Users}R`.++## Changes for 0.27++_2021-10-10, Oleg Grenrus_++- Add vector of `SimpleTeam` in "requested_teams" field of `PullRequest`+  [#453](https://github.com/haskell-github/github/pull/453)+- Add endpoint to create gist+  [#455](https://github.com/haskell-github/github/pull/455)+- Update `RepoWebhookEvent`+  [#461](https://github.com/haskell-github/github/pull/461)+- `PullRequest` Reviews may not have submitted_at field+  [#450](https://github.com/haskell-github/github/pull/450)++## Changes for 0.26++_2020-05-26, Oleg Grenrus_++- Generalize `PagedQuery` to allow its reuse by preview github APIs+  [#439](https://github.com/haskell-github/github/pull/439)+- Add endpoint for listing organizations outside collaborators+  [#445](https://github.com/haskell-github/github/pull/445)+- Add endpoint for users search+  [#444](https://github.com/haskell-github/github/pull/444)+- Make `repoWebhookResponseStatus` optional+  [#436](https://github.com/haskell-github/github/pull/436)+- Teams improvements+  [#417](https://github.com/haskell-github/github/pull/417)+- Add `deleteReference` endpoint+  [#388](https://github.com/haskell-github/github/pull/388)++## Changes for 0.25++_2020-02-18, Oleg Grenrus_++- Add `executeRequestWithMgrAndRes`+  [#421](https://github.com/haskell-github/github/pull/421)+- Add `limitsFromHttpResponse`+  [#421](https://github.com/haskell-github/github/pull/421)+- Add label descriptions+  [#418](https://github.com/haskell-github/github/pull/418)+- Add "draft" option to mergeable state+  [#431](https://github.com/haskell-github/github/pull/431)+- Use `IssueNumber` in `editIssueR` and `issueR`+  [#429](https://github.com/haskell-github/github/pull/429)+- Manage orgs in GitHub Enterprise+  [#420](https://github.com/haskell-github/github/pull/420)+- Add support for collaborator permission endpoint+  [#425](https://github.com/haskell-github/github/pull/425)+- Add support for the comment reply endpoint+  [#424](https://github.com/haskell-github/github/pull/424)+- Organise exports in `GitHub`+  [#430](https://github.com/haskell-github/github/pull/430)++## Changes for 0.24++_2019-11-27, Oleg Grenrus_++**Major change**:+Introduce `github` n-ary combinator to hoist `... -> Request rw res`+into `... -> IO (Either Error res)` (i.e. n-ary `executeRequest`).+With that in place drop `.. -> IO (Either Error res)` functions.++This reduces symbol bloat in the library.+[#415](https://github.com/haskell-github/github/pull/415)++- Remove double `withOpenSSL`+  [#414](https://github.com/haskell-github/github/pull/414)+- Pull requests reviews API uses issue number+  [#409](https://github.com/haskell-github/github/pull/409)+- Update `Repo`, `NewRepo` and `EditRepo` data types+  [#407](https://github.com/haskell-github/github/pull/407)++## Changes for 0.23++_2019-10-01, Oleg Grenrus_++- Escape URI paths+  [#404](https://github.com/haskell-github/github/pull/404)+- Add `OwnerBot` to `OwnerType`+  [#399](https://github.com/haskell-github/github/pull/399)+- Make `File.fileSha` optional+  [#392](https://github.com/haskell-github/github/pull/392)+- Update User-Agent to contain up to date version+  [#403](https://github.com/haskell-github/github/pull/403)+  [#394](https://github.com/haskell-github/github/pull/394)++## Changes for 0.22++_2019-05-31, Oleg Grenrus_++- Type-class for various auth methods+  [#365](https://github.com/haskell-github/github/pull/365)+- Throw on non-200 responses+  [#350](https://github.com/haskell-github/github/pull/350)+- Add extension point for (preview) media types+  [#370](https://github.com/haskell-github/github/pull/370)+- Add missing webhook event types+  [#359](https://github.com/haskell-github/github/pull/359)+- Add invitation endpoint+  [#360](https://github.com/haskell-github/github/pull/360)+- Add notifications endpoints+  [#324](https://github.com/haskell-github/github/pull/324)+- Add ssh keys endpoints+  [#363](https://github.com/haskell-github/github/pull/365)+- Case insensitive enum parsing+  [#373](https://github.com/haskell-github/github/pull/373)+- Don't try parse unitary responses+  [#377](https://github.com/haskell-github/github/issues/377)+- Update dependencies+  [#364](https://github.com/haskell-github/github/pull/364)+  [#368](https://github.com/haskell-github/github/pull/368)+  [#369](https://github.com/haskell-github/github/pull/369)+- Documentation improvements+  [#357](https://github.com/haskell-github/github/pull/357)++## Changes for 0.21++_2019-02-18, Oleg Grenrus_++- Refactor `Request` type.+  [#349](https://github.com/haskell-github/github/pull/349)+- Allow `http-client-0.6`+  [#344](https://github.com/haskell-github/github/pull/344)+- Change to use `cryptohash-sha1` (`cryptohash` was used before)+- Add Create milestone endpoints+  [#337](https://github.com/haskell-github/github/pull/337)+- Make `fileBlobUrl` and `fileRawUrl` optional+  [#339](https://github.com/haskell-github/github/issues/339)+  [#340](https://github.com/haskell-github/github/pull/340)+- Add `organizationsR` to request user organizations+  [#345](https://github.com/haskell-github/github/pull/345)+- Add `updateMilestoneR`, `deleteMilestoneR`+  [#338](https://github.com/haskell-github/github/pull/338)+- Allow multiple assignees in `NewIssue` and `EditIssue`+  [#336](https://github.com/haskell-github/github/pull/336)+- Add `pullRequestPatchR` and `pullRequestDiffR`+  [#325](https://github.com/haskell-github/github/pull/325)++## Changes for 0.20++_2018-09-26, Oleg Grenrus_++- Add ratelimit endpoint+  [#315](https://github.com/haskell-github/github/pull/315)+- Add some deployment endoints+  [#330](https://github.com/haskell-github/github/pull/330)+- Add webhook installation events+  [#329](https://github.com/haskell-github/github/pull/330)+- Tighten lower bounds (also remove `aeson-compat` dep)+  [#332](https://github.com/haskell-github/github/pull/332)+ ## Changes for 0.19 +_2018-02-19, Oleg Grenrus_+ - Fix issue event type enumeration-  [#301](https://github.com/phadej/github/issues/301)-- Include label info in `IssseEvent`-  [#302](https://github.com/phadej/github/issues/302)+  [#301](https://github.com/haskell-github/github/issues/301)+- Include label info in `IssueEvent`+  [#302](https://github.com/haskell-github/github/issues/302) - Fix `ShowRepo` example-  [#306](https://github.com/phadej/github/pull/306)+  [#306](https://github.com/haskell-github/github/pull/306) - Add "Get archive link" API-  [#307](https://github.com/phadej/github/pull/307)-- Make "repo" in PullRequestCommit nullable (repository can be gone)-  [#311](https://github.com/phadej/github/pull/311)-- Add 	read-only emails endpoint-  [#313](https://github.com/phadej/github/pull/313)+  [#307](https://github.com/haskell-github/github/pull/307)+- Make "repo" in `PullRequestCommit` nullable (repository can be gone)+  [#311](https://github.com/haskell-github/github/pull/311)+- Add read-only emails endpoint+  [#313](https://github.com/haskell-github/github/pull/313) - Organisation membership API-  [#312](https://github.com/phadej/github/pull/312)-- Fix isPullRequestMerged and other boolean responses-  [#312](https://github.com/phadej/github/pull/312)+  [#312](https://github.com/haskell-github/github/pull/312)+- Fix `isPullRequestMerged` and other boolean responses+  [#312](https://github.com/haskell-github/github/pull/312) - Add `behind` pull request mergeable state-  [#308](https://github.com/phadej/github/pull/308)+  [#308](https://github.com/haskell-github/github/pull/308) - Add list organisation invitations endpoint  ## Changes for 0.18 -- Endpoints for deleting issue comments. -  [#294](https://github.com/phadej/github/pull/294)+_2017-11-10, Oleg Grenrus_++- Endpoints for deleting issue comments.+  [#294](https://github.com/haskell-github/github/pull/294) - Endpoints for (un)starring gists.-  [#296](https://github.com/phadej/github/pull/296)+  [#296](https://github.com/haskell-github/github/pull/296) - Add `archived` field to `Repo`.-  [#298](https://github.com/phadej/github/pull/298)+  [#298](https://github.com/haskell-github/github/pull/298) - Update dependencies.-  [#295](https://github.com/phadej/github/pull/295)+  [#295](https://github.com/haskell-github/github/pull/295) - Add Statuses endpoints.-  [#268](https://github.com/phadej/github/pull/268)+  [#268](https://github.com/haskell-github/github/pull/268) - Add requested reviewers field to pull request records.-  [#292](https://github.com/phadej/github/pull/292)+  [#292](https://github.com/haskell-github/github/pull/292)  ## Changes for 0.17.0 +_2017-09-26, Oleg Grenrus_+ - Add `Ord Request` instance - Repository contents - Repository starring endpoints@@ -44,15 +289,19 @@  ## Changes for 0.16.0 +_2017-07-24, Oleg Grenrus_+ - Add support for `mergeable_state = "blocked".` - Fix HTTP status code of merge PR - Supports newest versions of dependencies - user events - release endpoints-- forkExistingRepo+- `forkExistingRepo`  ## Changes for 0.15.0 +_2016-11-04, Oleg Grenrus_+ - Reworked `PullRequest` (notably `pullRequestsFor`) - Reworked PR and Issue filtering - GHC-8.0.1 support@@ -62,19 +311,21 @@ - Add `HeaderQuery` to `Request` - Add `Hashable Auth` instance - Add `mkUserId`, `mkUserName`, `fromUserId`, `fromOrganizationId`-- Add 'userIssuesR'-- Add 'organizationIssuesR'+- Add `userIssuesR`+- Add `organizationIssuesR` - Make `teamName :: Text` amnd `teamSlug :: Name Team` in both: `Team` and `SimpleTeam`-- Refactor 'Request' structure+- Refactor `Request` structure - Added multiple issue assignees - Preliminary support for repository events: `repositoryEventsR` - Support for adding repository permissions to the team-- Remove 'simpleUserType', it was always the same.+- Remove `simpleUserType`, it was always the same. -See [git commit summary](https://github.com/phadej/github/compare/v0.14.1...v0.15.0)+See [git commit summary](https://github.com/haskell-github/github/compare/v0.14.1...v0.15.0)  ## Changes for 0.14.1 +_2016-02-02, Oleg Grenrus_+ - Add `membersOfWithR`, `listTeamMembersR` - Add related enums: `OrgMemberFilter`, `OrgMemberRole`, `TeamMemberRole` - Add `Enum` and `Bounded` instances to `Privacy`, `Permission`,@@ -83,6 +334,8 @@  ## Changes for 0.14.0 +_2016-01-25, Oleg Grenrus_+ Large API changes:  - Use `Text` and `Vector` in place of `String` and `[]`.@@ -92,28 +345,56 @@ - Add `Binary` instances for all data - `GithubOwner` is a `newtype` of `Either User Organization`. There's still `SimpleOwner`. +## Releases without changelog++| Version | Date  | Uploader  |+|---|---|---|+| __0.13.2__ | _2015-04-26_ | _John Wiegley_        |+| __0.13.1__ | _2014-12-01_ | _César López-Natarén_ |+| __0.13__   | _2014-11-09_ | _César López-Natarén_ |+| __0.12__   | _2014-11-09_ | _César López-Natarén_ |+| __0.11.1__ | _2014-09-07_ | _César López-Natarén_ |+| __0.11.0__ | _2014-08-25_ | _César López-Natarén_ |+| __0.10.0__ | _2014-08-18_ | _César López-Natarén_ |+| __0.9__    | _2014-07-31_ | _John Wiegley_        |+| __0.8__    | _2014-05-02_ | _John Wiegley_        |+| __0.7.4__  | _2014-01-22_ | _John Wiegley_        |+| __0.7.3__  | _2013-12-21_ | _John Wiegley_        |+| __0.7.2__  | _2013-12-02_ | _John Wiegley_        |+| __0.7.1__  | _2013-08-08_ | _John Wiegley_        |+| __0.7.0__  | _2013-04-26_ | _John Wiegley_        |+| __0.6.0__  | _2013-04-12_ | _John Wiegley_        |+ ## Changes for 0.5.0: -* OAuth.+_2013-02-05, Mike Burns_++* `OAuth`. * New function: `Github.Repos.organizationRepo`, to get the repo for a specific organization. * Introduce a new `newRepoAutoInit` flag to `NewRepo`, for whether to initialize a repo while creating it.-* Relax the attoparsec version requirements.+* Relax the `attoparsec` version requirements. * The above by [John Wiegley](https://github.com/jwiegley).  ## Changes for 0.4.1: -* Stop using the uri package.-* Use aeson version 0.6.1.0.-* Use attoparsec version 0.10.3.0.-* Use http-conduit over 1.8.-* Use unordered-containers between 0.2 and 0.3.+_2013-01-14, Mike Burns_ +* Stop using the `uri` package.+* Use `aeson` version 0.6.1.0.+* Use `attoparsec` version 0.10.3.0.+* Use `http-conduit` over 1.8.+* Use `unordered-containers` between 0.2 and 0.3.+ ## Changes for 0.4.0: -* Use http-conduit version 1.4.1.10.+_2012-06-26, Mike Burns_ +* Use `http-conduit` version 1.4.1.10.+ ## Changes for 0.3.0: +_2012-06-10, Mike Burns_+ * Re-instantiate the Blobs API. * `repoDescription1` and `repoPushedAt` are a `Maybe GithubDate`. * Add `deleteRepo`, `editRepo`, and `createRepo`.@@ -124,13 +405,17 @@  ## Changes for 0.2.1: -* Expand the unordered-containers dependency to anything in 0.1.x .+_2012-02-16, Mike Burns_ +* Expand the `unordered-containers` dependency to anything in 0.1.x .+ ## Changes for 0.2.0: +_2012-02-15, Mike Burns_+ * `milestoneDueOn` and `repoLanguage` are now `Maybe` types.-* Introduce `GithubOwner` as the sum type for a `GithubUser` or `GithubOrganization`. Everything that once produced a `GithubUser` now produces a `GithubOwner`. All record accessors have changed their names-* Similar to `GithubOwner`, introduce `DetailedOwner`, which can be a `DetailedUser` or a `DetailedOrganization`. All record accessors have changed their names+* Introduce `GithubOwner` as the sum type for a `GithubUser` or `GithubOrganization`. Everything that once produced a `GithubUser` now produces a `GithubOwner`. All record accessors have changed their names.+* Similar to `GithubOwner`, introduce `DetailedOwner`, which can be a `DetailedUser` or a `DetailedOrganization`. All record accessors have changed their names. * An `HTTPConnectionError` now composes `SomeException` instead of `IOException`. All exceptions raised by the underlying http-conduit library are encapulated there. * The `githubIssueClosedBy` function now produces a `Maybe GithubOwner`. * Remove the Blobs API, as it is broken upstream.
README.md view
@@ -1,15 +1,15 @@-Github+GitHub ------ -[![Build Status](https://travis-ci.org/phadej/github.svg?branch=master)](https://travis-ci.org/phadej/github)-[![Hackage](https://img.shields.io/hackage/v/github.svg)][hackage]-[![Stackage LTS 5](http://stackage.org/package/github/badge/lts-5)](http://stackage.org/lts-5/package/github)-[![Stackage Nightly](http://stackage.org/package/github/badge/nightly)](http://stackage.org/nightly/package/github)+[![Hackage version](https://img.shields.io/hackage/v/github.svg?label=Hackage&color=informational)](http://hackage.haskell.org/package/github)+[![github on Stackage Nightly](https://stackage.org/package/github/badge/nightly)](https://stackage.org/nightly/package/github)+[![Stackage LTS version](https://www.stackage.org/package/github/badge/lts?label=Stackage)](https://www.stackage.org/package/github)+[![Haskell-CI](https://github.com/haskell-github/github/actions/workflows/haskell-ci.yml/badge.svg)](https://github.com/haskell-github/github/actions/workflows/haskell-ci.yml) -The Github API v3 for Haskell.+The GitHub API v3 for Haskell. -Some functions are missing; these are functions where the Github API did-not work as expected. The full Github API is in beta and constantly+Some functions are missing; these are functions where the GitHub API did+not work as expected. The full GitHub API is in beta and constantly improving.  Installation@@ -18,31 +18,32 @@ In your project's cabal file:  ```cabal--- Packages needed in order to build this package. Build-depends:       github ```  Or from the command line:  ```sh-cabal install github+cabal v1-install github ```  Example Usage =============  See the samples in the-[samples/](https://github.com/fpco/github/tree/master/samples) directory.+[samples/](https://github.com/haskell-github/github/tree/master/samples) directory. +Note: some samples might be outdated.+ Documentation =============  For details see the reference [documentation on Hackage][hackage].  Each module lines up with the hierarchy of-[documentation from the Github API](http://developer.github.com/v3/).+[documentation from the GitHub API](https://docs.github.com/en/rest). -Request functions (ending with `R`) construct a data type with can be executed+Request functions (ending with `R`) construct a data type which can be executed in `IO` by `executeRequest` functions. They are all listed in the root `GitHub` module. @@ -51,7 +52,7 @@ possible error message. Here's an example from the samples:  Many function have samples under-[`samples/`](https://github.com/phadej/github/tree/master/samples) directory.+[`samples/`](https://github.com/haskell-github/github/tree/master/samples) directory.  ```hs {-# LANGUAGE NoImplicitPrelude #-}@@ -63,11 +64,12 @@ import Data.Text.IO as T (putStrLn) import Data.Monoid       ((<>)) -import qualified GitHub.Endpoints.Users.Followers as GitHub+import GitHub (github')+import qualified GitHub  main :: IO () main = do-    possibleUsers <- GitHub.usersFollowing "mike-burns"+    possibleUsers <- github' GitHub.usersFollowingR "phadej"     T.putStrLn $ either (("Error: " <>) . pack . show)                         (foldMap ((<> "\n") . formatUser))                         possibleUsers@@ -76,21 +78,11 @@ formatUser = GitHub.untagName . GitHub.simpleUserLogin ``` -Test setup-==========--To run integration part of tests, you'll need [github access token](https://github.com/settings/tokens/new)-Token is needed, because unauthorised access is highly limited.-It's enough to add only basic read access for public information.--With `travis encrypt --org --repo yournick/github "GITHUB_TOKEN=yourtoken"` command you get a secret,-you can use in your travis setup to run the test-suite there.- Contributions =============  Please see-[CONTRIBUTING.md](https://github.com/fpco/github/blob/master/CONTRIBUTING.md)+[CONTRIBUTING.md](https://github.com/haskell-github/github/blob/master/CONTRIBUTING.md) for details on how you can help.  Copyright@@ -98,8 +90,16 @@  Copyright 2011-2012 Mike Burns. Copyright 2013-2015 John Wiegley.-Copyright 2016 Oleg Grenrus.+Copyright 2016-2019 Oleg Grenrus.  Available under the BSD 3-clause license. -[hackage]: http://hackage.haskell.org/package/github "Hackage"+[hackage]: https://hackage.haskell.org/package/github "Hackage"++Alternative+===========++Library [`github-rest`](https://hackage.haskell.org/package/github-rest)+also provides an interface to the GitHub API.+It compares itself to `github` here:+https://github.com/LeapYear/github-rest#comparison-to-other-libraries
+ fixtures/actions/artifact.json view
@@ -0,0 +1,19 @@+{+  "id": 416767789,+  "node_id": "MDg6QXJ0aWZhY3Q0MTY3Njc3ODk=",+  "name": "dist-without-markdown",+  "size_in_bytes": 42718,+  "url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/artifacts/416767789",+  "archive_download_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/artifacts/416767789/zip",+  "expired": false,+  "created_at": "2022-10-29T22:18:21Z",+  "updated_at": "2022-10-29T22:18:23Z",+  "expires_at": "2023-01-27T22:18:16Z",+  "workflow_run": {+    "id": 3353148947,+    "repository_id": 559365297,+    "head_repository_id": 559365297,+    "head_branch": "main",+    "head_sha": "601593ecb1d8a57a04700fdb445a28d4186b8954"+  }+}
+ fixtures/actions/artifacts-list.json view
@@ -0,0 +1,43 @@+{+  "total_count": 23809,+  "artifacts": [+    {+      "id": 416737084,+      "node_id": "MDg6QXJ0aWZhY3Q0MTY3MzcwODQ=",+      "name": "doc-html",+      "size_in_bytes": 61667543,+      "url": "https://api.github.com/repos/python/cpython/actions/artifacts/416737084",+      "archive_download_url": "https://api.github.com/repos/python/cpython/actions/artifacts/416737084/zip",+      "expired": false,+      "created_at": "2022-10-29T20:56:24Z",+      "updated_at": "2022-10-29T20:56:25Z",+      "expires_at": "2023-01-27T20:50:21Z",+      "workflow_run": {+        "id": 3352897496,+        "repository_id": 81598961,+        "head_repository_id": 101955313,+        "head_branch": "backport-bfecff5-3.11",+        "head_sha": "692cd77975413d71ff0951072df686e6f38711c8"+      }+    },+    {+      "id": 416712612,+      "node_id": "MDg6QXJ0aWZhY3Q0MTY3MTI2MTI=",+      "name": "doc-html",+      "size_in_bytes": 61217330,+      "url": "https://api.github.com/repos/python/cpython/actions/artifacts/416712612",+      "archive_download_url": "https://api.github.com/repos/python/cpython/actions/artifacts/416712612/zip",+      "expired": false,+      "created_at": "2022-10-29T19:53:19Z",+      "updated_at": "2022-10-29T19:53:20Z",+      "expires_at": "2023-01-27T19:49:12Z",+      "workflow_run": {+        "id": 3352724493,+        "repository_id": 81598961,+        "head_repository_id": 559335486,+        "head_branch": "patch-1",+        "head_sha": "62eb88a66d1d35f7701873d8b698a2f8d7e84fa5"+      }+    }+  ]+}
+ fixtures/actions/cache-list.json view
@@ -0,0 +1,14 @@+{+  "total_count": 1,+  "actions_caches": [+    {+      "id": 1,+      "ref": "refs/heads/main",+      "key": "cache_key",+      "version": "f5f850afdadd47730296d4ffa900de95f6bbafb75dc1e8475df1fa6ae79dcece",+      "last_accessed_at": "2022-10-30T00:08:14.223333300Z",+      "created_at": "2022-10-30T00:08:14.223333300Z",+      "size_in_bytes": 26586+    }+  ]+}
+ fixtures/actions/org-cache-usage.json view
@@ -0,0 +1,4 @@+{+  "total_active_caches_size_in_bytes": 26586,+  "total_active_caches_count": 1+}
+ fixtures/actions/org-public-key.json view
@@ -0,0 +1,4 @@+{+  "key_id": "568250167242549743",+  "key": "KHVvOxB765kjkShEgUu27QCzl5XxKz/L20V+KRsWf0w="+}
+ fixtures/actions/org-secrets-list.json view
@@ -0,0 +1,18 @@+{+  "total_count": 2,+  "secrets": [+    {+      "name": "TEST_SECRET",+      "created_at": "2022-10-31T00:08:12Z",+      "updated_at": "2022-10-31T00:08:12Z",+      "visibility": "all"+    },+    {+      "name": "TEST_SELECTED",+      "created_at": "2022-10-31T00:08:43Z",+      "updated_at": "2022-10-31T00:08:43Z",+      "visibility": "selected",+      "selected_repositories_url": "https://api.github.com/orgs/kote-test-org-actions/actions/secrets/TEST_SELECTED/repositories"+    }+  ]+}
+ fixtures/actions/repo-cache-usage.json view
@@ -0,0 +1,5 @@+{+  "full_name": "python/cpython",+  "active_caches_size_in_bytes": 55000268087,+  "active_caches_count": 171+}
+ fixtures/actions/selected-repositories-for-secret.json view
@@ -0,0 +1,72 @@+{+  "total_count": 1,+  "repositories": [+    {+      "id": 559365297,+      "node_id": "R_kgDOIVc8sQ",+      "name": "actions-api",+      "full_name": "kote-test-org-actions/actions-api",+      "private": true,+      "owner": {+        "login": "kote-test-org-actions",+        "id": 116976977,+        "node_id": "O_kgDOBvjtUQ",+        "avatar_url": "https://avatars.githubusercontent.com/u/116976977?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/kote-test-org-actions",+        "html_url": "https://github.com/kote-test-org-actions",+        "followers_url": "https://api.github.com/users/kote-test-org-actions/followers",+        "following_url": "https://api.github.com/users/kote-test-org-actions/following{/other_user}",+        "gists_url": "https://api.github.com/users/kote-test-org-actions/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/kote-test-org-actions/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/kote-test-org-actions/subscriptions",+        "organizations_url": "https://api.github.com/users/kote-test-org-actions/orgs",+        "repos_url": "https://api.github.com/users/kote-test-org-actions/repos",+        "events_url": "https://api.github.com/users/kote-test-org-actions/events{/privacy}",+        "received_events_url": "https://api.github.com/users/kote-test-org-actions/received_events",+        "type": "Organization",+        "site_admin": false+      },+      "html_url": "https://github.com/kote-test-org-actions/actions-api",+      "description": null,+      "fork": false,+      "url": "https://api.github.com/repos/kote-test-org-actions/actions-api",+      "forks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/forks",+      "keys_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/keys{/key_id}",+      "collaborators_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/collaborators{/collaborator}",+      "teams_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/teams",+      "hooks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/hooks",+      "issue_events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/events{/number}",+      "events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/events",+      "assignees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/assignees{/user}",+      "branches_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/branches{/branch}",+      "tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/tags",+      "blobs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/blobs{/sha}",+      "git_tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/tags{/sha}",+      "git_refs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/refs{/sha}",+      "trees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/trees{/sha}",+      "statuses_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/statuses/{sha}",+      "languages_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/languages",+      "stargazers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/stargazers",+      "contributors_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contributors",+      "subscribers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscribers",+      "subscription_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscription",+      "commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/commits{/sha}",+      "git_commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/commits{/sha}",+      "comments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/comments{/number}",+      "issue_comment_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/comments{/number}",+      "contents_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contents/{+path}",+      "compare_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/compare/{base}...{head}",+      "merges_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/merges",+      "archive_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/{archive_format}{/ref}",+      "downloads_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/downloads",+      "issues_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues{/number}",+      "pulls_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/pulls{/number}",+      "milestones_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/milestones{/number}",+      "notifications_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/notifications{?since,all,participating}",+      "labels_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/labels{/name}",+      "releases_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/releases{/id}",+      "deployments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/deployments"+    }+  ]+}
+ fixtures/actions/workflow-job.json view
@@ -0,0 +1,113 @@+{+  "id": 9183275828,+  "run_id": 3353449941,+  "run_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353449941",+  "run_attempt": 1,+  "node_id": "CR_kwDOIVc8sc8AAAACI12rNA",+  "head_sha": "3156f684232a3adec5085c920d2006aca80f2798",+  "url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/jobs/9183275828",+  "html_url": "https://github.com/kote-test-org-actions/actions-api/actions/runs/3353449941/jobs/5556228789",+  "status": "completed",+  "conclusion": "success",+  "started_at": "2022-10-30T00:09:29Z",+  "completed_at": "2022-10-30T00:09:49Z",+  "name": "check-bats-version",+  "steps": [+    {+      "name": "Set up job",+      "status": "completed",+      "conclusion": "success",+      "number": 1,+      "started_at": "2022-10-29T17:09:29.000-07:00",+      "completed_at": "2022-10-29T17:09:32.000-07:00"+    },+    {+      "name": "Run actions/checkout@v3",+      "status": "completed",+      "conclusion": "success",+      "number": 2,+      "started_at": "2022-10-29T17:09:32.000-07:00",+      "completed_at": "2022-10-29T17:09:33.000-07:00"+    },+    {+      "name": "Run actions/setup-node@v3",+      "status": "completed",+      "conclusion": "success",+      "number": 3,+      "started_at": "2022-10-29T17:09:34.000-07:00",+      "completed_at": "2022-10-29T17:09:39.000-07:00"+    },+    {+      "name": "Run npm install -g bats",+      "status": "completed",+      "conclusion": "success",+      "number": 4,+      "started_at": "2022-10-29T17:09:40.000-07:00",+      "completed_at": "2022-10-29T17:09:42.000-07:00"+    },+    {+      "name": "Run bats -v",+      "status": "completed",+      "conclusion": "success",+      "number": 5,+      "started_at": "2022-10-29T17:09:42.000-07:00",+      "completed_at": "2022-10-29T17:09:42.000-07:00"+    },+    {+      "name": "Archive Test",+      "status": "completed",+      "conclusion": "success",+      "number": 6,+      "started_at": "2022-10-29T17:09:42.000-07:00",+      "completed_at": "2022-10-29T17:09:46.000-07:00"+    },+    {+      "name": "Cache",+      "status": "completed",+      "conclusion": "success",+      "number": 7,+      "started_at": "2022-10-29T17:09:46.000-07:00",+      "completed_at": "2022-10-29T17:09:47.000-07:00"+    },+    {+      "name": "Post Cache",+      "status": "completed",+      "conclusion": "success",+      "number": 12,+      "started_at": "2022-10-29T17:09:49.000-07:00",+      "completed_at": "2022-10-29T17:09:47.000-07:00"+    },+    {+      "name": "Post Run actions/setup-node@v3",+      "status": "completed",+      "conclusion": "success",+      "number": 13,+      "started_at": "2022-10-29T17:09:49.000-07:00",+      "completed_at": "2022-10-29T17:09:49.000-07:00"+    },+    {+      "name": "Post Run actions/checkout@v3",+      "status": "completed",+      "conclusion": "success",+      "number": 14,+      "started_at": "2022-10-29T17:09:49.000-07:00",+      "completed_at": "2022-10-29T17:09:49.000-07:00"+    },+    {+      "name": "Complete job",+      "status": "completed",+      "conclusion": "success",+      "number": 15,+      "started_at": "2022-10-29T17:09:47.000-07:00",+      "completed_at": "2022-10-29T17:09:47.000-07:00"+    }+  ],+  "check_run_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/check-runs/9183275828",+  "labels": [+    "ubuntu-latest"+  ],+  "runner_id": 1,+  "runner_name": "Hosted Agent",+  "runner_group_id": 2,+  "runner_group_name": "GitHub Actions"+}
+ fixtures/actions/workflow-list.json view
@@ -0,0 +1,17 @@+{+  "total_count": 1,+  "workflows": [+    {+      "id": 39065091,+      "node_id": "W_kwDOIVc8sc4CVBYD",+      "name": "learn-github-actions",+      "path": ".github/workflows/make_artifact.yaml",+      "state": "active",+      "created_at": "2022-10-29T15:17:59.000-07:00",+      "updated_at": "2022-10-29T15:17:59.000-07:00",+      "url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/workflows/39065091",+      "html_url": "https://github.com/kote-test-org-actions/actions-api/blob/main/.github/workflows/make_artifact.yaml",+      "badge_url": "https://github.com/kote-test-org-actions/actions-api/workflows/learn-github-actions/badge.svg"+    }+  ]+}
+ fixtures/actions/workflow-runs-list.json view
@@ -0,0 +1,665 @@+{+  "total_count": 3,+  "workflow_runs": [+    {+      "id": 3353449941,+      "name": "K0Te is learning GitHub Actions",+      "node_id": "WFR_kwLOIVc8sc7H4ZXV",+      "head_branch": "main",+      "head_sha": "3156f684232a3adec5085c920d2006aca80f2798",+      "path": ".github/workflows/make_artifact.yaml",+      "display_title": "K0Te is learning GitHub Actions",+      "run_number": 3,+      "event": "push",+      "status": "completed",+      "conclusion": "success",+      "workflow_id": 39065091,+      "check_suite_id": 9030268154,+      "check_suite_node_id": "CS_kwDOIVc8sc8AAAACGj70-g",+      "url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353449941",+      "html_url": "https://github.com/kote-test-org-actions/actions-api/actions/runs/3353449941",+      "pull_requests": [],+      "created_at": "2022-10-30T00:09:22Z",+      "updated_at": "2022-10-30T00:09:50Z",+      "actor": {+        "login": "K0Te",+        "id": 6162155,+        "node_id": "MDQ6VXNlcjYxNjIxNTU=",+        "avatar_url": "https://avatars.githubusercontent.com/u/6162155?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/K0Te",+        "html_url": "https://github.com/K0Te",+        "followers_url": "https://api.github.com/users/K0Te/followers",+        "following_url": "https://api.github.com/users/K0Te/following{/other_user}",+        "gists_url": "https://api.github.com/users/K0Te/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/K0Te/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/K0Te/subscriptions",+        "organizations_url": "https://api.github.com/users/K0Te/orgs",+        "repos_url": "https://api.github.com/users/K0Te/repos",+        "events_url": "https://api.github.com/users/K0Te/events{/privacy}",+        "received_events_url": "https://api.github.com/users/K0Te/received_events",+        "type": "User",+        "site_admin": false+      },+      "run_attempt": 1,+      "referenced_workflows": [],+      "run_started_at": "2022-10-30T00:09:22Z",+      "triggering_actor": {+        "login": "K0Te",+        "id": 6162155,+        "node_id": "MDQ6VXNlcjYxNjIxNTU=",+        "avatar_url": "https://avatars.githubusercontent.com/u/6162155?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/K0Te",+        "html_url": "https://github.com/K0Te",+        "followers_url": "https://api.github.com/users/K0Te/followers",+        "following_url": "https://api.github.com/users/K0Te/following{/other_user}",+        "gists_url": "https://api.github.com/users/K0Te/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/K0Te/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/K0Te/subscriptions",+        "organizations_url": "https://api.github.com/users/K0Te/orgs",+        "repos_url": "https://api.github.com/users/K0Te/repos",+        "events_url": "https://api.github.com/users/K0Te/events{/privacy}",+        "received_events_url": "https://api.github.com/users/K0Te/received_events",+        "type": "User",+        "site_admin": false+      },+      "jobs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353449941/jobs",+      "logs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353449941/logs",+      "check_suite_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/check-suites/9030268154",+      "artifacts_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353449941/artifacts",+      "cancel_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353449941/cancel",+      "rerun_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353449941/rerun",+      "previous_attempt_url": null,+      "workflow_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/workflows/39065091",+      "head_commit": {+        "id": "3156f684232a3adec5085c920d2006aca80f2798",+        "tree_id": "f51ba8632086ca7af92f5e58c1dc98df1c62d7ce",+        "message": "up",+        "timestamp": "2022-10-30T00:09:16Z",+        "author": {+          "name": "Oleg Nykolyn",+          "email": "juravel2@gmail.com"+        },+        "committer": {+          "name": "Oleg Nykolyn",+          "email": "juravel2@gmail.com"+        }+      },+      "repository": {+        "id": 559365297,+        "node_id": "R_kgDOIVc8sQ",+        "name": "actions-api",+        "full_name": "kote-test-org-actions/actions-api",+        "private": true,+        "owner": {+          "login": "kote-test-org-actions",+          "id": 116976977,+          "node_id": "O_kgDOBvjtUQ",+          "avatar_url": "https://avatars.githubusercontent.com/u/116976977?v=4",+          "gravatar_id": "",+          "url": "https://api.github.com/users/kote-test-org-actions",+          "html_url": "https://github.com/kote-test-org-actions",+          "followers_url": "https://api.github.com/users/kote-test-org-actions/followers",+          "following_url": "https://api.github.com/users/kote-test-org-actions/following{/other_user}",+          "gists_url": "https://api.github.com/users/kote-test-org-actions/gists{/gist_id}",+          "starred_url": "https://api.github.com/users/kote-test-org-actions/starred{/owner}{/repo}",+          "subscriptions_url": "https://api.github.com/users/kote-test-org-actions/subscriptions",+          "organizations_url": "https://api.github.com/users/kote-test-org-actions/orgs",+          "repos_url": "https://api.github.com/users/kote-test-org-actions/repos",+          "events_url": "https://api.github.com/users/kote-test-org-actions/events{/privacy}",+          "received_events_url": "https://api.github.com/users/kote-test-org-actions/received_events",+          "type": "Organization",+          "site_admin": false+        },+        "html_url": "https://github.com/kote-test-org-actions/actions-api",+        "description": null,+        "fork": false,+        "url": "https://api.github.com/repos/kote-test-org-actions/actions-api",+        "forks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/forks",+        "keys_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/keys{/key_id}",+        "collaborators_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/collaborators{/collaborator}",+        "teams_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/teams",+        "hooks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/hooks",+        "issue_events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/events{/number}",+        "events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/events",+        "assignees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/assignees{/user}",+        "branches_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/branches{/branch}",+        "tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/tags",+        "blobs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/blobs{/sha}",+        "git_tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/tags{/sha}",+        "git_refs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/refs{/sha}",+        "trees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/trees{/sha}",+        "statuses_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/statuses/{sha}",+        "languages_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/languages",+        "stargazers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/stargazers",+        "contributors_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contributors",+        "subscribers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscribers",+        "subscription_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscription",+        "commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/commits{/sha}",+        "git_commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/commits{/sha}",+        "comments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/comments{/number}",+        "issue_comment_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/comments{/number}",+        "contents_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contents/{+path}",+        "compare_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/compare/{base}...{head}",+        "merges_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/merges",+        "archive_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/{archive_format}{/ref}",+        "downloads_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/downloads",+        "issues_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues{/number}",+        "pulls_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/pulls{/number}",+        "milestones_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/milestones{/number}",+        "notifications_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/notifications{?since,all,participating}",+        "labels_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/labels{/name}",+        "releases_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/releases{/id}",+        "deployments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/deployments"+      },+      "head_repository": {+        "id": 559365297,+        "node_id": "R_kgDOIVc8sQ",+        "name": "actions-api",+        "full_name": "kote-test-org-actions/actions-api",+        "private": true,+        "owner": {+          "login": "kote-test-org-actions",+          "id": 116976977,+          "node_id": "O_kgDOBvjtUQ",+          "avatar_url": "https://avatars.githubusercontent.com/u/116976977?v=4",+          "gravatar_id": "",+          "url": "https://api.github.com/users/kote-test-org-actions",+          "html_url": "https://github.com/kote-test-org-actions",+          "followers_url": "https://api.github.com/users/kote-test-org-actions/followers",+          "following_url": "https://api.github.com/users/kote-test-org-actions/following{/other_user}",+          "gists_url": "https://api.github.com/users/kote-test-org-actions/gists{/gist_id}",+          "starred_url": "https://api.github.com/users/kote-test-org-actions/starred{/owner}{/repo}",+          "subscriptions_url": "https://api.github.com/users/kote-test-org-actions/subscriptions",+          "organizations_url": "https://api.github.com/users/kote-test-org-actions/orgs",+          "repos_url": "https://api.github.com/users/kote-test-org-actions/repos",+          "events_url": "https://api.github.com/users/kote-test-org-actions/events{/privacy}",+          "received_events_url": "https://api.github.com/users/kote-test-org-actions/received_events",+          "type": "Organization",+          "site_admin": false+        },+        "html_url": "https://github.com/kote-test-org-actions/actions-api",+        "description": null,+        "fork": false,+        "url": "https://api.github.com/repos/kote-test-org-actions/actions-api",+        "forks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/forks",+        "keys_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/keys{/key_id}",+        "collaborators_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/collaborators{/collaborator}",+        "teams_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/teams",+        "hooks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/hooks",+        "issue_events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/events{/number}",+        "events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/events",+        "assignees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/assignees{/user}",+        "branches_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/branches{/branch}",+        "tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/tags",+        "blobs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/blobs{/sha}",+        "git_tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/tags{/sha}",+        "git_refs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/refs{/sha}",+        "trees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/trees{/sha}",+        "statuses_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/statuses/{sha}",+        "languages_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/languages",+        "stargazers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/stargazers",+        "contributors_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contributors",+        "subscribers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscribers",+        "subscription_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscription",+        "commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/commits{/sha}",+        "git_commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/commits{/sha}",+        "comments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/comments{/number}",+        "issue_comment_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/comments{/number}",+        "contents_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contents/{+path}",+        "compare_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/compare/{base}...{head}",+        "merges_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/merges",+        "archive_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/{archive_format}{/ref}",+        "downloads_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/downloads",+        "issues_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues{/number}",+        "pulls_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/pulls{/number}",+        "milestones_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/milestones{/number}",+        "notifications_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/notifications{?since,all,participating}",+        "labels_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/labels{/name}",+        "releases_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/releases{/id}",+        "deployments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/deployments"+      }+    },+    {+      "id": 3353445625,+      "name": "K0Te is learning GitHub Actions",+      "node_id": "WFR_kwLOIVc8sc7H4YT5",+      "head_branch": "main",+      "head_sha": "2d2486b9aecb80bf916717f47f7c312431d3ceb6",+      "path": ".github/workflows/make_artifact.yaml",+      "display_title": "K0Te is learning GitHub Actions",+      "run_number": 2,+      "event": "push",+      "status": "completed",+      "conclusion": "success",+      "workflow_id": 39065091,+      "check_suite_id": 9030259685,+      "check_suite_node_id": "CS_kwDOIVc8sc8AAAACGj7T5Q",+      "url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353445625",+      "html_url": "https://github.com/kote-test-org-actions/actions-api/actions/runs/3353445625",+      "pull_requests": [],+      "created_at": "2022-10-30T00:07:49Z",+      "updated_at": "2022-10-30T00:08:19Z",+      "actor": {+        "login": "K0Te",+        "id": 6162155,+        "node_id": "MDQ6VXNlcjYxNjIxNTU=",+        "avatar_url": "https://avatars.githubusercontent.com/u/6162155?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/K0Te",+        "html_url": "https://github.com/K0Te",+        "followers_url": "https://api.github.com/users/K0Te/followers",+        "following_url": "https://api.github.com/users/K0Te/following{/other_user}",+        "gists_url": "https://api.github.com/users/K0Te/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/K0Te/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/K0Te/subscriptions",+        "organizations_url": "https://api.github.com/users/K0Te/orgs",+        "repos_url": "https://api.github.com/users/K0Te/repos",+        "events_url": "https://api.github.com/users/K0Te/events{/privacy}",+        "received_events_url": "https://api.github.com/users/K0Te/received_events",+        "type": "User",+        "site_admin": false+      },+      "run_attempt": 1,+      "referenced_workflows": [],+      "run_started_at": "2022-10-30T00:07:49Z",+      "triggering_actor": {+        "login": "K0Te",+        "id": 6162155,+        "node_id": "MDQ6VXNlcjYxNjIxNTU=",+        "avatar_url": "https://avatars.githubusercontent.com/u/6162155?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/K0Te",+        "html_url": "https://github.com/K0Te",+        "followers_url": "https://api.github.com/users/K0Te/followers",+        "following_url": "https://api.github.com/users/K0Te/following{/other_user}",+        "gists_url": "https://api.github.com/users/K0Te/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/K0Te/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/K0Te/subscriptions",+        "organizations_url": "https://api.github.com/users/K0Te/orgs",+        "repos_url": "https://api.github.com/users/K0Te/repos",+        "events_url": "https://api.github.com/users/K0Te/events{/privacy}",+        "received_events_url": "https://api.github.com/users/K0Te/received_events",+        "type": "User",+        "site_admin": false+      },+      "jobs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353445625/jobs",+      "logs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353445625/logs",+      "check_suite_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/check-suites/9030259685",+      "artifacts_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353445625/artifacts",+      "cancel_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353445625/cancel",+      "rerun_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353445625/rerun",+      "previous_attempt_url": null,+      "workflow_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/workflows/39065091",+      "head_commit": {+        "id": "2d2486b9aecb80bf916717f47f7c312431d3ceb6",+        "tree_id": "21d858674ab650ea734b7efbf05442a21685d121",+        "message": "up",+        "timestamp": "2022-10-30T00:07:44Z",+        "author": {+          "name": "Oleg Nykolyn",+          "email": "juravel2@gmail.com"+        },+        "committer": {+          "name": "Oleg Nykolyn",+          "email": "juravel2@gmail.com"+        }+      },+      "repository": {+        "id": 559365297,+        "node_id": "R_kgDOIVc8sQ",+        "name": "actions-api",+        "full_name": "kote-test-org-actions/actions-api",+        "private": true,+        "owner": {+          "login": "kote-test-org-actions",+          "id": 116976977,+          "node_id": "O_kgDOBvjtUQ",+          "avatar_url": "https://avatars.githubusercontent.com/u/116976977?v=4",+          "gravatar_id": "",+          "url": "https://api.github.com/users/kote-test-org-actions",+          "html_url": "https://github.com/kote-test-org-actions",+          "followers_url": "https://api.github.com/users/kote-test-org-actions/followers",+          "following_url": "https://api.github.com/users/kote-test-org-actions/following{/other_user}",+          "gists_url": "https://api.github.com/users/kote-test-org-actions/gists{/gist_id}",+          "starred_url": "https://api.github.com/users/kote-test-org-actions/starred{/owner}{/repo}",+          "subscriptions_url": "https://api.github.com/users/kote-test-org-actions/subscriptions",+          "organizations_url": "https://api.github.com/users/kote-test-org-actions/orgs",+          "repos_url": "https://api.github.com/users/kote-test-org-actions/repos",+          "events_url": "https://api.github.com/users/kote-test-org-actions/events{/privacy}",+          "received_events_url": "https://api.github.com/users/kote-test-org-actions/received_events",+          "type": "Organization",+          "site_admin": false+        },+        "html_url": "https://github.com/kote-test-org-actions/actions-api",+        "description": null,+        "fork": false,+        "url": "https://api.github.com/repos/kote-test-org-actions/actions-api",+        "forks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/forks",+        "keys_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/keys{/key_id}",+        "collaborators_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/collaborators{/collaborator}",+        "teams_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/teams",+        "hooks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/hooks",+        "issue_events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/events{/number}",+        "events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/events",+        "assignees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/assignees{/user}",+        "branches_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/branches{/branch}",+        "tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/tags",+        "blobs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/blobs{/sha}",+        "git_tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/tags{/sha}",+        "git_refs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/refs{/sha}",+        "trees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/trees{/sha}",+        "statuses_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/statuses/{sha}",+        "languages_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/languages",+        "stargazers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/stargazers",+        "contributors_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contributors",+        "subscribers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscribers",+        "subscription_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscription",+        "commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/commits{/sha}",+        "git_commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/commits{/sha}",+        "comments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/comments{/number}",+        "issue_comment_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/comments{/number}",+        "contents_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contents/{+path}",+        "compare_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/compare/{base}...{head}",+        "merges_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/merges",+        "archive_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/{archive_format}{/ref}",+        "downloads_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/downloads",+        "issues_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues{/number}",+        "pulls_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/pulls{/number}",+        "milestones_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/milestones{/number}",+        "notifications_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/notifications{?since,all,participating}",+        "labels_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/labels{/name}",+        "releases_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/releases{/id}",+        "deployments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/deployments"+      },+      "head_repository": {+        "id": 559365297,+        "node_id": "R_kgDOIVc8sQ",+        "name": "actions-api",+        "full_name": "kote-test-org-actions/actions-api",+        "private": true,+        "owner": {+          "login": "kote-test-org-actions",+          "id": 116976977,+          "node_id": "O_kgDOBvjtUQ",+          "avatar_url": "https://avatars.githubusercontent.com/u/116976977?v=4",+          "gravatar_id": "",+          "url": "https://api.github.com/users/kote-test-org-actions",+          "html_url": "https://github.com/kote-test-org-actions",+          "followers_url": "https://api.github.com/users/kote-test-org-actions/followers",+          "following_url": "https://api.github.com/users/kote-test-org-actions/following{/other_user}",+          "gists_url": "https://api.github.com/users/kote-test-org-actions/gists{/gist_id}",+          "starred_url": "https://api.github.com/users/kote-test-org-actions/starred{/owner}{/repo}",+          "subscriptions_url": "https://api.github.com/users/kote-test-org-actions/subscriptions",+          "organizations_url": "https://api.github.com/users/kote-test-org-actions/orgs",+          "repos_url": "https://api.github.com/users/kote-test-org-actions/repos",+          "events_url": "https://api.github.com/users/kote-test-org-actions/events{/privacy}",+          "received_events_url": "https://api.github.com/users/kote-test-org-actions/received_events",+          "type": "Organization",+          "site_admin": false+        },+        "html_url": "https://github.com/kote-test-org-actions/actions-api",+        "description": null,+        "fork": false,+        "url": "https://api.github.com/repos/kote-test-org-actions/actions-api",+        "forks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/forks",+        "keys_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/keys{/key_id}",+        "collaborators_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/collaborators{/collaborator}",+        "teams_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/teams",+        "hooks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/hooks",+        "issue_events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/events{/number}",+        "events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/events",+        "assignees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/assignees{/user}",+        "branches_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/branches{/branch}",+        "tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/tags",+        "blobs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/blobs{/sha}",+        "git_tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/tags{/sha}",+        "git_refs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/refs{/sha}",+        "trees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/trees{/sha}",+        "statuses_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/statuses/{sha}",+        "languages_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/languages",+        "stargazers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/stargazers",+        "contributors_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contributors",+        "subscribers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscribers",+        "subscription_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscription",+        "commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/commits{/sha}",+        "git_commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/commits{/sha}",+        "comments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/comments{/number}",+        "issue_comment_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/comments{/number}",+        "contents_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contents/{+path}",+        "compare_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/compare/{base}...{head}",+        "merges_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/merges",+        "archive_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/{archive_format}{/ref}",+        "downloads_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/downloads",+        "issues_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues{/number}",+        "pulls_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/pulls{/number}",+        "milestones_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/milestones{/number}",+        "notifications_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/notifications{?since,all,participating}",+        "labels_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/labels{/name}",+        "releases_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/releases{/id}",+        "deployments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/deployments"+      }+    },+    {+      "id": 3353148947,+      "name": "K0Te is learning GitHub Actions",+      "node_id": "WFR_kwLOIVc8sc7H3P4T",+      "head_branch": "main",+      "head_sha": "601593ecb1d8a57a04700fdb445a28d4186b8954",+      "path": ".github/workflows/make_artifact.yaml",+      "display_title": "K0Te is learning GitHub Actions",+      "run_number": 1,+      "event": "push",+      "status": "completed",+      "conclusion": "success",+      "workflow_id": 39065091,+      "check_suite_id": 9029740591,+      "check_suite_node_id": "CS_kwDOIVc8sc8AAAACGjboLw",+      "url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353148947",+      "html_url": "https://github.com/kote-test-org-actions/actions-api/actions/runs/3353148947",+      "pull_requests": [],+      "created_at": "2022-10-29T22:18:02Z",+      "updated_at": "2022-10-29T22:18:22Z",+      "actor": {+        "login": "K0Te",+        "id": 6162155,+        "node_id": "MDQ6VXNlcjYxNjIxNTU=",+        "avatar_url": "https://avatars.githubusercontent.com/u/6162155?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/K0Te",+        "html_url": "https://github.com/K0Te",+        "followers_url": "https://api.github.com/users/K0Te/followers",+        "following_url": "https://api.github.com/users/K0Te/following{/other_user}",+        "gists_url": "https://api.github.com/users/K0Te/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/K0Te/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/K0Te/subscriptions",+        "organizations_url": "https://api.github.com/users/K0Te/orgs",+        "repos_url": "https://api.github.com/users/K0Te/repos",+        "events_url": "https://api.github.com/users/K0Te/events{/privacy}",+        "received_events_url": "https://api.github.com/users/K0Te/received_events",+        "type": "User",+        "site_admin": false+      },+      "run_attempt": 1,+      "referenced_workflows": [],+      "run_started_at": "2022-10-29T22:18:02Z",+      "triggering_actor": {+        "login": "K0Te",+        "id": 6162155,+        "node_id": "MDQ6VXNlcjYxNjIxNTU=",+        "avatar_url": "https://avatars.githubusercontent.com/u/6162155?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/K0Te",+        "html_url": "https://github.com/K0Te",+        "followers_url": "https://api.github.com/users/K0Te/followers",+        "following_url": "https://api.github.com/users/K0Te/following{/other_user}",+        "gists_url": "https://api.github.com/users/K0Te/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/K0Te/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/K0Te/subscriptions",+        "organizations_url": "https://api.github.com/users/K0Te/orgs",+        "repos_url": "https://api.github.com/users/K0Te/repos",+        "events_url": "https://api.github.com/users/K0Te/events{/privacy}",+        "received_events_url": "https://api.github.com/users/K0Te/received_events",+        "type": "User",+        "site_admin": false+      },+      "jobs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353148947/jobs",+      "logs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353148947/logs",+      "check_suite_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/check-suites/9029740591",+      "artifacts_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353148947/artifacts",+      "cancel_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353148947/cancel",+      "rerun_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/runs/3353148947/rerun",+      "previous_attempt_url": null,+      "workflow_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/actions/workflows/39065091",+      "head_commit": {+        "id": "601593ecb1d8a57a04700fdb445a28d4186b8954",+        "tree_id": "7aa2d4e6f4e0ddb277fe2f35f7615651ee01c5a2",+        "message": "test",+        "timestamp": "2022-10-29T22:17:55Z",+        "author": {+          "name": "Oleg Nykolyn",+          "email": "juravel2@gmail.com"+        },+        "committer": {+          "name": "Oleg Nykolyn",+          "email": "juravel2@gmail.com"+        }+      },+      "repository": {+        "id": 559365297,+        "node_id": "R_kgDOIVc8sQ",+        "name": "actions-api",+        "full_name": "kote-test-org-actions/actions-api",+        "private": true,+        "owner": {+          "login": "kote-test-org-actions",+          "id": 116976977,+          "node_id": "O_kgDOBvjtUQ",+          "avatar_url": "https://avatars.githubusercontent.com/u/116976977?v=4",+          "gravatar_id": "",+          "url": "https://api.github.com/users/kote-test-org-actions",+          "html_url": "https://github.com/kote-test-org-actions",+          "followers_url": "https://api.github.com/users/kote-test-org-actions/followers",+          "following_url": "https://api.github.com/users/kote-test-org-actions/following{/other_user}",+          "gists_url": "https://api.github.com/users/kote-test-org-actions/gists{/gist_id}",+          "starred_url": "https://api.github.com/users/kote-test-org-actions/starred{/owner}{/repo}",+          "subscriptions_url": "https://api.github.com/users/kote-test-org-actions/subscriptions",+          "organizations_url": "https://api.github.com/users/kote-test-org-actions/orgs",+          "repos_url": "https://api.github.com/users/kote-test-org-actions/repos",+          "events_url": "https://api.github.com/users/kote-test-org-actions/events{/privacy}",+          "received_events_url": "https://api.github.com/users/kote-test-org-actions/received_events",+          "type": "Organization",+          "site_admin": false+        },+        "html_url": "https://github.com/kote-test-org-actions/actions-api",+        "description": null,+        "fork": false,+        "url": "https://api.github.com/repos/kote-test-org-actions/actions-api",+        "forks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/forks",+        "keys_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/keys{/key_id}",+        "collaborators_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/collaborators{/collaborator}",+        "teams_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/teams",+        "hooks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/hooks",+        "issue_events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/events{/number}",+        "events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/events",+        "assignees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/assignees{/user}",+        "branches_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/branches{/branch}",+        "tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/tags",+        "blobs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/blobs{/sha}",+        "git_tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/tags{/sha}",+        "git_refs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/refs{/sha}",+        "trees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/trees{/sha}",+        "statuses_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/statuses/{sha}",+        "languages_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/languages",+        "stargazers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/stargazers",+        "contributors_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contributors",+        "subscribers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscribers",+        "subscription_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscription",+        "commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/commits{/sha}",+        "git_commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/commits{/sha}",+        "comments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/comments{/number}",+        "issue_comment_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/comments{/number}",+        "contents_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contents/{+path}",+        "compare_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/compare/{base}...{head}",+        "merges_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/merges",+        "archive_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/{archive_format}{/ref}",+        "downloads_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/downloads",+        "issues_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues{/number}",+        "pulls_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/pulls{/number}",+        "milestones_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/milestones{/number}",+        "notifications_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/notifications{?since,all,participating}",+        "labels_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/labels{/name}",+        "releases_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/releases{/id}",+        "deployments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/deployments"+      },+      "head_repository": {+        "id": 559365297,+        "node_id": "R_kgDOIVc8sQ",+        "name": "actions-api",+        "full_name": "kote-test-org-actions/actions-api",+        "private": true,+        "owner": {+          "login": "kote-test-org-actions",+          "id": 116976977,+          "node_id": "O_kgDOBvjtUQ",+          "avatar_url": "https://avatars.githubusercontent.com/u/116976977?v=4",+          "gravatar_id": "",+          "url": "https://api.github.com/users/kote-test-org-actions",+          "html_url": "https://github.com/kote-test-org-actions",+          "followers_url": "https://api.github.com/users/kote-test-org-actions/followers",+          "following_url": "https://api.github.com/users/kote-test-org-actions/following{/other_user}",+          "gists_url": "https://api.github.com/users/kote-test-org-actions/gists{/gist_id}",+          "starred_url": "https://api.github.com/users/kote-test-org-actions/starred{/owner}{/repo}",+          "subscriptions_url": "https://api.github.com/users/kote-test-org-actions/subscriptions",+          "organizations_url": "https://api.github.com/users/kote-test-org-actions/orgs",+          "repos_url": "https://api.github.com/users/kote-test-org-actions/repos",+          "events_url": "https://api.github.com/users/kote-test-org-actions/events{/privacy}",+          "received_events_url": "https://api.github.com/users/kote-test-org-actions/received_events",+          "type": "Organization",+          "site_admin": false+        },+        "html_url": "https://github.com/kote-test-org-actions/actions-api",+        "description": null,+        "fork": false,+        "url": "https://api.github.com/repos/kote-test-org-actions/actions-api",+        "forks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/forks",+        "keys_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/keys{/key_id}",+        "collaborators_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/collaborators{/collaborator}",+        "teams_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/teams",+        "hooks_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/hooks",+        "issue_events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/events{/number}",+        "events_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/events",+        "assignees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/assignees{/user}",+        "branches_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/branches{/branch}",+        "tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/tags",+        "blobs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/blobs{/sha}",+        "git_tags_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/tags{/sha}",+        "git_refs_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/refs{/sha}",+        "trees_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/trees{/sha}",+        "statuses_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/statuses/{sha}",+        "languages_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/languages",+        "stargazers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/stargazers",+        "contributors_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contributors",+        "subscribers_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscribers",+        "subscription_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/subscription",+        "commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/commits{/sha}",+        "git_commits_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/git/commits{/sha}",+        "comments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/comments{/number}",+        "issue_comment_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues/comments{/number}",+        "contents_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/contents/{+path}",+        "compare_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/compare/{base}...{head}",+        "merges_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/merges",+        "archive_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/{archive_format}{/ref}",+        "downloads_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/downloads",+        "issues_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/issues{/number}",+        "pulls_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/pulls{/number}",+        "milestones_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/milestones{/number}",+        "notifications_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/notifications{?since,all,participating}",+        "labels_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/labels{/name}",+        "releases_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/releases{/id}",+        "deployments_url": "https://api.github.com/repos/kote-test-org-actions/actions-api/deployments"+      }+    }+  ]+}
+ fixtures/pull-request-approved-review.json view
@@ -0,0 +1,38 @@+{+  "id": 80,+  "node_id": "MDE3OlB1bGxSZXF1ZXN0UmV2aWV3ODA=",+  "user": {+    "login": "octocat",+    "id": 1,+    "node_id": "MDQ6VXNlcjE=",+    "avatar_url": "https://github.com/images/error/octocat_happy.gif",+    "gravatar_id": "",+    "url": "https://api.github.com/users/octocat",+    "html_url": "https://github.com/octocat",+    "followers_url": "https://api.github.com/users/octocat/followers",+    "following_url": "https://api.github.com/users/octocat/following{/other_user}",+    "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",+    "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",+    "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",+    "organizations_url": "https://api.github.com/users/octocat/orgs",+    "repos_url": "https://api.github.com/users/octocat/repos",+    "events_url": "https://api.github.com/users/octocat/events{/privacy}",+    "received_events_url": "https://api.github.com/users/octocat/received_events",+    "type": "User",+    "site_admin": false+  },+  "body": "Here is the body for the review.",+  "state": "APPROVED",+  "html_url": "https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80",+  "pull_request_url": "https://api.github.com/repos/octocat/Hello-World/pulls/12",+  "_links": {+    "html": {+      "href": "https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80"+    },+    "pull_request": {+      "href": "https://api.github.com/repos/octocat/Hello-World/pulls/12"+    }+  },+  "submitted_at": "2019-11-17T17:43:43Z",+  "commit_id": "ecdd80bb57125d7ba9641ffaa4d7d2c19d3f3091"+}
+ fixtures/pull-request-pending-review.json view
@@ -0,0 +1,37 @@+{+  "id": 80,+  "node_id": "MDE3OlB1bGxSZXF1ZXN0UmV2aWV3ODA=",+  "user": {+    "login": "octocat",+    "id": 1,+    "node_id": "MDQ6VXNlcjE=",+    "avatar_url": "https://github.com/images/error/octocat_happy.gif",+    "gravatar_id": "",+    "url": "https://api.github.com/users/octocat",+    "html_url": "https://github.com/octocat",+    "followers_url": "https://api.github.com/users/octocat/followers",+    "following_url": "https://api.github.com/users/octocat/following{/other_user}",+    "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",+    "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",+    "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",+    "organizations_url": "https://api.github.com/users/octocat/orgs",+    "repos_url": "https://api.github.com/users/octocat/repos",+    "events_url": "https://api.github.com/users/octocat/events{/privacy}",+    "received_events_url": "https://api.github.com/users/octocat/received_events",+    "type": "User",+    "site_admin": false+  },+  "body": "Here is the body for the review.",+  "state": "PENDING",+  "html_url": "https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80",+  "pull_request_url": "https://api.github.com/repos/octocat/Hello-World/pulls/12",+  "_links": {+    "html": {+      "href": "https://github.com/octocat/Hello-World/pull/12#pullrequestreview-80"+    },+    "pull_request": {+      "href": "https://api.github.com/repos/octocat/Hello-World/pulls/12"+    }+  },+  "commit_id": "ecdd80bb57125d7ba9641ffaa4d7d2c19d3f3091"+}
+ fixtures/pull-request-team-review-requested.json view
@@ -0,0 +1,362 @@+{+  "url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/pulls/910",+  "id": 529597962,+  "node_id": "MDExOlB1bGxSZXF1ZXN0NTI5NTk3OTYy",+  "html_url": "https://github.com/tahoe-lafs/tahoe-lafs/pull/910",+  "diff_url": "https://github.com/tahoe-lafs/tahoe-lafs/pull/910.diff",+  "patch_url": "https://github.com/tahoe-lafs/tahoe-lafs/pull/910.patch",+  "issue_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/issues/910",+  "number": 910,+  "state": "open",+  "locked": false,+  "title": "Fix NodeMaker's use of the WeakValueDictionary",+  "user": {+    "login": "exarkun",+    "id": 254565,+    "node_id": "MDQ6VXNlcjI1NDU2NQ==",+    "avatar_url": "https://avatars1.githubusercontent.com/u/254565?v=4",+    "gravatar_id": "",+    "url": "https://api.github.com/users/exarkun",+    "html_url": "https://github.com/exarkun",+    "followers_url": "https://api.github.com/users/exarkun/followers",+    "following_url": "https://api.github.com/users/exarkun/following{/other_user}",+    "gists_url": "https://api.github.com/users/exarkun/gists{/gist_id}",+    "starred_url": "https://api.github.com/users/exarkun/starred{/owner}{/repo}",+    "subscriptions_url": "https://api.github.com/users/exarkun/subscriptions",+    "organizations_url": "https://api.github.com/users/exarkun/orgs",+    "repos_url": "https://api.github.com/users/exarkun/repos",+    "events_url": "https://api.github.com/users/exarkun/events{/privacy}",+    "received_events_url": "https://api.github.com/users/exarkun/received_events",+    "type": "User",+    "site_admin": false+  },+  "body": "https://tahoe-lafs.org/trac/tahoe-lafs/ticket/3539",+  "created_at": "2020-11-30T14:46:37Z",+  "updated_at": "2020-12-02T17:23:41Z",+  "closed_at": null,+  "merged_at": null,+  "merge_commit_sha": "3c97064ee5f71357c88f7940a91da8859641c2c6",+  "assignee": null,+  "assignees": [++  ],+  "requested_reviewers": [++  ],+  "requested_teams": [+    {+      "name": "Tahoe Committers",+      "id": 121616,+      "node_id": "MDQ6VGVhbTEyMTYxNg==",+      "slug": "tahoe-committers",+      "description": null,+      "privacy": "closed",+      "url": "https://api.github.com/organizations/1156454/team/121616",+      "html_url": "https://github.com/orgs/tahoe-lafs/teams/tahoe-committers",+      "members_url": "https://api.github.com/organizations/1156454/team/121616/members{/member}",+      "repositories_url": "https://api.github.com/organizations/1156454/team/121616/repos",+      "permission": "push",+      "parent": null+    }+  ],+  "labels": [++  ],+  "milestone": null,+  "draft": false,+  "commits_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/pulls/910/commits",+  "review_comments_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/pulls/910/comments",+  "review_comment_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/pulls/comments{/number}",+  "comments_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/issues/910/comments",+  "statuses_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/statuses/ef2f7e61364c6a3187d2ab4859adfc4031213bdd",+  "head": {+    "label": "tahoe-lafs:3539.nodemaker-weakrefdict",+    "ref": "3539.nodemaker-weakrefdict",+    "sha": "ef2f7e61364c6a3187d2ab4859adfc4031213bdd",+    "user": {+      "login": "tahoe-lafs",+      "id": 1156454,+      "node_id": "MDEyOk9yZ2FuaXphdGlvbjExNTY0NTQ=",+      "avatar_url": "https://avatars1.githubusercontent.com/u/1156454?v=4",+      "gravatar_id": "",+      "url": "https://api.github.com/users/tahoe-lafs",+      "html_url": "https://github.com/tahoe-lafs",+      "followers_url": "https://api.github.com/users/tahoe-lafs/followers",+      "following_url": "https://api.github.com/users/tahoe-lafs/following{/other_user}",+      "gists_url": "https://api.github.com/users/tahoe-lafs/gists{/gist_id}",+      "starred_url": "https://api.github.com/users/tahoe-lafs/starred{/owner}{/repo}",+      "subscriptions_url": "https://api.github.com/users/tahoe-lafs/subscriptions",+      "organizations_url": "https://api.github.com/users/tahoe-lafs/orgs",+      "repos_url": "https://api.github.com/users/tahoe-lafs/repos",+      "events_url": "https://api.github.com/users/tahoe-lafs/events{/privacy}",+      "received_events_url": "https://api.github.com/users/tahoe-lafs/received_events",+      "type": "Organization",+      "site_admin": false+    },+    "repo": {+      "id": 3007569,+      "node_id": "MDEwOlJlcG9zaXRvcnkzMDA3NTY5",+      "name": "tahoe-lafs",+      "full_name": "tahoe-lafs/tahoe-lafs",+      "private": false,+      "owner": {+        "login": "tahoe-lafs",+        "id": 1156454,+        "node_id": "MDEyOk9yZ2FuaXphdGlvbjExNTY0NTQ=",+        "avatar_url": "https://avatars1.githubusercontent.com/u/1156454?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/tahoe-lafs",+        "html_url": "https://github.com/tahoe-lafs",+        "followers_url": "https://api.github.com/users/tahoe-lafs/followers",+        "following_url": "https://api.github.com/users/tahoe-lafs/following{/other_user}",+        "gists_url": "https://api.github.com/users/tahoe-lafs/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/tahoe-lafs/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/tahoe-lafs/subscriptions",+        "organizations_url": "https://api.github.com/users/tahoe-lafs/orgs",+        "repos_url": "https://api.github.com/users/tahoe-lafs/repos",+        "events_url": "https://api.github.com/users/tahoe-lafs/events{/privacy}",+        "received_events_url": "https://api.github.com/users/tahoe-lafs/received_events",+        "type": "Organization",+        "site_admin": false+      },+      "html_url": "https://github.com/tahoe-lafs/tahoe-lafs",+      "description": "The Tahoe-LAFS decentralized secure filesystem.",+      "fork": false,+      "url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs",+      "forks_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/forks",+      "keys_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/keys{/key_id}",+      "collaborators_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/collaborators{/collaborator}",+      "teams_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/teams",+      "hooks_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/hooks",+      "issue_events_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/issues/events{/number}",+      "events_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/events",+      "assignees_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/assignees{/user}",+      "branches_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/branches{/branch}",+      "tags_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/tags",+      "blobs_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/git/blobs{/sha}",+      "git_tags_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/git/tags{/sha}",+      "git_refs_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/git/refs{/sha}",+      "trees_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/git/trees{/sha}",+      "statuses_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/statuses/{sha}",+      "languages_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/languages",+      "stargazers_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/stargazers",+      "contributors_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/contributors",+      "subscribers_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/subscribers",+      "subscription_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/subscription",+      "commits_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/commits{/sha}",+      "git_commits_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/git/commits{/sha}",+      "comments_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/comments{/number}",+      "issue_comment_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/issues/comments{/number}",+      "contents_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/contents/{+path}",+      "compare_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/compare/{base}...{head}",+      "merges_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/merges",+      "archive_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/{archive_format}{/ref}",+      "downloads_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/downloads",+      "issues_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/issues{/number}",+      "pulls_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/pulls{/number}",+      "milestones_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/milestones{/number}",+      "notifications_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/notifications{?since,all,participating}",+      "labels_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/labels{/name}",+      "releases_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/releases{/id}",+      "deployments_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/deployments",+      "created_at": "2011-12-18T19:33:55Z",+      "updated_at": "2020-12-02T20:24:23Z",+      "pushed_at": "2020-12-02T20:27:05Z",+      "git_url": "git://github.com/tahoe-lafs/tahoe-lafs.git",+      "ssh_url": "git@github.com:tahoe-lafs/tahoe-lafs.git",+      "clone_url": "https://github.com/tahoe-lafs/tahoe-lafs.git",+      "svn_url": "https://github.com/tahoe-lafs/tahoe-lafs",+      "homepage": "https://tahoe-lafs.org/",+      "size": 73606,+      "stargazers_count": 1018,+      "watchers_count": 1018,+      "language": "Python",+      "has_issues": false,+      "has_projects": false,+      "has_downloads": true,+      "has_wiki": false,+      "has_pages": false,+      "forks_count": 236,+      "mirror_url": null,+      "archived": false,+      "disabled": false,+      "open_issues_count": 21,+      "license": {+        "key": "other",+        "name": "Other",+        "spdx_id": "NOASSERTION",+        "url": null,+        "node_id": "MDc6TGljZW5zZTA="+      },+      "forks": 236,+      "open_issues": 21,+      "watchers": 1018,+      "default_branch": "master"+    }+  },+  "base": {+    "label": "tahoe-lafs:master",+    "ref": "master",+    "sha": "fba386cb8ee2b48a34c0d954b5c6b5b080d3234e",+    "user": {+      "login": "tahoe-lafs",+      "id": 1156454,+      "node_id": "MDEyOk9yZ2FuaXphdGlvbjExNTY0NTQ=",+      "avatar_url": "https://avatars1.githubusercontent.com/u/1156454?v=4",+      "gravatar_id": "",+      "url": "https://api.github.com/users/tahoe-lafs",+      "html_url": "https://github.com/tahoe-lafs",+      "followers_url": "https://api.github.com/users/tahoe-lafs/followers",+      "following_url": "https://api.github.com/users/tahoe-lafs/following{/other_user}",+      "gists_url": "https://api.github.com/users/tahoe-lafs/gists{/gist_id}",+      "starred_url": "https://api.github.com/users/tahoe-lafs/starred{/owner}{/repo}",+      "subscriptions_url": "https://api.github.com/users/tahoe-lafs/subscriptions",+      "organizations_url": "https://api.github.com/users/tahoe-lafs/orgs",+      "repos_url": "https://api.github.com/users/tahoe-lafs/repos",+      "events_url": "https://api.github.com/users/tahoe-lafs/events{/privacy}",+      "received_events_url": "https://api.github.com/users/tahoe-lafs/received_events",+      "type": "Organization",+      "site_admin": false+    },+    "repo": {+      "id": 3007569,+      "node_id": "MDEwOlJlcG9zaXRvcnkzMDA3NTY5",+      "name": "tahoe-lafs",+      "full_name": "tahoe-lafs/tahoe-lafs",+      "private": false,+      "owner": {+        "login": "tahoe-lafs",+        "id": 1156454,+        "node_id": "MDEyOk9yZ2FuaXphdGlvbjExNTY0NTQ=",+        "avatar_url": "https://avatars1.githubusercontent.com/u/1156454?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/tahoe-lafs",+        "html_url": "https://github.com/tahoe-lafs",+        "followers_url": "https://api.github.com/users/tahoe-lafs/followers",+        "following_url": "https://api.github.com/users/tahoe-lafs/following{/other_user}",+        "gists_url": "https://api.github.com/users/tahoe-lafs/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/tahoe-lafs/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/tahoe-lafs/subscriptions",+        "organizations_url": "https://api.github.com/users/tahoe-lafs/orgs",+        "repos_url": "https://api.github.com/users/tahoe-lafs/repos",+        "events_url": "https://api.github.com/users/tahoe-lafs/events{/privacy}",+        "received_events_url": "https://api.github.com/users/tahoe-lafs/received_events",+        "type": "Organization",+        "site_admin": false+      },+      "html_url": "https://github.com/tahoe-lafs/tahoe-lafs",+      "description": "The Tahoe-LAFS decentralized secure filesystem.",+      "fork": false,+      "url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs",+      "forks_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/forks",+      "keys_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/keys{/key_id}",+      "collaborators_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/collaborators{/collaborator}",+      "teams_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/teams",+      "hooks_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/hooks",+      "issue_events_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/issues/events{/number}",+      "events_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/events",+      "assignees_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/assignees{/user}",+      "branches_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/branches{/branch}",+      "tags_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/tags",+      "blobs_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/git/blobs{/sha}",+      "git_tags_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/git/tags{/sha}",+      "git_refs_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/git/refs{/sha}",+      "trees_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/git/trees{/sha}",+      "statuses_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/statuses/{sha}",+      "languages_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/languages",+      "stargazers_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/stargazers",+      "contributors_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/contributors",+      "subscribers_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/subscribers",+      "subscription_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/subscription",+      "commits_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/commits{/sha}",+      "git_commits_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/git/commits{/sha}",+      "comments_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/comments{/number}",+      "issue_comment_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/issues/comments{/number}",+      "contents_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/contents/{+path}",+      "compare_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/compare/{base}...{head}",+      "merges_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/merges",+      "archive_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/{archive_format}{/ref}",+      "downloads_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/downloads",+      "issues_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/issues{/number}",+      "pulls_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/pulls{/number}",+      "milestones_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/milestones{/number}",+      "notifications_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/notifications{?since,all,participating}",+      "labels_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/labels{/name}",+      "releases_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/releases{/id}",+      "deployments_url": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/deployments",+      "created_at": "2011-12-18T19:33:55Z",+      "updated_at": "2020-12-02T20:24:23Z",+      "pushed_at": "2020-12-02T20:27:05Z",+      "git_url": "git://github.com/tahoe-lafs/tahoe-lafs.git",+      "ssh_url": "git@github.com:tahoe-lafs/tahoe-lafs.git",+      "clone_url": "https://github.com/tahoe-lafs/tahoe-lafs.git",+      "svn_url": "https://github.com/tahoe-lafs/tahoe-lafs",+      "homepage": "https://tahoe-lafs.org/",+      "size": 73606,+      "stargazers_count": 1018,+      "watchers_count": 1018,+      "language": "Python",+      "has_issues": false,+      "has_projects": false,+      "has_downloads": true,+      "has_wiki": false,+      "has_pages": false,+      "forks_count": 236,+      "mirror_url": null,+      "archived": false,+      "disabled": false,+      "open_issues_count": 21,+      "license": {+        "key": "other",+        "name": "Other",+        "spdx_id": "NOASSERTION",+        "url": null,+        "node_id": "MDc6TGljZW5zZTA="+      },+      "forks": 236,+      "open_issues": 21,+      "watchers": 1018,+      "default_branch": "master"+    }+  },+  "_links": {+    "self": {+      "href": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/pulls/910"+    },+    "html": {+      "href": "https://github.com/tahoe-lafs/tahoe-lafs/pull/910"+    },+    "issue": {+      "href": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/issues/910"+    },+    "comments": {+      "href": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/issues/910/comments"+    },+    "review_comments": {+      "href": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/pulls/910/comments"+    },+    "review_comment": {+      "href": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/pulls/comments{/number}"+    },+    "commits": {+      "href": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/pulls/910/commits"+    },+    "statuses": {+      "href": "https://api.github.com/repos/tahoe-lafs/tahoe-lafs/statuses/ef2f7e61364c6a3187d2ab4859adfc4031213bdd"+    }+  },+  "author_association": "MEMBER",+  "active_lock_reason": null,+  "merged": false,+  "mergeable": true,+  "rebaseable": true,+  "mergeable_state": "clean",+  "merged_by": null,+  "comments": 1,+  "review_comments": 0,+  "maintainer_can_modify": false,+  "commits": 5,+  "additions": 223,+  "deletions": 4,+  "changed_files": 5+}
+ fixtures/user-bot.json view
@@ -0,0 +1,32 @@+{+  "login": "mike-burns",+  "id": 4550,+  "avatar_url": "https://avatars.githubusercontent.com/u/4550?v=3",+  "gravatar_id": "",+  "url": "https://api.github.com/users/mike-burns",+  "html_url": "https://github.com/mike-burns",+  "followers_url": "https://api.github.com/users/mike-burns/followers",+  "following_url": "https://api.github.com/users/mike-burns/following{/other_user}",+  "gists_url": "https://api.github.com/users/mike-burns/gists{/gist_id}",+  "starred_url": "https://api.github.com/users/mike-burns/starred{/owner}{/repo}",+  "subscriptions_url": "https://api.github.com/users/mike-burns/subscriptions",+  "organizations_url": "https://api.github.com/users/mike-burns/orgs",+  "repos_url": "https://api.github.com/users/mike-burns/repos",+  "events_url": "https://api.github.com/users/mike-burns/events{/privacy}",+  "received_events_url": "https://api.github.com/users/mike-burns/received_events",+  "type": "Bot",+  "site_admin": false,+  "name": "Mike Burns",+  "company": "thoughtbot",+  "blog": "http://mike-burns.com/",+  "location": "Stockholm, Sweden",+  "email": "mburns@thoughtbot.com",+  "hireable": true,+  "bio": null,+  "public_repos": 35,+  "public_gists": 32,+  "followers": 171,+  "following": 0,+  "created_at": "2008-04-03T17:54:24Z",+  "updated_at": "2015-10-02T16:53:25Z"+}
github.cabal view
@@ -1,6 +1,8 @@-name:                github-version:             0.19-synopsis:            Access to the GitHub API, v3.+cabal-version:      2.4+name:               github+version:            0.30.0.2+synopsis:           Access to the GitHub API, v3.+category:           Network description:   The GitHub API provides programmatic access to the full   GitHub Web site, from Issues to Gists to repos down to the underlying git data@@ -13,68 +15,97 @@   >   > main :: IO ()   > main = do-  >     possibleUser <- GH.executeRequest' $ GH.userInfoR "phadej"+  >     possibleUser <- GH.github' GH.userInfoForR "phadej"   >     print possibleUser   .-  For more of an overview please see the README: <https://github.com/phadej/github/blob/master/README.md>-license:             BSD3-license-file:        LICENSE-author:              Mike Burns, John Wiegley, Oleg Grenrus-maintainer:          Oleg Grenrus <oleg.grenrus@iki.fi>-homepage:            https://github.com/phadej/github-copyright:           Copyright 2012-2013 Mike Burns, Copyright 2013-2015 John Wiegley, Copyright 2016 Oleg Grenrus-category:            Network-build-type:          Simple-tested-with:         GHC==7.8.4, GHC==7.10.3, GHC==8.0.2, GHC==8.2.2-cabal-version:       >=1.10-extra-source-files:-  README.md,-  CHANGELOG.md,-  fixtures/issue-search.json,-  fixtures/list-teams.json,-  fixtures/members-list.json,-  fixtures/pull-request-opened.json,-  fixtures/pull-request-review-requested.json,-  fixtures/user-organizations.json,-  fixtures/user.json+  For more of an overview please see the README: <https://github.com/haskell-github/github/blob/master/README.md> -flag aeson-compat-  description: Whether to use aeson-compat or aeson-extra-  default: True-  manual: False+license:            BSD-3-Clause+license-file:       LICENSE+author:             Mike Burns, John Wiegley, Oleg Grenrus+maintainer:         Andreas Abel+homepage:           https://github.com/haskell-github/github+build-type:         Simple+copyright:+  Copyright 2012-2013 Mike Burns, Copyright 2013-2015 John Wiegley, Copyright 2016-2021 Oleg Grenrus +tested-with:+  GHC == 9.14.1+  GHC == 9.12.2+  GHC == 9.10.3+  GHC == 9.8.4+  GHC == 9.6.7+  GHC == 9.4.8+  GHC == 9.2.8+  GHC == 9.0.2+  GHC == 8.10.7+  GHC == 8.8.4+  GHC == 8.6.5+  GHC == 8.4.4+  GHC == 8.2.2++extra-doc-files:+  README.md+  CHANGELOG.md++extra-source-files:+  fixtures/**/*.json+ source-repository head-  type: git-  location: git://github.com/phadej/github.git+  type:     git+  location: https://github.com/haskell-github/github.git -Library-  default-language: Haskell2010-  ghc-options: -Wall-  hs-source-dirs: src+flag openssl+  description: "Use http-client-openssl"+  manual:      True+  default:     False++library+  default-language:   Haskell2010+  ghc-options:+    -Wall+    -Wcompat+    -Wno-star-is-type+      -- The star-is-type warning cannot be sensiblity addressed while supporting GHC 7.+  hs-source-dirs:     src   default-extensions:     DataKinds     DeriveDataTypeable     DeriveGeneric+    LambdaCase     OverloadedStrings     ScopedTypeVariables+    TypeOperators+   other-extensions:     CPP     FlexibleContexts     FlexibleInstances     GADTs     KindSignatures+    RecordWildCards     StandaloneDeriving+   exposed-modules:     GitHub-    GitHub.Internal.Prelude     GitHub.Auth     GitHub.Data+    GitHub.Data.Actions.Common+    GitHub.Data.Actions.Artifacts+    GitHub.Data.Actions.Cache+    GitHub.Data.Actions.Secrets+    GitHub.Data.Actions.Workflows+    GitHub.Data.Actions.WorkflowJobs+    GitHub.Data.Actions.WorkflowRuns     GitHub.Data.Activities     GitHub.Data.Comments     GitHub.Data.Content     GitHub.Data.Definitions     GitHub.Data.DeployKeys+    GitHub.Data.Deployments     GitHub.Data.Email+    GitHub.Data.Enterprise+    GitHub.Data.Enterprise.Organizations     GitHub.Data.Events     GitHub.Data.Gists     GitHub.Data.GitData@@ -84,7 +115,10 @@     GitHub.Data.Milestone     GitHub.Data.Name     GitHub.Data.Options+    GitHub.Data.PublicSSHKeys     GitHub.Data.PullRequests+    GitHub.Data.RateLimit+    GitHub.Data.Reactions     GitHub.Data.Releases     GitHub.Data.Repos     GitHub.Data.Request@@ -95,9 +129,17 @@     GitHub.Data.URL     GitHub.Data.Webhooks     GitHub.Data.Webhooks.Validate+    GitHub.Endpoints.Actions.Artifacts+    GitHub.Endpoints.Actions.Cache+    GitHub.Endpoints.Actions.Secrets+    GitHub.Endpoints.Actions.Workflows+    GitHub.Endpoints.Actions.WorkflowJobs+    GitHub.Endpoints.Actions.WorkflowRuns     GitHub.Endpoints.Activity.Events+    GitHub.Endpoints.Activity.Notifications     GitHub.Endpoints.Activity.Starring     GitHub.Endpoints.Activity.Watching+    GitHub.Endpoints.Enterprise.Organizations     GitHub.Endpoints.Gists     GitHub.Endpoints.Gists.Comments     GitHub.Endpoints.GitData.Blobs@@ -111,17 +153,22 @@     GitHub.Endpoints.Issues.Milestones     GitHub.Endpoints.Organizations     GitHub.Endpoints.Organizations.Members+    GitHub.Endpoints.Organizations.OutsideCollaborators     GitHub.Endpoints.Organizations.Teams     GitHub.Endpoints.PullRequests-    GitHub.Endpoints.PullRequests.Reviews     GitHub.Endpoints.PullRequests.Comments+    GitHub.Endpoints.PullRequests.Reviews+    GitHub.Endpoints.RateLimit+    GitHub.Endpoints.Reactions     GitHub.Endpoints.Repos     GitHub.Endpoints.Repos.Collaborators     GitHub.Endpoints.Repos.Comments     GitHub.Endpoints.Repos.Commits     GitHub.Endpoints.Repos.Contents     GitHub.Endpoints.Repos.DeployKeys+    GitHub.Endpoints.Repos.Deployments     GitHub.Endpoints.Repos.Forks+    GitHub.Endpoints.Repos.Invitations     GitHub.Endpoints.Repos.Releases     GitHub.Endpoints.Repos.Statuses     GitHub.Endpoints.Repos.Webhooks@@ -129,81 +176,96 @@     GitHub.Endpoints.Users     GitHub.Endpoints.Users.Emails     GitHub.Endpoints.Users.Followers+    GitHub.Endpoints.Users.PublicSSHKeys+    GitHub.Enterprise+    GitHub.Internal.Prelude     GitHub.Request +  other-modules:   Paths_github+  autogen-modules: Paths_github+   -- Packages bundles with GHC, mtl and text are also here+  -- Lower bounds at least those of https://www.stackage.org/lts-10.0 (GHC 8.2.2)   build-depends:-    base                  >=4.7       && <4.11,-    bytestring            >=0.10.4.0  && <0.11,-    containers            >=0.5.5.1   && <0.6,-    deepseq               >=1.3.0.2   && <1.5,-    mtl                   (>=2.1.3.1   && <2.2) || (>=2.2.1 && <2.3),-    text                  >=1.2.0.6   && <1.3,-    time                  >=1.4       && <1.10,-    transformers          >=0.3.0.0   && <0.6+      base          >=4.10     && <5+    , binary        >=0.8.5.1  && <0.11+    , bytestring    >=0.10.8.2 && <0.13+    , containers    >=0.5.10.2 && <1+    , deepseq       >=1.4.3.0  && <1.6+    , exceptions    >=0.10.2   && <0.11+    , mtl           >=2.2.1    && <2.4+    , text          >=1.2.2.2  && <2.2+    , time          >=1.8.0.2  && <2+    , transformers  >=0.5.2.0  && <0.7    -- other packages   build-depends:-    aeson                 >=0.7.0.6   && <1.3,-    base-compat           >=0.9.1     && <0.10,-    base16-bytestring     >=0.1.1.6   && <0.2,-    binary                >=0.7.1.0   && <0.10,-    binary-orphans        >=0.1.0.0   && <0.2,-    byteable              >=0.1.1     && <0.2,-    cryptohash            >=0.11      && <0.12,-    deepseq-generics      >=0.1.1.2   && <0.3,-    exceptions            >=0.8.0.2   && <0.9,-    hashable              >=1.2.3.3   && <1.3,-    http-client           >=0.4.8.1   && <0.6,-    http-client-tls       >=0.2.2     && <0.4,-    http-link-header      >=1.0.1     && <1.1,-    http-types            >=0.12.1    && <0.13,-    iso8601-time          >=0.1.4     && <0.2,-    network-uri           >=2.6.0.3   && <2.7,-    semigroups            >=0.16.2.2  && <0.19,-    transformers-compat   >=0.4.0.3   && <0.6,-    unordered-containers  >=0.2       && <0.3,-    vector                >=0.10.12.3 && <0.13,-    vector-instances      >=3.3.0.1   && <3.5,+      aeson                 >=1.4.0.0    && <1.6 || >=2.0.1.0 && <2.3+    , base-compat           >=0.11.1     && <1+    , base16-bytestring     >=0.1.1.6    && <1.1+    , binary-instances      >=1          && <1.1+    , cryptohash-sha1       >=0.11.100.1 && <0.12+    , hashable              >=1.2.7.0    && <2+    , http-client           >=0.5.12     && <0.8+    , http-link-header      >=1.0.3.1    && <1.3+    , http-types            >=0.12.3     && <0.13+    , iso8601-time          >=0.1.5      && <0.2+    , network-uri           >=2.6.1.0    && <2.7+    , tagged                >=0.8.5      && <0.9+    , unordered-containers  >=0.2.10.0   && <0.3+    , vector                >=0.12.0.1   && <0.14 -    tls                   >=1.3.5+  if flag(openssl)+    build-depends:+        HsOpenSSL              >=0.11.4.16 && <0.12+      , HsOpenSSL-x509-system  >=0.1.0.3   && <0.2+      , http-client-openssl    >=0.2.2.0   && <0.4 -  if flag(aeson-compat)-    build-depends: aeson-compat >=0.3.0.0 && <0.4   else-    build-depends: aeson-extra  >=0.2.0.0 && <0.3+    build-depends:+        http-client-tls  >=0.3.5.3 && <0.5+      , tls              >=1.4.1  test-suite github-test-  default-language: Haskell2010-  type: exitcode-stdio-1.0-  hs-source-dirs: spec-  other-extensions:-    TemplateHaskell+  default-language:   Haskell2010+  type:               exitcode-stdio-1.0+  hs-source-dirs:     spec+  main-is:            Spec.hs+  ghc-options:        -Wall -threaded+  build-tool-depends: hspec-discover:hspec-discover >=2.7.1 && <2.12+  other-extensions:   TemplateHaskell   other-modules:+    GitHub.Actions.ArtifactsSpec+    GitHub.Actions.CacheSpec+    GitHub.Actions.SecretsSpec+    GitHub.Actions.WorkflowJobSpec+    GitHub.Actions.WorkflowRunsSpec+    GitHub.Actions.WorkflowSpec     GitHub.ActivitySpec     GitHub.CommitsSpec-    GitHub.OrganizationsSpec+    GitHub.EventsSpec     GitHub.IssuesSpec-    GitHub.PullRequestsSpec+    GitHub.OrganizationsSpec+    GitHub.PublicSSHKeysSpec     GitHub.PullRequestReviewsSpec+    GitHub.PullRequestsSpec+    GitHub.RateLimitSpec     GitHub.ReleasesSpec     GitHub.ReposSpec+    GitHub.ReviewDecodeSpec     GitHub.SearchSpec     GitHub.UsersSpec-    GitHub.EventsSpec-  main-is: Spec.hs-  ghc-options: -Wall-  build-tool-depends: hspec-discover:hspec-discover-  build-depends: base,-                 base-compat,-                 bytestring,-                 github,-                 vector,-                 unordered-containers,-                 file-embed,-                 hspec-  if flag(aeson-compat)-    build-depends: aeson-compat-  else-    build-depends: aeson-extra +  build-depends:+      aeson+    , base+    , base-compat+    , bytestring+    , file-embed+    , github+    , hspec                 >=2.6.1 && <2.12+    , http-client+    , tagged+    , text+    , unordered-containers+    , vector
+ spec/GitHub/Actions/ArtifactsSpec.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+module GitHub.Actions.ArtifactsSpec where++import qualified GitHub as GH++import Prelude ()+import Prelude.Compat++import           Data.Aeson         (eitherDecodeStrict)+import           Data.ByteString    (ByteString)+import           Data.Either.Compat (isRight)+import           Data.FileEmbed     (embedFile)+import           Data.Foldable      (for_)+import           Data.String        (fromString)+import qualified Data.Vector        as V+import           System.Environment (lookupEnv)+import           Test.Hspec+                 (Spec, describe, it, pendingWith, shouldBe, shouldSatisfy)++fromRightS :: Show a => Either a b -> b+fromRightS (Right b) = b+fromRightS (Left a) = error $ "Expected a Right and got a Left" ++ show a++withAuth :: (GH.Auth -> IO ()) -> IO ()+withAuth action = do+    mtoken <- lookupEnv "GITHUB_TOKEN"+    case mtoken of+        Nothing    -> pendingWith "no GITHUB_TOKEN"+        Just token -> action (GH.OAuth $ fromString token)++spec :: Spec+spec = do+    describe "artifactsForR" $ do+        it "works" $ withAuth $ \auth -> for_ repos $ \(owner, repo) -> do+            cs <- GH.executeRequest auth $+                GH.artifactsForR owner repo mempty GH.FetchAll+            cs `shouldSatisfy` isRight++    describe "decoding artifacts payloads" $ do+        it "decodes artifacts list payload" $ do+            GH.withTotalCountTotalCount artifactList `shouldBe` 23809+            V.length (GH.withTotalCountItems artifactList) `shouldBe` 2+        it "decodes signle artifact payload" $ do+            GH.artifactName artifact `shouldBe` "dist-without-markdown"+            GH.artifactWorkflowRunHeadSha (GH.artifactWorkflowRun artifact) `shouldBe` "601593ecb1d8a57a04700fdb445a28d4186b8954"++  where+    repos =+      [ ("thoughtbot", "paperclip")+      , ("phadej", "github")+      ]++    artifactList :: GH.WithTotalCount GH.Artifact+    artifactList =+        fromRightS (eitherDecodeStrict artifactsListPayload)++    artifact :: GH.Artifact+    artifact =+        fromRightS (eitherDecodeStrict artifactPayload)++    artifactsListPayload :: ByteString+    artifactsListPayload = $(embedFile "fixtures/actions/artifacts-list.json")++    artifactPayload :: ByteString+    artifactPayload = $(embedFile "fixtures/actions/artifact.json")
+ spec/GitHub/Actions/CacheSpec.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+module GitHub.Actions.CacheSpec where++import qualified GitHub as GH++import Prelude ()+import Prelude.Compat++import           Data.Aeson      (eitherDecodeStrict)+import           Data.ByteString (ByteString)+import           Data.FileEmbed  (embedFile)+import qualified Data.Vector     as V+import           Test.Hspec      (Spec, describe, it, shouldBe)++fromRightS :: Show a => Either a b -> b+fromRightS (Right b) = b+fromRightS (Left a) = error $ "Expected a Right and got a Left" ++ show a++spec :: Spec+spec = do+    describe "decoding cache payloads" $ do+        it "decodes cache list payload" $ do+            V.length (GH.withTotalCountItems cacheList) `shouldBe` 1+        it "decodes cache usage for repo" $ do+            GH.repositoryCacheUsageFullName repoCacheUsage `shouldBe` "python/cpython"+            GH.repositoryCacheUsageActiveCachesSizeInBytes repoCacheUsage `shouldBe` 55000268087+            GH.repositoryCacheUsageActiveCachesCount repoCacheUsage `shouldBe` 171+        it "decodes cache usage for org" $ do+            GH.organizationCacheUsageTotalActiveCachesSizeInBytes orgCacheUsage `shouldBe` 26586+            GH.organizationCacheUsageTotalActiveCachesCount orgCacheUsage `shouldBe` 1++  where+    cacheList :: GH.WithTotalCount GH.Cache+    cacheList =+        fromRightS (eitherDecodeStrict cacheListPayload)++    repoCacheUsage :: GH.RepositoryCacheUsage+    repoCacheUsage =+        fromRightS (eitherDecodeStrict repoCacheUsagePayload)++    orgCacheUsage :: GH.OrganizationCacheUsage+    orgCacheUsage =+        fromRightS (eitherDecodeStrict orgCacheUsagePayload)++    cacheListPayload :: ByteString+    cacheListPayload = $(embedFile "fixtures/actions/cache-list.json")++    repoCacheUsagePayload :: ByteString+    repoCacheUsagePayload = $(embedFile "fixtures/actions/repo-cache-usage.json")++    orgCacheUsagePayload :: ByteString+    orgCacheUsagePayload = $(embedFile "fixtures/actions/org-cache-usage.json")
+ spec/GitHub/Actions/SecretsSpec.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+module GitHub.Actions.SecretsSpec where++import qualified GitHub as GH++import Prelude ()+import Prelude.Compat++import           Data.Aeson      (eitherDecodeStrict)+import           Data.ByteString (ByteString)+import           Data.FileEmbed  (embedFile)+import qualified Data.Vector     as V+import           Test.Hspec      (Spec, describe, it, shouldBe)++fromRightS :: Show a => Either a b -> b+fromRightS (Right b) = b+fromRightS (Left a) = error $ "Expected a Right and got a Left" ++ show a++spec :: Spec+spec = do+    describe "decoding secrets payloads" $ do+        it "decodes selected repo list payload" $ do+            V.length (GH.withTotalCountItems repoList) `shouldBe` 1+        it "decodes secret list payload" $ do+            V.length (GH.withTotalCountItems orgSecretList) `shouldBe` 2+        it "decodes public key payload" $ do+            GH.publicKeyId orgPublicKey `shouldBe` "568250167242549743"++  where+    repoList :: GH.WithTotalCount GH.SelectedRepo+    repoList =+        fromRightS (eitherDecodeStrict repoListPayload)++    orgSecretList:: GH.WithTotalCount GH.OrganizationSecret+    orgSecretList=+        fromRightS (eitherDecodeStrict orgSecretListPayload)++    orgPublicKey:: GH.PublicKey+    orgPublicKey=+        fromRightS (eitherDecodeStrict orgPublicKeyPayload)++    repoListPayload :: ByteString+    repoListPayload = $(embedFile "fixtures/actions/selected-repositories-for-secret.json")++    orgSecretListPayload :: ByteString+    orgSecretListPayload = $(embedFile "fixtures/actions/org-secrets-list.json")++    orgPublicKeyPayload :: ByteString+    orgPublicKeyPayload = $(embedFile "fixtures/actions/org-public-key.json")
+ spec/GitHub/Actions/WorkflowJobSpec.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+module GitHub.Actions.WorkflowJobSpec where++import qualified GitHub         as GH+import           GitHub.Data.Id++import Prelude ()+import Prelude.Compat++import Data.Aeson      (eitherDecodeStrict)+import Data.ByteString (ByteString)+import Data.FileEmbed  (embedFile)+import Test.Hspec      (Spec, describe, it, shouldBe)++fromRightS :: Show a => Either a b -> b+fromRightS (Right b) = b+fromRightS (Left a) = error $ "Expected a Right and got a Left" ++ show a++spec :: Spec+spec = do+    describe "decoding workflow jobs payloads" $ do+        it "decodes workflow job" $ do+            GH.jobId workflowJob `shouldBe` Id 9183275828++  where+    workflowJob:: GH.Job+    workflowJob=+        fromRightS (eitherDecodeStrict workflowJobPayload)++    workflowJobPayload :: ByteString+    workflowJobPayload = $(embedFile "fixtures/actions/workflow-job.json")
+ spec/GitHub/Actions/WorkflowRunsSpec.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+module GitHub.Actions.WorkflowRunsSpec where++import qualified GitHub as GH++import Prelude ()+import Prelude.Compat++import           Data.Aeson      (eitherDecodeStrict)+import           Data.ByteString (ByteString)+import           Data.FileEmbed  (embedFile)+import qualified Data.Vector     as V+import           Test.Hspec      (Spec, describe, it, shouldBe)++fromRightS :: Show a => Either a b -> b+fromRightS (Right b) = b+fromRightS (Left a) = error $ "Expected a Right and got a Left" ++ show a++spec :: Spec+spec = do+    describe "decoding workflow runs payloads" $ do+        it "decodes workflow runs list" $ do+            V.length (GH.withTotalCountItems workflowRunsList) `shouldBe` 3++  where+    workflowRunsList:: GH.WithTotalCount GH.WorkflowRun+    workflowRunsList =+        fromRightS (eitherDecodeStrict workflowRunsPayload)++    workflowRunsPayload :: ByteString+    workflowRunsPayload = $(embedFile "fixtures/actions/workflow-runs-list.json")
+ spec/GitHub/Actions/WorkflowSpec.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+module GitHub.Actions.WorkflowSpec where++import qualified GitHub as GH++import Prelude ()+import Prelude.Compat++import           Data.Aeson      (eitherDecodeStrict)+import           Data.ByteString (ByteString)+import           Data.FileEmbed  (embedFile)+import qualified Data.Vector     as V+import           Test.Hspec      (Spec, describe, it, shouldBe)++fromRightS :: Show a => Either a b -> b+fromRightS (Right b) = b+fromRightS (Left a) = error $ "Expected a Right and got a Left" ++ show a++spec :: Spec+spec = do+    describe "decoding workflow payloads" $ do+        it "decodes workflow list" $ do+            V.length (GH.withTotalCountItems workflowList) `shouldBe` 1++  where+    workflowList:: GH.WithTotalCount GH.Workflow+    workflowList =+        fromRightS (eitherDecodeStrict workflowPayload)++    workflowPayload :: ByteString+    workflowPayload = $(embedFile "fixtures/actions/workflow-list.json")
spec/GitHub/ActivitySpec.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell   #-} module GitHub.ActivitySpec where  import qualified GitHub@@ -31,7 +30,7 @@ spec = do   describe "watchersForR" $ do     it "works" $ withAuth $ \auth -> do-      cs <- executeRequest auth $ watchersForR "phadej" "github" GitHub.FetchAll +      cs <- executeRequest auth $ watchersForR "haskell-github" "github" GitHub.FetchAll       cs `shouldSatisfy` isRight       V.length (fromRightS cs) `shouldSatisfy` (> 10)   describe "myStarredR" $ do
spec/GitHub/CommitsSpec.hs view
@@ -1,13 +1,9 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell   #-} module GitHub.CommitsSpec where -import qualified GitHub- import GitHub.Auth                    (Auth (..))-import GitHub.Endpoints.Repos.Commits (Commit, commitSha, commitsFor',-                                       commitsForR, diffR, mkCommitName)-import GitHub.Request                 (executeRequest)+import GitHub.Endpoints.Repos.Commits (commitSha, commitsForR, diffR, mkCommitName, FetchCount (..))+import GitHub.Request                 (github)  import Control.Monad      (forM_) import Data.Either.Compat (isRight)@@ -34,13 +30,13 @@ spec = do   describe "commitsFor" $ do     it "works" $ withAuth $ \auth -> do-      cs <-  commitsFor' (Just auth) "phadej" "github"+      cs <- github auth commitsForR "haskell-github" "github" FetchAll       cs `shouldSatisfy` isRight       V.length (fromRightS cs) `shouldSatisfy` (> 300)      -- Page size is 30, so we get 60 commits     it "limits the response" $ withAuth $ \auth -> do-      cs <- executeRequest auth $ commitsForR "phadej" "github" (GitHub.FetchAtLeast 40)+      cs <- github auth commitsForR "haskell-github" "github" (FetchAtLeast 40)       cs `shouldSatisfy` isRight       let cs' = fromRightS cs       V.length cs' `shouldSatisfy` (< 70)@@ -49,14 +45,19 @@    describe "diff" $ do     it "works" $ withAuth $ \auth -> do-      cs <- executeRequest auth $ commitsForR "phadej" "github" (GitHub.FetchAtLeast 30)+      cs <- github auth commitsForR "haskell-github" "github" (FetchAtLeast 30)       cs `shouldSatisfy` isRight       let commits = take 10 . V.toList . fromRightS $ cs       let pairs = zip commits $ drop 1 commits       forM_ pairs $ \(a, b) -> do-        d <- executeRequest auth $ diffR "phadej" "github" (commitSha a) (commitSha b)+        d <- github auth diffR "haskell-github" "github" (commitSha a) (commitSha b)         d `shouldSatisfy` isRight      it "issue #155" $ withAuth $ \auth -> do-      d <- executeRequest auth $ diffR "nomeata" "codespeed" (mkCommitName "ghc") (mkCommitName "tobami:master")+      d <- github auth diffR "nomeata" "codespeed" (mkCommitName "ghc") (mkCommitName "tobami:master")+      d `shouldSatisfy` isRight++    -- diff that includes a commit where a submodule is removed+    it "issue #339" $ withAuth $ \auth -> do+      d <- github auth diffR "scott-fleischman" "repo-remove-submodule" "d03c152482169d809be9b1eab71dcf64d7405f76" "42cfd732b20cd093534f246e630b309186eb485d"       d `shouldSatisfy` isRight
spec/GitHub/EventsSpec.hs view
@@ -27,9 +27,9 @@ spec = do   describe "repositoryEventsR" $ do     it "returns non empty list of events" $ shouldSucceed $-      GitHub.repositoryEventsR "phadej" "github" 1+      GitHub.repositoryEventsR "haskell-github" "github" 1   describe "userEventsR" $ do-    it "returns non empty list of events" $ shouldSucceed $ GitHub.userEventsR "phadej" 1 +    it "returns non empty list of events" $ shouldSucceed $ GitHub.userEventsR "phadej" 1   where shouldSucceed f = withAuth $ \auth -> do           cs <- GitHub.executeRequest auth $ f           cs `shouldSatisfy` isRight
spec/GitHub/IssuesSpec.hs view
@@ -6,12 +6,14 @@ import Prelude () import Prelude.Compat -import Data.Either.Compat (isRight)-import Data.Foldable      (for_)-import Data.String        (fromString)-import System.Environment (lookupEnv)-import Test.Hspec         (Spec, describe, it, pendingWith, shouldSatisfy)+import Data.Either.Compat  (isRight)+import Data.Foldable       (for_)+import Data.String         (fromString)+import Network.HTTP.Client (newManager, responseBody)+import System.Environment  (lookupEnv)+import Test.Hspec          (Spec, describe, expectationFailure, it, pendingWith, shouldSatisfy) + fromRightS :: Show a => Either a b -> b fromRightS (Right b) = b fromRightS (Left a) = error $ "Expected a Right and got a Left" ++ show a@@ -28,11 +30,41 @@     describe "issuesForRepoR" $ do         it "works" $ withAuth $ \auth -> for_ repos $ \(owner, repo) -> do             cs <- GitHub.executeRequest auth $-                GitHub.issuesForRepoR owner repo mempty GitHub.FetchAll -            cs `shouldSatisfy` isRight+                GitHub.issuesForRepoR owner repo mempty GitHub.FetchAll+            case cs of+              Left e ->+                expectationFailure . show $ e+              Right cs' -> do+                for_ cs' $ \i -> do+                  cms <- GitHub.executeRequest auth $+                    GitHub.commentsR owner repo (GitHub.issueNumber i) 1+                  cms `shouldSatisfy` isRight++    describe "issuesForRepoR paged" $ do+        it "works" $ withAuth $ \auth -> for_ repos $ \(owner, repo) -> do+            mgr <- newManager GitHub.tlsManagerSettings+            ret <- GitHub.executeRequestWithMgrAndRes mgr auth $+                GitHub.issuesForRepoR owner repo mempty (GitHub.FetchPage (GitHub.PageParams (Just 2) (Just 1)))++            case ret of+              Left e ->+                expectationFailure . show $ e+              Right res -> do+                let issues = responseBody res+                length issues `shouldSatisfy` (<= 2)++                for_ issues $ \i -> do+                  cms <- GitHub.executeRequest auth $+                    GitHub.commentsR owner repo (GitHub.issueNumber i) 1+                  cms `shouldSatisfy` isRight++    describe "issueR" $ do+        it "fetches issue #428" $ withAuth $ \auth -> do+            resIss <- GitHub.executeRequest auth $+                GitHub.issueR "haskell-github" "github" (GitHub.IssueNumber 428)+            resIss `shouldSatisfy` isRight   where     repos =       [ ("thoughtbot", "paperclip")-      , ("phadej", "github")-      , ("haskell", "cabal")+      , ("haskell-github", "github")       ]
spec/GitHub/OrganizationsSpec.hs view
@@ -2,20 +2,20 @@ {-# LANGUAGE TemplateHaskell   #-} module GitHub.OrganizationsSpec where +import GitHub                                 (FetchCount (..), github) import GitHub.Auth                            (Auth (..))-import GitHub.Data                            (SimpleOrganization (..),-                                               SimpleOwner (..),-                                               SimpleTeam (..))-import GitHub.Endpoints.Organizations         (publicOrganizationsFor')-import GitHub.Endpoints.Organizations.Members (membersOf')+import GitHub.Data+       (SimpleOrganization (..), SimpleOwner (..), SimpleTeam (..))+import GitHub.Endpoints.Organizations         (publicOrganizationsForR)+import GitHub.Endpoints.Organizations.Members (membersOfR) -import Data.Aeson.Compat  (eitherDecodeStrict)+import Data.Aeson         (eitherDecodeStrict) import Data.Either.Compat (isRight) import Data.FileEmbed     (embedFile) import Data.String        (fromString) import System.Environment (lookupEnv)-import Test.Hspec         (Spec, describe, it, pendingWith, shouldBe,-                           shouldSatisfy)+import Test.Hspec+       (Spec, describe, it, pendingWith, shouldBe, shouldSatisfy)  fromRightS :: Show a => Either a b -> b fromRightS (Right b) = b@@ -36,7 +36,7 @@       simpleOrganizationLogin (head $ fromRightS orgs) `shouldBe` "github"      it "returns information about the user's organizations" $ withAuth $ \auth -> do-      orgs <- publicOrganizationsFor' (Just auth) "mike-burns"+      orgs <- github auth publicOrganizationsForR "mike-burns" FetchAll       orgs  `shouldSatisfy` isRight    describe "teamsOf" $ do@@ -50,5 +50,5 @@       simpleOwnerLogin (head $ fromRightS ms) `shouldBe` "octocat"      it "works" $ withAuth $ \auth -> do-      ms <- membersOf' (Just auth) "haskell"+      ms <- github auth membersOfR "haskell" FetchAll       ms `shouldSatisfy` isRight
+ spec/GitHub/PublicSSHKeysSpec.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE OverloadedStrings #-}+module GitHub.PublicSSHKeysSpec where++import GitHub+       (Auth (..), FetchCount (..), PublicSSHKey (..),github)+import GitHub.Endpoints.Users.PublicSSHKeys+       (publicSSHKeyR, publicSSHKeysR, publicSSHKeysForR)++import Data.Either.Compat (isRight)+import Data.String        (fromString)+import System.Environment (lookupEnv)+import Test.Hspec         (Spec, describe, it, pendingWith, shouldSatisfy)++import qualified Data.Vector as V++fromRightS :: Show a => Either a b -> b+fromRightS (Right b) = b+fromRightS (Left a) = error $ "Expected a Right and got a Left" ++ show a++withAuth :: (Auth -> IO ()) -> IO ()+withAuth action = do+  mtoken <- lookupEnv "GITHUB_TOKEN"+  case mtoken of+    Nothing    -> pendingWith "no GITHUB_TOKEN"+    Just token -> action (OAuth $ fromString token)++spec :: Spec+spec = do+  describe "publicSSHKeysFor'" $ do+    it "works" $ withAuth $ \auth -> do+      keys <- github auth publicSSHKeysForR "phadej" FetchAll+      V.length (fromRightS keys) `shouldSatisfy` (> 1)++  describe "publicSSHKeys' and publicSSHKey'" $ do+    it "works" $ withAuth $ \auth -> do+      keys <- github auth publicSSHKeysR+      V.length (fromRightS keys) `shouldSatisfy` (> 1)++      key <- github auth publicSSHKeyR (publicSSHKeyId $ V.head (fromRightS keys))+      key `shouldSatisfy` isRight
spec/GitHub/PullRequestReviewsSpec.hs view
@@ -2,16 +2,16 @@ module GitHub.PullRequestReviewsSpec where  import qualified GitHub-import GitHub.Data.Id (Id(Id))+import           GitHub.Data (IssueNumber (IssueNumber))  import Prelude () import Prelude.Compat -import Data.Either.Compat   (isRight)-import Data.Foldable        (for_)-import Data.String          (fromString)-import System.Environment   (lookupEnv)-import Test.Hspec           (Spec, describe, it, pendingWith, shouldSatisfy)+import Data.Either.Compat (isRight)+import Data.Foldable      (for_)+import Data.String        (fromString)+import System.Environment (lookupEnv)+import Test.Hspec         (Spec, describe, it, pendingWith, shouldSatisfy)  withAuth :: (GitHub.Auth -> IO ()) -> IO () withAuth action = do@@ -29,4 +29,4 @@             cs `shouldSatisfy` isRight   where     prs =-      [("phadej", "github", Id 268)]+      [("haskell-github", "github", IssueNumber 268)]
spec/GitHub/PullRequestsSpec.hs view
@@ -1,89 +1,164 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell   #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE TemplateHaskell       #-} module GitHub.PullRequestsSpec where -import qualified GitHub-import GitHub.Data.Id (Id(Id))+import qualified GitHub as GH  import Prelude () import Prelude.Compat -import Data.Aeson.Compat     (eitherDecodeStrict)-import Data.ByteString       (ByteString)-import Data.Either.Compat    (isRight)-import Data.FileEmbed        (embedFile)-import Data.Foldable         (for_)-import Data.String           (fromString)-import qualified Data.Vector as V-import System.Environment    (lookupEnv)-import Test.Hspec            (Spec, describe, it, pendingWith, shouldBe, shouldSatisfy)+import           Data.Aeson+                 (FromJSON (..), eitherDecodeStrict, withObject, (.:))+import           Data.ByteString            (ByteString)+import qualified Data.ByteString.Lazy.Char8 as LBS8+import           Data.Either.Compat         (isRight)+import           Data.FileEmbed             (embedFile)+import           Data.Foldable              (for_)+import           Data.String                (fromString)+import           Data.Tagged                (Tagged (..))+import           Data.Text                  (Text)+import qualified Data.Vector                as V+import           System.Environment         (lookupEnv)+import           Test.Hspec+                 (Spec, describe, it, pendingWith, shouldBe, shouldSatisfy)  fromRightS :: Show a => Either a b -> b fromRightS (Right b) = b fromRightS (Left a) = error $ "Expected a Right and got a Left" ++ show a -withAuth :: (GitHub.Auth -> IO ()) -> IO ()+withAuth :: (GH.Auth -> IO ()) -> IO () withAuth action = do     mtoken <- lookupEnv "GITHUB_TOKEN"     case mtoken of         Nothing    -> pendingWith "no GITHUB_TOKEN"-        Just token -> action (GitHub.OAuth $ fromString token)+        Just token -> action (GH.OAuth $ fromString token)  spec :: Spec spec = do     describe "pullRequestsForR" $ do         it "works" $ withAuth $ \auth -> for_ repos $ \(owner, repo) -> do-            cs <- GitHub.executeRequest auth $-                GitHub.pullRequestsForR owner repo opts GitHub.FetchAll+            cs <- GH.executeRequest auth $+                GH.pullRequestsForR owner repo opts GH.FetchAll             cs `shouldSatisfy` isRight +    describe "pullRequestPatchR" $+        it "works" $ withAuth $ \auth -> do+            Right patch <- GH.executeRequest auth $+                GH.pullRequestPatchR "haskell-github" "github" (GH.IssueNumber 349)+            head (LBS8.lines patch) `shouldBe` "From c0e4ad33811be82e1f72ee76116345c681703103 Mon Sep 17 00:00:00 2001"+     describe "decoding pull request payloads" $ do         it "decodes a pull request 'opened' payload" $ do-            V.length (GitHub.simplePullRequestRequestedReviewers simplePullRequestOpened)+            V.length (GH.simplePullRequestRequestedReviewers simplePullRequestOpened)                 `shouldBe` 0 -            V.length (GitHub.pullRequestRequestedReviewers pullRequestOpened)+            V.length (GH.pullRequestRequestedReviewers pullRequestOpened)                 `shouldBe` 0          it "decodes a pull request 'review_requested' payload" $ do-            V.length (GitHub.simplePullRequestRequestedReviewers simplePullRequestReviewRequested)+            V.length (GH.simplePullRequestRequestedReviewers simplePullRequestReviewRequested)                 `shouldBe` 1 -            V.length (GitHub.pullRequestRequestedReviewers pullRequestReviewRequested)+            V.length (GH.pullRequestRequestedReviewers pullRequestReviewRequested)                 `shouldBe` 1 +        it "decodes a pull request 'team_requested' payload" $ do+          V.length (GH.simplePullRequestRequestedTeamReviewers simplePullRequestTeamReviewRequested)+                `shouldBe` 1++          V.length (GH.pullRequestRequestedTeamReviewers pullRequestTeamReviewRequested)+                `shouldBe` 1+     describe "checking if a pull request is merged" $ do         it "works" $ withAuth $ \auth -> do-            b <- GitHub.executeRequest auth $ GitHub.isPullRequestMergedR "phadej" "github" (Id 14)+            b <- GH.executeRequest auth $ GH.isPullRequestMergedR "haskell-github" "github" (GH.IssueNumber 14)             b `shouldSatisfy` isRight             fromRightS b `shouldBe` True +    describe "Draft Pull Request" $ do+        it "works" $ withAuth $ \auth -> do+            cs <- GH.executeRequest auth $+                draftPullRequestsForR "haskell-github" "github" opts GH.FetchAll++            cs `shouldSatisfy` isRight+   where     repos =       [ ("thoughtbot", "paperclip")-      , ("phadej", "github")-      , ("haskell", "cabal")+      , ("haskell-github", "github")       ]-    opts = GitHub.stateClosed+    opts = GH.stateClosed -    simplePullRequestOpened :: GitHub.SimplePullRequest+    simplePullRequestOpened :: GH.SimplePullRequest     simplePullRequestOpened =         fromRightS (eitherDecodeStrict prOpenedPayload) -    pullRequestOpened :: GitHub.PullRequest+    pullRequestOpened :: GH.PullRequest     pullRequestOpened =         fromRightS (eitherDecodeStrict prOpenedPayload) -    simplePullRequestReviewRequested :: GitHub.SimplePullRequest+    simplePullRequestReviewRequested :: GH.SimplePullRequest     simplePullRequestReviewRequested =         fromRightS (eitherDecodeStrict prReviewRequestedPayload) -    pullRequestReviewRequested :: GitHub.PullRequest+    simplePullRequestTeamReviewRequested :: GH.SimplePullRequest+    simplePullRequestTeamReviewRequested =+        fromRightS (eitherDecodeStrict prTeamReviewRequestedPayload)++    pullRequestReviewRequested :: GH.PullRequest     pullRequestReviewRequested =         fromRightS (eitherDecodeStrict prReviewRequestedPayload) +    pullRequestTeamReviewRequested :: GH.PullRequest+    pullRequestTeamReviewRequested =+        fromRightS (eitherDecodeStrict prTeamReviewRequestedPayload)+     prOpenedPayload :: ByteString     prOpenedPayload = $(embedFile "fixtures/pull-request-opened.json")      prReviewRequestedPayload :: ByteString     prReviewRequestedPayload = $(embedFile "fixtures/pull-request-review-requested.json")++    prTeamReviewRequestedPayload :: ByteString+    prTeamReviewRequestedPayload = $(embedFile "fixtures/pull-request-team-review-requested.json")++-------------------------------------------------------------------------------+-- Draft Pull Requests+-------------------------------------------------------------------------------++draftPullRequestsForR+    :: GH.Name GH.Owner+    -> GH.Name GH.Repo+    -> GH.PullRequestMod+    -> GH.FetchCount+    -> GH.GenRequest ('GH.MtPreview ShadowCat) k (V.Vector DraftPR)+draftPullRequestsForR user repo opts = GH.PagedQuery+    ["repos", GH.toPathPart user, GH.toPathPart repo, "pulls"]+    (GH.prModToQueryString opts)++data DraftPR = DraftPR+    { dprId     :: !(GH.Id GH.PullRequest)+    , dprNumber :: !GH.IssueNumber+    , dprTitle  :: !Text+    , dprDraft  :: !Bool+    }+  deriving (Show)++instance FromJSON DraftPR where+    parseJSON = withObject "DraftPR" $ \obj -> DraftPR+        <$> obj .: "id"+        <*> obj .: "number"+        <*> obj .: "title"+        <*> obj .: "draft"++-- | @application/vnd.github.shadow-cat-preview+json@ <https://developer.github.com/v3/previews/#draft-pull-requests>+data ShadowCat++instance GH.PreviewAccept ShadowCat where+    previewContentType = Tagged "application/vnd.github.shadow-cat-preview+json"++instance FromJSON a => GH.PreviewParseResponse ShadowCat a where+    previewParseResponse _ res = Tagged (GH.parseResponseJSON res)
+ spec/GitHub/RateLimitSpec.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE OverloadedStrings #-}+module GitHub.RateLimitSpec where++import qualified GitHub++import Prelude ()+import Prelude.Compat++import Data.Either.Compat (isRight)+import Data.String        (fromString)+import System.Environment (lookupEnv)+import Test.Hspec         (Spec, describe, it, pendingWith, shouldSatisfy)++fromRightS :: Show a => Either a b -> b+fromRightS (Right b) = b+fromRightS (Left a) = error $ "Expected a Right and got a Left" ++ show a++withAuth :: (GitHub.Auth -> IO ()) -> IO ()+withAuth action = do+    mtoken <- lookupEnv "GITHUB_TOKEN"+    case mtoken of+        Nothing    -> pendingWith "no GITHUB_TOKEN"+        Just token -> action (GitHub.OAuth $ fromString token)++spec :: Spec+spec = describe "rateLimitR" $+    it "works" $ withAuth $ \auth -> do+        cs <- GitHub.executeRequest auth GitHub.rateLimitR+        cs `shouldSatisfy` isRight
spec/GitHub/ReleasesSpec.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell   #-} module GitHub.ReleasesSpec where  import qualified GitHub
spec/GitHub/ReposSpec.hs view
@@ -1,16 +1,22 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell   #-}++#if __GLASGOW_HASKELL__ >= 900+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+#endif+ module GitHub.ReposSpec where -import GitHub                 (Auth (..), Repo (..), RepoPublicity (..),-                               executeRequest, repositoryR)-import GitHub.Endpoints.Repos (currentUserRepos, languagesFor', userRepos')+import GitHub+       (Auth (..), FetchCount (..), Repo (..), RepoPublicity (..), github,+       repositoryR)+import GitHub.Endpoints.Repos (currentUserReposR, languagesForR, userReposR)  import Data.Either.Compat (isRight) import Data.String        (fromString) import System.Environment (lookupEnv)-import Test.Hspec         (Spec, describe, it, pendingWith, shouldBe,-                           shouldSatisfy)+import Test.Hspec+       (Spec, describe, it, pendingWith, shouldBe, shouldSatisfy)  import qualified Data.HashMap.Strict as HM @@ -29,24 +35,24 @@ spec = do   describe "repositoryR" $ do     it "works" $ withAuth $ \auth -> do-      er <- executeRequest auth $ repositoryR "phadej" "github"+      er <- github auth repositoryR "haskell-github" "github"       er `shouldSatisfy` isRight       let Right r = er-      -- https://github.com/phadej/github/pull/219+      -- https://github.com/haskell-github/github/pull/219       repoDefaultBranch r `shouldBe` Just "master"    describe "currentUserRepos" $ do     it "works" $ withAuth $ \auth -> do-      cs <- currentUserRepos auth RepoPublicityAll+      cs <- github auth currentUserReposR RepoPublicityAll FetchAll       cs `shouldSatisfy` isRight    describe "userRepos" $ do     it "works" $ withAuth $ \auth -> do-      cs <- userRepos' (Just auth) "phadej" RepoPublicityAll+      cs <- github auth userReposR "phadej" RepoPublicityAll FetchAll       cs `shouldSatisfy` isRight    describe "languagesFor'" $ do     it "works" $ withAuth $ \auth -> do-      ls <- languagesFor' (Just auth) "phadej" "github"+      ls <- github auth languagesForR "haskell-github" "github"       ls `shouldSatisfy` isRight       fromRightS ls `shouldSatisfy` HM.member "Haskell"
+ spec/GitHub/ReviewDecodeSpec.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+module GitHub.ReviewDecodeSpec where++import Data.Aeson         (eitherDecodeStrict)+import Data.Either.Compat (isRight)+import Data.FileEmbed     (embedFile)+import Test.Hspec+       (Spec, describe, it, shouldSatisfy)++import GitHub.Data (Review)++spec :: Spec+spec = do+  describe "PENDING state" $ do+    -- https://docs.github.com/en/rest/reference/pulls#create-a-review-for-a-pull-request+    -- > Pull request reviews created in the PENDING state do not include the submitted_at property in the response.+    it "decodes review when submitted_at is missing" $ do+      let reviewInfo = eitherDecodeStrict $(embedFile "fixtures/pull-request-pending-review.json") :: Either String Review+      reviewInfo `shouldSatisfy` isRight++  describe "Other states" $ do+    it "decodes review" $ do+      let reviewInfo = eitherDecodeStrict $(embedFile "fixtures/pull-request-approved-review.json") :: Either String Review+      reviewInfo `shouldSatisfy` isRight
spec/GitHub/SearchSpec.hs view
@@ -2,10 +2,10 @@ {-# LANGUAGE TemplateHaskell   #-} module GitHub.SearchSpec where -import Prelude        ()+import Prelude () import Prelude.Compat -import Data.Aeson.Compat  (eitherDecodeStrict)+import Data.Aeson         (eitherDecodeStrict) import Data.FileEmbed     (embedFile) import Data.Proxy         (Proxy (..)) import Data.String        (fromString)@@ -14,8 +14,11 @@  import qualified Data.Vector as V -import GitHub.Data             (Auth (..), Issue (..), mkId, IssueState (..))-import GitHub.Endpoints.Search (SearchResult (..), searchIssues')+import GitHub (github)+import GitHub.Data+       (Auth (..), Issue (..), IssueNumber (..), IssueState (..),+       SimpleUser (..), User, mkId)+import GitHub.Endpoints.Search (SearchResult' (..), SearchResult, searchIssuesR, searchUsersR)  fromRightS :: Show a => Either a b -> b fromRightS (Right b) = b@@ -40,18 +43,25 @@        let issue1 = issues V.! 0       issueId issue1 `shouldBe` mkId (Proxy :: Proxy Issue) 123898390-      issueNumber issue1 `shouldBe` 130+      issueNumber issue1 `shouldBe` IssueNumber 130       issueTitle issue1 `shouldBe` "Make test runner more robust"       issueState issue1 `shouldBe` StateClosed        let issue2 = issues V.! 1       issueId issue2 `shouldBe` mkId (Proxy :: Proxy Issue) 119694665-      issueNumber issue2 `shouldBe` 127+      issueNumber issue2 `shouldBe` IssueNumber 127       issueTitle issue2 `shouldBe` "Decouple request creation from execution"       issueState issue2 `shouldBe` StateOpen      it "performs an issue search via the API" $ withAuth $ \auth -> do-      let query = "Decouple in:title repo:phadej/github created:<=2015-12-01"-      issues <- searchResultResults . fromRightS <$> searchIssues' (Just auth) query+      let query = "Decouple in:title repo:haskell-github/github created:<=2015-12-01"+      issues <- fmap (searchResultResults . fromRightS) <$> github auth $ searchIssuesR query 5       length issues `shouldBe` 1       issueId (V.head issues) `shouldBe` mkId (Proxy :: Proxy Issue) 119694665++  describe "searchUsers" $+    it "performs a user search via the API" $ withAuth $ \auth -> do+      let query = "oleg.grenrus@iki.fi created:<2020-01-01"+      users <- fmap (searchResultResults . fromRightS) <$> github auth $ searchUsersR query 5+      length users `shouldBe` 1+      simpleUserId (V.head users) `shouldBe` mkId (Proxy :: Proxy User) 51087
spec/GitHub/UsersSpec.hs view
@@ -2,22 +2,22 @@ {-# LANGUAGE TemplateHaskell   #-} module GitHub.UsersSpec where -import Data.Aeson.Compat  (eitherDecodeStrict)+import Data.Aeson         (eitherDecodeStrict) import Data.Either.Compat (isLeft, isRight) import Data.FileEmbed     (embedFile) import Data.String        (fromString) import System.Environment (lookupEnv)-import Test.Hspec         (Spec, describe, it, pendingWith, shouldBe,-                           shouldSatisfy)+import Test.Hspec+       (Spec, describe, it, pendingWith, shouldBe, shouldSatisfy)  import qualified GitHub -import GitHub.Data                      (Auth (..), Organization (..),-                                         User (..), fromOwner)-import GitHub.Endpoints.Users           (ownerInfoForR, userInfoCurrent',-                                         userInfoFor')+import GitHub.Data+       (Auth (..), Organization (..), User (..), fromOwner)+import GitHub.Endpoints.Users+       (ownerInfoForR, userInfoCurrentR, userInfoForR) import GitHub.Endpoints.Users.Followers (usersFollowedByR, usersFollowingR)-import GitHub.Request                   (executeRequest)+import GitHub.Request                   (github)  fromRightS :: Show a => Either a b -> b fromRightS (Right b) = b@@ -41,38 +41,42 @@       let userInfo = eitherDecodeStrict $(embedFile "fixtures/user.json")       userLogin (fromRightS userInfo) `shouldBe` "mike-burns" +    it "decodes user-bot json" $ do+      let userInfo = eitherDecodeStrict $(embedFile "fixtures/user-bot.json")+      userLogin (fromRightS userInfo) `shouldBe` "mike-burns"+     it "returns information about the user" $ withAuth $ \auth -> do-      userInfo <- userInfoFor' (Just auth) "mike-burns"+      userInfo <- github auth userInfoForR "mike-burns"       userLogin (fromRightS userInfo) `shouldBe` "mike-burns"      it "catches http exceptions" $ withAuth $ \auth -> do-      userInfo <- userInfoFor' (Just auth) "i-hope-this-user-will-never-exist"+      userInfo <- github auth userInfoForR "i-hope-this-user-will-never-exist"       userInfo `shouldSatisfy` isLeft      it "should fail for organization" $ withAuth $ \auth -> do-      userInfo <- userInfoFor' (Just auth) "haskell"+      userInfo <- github auth userInfoForR "haskell"       userInfo `shouldSatisfy` isLeft    describe "ownerInfoFor" $ do     it "works for users and organizations" $ withAuth $ \auth -> do-      a <- executeRequest auth $ ownerInfoForR "haskell"-      b <- executeRequest auth $ ownerInfoForR "phadej"+      a <- github auth ownerInfoForR "haskell"+      b <- github auth ownerInfoForR "phadej"       a `shouldSatisfy` isRight       b `shouldSatisfy` isRight       (organizationLogin . fromRightS . fromOwner . fromRightS $ a) `shouldBe` "haskell"       (userLogin . fromLeftS . fromOwner . fromRightS $ b) `shouldBe` "phadej" -  describe "userInfoCurrent'" $ do-    it "returns information about the autenticated user" $ withAuth $ \auth -> do-      userInfo <- userInfoCurrent' auth+  describe "userInfoCurrentR" $ do+    it "returns information about the authenticated user" $ withAuth $ \auth -> do+      userInfo <- github auth userInfoCurrentR       userInfo `shouldSatisfy` isRight    describe "usersFollowing" $ do     it "works" $ withAuth $ \auth -> do-      us <- executeRequest auth $ usersFollowingR "phadej" (GitHub.FetchAtLeast 10)+      us <- github auth usersFollowingR "phadej" (GitHub.FetchAtLeast 10)       us `shouldSatisfy` isRight    describe "usersFollowedBy" $ do     it "works" $ withAuth $ \auth -> do-      us <- executeRequest auth $ usersFollowedByR "phadej" (GitHub.FetchAtLeast 10)+      us <- github auth usersFollowedByR "phadej" (GitHub.FetchAtLeast 10)       us `shouldSatisfy` isRight
src/GitHub.hs view
@@ -1,24 +1,33 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>------ This module re-exports all request constructrors and data definitions from+-- This module re-exports all request constructors and data definitions from -- this package. ----- See "GitHub.Request" module for executing 'Request', or other modules--- of this package (e.g. "GitHub.Users") for already composed versions.+-- See "GitHub.Request" module for executing 'Request', in short+-- use @'github' request@, for example --+-- @+-- 'github' 'userInfoForR'+--   :: 'AuthMethod' am => am -> 'Name' 'User' -> IO (Either 'Error' 'User')+-- @+-- -- The missing endpoints lists show which endpoints we know are missing, there -- might be more.+ module GitHub (     -- * Activity     -- | See <https://developer.github.com/v3/activity/>      -- ** Events-    -- | See https://developer.github.com/v3/activity/events/#events+    -- | See <https://developer.github.com/v3/activity/events/>     repositoryEventsR,     userEventsR,++    -- ** Notifications+    -- | See <https://developer.github.com/v3/activity/notifications/>+    getNotificationsR,+    markNotificationAsReadR,+    markAllNotificationsAsReadR,+     -- ** Starring     -- | See <https://developer.github.com/v3/activity/starring/>     --@@ -39,9 +48,9 @@     --     -- * Query a Repository Subscription     -- * Set a Repository Subscription-    -- * Delete a Repository Subscription     watchersForR,     reposWatchedByR,+    unwatchRepoR,      -- * Gists     -- | See <https://developer.github.com/v3/gists/>@@ -49,7 +58,6 @@     -- Missing endpoints:     --     -- * Query a specific revision of a gist-    -- * Create a gist     -- * Edit a gist     -- * List gist commits     -- * Check if a gist is starred@@ -57,6 +65,7 @@     -- * List gist forks     gistsR,     gistR,+    createGistR,     starGistR,     unstarGistR,     deleteGistR,@@ -87,6 +96,8 @@     referenceR,     referencesR,     createReferenceR,+    deleteReferenceR,+    namespacedReferencesR,      -- ** Trees     -- | See <https://developer.github.com/v3/git/trees/>@@ -137,13 +148,11 @@     -- ** Milestone     -- | See <https://developer.github.com/v3/issues/milestones/>     ---    -- Missing endpoints:-    ---    -- * Create a milestone-    -- * Update a milestone-    -- * Delete a milestone     milestonesR,     milestoneR,+    createMilestoneR,+    updateMilestoneR,+    deleteMilestoneR,      -- * Organizations     -- | See <https://developer.github.com/v3/orgs/>@@ -155,6 +164,7 @@     -- * Edit an organization     publicOrganizationsForR,     publicOrganizationR,+    organizationsR,     -- ** Members     -- | See <https://developer.github.com/v3/orgs/members/>     --@@ -163,6 +173,12 @@     membersOfWithR,     isMemberOfR,     orgInvitationsR,+    orgMembershipR,+    -- ** Outside Collaborators+    -- | See <https://developer.github.com/v3/orgs/outside_collaborators/>+    --+    -- Missing endpoints: All except /Outside Collaborator List/+    outsideCollaboratorsR,      -- ** Teams     -- | See <https://developer.github.com/v3/orgs/teams/>@@ -191,6 +207,8 @@     -- | See <https://developer.github.com/v3/pulls/>     pullRequestsForR,     pullRequestR,+    pullRequestPatchR,+    pullRequestDiffR,     createPullRequestR,     updatePullRequestR,     pullRequestCommitsR,@@ -204,11 +222,12 @@     -- Missing endpoints:     --     -- * List comments in a repository-    -- * Create a comment     -- * Edit a comment     -- * Delete a comment     pullRequestCommentsR,     pullRequestCommentR,+    createPullCommentR,+    createPullCommentReplyR,      -- ** Pull request reviews     -- | See <https://developer.github.com/v3/pulls/reviews/>@@ -220,14 +239,8 @@     -- * Submit a pull request review     -- * Dismiss a pull request review     pullRequestReviewsR,-    pullRequestReviews,-    pullRequestReviews',     pullRequestReviewR,-    pullRequestReview,-    pullRequestReview',     pullRequestReviewCommentsR,-    pullRequestReviewCommentsIO,-    pullRequestReviewCommentsIO',      -- * Repositories     -- | See <https://developer.github.com/v3/repos/>@@ -250,7 +263,9 @@     -- ** Collaborators     -- | See <https://developer.github.com/v3/repos/collaborators/>     collaboratorsOnR,+    collaboratorPermissionOnR,     isCollaboratorOnR,+    addCollaboratorR,      -- ** Comments     -- | See <https://developer.github.com/v3/repos/comments/>@@ -259,7 +274,7 @@     --     -- * Create a commit comment     -- * Update a commit comment-    -- *  Delete a commit comment+    -- * Delete a commit comment     commentsForR,     commitCommentsForR,     commitCommentForR,@@ -271,6 +286,43 @@     commitR,     diffR, +    -- ** Reactions+    -- | See <https://docs.github.com/en/rest/reactions/reactions?apiVersion=2022-11-28>+    issueReactionsR,+    createIssueReactionR,+    deleteIssueReactionR,+    commentReactionsR,+    createCommentReactionR,+    deleteCommentReactionR,++    -- ** Contents+    -- | See <https://developer.github.com/v3/repos/contents/>+    contentsForR,+    readmeForR,+    archiveForR,+    createFileR,+    updateFileR,+    deleteFileR,++    -- ** Deploy Keys+    -- | See <https://developer.github.com/v3/repos/keys/>+    deployKeysForR,+    deployKeyForR,+    createRepoDeployKeyR,+    deleteRepoDeployKeyR,++    -- ** Deployments+    -- | See <https://developer.github.com/v3/repos/deployments/#deployments>+    --+    -- Missing endpoints:+    -- * Get a single deployment+    -- * Update a deployment+    -- * Get a single deployment status+    deploymentsWithOptionsForR,+    createDeploymentR,+    deploymentStatusesForR,+    createDeploymentStatusR,+     -- ** Forks     -- | See <https://developer.github.com/v3/repos/forks/>     --@@ -279,6 +331,12 @@     -- * Create a fork     forksForR, +    -- ** Statuses+    -- | See <https://developer.github.com/v3/repos/statuses/>+    createStatusR,+    statusesForR,+    statusForR,+     -- ** Webhooks     -- | See <https://developer.github.com/v3/repos/hooks/>     webhooksForR,@@ -295,15 +353,25 @@     latestReleaseR,     releaseByTagNameR, +    -- ** Invitations+    -- | See <https://developer.github.com/v3/repos/invitations/>+    -- Missing endpoints:++    -- * Delete a repository invitation+    -- * Update a repository invitation+    -- * Decline a repository invitation++    listInvitationsOnR,+    acceptInvitationFromR,+    listInvitationsForR,++     -- * Search     -- | See <https://developer.github.com/v3/search/>-    ---    -- Missing endpoints:-    ---    -- * Search users     searchReposR,     searchCodeR,     searchIssuesR,+    searchUsersR,      -- * Users     -- | See <https://developer.github.com/v3/users/>@@ -339,12 +407,88 @@     usersFollowingR,     usersFollowedByR, -    -- ** Statuses-    -- | See <https://developer.github.com/v3/repos/statuses/>-    createStatusR,-    statusesForR,-    statusForR,+    -- ** Git SSH Keys+    -- | See <https://developer.github.com/v3/users/keys/>+    publicSSHKeysR,+    publicSSHKeysForR,+    publicSSHKeyR,+    createUserPublicSSHKeyR,+    deleteUserPublicSSHKeyR, +    -- ** Rate Limit+    -- | See <https://developer.github.com/v3/rate_limit/>+    rateLimitR,++    -- ** Actions - artifacts+    -- | See <https://docs.github.com/en/rest/actions/artifacts>+    artifactsForR,+    artifactR,+    deleteArtifactR,+    downloadArtifactR,+    artifactsForWorkflowRunR,++    -- ** Actions - cache+    -- | See <https://docs.github.com/en/rest/actions/cache>+    cacheUsageOrganizationR,+    cacheUsageByRepositoryR,+    cacheUsageR,+    cachesForRepoR,+    deleteCacheR,++    -- ** Actions - secrets+    -- | See <https://docs.github.com/en/rest/actions/secrets>+    organizationSecretsR,+    organizationPublicKeyR,+    organizationSecretR,+    setOrganizationSecretR,+    deleteOrganizationSecretR,+    organizationSelectedRepositoriesForSecretR,+    setOrganizationSelectedRepositoriesForSecretR,+    addOrganizationSelectedRepositoriesForSecretR,+    removeOrganizationSelectedRepositoriesForSecretR,+    repoSecretsR,+    repoPublicKeyR,+    repoSecretR,+    setRepoSecretR,+    deleteRepoSecretR,+    environmentSecretsR,+    environmentPublicKeyR,+    environmentSecretR,+    setEnvironmentSecretR,+    deleteEnvironmentSecretR,++    -- ** Actions - workflow jobs+    -- | See <https://docs.github.com/en/rest/actions/workflow-jobs>+    jobR,+    downloadJobLogsR,+    jobsForWorkflowRunAttemptR,+    jobsForWorkflowRunR,++    -- ** Actions - workflow runs+    -- | See <https://docs.github.com/en/rest/actions/workflow-runs>+    reRunJobR,+    workflowRunsR,+    workflowRunR,+    deleteWorkflowRunR,+    workflowRunReviewHistoryR,+    approveWorkflowRunR,+    workflowRunAttemptR,+    downloadWorkflowRunAttemptLogsR,+    cancelWorkflowRunR,+    downloadWorkflowRunLogsR,+    deleteWorkflowRunLogsR,+    reRunWorkflowR,+    reRunFailedJobsR,+    workflowRunsForWorkflowR,++    -- ** Actions - workflows+    -- | See <https://docs.github.com/en/rest/actions/workflows>+    repositoryWorkflowsR,+    workflowR,+    disableWorkflowR,+    triggerWorkflowR,+    enableWorkflowR,+     -- * Data definitions     module GitHub.Data,     -- * Request handling@@ -352,7 +496,14 @@     ) where  import GitHub.Data+import GitHub.Endpoints.Actions.Artifacts+import GitHub.Endpoints.Actions.Cache+import GitHub.Endpoints.Actions.Secrets+import GitHub.Endpoints.Actions.WorkflowJobs+import GitHub.Endpoints.Actions.WorkflowRuns+import GitHub.Endpoints.Actions.Workflows import GitHub.Endpoints.Activity.Events+import GitHub.Endpoints.Activity.Notifications import GitHub.Endpoints.Activity.Starring import GitHub.Endpoints.Activity.Watching import GitHub.Endpoints.Gists@@ -368,15 +519,22 @@ import GitHub.Endpoints.Issues.Milestones import GitHub.Endpoints.Organizations import GitHub.Endpoints.Organizations.Members+import GitHub.Endpoints.Organizations.OutsideCollaborators import GitHub.Endpoints.Organizations.Teams import GitHub.Endpoints.PullRequests-import GitHub.Endpoints.PullRequests.Reviews import GitHub.Endpoints.PullRequests.Comments+import GitHub.Endpoints.PullRequests.Reviews+import GitHub.Endpoints.Reactions+import GitHub.Endpoints.RateLimit import GitHub.Endpoints.Repos import GitHub.Endpoints.Repos.Collaborators import GitHub.Endpoints.Repos.Comments import GitHub.Endpoints.Repos.Commits+import GitHub.Endpoints.Repos.Contents+import GitHub.Endpoints.Repos.DeployKeys+import GitHub.Endpoints.Repos.Deployments import GitHub.Endpoints.Repos.Forks+import GitHub.Endpoints.Repos.Invitations import GitHub.Endpoints.Repos.Releases import GitHub.Endpoints.Repos.Statuses import GitHub.Endpoints.Repos.Webhooks@@ -384,4 +542,5 @@ import GitHub.Endpoints.Users import GitHub.Endpoints.Users.Emails import GitHub.Endpoints.Users.Followers+import GitHub.Endpoints.Users.PublicSSHKeys import GitHub.Request
src/GitHub/Auth.hs view
@@ -1,26 +1,58 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>----module GitHub.Auth where+module GitHub.Auth (+    Auth (..),+    Token,+    JWTToken,+    AuthMethod,+    endpoint,+    setAuthRequest+    ) where  import GitHub.Internal.Prelude import Prelude () -import qualified Data.ByteString as BS+import qualified Data.ByteString     as BS+import qualified Data.Text.Encoding  as TE+import qualified Network.HTTP.Client as HTTP  type Token = BS.ByteString+type JWTToken = Text  -- | The Github auth data type data Auth-    = BasicAuth BS.ByteString BS.ByteString-    | OAuth Token -- ^ token-    | EnterpriseOAuth Text    -- custom API endpoint without-                              -- trailing slash-                      Token   -- token-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    = BasicAuth BS.ByteString BS.ByteString  -- ^ Username and password+    | OAuth Token                            -- ^ OAuth token+    | JWT JWTToken                           -- ^ JWT Token+    | EnterpriseOAuth Text Token             -- ^ Custom endpoint and OAuth token+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData Auth where rnf = genericRnf+instance NFData Auth instance Binary Auth instance Hashable Auth++-- | A type class for different authentication methods+--+-- Note the '()' intance, which doee nothing, i.e. is unauthenticated.+class AuthMethod a where+    -- | Custom API endpoint without trailing slash+    endpoint       :: a -> Maybe Text+    -- | A function which sets authorisation on an HTTP request+    setAuthRequest :: a -> HTTP.Request -> HTTP.Request++instance AuthMethod () where+    endpoint _ = Nothing+    setAuthRequest _ = id++instance AuthMethod Auth where+    endpoint (BasicAuth _ _)       = Nothing+    endpoint (OAuth _)             = Nothing+    endpoint (JWT _)             = Nothing+    endpoint (EnterpriseOAuth e _) = Just e++    setAuthRequest (BasicAuth u p)       = HTTP.applyBasicAuth u p+    setAuthRequest (OAuth t)             = setAuthHeader $ "token " <> t+    setAuthRequest (JWT t)               = setAuthHeader $ "Bearer " <> TE.encodeUtf8 t+    setAuthRequest (EnterpriseOAuth _ t) = setAuthHeader $ "token " <> t++setAuthHeader :: BS.ByteString -> HTTP.Request -> HTTP.Request+setAuthHeader auth req =+    req { HTTP.requestHeaders = ("Authorization", auth) : HTTP.requestHeaders req }
src/GitHub/Data.hs view
@@ -1,10 +1,6 @@-{-# LANGUAGE CPP #-}------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>------ This module re-exports the @GitHub.Data.@ and "Github.Auth" submodules.+-- This module re-exports the @GitHub.Data.@ and "GitHub.Auth" submodules.+ module GitHub.Data (     -- * Tagged types     -- ** Name@@ -30,13 +26,23 @@     mkRepoId,     fromUserId,     fromOrganizationId,+    -- * IssueNumber+    IssueNumber (..),     -- * Module re-exports     module GitHub.Auth,+    module GitHub.Data.Actions.Common,+    module GitHub.Data.Actions.Artifacts,+    module GitHub.Data.Actions.Cache,+    module GitHub.Data.Actions.Secrets,+    module GitHub.Data.Actions.Workflows,+    module GitHub.Data.Actions.WorkflowJobs,+    module GitHub.Data.Actions.WorkflowRuns,     module GitHub.Data.Activities,     module GitHub.Data.Comments,     module GitHub.Data.Content,     module GitHub.Data.Definitions,     module GitHub.Data.DeployKeys,+    module GitHub.Data.Deployments,     module GitHub.Data.Email,     module GitHub.Data.Events,     module GitHub.Data.Gists,@@ -45,8 +51,11 @@     module GitHub.Data.Issues,     module GitHub.Data.Milestone,     module GitHub.Data.Options,+    module GitHub.Data.PublicSSHKeys,     module GitHub.Data.PullRequests,+    module GitHub.Data.RateLimit,     module GitHub.Data.Releases,+    module GitHub.Data.Reactions,     module GitHub.Data.Repos,     module GitHub.Data.Request,     module GitHub.Data.Reviews,@@ -54,18 +63,27 @@     module GitHub.Data.Statuses,     module GitHub.Data.Teams,     module GitHub.Data.URL,-    module GitHub.Data.Webhooks+    module GitHub.Data.Webhooks,+    module GitHub.Data.Webhooks.Validate,     ) where  import GitHub.Internal.Prelude import Prelude ()  import GitHub.Auth+import GitHub.Data.Actions.Common+import GitHub.Data.Actions.Artifacts+import GitHub.Data.Actions.Secrets+import GitHub.Data.Actions.Cache+import GitHub.Data.Actions.Workflows+import GitHub.Data.Actions.WorkflowJobs+import GitHub.Data.Actions.WorkflowRuns import GitHub.Data.Activities import GitHub.Data.Comments import GitHub.Data.Content import GitHub.Data.Definitions import GitHub.Data.DeployKeys+import GitHub.Data.Deployments import GitHub.Data.Email import GitHub.Data.Events import GitHub.Data.Gists@@ -76,8 +94,11 @@ import GitHub.Data.Milestone import GitHub.Data.Name import GitHub.Data.Options+import GitHub.Data.PublicSSHKeys import GitHub.Data.PullRequests+import GitHub.Data.RateLimit import GitHub.Data.Releases+import GitHub.Data.Reactions import GitHub.Data.Repos import GitHub.Data.Request import GitHub.Data.Reviews@@ -86,6 +107,7 @@ import GitHub.Data.Teams import GitHub.Data.URL import GitHub.Data.Webhooks+import GitHub.Data.Webhooks.Validate  mkOwnerId :: Int -> Id Owner mkOwnerId = Id
+ src/GitHub/Data/Actions/Artifacts.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE DataKinds         #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures    #-}++module GitHub.Data.Actions.Artifacts (+    Artifact(..),+    ArtifactWorkflowRun(..),+    ) where++import GitHub.Data.Id          (Id)+import GitHub.Data.URL         (URL)+import GitHub.Internal.Prelude+import Prelude ()++import GitHub.Data.Actions.Common       (WithTotalCount (WithTotalCount))+import GitHub.Data.Actions.WorkflowRuns (WorkflowRun)+import GitHub.Data.Repos                (Repo)++-------------------------------------------------------------------------------+-- Artifact+-------------------------------------------------------------------------------++data ArtifactWorkflowRun  = ArtifactWorkflowRun+    { artifactWorkflowRunWorkflowRunId    :: !(Id WorkflowRun)+    , artifactWorkflowRunRepositoryId     :: !(Id Repo)+    , artifactWorkflowRunHeadRepositoryId :: !(Id Repo)+    , artifactWorkflowRunHeadBranch       :: !Text+    , artifactWorkflowRunHeadSha          :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++data Artifact = Artifact+    { artifactArchiveDownloadUrl :: !URL+    , artifactCreatedAt          :: !UTCTime+    , artifactExpired            :: !Bool+    , artifactExpiresAt          :: !UTCTime+    , artifactId                 :: !(Id Artifact)+    , artifactName               :: !Text+    , artifactNodeId             :: !Text+    , artifactSizeInBytes        :: !Int+    , artifactUpdatedAt          :: !UTCTime+    , artifactUrl                :: !URL+    , artifactWorkflowRun        :: !ArtifactWorkflowRun+    }+  deriving (Show, Data, Eq, Ord, Generic)++-------------------------------------------------------------------------------+-- JSON instances+-------------------------------------------------------------------------------++instance FromJSON ArtifactWorkflowRun where+    parseJSON = withObject "ArtifactWorkflowRun" $ \o -> ArtifactWorkflowRun+        <$> o .: "id"+        <*> o .: "repository_id"+        <*> o .: "head_repository_id"+        <*> o .: "head_branch"+        <*> o .: "head_sha"++instance FromJSON Artifact where+    parseJSON = withObject "Artifact" $ \o -> Artifact+        <$> o .: "archive_download_url"+        <*> o .: "created_at"+        <*> o .: "expired"+        <*> o .: "expires_at"+        <*> o .: "id"+        <*> o .: "name"+        <*> o .: "node_id"+        <*> o .: "size_in_bytes"+        <*> o .: "updated_at"+        <*> o .: "url"+        <*> o .: "workflow_run"++instance FromJSON (WithTotalCount Artifact) where+    parseJSON = withObject "ArtifactList" $ \o -> WithTotalCount+        <$> o .: "artifacts"+        <*> o .: "total_count"
+ src/GitHub/Data/Actions/Cache.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE DataKinds         #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures    #-}++module GitHub.Data.Actions.Cache (+    Cache(..),+    RepositoryCacheUsage(..),+    OrganizationCacheUsage(..)+    ) where++import GitHub.Data.Id          (Id)+import GitHub.Internal.Prelude+import Prelude ()++import GitHub.Data.Actions.Common (WithTotalCount (WithTotalCount))++-------------------------------------------------------------------------------+-- Cache+-------------------------------------------------------------------------------++data Cache = Cache+    { cacheId             :: !(Id Cache)+    , cacheRef            :: !Text+    , cacheKey            :: !Text+    , cacheVersion        :: !Text+    , cacheLastAccessedAt :: !UTCTime+    , cacheCreatedAt      :: !UTCTime+    , cacheSizeInBytes    :: !Int+    }+  deriving (Show, Data, Eq, Ord, Generic)++data RepositoryCacheUsage = RepositoryCacheUsage+    { repositoryCacheUsageFullName                :: !Text+    , repositoryCacheUsageActiveCachesSizeInBytes :: !Int+    , repositoryCacheUsageActiveCachesCount       :: !Int+    }+  deriving (Show, Data, Eq, Ord, Generic)++data OrganizationCacheUsage = OrganizationCacheUsage+    { organizationCacheUsageTotalActiveCachesSizeInBytes :: !Int+    , organizationCacheUsageTotalActiveCachesCount       :: !Int+    }+  deriving (Show, Data, Eq, Ord, Generic)++-------------------------------------------------------------------------------+-- JSON instances+-------------------------------------------------------------------------------++instance FromJSON Cache where+    parseJSON = withObject "Cache" $ \o -> Cache+        <$> o .: "id"+        <*> o .: "ref"+        <*> o .: "key"+        <*> o .: "version"+        <*> o .: "last_accessed_at"+        <*> o .: "created_at"+        <*> o .: "size_in_bytes"++instance FromJSON (WithTotalCount Cache) where+    parseJSON = withObject "CacheList" $ \o -> WithTotalCount+        <$> o .: "actions_caches"+        <*> o .: "total_count"++instance FromJSON OrganizationCacheUsage where+    parseJSON = withObject "OrganizationCacheUsage" $ \o -> OrganizationCacheUsage+        <$> o .: "total_active_caches_size_in_bytes"+        <*> o .: "total_active_caches_count"++instance FromJSON RepositoryCacheUsage where+    parseJSON = withObject "RepositoryCacheUsage" $ \o -> RepositoryCacheUsage+        <$> o .: "full_name"+        <*> o .: "active_caches_size_in_bytes"+        <*> o .: "active_caches_count"++instance FromJSON (WithTotalCount RepositoryCacheUsage) where+    parseJSON = withObject "CacheUsageList" $ \o -> WithTotalCount+        <$> o .: "repository_cache_usages"+        <*> o .: "total_count"
+ src/GitHub/Data/Actions/Common.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE DataKinds         #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures    #-}++module GitHub.Data.Actions.Common (+    WithTotalCount(..),+    ) where++import GitHub.Internal.Prelude+import Prelude ()++-------------------------------------------------------------------------------+-- Common+-------------------------------------------------------------------------------++-- | A page of a paginated response.+data WithTotalCount a = WithTotalCount+    { withTotalCountItems      :: !(Vector a)+        -- ^ A snippet of the answer.+    , withTotalCountTotalCount :: !Int+        -- ^ The total size of the answer.+    }+  deriving (Show, Data, Eq, Ord, Generic)++-- | Joining two pages of a paginated response.+--   The 'withTotalCountTotalCount' is assumed to be the same in both pages,+--   but this is not checked.+instance Semigroup (WithTotalCount a) where+    WithTotalCount items1 count1 <> WithTotalCount items2 _ =+        WithTotalCount (items1 <> items2) count1++instance Foldable WithTotalCount where+    foldMap f (WithTotalCount items _) = foldMap f items
+ src/GitHub/Data/Actions/Secrets.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE DataKinds         #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures    #-}+{-# LANGUAGE RecordWildCards   #-}++module GitHub.Data.Actions.Secrets (+    OrganizationSecret(..),+    PublicKey(..),+    SetSecret(..),+    SetRepoSecret(..),+    SelectedRepo(..),+    SetSelectedRepositories(..),+    RepoSecret(..),+    Environment(..),+    ) where++import GitHub.Data.Id          (Id)+import GitHub.Internal.Prelude+import Prelude ()++import Data.Maybe                 (maybeToList)+import GitHub.Data.Actions.Common (WithTotalCount (WithTotalCount))+import GitHub.Data.Name           (Name)+import GitHub.Data.Repos          (Repo)++-------------------------------------------------------------------------------+-- Secret+-------------------------------------------------------------------------------++data OrganizationSecret = OrganizationSecret+    { organizationSecretName :: !(Name OrganizationSecret)+    , organizationSecretCreatedAt :: !UTCTime+    , organizationSecretUpdatedAt :: !UTCTime+    , organizationSecretVisibility :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++data PublicKey = PublicKey+    { publicKeyId :: !Text+    , publicKeyKey :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++data SetSecret = SetSecret+    { setSecretPublicKeyId :: !Text+    , setSecretEncryptedValue :: !Text+    , setSecretVisibility :: !Text+    , setSecretSelectedRepositoryIds :: !(Maybe [Id Repo])+    }+  deriving (Show, Data, Eq, Ord, Generic)++data SetRepoSecret = SetRepoSecret+    { setRepoSecretPublicKeyId :: !Text+    , setRepoSecretEncryptedValue :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++data SelectedRepo = SelectedRepo+    { selectedRepoRepoId :: !(Id Repo)+    , selectedRepoRepoName :: !(Name Repo)+    }+  deriving (Show, Data, Eq, Ord, Generic)++data SetSelectedRepositories = SetSelectedRepositories+    { setSelectedRepositoriesRepositoryIds :: ![Id Repo]+    }+  deriving (Show, Data, Eq, Ord, Generic)++data RepoSecret = RepoSecret+    { repoSecretName :: !(Name RepoSecret)+    , repoSecretCreatedAt :: !UTCTime+    , repoSecretUpdatedAt :: !UTCTime+    }+  deriving (Show, Data, Eq, Ord, Generic)++-- TODO move somewhere else?+data Environment = Environment+  deriving (Show, Data, Eq, Ord, Generic)++-------------------------------------------------------------------------------+-- JSON instances+-------------------------------------------------------------------------------++instance FromJSON OrganizationSecret where+    parseJSON = withObject "Secret" $ \o -> OrganizationSecret+        <$> o .: "name"+        <*> o .: "created_at"+        <*> o .: "updated_at"+        <*> o .: "visibility"++instance FromJSON (WithTotalCount OrganizationSecret) where+    parseJSON = withObject "SecretList" $ \o -> WithTotalCount+        <$> o .: "secrets"+        <*> o .: "total_count"++instance FromJSON PublicKey where+    parseJSON = withObject "PublicKey" $ \o -> PublicKey+        <$> o .: "key_id"+        <*> o .: "key"++instance FromJSON SelectedRepo where+    parseJSON = withObject "SelectedRepo" $ \o -> SelectedRepo+        <$> o .: "id"+        <*> o .: "name"++instance ToJSON SetSelectedRepositories where+    toJSON SetSelectedRepositories{..} =+        object+            [ "selected_repository_ids" .=  setSelectedRepositoriesRepositoryIds+            ]++instance ToJSON SetSecret where+    toJSON SetSecret{..} =+        object $+            [ "encrypted_value" .= setSecretEncryptedValue+            ,  "key_id" .= setSecretPublicKeyId+            ,  "visibility" .= setSecretVisibility+            ] <> maybeToList (fmap ("selected_repository_ids" .=) setSecretSelectedRepositoryIds)++instance ToJSON SetRepoSecret where+    toJSON SetRepoSecret{..} =+        object+            [ "encrypted_value" .= setRepoSecretEncryptedValue+            ,  "key_id" .= setRepoSecretPublicKeyId+            ]++instance FromJSON (WithTotalCount SelectedRepo) where+    parseJSON = withObject "SelectedRepoList" $ \o -> WithTotalCount+        <$> o .: "repositories"+        <*> o .: "total_count"++instance FromJSON RepoSecret where+    parseJSON = withObject "RepoSecret" $ \o -> RepoSecret+        <$> o .: "name"+        <*> o .: "created_at"+        <*> o .: "updated_at"++instance FromJSON (WithTotalCount RepoSecret) where+    parseJSON = withObject "RepoSecretList" $ \o -> WithTotalCount+        <$> o .: "secrets"+        <*> o .: "total_count"
+ src/GitHub/Data/Actions/WorkflowJobs.hs view
@@ -0,0 +1,100 @@+{-# LANGUAGE DataKinds         #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures    #-}++module GitHub.Data.Actions.WorkflowJobs (+    JobStep(..),+    Job(..),+    ) where++import Prelude ()+import GitHub.Internal.Prelude+       (Applicative ((<*>)), Data, Eq, FromJSON (parseJSON), Generic, Integer,+       Ord, Show, Text, UTCTime, Vector, withObject, ($), (.:),+       (<$>))++import GitHub.Data.Id                   (Id)+import GitHub.Data.Name                 (Name)+import GitHub.Data.URL                  (URL)++import GitHub.Data.Actions.Common       (WithTotalCount (WithTotalCount))+import GitHub.Data.Actions.WorkflowRuns (WorkflowRun)++-------------------------------------------------------------------------------+-- Workflow jobs+-------------------------------------------------------------------------------++data JobStep = JobStep+    { jobStepName        :: !(Name JobStep)+    , jobStepStatus      :: !Text+    , jobStepConclusion  :: !Text+    , jobStepNumber      :: !Integer+    , jobStepStartedAt   :: !UTCTime+    , jobStepCompletedAt :: !UTCTime+    }+  deriving (Show, Data, Eq, Ord, Generic)++data Job = Job+    { jobId              :: !(Id Job)+    , jobRunId           :: !(Id WorkflowRun)+    , jobRunUrl          :: !URL+    , jobRunAttempt      :: !Integer+    , jobNodeId          :: !Text+    , jobHeadSha         :: !Text+    , jobUrl             :: !URL+    , jobHtmlUrl         :: !URL+    , jobStatus          :: !Text+    , jobConclusion      :: !Text+    , jobStartedAt       :: !UTCTime+    , jobCompletedAt     :: !UTCTime+    , jobName            :: !(Name Job)+    , jobSteps           :: !(Vector JobStep)+    , jobRunCheckUrl     :: !URL+    , jobLabels          :: !(Vector Text)+    , jobRunnerId        :: !Integer+    , jobRunnerName      :: !Text+    , jobRunnerGroupId   :: !Integer+    , jobRunnerGroupName :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++-------------------------------------------------------------------------------+-- JSON instances+-------------------------------------------------------------------------------++instance FromJSON JobStep where+    parseJSON = withObject "JobStep" $ \o -> JobStep+        <$> o .: "name"+        <*> o .: "status"+        <*> o .: "conclusion"+        <*> o .: "number"+        <*> o .: "started_at"+        <*> o .: "completed_at"++instance FromJSON Job where+    parseJSON = withObject "Job" $ \o -> Job+        <$> o .: "id"+        <*> o .: "run_id"+        <*> o .: "run_url"+        <*> o .: "run_attempt"+        <*> o .: "node_id"+        <*> o .: "head_sha"+        <*> o .: "url"+        <*> o .: "html_url"+        <*> o .: "status"+        <*> o .: "conclusion"+        <*> o .: "started_at"+        <*> o .: "completed_at"+        <*> o .: "name"+        <*> o .: "steps"+        <*> o .: "check_run_url"+        <*> o .: "labels"+        <*> o .: "runner_id"+        <*> o .: "runner_name"+        <*> o .: "runner_group_id"+        <*> o .: "runner_group_name"++instance FromJSON (WithTotalCount Job) where+    parseJSON = withObject "JobList" $ \o -> WithTotalCount+        <$> o .: "jobs"+        <*> o .: "total_count"
+ src/GitHub/Data/Actions/WorkflowRuns.hs view
@@ -0,0 +1,91 @@+{-# LANGUAGE DataKinds         #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures    #-}++module GitHub.Data.Actions.WorkflowRuns (+    WorkflowRun(..),+    RunAttempt(..),+    ReviewHistory(..),+    ) where++import GitHub.Data.Actions.Common (WithTotalCount (WithTotalCount))+import GitHub.Data.Definitions+import GitHub.Data.URL            (URL)+import GitHub.Internal.Prelude+import Prelude ()++import GitHub.Data.Id   (Id)+import GitHub.Data.Name (Name)++-------------------------------------------------------------------------------+-- Workflow runs+-------------------------------------------------------------------------------++data WorkflowRun  = WorkflowRun+    { workflowRunWorkflowRunId :: !(Id WorkflowRun)+    , workflowRunName :: !(Name WorkflowRun)+    , workflowRunHeadBranch :: !Text+    , workflowRunHeadSha :: !Text+    , workflowRunPath :: !Text+    , workflowRunDisplayTitle :: !Text+    , workflowRunRunNumber :: !Integer+    , workflowRunEvent :: !Text+    , workflowRunStatus :: !Text+    , workflowRunConclusion :: !(Maybe Text)+    , workflowRunWorkflowId :: !Integer+    , workflowRunUrl :: !URL+    , workflowRunHtmlUrl :: !URL+    , workflowRunCreatedAt :: !UTCTime+    , workflowRunUpdatedAt :: !UTCTime+    , workflowRunActor :: !SimpleUser+    , workflowRunAttempt :: !Integer+    , workflowRunStartedAt :: !UTCTime+    }+  deriving (Show, Data, Eq, Ord, Generic)++data RunAttempt = RunAttempt+  deriving (Show, Data, Eq, Ord, Generic)++data ReviewHistory  = ReviewHistory+    { reviewHistoryState :: !Text+    , reviewHistoryComment :: !Text+    , reviewHistoryUser :: !SimpleUser++    }+  deriving (Show, Data, Eq, Ord, Generic)++-------------------------------------------------------------------------------+-- JSON instances+-------------------------------------------------------------------------------++instance FromJSON WorkflowRun where+    parseJSON = withObject "WorkflowRun" $ \o -> WorkflowRun+        <$> o .: "id"+        <*> o .: "name"+        <*> o .: "head_branch"+        <*> o .: "head_sha"+        <*> o .: "path"+        <*> o .: "display_title"+        <*> o .: "run_number"+        <*> o .: "event"+        <*> o .: "status"+        <*> o .: "conclusion"+        <*> o .: "workflow_id"+        <*> o .: "url"+        <*> o .: "html_url"+        <*> o .: "created_at"+        <*> o .: "updated_at"+        <*> o .: "actor"+        <*> o .: "run_attempt"+        <*> o .: "run_started_at"++instance FromJSON (WithTotalCount WorkflowRun) where+    parseJSON = withObject "WorkflowRunList" $ \o -> WithTotalCount+        <$> o .: "workflow_runs"+        <*> o .: "total_count"++instance FromJSON ReviewHistory where+    parseJSON = withObject "ReviewHistory" $ \o -> ReviewHistory+        <$> o .: "state"+        <*> o .: "comment"+        <*> o .: "user"
+ src/GitHub/Data/Actions/Workflows.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE DataKinds         #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures    #-}++module GitHub.Data.Actions.Workflows (+    Workflow(..),+    CreateWorkflowDispatchEvent(..),+    ) where++import Prelude ()+import GitHub.Internal.Prelude++import GitHub.Data.Actions.Common (WithTotalCount (WithTotalCount))+import GitHub.Data.Id             (Id)+import GitHub.Data.URL            (URL)++data Workflow = Workflow+    { workflowWorkflowId :: !(Id Workflow)+    , workflowName       :: !Text+    , workflowPath       :: !Text+    , workflowState      :: !Text+    , workflowCreatedAt  :: !UTCTime+    , workflowUpdatedAt  :: !UTCTime+    , workflowUrl        :: !URL+    , workflowHtmlUrl    :: !URL+    , workflowBadgeUrl   :: !URL+    }+  deriving (Show, Data, Eq, Ord, Generic)++data CreateWorkflowDispatchEvent a = CreateWorkflowDispatchEvent+    { createWorkflowDispatchEventRef    :: !Text+    , createWorkflowDispatchEventInputs :: !a+    }+  deriving (Show, Generic)++instance (NFData a) => NFData (CreateWorkflowDispatchEvent a)+instance (Binary a) => Binary (CreateWorkflowDispatchEvent a)++-------------------------------------------------------------------------------+-- JSON instances+-------------------------------------------------------------------------------++instance FromJSON Workflow where+    parseJSON = withObject "Workflow" $ \o -> Workflow+        <$> o .: "id"+        <*> o .: "name"+        <*> o .: "path"+        <*> o .: "state"+        <*> o .: "created_at"+        <*> o .: "updated_at"+        <*> o .: "url"+        <*> o .: "html_url"+        <*> o .: "badge_url"++instance FromJSON (WithTotalCount Workflow) where+    parseJSON = withObject "WorkflowList" $ \o -> WithTotalCount+        <$> o .: "workflows"+        <*> o .: "total_count"++instance ToJSON a => ToJSON (CreateWorkflowDispatchEvent a) where+    toJSON (CreateWorkflowDispatchEvent ref inputs) =+        object [ "ref" .= ref, "inputs" .= inputs ]
src/GitHub/Data/Activities.hs view
@@ -1,21 +1,21 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Activities where -import GitHub.Data.Repos       (Repo)+import GitHub.Data.Id          (Id, mkId)+import GitHub.Data.Repos       (Repo, RepoRef)+import GitHub.Data.URL         (URL) import GitHub.Internal.Prelude+ import Prelude () +import qualified Data.Text as T+ data RepoStarred = RepoStarred     { repoStarredStarredAt :: !UTCTime     , repoStarredRepo      :: !Repo     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData RepoStarred where rnf = genericRnf+instance NFData RepoStarred instance Binary RepoStarred  -- JSON Instances@@ -24,3 +24,91 @@         <$> o .: "starred_at"         <*> o .: "repo" +data Subject = Subject+    { subjectTitle :: !Text+    , subjectURL :: !(Maybe URL)+    , subjectLatestCommentURL :: !(Maybe URL)+    -- https://developer.github.com/v3/activity/notifications/ doesn't indicate+    -- what the possible values for this field are.+    -- TODO: Make an ADT for this.+    , subjectType :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Subject+instance Binary Subject++instance FromJSON Subject where+    parseJSON = withObject "Subject" $ \o -> Subject+        <$> o .: "title"+        <*> o .: "url"+        <*> o .:? "latest_comment_url"+        <*> o .: "type"++data NotificationReason+    = ApprovalRequestedReason+    | AssignReason+    | AuthorReason+    | CommentReason+    | CiActivityReason+    | InvitationReason+    | ManualReason+    | MemberFeatureRequestedReason+    | MentionReason+    | ReviewRequestedReason+    | SecurityAlertReason+    | SecurityAdvisoryCreditReason+    | StateChangeReason+    | SubscribedReason+    | TeamMentionReason+  deriving (Show, Data, Enum, Bounded, Eq, Ord, Generic)++instance NFData NotificationReason+instance Binary NotificationReason++instance FromJSON NotificationReason where+    parseJSON = withText "NotificationReason" $ \t -> case T.toLower t of+      "approval_requested"       -> pure ApprovalRequestedReason+      "assign"                   -> pure AssignReason+      "author"                   -> pure AuthorReason+      "comment"                  -> pure CommentReason+      "ci_activity"              -> pure CiActivityReason+      "invitation"               -> pure InvitationReason+      "manual"                   -> pure ManualReason+      "member_feature_requested" -> pure MemberFeatureRequestedReason+      "mention"                  -> pure MentionReason+      "review_requested"         -> pure ReviewRequestedReason+      "security_alert"           -> pure SecurityAlertReason+      "security_advisory_credit" -> pure SecurityAdvisoryCreditReason+      "state_change"             -> pure StateChangeReason+      "subscribed"               -> pure SubscribedReason+      "team_mention"             -> pure TeamMentionReason+      _                          -> fail $ "Unknown NotificationReason " ++ show t++data Notification = Notification+    -- XXX: The notification id field type IS in fact string. Not sure why gh+    -- chose to do this when all the other ids are Numbers...+    { notificationId :: !(Id Notification)+    , notificationRepo :: !RepoRef+    , notificationSubject :: !Subject+    , notificationReason :: !NotificationReason+    , notificationUnread :: !Bool+    , notificationUpdatedAt :: !(Maybe UTCTime)+    , notificationLastReadAt :: !(Maybe UTCTime)+    , notificationUrl :: !URL+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Notification+instance Binary Notification++instance FromJSON Notification where+    parseJSON = withObject "Notification" $ \o -> Notification+        <$> (mkId undefined . read <$> o .: "id")+        <*> o .: "repository"+        <*> o .: "subject"+        <*> o .: "reason"+        <*> o .: "unread"+        <*> o .: "updated_at"+        <*> o .: "last_read_at"+        <*> o .: "url"
src/GitHub/Data/Comments.hs view
@@ -1,8 +1,3 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Comments where  import GitHub.Data.Definitions@@ -24,9 +19,9 @@     , commentUser      :: !SimpleUser     , commentId        :: !(Id Comment)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData Comment where rnf = genericRnf+instance NFData Comment instance Binary Comment  instance FromJSON Comment where@@ -46,9 +41,9 @@ data NewComment = NewComment     { newCommentBody :: !Text     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData NewComment where rnf = genericRnf+instance NFData NewComment instance Binary NewComment  instance ToJSON NewComment where@@ -57,10 +52,41 @@ data EditComment = EditComment     { editCommentBody :: !Text     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData EditComment where rnf = genericRnf+instance NFData EditComment instance Binary EditComment  instance ToJSON EditComment where     toJSON (EditComment b) = object [ "body" .= b ]++data NewPullComment = NewPullComment+    { newPullCommentCommit   :: !Text+    , newPullCommentPath     :: !Text+    , newPullCommentPosition :: !Int+    , newPullCommentBody     :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData NewPullComment+instance Binary NewPullComment++instance ToJSON NewPullComment where+    toJSON (NewPullComment c path pos b) =+        object [ "body" .= b+               , "commit_id" .= c+               , "path" .= path+               , "position" .= pos+               ]++data PullCommentReply = PullCommentReply+    { pullCommentReplyBody     :: Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData PullCommentReply++instance ToJSON PullCommentReply where+    toJSON (PullCommentReply b) =+        object [ "body" .= b+               ]
src/GitHub/Data/Content.hs view
@@ -1,24 +1,26 @@ {-# LANGUAGE RecordWildCards #-}--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>---+{-# LANGUAGE CPP #-}+ module GitHub.Data.Content where -import Data.Aeson.Types        (Pair)-import Data.Maybe              (maybe) import GitHub.Data.GitData import GitHub.Data.URL import GitHub.Internal.Prelude import Prelude () +import Data.Aeson.Types (Pair)+import qualified Data.Text as T++#if MIN_VERSION_aeson(2,0,0)+import Data.Aeson (Key)+#endif+ data Content   = ContentFile !ContentFileData   | ContentDirectory !(Vector ContentItem)- deriving (Show, Data, Typeable, Eq, Ord, Generic)+ deriving (Show, Data, Eq, Ord, Generic) -instance NFData Content where rnf = genericRnf+instance NFData Content instance Binary Content  data ContentFileData = ContentFileData {@@ -26,24 +28,24 @@   ,contentFileEncoding :: !Text   ,contentFileSize     :: !Int   ,contentFileContent  :: !Text-} deriving (Show, Data, Typeable, Eq, Ord, Generic)+} deriving (Show, Data, Eq, Ord, Generic) -instance NFData ContentFileData where rnf = genericRnf+instance NFData ContentFileData instance Binary ContentFileData  -- | An item in a directory listing. data ContentItem = ContentItem {    contentItemType :: !ContentItemType   ,contentItemInfo :: !ContentInfo-} deriving (Show, Data, Typeable, Eq, Ord, Generic)+} deriving (Show, Data, Eq, Ord, Generic) -instance NFData ContentItem where rnf = genericRnf+instance NFData ContentItem instance Binary ContentItem  data ContentItemType = ItemFile | ItemDir-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData ContentItemType where rnf = genericRnf+instance NFData ContentItemType instance Binary ContentItemType  -- | Information common to both kinds of Content: files and directories.@@ -54,34 +56,34 @@   ,contentUrl     :: !URL   ,contentGitUrl  :: !URL   ,contentHtmlUrl :: !URL-} deriving (Show, Data, Typeable, Eq, Ord, Generic)+} deriving (Show, Data, Eq, Ord, Generic) -instance NFData ContentInfo where rnf = genericRnf+instance NFData ContentInfo instance Binary ContentInfo  data ContentResultInfo = ContentResultInfo     { contentResultInfo :: !ContentInfo     , contentResultSize :: !Int-    } deriving (Show, Data, Typeable, Eq, Ord, Generic)+    } deriving (Show, Data, Eq, Ord, Generic) -instance NFData ContentResultInfo where rnf = genericRnf+instance NFData ContentResultInfo instance Binary ContentResultInfo  data ContentResult = ContentResult     { contentResultContent  :: !ContentResultInfo     , contentResultCommit   :: !GitCommit-    } deriving (Show, Data, Typeable, Eq, Ord, Generic)+    } deriving (Show, Data, Eq, Ord, Generic) -instance NFData ContentResult where rnf = genericRnf+instance NFData ContentResult instance Binary ContentResult  data Author = Author     { authorName  :: !Text     , authorEmail :: !Text     }-    deriving (Eq, Ord, Show, Data, Typeable, Generic)+    deriving (Eq, Ord, Show, Data, Generic) -instance NFData Author where rnf = genericRnf+instance NFData Author instance Binary Author  data CreateFile = CreateFile@@ -92,9 +94,9 @@     , createFileAuthor    :: !(Maybe Author)     , createFileCommitter :: !(Maybe Author)     }-    deriving (Eq, Ord, Show, Data, Typeable, Generic)+    deriving (Eq, Ord, Show, Data, Generic) -instance NFData CreateFile where rnf = genericRnf+instance NFData CreateFile instance Binary CreateFile  data UpdateFile = UpdateFile@@ -106,9 +108,9 @@     , updateFileAuthor    :: !(Maybe Author)     , updateFileCommitter :: !(Maybe Author)     }-    deriving (Eq, Ord, Show, Data, Typeable, Generic)+    deriving (Eq, Ord, Show, Data, Generic) -instance NFData UpdateFile where rnf = genericRnf+instance NFData UpdateFile instance Binary UpdateFile  data DeleteFile = DeleteFile@@ -119,9 +121,9 @@     , deleteFileAuthor    :: !(Maybe Author)     , deleteFileCommitter :: !(Maybe Author)     }-    deriving (Eq, Ord, Show, Data, Typeable, Generic)+    deriving (Eq, Ord, Show, Data, Generic) -instance NFData DeleteFile where rnf = genericRnf+instance NFData DeleteFile instance Binary DeleteFile  instance FromJSON Content where@@ -142,11 +144,10 @@                 <*> parseJSON (Object o)  instance FromJSON ContentItemType where-  parseJSON = withText "ContentItemType" $ \t ->-      case t of-          "file" -> return ItemFile-          "dir"  -> return ItemDir-          _      -> fail $ "Invalid ContentItemType: " ++ unpack t+  parseJSON = withText "ContentItemType" $ \t -> case T.toLower t of+    "file" -> pure ItemFile+    "dir"  -> pure ItemDir+    _      -> fail $ "Unknown ContentItemType: " <> T.unpack t  instance FromJSON ContentInfo where   parseJSON = withObject "ContentInfo" $ \o ->@@ -204,5 +205,9 @@     ++ "author"    .=? deleteFileAuthor     ++ "committer" .=? deleteFileCommitter +#if MIN_VERSION_aeson(2,0,0)+(.=?) :: ToJSON v => Key -> Maybe v -> [Pair]+#else (.=?) :: ToJSON v => Text -> Maybe v -> [Pair]+#endif name .=? value = maybe [] (pure . (name .=)) value
src/GitHub/Data/Definitions.hs view
@@ -1,8 +1,3 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Definitions where  import GitHub.Internal.Prelude@@ -27,13 +22,13 @@     | ParseError !Text -- ^ An error in the parser itself.     | JsonError !Text -- ^ The JSON is malformed or unexpected.     | UserError !Text -- ^ Incorrect input.-    deriving (Show, Typeable)+    deriving (Show)  instance E.Exception Error  -- | Type of the repository owners.-data OwnerType = OwnerUser | OwnerOrganization-    deriving (Eq, Ord, Enum, Bounded, Show, Read, Generic, Typeable, Data)+data OwnerType = OwnerUser | OwnerOrganization | OwnerBot+    deriving (Eq, Ord, Enum, Bounded, Show, Read, Generic, Data)  instance NFData OwnerType instance Binary OwnerType@@ -44,9 +39,9 @@     , simpleUserAvatarUrl :: !URL     , simpleUserUrl       :: !URL     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData SimpleUser where rnf = genericRnf+instance NFData SimpleUser instance Binary SimpleUser  data SimpleOrganization = SimpleOrganization@@ -55,9 +50,9 @@     , simpleOrganizationUrl       :: !URL     , simpleOrganizationAvatarUrl :: !URL     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData SimpleOrganization where rnf = genericRnf+instance NFData SimpleOrganization instance Binary SimpleOrganization  -- | Sometimes we don't know the type of the owner, e.g. in 'Repo'@@ -68,16 +63,16 @@     , simpleOwnerAvatarUrl :: !URL     , simpleOwnerType      :: !OwnerType     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData SimpleOwner where rnf = genericRnf+instance NFData SimpleOwner instance Binary SimpleOwner  data User = User     { userId          :: !(Id User)     , userLogin       :: !(Name User)     , userName        :: !(Maybe Text)-    , userType        :: !OwnerType  -- ^ Should always be 'OwnerUser'+    , userType        :: !OwnerType  -- ^ Should always be 'OwnerUser' or 'OwnerBot'     , userCreatedAt   :: !UTCTime     , userPublicGists :: !Int     , userAvatarUrl   :: !URL@@ -93,9 +88,9 @@     , userUrl         :: !URL     , userHtmlUrl     :: !URL     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData User where rnf = genericRnf+instance NFData User instance Binary User  data Organization = Organization@@ -116,16 +111,16 @@     , organizationUrl         :: !URL     , organizationCreatedAt   :: !UTCTime     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData Organization where rnf = genericRnf+instance NFData Organization instance Binary Organization --- | In practic, you cam't have concrete values of 'Owner'.+-- | In practice you can't have concrete values of 'Owner'. newtype Owner = Owner (Either User Organization)-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData Owner where rnf = genericRnf+instance NFData Owner instance Binary Owner  fromOwner :: Owner -> Either User Organization@@ -134,11 +129,11 @@ -- JSON instances  instance FromJSON OwnerType where-    parseJSON = withText "Owner type" $ \t ->-        case t of-            "User"          -> pure $ OwnerUser-            "Organization"  -> pure $ OwnerOrganization-            _               -> fail $ "Unknown owner type: " ++ T.unpack t+    parseJSON = withText "OwnerType" $ \t -> case T.toLower t of+        "user"         -> pure $ OwnerUser+        "organization" -> pure $ OwnerOrganization+        "bot"          -> pure $ OwnerBot+        _              -> fail $ "Unknown OwnerType: " <> T.unpack t  instance FromJSON SimpleUser where     parseJSON = withObject "SimpleUser" $ \obj -> do@@ -206,7 +201,7 @@     <*> obj .: "created_at"  instance FromJSON User where-    parseJSON = mfilter ((== OwnerUser) . userType) . withObject "User" parseUser+    parseJSON = mfilter ((/= OwnerOrganization) . userType) . withObject "User" parseUser  instance FromJSON Organization where     parseJSON = withObject "Organization" parseOrganization@@ -216,20 +211,21 @@         t <- obj .: "type"         case t of             OwnerUser         -> Owner . Left <$> parseUser obj+            OwnerBot          -> Owner . Left <$> parseUser obj             OwnerOrganization -> Owner . Right <$> parseOrganization obj  -- | Filter members returned in the list. data OrgMemberFilter     = OrgMemberFilter2faDisabled  -- ^ Members without two-factor authentication enabled. Available for organization owners.     | OrgMemberFilterAll          -- ^ All members the authenticated user can see.-    deriving (Show, Eq, Ord, Enum, Bounded, Typeable, Data, Generic)+    deriving (Show, Eq, Ord, Enum, Bounded, Data, Generic)  -- | Filter members returned by their role. data OrgMemberRole     = OrgMemberRoleAll     -- ^ All members of the organization, regardless of role.     | OrgMemberRoleAdmin   -- ^ Organization owners.     | OrgMemberRoleMember  -- ^ Non-owner organization members.-    deriving (Show, Eq, Ord, Enum, Bounded, Typeable, Data, Generic)+    deriving (Show, Eq, Ord, Enum, Bounded, Data, Generic)  -- | Request query string type QueryString = [(BS.ByteString, Maybe BS.ByteString)]@@ -237,7 +233,86 @@ -- | Count of elements type Count = Int +++data MembershipRole+    = MembershipRoleMember+    | MembershipRoleAdmin+    | MembershipRoleBillingManager+  deriving+    (Eq, Ord, Show, Enum, Bounded, Generic, Data)++instance NFData MembershipRole+instance Binary MembershipRole++instance FromJSON MembershipRole where+    parseJSON = withText "MembershipRole" $ \t -> case T.toLower t of+        "member"   -> pure MembershipRoleMember+        "admin"           -> pure MembershipRoleAdmin+        "billing_manager" -> pure MembershipRoleBillingManager+        _                 -> fail $ "Unknown MembershipRole: " <> T.unpack t++data MembershipState+    = MembershipPending+    | MembershipActive+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData MembershipState+instance Binary MembershipState++instance FromJSON MembershipState where+    parseJSON = withText "MembershipState" $ \t -> case T.toLower t of+        "active"  -> pure MembershipActive+        "pending" -> pure MembershipPending+        _         -> fail $ "Unknown MembershipState: " <> T.unpack t+++data Membership = Membership+    { membershipUrl             :: !URL+    , membershipState           :: !MembershipState+    , membershipRole            :: !MembershipRole+    , membershipOrganizationUrl :: !URL+    , membershipOrganization    :: !SimpleOrganization+    , membershipUser            :: !SimpleUser+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData Membership+instance Binary Membership++instance FromJSON Membership where+    parseJSON = withObject "Membership" $ \o -> Membership+        <$> o .: "url"+        <*> o .: "state"+        <*> o .: "role"+        <*> o .: "organization_url"+        <*> o .: "organization"+        <*> o .: "user"++ -------------------------------------------------------------------------------+-- IssueNumber+-------------------------------------------------------------------------------++newtype IssueNumber = IssueNumber Int+    deriving (Eq, Ord, Show, Generic, Data)++unIssueNumber :: IssueNumber -> Int+unIssueNumber (IssueNumber i) = i++instance Hashable IssueNumber+instance Binary IssueNumber++instance NFData IssueNumber where+    rnf (IssueNumber s) = rnf s++instance FromJSON IssueNumber where+    parseJSON = fmap IssueNumber . parseJSON++instance ToJSON IssueNumber where+    toJSON = toJSON . unIssueNumber++------------------------------------------------------------------------------- -- IssueLabel ------------------------------------------------------------------------------- @@ -245,10 +320,11 @@     { labelColor :: !Text     , labelUrl   :: !URL     , labelName  :: !(Name IssueLabel)+    , labelDesc  :: !(Maybe Text)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData IssueLabel where rnf = genericRnf+instance NFData IssueLabel instance Binary IssueLabel  instance FromJSON IssueLabel where@@ -256,3 +332,57 @@         <$> o .: "color"         <*> o .:? "url" .!= URL "" -- in events there aren't URL         <*> o .: "name"+        <*> o .:? "description"+++-------------------------------------------------------------------------------+-- NewIssueLabel+-------------------------------------------------------------------------------++data NewIssueLabel = NewIssueLabel+    { newLabelColor :: !Text+    , newLabelName  :: !(Name NewIssueLabel)+    , newLabelDesc  :: !(Maybe Text)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData NewIssueLabel+instance Binary NewIssueLabel+++instance ToJSON NewIssueLabel where+    toJSON (NewIssueLabel color lblName lblDesc) = object $ filter notNull+        [ "name" .= lblName+        , "color" .= color+        , "description" .= lblDesc+        ]+        where+            notNull (_, Null) = False+            notNull (_, _)    = True++++-------------------------------------------------------------------------------+-- UpdateIssueLabel+-------------------------------------------------------------------------------++data UpdateIssueLabel = UpdateIssueLabel+    { updateLabelColor :: !Text+    , updateLabelName  :: !(Name UpdateIssueLabel)+    , updateLabelDesc  :: !(Maybe Text)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData UpdateIssueLabel+instance Binary UpdateIssueLabel+++instance ToJSON UpdateIssueLabel where+    toJSON (UpdateIssueLabel color lblName lblDesc) = object $ filter notNull+        [ "new_name" .= lblName+        , "color" .= color+        , "description" .= lblDesc+        ]+        where+            notNull (_, Null) = False+            notNull (_, _)    = True
src/GitHub/Data/DeployKeys.hs view
@@ -19,7 +19,7 @@     , repoDeployKeyCreatedAt :: !UTCTime     , repoDeployKeyReadOnly  :: !Bool     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic)  instance FromJSON RepoDeployKey where     parseJSON = withObject "RepoDeployKey" $ \o -> RepoDeployKey@@ -36,7 +36,7 @@     , newRepoDeployKeyTitle    :: !Text     , newRepoDeployKeyReadOnly :: !Bool     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic)  instance ToJSON NewRepoDeployKey where     toJSON (NewRepoDeployKey key title readOnly) = object
+ src/GitHub/Data/Deployments.hs view
@@ -0,0 +1,204 @@+{-# LANGUAGE LambdaCase #-}++module GitHub.Data.Deployments+    ( DeploymentQueryOption (..)+    , renderDeploymentQueryOption++    , Deployment (..)+    , CreateDeployment (..)++    , DeploymentStatus (..)+    , DeploymentStatusState (..)+    , CreateDeploymentStatus (..)+    ) where+++import GitHub.Internal.Prelude+import Prelude ()++import Control.Arrow (second)++import Data.ByteString (ByteString)++import GitHub.Data.Definitions (SimpleUser)+import GitHub.Data.Id          (Id)+import GitHub.Data.Name        (Name)+import GitHub.Data.URL         (URL)++import qualified Data.Aeson         as JSON+import qualified Data.Text          as T+import qualified Data.Text.Encoding as T++data DeploymentQueryOption+    = DeploymentQuerySha         !Text+    | DeploymentQueryRef         !Text+    | DeploymentQueryTask        !Text+    | DeploymentQueryEnvironment !Text+      deriving (Show, Data, Eq, Ord, Generic)++instance NFData DeploymentQueryOption+instance Binary DeploymentQueryOption++renderDeploymentQueryOption :: DeploymentQueryOption -> (ByteString, ByteString)+renderDeploymentQueryOption =+    second T.encodeUtf8 . \case+        DeploymentQuerySha         sha  -> ("sha",         sha)+        DeploymentQueryRef         ref  -> ("ref",         ref)+        DeploymentQueryTask        task -> ("task",        task)+        DeploymentQueryEnvironment env  -> ("environment", env)++data Deployment a = Deployment+    { deploymentUrl           :: !URL+    , deploymentId            :: !(Id   (Deployment a))+    , deploymentSha           :: !(Name (Deployment a))+    , deploymentRef           :: !Text+    , deploymentTask          :: !Text+    , deploymentPayload       :: !(Maybe a)+    , deploymentEnvironment   :: !Text+    , deploymentDescription   :: !Text+    , deploymentCreator       :: !SimpleUser+    , deploymentCreatedAt     :: !UTCTime+    , deploymentUpdatedAt     :: !UTCTime+    , deploymentStatusesUrl   :: !URL+    , deploymentRepositoryUrl :: !URL+    } deriving (Show, Data, Eq, Ord, Generic)++instance NFData a => NFData (Deployment a)+instance Binary a => Binary (Deployment a)++instance FromJSON a => FromJSON (Deployment a) where+    parseJSON = withObject "GitHub Deployment" $ \o ->+        Deployment+            <$> o .: "url"+            <*> o .: "id"+            <*> o .: "sha"+            <*> o .: "ref"+            <*> o .: "task"+            <*> o .:? "payload"+            <*> o .: "environment"+            <*> o .: "description"+            <*> o .: "creator"+            <*> o .: "created_at"+            <*> o .: "updated_at"+            <*> o .: "statuses_url"+            <*> o .: "repository_url"++data CreateDeployment a = CreateDeployment+    { createDeploymentRef              :: !Text+    -- ^ Required. The ref to deploy. This can be a branch, tag, or SHA.+    , createDeploymentTask             :: !(Maybe Text)+    -- ^ Specifies a task to execute (e.g., deploy or deploy:migrations).+    -- Default: deploy+    , createDeploymentAutoMerge        :: !(Maybe Bool)+    -- ^ Attempts to automatically merge the default branch into the requested+    -- ref, if it is behind the default branch. Default: true+    , createDeploymentRequiredContexts :: !(Maybe (Vector Text))+    -- ^ The status contexts to verify against commit status checks. If this+    -- parameter is omitted, then all unique contexts will be verified before a+    -- deployment is created. To bypass checking entirely pass an empty array.+    -- Defaults to all unique contexts.+    , createDeploymentPayload          :: !(Maybe a)+    -- ^ JSON payload with extra information about the deployment. Default: ""+    , createDeploymentEnvironment      :: !(Maybe Text)+    -- ^ Name for the target deployment environment (e.g., production, staging,+    -- qa). Default: production+    , createDeploymentDescription      :: !(Maybe Text)+    -- ^ Short description of the deployment. Default: ""+    } deriving (Show, Data, Eq, Ord, Generic)++instance NFData a => NFData (CreateDeployment a)+instance Binary a => Binary (CreateDeployment a)++instance ToJSON a => ToJSON (CreateDeployment a) where+    toJSON x =+        JSON.object $ catMaybes+            [ Just ("ref"          .=      createDeploymentRef x)+            , ("task"              .=) <$> createDeploymentTask x+            , ("auto_merge"        .=) <$> createDeploymentAutoMerge x+            , ("required_contexts" .=) <$> createDeploymentRequiredContexts x+            , ("payload"           .=) <$> createDeploymentPayload x+            , ("environment"       .=) <$> createDeploymentEnvironment x+            , ("description"       .=) <$> createDeploymentDescription x+            ]++data DeploymentStatus = DeploymentStatus+    { deploymentStatusUrl           :: !URL+    , deploymentStatusId            :: !(Id DeploymentStatus)+    , deploymentStatusState         :: !DeploymentStatusState+    , deploymentStatusCreator       :: !SimpleUser+    , deploymentStatusDescription   :: !Text+    , deploymentStatusTargetUrl     :: !URL+    , deploymentStatusCreatedAt     :: !UTCTime+    , deploymentStatusUpdatedAt     :: !UTCTime+    , deploymentStatusDeploymentUrl :: !URL+    , deploymentStatusRepositoryUrl :: !URL+    } deriving (Show, Data, Eq, Ord, Generic)++instance NFData DeploymentStatus+instance Binary DeploymentStatus++instance FromJSON DeploymentStatus where+    parseJSON = withObject "GitHub DeploymentStatus" $ \o ->+        DeploymentStatus+            <$> o .: "url"+            <*> o .: "id"+            <*> o .: "state"+            <*> o .: "creator"+            <*> o .: "description"+            <*> o .: "target_url"+            <*> o .: "created_at"+            <*> o .: "updated_at"+            <*> o .: "deployment_url"+            <*> o .: "repository_url"++data DeploymentStatusState+    = DeploymentStatusError+    | DeploymentStatusFailure+    | DeploymentStatusPending+    | DeploymentStatusSuccess+    | DeploymentStatusInactive+      deriving (Show, Data, Eq, Ord, Generic)++instance NFData DeploymentStatusState+instance Binary DeploymentStatusState++instance ToJSON DeploymentStatusState where+    toJSON = \case+        DeploymentStatusError    -> "error"+        DeploymentStatusFailure  -> "failure"+        DeploymentStatusPending  -> "pending"+        DeploymentStatusSuccess  -> "success"+        DeploymentStatusInactive -> "inactive"++instance FromJSON DeploymentStatusState where+    parseJSON = withText "DeploymentStatusState" $ \t -> case T.toLower t of+        "error"    -> pure DeploymentStatusError+        "failure"  -> pure DeploymentStatusFailure+        "pending"  -> pure DeploymentStatusPending+        "success"  -> pure DeploymentStatusSuccess+        "inactive" -> pure DeploymentStatusInactive+        _          -> fail $ "Unknown DeploymentStatusState: " <> T.unpack t++data CreateDeploymentStatus = CreateDeploymentStatus+    { createDeploymentStatusState       :: !DeploymentStatusState+    -- ^ Required. The state of the status. Can be one of error, failure,+    -- pending, or success.+    , createDeploymentStatusTargetUrl   :: !(Maybe Text) -- TODO: should this be URL?+    -- ^ The target URL to associate with this status. This URL should contain+    -- output to keep the user updated while the task is running or serve as+    -- historical information for what happened in the deployment. Default: ""+    , createDeploymentStatusDescription :: !(Maybe Text)+    -- ^ A short description of the status. Maximum length of 140 characters.+    -- Default: ""+    } deriving (Show, Data, Eq, Ord, Generic)++instance NFData CreateDeploymentStatus+instance Binary CreateDeploymentStatus++instance ToJSON CreateDeploymentStatus where+    toJSON x =+        JSON.object $ catMaybes+            [ Just ("state"  .= createDeploymentStatusState x)+            , ("target_url"  .=) <$> createDeploymentStatusTargetUrl x+            , ("description" .=) <$> createDeploymentStatusDescription x+            ]
src/GitHub/Data/Email.hs view
@@ -1,34 +1,32 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Email where  import GitHub.Internal.Prelude import Prelude () +import qualified Data.Text as T+ data EmailVisibility     = EmailVisibilityPrivate     | EmailVisibilityPublic-    deriving (Show, Data, Enum, Bounded, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Enum, Bounded, Eq, Ord, Generic) -instance NFData EmailVisibility where rnf = genericRnf+instance NFData EmailVisibility instance Binary EmailVisibility  instance FromJSON EmailVisibility where-    parseJSON (String "private") = pure EmailVisibilityPrivate-    parseJSON (String "public")  = pure EmailVisibilityPublic-    parseJSON _ = fail "Could not build an EmailVisibility"+    parseJSON = withText "EmailVisibility" $ \t -> case T.toLower t of+        "private" -> pure EmailVisibilityPrivate+        "public"  -> pure EmailVisibilityPublic+        _         -> fail $ "Unknown EmailVisibility: " <> T.unpack t  data Email = Email     { emailAddress    :: !Text     , emailVerified   :: !Bool     , emailPrimary    :: !Bool     , emailVisibility :: !(Maybe EmailVisibility)-    } deriving (Show, Data, Typeable, Eq, Ord, Generic)+    } deriving (Show, Data, Eq, Ord, Generic) -instance NFData Email where rnf = genericRnf+instance NFData Email instance Binary Email  instance FromJSON Email where
+ src/GitHub/Data/Enterprise.hs view
@@ -0,0 +1,9 @@+-- |+-- This module re-exports the @GitHub.Data.Enterprise.@ submodules.++module GitHub.Data.Enterprise (+    -- * Module re-exports+    module GitHub.Data.Enterprise.Organizations,+    ) where++import GitHub.Data.Enterprise.Organizations
+ src/GitHub/Data/Enterprise/Organizations.hs view
@@ -0,0 +1,59 @@+module GitHub.Data.Enterprise.Organizations where++import GitHub.Data.Definitions+import GitHub.Data.Name (Name)+import GitHub.Data.URL (URL)+import GitHub.Internal.Prelude+import Prelude ()++data CreateOrganization = CreateOrganization+    { createOrganizationLogin       :: !(Name Organization)+    , createOrganizationAdmin       :: !(Name User)+    , createOrganizationProfileName :: !(Maybe Text)+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData CreateOrganization+instance Binary CreateOrganization++data RenameOrganization = RenameOrganization+    { renameOrganizationLogin :: !(Name Organization)+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData RenameOrganization+instance Binary RenameOrganization++data RenameOrganizationResponse = RenameOrganizationResponse+    { renameOrganizationResponseMessage :: !Text+    , renameOrganizationResponseUrl     :: !URL+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData RenameOrganizationResponse+instance Binary RenameOrganizationResponse++-- JSON Instances++instance ToJSON CreateOrganization where+    toJSON (CreateOrganization login admin profileName) =+        object $ filter notNull+            [ "login"        .= login+            , "admin"        .= admin+            , "profile_name" .= profileName+            ]+      where+        notNull (_, Null) = False+        notNull (_, _) = True++instance ToJSON RenameOrganization where+    toJSON (RenameOrganization login) =+        object+            [ "login" .= login+            ]++instance FromJSON RenameOrganizationResponse where+    parseJSON = withObject "RenameOrganizationResponse" $ \o ->+        RenameOrganizationResponse+            <$> o .: "message"+            <*> o .: "url"
src/GitHub/Data/Events.hs view
@@ -1,8 +1,3 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Events where  import GitHub.Data.Definitions@@ -14,19 +9,20 @@ -- /TODO:/ -- -- * missing repo, org, payload, id+-- data Event = Event     -- { eventId        :: !(Id Event) -- id can be encoded as string.     { eventActor     :: !SimpleUser     , eventCreatedAt :: !UTCTime     , eventPublic    :: !Bool     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData Event where rnf = genericRnf-instance Binary Event +instance NFData Event+instance Binary Event  instance FromJSON Event where-    parseJSON = withObject "Event" $ \obj -> Event +    parseJSON = withObject "Event" $ \obj -> Event         -- <$> obj .: "id"         <$> obj .: "actor"         <*> obj .: "created_at"
src/GitHub/Data/Gists.hs view
@@ -1,8 +1,3 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Gists where  import GitHub.Data.Definitions@@ -26,9 +21,9 @@     , gistId          :: !(Name Gist)     , gistFiles       :: !(HashMap Text GistFile)     , gistGitPullUrl  :: !URL-    } deriving (Show, Data, Typeable, Eq, Generic)+    } deriving (Show, Data, Eq, Generic) -instance NFData Gist where rnf = genericRnf+instance NFData Gist instance Binary Gist  instance FromJSON Gist where@@ -54,9 +49,9 @@     , gistFileFilename :: !Text     , gistFileContent  :: !(Maybe Text)     }-  deriving (Show, Data, Typeable, Eq, Generic)+  deriving (Show, Data, Eq, Generic) -instance NFData GistFile where rnf = genericRnf+instance NFData GistFile instance Binary GistFile  instance FromJSON GistFile where@@ -76,9 +71,9 @@     , gistCommentUpdatedAt :: !UTCTime     , gistCommentId        :: !(Id GistComment)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData GistComment where rnf = genericRnf+instance NFData GistComment instance Binary GistComment  instance FromJSON GistComment where@@ -89,3 +84,35 @@         <*> o .: "body"         <*> o .: "updated_at"         <*> o .: "id"++data NewGist = NewGist+    { newGistDescription :: !(Maybe Text)+    , newGistFiles       :: !(HashMap Text NewGistFile)+    , newGistPublic      :: !(Maybe Bool)+    } deriving (Show, Data, Eq, Generic)++instance NFData NewGist+instance Binary NewGist++instance ToJSON NewGist where+    toJSON NewGist { newGistDescription = description+                   , newGistFiles       = files+                   , newGistPublic      = public+                   } = object $ filter notNull+                   [ "description"      .= description+                   , "files"            .= files+                   , "public"           .= public+                   ]+      where+        notNull (_, Null) = False+        notNull (_, _)    = True++data NewGistFile = NewGistFile+    { newGistFileContent :: !Text+    } deriving (Show, Data, Eq, Generic)++instance NFData NewGistFile+instance Binary NewGistFile++instance ToJSON NewGistFile where+    toJSON (NewGistFile c) = object ["content" .= c]
src/GitHub/Data/GitData.hs view
@@ -1,8 +1,3 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.GitData where  import GitHub.Data.Definitions@@ -20,16 +15,16 @@     | CommitQueryAuthor !Text     | CommitQuerySince !UTCTime     | CommitQueryUntil !UTCTime-  deriving (Show, Eq, Ord, Generic, Typeable, Data)+  deriving (Show, Eq, Ord, Generic, Data)  data Stats = Stats     { statsAdditions :: !Int     , statsTotal     :: !Int     , statsDeletions :: !Int     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData Stats where rnf = genericRnf+instance NFData Stats instance Binary Stats  data Commit = Commit@@ -42,9 +37,9 @@     , commitFiles     :: !(Vector File)     , commitStats     :: !(Maybe Stats)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData Commit where rnf = genericRnf+instance NFData Commit instance Binary Commit  data Tree = Tree@@ -52,9 +47,9 @@     , treeUrl      :: !URL     , treeGitTrees :: !(Vector GitTree)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData Tree where rnf = genericRnf+instance NFData Tree instance Binary Tree  data GitTree = GitTree@@ -66,9 +61,9 @@     , gitTreePath :: !Text     , gitTreeMode :: !Text     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData GitTree where rnf = genericRnf+instance NFData GitTree instance Binary GitTree  data GitCommit = GitCommit@@ -80,9 +75,9 @@     , gitCommitSha       :: !(Maybe (Name GitCommit))     , gitCommitParents   :: !(Vector Tree)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData GitCommit where rnf = genericRnf+instance NFData GitCommit instance Binary GitCommit  data Blob = Blob@@ -92,9 +87,9 @@     , blobSha      :: !(Name Blob)     , blobSize     :: !Int     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData Blob where rnf = genericRnf+instance NFData Blob instance Binary Blob  data Tag = Tag@@ -103,26 +98,26 @@     , tagTarballUrl :: !URL     , tagCommit     :: !BranchCommit     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData Tag where rnf = genericRnf+instance NFData Tag instance Binary Tag  data Branch = Branch     { branchName   :: !Text     , branchCommit :: !BranchCommit     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData Branch where rnf = genericRnf+instance NFData Branch  data BranchCommit = BranchCommit     { branchCommitSha :: !Text     , branchCommitUrl :: !URL     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData BranchCommit where rnf = genericRnf+instance NFData BranchCommit instance Binary BranchCommit  data Diff = Diff@@ -139,28 +134,28 @@     , diffDiffUrl      :: !URL     , diffPermalinkUrl :: !URL     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData Diff where rnf = genericRnf+instance NFData Diff instance Binary Diff  data NewGitReference = NewGitReference     { newGitReferenceRef :: !Text     , newGitReferenceSha :: !Text     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData NewGitReference where rnf = genericRnf+instance NFData NewGitReference instance Binary NewGitReference  data GitReference = GitReference     { gitReferenceObject :: !GitObject     , gitReferenceUrl    :: !URL-    , gitReferenceRef    :: !Text+    , gitReferenceRef    :: !(Name GitReference)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData GitReference where rnf = genericRnf+instance NFData GitReference instance Binary GitReference  data GitObject = GitObject@@ -168,9 +163,9 @@     , gitObjectSha  :: !Text     , gitObjectUrl  :: !URL     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData GitObject where rnf = genericRnf+instance NFData GitObject instance Binary GitObject  data GitUser = GitUser@@ -178,25 +173,25 @@     , gitUserEmail :: !Text     , gitUserDate  :: !UTCTime     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData GitUser where rnf = genericRnf+instance NFData GitUser instance Binary GitUser  data File = File-    { fileBlobUrl   :: !URL+    { fileBlobUrl   :: !(Maybe URL)     , fileStatus    :: !Text-    , fileRawUrl    :: !URL+    , fileRawUrl    :: !(Maybe URL)     , fileAdditions :: !Int-    , fileSha       :: !Text+    , fileSha       :: !(Maybe Text)     , fileChanges   :: !Int     , filePatch     :: !(Maybe Text)     , fileFilename  :: !Text     , fileDeletions :: !Int     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData File where rnf = genericRnf+instance NFData File instance Binary File  -- JSON instances@@ -213,8 +208,8 @@         <*> o .: "parents"         <*> o .: "url"         <*> o .: "commit"-        <*> o .:? "committer"-        <*> o .:? "author"+        <*> (o .:? "committer" <|> pure Nothing)+        <*> (o .:? "author" <|> pure Nothing)         <*> o .:? "files" .!= V.empty         <*> o .:? "stats" @@ -251,11 +246,11 @@  instance FromJSON File where     parseJSON = withObject "File" $ \o -> File-        <$> o .: "blob_url"+        <$> o .:? "blob_url"         <*> o .: "status"-        <*> o .: "raw_url"+        <*> o .:? "raw_url"         <*> o .: "additions"-        <*> o .: "sha"+        <*> o .:? "sha"         <*> o .: "changes"         <*> o .:? "patch"         <*> o .: "filename"
src/GitHub/Data/Id.hs view
@@ -1,8 +1,3 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Id (     Id(..),     mkId,@@ -14,7 +9,7 @@  -- | Numeric identifier. newtype Id entity = Id Int-    deriving (Eq, Ord, Show, Generic, Typeable, Data)+    deriving (Eq, Ord, Show, Generic, Data)  -- | Smart constructor for 'Id'. mkId :: proxy entity -> Int -> Id entity
src/GitHub/Data/Invitation.hs view
@@ -1,16 +1,15 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Invitation where  import GitHub.Data.Definitions import GitHub.Data.Id          (Id) import GitHub.Data.Name        (Name)+import GitHub.Data.Repos       (Repo)+import GitHub.Data.URL         (URL) import GitHub.Internal.Prelude import Prelude () +import qualified Data.Text as T+ data Invitation = Invitation     { invitationId        :: !(Id Invitation)     -- TODO: technically either one should be, maybe both. use `these` ?@@ -20,9 +19,9 @@     , invitationCreatedAt :: !UTCTime     , inviter             :: !SimpleUser     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData Invitation where rnf = genericRnf+instance NFData Invitation instance Binary Invitation  instance FromJSON Invitation where@@ -42,16 +41,42 @@     | InvitationRoleHiringManager     | InvitationRoleReinstate   deriving-    (Eq, Ord, Show, Enum, Bounded, Generic, Typeable, Data)+    (Eq, Ord, Show, Enum, Bounded, Generic, Data) -instance NFData InvitationRole where rnf = genericRnf+instance NFData InvitationRole instance Binary InvitationRole  instance FromJSON InvitationRole where-    parseJSON = withText "InvirationRole" $ \t -> case t of+    parseJSON = withText "InvitationRole" $ \t -> case T.toLower t of         "direct_member"   -> pure InvitationRoleDirectMember         "admin"           -> pure InvitationRoleAdmin         "billing_manager" -> pure InvitationRoleBillingManager         "hiring_manager"  -> pure InvitationRoleHiringManager         "reinstate"       -> pure InvitationRoleReinstate-        _                 -> fail $ "Invalid role " ++ show t+        _                 -> fail $ "Unknown InvitationRole: " <> T.unpack t++data RepoInvitation = RepoInvitation+    { repoInvitationId         :: !(Id RepoInvitation)+    , repoInvitationInvitee    :: !SimpleUser+    , repoInvitationInviter    :: !SimpleUser+    , repoInvitationRepo       :: !Repo+    , repoInvitationUrl        :: !URL+    , repoInvitationCreatedAt  :: !UTCTime+    , repoInvitationPermission :: !Text+    , repoInvitationHtmlUrl    :: !URL+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData RepoInvitation+instance Binary RepoInvitation++instance FromJSON RepoInvitation where+    parseJSON = withObject "RepoInvitation" $ \o -> RepoInvitation+        <$> o .: "id"+        <*> o .: "invitee"+        <*> o .: "inviter"+        <*> o .: "repository"+        <*> o .: "url"+        <*> o .: "created_at"+        <*> o .: "permissions"+        <*> o .: "html_url"
src/GitHub/Data/Issues.hs view
@@ -1,20 +1,17 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Issues where  import GitHub.Data.Definitions import GitHub.Data.Id           (Id) import GitHub.Data.Milestone    (Milestone) import GitHub.Data.Name         (Name)-import GitHub.Data.Options      (IssueState)+import GitHub.Data.Options      (IssueState, IssueStateReason) import GitHub.Data.PullRequests import GitHub.Data.URL          (URL) import GitHub.Internal.Prelude-import Prelude ()+import Prelude                  () +import qualified Data.Text as T+ data Issue = Issue     { issueClosedAt    :: !(Maybe UTCTime)     , issueUpdatedAt   :: !UTCTime@@ -22,7 +19,7 @@     , issueHtmlUrl     :: !(Maybe URL)     , issueClosedBy    :: !(Maybe SimpleUser)     , issueLabels      :: !(Vector IssueLabel)-    , issueNumber      :: !Int+    , issueNumber      :: !IssueNumber     , issueAssignees   :: !(Vector SimpleUser)     , issueUser        :: !SimpleUser     , issueTitle       :: !Text@@ -34,35 +31,36 @@     , issueId          :: !(Id Issue)     , issueComments    :: !Int     , issueMilestone   :: !(Maybe Milestone)+    , issueStateReason :: !(Maybe IssueStateReason)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData Issue where rnf = genericRnf+instance NFData Issue instance Binary Issue  data NewIssue = NewIssue     { newIssueTitle     :: !Text     , newIssueBody      :: !(Maybe Text)-    , newIssueAssignee  :: !(Maybe Text)+    , newIssueAssignees :: !(Vector (Name User))     , newIssueMilestone :: !(Maybe (Id Milestone))     , newIssueLabels    :: !(Maybe (Vector (Name IssueLabel)))     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData NewIssue where rnf = genericRnf+instance NFData NewIssue instance Binary NewIssue  data EditIssue = EditIssue     { editIssueTitle     :: !(Maybe Text)     , editIssueBody      :: !(Maybe Text)-    , editIssueAssignee  :: !(Maybe (Name User))+    , editIssueAssignees :: !(Maybe (Vector (Name User)))     , editIssueState     :: !(Maybe IssueState)     , editIssueMilestone :: !(Maybe (Id Milestone))     , editIssueLabels    :: !(Maybe (Vector (Name IssueLabel)))     }-  deriving  (Show, Data, Typeable, Eq, Ord, Generic)+  deriving  (Show, Data, Eq, Ord, Generic) -instance NFData EditIssue where rnf = genericRnf+instance NFData EditIssue instance Binary EditIssue  data IssueComment = IssueComment@@ -74,9 +72,9 @@     , issueCommentBody      :: !Text     , issueCommentId        :: !Int     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData IssueComment where rnf = genericRnf+instance NFData IssueComment instance Binary IssueComment  -- | See <https://developer.github.com/v3/issues/events/#events-1>@@ -108,9 +106,9 @@     | MovedColumnsInProject -- ^ The issue was moved between columns in a project board.     | RemovedFromProject    -- ^ The issue was removed from a project board.     | ConvertedNoteToIssue  -- ^ The issue was created by converting a note in a project board to an issue.-  deriving (Show, Data, Enum, Bounded, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Enum, Bounded, Eq, Ord, Generic) -instance NFData EventType where rnf = genericRnf+instance NFData EventType instance Binary EventType  -- | Issue event@@ -124,9 +122,9 @@     , issueEventIssue     :: !(Maybe Issue)     , issueEventLabel     :: !(Maybe IssueLabel)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData IssueEvent where rnf = genericRnf+instance NFData IssueEvent instance Binary IssueEvent  instance FromJSON IssueEvent where@@ -141,7 +139,7 @@         <*> o .:? "label"  instance FromJSON EventType where-    parseJSON = withText "EventType" $ \t -> case t of+    parseJSON = withText "EventType" $ \t -> case T.toLower t of         "closed"                   -> pure Closed         "reopened"                 -> pure Reopened         "subscribed"               -> pure Subscribed@@ -169,7 +167,7 @@         "removed_from_project"     -> pure RemovedFromProject         "converted_note_to_issue"  -> pure ConvertedNoteToIssue         "unsubscribed"             -> pure Unsubscribed -- not in api docs list-        _                          -> fail $ "Unknown EventType " ++ show t+        _                          -> fail $ "Unknown EventType: " <> T.unpack t  instance FromJSON IssueComment where     parseJSON = withObject "IssueComment" $ \o -> IssueComment@@ -201,21 +199,25 @@         <*> o .: "id"         <*> o .: "comments"         <*> o .:? "milestone"+        <*> o .:? "state_reason"  instance ToJSON NewIssue where-    toJSON (NewIssue t b a m ls) = object+    toJSON (NewIssue t b a m ls) = object $ filter notNull         [ "title"     .= t         , "body"      .= b-        , "assignee"  .= a+        , "assignees" .= a         , "milestone" .= m         , "labels"    .= ls         ]+      where+        notNull (_, Null) = False+        notNull (_, _)    = True  instance ToJSON EditIssue where-    toJSON (EditIssue t b a s m ls) = object $ filter notNull $+    toJSON (EditIssue t b a s m ls) = object $ filter notNull         [ "title"     .= t         , "body"      .= b-        , "assignee"  .= a+        , "assignees" .= a         , "state"     .= s         , "milestone" .= m         , "labels"    .= ls
src/GitHub/Data/Milestone.hs view
@@ -1,8 +1,3 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Milestone where  import GitHub.Data.Definitions@@ -23,9 +18,9 @@     , milestoneCreatedAt    :: !UTCTime     , milestoneState        :: !Text     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData Milestone where rnf = genericRnf+instance NFData Milestone instance Binary Milestone  instance FromJSON Milestone where@@ -40,3 +35,49 @@         <*> o .: "url"         <*> o .: "created_at"         <*> o .: "state"++data NewMilestone = NewMilestone+    { newMilestoneTitle       :: !Text+    , newMilestoneState       :: !Text+    , newMilestoneDescription :: !(Maybe Text)+    , newMilestoneDueOn       :: !(Maybe UTCTime)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData NewMilestone+instance Binary NewMilestone+++instance ToJSON NewMilestone where+    toJSON (NewMilestone title state desc due) = object $ filter notNull+        [ "title"       .= title+        , "state"       .= state+        , "description" .= desc+        , "due_on"      .= due+        ]+      where+        notNull (_, Null) = False+        notNull (_, _)    = True++data UpdateMilestone = UpdateMilestone+  { updateMilestoneTitle       :: !(Maybe Text)+  , updateMilestoneState       :: !(Maybe Text)+  , updateMilestoneDescription :: !(Maybe Text)+  , updateMilestoneDueOn       :: !(Maybe UTCTime)+  }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData UpdateMilestone+instance Binary UpdateMilestone+++instance ToJSON UpdateMilestone where+  toJSON (UpdateMilestone title state desc due) = object $ filter notNull+      [ "title"       .= title+      , "state"       .= state+      , "description" .= desc+      , "due_on"      .= due+      ]+    where+      notNull (_, Null) = False+      notNull (_, _)    = True
src/GitHub/Data/Name.hs view
@@ -1,9 +1,3 @@-{-# LANGUAGE CPP #-}--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Name (     Name(..),     mkName,@@ -13,13 +7,11 @@ import Prelude () import GitHub.Internal.Prelude -#if MIN_VERSION_aeson(1,0,0) import Data.Aeson.Types        (FromJSONKey (..), ToJSONKey (..), fromJSONKeyCoerce, toJSONKeyText)-#endif  newtype Name entity = N Text-    deriving (Eq, Ord, Show, Generic, Typeable, Data)+    deriving (Eq, Ord, Show, Generic, Data)  -- | Smart constructor for 'Name' mkName :: proxy entity -> Text -> Name entity@@ -43,7 +35,6 @@ instance IsString (Name entity) where     fromString = N . fromString -#if MIN_VERSION_aeson(1,0,0) -- | @since 0.15.0.0 instance ToJSONKey (Name entity) where     toJSONKey = toJSONKeyText untagName@@ -51,4 +42,3 @@ -- | @since 0.15.0.0 instance FromJSONKey (Name entity) where     fromJSONKey = fromJSONKeyCoerce-#endif
src/GitHub/Data/Options.hs view
@@ -1,10 +1,9 @@ {-# LANGUAGE RecordWildCards #-}------------------------------------------------------------------------------+{-# LANGUAGE LambdaCase #-}+ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- Module with modifiers for pull requests' and issues' listings.+ module GitHub.Data.Options (     -- * Common modifiers     stateOpen,@@ -38,14 +37,44 @@     -- * Repo issues     IssueRepoMod,     issueRepoModToQueryString,+    optionsCreator,+    optionsMentioned,     optionsIrrelevantMilestone,     optionsAnyMilestone,     optionsNoMilestone,+    optionsMilestone,     optionsIrrelevantAssignee,     optionsAnyAssignee,     optionsNoAssignee,+    optionsAssignee,+    -- * Actions artifacts+    ArtifactMod,+    artifactModToQueryString,+    optionsArtifactName,+    -- * Actions cache+    CacheMod,+    cacheModToQueryString,+    optionsRef,+    optionsNoRef,+    optionsKey,+    optionsNoKey,+    optionsDirectionAsc,+    optionsDirectionDesc,+    sortByCreatedAt,+    sortByLastAccessedAt,+    sortBySizeInBytes,+    -- * Actions workflow runs+    WorkflowRunMod,+    workflowRunModToQueryString,+    optionsWorkflowRunActor,+    optionsWorkflowRunBranch,+    optionsWorkflowRunEvent,+    optionsWorkflowRunStatus,+    optionsWorkflowRunCreated,+    optionsWorkflowRunHeadSha,     -- * Data     IssueState (..),+    IssueStateReason (..),     MergeableState (..),     -- * Internal     HasState,@@ -75,20 +104,48 @@     = StateOpen     | StateClosed   deriving-    (Eq, Ord, Show, Enum, Bounded, Generic, Typeable, Data)+    (Eq, Ord, Show, Enum, Bounded, Generic, Data)  instance ToJSON IssueState where     toJSON StateOpen    = String "open"     toJSON StateClosed  = String "closed"  instance FromJSON IssueState where-    parseJSON (String "open")   = pure StateOpen-    parseJSON (String "closed") = pure StateClosed-    parseJSON v                 = typeMismatch "IssueState" v+    parseJSON = withText "IssueState" $ \t -> case T.toLower t of+        "open"   -> pure StateOpen+        "closed" -> pure StateClosed+        _        -> fail $ "Unknown IssueState: " <> T.unpack t -instance NFData IssueState where rnf = genericRnf+instance NFData IssueState instance Binary IssueState +-- | 'GitHub.Data.Issues.Issue' state reason+data IssueStateReason+    = StateReasonCompleted+    | StateReasonDuplicate+    | StateReasonNotPlanned+    | StateReasonReopened+  deriving+    (Eq, Ord, Show, Enum, Bounded, Generic, Data)++instance ToJSON IssueStateReason where+    toJSON = String . \case+      StateReasonCompleted  -> "completed"+      StateReasonDuplicate  -> "duplicate"+      StateReasonNotPlanned -> "not_planned"+      StateReasonReopened   -> "reopened"++instance FromJSON IssueStateReason where+    parseJSON = withText "IssueStateReason" $ \t -> case T.toLower t of+        "completed"   -> pure StateReasonCompleted+        "duplicate"   -> pure StateReasonDuplicate+        "not_planned" -> pure StateReasonNotPlanned+        "reopened"    -> pure StateReasonReopened+        _ -> fail $ "Unknown IssueStateReason: " <> T.unpack t++instance NFData IssueStateReason+instance Binary IssueStateReason+ -- | 'GitHub.Data.PullRequests.PullRequest' mergeable_state data MergeableState     = StateUnknown@@ -97,8 +154,9 @@     | StateUnstable     | StateBlocked     | StateBehind+    | StateDraft   deriving-    (Eq, Ord, Show, Enum, Bounded, Generic, Typeable, Data)+    (Eq, Ord, Show, Enum, Bounded, Generic, Data)  instance ToJSON MergeableState where     toJSON StateUnknown  = String "unknown"@@ -107,26 +165,29 @@     toJSON StateUnstable = String "unstable"     toJSON StateBlocked  = String "blocked"     toJSON StateBehind   = String "behind"+    toJSON StateDraft    = String "draft"  instance FromJSON MergeableState where-    parseJSON (String "unknown")  = pure StateUnknown-    parseJSON (String "clean")    = pure StateClean-    parseJSON (String "dirty")    = pure StateDirty-    parseJSON (String "unstable") = pure StateUnstable-    parseJSON (String "blocked")  = pure StateBlocked-    parseJSON (String "behind")   = pure StateBehind-    parseJSON v                   = typeMismatch "MergeableState" v+    parseJSON = withText "MergeableState" $ \t -> case T.toLower t of+        "unknown"  -> pure StateUnknown+        "clean"    -> pure StateClean+        "dirty"    -> pure StateDirty+        "unstable" -> pure StateUnstable+        "blocked"  -> pure StateBlocked+        "behind"   -> pure StateBehind+        "draft"    -> pure StateDraft+        _          -> fail $ "Unknown MergeableState: " <> T.unpack t -instance NFData MergeableState where rnf = genericRnf+instance NFData MergeableState instance Binary MergeableState  data SortDirection     = SortAscending     | SortDescending   deriving-    (Eq, Ord, Show, Enum, Bounded, Generic, Typeable, Data)+    (Eq, Ord, Show, Enum, Bounded, Generic, Data) -instance NFData SortDirection where rnf = genericRnf+instance NFData SortDirection instance Binary SortDirection  -- PR@@ -137,9 +198,9 @@     | SortPRPopularity     | SortPRLongRunning   deriving-    (Eq, Ord, Show, Enum, Bounded, Generic, Typeable, Data)+    (Eq, Ord, Show, Enum, Bounded, Generic, Data) -instance NFData SortPR where rnf = genericRnf+instance NFData SortPR instance Binary SortPR  -- Issue@@ -150,9 +211,9 @@     | IssueFilterSubscribed     | IssueFilterAll   deriving-    (Eq, Ord, Show, Enum, Bounded, Generic, Typeable, Data)+    (Eq, Ord, Show, Enum, Bounded, Generic, Data) -instance NFData IssueFilter where rnf = genericRnf+instance NFData IssueFilter instance Binary IssueFilter  data SortIssue@@ -160,9 +221,9 @@     | SortIssueUpdated     | SortIssueComments   deriving-    (Eq, Ord, Show, Enum, Bounded, Generic, Typeable, Data)+    (Eq, Ord, Show, Enum, Bounded, Generic, Data) -instance NFData SortIssue where rnf = genericRnf+instance NFData SortIssue instance Binary SortIssue  data FilterBy a@@ -173,8 +234,20 @@       -- ^ e.g. for milestones "any" means "any milestone".       -- I.e. won't show issues without mileston specified   deriving-    (Eq, Ord, Show, Generic, Typeable, Data)+    (Eq, Ord, Show, Generic, Data) +-- Actions cache++data SortCache+    = SortCacheCreatedAt+    | SortCacheLastAccessedAt+    | SortCacheSizeInBytes+  deriving+    (Eq, Ord, Show, Enum, Bounded, Generic, Data)++instance NFData SortCache+instance Binary SortCache+ ------------------------------------------------------------------------------- -- Classes -------------------------------------------------------------------------------@@ -261,7 +334,7 @@     , pullRequestOptionsDirection :: !SortDirection     }   deriving-    (Eq, Ord, Show, Generic, Typeable, Data)+    (Eq, Ord, Show, Generic, Data)  defaultPullRequestOptions :: PullRequestOptions defaultPullRequestOptions = PullRequestOptions@@ -346,7 +419,7 @@ -- Issues ------------------------------------------------------------------------------- --- | See <https://developer.github.com/v3/issues/#parameters>.+-- | See <https://docs.github.com/en/rest/reference/issues#list-issues-assigned-to-the-authenticated-user--parameters>. data IssueOptions = IssueOptions     { issueOptionsFilter    :: !IssueFilter     , issueOptionsState     :: !(Maybe IssueState)@@ -356,7 +429,7 @@     , issueOptionsSince     :: !(Maybe UTCTime)     }   deriving-    (Eq, Ord, Show, Generic, Typeable, Data)+    (Eq, Ord, Show, Generic, Data)  defaultIssueOptions :: IssueOptions defaultIssueOptions = IssueOptions@@ -368,7 +441,7 @@     , issueOptionsSince     = Nothing     } --- | See <https://developer.github.com/v3/issues/#parameters>.+-- | See <https://docs.github.com/en/rest/reference/issues#list-issues-assigned-to-the-authenticated-user--parameters>. newtype IssueMod = IssueMod (IssueOptions -> IssueOptions)  instance Semigroup IssueMod where@@ -486,19 +559,23 @@ -- Issues repo ------------------------------------------------------------------------------- +-- | Parameters of "list repository issues" (@get /repos/{owner}/{repo}/issues@).+--+-- See <https://docs.github.com/en/rest/reference/issues#list-repository-issues>.+-- data IssueRepoOptions = IssueRepoOptions-    { issueRepoOptionsMilestone :: !(FilterBy (Id Milestone))-    , issueRepoOptionsState     :: !(Maybe IssueState)-    , issueRepoOptionsAssignee  :: !(FilterBy (Name User))-    , issueRepoOptionsCreator   :: !(Maybe (Name User))-    , issueRepoOptionsMentioned :: !(Maybe (Name User))-    , issueRepoOptionsLabels    :: ![Name IssueLabel]-    , issueRepoOptionsSort      :: !SortIssue-    , issueRepoOptionsDirection :: !SortDirection-    , issueRepoOptionsSince     :: !(Maybe UTCTime)+    { issueRepoOptionsMilestone :: !(FilterBy (Id Milestone))   -- ^ 'optionsMilestone' etc.+    , issueRepoOptionsState     :: !(Maybe IssueState)          -- ^ 'HasState'+    , issueRepoOptionsAssignee  :: !(FilterBy (Name User))      -- ^ 'optionsAssignee' etc.+    , issueRepoOptionsCreator   :: !(Maybe (Name User))         -- ^ 'optionsCreator'+    , issueRepoOptionsMentioned :: !(Maybe (Name User))         -- ^ 'optionsMentioned'+    , issueRepoOptionsLabels    :: ![Name IssueLabel]           -- ^ 'HasLabels'+    , issueRepoOptionsSort      :: !SortIssue                   -- ^ 'HasCreatedUpdated' and 'HasComments'+    , issueRepoOptionsDirection :: !SortDirection               -- ^ 'HasDirection'+    , issueRepoOptionsSince     :: !(Maybe UTCTime)             -- ^ 'HasSince'     }   deriving-    (Eq, Ord, Show, Generic, Typeable, Data)+    (Eq, Ord, Show, Generic, Data)  defaultIssueRepoOptions :: IssueRepoOptions defaultIssueRepoOptions = IssueRepoOptions@@ -574,7 +651,17 @@ -- Issues repo modifiers ------------------------------------------------------------------------------- --- | Don't care about milestones.+-- | Issues created by a certain user.+optionsCreator :: Name User -> IssueRepoMod+optionsCreator u = IssueRepoMod $ \opts ->+    opts { issueRepoOptionsCreator = Just u }++-- | Issue mentioning the given user.+optionsMentioned :: Name User -> IssueRepoMod+optionsMentioned u = IssueRepoMod $ \opts ->+    opts { issueRepoOptionsMentioned = Just u }++-- | Don't care about milestones (default). -- -- 'optionsAnyMilestone' means there should be some milestone, but it can be any. --@@ -583,22 +670,270 @@ optionsIrrelevantMilestone = IssueRepoMod $ \opts ->     opts { issueRepoOptionsMilestone = FilterNotSpecified } +-- | Issues that have a milestone. optionsAnyMilestone :: IssueRepoMod optionsAnyMilestone = IssueRepoMod $ \opts ->     opts { issueRepoOptionsMilestone = FilterAny } +-- | Issues that have no milestone. optionsNoMilestone :: IssueRepoMod optionsNoMilestone = IssueRepoMod $ \opts ->     opts { issueRepoOptionsMilestone = FilterNone } +-- | Issues with the given milestone.+optionsMilestone :: Id Milestone -> IssueRepoMod+optionsMilestone m = IssueRepoMod $ \opts ->+    opts { issueRepoOptionsMilestone = FilterBy m }++-- | Issues with or without assignee (default). optionsIrrelevantAssignee :: IssueRepoMod optionsIrrelevantAssignee = IssueRepoMod $ \opts ->     opts { issueRepoOptionsAssignee = FilterNotSpecified } +-- | Issues assigned to someone. optionsAnyAssignee :: IssueRepoMod optionsAnyAssignee = IssueRepoMod $ \opts ->     opts { issueRepoOptionsAssignee = FilterAny } +-- | Issues assigned to nobody. optionsNoAssignee :: IssueRepoMod optionsNoAssignee = IssueRepoMod $ \opts ->     opts { issueRepoOptionsAssignee = FilterNone }++-- | Issues assigned to a specific user.+optionsAssignee :: Name User -> IssueRepoMod+optionsAssignee u = IssueRepoMod $ \opts ->+    opts { issueRepoOptionsAssignee = FilterBy u }++-------------------------------------------------------------------------------+-- Actions artifacts+-------------------------------------------------------------------------------++-- | See <https://docs.github.com/en/rest/actions/artifacts#list-artifacts-for-a-repository>.+data ArtifactOptions = ArtifactOptions+    { artifactOptionsName :: !(Maybe Text)+    }+  deriving+    (Eq, Ord, Show, Generic, Data)++defaultArtifactOptions :: ArtifactOptions+defaultArtifactOptions = ArtifactOptions+    { artifactOptionsName = Nothing+    }++-- | See <https://docs.github.com/en/rest/actions/artifacts#list-artifacts-for-a-repository>.+newtype ArtifactMod = ArtifactMod (ArtifactOptions -> ArtifactOptions)++instance Semigroup ArtifactMod where+    ArtifactMod f <> ArtifactMod g = ArtifactMod (g . f)++instance Monoid ArtifactMod where+    mempty  = ArtifactMod id+    mappend = (<>)++-- | Filters artifacts by exact match on their name field.+optionsArtifactName :: Text -> ArtifactMod+optionsArtifactName n = ArtifactMod $ \opts ->+    opts { artifactOptionsName = Just n }++toArtifactOptions :: ArtifactMod -> ArtifactOptions+toArtifactOptions (ArtifactMod f) = f defaultArtifactOptions++artifactModToQueryString :: ArtifactMod -> QueryString+artifactModToQueryString = artifactOptionsToQueryString . toArtifactOptions++artifactOptionsToQueryString :: ArtifactOptions -> QueryString+artifactOptionsToQueryString (ArtifactOptions name) =+    catMaybes+    [ mk "name" <$> name'+    ]+  where+    mk k v = (k, Just v)+    name' = fmap TE.encodeUtf8 name++-------------------------------------------------------------------------------+-- Actions cache+-------------------------------------------------------------------------------++-- | See <https://docs.github.com/en/rest/actions/cache#list-github-actions-caches-for-a-repository>.+data CacheOptions = CacheOptions+    { cacheOptionsRef       :: !(Maybe Text)+    , cacheOptionsKey       :: !(Maybe Text)+    , cacheOptionsSort      :: !(Maybe SortCache)+    , cacheOptionsDirection :: !(Maybe SortDirection)+    }+  deriving+    (Eq, Ord, Show, Generic, Data)++defaultCacheOptions :: CacheOptions+defaultCacheOptions = CacheOptions+    { cacheOptionsRef       = Nothing+    , cacheOptionsKey       = Nothing+    , cacheOptionsSort      = Nothing+    , cacheOptionsDirection = Nothing+    }++-- | See <https://docs.github.com/en/rest/actions/cache#list-github-actions-caches-for-a-repository>.+newtype CacheMod = CacheMod (CacheOptions -> CacheOptions)++instance Semigroup CacheMod where+    CacheMod f <> CacheMod g = CacheMod (g . f)++instance Monoid CacheMod where+    mempty  = CacheMod id+    mappend = (<>)++toCacheOptions :: CacheMod -> CacheOptions+toCacheOptions (CacheMod f) = f defaultCacheOptions++cacheModToQueryString :: CacheMod -> QueryString+cacheModToQueryString = cacheOptionsToQueryString . toCacheOptions++cacheOptionsToQueryString :: CacheOptions -> QueryString+cacheOptionsToQueryString (CacheOptions ref key sort dir) =+    catMaybes+    [ mk "ref"        <$> ref'+    , mk "key"        <$> key'+    , mk "sort"       <$> sort'+    , mk "directions" <$> direction'+    ]+  where+    mk k v = (k, Just v)+    sort' = sort <&> \case+        SortCacheCreatedAt      -> "created_at"+        SortCacheLastAccessedAt -> "last_accessed_at"+        SortCacheSizeInBytes    -> "size_in_bytes"+    direction' = dir <&> \case+       SortDescending -> "desc"+       SortAscending  -> "asc"+    ref' = fmap TE.encodeUtf8 ref+    key' = fmap TE.encodeUtf8 key++-------------------------------------------------------------------------------+-- Cache modifiers+-------------------------------------------------------------------------------++optionsRef :: Text -> CacheMod+optionsRef x = CacheMod $ \opts ->+    opts { cacheOptionsRef = Just x }++optionsNoRef :: CacheMod+optionsNoRef = CacheMod $ \opts ->+    opts { cacheOptionsRef = Nothing }++optionsKey :: Text -> CacheMod+optionsKey x = CacheMod $ \opts ->+    opts { cacheOptionsKey = Just x }++optionsNoKey :: CacheMod+optionsNoKey = CacheMod $ \opts ->+    opts { cacheOptionsKey = Nothing }++optionsDirectionAsc :: CacheMod+optionsDirectionAsc = CacheMod $ \opts ->+    opts { cacheOptionsDirection = Just SortAscending }++optionsDirectionDesc :: CacheMod+optionsDirectionDesc = CacheMod $ \opts ->+    opts { cacheOptionsDirection = Just SortDescending }++sortByCreatedAt :: CacheMod+sortByCreatedAt = CacheMod $ \opts ->+    opts { cacheOptionsSort = Just SortCacheCreatedAt }++sortByLastAccessedAt :: CacheMod+sortByLastAccessedAt = CacheMod $ \opts ->+    opts { cacheOptionsSort = Just SortCacheLastAccessedAt }++sortBySizeInBytes :: CacheMod+sortBySizeInBytes = CacheMod $ \opts ->+    opts { cacheOptionsSort = Just SortCacheSizeInBytes }++-------------------------------------------------------------------------------+-- Actions workflow runs+-------------------------------------------------------------------------------++-- | See <https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-repository>.+data WorkflowRunOptions = WorkflowRunOptions+    { workflowRunOptionsActor   :: !(Maybe Text)+    , workflowRunOptionsBranch  :: !(Maybe Text)+    , workflowRunOptionsEvent   :: !(Maybe Text)+    , workflowRunOptionsStatus  :: !(Maybe Text)+    , workflowRunOptionsCreated :: !(Maybe Text)+    , workflowRunOptionsHeadSha :: !(Maybe Text)+    }+  deriving+    (Eq, Ord, Show, Generic, Data)++defaultWorkflowRunOptions :: WorkflowRunOptions+defaultWorkflowRunOptions = WorkflowRunOptions+    { workflowRunOptionsActor   = Nothing+    , workflowRunOptionsBranch  = Nothing+    , workflowRunOptionsEvent   = Nothing+    , workflowRunOptionsStatus  = Nothing+    , workflowRunOptionsCreated = Nothing+    , workflowRunOptionsHeadSha = Nothing+    }++-- | See <https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-repository>.+newtype WorkflowRunMod = WorkflowRunMod (WorkflowRunOptions -> WorkflowRunOptions)++instance Semigroup WorkflowRunMod where+    WorkflowRunMod f <> WorkflowRunMod g = WorkflowRunMod (g . f)++instance Monoid WorkflowRunMod where+    mempty  = WorkflowRunMod id+    mappend = (<>)++toWorkflowRunOptions :: WorkflowRunMod -> WorkflowRunOptions+toWorkflowRunOptions (WorkflowRunMod f) = f defaultWorkflowRunOptions++workflowRunModToQueryString :: WorkflowRunMod -> QueryString+workflowRunModToQueryString = workflowRunOptionsToQueryString . toWorkflowRunOptions++workflowRunOptionsToQueryString :: WorkflowRunOptions -> QueryString+workflowRunOptionsToQueryString (WorkflowRunOptions actor branch event status created headSha) =+    catMaybes+    [ mk "actor"    <$> actor'+    , mk "branch"   <$> branch'+    , mk "event"    <$> event'+    , mk "status"   <$> status'+    , mk "created"  <$> created'+    , mk "head_sha" <$> headSha'+    ]+  where+    mk k v = (k, Just v)+    actor'   = fmap TE.encodeUtf8 actor+    branch'  = fmap TE.encodeUtf8 branch+    event'   = fmap TE.encodeUtf8 event+    status'  = fmap TE.encodeUtf8 status+    created' = fmap TE.encodeUtf8 created+    headSha' = fmap TE.encodeUtf8 headSha++-------------------------------------------------------------------------------+-- Workflow run modifiers+-------------------------------------------------------------------------------++optionsWorkflowRunActor :: Text -> WorkflowRunMod+optionsWorkflowRunActor x = WorkflowRunMod $ \opts ->+    opts { workflowRunOptionsActor = Just x }++optionsWorkflowRunBranch :: Text -> WorkflowRunMod+optionsWorkflowRunBranch x = WorkflowRunMod $ \opts ->+    opts { workflowRunOptionsBranch = Just x }++optionsWorkflowRunEvent :: Text -> WorkflowRunMod+optionsWorkflowRunEvent x = WorkflowRunMod $ \opts ->+    opts { workflowRunOptionsEvent = Just x }++optionsWorkflowRunStatus :: Text -> WorkflowRunMod+optionsWorkflowRunStatus x = WorkflowRunMod $ \opts ->+    opts { workflowRunOptionsStatus = Just x }++optionsWorkflowRunCreated :: Text -> WorkflowRunMod+optionsWorkflowRunCreated x = WorkflowRunMod $ \opts ->+    opts { workflowRunOptionsCreated = Just x }++optionsWorkflowRunHeadSha :: Text -> WorkflowRunMod+optionsWorkflowRunHeadSha x = WorkflowRunMod $ \opts ->+    opts { workflowRunOptionsHeadSha = Just x }
+ src/GitHub/Data/PublicSSHKeys.hs view
@@ -0,0 +1,60 @@+-----------------------------------------------------------------------------+-- |+-- License     :  BSD-3-Clause+-- Maintainer  :  Todd Mohney <toddmohney@gmail.com>+--+module GitHub.Data.PublicSSHKeys where++import GitHub.Data.Id          (Id)+import GitHub.Data.URL         (URL)+import GitHub.Internal.Prelude+import Prelude ()++data PublicSSHKeyBasic = PublicSSHKeyBasic+    { basicPublicSSHKeyId        :: !(Id PublicSSHKey)+    , basicPublicSSHKeyKey       :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance FromJSON PublicSSHKeyBasic where+    parseJSON = withObject "PublicSSHKeyBasic" $ \o -> PublicSSHKeyBasic+        <$> o .: "id"+        <*> o .: "key"++data PublicSSHKey = PublicSSHKey+    { publicSSHKeyId        :: !(Id PublicSSHKey)+    , publicSSHKeyKey       :: !Text+    , publicSSHKeyUrl       :: !URL+    , publicSSHKeyTitle     :: !Text+    , publicSSHKeyVerified  :: !Bool+    , publicSSHKeyCreatedAt :: !(Maybe UTCTime)+    , publicSSHKeyReadOnly  :: !Bool+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance FromJSON PublicSSHKey where+    parseJSON = withObject "PublicSSHKey" $ \o -> PublicSSHKey+        <$> o .: "id"+        <*> o .: "key"+        <*> o .: "url"+        <*> o .: "title"+        <*> o .: "verified"+        <*> o .:? "created_at"+        <*> o .: "read_only"++data NewPublicSSHKey = NewPublicSSHKey+    { newPublicSSHKeyKey      :: !Text+    , newPublicSSHKeyTitle    :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance ToJSON NewPublicSSHKey where+    toJSON (NewPublicSSHKey key title) = object+        [ "key" .= key+        , "title" .= title+        ]++instance FromJSON NewPublicSSHKey where+    parseJSON = withObject "PublicSSHKey" $ \o -> NewPublicSSHKey+        <$> o .: "key"+        <*> o .: "title"
src/GitHub/Data/PullRequests.hs view
@@ -1,8 +1,3 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.PullRequests (     SimplePullRequest(..),     PullRequest(..),@@ -14,15 +9,14 @@     PullRequestEventType(..),     PullRequestReference(..),     MergeResult(..),-    statusMerge,     ) where  import GitHub.Data.Definitions import GitHub.Data.Id          (Id) import GitHub.Data.Options     (IssueState (..), MergeableState (..)) import GitHub.Data.Repos       (Repo)-import GitHub.Data.Request     (StatusMap) import GitHub.Data.URL         (URL)+import GitHub.Data.Teams       (SimpleTeam) import GitHub.Internal.Prelude import Prelude () @@ -34,12 +28,13 @@     , simplePullRequestUser               :: !SimpleUser     , simplePullRequestPatchUrl           :: !URL     , simplePullRequestState              :: !IssueState-    , simplePullRequestNumber             :: !Int+    , simplePullRequestNumber             :: !IssueNumber     , simplePullRequestHtmlUrl            :: !URL     , simplePullRequestUpdatedAt          :: !UTCTime     , simplePullRequestBody               :: !(Maybe Text)     , simplePullRequestAssignees          :: (Vector SimpleUser)     , simplePullRequestRequestedReviewers :: (Vector SimpleUser)+    , simplePullRequestRequestedTeamReviewers:: (Vector SimpleTeam)     , simplePullRequestIssueUrl           :: !URL     , simplePullRequestDiffUrl            :: !URL     , simplePullRequestUrl                :: !URL@@ -48,9 +43,9 @@     , simplePullRequestTitle              :: !Text     , simplePullRequestId                 :: !(Id PullRequest)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData SimplePullRequest where rnf = genericRnf+instance NFData SimplePullRequest instance Binary SimplePullRequest  data PullRequest = PullRequest@@ -59,12 +54,13 @@     , pullRequestUser                 :: !SimpleUser     , pullRequestPatchUrl             :: !URL     , pullRequestState                :: !IssueState-    , pullRequestNumber               :: !Int+    , pullRequestNumber               :: !IssueNumber     , pullRequestHtmlUrl              :: !URL     , pullRequestUpdatedAt            :: !UTCTime     , pullRequestBody                 :: !(Maybe Text)     , pullRequestAssignees            :: (Vector SimpleUser)     , pullRequestRequestedReviewers   :: (Vector SimpleUser)+    , pullRequestRequestedTeamReviewers :: (Vector SimpleTeam)     , pullRequestIssueUrl             :: !URL     , pullRequestDiffUrl              :: !URL     , pullRequestUrl                  :: !URL@@ -85,9 +81,9 @@     , pullRequestMergeable            :: !(Maybe Bool)     , pullRequestMergeableState       :: !MergeableState     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData PullRequest where rnf = genericRnf+instance NFData PullRequest instance Binary PullRequest  data EditPullRequest = EditPullRequest@@ -100,7 +96,7 @@     }   deriving (Show, Generic) -instance NFData EditPullRequest where rnf = genericRnf+instance NFData EditPullRequest instance Binary EditPullRequest  data CreatePullRequest@@ -117,7 +113,7 @@       }   deriving (Show, Generic) -instance NFData CreatePullRequest where rnf = genericRnf+instance NFData CreatePullRequest instance Binary CreatePullRequest  data PullRequestLinks = PullRequestLinks@@ -126,9 +122,9 @@     , pullRequestLinksHtml           :: !URL     , pullRequestLinksSelf           :: !URL     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData PullRequestLinks where rnf = genericRnf+instance NFData PullRequestLinks instance Binary PullRequestLinks  data PullRequestCommit = PullRequestCommit@@ -138,9 +134,9 @@     , pullRequestCommitUser  :: !SimpleUser     , pullRequestCommitRepo  :: !(Maybe Repo)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData PullRequestCommit where rnf = genericRnf+instance NFData PullRequestCommit instance Binary PullRequestCommit  data PullRequestEvent = PullRequestEvent@@ -150,9 +146,9 @@     , pullRequestRepository       :: !Repo     , pullRequestSender           :: !SimpleUser     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData PullRequestEvent where rnf = genericRnf+instance NFData PullRequestEvent instance Binary PullRequestEvent  data PullRequestEventType@@ -167,9 +163,9 @@     | PullRequestReviewRequested     | PullRequestReviewRequestRemoved     | PullRequestEdited-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData PullRequestEventType where rnf = genericRnf+instance NFData PullRequestEventType instance Binary PullRequestEventType  data PullRequestReference = PullRequestReference@@ -177,9 +173,9 @@     , pullRequestReferencePatchUrl :: !(Maybe URL)     , pullRequestReferenceDiffUrl  :: !(Maybe URL)     }-    deriving (Eq, Ord, Show, Generic, Typeable, Data)+    deriving (Eq, Ord, Show, Generic, Data) -instance NFData PullRequestReference where rnf = genericRnf+instance NFData PullRequestReference instance Binary PullRequestReference  @@ -200,6 +196,7 @@         <*> o .:? "body"         <*> o .: "assignees"         <*> o .:? "requested_reviewers" .!= mempty+        <*> o .:? "requested_teams" .!= mempty         <*> o .: "issue_url"         <*> o .: "diff_url"         <*> o .: "url"@@ -241,6 +238,7 @@         <*> o .:? "body"         <*> o .: "assignees"         <*> o .:? "requested_reviewers" .!= mempty+        <*> o .:? "requested_teams" .!= mempty         <*> o .: "issue_url"         <*> o .: "diff_url"         <*> o .: "url"@@ -285,19 +283,19 @@         <*> o .: "sender"  instance FromJSON PullRequestEventType where-    parseJSON (String "opened") = pure PullRequestOpened-    parseJSON (String "closed") = pure PullRequestClosed-    parseJSON (String "synchronize") = pure PullRequestSynchronized-    parseJSON (String "reopened") = pure PullRequestReopened-    parseJSON (String "assigned") = pure PullRequestAssigned-    parseJSON (String "unassigned") = pure PullRequestUnassigned-    parseJSON (String "labeled") = pure PullRequestLabeled-    parseJSON (String "unlabeled") = pure PullRequestUnlabeled-    parseJSON (String "review_requested") = pure PullRequestReviewRequested-    parseJSON (String "review_request_removed") = pure PullRequestReviewRequestRemoved-    parseJSON (String "edited") = pure PullRequestEdited-    parseJSON (String s) = fail $ "Unknown action type " <> T.unpack s-    parseJSON v = typeMismatch "Could not build a PullRequestEventType" v+    parseJSON = withText "PullRequestEventType" $ \t -> case T.toLower t of+        "opened"                 -> pure PullRequestOpened+        "closed"                 -> pure PullRequestClosed+        "synchronize"            -> pure PullRequestSynchronized+        "reopened"               -> pure PullRequestReopened+        "assigned"               -> pure PullRequestAssigned+        "unassigned"             -> pure PullRequestUnassigned+        "labeled"                -> pure PullRequestLabeled+        "unlabeled"              -> pure PullRequestUnlabeled+        "review_requested"       -> pure PullRequestReviewRequested+        "review_request_removed" -> pure PullRequestReviewRequestRemoved+        "edited"                 -> pure PullRequestEdited+        _                        -> fail $ "Unknown PullRequestEventType: " <> T.unpack t  instance FromJSON PullRequestReference where     parseJSON = withObject "PullRequestReference" $ \o -> PullRequestReference@@ -318,11 +316,4 @@     = MergeSuccessful     | MergeCannotPerform     | MergeConflict-  deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable)--statusMerge :: StatusMap MergeResult-statusMerge =-    [ (200, MergeSuccessful)-    , (405, MergeCannotPerform)-    , (409, MergeConflict)-    ]+  deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic)
+ src/GitHub/Data/RateLimit.hs view
@@ -0,0 +1,61 @@+module GitHub.Data.RateLimit where++import GitHub.Internal.Prelude+import Prelude ()++import Data.Time.Clock.System (SystemTime (..))++import qualified Data.ByteString.Char8 as BS8+import qualified Network.HTTP.Client as HTTP++data Limits = Limits+    { limitsMax       :: !Int+    , limitsRemaining :: !Int+    , limitsReset     :: !SystemTime+    }+  deriving (Show, Eq, Ord, Generic)++instance NFData Limits+instance Binary Limits++instance FromJSON Limits where+    parseJSON = withObject "Limits" $ \obj -> Limits+        <$> obj .: "limit"+        <*> obj .: "remaining"+        <*> fmap (\t -> MkSystemTime t 0) (obj .: "reset")++data RateLimit = RateLimit+    { rateLimitCore    :: Limits+    , rateLimitSearch  :: Limits+    , rateLimitGraphQL :: Limits+    }+  deriving (Show, Eq, Ord, Generic)++instance NFData RateLimit+instance Binary RateLimit++instance FromJSON RateLimit where+    parseJSON = withObject "RateLimit" $ \obj -> do+        resources <- obj .: "resources"+        RateLimit+            <$> resources .: "core"+            <*> resources .: "search"+            <*> resources .: "graphql"++-------------------------------------------------------------------------------+-- Extras+-------------------------------------------------------------------------------++-- | @since 0.24+limitsFromHttpResponse :: HTTP.Response a -> Maybe Limits+limitsFromHttpResponse res = do+    let hdrs = HTTP.responseHeaders res+    m <- lookup "X-RateLimit-Limit"     hdrs >>= readIntegral+    r <- lookup "X-RateLimit-Remaining" hdrs >>= readIntegral+    t <- lookup "X-RateLimit-Reset"     hdrs >>= readIntegral+    return (Limits m r (MkSystemTime t 0))+  where+    readIntegral :: Num a => BS8.ByteString -> Maybe a+    readIntegral bs = case BS8.readInt bs of+        Just (n, bs') | BS8.null bs' -> Just (fromIntegral n)+        _                            -> Nothing
+ src/GitHub/Data/Reactions.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE InstanceSigs #-}+module GitHub.Data.Reactions where++import qualified Data.Text as T+import GitHub.Data.Id (Id)+import GitHub.Data.Definitions (SimpleUser)+import GitHub.Internal.Prelude+import Prelude ()++data Reaction = Reaction+  { reactionId :: Id Reaction+  , reactionUser :: !(Maybe SimpleUser)+  , reactionContent :: !ReactionContent+  , reactionCreatedAt :: !UTCTime+  }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Reaction+instance Binary Reaction++data NewReaction = NewReaction+  { newReactionContent :: !ReactionContent+  }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData NewReaction+instance Binary NewReaction++-- |+-- <https://docs.github.com/en/rest/reactions/reactions?apiVersion=2022-11-28#about-reactions>+data ReactionContent+  = PlusOne+  | MinusOne+  | Laugh+  | Confused+  | Heart+  | Hooray+  | Rocket+  | Eyes+  deriving (Show, Data, Eq, Ord, Enum, Bounded, Generic)++instance NFData ReactionContent+instance Binary ReactionContent++-- JSON instances++instance FromJSON Reaction where+  parseJSON = withObject "Reaction" $ \o ->+    Reaction+      <$> o .: "id"+      <*> o .:? "user"+      <*> o .: "content"+      <*> o .: "created_at"++instance ToJSON NewReaction where+  toJSON (NewReaction content) = object ["content" .= content]++instance FromJSON ReactionContent where+  parseJSON = withText "ReactionContent" $ \case+    "+1" -> pure PlusOne+    "-1" -> pure MinusOne+    "laugh" -> pure Laugh+    "confused" -> pure Confused+    "heart" -> pure Heart+    "hooray" -> pure Hooray+    "rocket" -> pure Rocket+    "eyes" -> pure Eyes+    t -> fail $ "Unknown ReactionContent: " <> T.unpack t++instance ToJSON ReactionContent where+  toJSON PlusOne = String "+1"+  toJSON MinusOne = String "-1"+  toJSON Laugh = String "laugh"+  toJSON Confused = String "confused"+  toJSON Heart = String "heart"+  toJSON Hooray = String "hooray"+  toJSON Rocket = String "rocket"+  toJSON Eyes = String "eyes"
src/GitHub/Data/Releases.hs view
@@ -25,7 +25,7 @@     , releaseAuthor          :: !SimpleUser     , releaseAssets          :: !(Vector ReleaseAsset)     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic)  instance FromJSON Release where     parseJSON = withObject "Event" $ \o -> Release@@ -47,7 +47,7 @@         <*> o .: "author"         <*> o .: "assets" -instance NFData Release where rnf = genericRnf+instance NFData Release instance Binary Release  data ReleaseAsset = ReleaseAsset@@ -64,7 +64,7 @@     , releaseAssetUpdatedAt          :: !UTCTime     , releaseAssetUploader           :: !SimpleUser     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic)  instance FromJSON ReleaseAsset where     parseJSON = withObject "Event" $ \o -> ReleaseAsset@@ -81,5 +81,5 @@         <*> o .: "updated_at"         <*> o .: "uploader" -instance NFData ReleaseAsset where rnf = genericRnf+instance NFData ReleaseAsset instance Binary ReleaseAsset
src/GitHub/Data/Repos.hs view
@@ -1,14 +1,10 @@-{-# LANGUAGE CPP               #-} {-# LANGUAGE FlexibleInstances #-}-#define UNSAFE 1------------------------------------------------------------------------------+ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- This module also exports -- @'FromJSON' a => 'FromJSON' ('HM.HashMap' 'Language' a)@ -- orphan-ish instance for @aeson < 1@+ module GitHub.Data.Repos where  import GitHub.Data.Definitions@@ -20,88 +16,144 @@ import Prelude ()  import qualified Data.HashMap.Strict as HM-#if MIN_VERSION_aeson(1,0,0)+import qualified Data.Text as T import Data.Aeson.Types (FromJSONKey (..), fromJSONKeyCoerce)-#else-#ifdef UNSAFE-import Unsafe.Coerce (unsafeCoerce)-#endif-#endif  data Repo = Repo-    { repoSshUrl          :: !(Maybe URL)-    , repoDescription     :: !(Maybe Text)-    , repoCreatedAt       :: !(Maybe UTCTime)+    { repoId              :: !(Id Repo)+    , repoName            :: !(Name Repo)+    , repoOwner           :: !SimpleOwner+    , repoPrivate         :: !Bool     , repoHtmlUrl         :: !URL-    , repoSvnUrl          :: !(Maybe URL)-    , repoForks           :: !(Maybe Int)-    , repoHomepage        :: !(Maybe Text)+    , repoDescription     :: !(Maybe Text)     , repoFork            :: !(Maybe Bool)+    , repoUrl             :: !URL     , repoGitUrl          :: !(Maybe URL)-    , repoPrivate         :: !Bool-    , repoArchived        :: !Bool+    , repoSshUrl          :: !(Maybe URL)     , repoCloneUrl        :: !(Maybe URL)-    , repoSize            :: !(Maybe Int)-    , repoUpdatedAt       :: !(Maybe UTCTime)-    , repoWatchers        :: !(Maybe Int)-    , repoOwner           :: !SimpleOwner-    , repoName            :: !(Name Repo)+    , repoHooksUrl        :: !URL+    , repoSvnUrl          :: !(Maybe URL)+    , repoHomepage        :: !(Maybe Text)     , repoLanguage        :: !(Maybe Language)+    , repoForksCount      :: !Int+    , repoStargazersCount :: !Int+    , repoWatchersCount   :: !Int+    , repoSize            :: !(Maybe Int)     , repoDefaultBranch   :: !(Maybe Text)-    , repoPushedAt        :: !(Maybe UTCTime)   -- ^ this is Nothing for new repositories-    , repoId              :: !(Id Repo)-    , repoUrl             :: !URL-    , repoOpenIssues      :: !(Maybe Int)-    , repoHasWiki         :: !(Maybe Bool)+    , repoOpenIssuesCount :: !Int     , repoHasIssues       :: !(Maybe Bool)+    , repoHasProjects     :: !(Maybe Bool)+    , repoHasWiki         :: !(Maybe Bool)+    , repoHasPages        :: !(Maybe Bool)     , repoHasDownloads    :: !(Maybe Bool)-    , repoParent          :: !(Maybe RepoRef)-    , repoSource          :: !(Maybe RepoRef)-    , repoHooksUrl        :: !URL-    , repoStargazersCount :: !Int+    , repoArchived        :: !Bool+    , repoDisabled        :: !Bool+    , repoPushedAt        :: !(Maybe UTCTime)   -- ^ this is Nothing for new repositories+    , repoCreatedAt       :: !(Maybe UTCTime)+    , repoUpdatedAt       :: !(Maybe UTCTime)+    , repoPermissions     :: !(Maybe RepoPermissions) -- ^ Repository permissions as they relate to the authenticated user.     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData Repo where rnf = genericRnf+instance NFData Repo instance Binary Repo +data CodeSearchRepo = CodeSearchRepo+    { codeSearchRepoId              :: !(Id Repo)+    , codeSearchRepoName            :: !(Name Repo)+    , codeSearchRepoOwner           :: !SimpleOwner+    , codeSearchRepoPrivate         :: !Bool+    , codeSearchRepoHtmlUrl         :: !URL+    , codeSearchRepoDescription     :: !(Maybe Text)+    , codeSearchRepoFork            :: !(Maybe Bool)+    , codeSearchRepoUrl             :: !URL+    , codeSearchRepoGitUrl          :: !(Maybe URL)+    , codeSearchRepoSshUrl          :: !(Maybe URL)+    , codeSearchRepoCloneUrl        :: !(Maybe URL)+    , codeSearchRepoHooksUrl        :: !URL+    , codeSearchRepoSvnUrl          :: !(Maybe URL)+    , codeSearchRepoHomepage        :: !(Maybe Text)+    , codeSearchRepoLanguage        :: !(Maybe Language)+    , codeSearchRepoSize            :: !(Maybe Int)+    , codeSearchRepoDefaultBranch   :: !(Maybe Text)+    , codeSearchRepoHasIssues       :: !(Maybe Bool)+    , codeSearchRepoHasProjects     :: !(Maybe Bool)+    , codeSearchRepoHasWiki         :: !(Maybe Bool)+    , codeSearchRepoHasPages        :: !(Maybe Bool)+    , codeSearchRepoHasDownloads    :: !(Maybe Bool)+    , codeSearchRepoArchived        :: !Bool+    , codeSearchRepoDisabled        :: !Bool+    , codeSearchRepoPushedAt        :: !(Maybe UTCTime)   -- ^ this is Nothing for new repositories+    , codeSearchRepoCreatedAt       :: !(Maybe UTCTime)+    , codeSearchRepoUpdatedAt       :: !(Maybe UTCTime)+    , codeSearchRepoPermissions     :: !(Maybe RepoPermissions) -- ^ Repository permissions as they relate to the authenticated user.+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData CodeSearchRepo+instance Binary CodeSearchRepo++-- | Repository permissions, as they relate to the authenticated user.+--+-- Returned by for example 'GitHub.Endpoints.Repos.currentUserReposR'+data RepoPermissions = RepoPermissions+    { repoPermissionAdmin :: !Bool+    , repoPermissionPush :: !Bool+    , repoPermissionPull :: !Bool+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData RepoPermissions+instance Binary RepoPermissions+ data RepoRef = RepoRef     { repoRefOwner :: !SimpleOwner     , repoRefRepo  :: !(Name Repo)     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData RepoRef where rnf = genericRnf+instance NFData RepoRef instance Binary RepoRef  data NewRepo = NewRepo-    { newRepoName        :: !(Name Repo)-    , newRepoDescription :: !(Maybe Text)-    , newRepoHomepage    :: !(Maybe Text)-    , newRepoPrivate     :: !(Maybe Bool)-    , newRepoHasIssues   :: !(Maybe Bool)-    , newRepoHasWiki     :: !(Maybe Bool)-    , newRepoAutoInit    :: !(Maybe Bool)-    } deriving (Eq, Ord, Show, Data, Typeable, Generic)+    { newRepoName              :: !(Name Repo)+    , newRepoDescription       :: !(Maybe Text)+    , newRepoHomepage          :: !(Maybe Text)+    , newRepoPrivate           :: !(Maybe Bool)+    , newRepoHasIssues         :: !(Maybe Bool)+    , newRepoHasProjects       :: !(Maybe Bool)+    , newRepoHasWiki           :: !(Maybe Bool)+    , newRepoAutoInit          :: !(Maybe Bool)+    , newRepoGitignoreTemplate :: !(Maybe Text)+    , newRepoLicenseTemplate   :: !(Maybe Text)+    , newRepoAllowSquashMerge  :: !(Maybe Bool)+    , newRepoAllowMergeCommit  :: !(Maybe Bool)+    , newRepoAllowRebaseMerge  :: !(Maybe Bool)+    } deriving (Eq, Ord, Show, Data, Generic) -instance NFData NewRepo where rnf = genericRnf+instance NFData NewRepo instance Binary NewRepo  newRepo :: Name Repo -> NewRepo-newRepo name = NewRepo name Nothing Nothing Nothing Nothing Nothing Nothing+newRepo name = NewRepo name Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing  data EditRepo = EditRepo-    { editName         :: !(Maybe (Name Repo))-    , editDescription  :: !(Maybe Text)-    , editHomepage     :: !(Maybe Text)-    , editPublic       :: !(Maybe Bool)-    , editHasIssues    :: !(Maybe Bool)-    , editHasWiki      :: !(Maybe Bool)-    , editHasDownloads :: !(Maybe Bool)+    { editName             :: !(Maybe (Name Repo))+    , editDescription      :: !(Maybe Text)+    , editHomepage         :: !(Maybe Text)+    , editPrivate          :: !(Maybe Bool)+    , editHasIssues        :: !(Maybe Bool)+    , editHasProjects      :: !(Maybe Bool)+    , editHasWiki          :: !(Maybe Bool)+    , editDefaultBranch    :: !(Maybe Text)+    , editAllowSquashMerge :: !(Maybe Bool)+    , editAllowMergeCommit :: !(Maybe Bool)+    , editAllowRebaseMerge :: !(Maybe Bool)+    , editArchived         :: !(Maybe Bool)     }-    deriving (Eq, Ord, Show, Data, Typeable, Generic)+    deriving (Eq, Ord, Show, Data, Generic) -instance NFData EditRepo where rnf = genericRnf+instance NFData EditRepo instance Binary EditRepo  -- | Filter the list of the user's repos using any of these constructors.@@ -111,19 +163,19 @@     | RepoPublicityPublic  -- ^ Only public repos.     | RepoPublicityPrivate -- ^ Only private repos.     | RepoPublicityMember  -- ^ Only repos to which the user is a member but not an owner.-    deriving (Show, Eq, Ord, Enum, Bounded, Typeable, Data, Generic)+    deriving (Show, Eq, Ord, Enum, Bounded, Data, Generic)  -- | The value is the number of bytes of code written in that language. type Languages = HM.HashMap Language Int  -- | A programming language. newtype Language = Language Text-   deriving (Show, Data, Typeable, Eq, Ord, Generic)+   deriving (Show, Data, Eq, Ord, Generic)  getLanguage :: Language -> Text getLanguage (Language l) = l -instance NFData Language where rnf = genericRnf+instance NFData Language instance Binary Language instance Hashable Language where     hashWithSalt salt (Language l) = hashWithSalt salt l@@ -136,9 +188,9 @@     = KnownContributor !Int !URL !(Name User) !URL !(Id User) !Text     -- | An unknown Github user with their number of contributions and recorded name.     | AnonymousContributor !Int !Text-   deriving (Show, Data, Typeable, Eq, Ord, Generic)+   deriving (Show, Data, Eq, Ord, Generic) -instance NFData Contributor where rnf = genericRnf+instance NFData Contributor instance Binary Contributor  contributorToSimpleUser :: Contributor -> Maybe SimpleUser@@ -146,76 +198,157 @@ contributorToSimpleUser (KnownContributor _contributions avatarUrl name url uid _gravatarid) =     Just $ SimpleUser uid name avatarUrl url +-- | The permission of a collaborator on a repository.+-- See <https://developer.github.com/v3/repos/collaborators/#review-a-users-permission-level>+data CollaboratorPermission+    = CollaboratorPermissionAdmin+    | CollaboratorPermissionWrite+    | CollaboratorPermissionRead+    | CollaboratorPermissionNone+    deriving (Show, Data, Enum, Bounded, Eq, Ord, Generic)++instance NFData CollaboratorPermission+instance Binary CollaboratorPermission++-- | A collaborator and its permission on a repository.+-- See <https://developer.github.com/v3/repos/collaborators/#review-a-users-permission-level>+data CollaboratorWithPermission+    = CollaboratorWithPermission SimpleUser CollaboratorPermission+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData CollaboratorWithPermission+instance Binary CollaboratorWithPermission+ -- JSON instances  instance FromJSON Repo where-    parseJSON = withObject "Repo" $ \o -> Repo <$> o .:? "ssh_url"-        <*> o .: "description"-        <*> o .:? "created_at"+    parseJSON = withObject "Repo" $ \o -> Repo <$> o .: "id"+        <*> o .: "name"+        <*> o .: "owner"+        <*> o .: "private"         <*> o .: "html_url"-        <*> o .:? "svn_url"-        <*> o .:? "forks"-        <*> o .:? "homepage"+        <*> o .:? "description"         <*> o .: "fork"+        <*> o .: "url"         <*> o .:? "git_url"-        <*> o .: "private"-        <*> o .:? "archived" .!= False+        <*> o .:? "ssh_url"         <*> o .:? "clone_url"+        <*> o .: "hooks_url"+        <*> o .:? "svn_url"+        <*> o .:? "homepage"+        <*> o .:? "language"+        <*> o .: "forks_count"+        <*> o .: "stargazers_count"+        <*> o .: "watchers_count"         <*> o .:? "size"+        <*> o .:? "default_branch"+        <*> o .: "open_issues_count"+        <*> o .:? "has_issues"+        <*> o .:? "has_projects"+        <*> o .:? "has_wiki"+        <*> o .:? "has_pages"+        <*> o .:? "has_downloads"+        <*> o .:? "archived" .!= False+        <*> o .:? "disabled" .!= False+        <*> o .:? "pushed_at"+        <*> o .:? "created_at"         <*> o .:? "updated_at"-        <*> o .:? "watchers"-        <*> o .: "owner"+        <*> o .:? "permissions"++instance FromJSON CodeSearchRepo where+    parseJSON = withObject "Repo" $ \o -> CodeSearchRepo <$> o .: "id"         <*> o .: "name"+        <*> o .: "owner"+        <*> o .: "private"+        <*> o .: "html_url"+        <*> o .:? "description"+        <*> o .: "fork"+        <*> o .: "url"+        <*> o .:? "git_url"+        <*> o .:? "ssh_url"+        <*> o .:? "clone_url"+        <*> o .: "hooks_url"+        <*> o .:? "svn_url"+        <*> o .:? "homepage"         <*> o .:? "language"+        <*> o .:? "size"         <*> o .:? "default_branch"-        <*> o .:? "pushed_at"-        <*> o .: "id"-        <*> o .: "url"-        <*> o .:? "open_issues"-        <*> o .:? "has_wiki"         <*> o .:? "has_issues"+        <*> o .:? "has_projects"+        <*> o .:? "has_wiki"+        <*> o .:? "has_pages"         <*> o .:? "has_downloads"-        <*> o .:? "parent"-        <*> o .:? "source"-        <*> o .: "hooks_url"-        <*> o .: "stargazers_count"+        <*> o .:? "archived" .!= False+        <*> o .:? "disabled" .!= False+        <*> o .:? "pushed_at"+        <*> o .:? "created_at"+        <*> o .:? "updated_at"+        <*> o .:? "permissions"  instance ToJSON NewRepo where-  toJSON (NewRepo { newRepoName         = name-                  , newRepoDescription  = description-                  , newRepoHomepage     = homepage-                  , newRepoPrivate      = private-                  , newRepoHasIssues    = hasIssues-                  , newRepoHasWiki      = hasWiki-                  , newRepoAutoInit     = autoInit+  toJSON (NewRepo { newRepoName              = name+                  , newRepoDescription       = description+                  , newRepoHomepage          = homepage+                  , newRepoPrivate           = private+                  , newRepoHasIssues         = hasIssues+                  , newRepoHasProjects       = hasProjects+                  , newRepoHasWiki           = hasWiki+                  , newRepoAutoInit          = autoInit+                  , newRepoGitignoreTemplate = gitignoreTemplate+                  , newRepoLicenseTemplate   = licenseTemplate+                  , newRepoAllowSquashMerge  = allowSquashMerge+                  , newRepoAllowMergeCommit  = allowMergeCommit+                  , newRepoAllowRebaseMerge  = allowRebaseMerge                   }) = object                   [ "name"                .= name                   , "description"         .= description                   , "homepage"            .= homepage                   , "private"             .= private                   , "has_issues"          .= hasIssues+                  , "has_projects"        .= hasProjects                   , "has_wiki"            .= hasWiki                   , "auto_init"           .= autoInit+                  , "gitignore_template"  .= gitignoreTemplate+                  , "license_template"    .= licenseTemplate+                  , "allow_squash_merge"  .= allowSquashMerge+                  , "allow_merge_commit"  .= allowMergeCommit+                  , "allow_rebase_merge"  .= allowRebaseMerge                   ]  instance ToJSON EditRepo where-  toJSON (EditRepo { editName         = name-                   , editDescription  = description-                   , editHomepage     = homepage-                   , editPublic       = public-                   , editHasIssues    = hasIssues-                   , editHasWiki      = hasWiki-                   , editHasDownloads = hasDownloads+  toJSON (EditRepo { editName             = name+                   , editDescription      = description+                   , editHomepage         = homepage+                   , editPrivate          = private+                   , editHasIssues        = hasIssues+                   , editHasProjects      = hasProjects+                   , editHasWiki          = hasWiki+                   , editDefaultBranch    = defaultBranch+                   , editAllowSquashMerge = allowSquashMerge+                   , editAllowMergeCommit = allowMergeCommit+                   , editAllowRebaseMerge = allowRebaseMerge+                   , editArchived         = archived                    }) = object-                   [ "name"          .= name-                   , "description"   .= description-                   , "homepage"      .= homepage-                   , "public"        .= public-                   , "has_issues"    .= hasIssues-                   , "has_wiki"      .= hasWiki-                   , "has_downloads" .= hasDownloads+                   [ "name"               .= name+                   , "description"        .= description+                   , "homepage"           .= homepage+                   , "private"            .= private+                   , "has_issues"         .= hasIssues+                   , "has_projects"       .= hasProjects+                   , "has_wiki"           .= hasWiki+                   , "default_branch"     .= defaultBranch+                   , "allow_squash_merge" .= allowSquashMerge+                   , "allow_merge_commit" .= allowMergeCommit+                   , "allow_rebase_merge" .= allowRebaseMerge+                   , "archived"           .= archived                    ] +instance FromJSON RepoPermissions where+  parseJSON = withObject "RepoPermissions" $ \o -> RepoPermissions+        <$> o .: "admin"+        <*> o .: "push"+        <*> o .: "pull"+ instance FromJSON RepoRef where     parseJSON = withObject "RepoRef" $ \o -> RepoRef         <$> o .: "owner"@@ -242,29 +375,34 @@ instance ToJSON Language where     toJSON = toJSON . getLanguage -#if MIN_VERSION_aeson(1,0,0) instance FromJSONKey Language where     fromJSONKey = fromJSONKeyCoerce-#else-instance FromJSON a => FromJSON (HM.HashMap Language a) where-    parseJSON = fmap mapKeyLanguage . parseJSON-      where-        mapKeyLanguage :: HM.HashMap Text a -> HM.HashMap Language a-#ifdef UNSAFE-        mapKeyLanguage = unsafeCoerce-#else-        mapKeyLanguage = mapKey Language-        mapKey :: (Eq k2, Hashable k2) => (k1 -> k2) -> HM.HashMap k1 a -> HM.HashMap k2 a-        mapKey f = HM.fromList . map (first f) . HM.toList-#endif-#endif  data ArchiveFormat     = ArchiveFormatTarball -- ^ ".tar.gz" format     | ArchiveFormatZipball -- ^ ".zip" format-    deriving (Show, Eq, Ord, Enum, Bounded, Typeable, Data, Generic)+    deriving (Show, Eq, Ord, Enum, Bounded, Data, Generic)  instance IsPathPart ArchiveFormat where     toPathPart af = case af of         ArchiveFormatTarball -> "tarball"         ArchiveFormatZipball -> "zipball"++instance FromJSON CollaboratorPermission where+    parseJSON = withText "CollaboratorPermission" $ \t -> case T.toLower t of+        "admin" -> pure CollaboratorPermissionAdmin+        "write" -> pure CollaboratorPermissionWrite+        "read"  -> pure CollaboratorPermissionRead+        "none"  -> pure CollaboratorPermissionNone+        _       -> fail $ "Unknown CollaboratorPermission: " <> T.unpack t++instance ToJSON CollaboratorPermission where+    toJSON CollaboratorPermissionAdmin = "admin"+    toJSON CollaboratorPermissionWrite = "write"+    toJSON CollaboratorPermissionRead  = "read"+    toJSON CollaboratorPermissionNone  = "none"++instance FromJSON CollaboratorWithPermission where+    parseJSON = withObject "CollaboratorWithPermission" $ \o -> CollaboratorWithPermission+        <$> o .: "user"+        <*> o .: "permission"
src/GitHub/Data/Request.hs view
@@ -1,44 +1,40 @@-{-# LANGUAGE CPP                #-} {-# LANGUAGE FlexibleContexts   #-} {-# LANGUAGE GADTs              #-} {-# LANGUAGE KindSignatures     #-} {-# LANGUAGE StandaloneDeriving #-}--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>---+ module GitHub.Data.Request (     -- * Request-    Request (..),-    SimpleRequest (..),+    Request,+    GenRequest (..),     -- * Smart constructors     query, pagedQuery, command,     -- * Auxiliary types     RW(..),-    StatusMap,-    statusOnlyOk,     CommandMethod(..),     toMethod,     FetchCount(..),+    PageParams(..),+    PageLinks(..),+    MediaType (..),     Paths,     IsPathPart(..),     QueryString,     Count,     ) where -import GitHub.Data.Definitions (Count, QueryString)+import GitHub.Data.Definitions (Count, IssueNumber, QueryString, unIssueNumber) import GitHub.Data.Id          (Id, untagId) import GitHub.Data.Name        (Name, untagName) import GitHub.Internal.Prelude  import qualified Data.ByteString.Lazy      as LBS import qualified Data.Text                 as T-import qualified Network.HTTP.Types        as Types import qualified Network.HTTP.Types.Method as Method-import Network.URI                         (URI)+import Network.URI (URI)+ --------------------------------------------------------------------------------- Auxillary types+-- Path parts ------------------------------------------------------------------------------  type Paths = [Text]@@ -52,43 +48,40 @@ instance IsPathPart (Id a) where     toPathPart = T.pack . show . untagId --- | Http method of requests with body.-data CommandMethod a where-    Post   :: CommandMethod a-    Patch  :: CommandMethod a-    Put    :: CommandMethod a-    Put'   :: CommandMethod ()-    Delete :: CommandMethod ()-    deriving (Typeable)+instance IsPathPart IssueNumber where+    toPathPart = T.pack . show . unIssueNumber -deriving instance Eq (CommandMethod a)-deriving instance Ord (CommandMethod a)+-------------------------------------------------------------------------------+-- Command Method+------------------------------------------------------------------------------- -instance Show (CommandMethod a) where-    showsPrec _ Post    = showString "Post"-    showsPrec _ Patch   = showString "Patch"-    showsPrec _ Put     = showString "Put"-    showsPrec _ Put'     = showString "Put'"-    showsPrec _ Delete  = showString "Delete"+-- | Http method of requests with body.+data CommandMethod+    = Post+    | Patch+    | Put+    | Delete+  deriving (Eq, Ord, Read, Show, Enum, Bounded, Data, Generic) -instance Hashable (CommandMethod a) where-    hashWithSalt salt Post    = hashWithSalt salt (0 :: Int)-    hashWithSalt salt Patch   = hashWithSalt salt (1 :: Int)-    hashWithSalt salt Put     = hashWithSalt salt (2 :: Int)-    hashWithSalt salt Put'    = hashWithSalt salt (3 :: Int)-    hashWithSalt salt Delete  = hashWithSalt salt (4 :: Int)+instance Hashable CommandMethod -toMethod :: CommandMethod a -> Method.Method+toMethod :: CommandMethod -> Method.Method toMethod Post   = Method.methodPost toMethod Patch  = Method.methodPatch toMethod Put    = Method.methodPut-toMethod Put'   = Method.methodPut toMethod Delete = Method.methodDelete +-------------------------------------------------------------------------------+-- Fetch count+-------------------------------------------------------------------------------+ -- | 'PagedQuery' returns just some results, using this data we can specify how -- many pages we want to fetch.-data FetchCount = FetchAtLeast !Word | FetchAll-    deriving (Eq, Ord, Read, Show, Generic, Typeable)+data FetchCount =+    FetchAtLeast !Word+    | FetchAll+    | FetchPage PageParams+    deriving (Eq, Ord, Read, Show, Generic)   -- | This instance is there mostly for 'fromInteger'.@@ -107,19 +100,67 @@  instance Hashable FetchCount instance Binary FetchCount-instance NFData FetchCount where rnf = genericRnf+instance NFData FetchCount +-------------------------------------------------------------------------------+-- PageParams+-------------------------------------------------------------------------------++-- | Params for specifying the precise page and items per page.+data PageParams = PageParams {+    pageParamsPerPage :: Maybe Int+    , pageParamsPage :: Maybe Int+    }+    deriving (Eq, Ord, Read, Show, Generic)++instance Hashable PageParams+instance Binary PageParams+instance NFData PageParams++-------------------------------------------------------------------------------+-- PageLinks+-------------------------------------------------------------------------------++-- | 'PagedQuery' returns just some results, using this data we can specify how+-- many pages we want to fetch.+data PageLinks = PageLinks {+    pageLinksPrev :: Maybe URI+    , pageLinksNext :: Maybe URI+    , pageLinksLast :: Maybe URI+    , pageLinksFirst :: Maybe URI+    }+    deriving (Eq, Ord, Show, Generic)++instance NFData PageLinks++-------------------------------------------------------------------------------+-- MediaType+-------------------------------------------------------------------------------++data MediaType a+    = MtJSON       -- ^ @application/vnd.github.v3+json@+    | MtRaw        -- ^ @application/vnd.github.v3.raw@ <https://developer.github.com/v3/media/#raw-1>+    | MtDiff       -- ^ @application/vnd.github.v3.diff@ <https://developer.github.com/v3/media/#diff>+    | MtPatch      -- ^ @application/vnd.github.v3.patch@ <https://developer.github.com/v3/media/#patch>+    | MtSha        -- ^ @application/vnd.github.v3.sha@ <https://developer.github.com/v3/media/#sha>+    | MtStar       -- ^ @application/vnd.github.v3.star+json@ <https://developer.github.com/v3/activity/starring/#alternative-response-with-star-creation-timestamps-1>+    | MtRedirect   -- ^ <https://developer.github.com/v3/repos/contents/#get-archive-link>+    | MtStatus     -- ^ Parse status+    | MtUnit       -- ^ Always succeeds+    | MtPreview  a -- ^ Some other (preview) type; this is an extension point.+  deriving (Eq, Ord, Read, Show, Data, Generic)+ --------------------------------------------------------------------------------- Github request+-- RW ------------------------------------------------------------------------------  -- | Type used as with @DataKinds@ to tag whether requests need authentication -- or aren't read-only. data RW     = RO  -- ^ /Read-only/, doesn't necessarily requires authentication-    | RA  -- ^ /Read autenticated/+    | RA  -- ^ /Read authenticated/     | RW  -- ^ /Read-write/, requires authentication-  deriving (Eq, Ord, Read, Show, Enum, Bounded, Typeable, Data, Generic)+  deriving (Eq, Ord, Read, Show, Enum, Bounded, Data, Generic)  {- data SRO (rw :: RW) where@@ -132,100 +173,53 @@ instance IReadOnly 'RA        where iro = ROA -} +-------------------------------------------------------------------------------+-- GitHub Request+-------------------------------------------------------------------------------+ -- | Github request data type. ----- * @k@ describes whether authentication is required. It's required for non-@GET@ requests.+-- * @rw@ describes whether authentication is required. It's required for non-@GET@ requests.+-- * @mt@ describes the media type, i.e. how the response should be interpreted. -- * @a@ is the result type -- -- /Note:/ 'Request' is not 'Functor' on purpose.-data Request (k :: RW) a where-    SimpleQuery   :: FromJSON a => SimpleRequest k a -> Request k a-    StatusQuery   :: StatusMap a -> SimpleRequest k () -> Request k a-    HeaderQuery   :: FromJSON a => Types.RequestHeaders -> SimpleRequest k a -> Request k a-    RedirectQuery :: SimpleRequest k () -> Request k URI-  deriving (Typeable)--data SimpleRequest (k :: RW) a where-    Query        :: Paths -> QueryString -> SimpleRequest k a-    PagedQuery   :: Paths -> QueryString -> FetchCount -> SimpleRequest k (Vector a)-    Command      :: CommandMethod a -> Paths -> LBS.ByteString -> SimpleRequest 'RW a-  deriving (Typeable)------------------------------------------------------------------------------------ Status Map--------------------------------------------------------------------------------+data GenRequest (mt :: MediaType *) (rw :: RW) a where+    Query        :: Paths -> QueryString -> GenRequest mt rw a+    PagedQuery   :: (a ~ t b, Foldable t, Semigroup a) => Paths -> QueryString -> FetchCount -> GenRequest mt rw a --- TODO: Change to 'Map' ?-type StatusMap a = [(Int, a)]+    -- | Command+    Command+        :: CommandMethod           -- ^ command+        -> Paths                   -- ^ path+        -> LBS.ByteString          -- ^ body+        -> GenRequest mt 'RW a -statusOnlyOk :: StatusMap Bool-statusOnlyOk =-    [ (204, True)-    , (404, False)-    ]+-- | Most requests ask for @JSON@.+type Request = GenRequest 'MtJSON  ------------------------------------------------------------------------------- -- Smart constructors ------------------------------------------------------------------------------- -query :: FromJSON a => Paths -> QueryString -> Request k a-query ps qs = SimpleQuery (Query ps qs)+query :: Paths -> QueryString -> Request mt a+query ps qs = Query ps qs -pagedQuery :: FromJSON a => Paths -> QueryString -> FetchCount -> Request k (Vector a)-pagedQuery ps qs fc = SimpleQuery (PagedQuery ps qs fc)+pagedQuery :: FromJSON a => Paths -> QueryString -> FetchCount -> Request mt (Vector a)+pagedQuery ps qs fc = PagedQuery ps qs fc -command :: FromJSON a => CommandMethod a -> Paths -> LBS.ByteString -> Request 'RW a-command m ps body = SimpleQuery (Command m ps body)+command :: CommandMethod -> Paths -> LBS.ByteString -> Request 'RW a+command m ps body = Command m ps body  ------------------------------------------------------------------------------- -- Instances ------------------------------------------------------------------------------- -deriving instance Eq a => Eq (Request k a)-deriving instance Eq a => Eq (SimpleRequest k a)--deriving instance Ord a => Ord (Request k a)-deriving instance Ord a => Ord (SimpleRequest k a)--instance Show (SimpleRequest k a) where-    showsPrec d r = showParen (d > appPrec) $ case r of-        Query ps qs -> showString "Query "-            . showsPrec (appPrec + 1) ps-            . showString " "-            . showsPrec (appPrec + 1) qs-        PagedQuery ps qs l -> showString "PagedQuery "-            . showsPrec (appPrec + 1) ps-            . showString " "-            . showsPrec (appPrec + 1) qs-            . showString " "-            . showsPrec (appPrec + 1) l-        Command m ps body -> showString "Command "-            . showsPrec (appPrec + 1) m-            . showString " "-            . showsPrec (appPrec + 1) ps-            . showString " "-            . showsPrec (appPrec + 1) body-      where-        appPrec = 10 :: Int--instance Show (Request k a) where-    showsPrec d r = showParen (d > appPrec) $ case r of-        SimpleQuery req -> showString "SimpleQuery "-            . showsPrec (appPrec + 1) req-        StatusQuery m req -> showString "Status "-            . showsPrec (appPrec + 1) (map fst m) -- !!! printing only keys-            . showString " "-            . showsPrec (appPrec + 1) req-        HeaderQuery m req -> showString "Header "-            . showsPrec (appPrec + 1) m-            . showString " "-            . showsPrec (appPrec + 1) req-        RedirectQuery req -> showString "Redirect "-            . showsPrec (appPrec + 1) req-      where-        appPrec = 10 :: Int+deriving instance Eq (GenRequest rw mt a)+deriving instance Ord (GenRequest rw mt a)+deriving instance Show (GenRequest rw mt a) -instance Hashable (SimpleRequest k a) where+instance Hashable (GenRequest rw mt a) where     hashWithSalt salt (Query ps qs) =         salt `hashWithSalt` (0 :: Int)              `hashWithSalt` ps@@ -241,18 +235,4 @@              `hashWithSalt` ps              `hashWithSalt` body -instance Hashable (Request k a) where-    hashWithSalt salt (SimpleQuery req) =-        salt `hashWithSalt` (0 :: Int)-             `hashWithSalt` req-    hashWithSalt salt (StatusQuery sm req) =-        salt `hashWithSalt` (1 :: Int)-             `hashWithSalt` map fst sm-             `hashWithSalt` req-    hashWithSalt salt (HeaderQuery h req) =-        salt `hashWithSalt` (2 :: Int)-             `hashWithSalt` h-             `hashWithSalt` req-    hashWithSalt salt (RedirectQuery req) =-        salt `hashWithSalt` (3 :: Int)-             `hashWithSalt` req+-- TODO: Binary
src/GitHub/Data/Reviews.hs view
@@ -1,12 +1,13 @@ module GitHub.Data.Reviews where -import Data.Text (Text) import GitHub.Data.Definitions (SimpleUser) import GitHub.Data.Id (Id) import GitHub.Data.URL (URL) import GitHub.Internal.Prelude import Prelude () +import qualified Data.Text as T+ data ReviewState     = ReviewStatePending     | ReviewStateApproved@@ -15,44 +16,41 @@     | ReviewStateChangesRequested     deriving (Show, Enum, Bounded, Eq, Ord, Generic) -instance NFData ReviewState where-    rnf = genericRnf-+instance NFData ReviewState instance Binary ReviewState  instance FromJSON ReviewState where-    parseJSON (String "APPROVED") = pure ReviewStateApproved-    parseJSON (String "PENDING") = pure ReviewStatePending-    parseJSON (String "DISMISSED") = pure ReviewStateDismissed-    parseJSON (String "COMMENTED") = pure ReviewStateCommented-    parseJSON (String "CHANGES_REQUESTED") = pure ReviewStateChangesRequested-    parseJSON _ = fail "Unexpected ReviewState"+    parseJSON = withText "ReviewState" $ \t -> case T.toLower t of+        "approved"          -> pure ReviewStateApproved+        "pending"           -> pure ReviewStatePending+        "dismissed"         -> pure ReviewStateDismissed+        "commented"         -> pure ReviewStateCommented+        "changes_requested" -> pure ReviewStateChangesRequested+        _                   -> fail $ "Unknown ReviewState: " <> T.unpack t  data Review = Review     { reviewBody :: !Text     , reviewCommitId :: !Text     , reviewState :: ReviewState-    , reviewSubmittedAt :: !UTCTime+    , reviewSubmittedAt :: !(Maybe UTCTime)     , reviewPullRequestUrl :: !URL     , reviewHtmlUrl :: !Text     , reviewUser :: !SimpleUser     , reviewId :: !(Id Review)     } deriving (Show, Generic) -instance NFData Review where-    rnf = genericRnf-+instance NFData Review instance Binary Review  instance FromJSON Review where     parseJSON =         withObject "Review" $ \o ->             Review <$> o .: "body" <*> o .: "commit_id" <*> o .: "state" <*>-            o .: "submitted_at" <*>-            o .: "pull_request_url" <*>-            o .: "html_url" <*>-            o .: "user" <*>-            o .: "id"+            o .:? "submitted_at" <*>+            o .:  "pull_request_url" <*>+            o .:  "html_url" <*>+            o .:  "user" <*>+            o .:  "id"  data ReviewComment = ReviewComment     { reviewCommentId :: !(Id ReviewComment)@@ -72,9 +70,7 @@     , reviewCommentPullRequestUrl :: !URL     } deriving (Show, Generic) -instance NFData ReviewComment where-    rnf = genericRnf-+instance NFData ReviewComment instance Binary ReviewComment  instance FromJSON ReviewComment where
src/GitHub/Data/Search.hs view
@@ -1,31 +1,34 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Search where -import GitHub.Data.Repos       (Repo)+import GitHub.Data.Repos       (CodeSearchRepo) import GitHub.Data.URL         (URL) import GitHub.Internal.Prelude import Prelude ()  import qualified Data.Vector as V -data SearchResult entity = SearchResult+data SearchResult' entities = SearchResult     { searchResultTotalCount :: !Int-    , searchResultResults    :: !(Vector entity)+    , searchResultResults    :: !entities     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData entity => NFData (SearchResult entity) where rnf = genericRnf-instance Binary entity => Binary (SearchResult entity)+type SearchResult entity = SearchResult' (V.Vector entity) -instance FromJSON entity => FromJSON (SearchResult entity) where+instance NFData entities => NFData (SearchResult' entities)+instance Binary entities => Binary (SearchResult' entities)++instance (Monoid entities, FromJSON entities) => FromJSON (SearchResult' entities) where     parseJSON = withObject "SearchResult" $ \o -> SearchResult         <$> o .: "total_count"-        <*> o .:? "items" .!= V.empty+        <*> o .:? "items" .!= mempty +instance Semigroup res => Semigroup (SearchResult' res) where+    (SearchResult count res) <> (SearchResult count' res') = SearchResult (max count count') (res <> res')++instance Foldable SearchResult' where+    foldMap f (SearchResult _count results) = f results+ data Code = Code     { codeName    :: !Text     , codePath    :: !Text@@ -33,11 +36,11 @@     , codeUrl     :: !URL     , codeGitUrl  :: !URL     , codeHtmlUrl :: !URL-    , codeRepo    :: !Repo+    , codeRepo    :: !CodeSearchRepo     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData Code where rnf = genericRnf+instance NFData Code instance Binary Code  instance FromJSON Code where
src/GitHub/Data/Statuses.hs view
@@ -1,7 +1,5 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveGeneric      #-} {-# LANGUAGE NoImplicitPrelude  #-}-{-# LANGUAGE OverloadedStrings  #-}+ module GitHub.Data.Statuses where  import GitHub.Data.Definitions@@ -14,23 +12,25 @@ import GitHub.Data.GitData (Commit) import GitHub.Data.Repos   (RepoRef) +import qualified Data.Text as T  data StatusState     = StatusPending     | StatusSuccess     | StatusError     | StatusFailure-  deriving (Show, Data, Enum, Bounded, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Enum, Bounded, Eq, Ord, Generic) -instance NFData StatusState where rnf = genericRnf+instance NFData StatusState instance Binary StatusState  instance FromJSON StatusState where-  parseJSON (String "pending") = pure StatusPending-  parseJSON (String "success") = pure StatusSuccess-  parseJSON (String "error")   = pure StatusError-  parseJSON (String "failure") = pure StatusFailure-  parseJSON _ = fail "Could not build a StatusState"+    parseJSON = withText "StatusState" $ \t -> case T.toLower t of+        "pending" -> pure StatusPending+        "success" -> pure StatusSuccess+        "error"   -> pure StatusError+        "failure" -> pure StatusFailure+        _         -> fail $ "Unknown StatusState: " <> T.unpack t  instance ToJSON StatusState where   toJSON StatusPending = String "pending"@@ -50,7 +50,7 @@     , statusContext     :: !(Maybe Text)     , statusCreator     :: !(Maybe SimpleUser)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic)  instance FromJSON Status where   parseJSON = withObject "Status" $ \o -> Status@@ -71,9 +71,9 @@     , newStatusDescription :: !(Maybe Text)     , newStatusContext     :: !(Maybe Text)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData NewStatus where rnf = genericRnf+instance NFData NewStatus instance Binary NewStatus  instance ToJSON NewStatus where@@ -97,7 +97,7 @@     , combinedStatusCommitUrl  :: !URL     , combinedStatusUrl        :: !URL     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic)  instance FromJSON CombinedStatus where     parseJSON = withObject "CombinedStatus" $ \o -> CombinedStatus
src/GitHub/Data/Teams.hs view
@@ -1,12 +1,5 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveGeneric      #-} {-# LANGUAGE NoImplicitPrelude  #-}-{-# LANGUAGE OverloadedStrings  #-}--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>---+ module GitHub.Data.Teams where  import GitHub.Data.Definitions@@ -17,29 +10,31 @@ import GitHub.Internal.Prelude import Prelude () +import qualified Data.Text as T+ data Privacy     = PrivacyClosed     | PrivacySecret-    deriving (Show, Data, Enum, Bounded, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Enum, Bounded, Eq, Ord, Generic) -instance NFData Privacy where rnf = genericRnf+instance NFData Privacy instance Binary Privacy  data Permission     = PermissionPull     | PermissionPush     | PermissionAdmin-    deriving (Show, Data, Enum, Bounded, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Enum, Bounded, Eq, Ord, Generic) -instance NFData Permission where rnf = genericRnf+instance NFData Permission instance Binary Permission  data AddTeamRepoPermission = AddTeamRepoPermission     { addTeamRepoPermission :: !Permission     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData AddTeamRepoPermission where rnf = genericRnf+instance NFData AddTeamRepoPermission instance Binary AddTeamRepoPermission  data SimpleTeam = SimpleTeam@@ -48,14 +43,14 @@     , simpleTeamName            :: !Text  -- TODO (0.15.0): unify this and 'simpleTeamSlug' as in 'Team'.     , simpleTeamSlug            :: !(Name Team)     , simpleTeamDescription     :: !(Maybe Text)-    , simpleTeamPrivacy         :: !(Maybe Privacy)+    , simpleTeamPrivacy         :: !Privacy     , simpleTeamPermission      :: !Permission     , simpleTeamMembersUrl      :: !URL     , simpleTeamRepositoriesUrl :: !URL     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData SimpleTeam where rnf = genericRnf+instance NFData SimpleTeam instance Binary SimpleTeam  data Team = Team@@ -64,7 +59,7 @@     , teamName            :: !Text     , teamSlug            :: !(Name Team)     , teamDescription     :: !(Maybe Text)-    , teamPrivacy         :: !(Maybe Privacy)+    , teamPrivacy         :: !Privacy     , teamPermission      :: !Permission     , teamMembersUrl      :: !URL     , teamRepositoriesUrl :: !URL@@ -72,38 +67,38 @@     , teamReposCount      :: !Int     , teamOrganization    :: !SimpleOrganization     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData Team where rnf = genericRnf+instance NFData Team instance Binary Team  data CreateTeam = CreateTeam     { createTeamName        :: !(Name Team)     , createTeamDescription :: !(Maybe Text)     , createTeamRepoNames   :: !(Vector (Name Repo))-    -- , createTeamPrivacy    :: Privacy-    , createTeamPermission  :: Permission+    , createTeamPrivacy     :: !Privacy+    , createTeamPermission  :: !Permission     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData CreateTeam where rnf = genericRnf+instance NFData CreateTeam instance Binary CreateTeam  data EditTeam = EditTeam     { editTeamName        :: !(Name Team)     , editTeamDescription :: !(Maybe Text)-    -- , editTeamPrivacy :: Privacy-    , editTeamPermission  :: !Permission+    , editTeamPrivacy     :: !(Maybe Privacy)+    , editTeamPermission  :: !(Maybe Permission)     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData EditTeam where rnf = genericRnf+instance NFData EditTeam instance Binary  EditTeam  data Role     = RoleMaintainer     | RoleMember-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic)  instance NFData Role instance Binary Role@@ -111,9 +106,9 @@ data ReqState     = StatePending     | StateActive-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData ReqState where rnf = genericRnf+instance NFData ReqState instance Binary ReqState  data TeamMembership = TeamMembership@@ -121,16 +116,16 @@     , teamMembershipRole     :: !Role     , teamMembershipReqState :: !ReqState     }-    deriving (Show, Data, Typeable, Eq, Ord, Generic)+    deriving (Show, Data, Eq, Ord, Generic) -instance NFData TeamMembership where rnf = genericRnf+instance NFData TeamMembership instance Binary TeamMembership  data CreateTeamMembership = CreateTeamMembership {   createTeamMembershipRole :: !Role-} deriving (Show, Data, Typeable, Eq, Ord, Generic)+} deriving (Show, Data, Eq, Ord, Generic) -instance NFData CreateTeamMembership where rnf = genericRnf+instance NFData CreateTeamMembership instance Binary CreateTeamMembership  -- JSON Instances@@ -142,7 +137,7 @@         <*> o .: "name"         <*> o .: "slug"         <*> o .:?"description" .!= Nothing-        <*> o .:?"privacy" .!= Nothing+        <*> o .: "privacy"         <*> o .: "permission"         <*> o .: "members_url"         <*> o .: "repositories_url"@@ -154,7 +149,7 @@         <*> o .: "name"         <*> o .: "slug"         <*> o .:?"description" .!= Nothing-        <*> o .:?"privacy" .!= Nothing+        <*> o .: "privacy"         <*> o .: "permission"         <*> o .: "members_url"         <*> o .: "repositories_url"@@ -163,19 +158,29 @@         <*> o .: "organization"  instance ToJSON CreateTeam where-  toJSON (CreateTeam name desc repo_names {-privacy-} permissions) =-    object [ "name"        .= name-           , "description" .= desc-           , "repo_names"  .= repo_names-           {-, "privacy" .= privacy-}-           , "permissions" .= permissions ]+    toJSON (CreateTeam name desc repo_names privacy permission) =+        object $ filter notNull+            [ "name"        .= name+            , "description" .= desc+            , "repo_names"  .= repo_names+            , "privacy"     .= privacy+            , "permission"  .= permission+            ]+      where+        notNull (_, Null) = False+        notNull (_, _) = True  instance ToJSON EditTeam where-  toJSON (EditTeam name desc {-privacy-} permissions) =-    object [ "name"        .= name-           , "description" .= desc-           {-, "privacy" .= privacy-}-           , "permissions" .= permissions ]+    toJSON (EditTeam name desc privacy permission) =+        object $ filter notNull+            [ "name"        .= name+            , "description" .= desc+            , "privacy"     .= privacy+            , "permission"  .= permission+            ]+      where+        notNull (_, Null) = False+        notNull (_, _) = True  instance FromJSON TeamMembership where     parseJSON = withObject "TeamMembership" $ \o -> TeamMembership@@ -200,42 +205,42 @@         object [ "permission" .= permission ]  instance FromJSON Role where-    parseJSON = withText "Attribute" $ \attr -> case attr of-        "maintainer" -> return RoleMaintainer-        "member"     -> return RoleMember-        _            -> fail $ "Unknown Role: " ++ show attr+    parseJSON = withText "Role" $ \t -> case T.toLower t of+        "maintainer" -> pure RoleMaintainer+        "member"     -> pure RoleMember+        _            -> fail $ "Unknown Role: " <> T.unpack t  instance ToJSON Role where     toJSON RoleMaintainer = String "maintainer"     toJSON RoleMember     = String "member" +instance FromJSON Permission where+    parseJSON = withText "Permission" $ \t -> case T.toLower t of+        "pull"  -> pure PermissionPull+        "push"  -> pure PermissionPush+        "admin" -> pure PermissionAdmin+        _       -> fail $ "Unknown Permission: " <> T.unpack t+ instance ToJSON Permission where     toJSON PermissionPull  = "pull"     toJSON PermissionPush  = "push"     toJSON PermissionAdmin = "admin" -instance FromJSON Permission where-    parseJSON = withText "Permission Attribute" $ \attr -> case attr of -        "pull"  -> return PermissionPull-        "push"  -> return PermissionPush-        "admin" -> return PermissionAdmin-        _       -> fail $ "Unknown Permission Attribute: " ++ show attr- instance FromJSON Privacy where-    parseJSON  = withText "Privacy Attribute" $ \attr -> case attr of-        "secret" -> return PrivacySecret-        "closed" -> return PrivacyClosed-        _        -> fail $ "Unknown Privacy Attribute: " ++ show attr+    parseJSON = withText "Privacy" $ \t -> case T.toLower t of+        "secret" -> pure PrivacySecret+        "closed" -> pure PrivacyClosed+        _        -> fail $ "Unknown Privacy: " <> T.unpack t  instance ToJSON Privacy where     toJSON PrivacySecret = String "secret"     toJSON PrivacyClosed = String "closed"  instance FromJSON ReqState where-    parseJSON = withText "ReqState" $ \attr -> case attr of-        "active"  -> return StateActive-        "pending" -> return StatePending-        _         -> fail $ "Unknown ReqState: " ++ show attr+    parseJSON = withText "ReqState" $ \t -> case T.toLower t of+        "active"  -> pure StateActive+        "pending" -> pure StatePending+        _         -> fail $ "Unknown ReqState: " <> T.unpack t  instance ToJSON ReqState where     toJSON StateActive  = String "active"@@ -246,4 +251,4 @@     = TeamMemberRoleAll         -- ^ all members of the team.     | TeamMemberRoleMaintainer  -- ^ team maintainers     | TeamMemberRoleMember      -- ^ normal members of the team.-    deriving (Show, Eq, Ord, Enum, Bounded, Typeable, Data, Generic)+    deriving (Show, Eq, Ord, Enum, Bounded, Data, Generic)
src/GitHub/Data/URL.hs view
@@ -1,8 +1,3 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.URL (     URL(..),     getUrl,@@ -15,12 +10,12 @@ -- -- /N.B./ syntactical validity is not verified. newtype URL = URL Text-    deriving (Eq, Ord, Show, Generic, Typeable, Data)+    deriving (Eq, Ord, Show, Generic, Data)  getUrl :: URL -> Text getUrl (URL url) = url -instance NFData URL where rnf = genericRnf+instance NFData URL instance Binary URL  instance ToJSON URL where
src/GitHub/Data/Webhooks.hs view
@@ -1,8 +1,3 @@--------------------------------------------------------------------------------- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- module GitHub.Data.Webhooks where  import GitHub.Data.Id          (Id)@@ -11,6 +6,7 @@ import Prelude ()  import qualified Data.Map as M+import qualified Data.Text as T  data RepoWebhook = RepoWebhook     { repoWebhookUrl          :: !URL@@ -24,46 +20,84 @@     , repoWebhookUpdatedAt    :: !UTCTime     , repoWebhookCreatedAt    :: !UTCTime     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData RepoWebhook where rnf = genericRnf+instance NFData RepoWebhook instance Binary RepoWebhook +-- | See <https://developer.github.com/webhooks/#events>. data RepoWebhookEvent     = WebhookWildcardEvent+    | WebhookCheckRunEvent+    | WebhookCheckSuiteEvent+    | WebhookCodeScanningAlert     | WebhookCommitCommentEvent+    | WebhookContentReferenceEvent     | WebhookCreateEvent     | WebhookDeleteEvent+    | WebhookDeployKeyEvent     | WebhookDeploymentEvent     | WebhookDeploymentStatusEvent+    | WebhookDiscussion+    | WebhookDiscussionComment+    | WebhookDownloadEvent+    | WebhookFollowEvent     | WebhookForkEvent+    | WebhookGistEvent+    | WebhookGitHubAppAuthorizationEvent     | WebhookGollumEvent+    | WebhookInstallationEvent+    | WebhookInstallationRepositoriesEvent     | WebhookIssueCommentEvent     | WebhookIssuesEvent+    | WebhookLabelEvent+    | WebhookMarketplacePurchaseEvent     | WebhookMemberEvent+    | WebhookMembershipEvent+    | WebhookMetaEvent+    | WebhookMilestoneEvent+    | WebhookOrgBlockEvent+    | WebhookOrganizationEvent+    | WebhookPackage     | WebhookPageBuildEvent     | WebhookPingEvent+    | WebhookProjectCardEvent+    | WebhookProjectColumnEvent+    | WebhookProjectEvent     | WebhookPublicEvent-    | WebhookPullRequestReviewCommentEvent     | WebhookPullRequestEvent+    | WebhookPullRequestReviewCommentEvent+    | WebhookPullRequestReviewEvent     | WebhookPushEvent+    | WebhookRegistryPackageEvent     | WebhookReleaseEvent+    | WebhookRepositoryDispatch+    | WebhookRepositoryEvent+    | WebhookRepositoryImportEvent+    | WebhookRepositoryVulnerabilityAlertEvent+    | WebhookSecretScanningAlert+    | WebhookSecurityAdvisoryEvent+    | WebhookSponsorship+    | WebhookStarEvent     | WebhookStatusEvent     | WebhookTeamAddEvent+    | WebhookTeamEvent     | WebhookWatchEvent-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+    | WebhookWorkflowDispatch+    | WebhookWorkflowRun+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData RepoWebhookEvent where rnf = genericRnf+instance NFData RepoWebhookEvent instance Binary RepoWebhookEvent  data RepoWebhookResponse = RepoWebhookResponse     { repoWebhookResponseCode    :: !(Maybe Int)-    , repoWebhookResponseStatus  :: !Text+    , repoWebhookResponseStatus  :: !(Maybe Text)     , repoWebhookResponseMessage :: !(Maybe Text)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData RepoWebhookResponse where rnf = genericRnf+instance NFData RepoWebhookResponse instance Binary RepoWebhookResponse  data PingEvent = PingEvent@@ -71,9 +105,9 @@     , pingEventHook   :: !RepoWebhook     , pingEventHookId :: !(Id RepoWebhook)     }-  deriving (Show, Data, Typeable, Eq, Ord, Generic)+  deriving (Show, Data, Eq, Ord, Generic) -instance NFData PingEvent where rnf = genericRnf+instance NFData PingEvent instance Binary PingEvent  data NewRepoWebhook = NewRepoWebhook@@ -82,9 +116,9 @@     , newRepoWebhookEvents :: !(Maybe (Vector RepoWebhookEvent))     , newRepoWebhookActive :: !(Maybe Bool)     }-  deriving (Eq, Ord, Show, Typeable, Data, Generic)+  deriving (Eq, Ord, Show, Data, Generic) -instance NFData NewRepoWebhook where rnf = genericRnf+instance NFData NewRepoWebhook instance Binary NewRepoWebhook  data EditRepoWebhook = EditRepoWebhook@@ -94,59 +128,134 @@     , editRepoWebhookRemoveEvents :: !(Maybe (Vector RepoWebhookEvent))     , editRepoWebhookActive       :: !(Maybe Bool)     }-  deriving (Eq, Ord, Show, Typeable, Data, Generic)+  deriving (Eq, Ord, Show, Data, Generic) -instance NFData EditRepoWebhook where rnf = genericRnf+instance NFData EditRepoWebhook instance Binary EditRepoWebhook  -- JSON instances  instance FromJSON RepoWebhookEvent where-    parseJSON (String "*") = pure WebhookWildcardEvent-    parseJSON (String "commit_comment") = pure WebhookCommitCommentEvent-    parseJSON (String "create") = pure WebhookCreateEvent-    parseJSON (String "delete") = pure WebhookDeleteEvent-    parseJSON (String "deployment") = pure WebhookDeploymentEvent-    parseJSON (String "deployment_status") = pure WebhookDeploymentStatusEvent-    parseJSON (String "fork") = pure WebhookForkEvent-    parseJSON (String "gollum") = pure WebhookGollumEvent-    parseJSON (String "issue_comment") = pure WebhookIssueCommentEvent-    parseJSON (String "issues") = pure WebhookIssuesEvent-    parseJSON (String "member") = pure WebhookMemberEvent-    parseJSON (String "page_build") = pure WebhookPageBuildEvent-    parseJSON (String "ping") = pure WebhookPingEvent-    parseJSON (String "public") = pure WebhookPublicEvent-    parseJSON (String "pull_request_review_comment") = pure WebhookPullRequestReviewCommentEvent-    parseJSON (String "pull_request") = pure WebhookPullRequestEvent-    parseJSON (String "push") = pure WebhookPushEvent-    parseJSON (String "release") = pure WebhookReleaseEvent-    parseJSON (String "status") = pure WebhookStatusEvent-    parseJSON (String "team_add") = pure WebhookTeamAddEvent-    parseJSON (String "watch") = pure WebhookWatchEvent-    parseJSON _ = fail "Could not build a Webhook event"+    parseJSON = withText "RepoWebhookEvent" $ \t -> case T.toLower t of+        "*"                              -> pure WebhookWildcardEvent+        "check_run"                      -> pure WebhookCheckRunEvent+        "check_suite"                    -> pure WebhookCheckSuiteEvent+        "code_scanning_alert"            -> pure WebhookCodeScanningAlert+        "commit_comment"                 -> pure WebhookCommitCommentEvent+        "content_reference"              -> pure WebhookContentReferenceEvent+        "create"                         -> pure WebhookCreateEvent+        "delete"                         -> pure WebhookDeleteEvent+        "deploy_key"                     -> pure WebhookDeployKeyEvent+        "deployment"                     -> pure WebhookDeploymentEvent+        "deployment_status"              -> pure WebhookDeploymentStatusEvent+        "discussion"                     -> pure WebhookDiscussion+        "discussion_comment"             -> pure WebhookDiscussionComment+        "download"                       -> pure WebhookDownloadEvent+        "follow"                         -> pure WebhookFollowEvent+        "fork"                           -> pure WebhookForkEvent+        "gist"                           -> pure WebhookGistEvent+        "github_app_authorization"       -> pure WebhookGitHubAppAuthorizationEvent+        "gollum"                         -> pure WebhookGollumEvent+        "installation"                   -> pure WebhookInstallationEvent+        "installation_repositories"      -> pure WebhookInstallationRepositoriesEvent+        "issue_comment"                  -> pure WebhookIssueCommentEvent+        "issues"                         -> pure WebhookIssuesEvent+        "label"                          -> pure WebhookLabelEvent+        "marketplace_purchase"           -> pure WebhookMarketplacePurchaseEvent+        "member"                         -> pure WebhookMemberEvent+        "membership"                     -> pure WebhookMembershipEvent+        "meta"                           -> pure WebhookMetaEvent+        "milestone"                      -> pure WebhookMilestoneEvent+        "org_block"                      -> pure WebhookOrgBlockEvent+        "organization"                   -> pure WebhookOrganizationEvent+        "package"                        -> pure WebhookPackage+        "page_build"                     -> pure WebhookPageBuildEvent+        "ping"                           -> pure WebhookPingEvent+        "project"                        -> pure WebhookProjectEvent+        "project_card"                   -> pure WebhookProjectCardEvent+        "project_column"                 -> pure WebhookProjectColumnEvent+        "public"                         -> pure WebhookPublicEvent+        "pull_request"                   -> pure WebhookPullRequestEvent+        "pull_request_review"            -> pure WebhookPullRequestReviewEvent+        "pull_request_review_comment"    -> pure WebhookPullRequestReviewCommentEvent+        "push"                           -> pure WebhookPushEvent+        "registry_package"               -> pure WebhookRegistryPackageEvent+        "release"                        -> pure WebhookReleaseEvent+        "repository"                     -> pure WebhookRepositoryEvent+        "repository_dispatch"            -> pure WebhookRepositoryDispatch+        "repository_import"              -> pure WebhookRepositoryImportEvent+        "repository_vulnerability_alert" -> pure WebhookRepositoryVulnerabilityAlertEvent+        "secret_scanning_alert"          -> pure WebhookSecretScanningAlert+        "security_advisory"              -> pure WebhookSecurityAdvisoryEvent+        "sponsorship"                    -> pure WebhookSponsorship+        "star"                           -> pure WebhookStarEvent+        "status"                         -> pure WebhookStatusEvent+        "team"                           -> pure WebhookTeamEvent+        "team_add"                       -> pure WebhookTeamAddEvent+        "watch"                          -> pure WebhookWatchEvent+        "workflow_dispatch"              -> pure WebhookWorkflowDispatch+        "workflow_run"                   -> pure WebhookWorkflowRun+        _                                -> fail $ "Unknown RepoWebhookEvent: " <> T.unpack t  instance ToJSON RepoWebhookEvent where-    toJSON WebhookWildcardEvent                 = String "*"-    toJSON WebhookCommitCommentEvent            = String "commit_comment"-    toJSON WebhookCreateEvent                   = String "create"-    toJSON WebhookDeleteEvent                   = String "delete"-    toJSON WebhookDeploymentEvent               = String "deployment"-    toJSON WebhookDeploymentStatusEvent         = String "deployment_status"-    toJSON WebhookForkEvent                     = String "fork"-    toJSON WebhookGollumEvent                   = String "gollum"-    toJSON WebhookIssueCommentEvent             = String "issue_comment"-    toJSON WebhookIssuesEvent                   = String "issues"-    toJSON WebhookMemberEvent                   = String "member"-    toJSON WebhookPageBuildEvent                = String "page_build"-    toJSON WebhookPingEvent                     = String "ping"-    toJSON WebhookPublicEvent                   = String "public"-    toJSON WebhookPullRequestReviewCommentEvent = String "pull_request_review_comment"-    toJSON WebhookPullRequestEvent              = String "pull_request"-    toJSON WebhookPushEvent                     = String "push"-    toJSON WebhookReleaseEvent                  = String "release"-    toJSON WebhookStatusEvent                   = String "status"-    toJSON WebhookTeamAddEvent                  = String "team_add"-    toJSON WebhookWatchEvent                    = String "watch"+    toJSON WebhookWildcardEvent                     = String "*"+    toJSON WebhookCheckRunEvent                     = String "check_run"+    toJSON WebhookCheckSuiteEvent                   = String "check_suite"+    toJSON WebhookCodeScanningAlert                 = String "code_scanning_alert"+    toJSON WebhookCommitCommentEvent                = String "commit_comment"+    toJSON WebhookContentReferenceEvent             = String "content_reference"+    toJSON WebhookCreateEvent                       = String "create"+    toJSON WebhookDeleteEvent                       = String "delete"+    toJSON WebhookDeployKeyEvent                    = String "deploy_key"+    toJSON WebhookDeploymentEvent                   = String "deployment"+    toJSON WebhookDeploymentStatusEvent             = String "deployment_status"+    toJSON WebhookDiscussion                        = String "discussion"+    toJSON WebhookDiscussionComment                 = String "discussion_comment"+    toJSON WebhookDownloadEvent                     = String "download"+    toJSON WebhookFollowEvent                       = String "follow"+    toJSON WebhookForkEvent                         = String "fork"+    toJSON WebhookGistEvent                         = String "gist"+    toJSON WebhookGitHubAppAuthorizationEvent       = String "github_app_authorization"+    toJSON WebhookGollumEvent                       = String "gollum"+    toJSON WebhookInstallationEvent                 = String "installation"+    toJSON WebhookInstallationRepositoriesEvent     = String "installation_repositories"+    toJSON WebhookIssueCommentEvent                 = String "issue_comment"+    toJSON WebhookIssuesEvent                       = String "issues"+    toJSON WebhookLabelEvent                        = String "label"+    toJSON WebhookMarketplacePurchaseEvent          = String "marketplace_purchase"+    toJSON WebhookMemberEvent                       = String "member"+    toJSON WebhookMembershipEvent                   = String "membership"+    toJSON WebhookMetaEvent                         = String "meta"+    toJSON WebhookMilestoneEvent                    = String "milestone"+    toJSON WebhookOrgBlockEvent                     = String "org_block"+    toJSON WebhookOrganizationEvent                 = String "organization"+    toJSON WebhookPackage                           = String "package"+    toJSON WebhookPageBuildEvent                    = String "page_build"+    toJSON WebhookPingEvent                         = String "ping"+    toJSON WebhookProjectCardEvent                  = String "project_card"+    toJSON WebhookProjectColumnEvent                = String "project_column"+    toJSON WebhookProjectEvent                      = String "project"+    toJSON WebhookPublicEvent                       = String "public"+    toJSON WebhookPullRequestEvent                  = String "pull_request"+    toJSON WebhookPullRequestReviewCommentEvent     = String "pull_request_review_comment"+    toJSON WebhookPullRequestReviewEvent            = String "pull_request_review"+    toJSON WebhookPushEvent                         = String "push"+    toJSON WebhookRegistryPackageEvent              = String "registry_package"+    toJSON WebhookReleaseEvent                      = String "release"+    toJSON WebhookRepositoryDispatch                = String "repository_dispatch"+    toJSON WebhookRepositoryEvent                   = String "repository"+    toJSON WebhookRepositoryImportEvent             = String "repository_import"+    toJSON WebhookRepositoryVulnerabilityAlertEvent = String "repository_vulnerability_alert"+    toJSON WebhookSecretScanningAlert               = String "secret_scanning_alert"+    toJSON WebhookSecurityAdvisoryEvent             = String "security_advisory"+    toJSON WebhookSponsorship                       = String "sponsorship"+    toJSON WebhookStarEvent                         = String "star"+    toJSON WebhookStatusEvent                       = String "status"+    toJSON WebhookTeamAddEvent                      = String "team_add"+    toJSON WebhookTeamEvent                         = String "team"+    toJSON WebhookWatchEvent                        = String "watch"+    toJSON WebhookWorkflowDispatch                  = String "workflow_dispatch"+    toJSON WebhookWorkflowRun                       = String "workflow_run"  instance FromJSON RepoWebhook where     parseJSON = withObject "RepoWebhook" $ \o -> RepoWebhook@@ -164,8 +273,8 @@ instance FromJSON RepoWebhookResponse where     parseJSON = withObject "RepoWebhookResponse" $ \o -> RepoWebhookResponse         <$> o .: "code"-        <*> o .: "status"-        <*> o .: "message"+        <*> o .:? "status"+        <*> o .:? "message"  instance ToJSON NewRepoWebhook where   toJSON (NewRepoWebhook { newRepoWebhookName = name
src/GitHub/Data/Webhooks/Validate.hs view
@@ -1,10 +1,7 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- Verification of incomming webhook payloads, as described at -- <https://developer.github.com/webhooks/securing/>+ module GitHub.Data.Webhooks.Validate (   isValidPayload ) where@@ -12,9 +9,8 @@ import GitHub.Internal.Prelude import Prelude () -import Crypto.Hash     (HMAC, SHA1, hmac, hmacGetDigest)-import Data.Byteable   (constEqBytes, toBytes)-import Data.ByteString (ByteString)+import Crypto.Hash.SHA1 (hmac)+import Data.ByteString  (ByteString)  import qualified Data.ByteString.Base16 as Hex import qualified Data.Text.Encoding     as TE@@ -30,10 +26,9 @@                     -- including the 'sha1=...' prefix   -> ByteString     -- ^ the body   -> Bool-isValidPayload secret shaOpt payload = maybe False (constEqBytes sign) shaOptBS+isValidPayload secret shaOpt payload = maybe False (sign ==) shaOptBS   where     shaOptBS = TE.encodeUtf8 <$> shaOpt-    hexDigest = Hex.encode . toBytes . hmacGetDigest--    hm = hmac (TE.encodeUtf8 secret) payload :: HMAC SHA1+    hexDigest = Hex.encode+    hm = hmac (TE.encodeUtf8 secret) payload     sign = "sha1=" <> hexDigest hm
+ src/GitHub/Endpoints/Actions/Artifacts.hs view
@@ -0,0 +1,61 @@+-- |+-- The actions API as documented at+-- <https://docs.github.com/en/rest/reference/actions>.++module GitHub.Endpoints.Actions.Artifacts (+    artifactsForR,+    artifactR,+    deleteArtifactR,+    downloadArtifactR,+    artifactsForWorkflowRunR,+    module GitHub.Data+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Network.URI             (URI)+import Prelude ()++-- | List artifacts for repository.+-- See <https://docs.github.com/en/rest/reference/actions#list-artifacts-for-a-repository>+artifactsForR+    :: Name Owner+    -> Name Repo+    -> ArtifactMod+    -> FetchCount+    -> Request 'RA (WithTotalCount Artifact)+artifactsForR user repo opts = PagedQuery+    ["repos", toPathPart user, toPathPart repo, "actions", "artifacts"]+    (artifactModToQueryString opts)++-- | Get an artifact.+-- See <https://docs.github.com/en/rest/reference/actions#get-an-artifact>+artifactR :: Name Owner -> Name Repo -> Id Artifact -> Request 'RA Artifact+artifactR user repo artid =+    query ["repos", toPathPart user, toPathPart repo, "actions", "artifacts", toPathPart artid] []++-- | Delete an artifact.+-- See <https://docs.github.com/en/rest/reference/actions#delete-an-artifact>+deleteArtifactR :: Name Owner -> Name Repo -> Id Comment -> GenRequest 'MtUnit 'RW ()+deleteArtifactR user repo artid =+    Command Delete parts mempty+  where+    parts = ["repos", toPathPart user, toPathPart repo, "actions", "artifacts", toPathPart artid]++-- | Download an artifact.+-- See <https://docs.github.com/en/rest/reference/actions#download-an-artifact>+downloadArtifactR :: Name Owner -> Name Repo -> Id Artifact -> GenRequest 'MtRedirect 'RW URI+downloadArtifactR user repo artid =+    Query ["repos", toPathPart user, toPathPart repo, "actions", "artifacts", toPathPart artid, "zip"] []++-- | List artifacts for a workflow run.+-- See <https://docs.github.com/en/rest/reference/actions#list-workflow-run-artifacts>+artifactsForWorkflowRunR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> FetchCount+    -> Request 'RA (WithTotalCount Artifact)+artifactsForWorkflowRunR user repo runid  = PagedQuery+    ["repos", toPathPart user, toPathPart repo, "actions", "runs", toPathPart runid, "artifacts"]+    []
+ src/GitHub/Endpoints/Actions/Cache.hs view
@@ -0,0 +1,66 @@+-- |+-- The actions API as documented at+-- <https://docs.github.com/en/rest/reference/actions>.++module GitHub.Endpoints.Actions.Cache (+    cacheUsageOrganizationR,+    cacheUsageByRepositoryR,+    cacheUsageR,+    cachesForRepoR,+    deleteCacheR,+    module GitHub.Data+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | Get Actions cache usage for the organization.+-- See <https://docs.github.com/en/rest/actions/cache#get-github-actions-cache-usage-for-an-organization>+cacheUsageOrganizationR+    :: Name Organization+    -> GenRequest 'MtJSON 'RA OrganizationCacheUsage+cacheUsageOrganizationR org =+    Query ["orgs", toPathPart org, "actions", "cache", "usage"] []++-- | List repositories with GitHub Actions cache usage for an organization.+-- See <https://docs.github.com/en/rest/actions/cache#list-repositories-with-github-actions-cache-usage-for-an-organization>+cacheUsageByRepositoryR+    :: Name Organization+    -> FetchCount+    -> GenRequest 'MtJSON 'RA (WithTotalCount RepositoryCacheUsage)+cacheUsageByRepositoryR org =+    PagedQuery ["orgs", toPathPart org, "actions", "cache", "usage-by-repository"] []++-- | Get GitHub Actions cache usage for a repository.+-- See <https://docs.github.com/en/rest/actions/cache#get-github-actions-cache-usage-for-a-repository>+cacheUsageR+    :: Name Owner+    -> Name Repo+    -> Request k RepositoryCacheUsage+cacheUsageR user repo =+    Query ["repos", toPathPart user, toPathPart repo, "actions", "cache", "usage"] []++-- | List the GitHub Actions caches for a repository.+-- See <https://docs.github.com/en/rest/actions/cache#list-github-actions-caches-for-a-repository>+cachesForRepoR+    :: Name Owner+    -> Name Repo+    -> CacheMod+    -> FetchCount+    -> GenRequest 'MtJSON 'RA (WithTotalCount Cache)+cachesForRepoR user repo opts = PagedQuery+    ["repos", toPathPart user, toPathPart repo, "actions", "caches"]+    (cacheModToQueryString opts)++-- | Delete GitHub Actions cache for a repository.+-- See <https://docs.github.com/en/rest/actions/cache#delete-a-github-actions-cache-for-a-repository-using-a-cache-id>+deleteCacheR+    :: Name Owner+    -> Name Repo+    -> Id Cache+    -> GenRequest 'MtUnit 'RW ()+deleteCacheR user repo cacheid =+    Command Delete parts mempty+  where+    parts = ["repos", toPathPart user, toPathPart repo, "actions", "caches", toPathPart cacheid]
+ src/GitHub/Endpoints/Actions/Secrets.hs view
@@ -0,0 +1,221 @@+-- |+-- The actions API as documented at+-- <https://docs.github.com/en/rest/reference/actions>.++module GitHub.Endpoints.Actions.Secrets (+    organizationSecretsR,+    organizationPublicKeyR,+    organizationSecretR,+    setOrganizationSecretR,+    deleteOrganizationSecretR,+    organizationSelectedRepositoriesForSecretR,+    setOrganizationSelectedRepositoriesForSecretR,+    addOrganizationSelectedRepositoriesForSecretR,+    removeOrganizationSelectedRepositoriesForSecretR,+    repoSecretsR,+    repoPublicKeyR,+    repoSecretR,+    setRepoSecretR,+    deleteRepoSecretR,+    environmentSecretsR,+    environmentPublicKeyR,+    environmentSecretR,+    setEnvironmentSecretR,+    deleteEnvironmentSecretR,+    module GitHub.Data+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | List organization secrets.+-- See <https://docs.github.com/en/rest/actions/secrets#list-organization-secrets>+organizationSecretsR+    :: Name Organization+    -> FetchCount+    -> GenRequest 'MtJSON 'RA (WithTotalCount OrganizationSecret)+organizationSecretsR org =+    PagedQuery ["orgs", toPathPart org, "actions", "secrets"] []++-- | List organization secrets.+-- See <https://docs.github.com/en/rest/actions/secrets#get-an-organization-public-key>+organizationPublicKeyR+    :: Name Organization+    -> GenRequest 'MtJSON 'RA PublicKey+organizationPublicKeyR org =+    Query ["orgs", toPathPart org, "actions", "secrets", "public-key"] []++-- | Get an organization secret.+-- See <https://docs.github.com/en/rest/actions/secrets#get-an-organization-secret>+organizationSecretR+    :: Name Organization+    -> Name OrganizationSecret+    -> GenRequest 'MtJSON 'RA OrganizationSecret+organizationSecretR org name =+    Query ["orgs", toPathPart org, "actions", "secrets", toPathPart name] []++-- | Create or update an organization secret.+-- See <https://docs.github.com/en/rest/actions/secrets#create-or-update-an-organization-secret>+setOrganizationSecretR+    :: Name Organization+    -> Name OrganizationSecret+    -> SetSecret+    -> GenRequest 'MtUnit 'RW ()+setOrganizationSecretR org name =+    Command Put ["orgs", toPathPart org, "actions", "secrets", toPathPart name] . encode++-- | Delete an organization secret.+-- See <https://docs.github.com/en/rest/actions/secrets#delete-an-organization-secret>+deleteOrganizationSecretR+    :: Name Organization+    -> Name OrganizationSecret+    -> GenRequest 'MtUnit 'RW ()+deleteOrganizationSecretR org name =+    Command Delete parts mempty+    where+        parts = ["orgs", toPathPart org, "actions", "secrets", toPathPart name]++-- | Get selected repositories for an organization secret.+-- See <https://docs.github.com/en/rest/actions/secrets#list-selected-repositories-for-an-organization-secret>+organizationSelectedRepositoriesForSecretR+    :: Name Organization+    -> Name OrganizationSecret+    -> FetchCount+    -> GenRequest 'MtJSON 'RA (WithTotalCount SelectedRepo)+organizationSelectedRepositoriesForSecretR org name =+    PagedQuery ["orgs", toPathPart org, "actions", "secrets", toPathPart name, "repositories"] []++-- | Set selected repositories for an organization secret.+-- See <https://docs.github.com/en/rest/actions/secrets#set-selected-repositories-for-an-organization-secret>+setOrganizationSelectedRepositoriesForSecretR+    :: Name Organization+    -> Name OrganizationSecret+    -> SetSelectedRepositories+    -> GenRequest 'MtUnit 'RW ()+setOrganizationSelectedRepositoriesForSecretR org name =+    Command Put ["orgs", toPathPart org, "actions", "secrets", toPathPart name, "repositories"]  . encode++-- | Add selected repository to an organization secret.+-- See <https://docs.github.com/en/rest/actions/secrets#add-selected-repository-to-an-organization-secret>+addOrganizationSelectedRepositoriesForSecretR+    :: Name Organization+    -> Name OrganizationSecret+    -> Id Repo+    -> GenRequest 'MtUnit 'RW ()+addOrganizationSelectedRepositoriesForSecretR org name repo =+    Command Put ["orgs", toPathPart org, "actions", "secrets", toPathPart name, "repositories", toPathPart repo] mempty++-- | Remove selected repository from an organization secret.+-- See <https://docs.github.com/en/rest/actions/secrets#remove-selected-repository-from-an-organization-secret>+removeOrganizationSelectedRepositoriesForSecretR+    :: Name Organization+    -> Name OrganizationSecret+    -> Id Repo+    -> GenRequest 'MtUnit 'RW ()+removeOrganizationSelectedRepositoriesForSecretR org name repo =+    Command Delete ["orgs", toPathPart org, "actions", "secrets", toPathPart name, "repositories", toPathPart repo] mempty++-- | List repository secrets.+-- See <https://docs.github.com/en/rest/actions/secrets#list-repository-secrets>+repoSecretsR+    :: Name Owner+    -> Name Repo+    -> FetchCount+    -> GenRequest 'MtJSON 'RA (WithTotalCount RepoSecret)+repoSecretsR user repo =+    PagedQuery ["repos", toPathPart user,  toPathPart repo, "actions", "secrets"] []++-- | Get a repository public key.+-- See <https://docs.github.com/en/rest/actions/secrets#get-a-repository-public-key>+repoPublicKeyR+    :: Name Owner+    -> Name Organization+    -> GenRequest 'MtJSON 'RA PublicKey+repoPublicKeyR user org =+    Query ["repos", toPathPart user, toPathPart org, "actions", "secrets", "public-key"] []++-- | Get a repository secret.+-- See <https://docs.github.com/en/rest/actions/secrets#get-a-repository-secret>+repoSecretR+    :: Name Owner+    -> Name Organization+    -> Name RepoSecret+    -> GenRequest 'MtJSON 'RA RepoSecret+repoSecretR user org name =+    Query ["repos", toPathPart user, toPathPart org, "actions", "secrets", toPathPart name] []++-- | Create or update a repository secret.+-- See <https://docs.github.com/en/rest/actions/secrets#create-or-update-a-repository-secret>+setRepoSecretR+    :: Name Owner+    -> Name Organization+    -> Name RepoSecret+    -> SetRepoSecret+    -> GenRequest 'MtUnit 'RW ()+setRepoSecretR user org name =+    Command Put ["repos", toPathPart user, toPathPart org, "actions", "secrets", toPathPart name] . encode++-- | Delete a repository secret.+-- See <https://docs.github.com/en/rest/actions/secrets#delete-a-repository-secret>+deleteRepoSecretR+    :: Name Owner+    -> Name Organization+    -> Name RepoSecret+    -> GenRequest 'MtUnit 'RW ()+deleteRepoSecretR user org name =+    Command Delete parts mempty+    where+        parts = ["repos", toPathPart user, toPathPart org, "actions", "secrets", toPathPart name]++-- | List environment secrets.+-- See <https://docs.github.com/en/rest/actions/secrets#list-environment-secrets>+environmentSecretsR+    :: Id Repo+    -> Name Environment+    -> FetchCount+    -> GenRequest 'MtJSON 'RA (WithTotalCount RepoSecret)+environmentSecretsR repo env =+    PagedQuery ["repositories", toPathPart repo, "environments", toPathPart env, "secrets"] []++-- | Get an environment public key.+-- See <https://docs.github.com/en/rest/actions/secrets#get-an-environment-public-key>+environmentPublicKeyR+    :: Id Repo+    -> Name Environment+    -> GenRequest 'MtJSON 'RA PublicKey+environmentPublicKeyR repo env =+    Query ["repositories", toPathPart repo, "environments", toPathPart env, "secrets", "public-key"] []++-- | Get an environment secret+-- See <https://docs.github.com/en/rest/actions/secrets#get-an-environment-secret>+environmentSecretR+    :: Id Repo+    -> Name Environment+    -> Name RepoSecret+    -> GenRequest 'MtJSON 'RA RepoSecret+environmentSecretR repo env name =+    Query ["repositories", toPathPart repo, "environments", toPathPart env, "secrets", toPathPart name] []++-- | Create or update an environment secret.+-- See <https://docs.github.com/en/rest/actions/secrets#create-or-update-an-environment-secret>+setEnvironmentSecretR+    :: Id Repo+    -> Name Environment+    -> Name RepoSecret+    -> SetRepoSecret+    -> GenRequest 'MtUnit 'RW ()+setEnvironmentSecretR repo env name =+    Command Put ["repositories", toPathPart repo, "environments", toPathPart env, "secrets", toPathPart name] . encode++-- | Delete an environment secret.+-- See <https://docs.github.com/en/rest/actions/secrets#delete-an-environment-secret>+deleteEnvironmentSecretR+    :: Id Repo+    -> Name Environment+    -> Name RepoSecret+    -> GenRequest 'MtUnit 'RW ()+deleteEnvironmentSecretR repo env name =+    Command Delete parts mempty+    where+        parts = ["repositories", toPathPart repo, "environments", toPathPart env, "secrets", toPathPart name]
+ src/GitHub/Endpoints/Actions/WorkflowJobs.hs view
@@ -0,0 +1,58 @@+-- |+-- The actions API as documented at+-- <https://docs.github.com/en/rest/reference/actions>.++module GitHub.Endpoints.Actions.WorkflowJobs (+    jobR,+    downloadJobLogsR,+    jobsForWorkflowRunAttemptR,+    jobsForWorkflowRunR,+    module GitHub.Data+    ) where++import GitHub.Data+import Network.URI (URI)+import Prelude ()++-- | Get a job for a workflow run.+-- See <https://docs.github.com/en/rest/actions/workflow-jobs#get-a-job-for-a-workflow-run>+jobR+    :: Name Owner+    -> Name Repo+    -> Id Job+    -> Request 'RA Job+jobR owner repo job =+    Query ["repos", toPathPart owner, toPathPart repo, "actions", "jobs", toPathPart job] []++-- | Download job logs for a workflow run.+-- See <https://docs.github.com/en/rest/actions/workflow-jobs#download-job-logs-for-a-workflow-run>+downloadJobLogsR+    :: Name Owner+    -> Name Repo+    -> Id Job+    -> GenRequest 'MtRedirect 'RO URI+downloadJobLogsR owner repo job =+    Query ["repos", toPathPart owner, toPathPart repo, "actions", "jobs", toPathPart job, "logs"] []++-- | List jobs for a workflow run attempt.+-- See <https://docs.github.com/en/rest/actions/workflow-jobs#list-jobs-for-a-workflow-run-attempt>+jobsForWorkflowRunAttemptR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> Id RunAttempt+    -> FetchCount+    -> GenRequest 'MtJSON 'RA (WithTotalCount Job)+jobsForWorkflowRunAttemptR owner repo run attempt =+    PagedQuery ["repos", toPathPart owner, toPathPart repo, "actions", "runs", toPathPart run, "attempts", toPathPart attempt, "jobs"] []++-- | List jobs for a workflow run.+-- See <https://docs.github.com/en/rest/actions/workflow-jobs#list-jobs-for-a-workflow-run>+jobsForWorkflowRunR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> FetchCount+    -> GenRequest 'MtJSON 'RA (WithTotalCount Job)+jobsForWorkflowRunR owner repo run =+    PagedQuery ["repos", toPathPart owner, toPathPart repo, "actions", "runs", toPathPart run, "jobs"] []
+ src/GitHub/Endpoints/Actions/WorkflowRuns.hs view
@@ -0,0 +1,181 @@+module GitHub.Endpoints.Actions.WorkflowRuns (+    reRunJobR,+    workflowRunsR,+    workflowRunR,+    deleteWorkflowRunR,+    workflowRunReviewHistoryR,+    approveWorkflowRunR,+    workflowRunAttemptR,+    downloadWorkflowRunAttemptLogsR,+    cancelWorkflowRunR,+    downloadWorkflowRunLogsR,+    deleteWorkflowRunLogsR,+    reRunWorkflowR,+    reRunFailedJobsR,+    workflowRunsForWorkflowR,+    module GitHub.Data+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Network.URI             (URI)+import Prelude ()++-- | Re-run a job from a workflow run.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#re-run-a-job-from-a-workflow-run>+reRunJobR+    :: Name Owner+    -> Name Repo+    -> Id Job+    -> GenRequest 'MtUnit 'RW ()+reRunJobR user repo job = Command Post+    ["repos", toPathPart user, toPathPart repo, "actions", "jobs", toPathPart job, "rerun"]+    mempty++-- | List workflow runs for a repository.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-repository>+workflowRunsR+    :: Name Owner+    -> Name Repo+    -> WorkflowRunMod+    -> FetchCount+    -> GenRequest 'MtJSON 'RA (WithTotalCount WorkflowRun)+workflowRunsR user repo runMod = PagedQuery+    ["repos", toPathPart user, toPathPart repo, "actions", "runs"]+    (workflowRunModToQueryString runMod)++-- | Get a workflow run.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#get-a-workflow-run>+workflowRunR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> GenRequest 'MtJSON 'RA WorkflowRun+workflowRunR user repo run = Query+    ["repos", toPathPart user, toPathPart repo, "actions", "runs", toPathPart run]+    []++-- | Delete a workflow run.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#delete-a-workflow-run>+deleteWorkflowRunR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> GenRequest 'MtUnit 'RW ()+deleteWorkflowRunR user repo run = Command Delete+    ["repos", toPathPart user, toPathPart repo, "actions", "runs", toPathPart run]+    mempty++-- | Get the review history for a workflow run.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#get-the-review-history-for-a-workflow-run>+workflowRunReviewHistoryR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> GenRequest 'MtJSON 'RA (Vector ReviewHistory)+workflowRunReviewHistoryR user repo run = Query+    ["repos", toPathPart user, toPathPart repo, "actions", "runs", toPathPart run, "approvals"]+    []++-- | Approve a workflow run for a fork pull request.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#approve-a-workflow-run-for-a-fork-pull-request>+approveWorkflowRunR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> GenRequest 'MtUnit 'RW ()+approveWorkflowRunR user repo run = Command Post+    ["repos", toPathPart user, toPathPart repo, "actions", "runs", toPathPart run, "approve"]+    mempty++-- | Get a workflow run attempt.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#get-a-workflow-run-attempt>+workflowRunAttemptR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> Id RunAttempt+    -> GenRequest 'MtJSON 'RA WorkflowRun+workflowRunAttemptR user repo run attempt = Query+    ["repos", toPathPart user, toPathPart repo, "actions", "runs", toPathPart run, "attempts", toPathPart attempt]+    []++-- | Download workflow run attempt logs.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#download-workflow-run-attempt-logs>+downloadWorkflowRunAttemptLogsR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> Id RunAttempt+    -> GenRequest 'MtRedirect 'RO URI+downloadWorkflowRunAttemptLogsR user repo run attempt = Query+    ["repos", toPathPart user, toPathPart repo, "actions", "runs", toPathPart run, "attempts", toPathPart attempt, "logs"]+    []++-- | Cancel a workflow run.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#cancel-a-workflow-run>+cancelWorkflowRunR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> GenRequest 'MtUnit 'RW ()+cancelWorkflowRunR user repo run = Command Post+    ["repos", toPathPart user, toPathPart repo, "actions", "runs", toPathPart run, "cancel"]+    mempty++-- | Download workflow run logs.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#download-workflow-run-logs>+downloadWorkflowRunLogsR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> GenRequest 'MtRedirect 'RA URI+downloadWorkflowRunLogsR user repo run = Query+    ["repos", toPathPart user, toPathPart repo, "actions", "runs", toPathPart run, "logs"]+    []++-- | Delete workflow run logs.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#delete-workflow-run-logs>+deleteWorkflowRunLogsR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    ->  GenRequest 'MtUnit 'RW ()+deleteWorkflowRunLogsR user repo run = Command Delete+    ["repos", toPathPart user, toPathPart repo, "actions", "runs", toPathPart run, "logs"]+    mempty++-- | Re-run a workflow.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#re-run-a-workflow>+reRunWorkflowR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> GenRequest 'MtUnit 'RW ()+reRunWorkflowR user repo run = Command Post+    ["repos", toPathPart user, toPathPart repo, "actions", "runs", toPathPart run, "rerun"]+    mempty++-- | Re-run failed jobs from a workflow run.+-- See <https://docs.github.com/en/rest/actions/re-run-failed-jobs-from-a-workflow-run>+reRunFailedJobsR+    :: Name Owner+    -> Name Repo+    -> Id WorkflowRun+    -> GenRequest 'MtUnit 'RW ()+reRunFailedJobsR user repo run = Command Post+    ["repos", toPathPart user, toPathPart repo, "actions", "runs", toPathPart run, "rerun-failed-jobs"]+    mempty++-- | List workflow runs for a workflow.+-- See <https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-workflow>+workflowRunsForWorkflowR+    :: (IsPathPart idOrName) => Name Owner+    -> Name Repo+    -> idOrName+    -> WorkflowRunMod+    -> FetchCount+    -> GenRequest 'MtJSON 'RA (WithTotalCount WorkflowRun)+workflowRunsForWorkflowR user repo idOrName runMod = PagedQuery+    ["repos", toPathPart user, toPathPart repo, "actions", "workflows", toPathPart idOrName, "runs"]+     (workflowRunModToQueryString runMod)
+ src/GitHub/Endpoints/Actions/Workflows.hs view
@@ -0,0 +1,68 @@+module GitHub.Endpoints.Actions.Workflows (+    repositoryWorkflowsR,+    workflowR,+    disableWorkflowR,+    triggerWorkflowR,+    enableWorkflowR,+    module GitHub.Data+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | List repository workflows.+-- See <https://docs.github.com/en/rest/actions/workflows#list-repository-workflows>+repositoryWorkflowsR+    :: Name Owner+    -> Name Repo+    -> FetchCount+    -> GenRequest 'MtJSON 'RA (WithTotalCount Workflow)+repositoryWorkflowsR user repo  = PagedQuery+    ["repos", toPathPart user, toPathPart repo, "actions", "workflows"]+    []++-- | Get a workflow.+-- See <https://docs.github.com/en/rest/actions/workflows#get-a-workflow>+workflowR+    :: (IsPathPart idOrName) => Name Owner+    -> Name Repo+    -> idOrName+    -> GenRequest 'MtJSON 'RA  Workflow+workflowR user repo idOrName  = Query+    ["repos", toPathPart user, toPathPart repo, "actions", "workflows", toPathPart idOrName]+    []++-- | Disable a workflow.+-- See <https://docs.github.com/en/rest/actions/workflows#disable-a-workflow>+disableWorkflowR+    :: (IsPathPart idOrName) => Name Owner+    -> Name Repo+    -> idOrName+    -> GenRequest 'MtUnit 'RW  ()+disableWorkflowR user repo idOrName  = Command Put+    ["repos", toPathPart user, toPathPart repo, "actions", "workflows", toPathPart idOrName, "disable"]+    mempty++-- | Create a workflow dispatch event.+-- See <https://docs.github.com/en/rest/actions/workflows#create-a-workflow-dispatch-event>+triggerWorkflowR+    :: (ToJSON a, IsPathPart idOrName) => Name Owner+    -> Name Repo+    -> idOrName+    -> CreateWorkflowDispatchEvent a+    -> GenRequest 'MtUnit 'RW  ()+triggerWorkflowR user repo idOrName  = Command Post+    ["repos", toPathPart user, toPathPart repo, "actions", "workflows", toPathPart idOrName, "dispatches"]+    . encode++-- | Enable a workflow.+-- See <https://docs.github.com/en/rest/actions/workflows#enable-a-workflow>+enableWorkflowR+    :: (IsPathPart idOrName) => Name Owner+    -> Name Repo+    -> idOrName+    -> GenRequest 'MtUnit 'RW  ()+enableWorkflowR user repo idOrName  = Command Put+    ["repos", toPathPart user, toPathPart repo, "actions", "workflows", toPathPart idOrName, "enable"]+    mempty
src/GitHub/Endpoints/Activity/Events.hs view
@@ -1,9 +1,6 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The events API as described on <https://developer.github.com/v3/activity/events/>.+ module GitHub.Endpoints.Activity.Events (     -- * Events     repositoryEventsR,
+ src/GitHub/Endpoints/Activity/Notifications.hs view
@@ -0,0 +1,32 @@+-- |+-- The repo watching API as described on+-- <https://developer.github.com/v3/activity/notifications/>.++module GitHub.Endpoints.Activity.Notifications (+    getNotificationsR,+    markNotificationAsReadR,+    markAllNotificationsAsReadR,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | List your notifications.+-- See <https://developer.github.com/v3/activity/notifications/#list-your-notifications>+getNotificationsR :: FetchCount -> Request 'RA (Vector Notification)+getNotificationsR = pagedQuery ["notifications"] []++-- | Mark a thread as read.+-- See <https://developer.github.com/v3/activity/notifications/#mark-a-thread-as-read>+markNotificationAsReadR :: Id Notification -> GenRequest 'MtUnit 'RW ()+markNotificationAsReadR nid = Command+    Patch+    ["notifications", "threads", toPathPart nid]+    (encode ())++-- | Mark as read.+-- See <https://developer.github.com/v3/activity/notifications/#mark-as-read>+markAllNotificationsAsReadR :: GenRequest 'MtUnit 'RW ()+markAllNotificationsAsReadR =+    Command Put ["notifications"] $ encode emptyObject
src/GitHub/Endpoints/Activity/Starring.hs view
@@ -1,22 +1,13 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The repo starring API as described on -- <https://developer.github.com/v3/activity/starring/>.+ module GitHub.Endpoints.Activity.Starring (-    stargazersFor,     stargazersForR,-    reposStarredBy,     reposStarredByR,-    myStarred,     myStarredR,-    myStarredAcceptStar,     myStarredAcceptStarR,-    starRepo,     starRepoR,-    unstarRepo,     unstarRepoR,     module GitHub.Data,     ) where@@ -24,29 +15,14 @@ import GitHub.Auth import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | The list of users that have starred the specified Github repo.------ > userInfoFor' Nothing "mike-burns"-stargazersFor :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector SimpleUser))-stargazersFor auth user repo =-    executeRequestMaybe auth $ stargazersForR user repo FetchAll- -- | List Stargazers. -- See <https://developer.github.com/v3/activity/starring/#list-stargazers> stargazersForR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector SimpleUser) stargazersForR user repo =     pagedQuery ["repos", toPathPart user, toPathPart repo, "stargazers"] [] --- | All the public repos starred by the specified user.------ > reposStarredBy Nothing "croaky"-reposStarredBy :: Maybe Auth -> Name Owner -> IO (Either Error (Vector Repo))-reposStarredBy auth user =-    executeRequestMaybe auth $ reposStarredByR user FetchAll- -- | List repositories being starred. -- See <https://developer.github.com/v3/activity/starring/#list-repositories-being-starred> reposStarredByR :: Name Owner -> FetchCount -> Request k (Vector Repo)@@ -54,44 +30,25 @@     pagedQuery ["users", toPathPart user, "starred"] []  -- | All the repos starred by the authenticated user.-myStarred :: Auth -> IO (Either Error (Vector Repo))-myStarred auth =-    executeRequest auth $ myStarredR FetchAll---- | All the repos starred by the authenticated user. -- See <https://developer.github.com/v3/activity/starring/#list-repositories-being-starred> myStarredR :: FetchCount -> Request 'RA (Vector Repo) myStarredR = pagedQuery ["user", "starred"] [] - -- | All the repos starred by the authenticated user.-myStarredAcceptStar :: Auth -> IO (Either Error (Vector RepoStarred))-myStarredAcceptStar auth =-    executeRequest auth $ myStarredAcceptStarR FetchAll---- | All the repos starred by the authenticated user. -- See <https://developer.github.com/v3/activity/starring/#alternative-response-with-star-creation-timestamps-1>-myStarredAcceptStarR :: FetchCount -> Request 'RA (Vector RepoStarred)-myStarredAcceptStarR = HeaderQuery [("Accept", "application/vnd.github.v3.star+json")] . PagedQuery ["user", "starred"] []---- | Star a repo by the authenticated user.-starRepo :: Auth -> Name Owner -> Name Repo -> IO (Either Error ())-starRepo auth user repo = executeRequest auth $ starRepoR user repo+myStarredAcceptStarR :: FetchCount -> GenRequest 'MtStar 'RA (Vector RepoStarred)+myStarredAcceptStarR = PagedQuery ["user", "starred"] []  -- | Star a repo by the authenticated user. -- See <https://developer.github.com/v3/activity/starring/#star-a-repository>-starRepoR :: Name Owner -> Name Repo -> Request 'RW ()-starRepoR user repo = command Put' paths mempty+starRepoR :: Name Owner -> Name Repo -> GenRequest 'MtUnit 'RW ()+starRepoR user repo = Command Put paths mempty   where     paths = ["user", "starred", toPathPart user, toPathPart repo]  -- | Unstar a repo by the authenticated user.-unstarRepo :: Auth -> Name Owner -> Name Repo -> IO (Either Error ())-unstarRepo auth user repo = executeRequest auth $ unstarRepoR user repo---- | Unstar a repo by the authenticated user. -- See <https://developer.github.com/v3/activity/starring/#unstar-a-repository>-unstarRepoR :: Name Owner -> Name Repo -> Request 'RW ()-unstarRepoR user repo = command Delete paths mempty+unstarRepoR :: Name Owner -> Name Repo -> GenRequest 'MtUnit 'RW ()+unstarRepoR user repo = Command Delete paths mempty   where     paths = ["user", "starred", toPathPart user, toPathPart repo]
src/GitHub/Endpoints/Activity/Watching.hs view
@@ -1,62 +1,33 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The repo watching API as described on -- <https://developer.github.com/v3/activity/watching/>.+ module GitHub.Endpoints.Activity.Watching (-    watchersFor,-    watchersFor',     watchersForR,-    reposWatchedBy,-    reposWatchedBy',     reposWatchedByR,+    unwatchRepoR,     module GitHub.Data, ) where  import GitHub.Auth import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | The list of users that are watching the specified Github repo.------ > watchersFor "thoughtbot" "paperclip"-watchersFor :: Name Owner -> Name Repo -> IO (Either Error (Vector SimpleUser))-watchersFor = watchersFor' Nothing---- | The list of users that are watching the specified Github repo.--- With authentication------ > watchersFor' (Just (User (user, password))) "thoughtbot" "paperclip"-watchersFor' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector SimpleUser))-watchersFor' auth user repo =-    executeRequestMaybe auth $ watchersForR user repo FetchAll- -- | List watchers. -- See <https://developer.github.com/v3/activity/watching/#list-watchers> watchersForR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector SimpleUser) watchersForR user repo limit =     pagedQuery ["repos", toPathPart user, toPathPart repo, "watchers"] [] limit --- | All the public repos watched by the specified user.------ > reposWatchedBy "croaky"-reposWatchedBy :: Name Owner -> IO (Either Error (Vector Repo))-reposWatchedBy = reposWatchedBy' Nothing---- | All the public repos watched by the specified user.--- With authentication------ > reposWatchedBy' (Just (User (user, password))) "croaky"-reposWatchedBy' :: Maybe Auth -> Name Owner -> IO (Either Error (Vector Repo))-reposWatchedBy' auth user =-    executeRequestMaybe auth $ reposWatchedByR user FetchAll- -- | List repositories being watched. -- See <https://developer.github.com/v3/activity/watching/#list-repositories-being-watched> reposWatchedByR :: Name Owner -> FetchCount -> Request k (Vector Repo) reposWatchedByR user =     pagedQuery ["users", toPathPart user, "subscriptions"] []++-- | Stop watching repository.+-- See <https://docs.github.com/en/rest/reference/activity#delete-a-repository-subscription>+unwatchRepoR :: Name Owner -> Name Repo -> Request 'RW ()+unwatchRepoR owner repo =+    command Delete ["repos", toPathPart owner, toPathPart repo, "subscription"] mempty
+ src/GitHub/Endpoints/Enterprise/Organizations.hs view
@@ -0,0 +1,25 @@+-- |+-- The GitHub Enterprise orgs API as described on <https://developer.github.com/enterprise/v3/enterprise-admin/orgs/>.++module GitHub.Endpoints.Enterprise.Organizations (+    createOrganizationR,+    renameOrganizationR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Data.Enterprise+import GitHub.Internal.Prelude+import Prelude ()++-- | Create an organization.+-- See <https://developer.github.com/enterprise/v3/enterprise-admin/orgs/#create-an-organization>+createOrganizationR :: CreateOrganization -> Request 'RW SimpleOrganization+createOrganizationR =+    command Post ["admin", "organizations"] . encode++-- | Rename an organization.+-- See <https://developer.github.com/enterprise/v3/enterprise-admin/orgs/#rename-an-organization>+renameOrganizationR :: Name Organization -> RenameOrganization -> Request 'RW RenameOrganizationResponse+renameOrganizationR org =+    command Patch ["admin", "organizations", toPathPart org] . encode
src/GitHub/Endpoints/Gists.hs view
@@ -1,96 +1,47 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The gists API as described at <http://developer.github.com/v3/gists/>.+ module GitHub.Endpoints.Gists (-    gists,-    gists',     gistsR,-    gist,-    gist',     gistR,-    starGist,+    createGistR,     starGistR,-    unstarGist,     unstarGistR,-    deleteGist,     deleteGistR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | The list of all gists created by the user------ > gists' (Just ("github-username", "github-password")) "mike-burns"-gists' :: Maybe Auth -> Name Owner -> IO (Either Error (Vector Gist))-gists' auth user =-    executeRequestMaybe auth $ gistsR user FetchAll---- | The list of all public gists created by the user.------ > gists "mike-burns"-gists :: Name Owner -> IO (Either Error (Vector Gist))-gists = gists' Nothing- -- | List gists. -- See <https://developer.github.com/v3/gists/#list-gists> gistsR :: Name Owner -> FetchCount -> Request k (Vector Gist) gistsR user = pagedQuery ["users", toPathPart user, "gists"] [] --- | A specific gist, given its id, with authentication credentials------ > gist' (Just ("github-username", "github-password")) "225074"-gist' :: Maybe Auth -> Name Gist -> IO (Either Error Gist)-gist' auth gid =-    executeRequestMaybe auth $ gistR gid---- | A specific gist, given its id.------ > gist "225074"-gist :: Name Gist -> IO (Either Error Gist)-gist = gist' Nothing- -- | Query a single gist. -- See <https://developer.github.com/v3/gists/#get-a-single-gist> gistR :: Name Gist -> Request k Gist gistR gid =     query ["gists", toPathPart gid] [] --- | Star a gist by the authenticated user.------ > starGist ("github-username", "github-password") "225074"-starGist :: Auth -> Name Gist -> IO (Either Error ())-starGist auth gid = executeRequest auth $ starGistR gid+-- | Create a new gist+-- See <https://docs.github.com/rest/reference/gists#create-a-gist>+createGistR :: NewGist -> Request 'RW Gist+createGistR ngist = command Post ["gists"] (encode ngist)  -- | Star a gist by the authenticated user. -- See <https://developer.github.com/v3/gists/#star-a-gist>-starGistR :: Name Gist -> Request 'RW ()-starGistR gid = command Put' ["gists", toPathPart gid, "star"] mempty---- | Unstar a gist by the authenticated user.------ > unstarGist ("github-username", "github-password") "225074"-unstarGist :: Auth -> Name Gist -> IO (Either Error ())-unstarGist auth gid = executeRequest auth $ unstarGistR gid+starGistR :: Name Gist -> GenRequest 'MtUnit 'RW ()+starGistR gid = Command Put ["gists", toPathPart gid, "star"] mempty  -- | Unstar a gist by the authenticated user. -- See <https://developer.github.com/v3/gists/#unstar-a-gist>-unstarGistR :: Name Gist -> Request 'RW ()-unstarGistR gid = command Delete ["gists", toPathPart gid, "star"] mempty---- | Delete a gist by the authenticated user.------ > deleteGist ("github-username", "github-password") "225074"-deleteGist :: Auth -> Name Gist -> IO (Either Error ())-deleteGist auth gid = executeRequest auth $ deleteGistR gid+unstarGistR :: Name Gist -> GenRequest 'MtUnit 'RW ()+unstarGistR gid = Command Delete ["gists", toPathPart gid, "star"] mempty  -- | Delete a gist by the authenticated user. -- See <https://developer.github.com/v3/gists/#delete-a-gist>-deleteGistR :: Name Gist -> Request 'RW ()-deleteGistR gid = command Delete ["gists", toPathPart gid] mempty+deleteGistR :: Name Gist -> GenRequest 'MtUnit 'RW ()+deleteGistR gid = Command Delete ["gists", toPathPart gid] mempty
src/GitHub/Endpoints/Gists/Comments.hs view
@@ -1,42 +1,22 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The loving comments people have left on Gists, described on -- <http://developer.github.com/v3/gists/comments/>.+ module GitHub.Endpoints.Gists.Comments (-    commentsOn,     commentsOnR,-    comment,     gistCommentR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | All the comments on a Gist, given the Gist ID.------ > commentsOn "1174060"-commentsOn :: Name Gist -> IO (Either Error (Vector GistComment))-commentsOn gid =-    executeRequest' $ commentsOnR gid FetchAll- -- | List comments on a gist. -- See <https://developer.github.com/v3/gists/comments/#list-comments-on-a-gist> commentsOnR :: Name Gist -> FetchCount -> Request k (Vector GistComment) commentsOnR gid =     pagedQuery ["gists", toPathPart gid, "comments"] []---- | A specific comment, by the comment ID.------ > comment (Id 62449)-comment :: Id GistComment -> IO (Either Error GistComment)-comment cid =-    executeRequest' $ gistCommentR cid  -- | Query a single comment. -- See <https://developer.github.com/v3/gists/comments/#get-a-single-comment>
src/GitHub/Endpoints/GitData/Blobs.hs view
@@ -1,34 +1,14 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The API for dealing with git blobs from Github repos, as described in -- <http://developer.github.com/v3/git/blobs/>.+ module GitHub.Endpoints.GitData.Blobs (-    blob,-    blob',     blobR,     module GitHub.Data,     ) where  import GitHub.Data-import GitHub.Internal.Prelude-import GitHub.Request import Prelude ()---- | Query a blob by SHA1.------ > blob' (Just ("github-username", "github-password")) "thoughtbot" "paperclip" "bc5c51d1ece1ee45f94b056a0f5a1674d7e8cba9"-blob' :: Maybe Auth -> Name Owner -> Name Repo -> Name Blob -> IO (Either Error Blob)-blob' auth user repo sha =-    executeRequestMaybe auth $ blobR user repo sha---- | Query a blob by SHA1.------ > blob "thoughtbot" "paperclip" "bc5c51d1ece1ee45f94b056a0f5a1674d7e8cba9"-blob :: Name Owner -> Name Repo -> Name Blob -> IO (Either Error Blob)-blob = blob' Nothing  -- | Query a blob. -- See <https://developer.github.com/v3/git/blobs/#get-a-blob>
src/GitHub/Endpoints/GitData/Commits.hs view
@@ -1,27 +1,14 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The API for underlying git commits of a Github repo, as described on -- <http://developer.github.com/v3/git/commits/>.+ module GitHub.Endpoints.GitData.Commits (-    commit,     gitCommitR,     module GitHub.Data, ) where  import GitHub.Data-import GitHub.Internal.Prelude-import GitHub.Request import Prelude ()---- | A single commit, by SHA1.------ > commit "thoughtbot" "paperclip" "bc5c51d1ece1ee45f94b056a0f5a1674d7e8cba9"-commit :: Name Owner -> Name Repo -> Name GitCommit -> IO (Either Error GitCommit)-commit user repo sha =-    executeRequest' $ gitCommitR user repo sha  -- | Query a commit. -- See <https://developer.github.com/v3/git/commits/#get-a-commit>
src/GitHub/Endpoints/GitData/References.hs view
@@ -1,61 +1,27 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The underlying git references on a Github repo, exposed for the world to -- see. The git internals documentation will also prove handy for understanding -- these. API documentation at <http://developer.github.com/v3/git/refs/>.+ module GitHub.Endpoints.GitData.References (-    reference,-    reference',     referenceR,-    references,-    references',     referencesR,-    createReference,     createReferenceR,-    namespacedReferences,+    deleteReferenceR,+    namespacedReferencesR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | A single reference by the ref name.------ > reference' (Just ("github-username", "github-password")) "mike-burns" "github" "heads/master"-reference' :: Maybe Auth -> Name Owner -> Name Repo -> Name GitReference -> IO (Either Error GitReference)-reference' auth user repo ref =-    executeRequestMaybe auth $ referenceR user repo ref---- | A single reference by the ref name.------ > reference "mike-burns" "github" "heads/master"-reference :: Name Owner -> Name Repo -> Name GitReference -> IO (Either Error GitReference)-reference = reference' Nothing---- | Query a reference.+-- | A single reference -- | Query a reference. -- See <https://developer.github.com/v3/git/refs/#get-a-reference> referenceR :: Name Owner -> Name Repo -> Name GitReference -> Request k GitReference referenceR user repo ref =     query ["repos", toPathPart user, toPathPart repo, "git", "refs", toPathPart ref] [] --- | The history of references for a repo.------ > references "mike-burns" "github"-references' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector GitReference))-references' auth user repo =-    executeRequestMaybe auth $ referencesR user repo FetchAll---- | The history of references for a repo.------ > references "mike-burns" "github"-references :: Name Owner -> Name Repo -> IO (Either Error (Vector GitReference))-references = references' Nothing- -- | Query all References. -- See <https://developer.github.com/v3/git/refs/#get-all-references> referencesR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector GitReference)@@ -63,22 +29,16 @@     pagedQuery ["repos", toPathPart user, toPathPart repo, "git", "refs"] []  -- | Create a reference.-createReference :: Auth -> Name Owner -> Name Repo -> NewGitReference -> IO (Either Error GitReference)-createReference auth user repo newRef =-    executeRequest auth $ createReferenceR user repo newRef---- | Create a reference. -- See <https://developer.github.com/v3/git/refs/#create-a-reference> createReferenceR :: Name Owner -> Name Repo -> NewGitReference -> Request 'RW GitReference createReferenceR user repo newRef =      command Post  ["repos", toPathPart user, toPathPart repo , "git", "refs"] (encode newRef) --- | Limited references by a namespace.------ > namespacedReferences "thoughtbot" "paperclip" "tags"-namespacedReferences :: Name Owner -> Name Repo -> Text -> IO (Either Error [GitReference])-namespacedReferences user repo namespace =-    executeRequest' $ namespacedReferencesR user repo namespace+-- | Delete a reference.+-- See <https://developer.github.com/v3/git/refs/#delete-a-reference>+deleteReferenceR :: Name Owner -> Name Repo -> Name GitReference -> GenRequest 'MtUnit 'RW ()+deleteReferenceR user repo ref =+    Command Delete ["repos", toPathPart user, toPathPart repo , "git", "refs", toPathPart ref] mempty  -- | Query namespaced references. -- See <https://developer.github.com/v3/git/refs/#get-all-references>
src/GitHub/Endpoints/GitData/Trees.hs view
@@ -1,56 +1,22 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The underlying tree of SHA1s and files that make up a git repo. The API is -- described on <http://developer.github.com/v3/git/trees/>.+ module GitHub.Endpoints.GitData.Trees (-    tree,-    tree',     treeR,-    nestedTree,-    nestedTree',     nestedTreeR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | A tree for a SHA1.------ > tree (Just ("github-username", "github-password")) "thoughtbot" "paperclip" "fe114451f7d066d367a1646ca7ac10e689b46844"-tree' :: Maybe Auth -> Name Owner -> Name Repo -> Name Tree -> IO (Either Error Tree)-tree' auth user repo sha =-    executeRequestMaybe auth $ treeR user repo sha---- | A tree for a SHA1.------ > tree "thoughtbot" "paperclip" "fe114451f7d066d367a1646ca7ac10e689b46844"-tree :: Name Owner -> Name Repo -> Name Tree -> IO (Either Error Tree)-tree = tree' Nothing- -- | Query a Tree. -- See <https://developer.github.com/v3/git/trees/#get-a-tree> treeR :: Name Owner -> Name Repo -> Name Tree -> Request k Tree treeR user repo sha =     query  ["repos", toPathPart user, toPathPart repo, "git", "trees", toPathPart sha] []---- | A recursively-nested tree for a SHA1.------ > nestedTree' (Just ("github-username", "github-password")) "thoughtbot" "paperclip" "fe114451f7d066d367a1646ca7ac10e689b46844"-nestedTree' :: Maybe Auth -> Name Owner -> Name Repo -> Name Tree -> IO (Either Error Tree)-nestedTree' auth user repo sha =-    executeRequestMaybe auth $ nestedTreeR user repo sha---- | A recursively-nested tree for a SHA1.------ > nestedTree "thoughtbot" "paperclip" "fe114451f7d066d367a1646ca7ac10e689b46844"-nestedTree :: Name Owner -> Name Repo -> Name Tree -> IO (Either Error Tree)-nestedTree = nestedTree' Nothing  -- | Query a Tree Recursively. -- See <https://developer.github.com/v3/git/trees/#get-a-tree-recursively>
src/GitHub/Endpoints/Issues.hs view
@@ -1,23 +1,13 @@-{-# LANGUAGE CPP #-}------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The issues API as described on <http://developer.github.com/v3/issues/>.+ module GitHub.Endpoints.Issues (     currentUserIssuesR,     organizationIssuesR,-    issue,-    issue',     issueR,-    issuesForRepo,-    issuesForRepo',     issuesForRepoR,-    createIssue,     createIssueR,     newIssue,-    editIssue,     editIssueR,     editOfIssue,     module GitHub.Data,@@ -25,7 +15,6 @@  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude ()  -- | See <https://developer.github.com/v3/issues/#list-issues>.@@ -38,42 +27,12 @@ organizationIssuesR org opts =     pagedQuery ["orgs", toPathPart org, "issues"] (issueModToQueryString opts) --- | Details on a specific issue, given the repo owner and name, and the issue--- number.'------ > issue' (Just ("github-username", "github-password")) "thoughtbot" "paperclip" "462"-issue' :: Maybe Auth -> Name Owner -> Name Repo -> Id Issue -> IO (Either Error Issue)-issue' auth user reqRepoName reqIssueNumber =-    executeRequestMaybe auth $ issueR user reqRepoName reqIssueNumber---- | Details on a specific issue, given the repo owner and name, and the issue--- number.------ > issue "thoughtbot" "paperclip" (Id "462")-issue :: Name Owner -> Name Repo -> Id Issue -> IO (Either Error Issue)-issue = issue' Nothing- -- | Query a single issue. -- See <https://developer.github.com/v3/issues/#get-a-single-issue>-issueR :: Name Owner -> Name Repo -> Id Issue -> Request k Issue+issueR :: Name Owner -> Name Repo -> IssueNumber -> Request k Issue issueR user reqRepoName reqIssueNumber =     query ["repos", toPathPart user, toPathPart reqRepoName, "issues", toPathPart reqIssueNumber] [] --- | All issues for a repo (given the repo owner and name), with optional--- restrictions as described in the 'IssueRepoMod' data type.------ > issuesForRepo' (Just ("github-username", "github-password")) "thoughtbot" "paperclip" [NoMilestone, OnlyClosed, Mentions "jyurek", Ascending]-issuesForRepo' :: Maybe Auth -> Name Owner -> Name Repo -> IssueRepoMod -> IO (Either Error (Vector Issue))-issuesForRepo' auth user reqRepoName opts =-    executeRequestMaybe auth $ issuesForRepoR user reqRepoName opts FetchAll---- | All issues for a repo (given the repo owner and name), with optional--- restrictions as described in the 'IssueRepoMod' data type.------ > issuesForRepo "thoughtbot" "paperclip" [NoMilestone, OnlyClosed, Mentions "jyurek", Ascending]-issuesForRepo :: Name Owner -> Name Repo -> IssueRepoMod -> IO (Either Error (Vector Issue))-issuesForRepo = issuesForRepo' Nothing- -- | List issues for a repository. -- See <https://developer.github.com/v3/issues/#list-issues-for-a-repository> issuesForRepoR :: Name Owner -> Name Repo -> IssueRepoMod -> FetchCount -> Request k (Vector Issue)@@ -85,17 +44,7 @@ -- Creating new issues.  newIssue :: Text -> NewIssue-newIssue title = NewIssue title Nothing Nothing Nothing Nothing----- | Create a new issue.------ > createIssue (User (user, password)) user repo--- >  (newIssue "some_repo") {...}-createIssue :: Auth -> Name Owner -> Name Repo -> NewIssue-            -> IO (Either Error Issue)-createIssue auth user repo ni =-     executeRequest auth $ createIssueR user repo ni+newIssue title = NewIssue title Nothing mempty Nothing Nothing  -- | Create an issue. -- See <https://developer.github.com/v3/issues/#create-an-issue>@@ -109,16 +58,7 @@ editOfIssue = EditIssue Nothing Nothing Nothing Nothing Nothing Nothing  -- | Edit an issue.------ > editIssue (User (user, password)) user repo issue--- >  editOfIssue {...}-editIssue :: Auth -> Name Owner -> Name Repo -> Id Issue -> EditIssue-            -> IO (Either Error Issue)-editIssue auth user repo iss edit =-     executeRequest auth $ editIssueR user repo iss edit---- | Edit an issue. -- See <https://developer.github.com/v3/issues/#edit-an-issue>-editIssueR :: Name Owner -> Name Repo -> Id Issue -> EditIssue -> Request 'RW Issue+editIssueR :: Name Owner -> Name Repo -> IssueNumber -> EditIssue -> Request 'RW Issue editIssueR user repo iss =     command Patch ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iss] . encode
src/GitHub/Endpoints/Issues/Comments.hs view
@@ -1,89 +1,41 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The Github issue comments API from -- <http://developer.github.com/v3/issues/comments/>.+ module GitHub.Endpoints.Issues.Comments (-    comment,     commentR,-    comments,     commentsR,-    comments',-    createComment,     createCommentR,-    deleteComment,     deleteCommentR,-    editComment,     editCommentR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | A specific comment, by ID.------ > comment "thoughtbot" "paperclip" 1468184-comment :: Name Owner -> Name Repo -> Id Comment -> IO (Either Error IssueComment)-comment user repo cid =-    executeRequest' $ commentR user repo cid- -- | Query a single comment. -- See <https://developer.github.com/v3/issues/comments/#get-a-single-comment> commentR :: Name Owner -> Name Repo -> Id Comment -> Request k IssueComment commentR user repo cid =     query ["repos", toPathPart user, toPathPart repo, "issues", "comments", toPathPart cid] [] --- | All comments on an issue, by the issue's number.------ > comments "thoughtbot" "paperclip" 635-comments :: Name Owner -> Name Repo -> Id Issue -> IO (Either Error (Vector IssueComment))-comments = comments' Nothing---- | All comments on an issue, by the issue's number, using authentication.------ > comments' (User (user, password)) "thoughtbot" "paperclip" 635-comments' :: Maybe Auth -> Name Owner -> Name Repo -> Id Issue -> IO (Either Error (Vector IssueComment))-comments' auth user repo iid =-    executeRequestMaybe auth $ commentsR user repo iid FetchAll- -- | List comments on an issue. -- See <https://developer.github.com/v3/issues/comments/#list-comments-on-an-issue>-commentsR :: Name Owner -> Name Repo -> Id Issue -> FetchCount -> Request k (Vector IssueComment)+commentsR :: Name Owner -> Name Repo -> IssueNumber -> FetchCount -> Request k (Vector IssueComment) commentsR user repo iid =     pagedQuery ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iid, "comments"] [] --- | Create a new comment.------ > createComment (User (user, password)) user repo issue--- >  "some words"-createComment :: Auth -> Name Owner -> Name Repo -> Id Issue -> Text-            -> IO (Either Error Comment)-createComment auth user repo iss body =-    executeRequest auth $ createCommentR user repo iss body- -- | Create a comment. -- See <https://developer.github.com/v3/issues/comments/#create-a-comment>-createCommentR :: Name Owner -> Name Repo -> Id Issue -> Text -> Request 'RW Comment+createCommentR :: Name Owner -> Name Repo -> IssueNumber -> Text -> Request 'RW Comment createCommentR user repo iss body =     command Post parts (encode $ NewComment body)   where     parts = ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iss, "comments"]  -- | Edit a comment.------ > editComment (User (user, password)) user repo commentid--- >  "new words"-editComment :: Auth -> Name Owner -> Name Repo -> Id Comment -> Text-            -> IO (Either Error Comment)-editComment auth user repo commid body =-    executeRequest auth $ editCommentR user repo commid body---- | Edit a comment. -- See <https://developer.github.com/v3/issues/comments/#edit-a-comment> editCommentR :: Name Owner -> Name Repo -> Id Comment -> Text -> Request 'RW Comment editCommentR user repo commid body =@@ -92,17 +44,9 @@     parts = ["repos", toPathPart user, toPathPart repo, "issues", "comments", toPathPart commid]  -- | Delete a comment.------ > deleteComment (User (user, password)) user repo commentid-deleteComment :: Auth -> Name Owner -> Name Repo -> Id Comment-              -> IO (Either Error ())-deleteComment auth user repo commid =-    executeRequest auth $ deleteCommentR user repo commid---- | Delete a comment. -- See <https://developer.github.com/v3/issues/comments/#delete-a-comment>-deleteCommentR :: Name Owner -> Name Repo -> Id Comment -> Request 'RW ()+deleteCommentR :: Name Owner -> Name Repo -> Id Comment -> GenRequest 'MtUnit 'RW () deleteCommentR user repo commid =-    command Delete parts mempty+    Command Delete parts mempty   where     parts = ["repos", toPathPart user, toPathPart repo, "issues", "comments", toPathPart commid]
src/GitHub/Endpoints/Issues/Events.hs view
@@ -1,78 +1,29 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The Github issue events API, which is described on -- <http://developer.github.com/v3/issues/events/>+ module GitHub.Endpoints.Issues.Events (-    eventsForIssue,-    eventsForIssue',     eventsForIssueR,-    eventsForRepo,-    eventsForRepo',     eventsForRepoR,-    event,-    event',     eventR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | All events that have happened on an issue.------ > eventsForIssue "thoughtbot" "paperclip" 49-eventsForIssue :: Name Owner -> Name Repo -> Id Issue -> IO (Either Error (Vector IssueEvent))-eventsForIssue = eventsForIssue' Nothing---- | All events that have happened on an issue, using authentication.------ > eventsForIssue' (User (user, password)) "thoughtbot" "paperclip" 49-eventsForIssue' :: Maybe Auth -> Name Owner -> Name Repo -> Id Issue -> IO (Either Error (Vector IssueEvent))-eventsForIssue' auth user repo iid =-    executeRequestMaybe auth $ eventsForIssueR user repo iid FetchAll- -- | List events for an issue. -- See <https://developer.github.com/v3/issues/events/#list-events-for-an-issue> eventsForIssueR :: Name Owner -> Name Repo -> Id Issue -> FetchCount -> Request k (Vector IssueEvent) eventsForIssueR user repo iid =     pagedQuery ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iid, "events"] [] --- | All the events for all issues in a repo.------ > eventsForRepo "thoughtbot" "paperclip"-eventsForRepo :: Name Owner -> Name Repo -> IO (Either Error (Vector IssueEvent))-eventsForRepo = eventsForRepo' Nothing---- | All the events for all issues in a repo, using authentication.------ > eventsForRepo' (User (user, password)) "thoughtbot" "paperclip"-eventsForRepo' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector IssueEvent))-eventsForRepo' auth user repo =-    executeRequestMaybe auth $ eventsForRepoR user repo FetchAll- -- | List events for a repository. -- See <https://developer.github.com/v3/issues/events/#list-events-for-a-repository> eventsForRepoR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector IssueEvent) eventsForRepoR user repo =     pagedQuery ["repos", toPathPart user, toPathPart repo, "issues", "events"] []---- | Details on a specific event, by the event's ID.------ > event "thoughtbot" "paperclip" 5335772-event :: Name Owner -> Name Repo -> Id IssueEvent -> IO (Either Error IssueEvent)-event = event' Nothing---- | Details on a specific event, by the event's ID, using authentication.------ > event' (User (user, password)) "thoughtbot" "paperclip" 5335772-event' :: Maybe Auth -> Name Owner -> Name Repo -> Id IssueEvent -> IO (Either Error IssueEvent)-event' auth user repo eid =-    executeRequestMaybe auth $ eventR user repo eid  -- | Query a single event. -- See <https://developer.github.com/v3/issues/events/#get-a-single-event>
src/GitHub/Endpoints/Issues/Labels.hs view
@@ -1,151 +1,59 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The API for dealing with labels on Github issues as described on -- <http://developer.github.com/v3/issues/labels/>.+ module GitHub.Endpoints.Issues.Labels (-    labelsOnRepo,-    labelsOnRepo',     labelsOnRepoR,-    label,-    label',     labelR,-    createLabel,     createLabelR,-    updateLabel,     updateLabelR,-    deleteLabel,     deleteLabelR,-    labelsOnIssue,-    labelsOnIssue',     labelsOnIssueR,-    addLabelsToIssue,     addLabelsToIssueR,-    removeLabelFromIssue,     removeLabelFromIssueR,-    replaceAllLabelsForIssue,     replaceAllLabelsForIssueR,-    removeAllLabelsFromIssue,     removeAllLabelsFromIssueR,-    labelsOnMilestone,-    labelsOnMilestone',     labelsOnMilestoneR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | All the labels available to use on any issue in the repo.------ > labelsOnRepo "thoughtbot" "paperclip"-labelsOnRepo :: Name Owner -> Name Repo -> IO (Either Error (Vector IssueLabel))-labelsOnRepo = labelsOnRepo' Nothing---- | All the labels available to use on any issue in the repo using authentication.------ > labelsOnRepo' (Just (User (user password))) "thoughtbot" "paperclip"-labelsOnRepo' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector IssueLabel))-labelsOnRepo' auth user repo =-    executeRequestMaybe auth $ labelsOnRepoR user repo FetchAll- -- | List all labels for this repository. -- See <https://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository> labelsOnRepoR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector IssueLabel) labelsOnRepoR user repo =     pagedQuery ["repos", toPathPart user, toPathPart repo, "labels"] [] --- | A label by name.------ > label "thoughtbot" "paperclip" "bug"-label :: Name Owner -> Name Repo -> Name IssueLabel -> IO (Either Error IssueLabel)-label = label' Nothing---- | A label by name using authentication.------ > label' (Just (User (user password))) "thoughtbot" "paperclip" "bug"-label' :: Maybe Auth -> Name Owner -> Name Repo -> Name IssueLabel -> IO (Either Error IssueLabel)-label' auth user repo lbl =-    executeRequestMaybe auth $ labelR user repo lbl- -- | Query a single label. -- See <https://developer.github.com/v3/issues/labels/#get-a-single-label> labelR :: Name Owner -> Name Repo -> Name IssueLabel -> Request k IssueLabel labelR user repo lbl =     query ["repos", toPathPart user, toPathPart repo, "labels", toPathPart lbl] [] --- | Create a label------ > createLabel (User (user password)) "thoughtbot" "paperclip" "bug" "f29513"-createLabel :: Auth -> Name Owner -> Name Repo -> Name IssueLabel -> String -> IO (Either Error IssueLabel)-createLabel auth user repo lbl color =-    executeRequest auth $ createLabelR user repo lbl color- -- | Create a label. -- See <https://developer.github.com/v3/issues/labels/#create-a-label>-createLabelR :: Name Owner -> Name Repo -> Name IssueLabel -> String -> Request 'RW IssueLabel-createLabelR user repo lbl color =-    command Post paths $ encode body-  where-    paths = ["repos", toPathPart user, toPathPart repo, "labels"]-    body = object ["name" .= untagName lbl, "color" .= color]---- | Update a label------ > updateLabel (User (user password)) "thoughtbot" "paperclip" "bug" "new-bug" "ff1111"-updateLabel :: Auth-            -> Name Owner-            -> Name Repo-            -> Name IssueLabel   -- ^ old label name-            -> Name IssueLabel   -- ^ new label name-            -> String            -- ^ new color-            -> IO (Either Error IssueLabel)-updateLabel auth user repo oldLbl newLbl color =-    executeRequest auth $ updateLabelR user repo oldLbl newLbl color+createLabelR :: Name Owner -> Name Repo -> NewIssueLabel -> Request 'RW IssueLabel+createLabelR user repo =+    command Post ["repos", toPathPart user, toPathPart repo, "labels"] . encode  -- | Update a label. -- See <https://developer.github.com/v3/issues/labels/#update-a-label> updateLabelR :: Name Owner              -> Name Repo              -> Name IssueLabel   -- ^ old label name-             -> Name IssueLabel   -- ^ new label name-             -> String            -- ^ new color+             -> UpdateIssueLabel   -- ^ new label              -> Request 'RW IssueLabel-updateLabelR user repo oldLbl newLbl color =-    command Patch paths (encode body)-  where-    paths = ["repos", toPathPart user, toPathPart repo, "labels", toPathPart oldLbl]-    body = object ["name" .= untagName newLbl, "color" .= color]---- | Delete a label------ > deleteLabel (User (user password)) "thoughtbot" "paperclip" "bug"-deleteLabel :: Auth -> Name Owner -> Name Repo -> Name IssueLabel -> IO (Either Error ())-deleteLabel auth user repo lbl =-    executeRequest auth $ deleteLabelR user repo lbl+updateLabelR user repo oldLbl =+    command Patch ["repos", toPathPart user, toPathPart repo, "labels", toPathPart oldLbl] . encode  -- | Delete a label. -- See <https://developer.github.com/v3/issues/labels/#delete-a-label>-deleteLabelR :: Name Owner -> Name Repo -> Name IssueLabel -> Request 'RW ()+deleteLabelR :: Name Owner -> Name Repo -> Name IssueLabel -> GenRequest 'MtUnit 'RW () deleteLabelR user repo lbl =-    command Delete ["repos", toPathPart user, toPathPart repo, "labels", toPathPart lbl] mempty---- | The labels on an issue in a repo.------ > labelsOnIssue "thoughtbot" "paperclip" 585-labelsOnIssue :: Name Owner -> Name Repo -> Id Issue -> IO (Either Error (Vector IssueLabel))-labelsOnIssue = labelsOnIssue' Nothing---- | The labels on an issue in a repo using authentication.------ > labelsOnIssue' (Just (User (user password))) "thoughtbot" "paperclip" (Id 585)-labelsOnIssue' :: Maybe Auth -> Name Owner -> Name Repo -> Id Issue -> IO (Either Error (Vector IssueLabel))-labelsOnIssue' auth user repo iid =-    executeRequestMaybe auth $ labelsOnIssueR user repo iid FetchAll+    Command Delete ["repos", toPathPart user, toPathPart repo, "labels", toPathPart lbl] mempty  -- | List labels on an issue. -- See <https://developer.github.com/v3/issues/labels/#list-labels-on-an-issue>@@ -153,19 +61,6 @@ labelsOnIssueR user repo iid =     pagedQuery ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iid, "labels"] [] --- | Add labels to an issue.------ > addLabelsToIssue (User (user password)) "thoughtbot" "paperclip" (Id 585) ["Label1" "Label2"]-addLabelsToIssue :: Foldable f-                 => Auth-                 -> Name Owner-                 -> Name Repo-                 -> Id Issue-                 -> f (Name IssueLabel)-                 -> IO (Either Error (Vector IssueLabel))-addLabelsToIssue auth user repo iid lbls =-    executeRequest auth $ addLabelsToIssueR user repo iid lbls- -- | Add lables to an issue. -- See <https://developer.github.com/v3/issues/labels/#add-labels-to-an-issue> addLabelsToIssueR :: Foldable f@@ -180,30 +75,10 @@     paths = ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iid, "labels"]  -- | Remove a label from an issue.------ > removeLabelFromIssue (User (user password)) "thoughtbot" "paperclip" (Id 585) "bug"-removeLabelFromIssue :: Auth -> Name Owner -> Name Repo -> Id Issue -> Name IssueLabel -> IO (Either Error ())-removeLabelFromIssue auth user repo iid lbl =-    executeRequest auth $ removeLabelFromIssueR user repo iid lbl---- | Remove a label from an issue. -- See <https://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue>-removeLabelFromIssueR :: Name Owner -> Name Repo -> Id Issue -> Name IssueLabel -> Request 'RW ()+removeLabelFromIssueR :: Name Owner -> Name Repo -> Id Issue -> Name IssueLabel -> GenRequest 'MtUnit 'RW () removeLabelFromIssueR user repo iid lbl =-    command Delete ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iid, "labels", toPathPart lbl] mempty---- | Replace all labels on an issue. Sending an empty list will remove all labels from the issue.------ > replaceAllLabelsForIssue (User (user password)) "thoughtbot" "paperclip" (Id 585) ["Label1" "Label2"]-replaceAllLabelsForIssue :: Foldable f-                         => Auth-                         -> Name Owner-                         -> Name Repo-                         -> Id Issue-                         -> f (Name IssueLabel)-                         -> IO (Either Error (Vector IssueLabel))-replaceAllLabelsForIssue auth user repo iid lbls =-    executeRequest auth $ replaceAllLabelsForIssueR user repo iid lbls+    Command Delete ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iid, "labels", toPathPart lbl] mempty  -- | Replace all labels on an issue. -- See <https://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue>@@ -221,30 +96,10 @@     paths = ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iid, "labels"]  -- | Remove all labels from an issue.------ > removeAllLabelsFromIssue (User (user password)) "thoughtbot" "paperclip" (Id 585)-removeAllLabelsFromIssue :: Auth -> Name Owner -> Name Repo -> Id Issue -> IO (Either Error ())-removeAllLabelsFromIssue auth user repo iid =-    executeRequest auth $ removeAllLabelsFromIssueR user repo iid---- | Remove all labels from an issue. -- See <https://developer.github.com/v3/issues/labels/#remove-all-labels-from-an-issue>-removeAllLabelsFromIssueR :: Name Owner -> Name Repo -> Id Issue -> Request 'RW ()+removeAllLabelsFromIssueR :: Name Owner -> Name Repo -> Id Issue -> GenRequest 'MtUnit 'RW () removeAllLabelsFromIssueR user repo iid =-    command Delete ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iid, "labels"] mempty---- | All the labels on a repo's milestone given the milestone ID.------ > labelsOnMilestone "thoughtbot" "paperclip" (Id 2)-labelsOnMilestone :: Name Owner -> Name Repo -> Id Milestone -> IO (Either Error (Vector IssueLabel))-labelsOnMilestone = labelsOnMilestone' Nothing---- | All the labels on a repo's milestone given the milestone ID using authentication.------ > labelsOnMilestone' (Just (User (user password))) "thoughtbot" "paperclip" (Id 2)-labelsOnMilestone' :: Maybe Auth -> Name Owner -> Name Repo -> Id Milestone -> IO (Either Error (Vector IssueLabel))-labelsOnMilestone' auth user repo mid =-    executeRequestMaybe auth $ labelsOnMilestoneR user repo mid FetchAll+    Command Delete ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iid, "labels"] mempty  -- | Query labels for every issue in a milestone. -- See <https://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone>
src/GitHub/Endpoints/Issues/Milestones.hs view
@@ -1,52 +1,47 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The milestones API as described on -- <http://developer.github.com/v3/issues/milestones/>.+ module GitHub.Endpoints.Issues.Milestones (-    milestones,-    milestones',     milestonesR,-    milestone,     milestoneR,+    createMilestoneR,+    updateMilestoneR,+    deleteMilestoneR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | All milestones in the repo.------ > milestones "thoughtbot" "paperclip"-milestones :: Name Owner -> Name Repo -> IO (Either Error (Vector Milestone))-milestones = milestones' Nothing---- | All milestones in the repo, using authentication.------ > milestones' (User (user, passwordG) "thoughtbot" "paperclip"-milestones' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector Milestone))-milestones' auth user repo =-    executeRequestMaybe auth $ milestonesR user repo FetchAll- -- | List milestones for a repository. -- See <https://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository> milestonesR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector Milestone) milestonesR user repo =     pagedQuery ["repos", toPathPart user, toPathPart repo, "milestones"] [] --- | Details on a specific milestone, given it's milestone number.------ > milestone "thoughtbot" "paperclip" (Id 2)-milestone :: Name Owner -> Name Repo -> Id Milestone -> IO (Either Error Milestone)-milestone user repo mid =-    executeRequest' $ milestoneR user repo mid- -- | Query a single milestone. -- See <https://developer.github.com/v3/issues/milestones/#get-a-single-milestone> milestoneR :: Name Owner -> Name Repo -> Id Milestone -> Request k Milestone milestoneR user repo mid =     query ["repos", toPathPart user, toPathPart repo, "milestones", toPathPart mid] []++-- | Create a milestone.+-- See <https://developer.github.com/v3/issues/milestones/#create-a-milestone>+createMilestoneR :: Name Owner -> Name Repo -> NewMilestone -> Request 'RW Milestone+createMilestoneR user repo =+    command Post ["repos", toPathPart user, toPathPart repo, "milestones"] . encode++-- | Update a milestone.+-- See <https://developer.github.com/v3/issues/milestones/#update-a-milestone>+updateMilestoneR :: Name Owner -> Name Repo -> Id Milestone -> UpdateMilestone -> Request 'RW Milestone+updateMilestoneR user repo mid =+    command Patch ["repos", toPathPart user, toPathPart repo, "milestones", toPathPart mid ] . encode++-- | Delete a milestone.+-- See <https://developer.github.com/v3/issues/milestones/#delete-a-milestone>+deleteMilestoneR :: Name Owner -> Name Repo -> Id Milestone -> GenRequest 'MtUnit 'RW ()+deleteMilestoneR user repo mid =+    Command Delete+        ["repos", toPathPart user, toPathPart repo, "milestones", toPathPart mid] mempty
src/GitHub/Endpoints/Organizations.hs view
@@ -1,53 +1,26 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The orgs API as described on <http://developer.github.com/v3/orgs/>.+ module GitHub.Endpoints.Organizations (-    publicOrganizationsFor,-    publicOrganizationsFor',     publicOrganizationsForR,-    publicOrganization,-    publicOrganization',     publicOrganizationR,+    organizationsR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | The public organizations for a user, given the user's login, with authorization------ > publicOrganizationsFor' (Just ("github-username", "github-password")) "mike-burns"-publicOrganizationsFor' :: Maybe Auth -> Name User -> IO (Either Error (Vector SimpleOrganization))-publicOrganizationsFor' auth org =-    executeRequestMaybe auth $ publicOrganizationsForR org FetchAll---- | List user organizations. The public organizations for a user, given the user's login.------ > publicOrganizationsFor "mike-burns"-publicOrganizationsFor :: Name User -> IO (Either Error (Vector SimpleOrganization))-publicOrganizationsFor = publicOrganizationsFor' Nothing+-- | List all user organizations.+-- See <https://developer.github.com/v3/orgs/#list-your-organizations>+organizationsR :: FetchCount -> Request k (Vector SimpleOrganization)+organizationsR = pagedQuery ["user", "orgs"] [] --- | List user organizations.+-- | List public user organizations. -- See <https://developer.github.com/v3/orgs/#list-user-organizations> publicOrganizationsForR :: Name User -> FetchCount -> Request k (Vector SimpleOrganization) publicOrganizationsForR user = pagedQuery ["users", toPathPart user, "orgs"] []---- | Details on a public organization. Takes the organization's login.------ > publicOrganization' (Just ("github-username", "github-password")) "thoughtbot"-publicOrganization' :: Maybe Auth -> Name Organization -> IO (Either Error Organization)-publicOrganization' auth = executeRequestMaybe auth . publicOrganizationR---- | Query an organization. Details on a public organization. Takes the organization's login.------ > publicOrganization "thoughtbot"-publicOrganization :: Name Organization -> IO (Either Error Organization)-publicOrganization = publicOrganization' Nothing  -- | Query an organization. -- See <https://developer.github.com/v3/orgs/#get-an-organization>
src/GitHub/Endpoints/Organizations/Members.hs view
@@ -1,42 +1,20 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The organization members API as described on -- <http://developer.github.com/v3/orgs/members/>.+ module GitHub.Endpoints.Organizations.Members (-    membersOf,-    membersOf',     membersOfR,     membersOfWithR,-    isMemberOf,-    isMemberOf',     isMemberOfR,     orgInvitationsR,+    orgMembershipR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | All the users who are members of the specified organization,--- | with or without authentication.------ > membersOf' (Just $ OAuth "token") "thoughtbot"-membersOf' :: Maybe Auth -> Name Organization -> IO (Either Error (Vector SimpleUser))-membersOf' auth org =-    executeRequestMaybe auth $ membersOfR org FetchAll---- | All the users who are members of the specified organization,--- | without authentication.------ > membersOf "thoughtbot"-membersOf :: Name Organization -> IO (Either Error (Vector SimpleUser))-membersOf = membersOf' Nothing- -- | All the users who are members of the specified organization. -- -- See <https://developer.github.com/v3/orgs/members/#members-list>@@ -59,26 +37,11 @@         OrgMemberRoleAdmin  -> "admin"         OrgMemberRoleMember -> "member" --- | Check if a user is a member of an organization,--- | with or without authentication.------ > isMemberOf' (Just $ OAuth "token") "phadej" "haskell-infra"-isMemberOf' :: Maybe Auth -> Name User -> Name Organization -> IO (Either Error Bool)-isMemberOf' auth user org =-    executeRequestMaybe auth $ isMemberOfR user org---- | Check if a user is a member of an organization,--- | without authentication.------ > isMemberOf "phadej" "haskell-infra"-isMemberOf :: Name User -> Name Organization -> IO (Either Error Bool)-isMemberOf = isMemberOf' Nothing- -- | Check if a user is a member of an organization. -- -- See <https://developer.github.com/v3/orgs/members/#check-membership>-isMemberOfR :: Name User -> Name Organization -> Request k Bool-isMemberOfR user org = StatusQuery statusOnlyOk $+isMemberOfR :: Name User -> Name Organization -> GenRequest 'MtStatus rw Bool+isMemberOfR user org =     Query [ "orgs", toPathPart org, "members", toPathPart user ] []  -- | List pending organization invitations@@ -86,3 +49,10 @@ -- See <https://developer.github.com/v3/orgs/members/#list-pending-organization-invitations> orgInvitationsR :: Name Organization -> FetchCount -> Request 'RA (Vector Invitation) orgInvitationsR org = pagedQuery ["orgs", toPathPart org, "invitations"] []++-- | Get user membership information in an organization+--+-- See <https://docs.github.com/en/rest/orgs/members#get-organization-membership-for-a-user>+orgMembershipR :: Name User -> Name Organization -> Request 'RA Membership+orgMembershipR user org =+    Query [ "orgs", toPathPart org, "memberships", toPathPart user ] []
+ src/GitHub/Endpoints/Organizations/OutsideCollaborators.hs view
@@ -0,0 +1,18 @@+-- |+-- The organization members API as described on+-- <https://developer.github.com/v3/orgs/outside_collaborators/>.++module GitHub.Endpoints.Organizations.OutsideCollaborators (+    outsideCollaboratorsR,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | All the users who are outside collaborators of the specified organization.+--+-- See <https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators>+outsideCollaboratorsR :: Name Organization -> FetchCount -> Request k (Vector SimpleUser)+outsideCollaboratorsR organization =+    pagedQuery ["orgs", toPathPart organization, "outside_collaborators"] []
src/GitHub/Endpoints/Organizations/Teams.hs view
@@ -1,132 +1,56 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The Owner teams API as described on -- <http://developer.github.com/v3/orgs/teams/>.+ module GitHub.Endpoints.Organizations.Teams (-    teamsOf,-    teamsOf',     teamsOfR,-    teamInfoFor,-    teamInfoFor',     teamInfoForR,-    createTeamFor',     createTeamForR,-    editTeam',     editTeamR,-    deleteTeam',     deleteTeamR,     listTeamMembersR,-    listTeamRepos,-    listTeamRepos',     listTeamReposR,-    addOrUpdateTeamRepo',     addOrUpdateTeamRepoR,-    teamMembershipInfoFor,-    teamMembershipInfoFor',     teamMembershipInfoForR,-    addTeamMembershipFor',     addTeamMembershipForR,-    deleteTeamMembershipFor',     deleteTeamMembershipForR,-    listTeamsCurrent',     listTeamsCurrentR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | List teams.  List the teams of an Owner.--- When authenticated, lists private teams visible to the authenticated user.--- When unauthenticated, lists only public teams for an Owner.------ > teamsOf' (Just $ OAuth "token") "thoughtbot"-teamsOf' :: Maybe Auth -> Name Organization -> IO (Either Error (Vector SimpleTeam))-teamsOf' auth org =-    executeRequestMaybe auth $ teamsOfR org FetchAll---- | List the public teams of an Owner.------ > teamsOf "thoughtbot"-teamsOf :: Name Organization -> IO (Either Error (Vector SimpleTeam))-teamsOf = teamsOf' Nothing- -- | List teams. -- See <https://developer.github.com/v3/orgs/teams/#list-teams> teamsOfR :: Name Organization -> FetchCount -> Request k (Vector SimpleTeam) teamsOfR org =     pagedQuery ["orgs", toPathPart org, "teams"] [] --- | The information for a single team, by team id.--- With authentication------ > teamInfoFor' (Just $ OAuth "token") 1010101-teamInfoFor' :: Maybe Auth -> Id Team -> IO (Either Error Team)-teamInfoFor' auth tid =-    executeRequestMaybe auth $ teamInfoForR tid---- | The information for a single team, by team id.------ > teamInfoFor' (Just $ OAuth "token") 1010101-teamInfoFor :: Id Team -> IO (Either Error Team)-teamInfoFor = teamInfoFor' Nothing- -- | Query team. -- See <https://developer.github.com/v3/orgs/teams/#get-team> teamInfoForR  :: Id Team -> Request k Team teamInfoForR tid =     query ["teams", toPathPart tid] [] --- | Create a team under an Owner------ > createTeamFor' (OAuth "token") "Owner" (CreateTeam "newteamname" "some description" [] PermssionPull)-createTeamFor' :: Auth-               -> Name Organization-               -> CreateTeam-               -> IO (Either Error Team)-createTeamFor' auth org cteam =-    executeRequest auth $ createTeamForR org cteam- -- | Create team. -- See <https://developer.github.com/v3/orgs/teams/#create-team> createTeamForR :: Name Organization -> CreateTeam -> Request 'RW Team createTeamForR org cteam =     command Post ["orgs", toPathPart org, "teams"] (encode cteam) --- | Edit a team, by id.------ > editTeamFor'-editTeam' :: Auth-          -> Id Team-          -> EditTeam-          -> IO (Either Error Team)-editTeam' auth tid eteam =-    executeRequest auth $ editTeamR tid eteam- -- | Edit team. -- See <https://developer.github.com/v3/orgs/teams/#edit-team> editTeamR :: Id Team -> EditTeam -> Request 'RW Team editTeamR tid eteam =     command Patch ["teams", toPathPart tid] (encode eteam) --- | Delete a team, by id. ----- > deleteTeam' (OAuth "token") 1010101-deleteTeam' :: Auth -> Id Team -> IO (Either Error ())-deleteTeam' auth tid =-    executeRequest auth $ deleteTeamR tid---- | Delete team.--- -- See <https://developer.github.com/v3/orgs/teams/#delete-team>-deleteTeamR :: Id Team -> Request 'RW ()+deleteTeamR :: Id Team -> GenRequest 'MtUnit 'RW () deleteTeamR tid =-    command Delete ["teams", toPathPart tid] mempty+    Command Delete ["teams", toPathPart tid] mempty  -- | List team members. --@@ -140,45 +64,17 @@         TeamMemberRoleMaintainer  -> "maintainer"         TeamMemberRoleMember      -> "member" --- | The repositories of a single team, by team id.--- With authentication------ > listTeamRepos' (Just $ GitHub.OAuth token) (GitHub.mkTeamId team_id)-listTeamRepos' :: Maybe Auth -> Id Team -> IO (Either Error (Vector Repo))-listTeamRepos' auth tid = executeRequestMaybe auth $ listTeamReposR tid FetchAll- -- | Query team repositories. -- See <https://developer.github.com/v3/orgs/teams/#list-team-repos> listTeamReposR :: Id Team -> FetchCount -> Request k (Vector Repo) listTeamReposR tid  =     pagedQuery ["teams", toPathPart tid, "repos"] [] --- | Retrieve repositories for a team.------ > listTeamRepos (GitHub.mkTeamId team_id)-listTeamRepos :: Id Team -> IO (Either Error (Vector Repo))-listTeamRepos = listTeamRepos' Nothing---- | Add a repository to a team or update the permission on the repository.------ > addOrUpdateTeamRepo' (OAuth "token") 1010101 "mburns" (Just PermissionPull)-addOrUpdateTeamRepo' :: Auth -> Id Team -> Name Organization -> Name Repo -> Permission -> IO (Either Error ())-addOrUpdateTeamRepo' auth tid org repo permission =-    executeRequest auth $ addOrUpdateTeamRepoR tid org repo permission- -- | Add or update a team repository. -- See <https://developer.github.com/v3/orgs/teams/#add-or-update-team-repository>-addOrUpdateTeamRepoR :: Id Team -> Name Organization -> Name Repo -> Permission -> Request 'RW ()+addOrUpdateTeamRepoR :: Id Team -> Name Organization -> Name Repo -> Permission -> GenRequest 'MtUnit 'RW () addOrUpdateTeamRepoR tid org repo permission =-    command Put' ["teams", toPathPart tid, "repos", toPathPart org, toPathPart repo] (encode $ AddTeamRepoPermission permission)---- | Retrieve team mebership information for a user.--- With authentication------ > teamMembershipInfoFor' (Just $ OAuth "token") 1010101 "mburns"-teamMembershipInfoFor' :: Maybe Auth -> Id Team -> Name Owner -> IO (Either Error TeamMembership)-teamMembershipInfoFor' auth tid user =-    executeRequestMaybe auth $ teamMembershipInfoForR tid user+    Command Put ["teams", toPathPart tid, "repos", toPathPart org, toPathPart repo] (encode $ AddTeamRepoPermission permission)  -- | Query team membership. -- See <https://developer.github.com/v3/orgs/teams/#get-team-membership@@ -186,43 +82,17 @@ teamMembershipInfoForR tid user =     query ["teams", toPathPart tid, "memberships", toPathPart user] [] --- | Retrieve team mebership information for a user.------ > teamMembershipInfoFor 1010101 "mburns"-teamMembershipInfoFor :: Id Team -> Name Owner -> IO (Either Error TeamMembership)-teamMembershipInfoFor = teamMembershipInfoFor' Nothing---- | Add (or invite) a member to a team.------ > addTeamMembershipFor' (OAuth "token") 1010101 "mburns" RoleMember-addTeamMembershipFor' :: Auth -> Id Team -> Name Owner -> Role -> IO (Either Error TeamMembership)-addTeamMembershipFor' auth tid user role =-    executeRequest auth $ addTeamMembershipForR tid user role- -- | Add team membership. -- See <https://developer.github.com/v3/orgs/teams/#add-team-membership> addTeamMembershipForR :: Id Team -> Name Owner -> Role -> Request 'RW TeamMembership addTeamMembershipForR tid user role =     command Put ["teams", toPathPart tid, "memberships", toPathPart user] (encode $ CreateTeamMembership role) --- | Delete a member of a team.------ > deleteTeamMembershipFor' (OAuth "token") 1010101 "mburns"-deleteTeamMembershipFor' :: Auth -> Id Team -> Name Owner -> IO (Either Error ())-deleteTeamMembershipFor' auth tid user =-    executeRequest auth $ deleteTeamMembershipForR tid user- -- | Remove team membership. -- See <https://developer.github.com/v3/orgs/teams/#remove-team-membership>-deleteTeamMembershipForR :: Id Team -> Name Owner -> Request 'RW ()+deleteTeamMembershipForR :: Id Team -> Name Owner -> GenRequest 'MtUnit 'RW () deleteTeamMembershipForR tid user =-    command Delete ["teams", toPathPart tid, "memberships", toPathPart user] mempty---- | List teams for current authenticated user------ > listTeamsCurrent' (OAuth "token")-listTeamsCurrent' :: Auth -> IO (Either Error (Vector Team))-listTeamsCurrent' auth = executeRequest auth $ listTeamsCurrentR FetchAll+    Command Delete ["teams", toPathPart tid, "memberships", toPathPart user] mempty  -- | List user teams. -- See <https://developer.github.com/v3/orgs/teams/#list-user-teams>
src/GitHub/Endpoints/PullRequests.hs view
@@ -1,52 +1,25 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The pull requests API as documented at -- <http://developer.github.com/v3/pulls/>.+ module GitHub.Endpoints.PullRequests (-    pullRequestsFor,-    pullRequestsFor',     pullRequestsForR,-    pullRequest',-    pullRequest,     pullRequestR,-    createPullRequest,+    pullRequestDiffR,+    pullRequestPatchR,     createPullRequestR,-    updatePullRequest,     updatePullRequestR,-    pullRequestCommits',-    pullRequestCommitsIO,     pullRequestCommitsR,-    pullRequestFiles',-    pullRequestFiles,     pullRequestFilesR,-    isPullRequestMerged,     isPullRequestMergedR,-    mergePullRequest,     mergePullRequestR,     module GitHub.Data     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude ()---- | All open pull requests for the repo, by owner and repo name.------ > pullRequestsFor "rails" "rails"-pullRequestsFor :: Name Owner -> Name Repo -> IO (Either Error (Vector SimplePullRequest))-pullRequestsFor user repo =-    executeRequest' $ pullRequestsForR user repo mempty FetchAll---- | All open pull requests for the repo, by owner and repo name.------ > pullRequestsFor "rails" "rails"-pullRequestsFor' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector SimplePullRequest))-pullRequestsFor' auth user repo =-    executeRequestMaybe auth $ pullRequestsForR user repo mempty FetchAll+import Data.ByteString.Lazy (ByteString)  -- | List pull requests. -- See <https://developer.github.com/v3/pulls/#list-pull-requests>@@ -60,36 +33,24 @@     ["repos", toPathPart user, toPathPart repo, "pulls"]     (prModToQueryString opts) --- | A detailed pull request, which has much more information. This takes the--- repo owner and name along with the number assigned to the pull request.--- With authentification.------ > pullRequest' (Just ("github-username", "github-password")) "thoughtbot" "paperclip" 562-pullRequest' :: Maybe Auth -> Name Owner -> Name Repo -> Id PullRequest -> IO (Either Error PullRequest)-pullRequest' auth user repo prid =-    executeRequestMaybe auth $ pullRequestR user repo prid+-- | Query a single pull request to obtain the diff+-- See <https://developer.github.com/v3/pulls/#get-a-single-pull-request>+pullRequestDiffR :: Name Owner -> Name Repo -> IssueNumber -> GenRequest 'MtDiff rw ByteString+pullRequestDiffR user repo prid =+    Query ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid] [] --- | A detailed pull request, which has much more information. This takes the--- repo owner and name along with the number assigned to the pull request.------ > pullRequest "thoughtbot" "paperclip" 562-pullRequest :: Name Owner -> Name Repo -> Id PullRequest -> IO (Either Error PullRequest)-pullRequest = pullRequest' Nothing+-- | Query a single pull request to obtain the patch+-- See <https://developer.github.com/v3/pulls/#get-a-single-pull-request>+pullRequestPatchR :: Name Owner -> Name Repo -> IssueNumber -> GenRequest 'MtPatch rw ByteString+pullRequestPatchR user repo prid =+    Query ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid] []  -- | Query a single pull request. -- See <https://developer.github.com/v3/pulls/#get-a-single-pull-request>-pullRequestR :: Name Owner -> Name Repo -> Id PullRequest -> Request k PullRequest+pullRequestR :: Name Owner -> Name Repo -> IssueNumber -> Request k PullRequest pullRequestR user repo prid =     query ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid] [] -createPullRequest :: Auth-                  -> Name Owner-                  -> Name Repo-                  -> CreatePullRequest-                  -> IO (Either Error PullRequest)-createPullRequest auth user repo cpr =-    executeRequest auth $ createPullRequestR user repo cpr- -- | Create a pull request. -- See <https://developer.github.com/v3/pulls/#create-a-pull-request> createPullRequestR :: Name Owner@@ -99,85 +60,38 @@ createPullRequestR user repo cpr =     command Post ["repos", toPathPart user, toPathPart repo, "pulls"] (encode cpr) --- | Update a pull request-updatePullRequest :: Auth -> Name Owner -> Name Repo -> Id PullRequest -> EditPullRequest -> IO (Either Error PullRequest)-updatePullRequest auth user repo prid epr =-    executeRequest auth $ updatePullRequestR user repo prid epr- -- | Update a pull request. -- See <https://developer.github.com/v3/pulls/#update-a-pull-request> updatePullRequestR :: Name Owner                    -> Name Repo-                   -> Id PullRequest+                   -> IssueNumber                    -> EditPullRequest                    -> Request 'RW PullRequest updatePullRequestR user repo prid epr =     command Patch ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid] (encode epr) --- | All the commits on a pull request, given the repo owner, repo name, and--- the number of the pull request.--- With authentification.------ > pullRequestCommits' (Just ("github-username", "github-password")) "thoughtbot" "paperclip" 688-pullRequestCommits' :: Maybe Auth -> Name Owner -> Name Repo -> Id PullRequest -> IO (Either Error (Vector Commit))-pullRequestCommits' auth user repo prid =-    executeRequestMaybe auth $ pullRequestCommitsR user repo prid FetchAll---- | All the commits on a pull request, given the repo owner, repo name, and--- the number of the pull request.------ > pullRequestCommits "thoughtbot" "paperclip" 688-pullRequestCommitsIO :: Name Owner -> Name Repo -> Id PullRequest -> IO (Either Error (Vector Commit))-pullRequestCommitsIO = pullRequestCommits' Nothing- -- | List commits on a pull request. -- See <https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request>-pullRequestCommitsR :: Name Owner -> Name Repo -> Id PullRequest -> FetchCount -> Request k (Vector Commit)+pullRequestCommitsR :: Name Owner -> Name Repo -> IssueNumber -> FetchCount -> Request k (Vector Commit) pullRequestCommitsR user repo prid =     pagedQuery ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid, "commits"] [] --- | The individual files that a pull request patches. Takes the repo owner and--- name, plus the number assigned to the pull request.--- With authentification.------ > pullRequestFiles' (Just ("github-username", "github-password")) "thoughtbot" "paperclip" 688-pullRequestFiles' :: Maybe Auth -> Name Owner -> Name Repo -> Id PullRequest -> IO (Either Error (Vector File))-pullRequestFiles' auth user repo prid =-    executeRequestMaybe auth $ pullRequestFilesR user repo prid FetchAll---- | The individual files that a pull request patches. Takes the repo owner and--- name, plus the number assigned to the pull request.------ > pullRequestFiles "thoughtbot" "paperclip" 688-pullRequestFiles :: Name Owner -> Name Repo -> Id PullRequest -> IO (Either Error (Vector File))-pullRequestFiles = pullRequestFiles' Nothing- -- | List pull requests files. -- See <https://developer.github.com/v3/pulls/#list-pull-requests-files>-pullRequestFilesR :: Name Owner -> Name Repo -> Id PullRequest -> FetchCount -> Request k (Vector File)+pullRequestFilesR :: Name Owner -> Name Repo -> IssueNumber -> FetchCount -> Request k (Vector File) pullRequestFilesR user repo prid =     pagedQuery ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid, "files"] [] --- | Check if pull request has been merged.-isPullRequestMerged :: Auth -> Name Owner -> Name Repo -> Id PullRequest -> IO (Either Error Bool)-isPullRequestMerged auth user repo prid =-    executeRequest auth $ isPullRequestMergedR user repo prid- -- | Query if a pull request has been merged. -- See <https://developer.github.com/v3/pulls/#get-if-a-pull-request-has-been-merged>-isPullRequestMergedR :: Name Owner -> Name Repo -> Id PullRequest -> Request k Bool-isPullRequestMergedR user repo prid = StatusQuery statusOnlyOk $+isPullRequestMergedR :: Name Owner -> Name Repo -> IssueNumber -> GenRequest 'MtStatus rw Bool+isPullRequestMergedR user repo prid =     Query ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid, "merge"] [] --- | Merge a pull request.-mergePullRequest :: Auth -> Name Owner -> Name Repo -> Id PullRequest -> Maybe Text -> IO (Either Error MergeResult)-mergePullRequest auth user repo prid commitMessage =-    executeRequest auth $ mergePullRequestR user repo prid commitMessage- -- | Merge a pull request (Merge Button). -- https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button-mergePullRequestR :: Name Owner -> Name Repo -> Id PullRequest -> Maybe Text -> Request 'RW MergeResult-mergePullRequestR user repo prid commitMessage = StatusQuery statusMerge $+mergePullRequestR :: Name Owner -> Name Repo -> IssueNumber -> Maybe Text -> GenRequest 'MtStatus 'RW MergeResult+mergePullRequestR user repo prid commitMessage =     Command Put paths (encode $ buildCommitMessageMap commitMessage)   where     paths = ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid, "merge"]@@ -185,4 +99,3 @@     buildCommitMessageMap :: Maybe Text -> Value     buildCommitMessageMap (Just msg) = object ["commit_message" .= msg ]     buildCommitMessageMap Nothing    = object []-
src/GitHub/Endpoints/PullRequests/Comments.hs view
@@ -1,45 +1,46 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The pull request review comments API as described at -- <http://developer.github.com/v3/pulls/comments/>.+ module GitHub.Endpoints.PullRequests.Comments (-    pullRequestCommentsIO,     pullRequestCommentsR,-    pullRequestComment,     pullRequestCommentR,+    createPullCommentR,+    createPullCommentReplyR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | All the comments on a pull request with the given ID.------ > pullRequestComments "thoughtbot" "factory_girl" (Id 256)-pullRequestCommentsIO :: Name Owner -> Name Repo -> Id PullRequest -> IO (Either Error (Vector Comment))-pullRequestCommentsIO user repo prid =-    executeRequest' $ pullRequestCommentsR user repo prid FetchAll- -- | List comments on a pull request. -- See <https://developer.github.com/v3/pulls/comments/#list-comments-on-a-pull-request>-pullRequestCommentsR :: Name Owner -> Name Repo -> Id PullRequest -> FetchCount -> Request k (Vector Comment)+pullRequestCommentsR :: Name Owner -> Name Repo -> IssueNumber -> FetchCount -> Request k (Vector Comment) pullRequestCommentsR user repo prid =     pagedQuery ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid, "comments"] [] --- | One comment on a pull request, by the comment's ID.------ > pullRequestComment "thoughtbot" "factory_girl" (Id 301819)-pullRequestComment :: Name Owner -> Name Repo -> Id Comment -> IO (Either Error Comment)-pullRequestComment user repo cid =-    executeRequest' $ pullRequestCommentR user repo cid- -- | Query a single comment. -- See <https://developer.github.com/v3/pulls/comments/#get-a-single-comment> pullRequestCommentR :: Name Owner -> Name Repo -> Id Comment -> Request k Comment pullRequestCommentR user repo cid =     query ["repos", toPathPart user, toPathPart repo, "pulls", "comments", toPathPart cid] []++-- | Create a comment.+--+-- See <https://developer.github.com/v3/pulls/comments/#create-a-comment>+createPullCommentR :: Name Owner -> Name Repo -> IssueNumber -> Text -> Text -> Int -> Text -> Request 'RW Comment+createPullCommentR user repo iss commit path position body =+    command Post parts (encode $ NewPullComment commit path position body)+  where+    parts = ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart iss, "comments"]++-- | Create a comment reply.+--+-- See <https://developer.github.com/v3/pulls/comments/#create-a-review-comment-reply>+createPullCommentReplyR :: Name Owner -> Name Repo -> IssueNumber -> Id Comment -> Text -> Request 'RW Comment+createPullCommentReplyR user repo iss cid body =+    command Post parts (encode $ PullCommentReply body)+  where+    parts = ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart iss+            , "comments", toPathPart cid, "replies"]
src/GitHub/Endpoints/PullRequests/Reviews.hs view
@@ -1,27 +1,15 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The reviews API as described on <http://developer.github.com/v3/pulls/reviews/>.+ module GitHub.Endpoints.PullRequests.Reviews     ( pullRequestReviewsR-    , pullRequestReviews-    , pullRequestReviews'     , pullRequestReviewR-    , pullRequestReview-    , pullRequestReview'     , pullRequestReviewCommentsR-    , pullRequestReviewCommentsIO-    , pullRequestReviewCommentsIO'     , module GitHub.Data     ) where  import GitHub.Data-import GitHub.Data.Id (Id) import GitHub.Internal.Prelude-import GitHub.Request-       (Request, executeRequest', executeRequestMaybe) import Prelude ()  -- | List reviews for a pull request.@@ -29,7 +17,7 @@ pullRequestReviewsR     :: Name Owner     -> Name Repo-    -> Id PullRequest+    -> IssueNumber     -> FetchCount     -> Request k (Vector Review) pullRequestReviewsR owner repo prid =@@ -43,37 +31,12 @@         ]         [] --- | All reviews for a pull request given the repo owner, repo name and the pull--- request id.------ > pullRequestReviews "thoughtbot" "paperclip" (Id 101)-pullRequestReviews-    :: Name Owner-    -> Name Repo-    -> Id PullRequest-    -> IO (Either Error (Vector Review))-pullRequestReviews owner repo prid =-    executeRequest' $ pullRequestReviewsR owner repo prid FetchAll---- | All reviews for a pull request given the repo owner, repo name and the pull--- request id. With authentication.------ > pullRequestReviews' (Just ("github-username", "github-password")) "thoughtbot" "paperclip" (Id 101)-pullRequestReviews'-    :: Maybe Auth-    -> Name Owner-    -> Name Repo-    -> Id PullRequest-    -> IO (Either Error (Vector Review))-pullRequestReviews' auth owner repo pr =-    executeRequestMaybe auth $ pullRequestReviewsR owner repo pr FetchAll- -- | Query a single pull request review. -- see <https://developer.github.com/v3/pulls/reviews/#get-a-single-review> pullRequestReviewR     :: Name Owner     -> Name Repo-    -> Id PullRequest+    -> IssueNumber     -> Id Review     -> Request k Review pullRequestReviewR owner repo prid rid =@@ -88,40 +51,12 @@         ]         [] --- | A detailed review on a pull request given the repo owner, repo name, pull--- request id and review id.------ > pullRequestReview "thoughtbot" "factory_girl" (Id 301819) (Id 332)-pullRequestReview-    :: Name Owner-    -> Name Repo-    -> Id PullRequest-    -> Id Review-    -> IO (Either Error Review)-pullRequestReview owner repo prid rid =-    executeRequest' $ pullRequestReviewR owner repo prid rid---- | A detailed review on a pull request given the repo owner, repo name, pull--- request id and review id. With authentication.------ > pullRequestReview' (Just ("github-username", "github-password"))--- "thoughtbot" "factory_girl" (Id 301819) (Id 332)-pullRequestReview'-    :: Maybe Auth-    -> Name Owner-    -> Name Repo-    -> Id PullRequest-    -> Id Review-    -> IO (Either Error Review)-pullRequestReview' auth owner repo prid rid =-    executeRequestMaybe auth $ pullRequestReviewR owner repo prid rid- -- | Query the comments for a single pull request review. -- see <https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review> pullRequestReviewCommentsR     :: Name Owner     -> Name Repo-    -> Id PullRequest+    -> IssueNumber     -> Id Review     -> Request k [ReviewComment] pullRequestReviewCommentsR owner repo prid rid =@@ -136,30 +71,3 @@         , "comments"         ]         []---- | All comments for a review on a pull request given the repo owner, repo--- name, pull request id and review id.------ > pullRequestReviewComments "thoughtbot" "factory_girl" (Id 301819) (Id 332)-pullRequestReviewCommentsIO-    :: Name Owner-    -> Name Repo-    -> Id PullRequest-    -> Id Review-    -> IO (Either Error [ReviewComment])-pullRequestReviewCommentsIO owner repo prid rid =-    executeRequest' $ pullRequestReviewCommentsR owner repo prid rid---- | All comments for a review on a pull request given the repo owner, repo--- name, pull request id and review id. With authentication.------ > pullRequestReviewComments' (Just ("github-username", "github-password")) "thoughtbot" "factory_girl" (Id 301819) (Id 332)-pullRequestReviewCommentsIO'-    :: Maybe Auth-    -> Name Owner-    -> Name Repo-    -> Id PullRequest-    -> Id Review-    -> IO (Either Error [ReviewComment])-pullRequestReviewCommentsIO' auth owner repo prid rid =-    executeRequestMaybe auth $ pullRequestReviewCommentsR owner repo prid rid
+ src/GitHub/Endpoints/RateLimit.hs view
@@ -0,0 +1,16 @@+-- |+-- The Github RateLimit API, as described at+-- <http://developer.github.com/v3/rate_limit/>.++module GitHub.Endpoints.RateLimit (+    rateLimitR,+    module GitHub.Data,+    ) where++import GitHub.Data+import Prelude ()++-- | Get your current rate limit status.+-- <https://developer.github.com/v3/rate_limit/#get-your-current-rate-limit-status>+rateLimitR :: Request k RateLimit+rateLimitR = query ["rate_limit"] []
+ src/GitHub/Endpoints/Reactions.hs view
@@ -0,0 +1,60 @@+-- |+-- The Reactions API as described at+-- <https://docs.github.com/en/rest/reactions/reactions?apiVersion=2022-11-28>.+module GitHub.Endpoints.Reactions (+  issueReactionsR,+  createIssueReactionR,+  deleteIssueReactionR,+  commentReactionsR,+  createCommentReactionR,+  deleteCommentReactionR,+  module GitHub.Data,+) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | List reactions for an issue.+-- See <https://docs.github.com/en/rest/reactions/reactions?apiVersion=2022-11-28#list-reactions-for-an-issue>+issueReactionsR :: Name Owner -> Name Repo -> Id Issue -> FetchCount -> Request k (Vector Reaction)+issueReactionsR owner repo iid =+  pagedQuery ["repos", toPathPart owner, toPathPart repo, "issues", toPathPart iid, "reactions"] []++-- | Create reaction for an issue comment.+-- See <https://docs.github.com/en/rest/reactions/reactions?apiVersion=2022-11-28#create-reaction-for-an-issue>+createIssueReactionR :: Name Owner -> Name Repo -> Id Issue -> ReactionContent -> Request 'RW Reaction+createIssueReactionR owner repo iid content =+    command Post parts (encode $ NewReaction content)+  where+    parts = ["repos", toPathPart owner, toPathPart repo, "issues", toPathPart iid, "reactions"]++-- | Delete an issue comment reaction.+-- See <https://docs.github.com/en/rest/reactions/reactions?apiVersion=2022-11-28#delete-an-issue-reaction>+deleteIssueReactionR :: Name Owner -> Name Repo -> Id Issue -> Id Reaction -> GenRequest 'MtUnit 'RW ()+deleteIssueReactionR owner repo iid rid =+    Command Delete parts mempty+  where+    parts = ["repos", toPathPart owner, toPathPart repo, "issues", toPathPart iid, "reactions", toPathPart rid]++-- | List reactions for an issue comment.+-- See <https://docs.github.com/en/rest/reactions/reactions?apiVersion=2022-11-28#list-reactions-for-an-issue-comment>+commentReactionsR :: Name Owner -> Name Repo -> Id Comment -> FetchCount -> Request k (Vector Reaction)+commentReactionsR owner repo cid =+  pagedQuery ["repos", toPathPart owner, toPathPart repo, "issues", "comments", toPathPart cid, "reactions"] []++-- | Create reaction for an issue comment.+-- See https://docs.github.com/en/rest/reactions/reactions?apiVersion=2022-11-28#create-reaction-for-an-issue-comment+createCommentReactionR :: Name Owner -> Name Repo -> Id Comment -> ReactionContent -> Request 'RW Reaction+createCommentReactionR owner repo cid content =+    command Post parts (encode $ NewReaction content)+  where+    parts = ["repos", toPathPart owner, toPathPart repo, "issues", "comments", toPathPart cid, "reactions"]++-- | Delete an issue comment reaction.+-- See <https://docs.github.com/en/rest/reactions/reactions?apiVersion=2022-11-28#delete-an-issue-comment-reaction>+deleteCommentReactionR :: Name Owner -> Name Repo -> Id Comment -> Id Reaction -> GenRequest 'MtUnit 'RW ()+deleteCommentReactionR owner repo cid rid =+    Command Delete parts mempty+  where+    parts = ["repos", toPathPart owner, toPathPart repo, "issues", "comments", toPathPart cid, "reactions", toPathPart rid]
src/GitHub/Endpoints/Repos.hs view
@@ -1,51 +1,27 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The Github Repos API, as documented at -- <http://developer.github.com/v3/repos/>+ module GitHub.Endpoints.Repos (     -- * Querying repositories-    currentUserRepos,     currentUserReposR,-    userRepos,-    userRepos',     userReposR,-    organizationRepos,-    organizationRepos',     organizationReposR,-    repository,-    repository',     repositoryR,-    contributors,-    contributors',     contributorsR,-    contributorsWithAnonymous,-    contributorsWithAnonymous',-    languagesFor,-    languagesFor',     languagesForR,-    tagsFor,-    tagsFor',     tagsForR,-    branchesFor,-    branchesFor',     branchesForR,      -- ** Create-    createRepo',     createRepoR,-    createOrganizationRepo',     createOrganizationRepoR,     forkExistingRepoR,      -- ** Edit-    editRepo,     editRepoR,      -- ** Delete-    deleteRepo,     deleteRepoR,      -- * Data@@ -54,7 +30,6 @@  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude ()  repoPublicityQueryString :: RepoPublicity -> QueryString@@ -65,65 +40,23 @@ repoPublicityQueryString RepoPublicityPrivate = [("type", Just "private")]  -- | List your repositories.-currentUserRepos :: Auth -> RepoPublicity -> IO (Either Error (Vector Repo))-currentUserRepos auth publicity =-    executeRequest auth $ currentUserReposR publicity FetchAll---- | List your repositories.--- See <https://developer.github.com/v3/repos/#list-your-repositories>+-- See <https://docs.github.com/en/rest/reference/repos#list-repositories-for-the-authenticated-user> currentUserReposR :: RepoPublicity -> FetchCount -> Request k (Vector Repo) currentUserReposR publicity =     pagedQuery  ["user", "repos"] qs   where     qs = repoPublicityQueryString publicity --- | The repos for a user, by their login. Can be restricted to just repos they--- own, are a member of, or publicize. Private repos will return empty list.------ > userRepos "mike-burns" All-userRepos :: Name Owner -> RepoPublicity -> IO (Either Error (Vector Repo))-userRepos = userRepos' Nothing---- | The repos for a user, by their login.--- With authentication.------ > userRepos' (Just (BasicAuth (user, password))) "mike-burns" All-userRepos'-    :: Maybe Auth-    -> Name Owner-    -> RepoPublicity-    -> IO (Either Error (Vector Repo))-userRepos' auth user publicity =-    executeRequestMaybe auth $ userReposR user publicity FetchAll- -- | List user repositories.--- See <https://developer.github.com/v3/repos/#list-user-repositories>+-- See <https://docs.github.com/en/rest/reference/repos#list-repositories-for-a-user> userReposR :: Name Owner -> RepoPublicity -> FetchCount -> Request k(Vector Repo) userReposR user publicity =     pagedQuery  ["users", toPathPart user, "repos"] qs   where     qs = repoPublicityQueryString publicity --- | The repos for an organization, by the organization name.------ > organizationRepos "thoughtbot"-organizationRepos :: Name Organization -> IO (Either Error (Vector Repo))-organizationRepos org = organizationRepos' Nothing org RepoPublicityAll---- | The repos for an organization, by the organization name.--- With authentication.------ > organizationRepos (Just (BasicAuth (user, password))) "thoughtbot" All-organizationRepos'-    :: Maybe Auth-    -> Name Organization-    -> RepoPublicity-    -> IO (Either Error (Vector Repo))-organizationRepos' auth org publicity =-    executeRequestMaybe auth $ organizationReposR org publicity FetchAll- -- | List organization repositories.--- See <https://developer.github.com/v3/repos/#list-organization-repositories>+-- See <https://docs.github.com/en/rest/reference/repos#list-organization-repositories> organizationReposR     :: Name Organization     -> RepoPublicity@@ -134,20 +67,6 @@   where     qs = repoPublicityQueryString publicity --- | Details on a specific repo, given the owner and repo name.------ > repository "mike-burns" "github"-repository :: Name Owner -> Name Repo -> IO (Either Error Repo)-repository = repository' Nothing---- | Details on a specific repo, given the owner and repo name.--- With authentication.------ > repository' (Just (BasicAuth (user, password))) "mike-burns" "github"-repository' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error Repo)-repository' auth user repo =-    executeRequestMaybe auth $ repositoryR user repo- -- | Query single repository. -- See <https://developer.github.com/v3/repos/#get> repositoryR :: Name Owner -> Name Repo -> Request k Repo@@ -155,13 +74,6 @@     query ["repos", toPathPart user, toPathPart repo] []  -- | Create a new repository.------ > createRepo' (BasicAuth (user, password)) (newRepo "some_repo") {newRepoHasIssues = Just False}-createRepo' :: Auth -> NewRepo -> IO (Either Error Repo)-createRepo' auth nrepo =-    executeRequest auth $ createRepoR nrepo---- | Create a new repository. -- See <https://developer.github.com/v3/repos/#create> createRepoR :: NewRepo -> Request 'RW Repo createRepoR nrepo =@@ -175,32 +87,12 @@     command Post ["repos", toPathPart owner, toPathPart repo, "forks" ] mempty  -- | Create a new repository for an organization.------ > createOrganizationRepo (BasicAuth (user, password)) "thoughtbot" (newRepo "some_repo") {newRepoHasIssues = Just False}-createOrganizationRepo' :: Auth -> Name Organization -> NewRepo -> IO (Either Error Repo)-createOrganizationRepo' auth org nrepo =-    executeRequest auth $ createOrganizationRepoR org nrepo---- | Create a new repository for an organization. -- See <https://developer.github.com/v3/repos/#create> createOrganizationRepoR :: Name Organization -> NewRepo -> Request 'RW Repo createOrganizationRepoR org nrepo =     command Post ["orgs", toPathPart org, "repos"] (encode nrepo)  -- | Edit an existing repository.------ > editRepo (BasicAuth (user, password)) "some_user" "some_repo" def {editDescription = Just "some description"}-editRepo-    :: Auth-    -> Name Owner      -- ^ owner-    -> Name Repo             -- ^ repository name-    -> EditRepo-    -> IO (Either Error Repo)-editRepo auth user repo body =-    executeRequest auth $ editRepoR user repo body----- | Edit an existing repository. -- See <https://developer.github.com/v3/repos/#edit> editRepoR :: Name Owner -> Name Repo -> EditRepo -> Request 'RW Repo editRepoR user repo body =@@ -209,20 +101,6 @@     -- if no name is given, use curent name     b = body {editName = editName body <|> Just repo} --- | The contributors to a repo, given the owner and repo name.------ > contributors "thoughtbot" "paperclip"-contributors :: Name Owner -> Name Repo -> IO (Either Error (Vector Contributor))-contributors = contributors' Nothing---- | The contributors to a repo, given the owner and repo name.--- With authentication.------ > contributors' (Just (BasicAuth (user, password))) "thoughtbot" "paperclip"-contributors' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector Contributor))-contributors' auth user repo =-    executeRequestMaybe auth $ contributorsR user repo False FetchAll- -- | List contributors. -- See <https://developer.github.com/v3/repos/#list-contributors> contributorsR@@ -237,93 +115,26 @@     qs | anon      = [("anon", Just "true")]        | otherwise = [] --- | The contributors to a repo, including anonymous contributors (such as--- deleted users or git commits with unknown email addresses), given the owner--- and repo name.------ > contributorsWithAnonymous "thoughtbot" "paperclip"-contributorsWithAnonymous :: Name Owner -> Name Repo -> IO (Either Error (Vector Contributor))-contributorsWithAnonymous = contributorsWithAnonymous' Nothing---- | The contributors to a repo, including anonymous contributors (such as--- deleted users or git commits with unknown email addresses), given the owner--- and repo name.--- With authentication.------ > contributorsWithAnonymous' (Just (BasicAuth (user, password))) "thoughtbot" "paperclip"-contributorsWithAnonymous' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector Contributor))-contributorsWithAnonymous' auth user repo =-    executeRequestMaybe auth $ contributorsR user repo True FetchAll---- | The programming languages used in a repo along with the number of--- characters written in that language. Takes the repo owner and name.------ > languagesFor "mike-burns" "ohlaunch"-languagesFor :: Name Owner -> Name Repo -> IO (Either Error Languages)-languagesFor = languagesFor' Nothing---- | The programming languages used in a repo along with the number of--- characters written in that language. Takes the repo owner and name.--- With authentication.------ > languagesFor' (Just (BasicAuth (user, password))) "mike-burns" "ohlaunch"-languagesFor' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error Languages)-languagesFor' auth user repo =-    executeRequestMaybe auth $ languagesForR user repo- -- | List languages. -- See <https://developer.github.com/v3/repos/#list-languages> languagesForR :: Name Owner -> Name Repo -> Request k Languages languagesForR user repo =     query ["repos", toPathPart user, toPathPart repo, "languages"] [] --- | The git tags on a repo, given the repo owner and name.------ > tagsFor "thoughtbot" "paperclip"-tagsFor :: Name Owner -> Name Repo -> IO (Either Error (Vector Tag))-tagsFor = tagsFor' Nothing---- | The git tags on a repo, given the repo owner and name.--- With authentication.------ > tagsFor' (Just (BasicAuth (user, password))) "thoughtbot" "paperclip"-tagsFor' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector Tag))-tagsFor' auth user repo =-    executeRequestMaybe auth $ tagsForR user repo FetchAll- -- | List tags. -- See <https://developer.github.com/v3/repos/#list-tags> tagsForR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector Tag) tagsForR user repo =     pagedQuery  ["repos", toPathPart user, toPathPart repo, "tags"] [] --- | The git branches on a repo, given the repo owner and name.------ > branchesFor "thoughtbot" "paperclip"-branchesFor :: Name Owner -> Name Repo -> IO (Either Error (Vector Branch))-branchesFor = branchesFor' Nothing---- | The git branches on a repo, given the repo owner and name.--- With authentication.------ > branchesFor' (Just (BasicAuth (user, password))) "thoughtbot" "paperclip"-branchesFor' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector Branch))-branchesFor' auth user repo =-    executeRequestMaybe auth $ branchesForR user repo FetchAll- -- | List branches. -- See <https://developer.github.com/v3/repos/#list-branches> branchesForR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector Branch) branchesForR user repo =     pagedQuery  ["repos", toPathPart user, toPathPart repo, "branches"] [] --- | Delete an existing repository.------ > deleteRepo (BasicAuth (user, password)) "thoughtbot" "some_repo"-deleteRepo :: Auth -> Name Owner -> Name Repo -> IO (Either Error ())-deleteRepo auth user repo =-    executeRequest auth $ deleteRepoR user repo--deleteRepoR :: Name Owner -> Name Repo -> Request 'RW ()+-- | Delete a repository,.+-- See <https://developer.github.com/v3/repos/#delete-a-repository>+deleteRepoR :: Name Owner -> Name Repo -> GenRequest 'MtUnit 'RW () deleteRepoR user repo =-    command Delete ["repos", toPathPart user, toPathPart repo] mempty+    Command Delete ["repos", toPathPart user, toPathPart repo] mempty
src/GitHub/Endpoints/Repos/Collaborators.hs view
@@ -1,55 +1,34 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The repo collaborators API as described on -- <http://developer.github.com/v3/repos/collaborators/>.+ module GitHub.Endpoints.Repos.Collaborators (-    collaboratorsOn,-    collaboratorsOn',     collaboratorsOnR,-    isCollaboratorOn,+    collaboratorPermissionOnR,     isCollaboratorOnR,+    addCollaboratorR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | All the users who have collaborated on a repo.------ > collaboratorsOn "thoughtbot" "paperclip"-collaboratorsOn :: Name Owner -> Name Repo -> IO (Either Error (Vector SimpleUser))-collaboratorsOn = collaboratorsOn' Nothing---- | All the users who have collaborated on a repo.--- With authentication.-collaboratorsOn' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector SimpleUser))-collaboratorsOn' auth user repo =-    executeRequestMaybe auth $ collaboratorsOnR user repo FetchAll- -- | List collaborators. -- See <https://developer.github.com/v3/repos/collaborators/#list-collaborators> collaboratorsOnR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector SimpleUser) collaboratorsOnR user repo =     pagedQuery ["repos", toPathPart user, toPathPart repo, "collaborators"] [] --- | Whether the user is collaborating on a repo. Takes the user in question,--- the user who owns the repo, and the repo name.------ > isCollaboratorOn Nothing "mike-burns" "thoughtbot" "paperclip"--- > isCollaboratorOn Nothing "johnson" "thoughtbot" "paperclip"-isCollaboratorOn-    :: Maybe Auth-    -> Name Owner  -- ^ Repository owner+-- | Review a user's permission level.+-- <https://developer.github.com/v3/repos/collaborators/#review-a-users-permission-level>+collaboratorPermissionOnR+    :: Name Owner        -- ^ Repository owner     -> Name Repo         -- ^ Repository name-    -> Name User         -- ^ Collaborator?-    -> IO (Either Error Bool)-isCollaboratorOn auth user repo coll =-    executeRequestMaybe auth $ isCollaboratorOnR user repo coll+    -> Name User         -- ^ Collaborator to check permissions of.+    -> GenRequest 'MtJSON rw CollaboratorWithPermission+collaboratorPermissionOnR owner repo coll =+    query ["repos", toPathPart owner, toPathPart repo, "collaborators", toPathPart coll, "permission"] []  -- | Check if a user is a collaborator. -- See <https://developer.github.com/v3/repos/collaborators/#check-if-a-user-is-a-collaborator>@@ -57,6 +36,16 @@     :: Name Owner  -- ^ Repository owner     -> Name Repo         -- ^ Repository name     -> Name User         -- ^ Collaborator?-    -> Request k Bool-isCollaboratorOnR user repo coll = StatusQuery statusOnlyOk $+    -> GenRequest 'MtStatus rw Bool+isCollaboratorOnR user repo coll =     Query ["repos", toPathPart user, toPathPart repo, "collaborators", toPathPart coll] []++-- | Invite a user as a collaborator.+-- See <https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator>+addCollaboratorR+    :: Name Owner        -- ^ Repository owner+    -> Name Repo         -- ^ Repository name+    -> Name User         -- ^ Collaborator to add+    -> GenRequest 'MtJSON 'RW (Maybe RepoInvitation)+addCollaboratorR owner repo coll =+    Command Put ["repos", toPathPart owner, toPathPart repo, "collaborators", toPathPart coll] mempty
src/GitHub/Endpoints/Repos/Comments.hs view
@@ -1,81 +1,29 @@-{-# LANGUAGE CPP #-}------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The repo commits API as described on -- <http://developer.github.com/v3/repos/comments/>.+ module GitHub.Endpoints.Repos.Comments (-    commentsFor,-    commentsFor',     commentsForR,-    commitCommentsFor,-    commitCommentsFor',     commitCommentsForR,-    commitCommentFor,-    commitCommentFor',     commitCommentForR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | All the comments on a Github repo.------ > commentsFor "thoughtbot" "paperclip"-commentsFor :: Name Owner -> Name Repo -> IO (Either Error (Vector Comment))-commentsFor = commentsFor' Nothing---- | All the comments on a Github repo.--- With authentication.------ > commentsFor "thoughtbot" "paperclip"-commentsFor' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector Comment))-commentsFor' auth user repo =-    executeRequestMaybe auth $ commentsForR user repo FetchAll- -- | List commit comments for a repository. -- See <https://developer.github.com/v3/repos/comments/#list-commit-comments-for-a-repository> commentsForR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector Comment) commentsForR user repo =     pagedQuery ["repos", toPathPart user, toPathPart repo, "comments"] [] --- | Just the comments on a specific SHA for a given Github repo.------ > commitCommentsFor "thoughtbot" "paperclip" "41f685f6e01396936bb8cd98e7cca517e2c7d96b"-commitCommentsFor :: Name Owner -> Name Repo -> Name Commit -> IO (Either Error (Vector Comment))-commitCommentsFor = commitCommentsFor' Nothing---- | Just the comments on a specific SHA for a given Github repo.--- With authentication.------ > commitCommentsFor "thoughtbot" "paperclip" "41f685f6e01396936bb8cd98e7cca517e2c7d96b"-commitCommentsFor' :: Maybe Auth -> Name Owner -> Name Repo -> Name Commit -> IO (Either Error (Vector Comment))-commitCommentsFor' auth user repo sha =-    executeRequestMaybe auth $ commitCommentsForR user repo sha FetchAll- -- | List comments for a single commit. -- See <https://developer.github.com/v3/repos/comments/#list-comments-for-a-single-commit> commitCommentsForR :: Name Owner -> Name Repo -> Name Commit -> FetchCount -> Request k (Vector Comment) commitCommentsForR user repo sha =     pagedQuery ["repos", toPathPart user, toPathPart repo, "commits", toPathPart sha, "comments"] []---- | A comment, by its ID, relative to the Github repo.------ > commitCommentFor "thoughtbot" "paperclip" "669575"-commitCommentFor :: Name Owner -> Name Repo -> Id Comment -> IO (Either Error Comment)-commitCommentFor = commitCommentFor' Nothing---- | A comment, by its ID, relative to the Github repo.------ > commitCommentFor "thoughtbot" "paperclip" "669575"-commitCommentFor' :: Maybe Auth -> Name Owner -> Name Repo -> Id Comment -> IO (Either Error Comment)-commitCommentFor' auth user repo cid =-    executeRequestMaybe auth $ commitCommentForR user repo cid  -- | Query a single commit comment. -- See <https://developer.github.com/v3/repos/comments/#get-a-single-commit-comment>
src/GitHub/Endpoints/Repos/Commits.hs view
@@ -1,31 +1,18 @@-{-# LANGUAGE CPP #-}------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The repo commits API as described on -- <http://developer.github.com/v3/repos/commits/>.+ module GitHub.Endpoints.Repos.Commits (     CommitQueryOption(..),-    commitsFor,-    commitsFor',     commitsForR,-    commitsWithOptionsFor,-    commitsWithOptionsFor',     commitsWithOptionsForR,-    commit,-    commit',     commitR,-    diff,-    diff',     diffR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude ()  import qualified Data.ByteString    as BS@@ -39,37 +26,11 @@ renderCommitQueryOption (CommitQuerySince date)    = ("since", Just $ TE.encodeUtf8 . T.pack $ formatISO8601 date) renderCommitQueryOption (CommitQueryUntil date)    = ("until", Just $ TE.encodeUtf8 . T.pack $ formatISO8601 date) --- | The commit history for a repo.------ > commitsFor "mike-burns" "github"-commitsFor :: Name Owner -> Name Repo -> IO (Either Error (Vector Commit))-commitsFor = commitsFor' Nothing---- | The commit history for a repo.--- With authentication.------ > commitsFor' (Just (BasicAuth (user, password))) "mike-burns" "github"-commitsFor' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector Commit))-commitsFor' auth user repo =-    commitsWithOptionsFor' auth user repo []- -- | List commits on a repository. -- See <https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository> commitsForR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector Commit) commitsForR user repo limit = commitsWithOptionsForR user repo limit [] -commitsWithOptionsFor :: Name Owner -> Name Repo -> [CommitQueryOption] -> IO (Either Error (Vector Commit))-commitsWithOptionsFor = commitsWithOptionsFor' Nothing---- | The commit history for a repo, with commits filtered to satisfy a list of--- query options.--- With authentication.------ > commitsWithOptionsFor' (Just (BasicAuth (user, password))) "mike-burns" "github" [CommitQueryAuthor "djeik"]-commitsWithOptionsFor' :: Maybe Auth -> Name Owner -> Name Repo -> [CommitQueryOption] -> IO (Either Error (Vector Commit))-commitsWithOptionsFor' auth user repo opts =-    executeRequestMaybe auth $ commitsWithOptionsForR user repo FetchAll opts- -- | List commits on a repository. -- See <https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository> commitsWithOptionsForR :: Name Owner -> Name Repo -> FetchCount -> [CommitQueryOption] -> Request k (Vector Commit)@@ -78,39 +39,11 @@   where     qs = map renderCommitQueryOption opts ---- | Details on a specific SHA1 for a repo.------ > commit "mike-burns" "github" "9d1a9a361266c3c890b1108ad2fdf52f824b1b81"-commit :: Name Owner -> Name Repo -> Name Commit -> IO (Either Error Commit)-commit = commit' Nothing---- | Details on a specific SHA1 for a repo.--- With authentication.------ > commit (Just $ BasicAuth (username, password)) "mike-burns" "github" "9d1a9a361266c3c890b1108ad2fdf52f824b1b81"-commit' :: Maybe Auth -> Name Owner -> Name Repo -> Name Commit -> IO (Either Error Commit)-commit' auth user repo sha =-    executeRequestMaybe auth $ commitR user repo sha- -- | Query a single commit. -- See <https://developer.github.com/v3/repos/commits/#get-a-single-commit> commitR :: Name Owner -> Name Repo -> Name Commit -> Request k Commit commitR user repo sha =     query ["repos", toPathPart user, toPathPart repo, "commits", toPathPart sha] []---- | The diff between two treeishes on a repo.------ > diff "thoughtbot" "paperclip" "41f685f6e01396936bb8cd98e7cca517e2c7d96b" "HEAD"-diff :: Name Owner -> Name Repo -> Name Commit -> Name Commit -> IO (Either Error Diff)-diff = diff' Nothing---- | The diff between two treeishes on a repo.------ > diff "thoughtbot" "paperclip" "41f685f6e01396936bb8cd98e7cca517e2c7d96b" "HEAD"-diff' :: Maybe Auth -> Name Owner -> Name Repo -> Name Commit -> Name Commit -> IO (Either Error Diff)-diff' auth user repo base headref =-    executeRequestMaybe auth $ diffR user repo base headref  -- | Compare two commits. -- See <https://developer.github.com/v3/repos/commits/#compare-two-commits>
src/GitHub/Endpoints/Repos/Contents.hs view
@@ -1,32 +1,20 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The Github Repo Contents API, as documented at -- <https://developer.github.com/v3/repos/contents/>+ module GitHub.Endpoints.Repos.Contents (     -- * Querying contents-    contentsFor,-    contentsFor',     contentsForR,-    readmeFor,-    readmeFor',     readmeForR,-    archiveFor,-    archiveFor',     archiveForR,      -- ** Create-    createFile,     createFileR,      -- ** Update-    updateFile,     updateFileR,      -- ** Delete-    deleteFile,     deleteFileR,      module GitHub.Data@@ -34,27 +22,12 @@  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude ()  import Data.Maybe (maybeToList) import qualified Data.Text.Encoding as TE import Network.URI (URI) --- | The contents of a file or directory in a repo, given the repo owner, name, and path to the file------ > contentsFor "thoughtbot" "paperclip" "README.md"-contentsFor :: Name Owner -> Name Repo -> Text -> Maybe Text -> IO (Either Error Content)-contentsFor = contentsFor' Nothing---- | The contents of a file or directory in a repo, given the repo owner, name, and path to the file--- With Authentication------ > contentsFor' (Just (BasicAuth (user, password))) "thoughtbot" "paperclip" "README.md" Nothing-contentsFor' :: Maybe Auth ->  Name Owner -> Name Repo -> Text -> Maybe Text -> IO (Either Error Content)-contentsFor' auth user repo path ref =-    executeRequestMaybe auth $ contentsForR user repo path ref- contentsForR     :: Name Owner     -> Name Repo@@ -66,60 +39,23 @@   where     qs =  maybe [] (\r -> [("ref", Just . TE.encodeUtf8 $ r)]) ref --- | The contents of a README file in a repo, given the repo owner and name------ > readmeFor "thoughtbot" "paperclip"-readmeFor :: Name Owner -> Name Repo -> IO (Either Error Content)-readmeFor = readmeFor' Nothing---- | The contents of a README file in a repo, given the repo owner and name--- With Authentication------ > readmeFor' (Just (BasicAuth (user, password))) "thoughtbot" "paperclip"-readmeFor' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error Content)-readmeFor' auth user repo =-    executeRequestMaybe auth $ readmeForR user repo- readmeForR :: Name Owner -> Name Repo -> Request k Content readmeForR user repo =     query ["repos", toPathPart user, toPathPart repo, "readme"] [] --- | The archive of a repo, given the repo owner, name, and archive type------ > archiveFor "thoughtbot" "paperclip" ArchiveFormatTarball Nothing-archiveFor :: Name Owner -> Name Repo -> ArchiveFormat -> Maybe Text -> IO (Either Error URI)-archiveFor = archiveFor' Nothing---- | The archive of a repo, given the repo owner, name, and archive type--- With Authentication------ > archiveFor' (Just (BasicAuth (user, password))) "thoughtbot" "paperclip" ArchiveFormatTarball Nothing-archiveFor' :: Maybe Auth ->  Name Owner -> Name Repo -> ArchiveFormat -> Maybe Text -> IO (Either Error URI)-archiveFor' auth user repo path ref =-    executeRequestMaybe auth $ archiveForR user repo path ref-+-- | Get archive link.+-- See <https://developer.github.com/v3/repos/contents/#get-archive-link> archiveForR     :: Name Owner     -> Name Repo     -> ArchiveFormat   -- ^ The type of archive to retrieve     -> Maybe Text      -- ^ Git commit-    -> Request k URI-archiveForR user repo format ref =-    RedirectQuery $ Query path []+    -> GenRequest 'MtRedirect rw URI+archiveForR user repo format ref = Query path []   where     path = ["repos", toPathPart user, toPathPart repo, toPathPart format] <> maybeToList ref  -- | Create a file.-createFile-    :: Auth-    -> Name Owner      -- ^ owner-    -> Name Repo       -- ^ repository name-    -> CreateFile-    -> IO (Either Error ContentResult)-createFile auth user repo body =-    executeRequest auth $ createFileR user repo body---- | Create a file. -- See <https://developer.github.com/v3/repos/contents/#create-a-file> createFileR     :: Name Owner@@ -130,16 +66,6 @@     command Put ["repos", toPathPart user, toPathPart repo, "contents", createFilePath body] (encode body)  -- | Update a file.-updateFile-    :: Auth-    -> Name Owner      -- ^ owner-    -> Name Repo       -- ^ repository name-    -> UpdateFile-    -> IO (Either Error ContentResult)-updateFile auth user repo body =-    executeRequest auth $ updateFileR user repo body---- | Update a file. -- See <https://developer.github.com/v3/repos/contents/#update-a-file> updateFileR     :: Name Owner@@ -150,21 +76,11 @@     command Put ["repos", toPathPart user, toPathPart repo, "contents", updateFilePath body] (encode body)  -- | Delete a file.-deleteFile-    :: Auth-    -> Name Owner      -- ^ owner-    -> Name Repo       -- ^ repository name-    -> DeleteFile-    -> IO (Either Error ())-deleteFile auth user repo body =-    executeRequest auth $ deleteFileR user repo body---- | Delete a file. -- See <https://developer.github.com/v3/repos/contents/#delete-a-file> deleteFileR     :: Name Owner     -> Name Repo     -> DeleteFile-    -> Request 'RW ()+    -> GenRequest 'MtUnit 'RW () deleteFileR user repo body =-    command Delete ["repos", toPathPart user, toPathPart repo, "contents", deleteFilePath body] (encode body)+    Command Delete ["repos", toPathPart user, toPathPart repo, "contents", deleteFilePath body] (encode body)
src/GitHub/Endpoints/Repos/DeployKeys.hs view
@@ -7,64 +7,40 @@ -- <https://developer.github.com/v3/repos/keys> module GitHub.Endpoints.Repos.DeployKeys (     -- * Querying deploy keys-    deployKeysFor',     deployKeysForR,-    deployKeyFor',     deployKeyForR,      -- ** Create-    createRepoDeployKey',     createRepoDeployKeyR,      -- ** Delete-    deleteRepoDeployKey',     deleteRepoDeployKeyR, ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude ()  -- | Querying deploy keys.-deployKeysFor' :: Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector RepoDeployKey))-deployKeysFor' auth user repo =-    executeRequest auth $ deployKeysForR user repo FetchAll---- | Querying deploy keys. -- See <https://developer.github.com/v3/repos/keys/#list-deploy-keys> deployKeysForR :: Name Owner -> Name Repo -> FetchCount -> Request 'RA (Vector RepoDeployKey) deployKeysForR user repo =     pagedQuery ["repos", toPathPart user, toPathPart repo, "keys"] [] --- | Querying a deploy key-deployKeyFor' :: Auth -> Name Owner -> Name Repo -> Id RepoDeployKey -> IO (Either Error RepoDeployKey)-deployKeyFor' auth user repo keyId =-    executeRequest auth $ deployKeyForR user repo keyId- -- | Querying a deploy key. -- See <https://developer.github.com/v3/repos/keys/#get-a-deploy-key> deployKeyForR :: Name Owner -> Name Repo -> Id RepoDeployKey -> Request 'RA RepoDeployKey deployKeyForR user repo keyId =     query ["repos", toPathPart user, toPathPart repo, "keys", toPathPart keyId] [] --- | Create a deploy key-createRepoDeployKey' :: Auth -> Name Owner -> Name Repo -> NewRepoDeployKey -> IO (Either Error RepoDeployKey)-createRepoDeployKey' auth user repo key =-    executeRequest auth $ createRepoDeployKeyR user repo key- -- | Create a deploy key. -- See <https://developer.github.com/v3/repos/keys/#add-a-new-deploy-key>. createRepoDeployKeyR :: Name Owner -> Name Repo -> NewRepoDeployKey -> Request 'RW RepoDeployKey createRepoDeployKeyR user repo key =     command Post ["repos", toPathPart user, toPathPart repo, "keys"] (encode key) -deleteRepoDeployKey' :: Auth -> Name Owner -> Name Repo -> Id RepoDeployKey -> IO (Either Error ())-deleteRepoDeployKey' auth user repo keyId =-    executeRequest auth $ deleteRepoDeployKeyR user repo keyId- -- | Delete a deploy key. -- See <https://developer.github.com/v3/repos/keys/#remove-a-deploy-key>-deleteRepoDeployKeyR :: Name Owner -> Name Repo -> Id RepoDeployKey -> Request 'RW ()+deleteRepoDeployKeyR :: Name Owner -> Name Repo -> Id RepoDeployKey -> GenRequest 'MtUnit 'RW () deleteRepoDeployKeyR user repo keyId =-    command Delete ["repos", toPathPart user, toPathPart repo, "keys", toPathPart keyId] mempty+    Command Delete ["repos", toPathPart user, toPathPart repo, "keys", toPathPart keyId] mempty
+ src/GitHub/Endpoints/Repos/Deployments.hs view
@@ -0,0 +1,72 @@+-- | The deployments API, as described at <https://developer.github.com/v3/repos/deployments/>+module GitHub.Endpoints.Repos.Deployments+    ( deploymentsWithOptionsForR+    , createDeploymentR++    , deploymentStatusesForR+    , createDeploymentStatusR++    , module GitHub.Data+    ) where++import Control.Arrow (second)++import GitHub.Data+import GitHub.Internal.Prelude++-- | List deployments.+-- See <https://developer.github.com/v3/repos/deployments/#list-deployments>+deploymentsWithOptionsForR+    :: FromJSON a+    => Name Owner+    -> Name Repo+    -> FetchCount+    -> [DeploymentQueryOption]+    -> Request 'RA (Vector (Deployment a))+deploymentsWithOptionsForR owner repo limit opts =+    pagedQuery (deployPaths owner repo)+        (map (second Just . renderDeploymentQueryOption) opts)+        limit++-- | Create a deployment.+-- See <https://developer.github.com/v3/repos/deployments/#create-a-deployment>+createDeploymentR+    :: ( ToJSON   a+       , FromJSON a+       )+    => Name Owner+    -> Name Repo+    -> CreateDeployment a+    -> Request 'RW (Deployment a)+createDeploymentR owner repo =+    command Post (deployPaths owner repo) . encode++-- | List deployment statuses.+-- See <https://developer.github.com/v3/repos/deployments/#list-deployment-statuses>+deploymentStatusesForR+    :: Name Owner+    -> Name Repo+    -> Id (Deployment a)+    -> FetchCount+    -> Request 'RA (Vector DeploymentStatus)+deploymentStatusesForR owner repo deploy =+    pagedQuery (statusesPaths owner repo deploy) []++-- | Create a deployment status.+-- See <https://developer.github.com/v3/repos/deployments/#list-deployment-statuses>+createDeploymentStatusR+    :: Name Owner+    -> Name Repo+    -> Id (Deployment a)+    -> CreateDeploymentStatus+    -> Request 'RW DeploymentStatus+createDeploymentStatusR owner repo deploy =+    command Post (statusesPaths owner repo deploy) . encode++statusesPaths :: Name Owner -> Name Repo -> Id (Deployment a) -> Paths+statusesPaths owner repo deploy =+    deployPaths owner repo ++ [toPathPart deploy, "statuses"]++deployPaths :: Name Owner -> Name Repo -> Paths+deployPaths owner repo =+    ["repos", toPathPart owner, toPathPart repo, "deployments"]
src/GitHub/Endpoints/Repos/Forks.hs view
@@ -1,35 +1,15 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- Hot forking action, as described at -- <http://developer.github.com/v3/repos/forks/>.+ module GitHub.Endpoints.Repos.Forks (-    forksFor,-    forksFor',     forksForR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude ()---- | All the repos that are forked off the given repo.------ > forksFor "thoughtbot" "paperclip"-forksFor :: Name Owner -> Name Repo -> IO (Either Error  (Vector Repo))-forksFor = forksFor' Nothing---- | All the repos that are forked off the given repo.--- | With authentication------ > forksFor' (Just (User (user, password))) "thoughtbot" "paperclip"-forksFor' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error  (Vector Repo))-forksFor' auth user repo =-    executeRequestMaybe auth $ forksForR user repo FetchAll  -- | List forks. -- See <https://developer.github.com/v3/repos/forks/#list-forks>
+ src/GitHub/Endpoints/Repos/Invitations.hs view
@@ -0,0 +1,32 @@+-- |+-- The repo invitations API as described on+-- <https://developer.github.com/v3/repos/invitations/>.++module GitHub.Endpoints.Repos.Invitations (+    listInvitationsOnR,+    listInvitationsForR,+    acceptInvitationFromR+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | List open invitations of a repository+-- See <https://developer.github.com/v3/repos/invitations/#list-invitations-for-a-repository>+listInvitationsOnR :: Name Owner -> Name Repo -> FetchCount -> GenRequest 'MtJSON k (Vector RepoInvitation)+listInvitationsOnR user repo =+    PagedQuery ["repos", toPathPart user, toPathPart repo, "invitations"] []++-- | List a user's repository invitations+-- See <https://developer.github.com/v3/repos/invitations/#list-a-users-repository-invitations>+listInvitationsForR :: FetchCount -> Request k (Vector RepoInvitation)+listInvitationsForR =+    pagedQuery ["user", "repository_invitations"] []+++-- | Accept a repository invitation+-- See <https://developer.github.com/v3/repos/invitations/#accept-a-repository-invitation>+acceptInvitationFromR :: Id RepoInvitation -> GenRequest 'MtUnit 'RW ()+acceptInvitationFromR invId =+    Command Patch ["user", "repository_invitations", toPathPart invId] mempty
src/GitHub/Endpoints/Repos/Releases.hs view
@@ -1,95 +1,34 @@ -- The Release API, as described at -- <https://developer.github.com/v3/repos/releases/>. module GitHub.Endpoints.Repos.Releases (-    releases,-    releases',     releasesR,-    release,-    release',     releaseR,-    latestRelease,-    latestRelease',     latestReleaseR,-    releaseByTagName,-    releaseByTagName',     releaseByTagNameR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | All releases for the given repo.------ > releases "calleerlandsson" "pick"-releases :: Name Owner -> Name Repo -> IO (Either Error  (Vector Release))-releases = releases' Nothing---- | All releases for the given repo with authentication.------ > releases' (Just (User (user, password))) "calleerlandsson" "pick"-releases' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error  (Vector Release))-releases' auth user repo =-    executeRequestMaybe auth $ releasesR user repo FetchAll- -- | List releases for a repository. -- See <https://developer.github.com/v3/repos/releases/#list-releases-for-a-repository> releasesR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector Release) releasesR user repo =     pagedQuery ["repos", toPathPart user, toPathPart repo, "releases"] [] --- | Query a single release.------ > release "calleerlandsson" "pick"-release :: Name Owner -> Name Repo -> Id Release -> IO (Either Error Release)-release = release' Nothing---- | Query a single release with authentication.------ > release' (Just (User (user, password))) "calleerlandsson" "pick"-release' :: Maybe Auth -> Name Owner -> Name Repo -> Id Release -> IO (Either Error Release)-release' auth user repo reqReleaseId =-    executeRequestMaybe auth $ releaseR user repo reqReleaseId- -- | Get a single release. -- See <https://developer.github.com/v3/repos/releases/#get-a-single-release> releaseR :: Name Owner -> Name Repo -> Id Release -> Request k Release releaseR user repo reqReleaseId =     query ["repos", toPathPart user, toPathPart repo, "releases", toPathPart reqReleaseId ] [] --- | Query latest release.------ > latestRelease "calleerlandsson" "pick"-latestRelease :: Name Owner -> Name Repo -> IO (Either Error Release)-latestRelease = latestRelease' Nothing---- | Query latest release with authentication.------ > latestRelease' (Just (User (user, password))) "calleerlandsson" "pick"-latestRelease' :: Maybe Auth -> Name Owner -> Name Repo -> IO (Either Error Release)-latestRelease' auth user repo  =-    executeRequestMaybe auth $ latestReleaseR user repo- -- | Get the latest release. -- See <https://developer.github.com/v3/repos/releases/#get-the-latest-release> latestReleaseR :: Name Owner -> Name Repo -> Request k Release latestReleaseR user repo =     query ["repos", toPathPart user, toPathPart repo, "releases", "latest" ] []---- | Query release by tag name.------ > releaseByTagName "calleerlandsson" "pick"-releaseByTagName :: Name Owner -> Name Repo -> Text -> IO (Either Error Release)-releaseByTagName = releaseByTagName' Nothing---- | Query release by tag name with authentication.------ > releaseByTagName' (Just (User (user, password))) "calleerlandsson" "pick"-releaseByTagName' :: Maybe Auth -> Name Owner -> Name Repo -> Text -> IO (Either Error Release)-releaseByTagName' auth user repo reqTagName =-    executeRequestMaybe auth $ releaseByTagNameR user repo reqTagName  -- | Get a release by tag name -- See <https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name>
src/GitHub/Endpoints/Repos/Statuses.hs view
@@ -1,35 +1,19 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The repo statuses API as described on -- <https://developer.github.com/v3/repos/statuses/>.+ module GitHub.Endpoints.Repos.Statuses (-    createStatus,     createStatusR,-    statusesFor,     statusesForR,-    statusFor,     statusForR,     module GitHub.Data     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude ()  -- | Create a new status------ > createStatus (BasicAuth user password) "thoughtbot" "paperclip"--- >   "41f685f6e01396936bb8cd98e7cca517e2c7d96b"--- >   (NewStatus StatusSuccess Nothing "Looks good!" Nothing)-createStatus :: Auth -> Name Owner -> Name Repo -> Name Commit -> NewStatus -> IO (Either Error Status)-createStatus auth owner repo sha ns =-    executeRequest auth $ createStatusR owner repo sha ns---- | Create a new status -- See <https://developer.github.com/v3/repos/statuses/#create-a-status> createStatusR :: Name Owner -> Name Repo -> Name Commit -> NewStatus -> Request 'RW Status createStatusR owner repo sha =@@ -38,26 +22,10 @@         parts = ["repos", toPathPart owner, toPathPart repo, "statuses", toPathPart sha]  -- | All statuses for a commit------ > statusesFor (BasicAuth user password) "thoughtbot" "paperclip"--- >   "41f685f6e01396936bb8cd98e7cca517e2c7d96b"-statusesFor :: Auth -> Name Owner -> Name Repo -> Name Commit -> IO (Either Error (Vector Status))-statusesFor auth user repo sha =-    executeRequest auth $ statusesForR user repo sha FetchAll---- | All statuses for a commit -- See <https://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref> statusesForR :: Name Owner -> Name Repo -> Name Commit -> FetchCount -> Request 'RW (Vector Status) statusesForR user repo sha =     pagedQuery ["repos", toPathPart user, toPathPart repo, "commits", toPathPart sha, "statuses"] []---- | The combined status for a specific commit------ > statusFor (BasicAuth user password) "thoughtbot" "paperclip"--- >   "41f685f6e01396936bb8cd98e7cca517e2c7d96b"-statusFor :: Auth -> Name Owner -> Name Repo -> Name Commit -> IO (Either Error CombinedStatus)-statusFor auth user repo sha =-    executeRequest auth $ statusForR user repo sha  -- | The combined status for a specific commit -- See <https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref>
src/GitHub/Endpoints/Repos/Webhooks.hs view
@@ -1,111 +1,70 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The webhooks API, as described at -- <https://developer.github.com/v3/repos/hooks/> -- <https://developer.github.com/webhooks>+ module GitHub.Endpoints.Repos.Webhooks (     -- * Querying repositories-    webhooksFor',     webhooksForR,-    webhookFor',     webhookForR,      -- ** Create-    createRepoWebhook',     createRepoWebhookR,      -- ** Edit-    editRepoWebhook',     editRepoWebhookR,      -- ** Test-    testPushRepoWebhook',     testPushRepoWebhookR,-    pingRepoWebhook',     pingRepoWebhookR,      -- ** Delete-    deleteRepoWebhook',     deleteRepoWebhookR, ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () -webhooksFor' :: Auth -> Name Owner -> Name Repo -> IO (Either Error (Vector RepoWebhook))-webhooksFor' auth user repo =-    executeRequest auth $ webhooksForR user repo FetchAll- -- | List hooks. -- See <https://developer.github.com/v3/repos/hooks/#list-hooks> webhooksForR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector RepoWebhook) webhooksForR user repo =     pagedQuery ["repos", toPathPart user, toPathPart repo, "hooks"] []--webhookFor' :: Auth -> Name Owner -> Name Repo -> Id RepoWebhook -> IO (Either Error RepoWebhook)-webhookFor' auth user repo hookId =-    executeRequest auth $ webhookForR user repo hookId---- | Query single hook. -- See <https://developer.github.com/v3/repos/hooks/#get-single-hook> webhookForR :: Name Owner -> Name Repo -> Id RepoWebhook -> Request k RepoWebhook webhookForR user repo hookId =     query ["repos", toPathPart user, toPathPart repo, "hooks", toPathPart hookId] [] -createRepoWebhook' :: Auth -> Name Owner -> Name Repo -> NewRepoWebhook -> IO (Either Error RepoWebhook)-createRepoWebhook' auth user repo hook =-    executeRequest auth $ createRepoWebhookR user repo hook- -- | Create a hook. -- See <https://developer.github.com/v3/repos/hooks/#create-a-hook> createRepoWebhookR :: Name Owner -> Name Repo -> NewRepoWebhook -> Request 'RW RepoWebhook createRepoWebhookR user repo hook =     command Post ["repos", toPathPart user, toPathPart repo, "hooks"] (encode hook) -editRepoWebhook' :: Auth -> Name Owner -> Name Repo -> Id RepoWebhook -> EditRepoWebhook -> IO (Either Error RepoWebhook)-editRepoWebhook' auth user repo hookId hookEdit =-    executeRequest auth $ editRepoWebhookR user repo hookId hookEdit- -- | Edit a hook. -- See <https://developer.github.com/v3/repos/hooks/#edit-a-hook> editRepoWebhookR :: Name Owner -> Name Repo -> Id RepoWebhook -> EditRepoWebhook -> Request 'RW RepoWebhook editRepoWebhookR user repo hookId hookEdit =     command Patch ["repos", toPathPart user, toPathPart repo, "hooks", toPathPart hookId] (encode hookEdit) -testPushRepoWebhook' :: Auth -> Name Owner -> Name Repo -> Id RepoWebhook -> IO (Either Error Bool)-testPushRepoWebhook' auth user repo hookId =-    executeRequest auth $ testPushRepoWebhookR user repo hookId- -- | Test a push hook. -- See <https://developer.github.com/v3/repos/hooks/#test-a-push-hook>-testPushRepoWebhookR :: Name Owner -> Name Repo -> Id RepoWebhook -> Request 'RW Bool-testPushRepoWebhookR user repo hookId = StatusQuery statusOnlyOk $+testPushRepoWebhookR :: Name Owner -> Name Repo -> Id RepoWebhook -> GenRequest 'MtStatus 'RW Bool+testPushRepoWebhookR user repo hookId =     Command Post (createWebhookOpPath user repo hookId $ Just "tests") (encode ()) -pingRepoWebhook' :: Auth -> Name Owner -> Name Repo -> Id RepoWebhook -> IO (Either Error Bool)-pingRepoWebhook' auth user repo hookId =-    executeRequest auth $ pingRepoWebhookR user repo hookId- -- | Ping a hook. -- See <https://developer.github.com/v3/repos/hooks/#ping-a-hook>-pingRepoWebhookR :: Name Owner -> Name Repo -> Id RepoWebhook -> Request 'RW Bool-pingRepoWebhookR user repo hookId = StatusQuery statusOnlyOk $+pingRepoWebhookR :: Name Owner -> Name Repo -> Id RepoWebhook -> GenRequest 'MtStatus 'RW Bool+pingRepoWebhookR user repo hookId =     Command Post (createWebhookOpPath user repo hookId $ Just "pings") (encode ()) -deleteRepoWebhook' :: Auth -> Name Owner -> Name Repo -> Id RepoWebhook -> IO (Either Error ())-deleteRepoWebhook' auth user repo hookId =-    executeRequest auth $ deleteRepoWebhookR user repo hookId- -- | Delete a hook. -- See <https://developer.github.com/v3/repos/hooks/#delete-a-hook>-deleteRepoWebhookR :: Name Owner -> Name Repo -> Id RepoWebhook -> Request 'RW ()+deleteRepoWebhookR :: Name Owner -> Name Repo -> Id RepoWebhook -> GenRequest 'MtUnit 'RW () deleteRepoWebhookR user repo hookId =-    command Delete (createWebhookOpPath user repo hookId Nothing) mempty+    Command Delete (createWebhookOpPath user repo hookId Nothing) mempty  createBaseWebhookPath :: Name Owner -> Name Repo -> Id RepoWebhook -> Paths createBaseWebhookPath user repo hookId =
src/GitHub/Endpoints/Search.hs view
@@ -1,86 +1,41 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The Github Search API, as described at -- <http://developer.github.com/v3/search/>.+ module GitHub.Endpoints.Search(-    searchRepos',-    searchRepos,     searchReposR,-    searchCode',-    searchCode,     searchCodeR,-    searchIssues',-    searchIssues,     searchIssuesR,+    searchUsersR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude ()  import qualified Data.Text.Encoding as TE --- | Perform a repository search.--- With authentication.------ > searchRepos' (Just $ BasicAuth "github-username" "github-password') "a in%3Aname language%3Ahaskell created%3A>2013-10-01&per_page=100"-searchRepos' :: Maybe Auth -> Text -> IO (Either Error (SearchResult Repo))-searchRepos' auth = executeRequestMaybe auth . searchReposR---- | Perform a repository search.--- Without authentication.------ > searchRepos "q=a in%3Aname language%3Ahaskell created%3A>2013-10-01&per_page=100"-searchRepos :: Text -> IO (Either Error (SearchResult Repo))-searchRepos = searchRepos' Nothing- -- | Search repositories. -- See <https://developer.github.com/v3/search/#search-repositories>-searchReposR :: Text -> Request k (SearchResult Repo)+searchReposR :: Text -> FetchCount -> Request k (SearchResult Repo) searchReposR searchString =-    query ["search", "repositories"] [("q", Just $ TE.encodeUtf8 searchString)]---- | Perform a code search.--- With authentication.------ > searchCode' (Just $ BasicAuth "github-username" "github-password') "a in%3Aname language%3Ahaskell created%3A>2013-10-01&per_page=100"-searchCode' :: Maybe Auth -> Text -> IO (Either Error (SearchResult Code))-searchCode' auth = executeRequestMaybe auth . searchCodeR---- | Perform a code search.--- Without authentication.------ > searchCode "q=addClass+in:file+language:js+repo:jquery/jquery"-searchCode :: Text -> IO (Either Error (SearchResult Code))-searchCode = searchCode' Nothing+    PagedQuery ["search", "repositories"] [("q", Just $ TE.encodeUtf8 searchString)]  -- | Search code. -- See <https://developer.github.com/v3/search/#search-code>-searchCodeR :: Text -> Request k (SearchResult Code)+searchCodeR :: Text -> FetchCount -> Request k (SearchResult Code) searchCodeR searchString =-    query ["search", "code"] [("q", Just $ TE.encodeUtf8 searchString)]---- | Perform an issue search.--- With authentication.------ > searchIssues' (Just $ BasicAuth "github-username" "github-password') "a repo%3Aphadej%2Fgithub&per_page=100"-searchIssues' :: Maybe Auth -> Text -> IO (Either Error (SearchResult Issue))-searchIssues' auth = executeRequestMaybe auth . searchIssuesR---- | Perform an issue search.--- Without authentication.------ > searchIssues "q=a repo%3Aphadej%2Fgithub&per_page=100"-searchIssues :: Text -> IO (Either Error (SearchResult Issue))-searchIssues = searchIssues' Nothing+    PagedQuery ["search", "code"] [("q", Just $ TE.encodeUtf8 searchString)]  -- | Search issues. -- See <https://developer.github.com/v3/search/#search-issues>-searchIssuesR :: Text -> Request k (SearchResult Issue)+searchIssuesR :: Text -> FetchCount -> Request k (SearchResult Issue) searchIssuesR searchString =-    query ["search", "issues"] [("q", Just $ TE.encodeUtf8 searchString)]+    PagedQuery ["search", "issues"] [("q", Just $ TE.encodeUtf8 searchString)]++-- | Search users.+-- See <https://developer.github.com/v3/search/#search-code>+searchUsersR :: Text -> FetchCount -> Request k (SearchResult SimpleUser)+searchUsersR searchString =+    PagedQuery ["search", "users"] [("q", Just $ TE.encodeUtf8 searchString)]
src/GitHub/Endpoints/Users.hs view
@@ -1,40 +1,26 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The Github Users API, as described at -- <http://developer.github.com/v3/users/>.+ module GitHub.Endpoints.Users (-    userInfoFor,-    userInfoFor',     userInfoForR,     ownerInfoForR,-    userInfoCurrent',     userInfoCurrentR,     module GitHub.Data,     ) where  import GitHub.Data-import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | The information for a single user, by login name.--- With authentification------ > userInfoFor' (Just ("github-username", "github-password")) "mike-burns"-userInfoFor' :: Maybe Auth -> Name User -> IO (Either Error User)-userInfoFor' auth = executeRequestMaybe auth . userInfoForR---- | The information for a single user, by login name.------ > userInfoFor "mike-burns"-userInfoFor :: Name User -> IO (Either Error User)-userInfoFor = executeRequest' . userInfoForR- -- | Query a single user. -- See <https://developer.github.com/v3/users/#get-a-single-user>+--+-- >>> github' userInfoForR "mike-burns"+--+-- or+--+-- >>> github userInfoForR (OAuth "github-token") "mike-burns"+-- userInfoForR :: Name User -> Request k User userInfoForR user = query ["users", toPathPart user] [] @@ -42,13 +28,6 @@ -- See <https://developer.github.com/v3/users/#get-a-single-user> ownerInfoForR :: Name Owner -> Request k Owner ownerInfoForR owner = query ["users", toPathPart owner] []---- | Retrieve information about the user associated with the supplied authentication.------ > userInfoCurrent' (OAuth "...")-userInfoCurrent' :: Auth -> IO (Either Error User)-userInfoCurrent' auth =-    executeRequest auth $ userInfoCurrentR  -- | Query the authenticated user. -- See <https://developer.github.com/v3/users/#get-the-authenticated-user>
src/GitHub/Endpoints/Users/Emails.hs view
@@ -1,42 +1,22 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The user emails API as described on -- <http://developer.github.com/v3/users/emails/>.+ module GitHub.Endpoints.Users.Emails (-    currentUserEmails',     currentUserEmailsR,-    currentUserPublicEmails',     currentUserPublicEmailsR,     module GitHub.Data,     ) where  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | List email addresses for the authenticated user.------ > currentUserEmails' (OAuth "token")-currentUserEmails' :: Auth -> IO (Either Error (Vector Email))-currentUserEmails' auth =-    executeRequest auth $ currentUserEmailsR FetchAll- -- | List email addresses. -- See <https://developer.github.com/v3/users/emails/#list-email-addresses-for-a-user> currentUserEmailsR :: FetchCount -> Request 'RA (Vector Email) currentUserEmailsR =     pagedQuery ["user", "emails"] []---- | List public email addresses for the authenticated user.------ > currentUserPublicEmails' (OAuth "token")-currentUserPublicEmails' :: Auth -> IO (Either Error (Vector Email))-currentUserPublicEmails' auth =-    executeRequest auth $ currentUserPublicEmailsR FetchAll  -- | List public email addresses. -- See <https://developer.github.com/v3/users/emails/#list-public-email-addresses-for-a-user>
src/GitHub/Endpoints/Users/Followers.hs view
@@ -1,13 +1,8 @@------------------------------------------------------------------------------ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- The user followers API as described on -- <http://developer.github.com/v3/users/followers/>.+ module GitHub.Endpoints.Users.Followers (-    usersFollowing,-    usersFollowedBy,     usersFollowingR,     usersFollowedByR,     module GitHub.Data,@@ -15,28 +10,13 @@  import GitHub.Data import GitHub.Internal.Prelude-import GitHub.Request import Prelude () --- | All the users following the given user.------ > usersFollowing "mike-burns"-usersFollowing :: Name User -> IO (Either Error (Vector SimpleUser))-usersFollowing user =-    executeRequest' $ usersFollowingR user FetchAll- -- | List followers of a user. -- See <https://developer.github.com/v3/users/followers/#list-followers-of-a-user> usersFollowingR :: Name User -> FetchCount -> Request k (Vector SimpleUser) usersFollowingR user =     pagedQuery ["users", toPathPart user, "followers"] []---- | All the users that the given user follows.------ > usersFollowedBy "mike-burns"-usersFollowedBy :: Name User -> IO (Either Error (Vector SimpleUser))-usersFollowedBy user =-    executeRequest' $ usersFollowedByR user FetchAll  -- | List users followed by another user. -- See <https://developer.github.com/v3/users/followers/#list-users-followed-by-another-user>
+ src/GitHub/Endpoints/Users/PublicSSHKeys.hs view
@@ -0,0 +1,53 @@+-----------------------------------------------------------------------------+-- |+-- License     :  BSD-3-Clause+-- Maintainer  :  Todd Mohney <toddmohney@gmail.com>+--+-- The public keys API, as described at+-- <https://developer.github.com/v3/users/keys/>+module GitHub.Endpoints.Users.PublicSSHKeys (+    -- * Querying public SSH keys+    publicSSHKeysR,+    publicSSHKeysForR,+    publicSSHKeyR,++    -- ** Create+    createUserPublicSSHKeyR,++    -- ** Delete+    deleteUserPublicSSHKeyR,+) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | Querying public SSH keys.+-- See <https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user>+publicSSHKeysForR :: Name Owner -> FetchCount -> Request 'RO (Vector PublicSSHKeyBasic)+publicSSHKeysForR user =+    pagedQuery ["users", toPathPart user, "keys"] []++-- | Querying the authenticated users' public SSH keys+-- See <https://developer.github.com/v3/users/keys/#list-your-public-keys>+publicSSHKeysR :: Request 'RA (Vector PublicSSHKey)+publicSSHKeysR =+    query ["user", "keys"] []++-- | Querying a public SSH key.+-- See <https://developer.github.com/v3/users/keys/#get-a-single-public-key>+publicSSHKeyR :: Id PublicSSHKey -> Request 'RA PublicSSHKey+publicSSHKeyR keyId =+    query ["user", "keys", toPathPart keyId] []++-- | Create a public SSH key.+-- See <https://developer.github.com/v3/users/keys/#create-a-public-key>.+createUserPublicSSHKeyR :: NewPublicSSHKey -> Request 'RW PublicSSHKey+createUserPublicSSHKeyR key =+    command Post ["user", "keys"] (encode key)++-- | Delete a public SSH key.+-- See <https://developer.github.com/v3/users/keys/#delete-a-public-key>+deleteUserPublicSSHKeyR :: Id PublicSSHKey -> GenRequest 'MtUnit 'RW ()+deleteUserPublicSSHKeyR keyId =+    Command Delete ["user", "keys", toPathPart keyId] mempty
+ src/GitHub/Enterprise.hs view
@@ -0,0 +1,19 @@+-- |+-- This module re-exports all request constructors and data definitions for+-- working with GitHub Enterprise.++module GitHub.Enterprise (+    -- * Enterprise Admin+    -- | See <https://developer.github.com/enterprise/v3/enterprise-admin/>++    -- ** Organizations+    -- | See <https://developer.github.com/enterprise/v3/enterprise-admin/orgs/>+    createOrganizationR,+    renameOrganizationR,++    -- * Data definitions+    module GitHub.Data.Enterprise,+    ) where++import GitHub.Data.Enterprise+import GitHub.Endpoints.Enterprise.Organizations
src/GitHub/Internal/Prelude.hs view
@@ -1,60 +1,30 @@ {-# LANGUAGE NoImplicitPrelude #-}------------------------------------------------------------------------------+ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>------ This module may change between minor releases. Do not rely on it contents.-module GitHub.Internal.Prelude (-    module Prelude.Compat,-    -- * Commonly used types-    UTCTime,-    HashMap,-    Text, pack, unpack,-    Vector,-    -- * Commonly used typeclasses-    Binary,-    Data, Typeable,-    Generic,-    Hashable(..),-    IsString(..),-    NFData(..), genericRnf,-    Semigroup(..),-    -- * Aeson-    FromJSON(..), ToJSON(..), Value(..), Object,-    encode,-    withText, withObject, (.:), (.:?), (.!=), (.=), object, typeMismatch,-    -- * Control.Applicative-    (<|>),-    -- * Data.Maybe-    catMaybes,-    -- * Data.List-    intercalate, toList,-    -- * Data.Time.ISO8601-    formatISO8601,-    ) where+-- This module may change between minor releases. Do not rely on its contents. -import Control.Applicative      ((<|>))-import Control.DeepSeq          (NFData (..))-import Control.DeepSeq.Generics (genericRnf)-import Data.Aeson.Compat+module GitHub.Internal.Prelude ( module X ) where++import Control.Applicative      as X ((<|>))+import Control.DeepSeq          as X (NFData (..))+import Data.Aeson               as X        (FromJSON (..), Object, ToJSON (..), Value (..), encode, object,        withObject, withText, (.!=), (.:), (.:?), (.=))-import Data.Aeson.Types         (typeMismatch)-import Data.Binary              (Binary)-import Data.Binary.Orphans ()-import Data.Data                (Data, Typeable)-import Data.Foldable            (toList)-import Data.Hashable            (Hashable (..))-import Data.HashMap.Strict      (HashMap)-import Data.List                (intercalate)-import Data.Maybe               (catMaybes)-import Data.Semigroup           (Semigroup (..))-import Data.String              (IsString (..))-import Data.Text                (Text, pack, unpack)-import Data.Time                (UTCTime)-import Data.Time.ISO8601        (formatISO8601)-import Data.Vector              (Vector)-import Data.Vector.Instances ()-import GHC.Generics             (Generic)-import Prelude.Compat+import Data.Aeson.Types         as X (emptyObject, typeMismatch)+import Data.Binary              as X (Binary)+import Data.Binary.Instances    as X ()+import Data.Data                as X (Data)+import Data.Foldable            as X (toList)+import Data.Hashable            as X (Hashable (..))+import Data.HashMap.Strict      as X (HashMap)+import Data.List                as X (intercalate)+import Data.Maybe               as X (catMaybes)+import Data.Semigroup           as X (Semigroup (..))+import Data.String              as X (IsString (..))+import Data.Text                as X (Text, pack, unpack)+import Data.Time                as X (UTCTime)+import Data.Time.ISO8601        as X (formatISO8601)+import Data.Vector              as X (Vector)+import GHC.Generics             as X (Generic)+import Prelude.Compat           as X+import Data.Functor.Compat      as X ((<&>))
src/GitHub/Request.hs view
@@ -1,13 +1,13 @@-{-# LANGUAGE CPP                #-}-{-# LANGUAGE FlexibleContexts   #-}-{-# LANGUAGE GADTs              #-}-{-# LANGUAGE KindSignatures     #-}-{-# LANGUAGE StandaloneDeriving #-}------------------------------------------------------------------------------+{-# LANGUAGE CPP                    #-}+{-# LANGUAGE FlexibleContexts       #-}+{-# LANGUAGE FlexibleInstances      #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs                  #-}+{-# LANGUAGE KindSignatures         #-}+{-# LANGUAGE ScopedTypeVariables    #-}+{-# LANGUAGE UndecidableInstances   #-}+ -- |--- License     :  BSD-3-Clause--- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>--- -- This module provides data types and helper methods, which makes possible -- to build alternative API request intepreters in addition to provided -- 'IO' functions.@@ -27,9 +27,16 @@ -- > -- | Lift request into Monad -- > githubRequest :: GH.Request 'False a -> GithubMonad a -- > githubRequest = singleton+ module GitHub.Request (+    -- * A convenient execution of requests+    github,+    github',+    GitHubRW,+    GitHubRO,     -- * Types-    Request(..),+    Request,+    GenRequest (..),     CommandMethod(..),     toMethod,     Paths,@@ -37,172 +44,397 @@     -- * Request execution in IO     executeRequest,     executeRequestWithMgr,+    executeRequestWithMgrAndRes,     executeRequest',     executeRequestWithMgr',     executeRequestMaybe,     unsafeDropAuthRequirements,     -- * Helpers+    Accept (..),+    ParseResponse (..),     makeHttpRequest,-    makeHttpSimpleRequest,-    parseResponse,     parseStatus,+    parsePageLinks,+    StatusMap,     getNextUrl,     performPagedRequest,+    parseResponseJSON,+    -- ** Preview+    PreviewAccept (..),+    PreviewParseResponse (..),+    -- * SSL+    -- | This always exist, independently of @openssl@ configuration flag.+    -- They change accordingly, to make use of the library simpler.+    withOpenSSL,+    tlsManagerSettings,     ) where  import GitHub.Internal.Prelude import Prelude () -#if MIN_VERSION_mtl(2,2,0)-import Control.Monad.Except (MonadError (..))-#else-import Control.Monad.Error (MonadError (..))-#endif+import Control.Monad.Error.Class (MonadError (..))  import Control.Monad              (when) import Control.Monad.Catch        (MonadCatch (..), MonadThrow) import Control.Monad.Trans.Class  (lift) import Control.Monad.Trans.Except (ExceptT (..), runExceptT)-import Data.Aeson.Compat          (eitherDecode)+import Data.Aeson                 (eitherDecode) import Data.List                  (find)+import Data.Maybe                 (fromMaybe)+import Data.Tagged                (Tagged (..))+import Data.Version               (showVersion)  import Network.HTTP.Client-       (HttpException (..), Manager, RequestBody (..), Response (..),-       applyBasicAuth, getUri, httpLbs, method, newManager, redirectCount,-       requestBody, requestHeaders, setQueryString, setRequestIgnoreStatus)-import Network.HTTP.Client.TLS  (tlsManagerSettings)+       (HttpException (..), Manager, RequestBody (..), Response (..), getUri,+       httpLbs, method, newManager, redirectCount, requestBody, requestHeaders,+       setQueryString, setRequestIgnoreStatus) import Network.HTTP.Link.Parser (parseLinkHeaderBS)-import Network.HTTP.Link.Types  (Link (..), LinkParam (..), href, linkParams)+import Network.HTTP.Link.Types  (Link(..), LinkParam (..), href, linkParams) import Network.HTTP.Types       (Method, RequestHeaders, Status (..))-import Network.URI              (URI, parseURIReference, relativeTo)--#if !MIN_VERSION_http_client(0,5,0)-import qualified Control.Exception  as E-import           Network.HTTP.Types (ResponseHeaders)-#endif+import Network.URI+       (URI, escapeURIString, isUnescapedInURIComponent, parseURIReference,+       relativeTo) +import qualified Data.ByteString              as BS+import           Data.ByteString.Builder      (intDec, toLazyByteString) import qualified Data.ByteString.Lazy         as LBS import qualified Data.Text                    as T import qualified Data.Text.Encoding           as TE-import qualified Data.Vector                  as V import qualified Network.HTTP.Client          as HTTP import qualified Network.HTTP.Client.Internal as HTTP -import GitHub.Auth         (Auth (..))-import GitHub.Data         (Error (..))+#ifdef MIN_VERSION_http_client_tls+import Network.HTTP.Client.TLS (tlsManagerSettings)+#else+import Network.HTTP.Client.OpenSSL (opensslManagerSettings, withOpenSSL)++import qualified OpenSSL.Session          as SSL+import qualified OpenSSL.X509.SystemStore as SSL+#endif++import GitHub.Auth              (AuthMethod, endpoint, setAuthRequest)+import GitHub.Data              (Error (..))+import GitHub.Data.PullRequests (MergeResult (..)) import GitHub.Data.Request --- | Execute 'Request' in 'IO'-executeRequest :: Auth -> Request k a -> IO (Either Error a)-executeRequest auth req = do-    manager <- newManager tlsManagerSettings-    x <- executeRequestWithMgr manager auth req-#if !MIN_VERSION_http_client(0, 4, 18)-    closeManager manager+import Paths_github (version)++-------------------------------------------------------------------------------+-- Convenience+-------------------------------------------------------------------------------++-- | A convenience function to turn functions returning @'Request' rw x@,+-- into functions returning @IO (Either 'Error' x)@.+--+-- >>> :t \auth -> github auth userInfoForR+-- \auth -> github auth userInfoForR+--   :: AuthMethod am => am -> Name User -> IO (Either Error User)+--+-- >>> :t github pullRequestsForR+-- \auth -> github auth pullRequestsForR+--   :: AuthMethod am =>+--      am+--      -> Name Owner+--      -> Name Repo+--      -> PullRequestMod+--      -> FetchCount+--      -> IO (Either Error (Data.Vector.Vector SimplePullRequest))+--+github :: (AuthMethod am, GitHubRW req res) => am -> req -> res+github = githubImpl++-- | Like 'github'' but for 'RO' i.e. read-only requests.+-- Note that GitHub has low request limit for non-authenticated requests.+--+-- >>> :t github' userInfoForR+-- github' userInfoForR :: Name User -> IO (Either Error User)+--+github' :: GitHubRO req res => req -> res+github' = githubImpl'++-- | A type-class implementing 'github'.+class GitHubRW req res | req -> res where+    githubImpl :: AuthMethod am => am -> req -> res++-- | A type-class implementing 'github''.+class GitHubRO req res | req -> res where+    githubImpl' :: req -> res++instance (ParseResponse mt req, res ~ Either Error req) => GitHubRW (GenRequest mt rw req) (IO res) where+    githubImpl = executeRequest++instance (ParseResponse mt req, res ~ Either Error req, rw ~ 'RO) => GitHubRO (GenRequest mt rw req) (IO res) where+    githubImpl' = executeRequest'++instance GitHubRW req res => GitHubRW (a -> req) (a -> res) where+    githubImpl am req x = githubImpl am (req x)++instance GitHubRO req res => GitHubRO (a -> req) (a -> res) where+    githubImpl' req x = githubImpl' (req x)++-------------------------------------------------------------------------------+-- Execution+-------------------------------------------------------------------------------++#ifdef MIN_VERSION_http_client_tls+withOpenSSL :: IO a -> IO a+withOpenSSL = id+#else+tlsManagerSettings :: HTTP.ManagerSettings+tlsManagerSettings = opensslManagerSettings $ do+    ctx <- SSL.context+    SSL.contextAddOption ctx SSL.SSL_OP_NO_SSLv2+    SSL.contextAddOption ctx SSL.SSL_OP_NO_SSLv3+    SSL.contextAddOption ctx SSL.SSL_OP_NO_TLSv1+    SSL.contextSetCiphers ctx "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"+    SSL.contextLoadSystemCerts ctx+    SSL.contextSetVerificationMode ctx $ SSL.VerifyPeer True True Nothing+    return ctx #endif-    pure x -lessFetchCount :: Int -> FetchCount -> Bool-lessFetchCount _ FetchAll         = True-lessFetchCount i (FetchAtLeast j) = i < fromIntegral j+-- | Execute 'Request' in 'IO'+executeRequest+    :: (AuthMethod am, ParseResponse mt a)+    => am+    -> GenRequest mt rw a+    -> IO (Either Error a)+executeRequest auth req = withOpenSSL $ do+    manager <- newManager tlsManagerSettings+    executeRequestWithMgr manager auth req  -- | Like 'executeRequest' but with provided 'Manager'. executeRequestWithMgr-    :: Manager-    -> Auth-    -> Request k a+    :: (AuthMethod am, ParseResponse mt a)+    => Manager+    -> am+    -> GenRequest mt rw a     -> IO (Either Error a)-executeRequestWithMgr mgr auth req = runExceptT $ do+executeRequestWithMgr mgr auth req =+    fmap (fmap responseBody) (executeRequestWithMgrAndRes mgr auth req)++-- | Execute request and return the last received 'HTTP.Response'.+--+-- @since 0.24+executeRequestWithMgrAndRes+    :: (AuthMethod am, ParseResponse mt a)+    => Manager+    -> am+    -> GenRequest mt rw a+    -> IO (Either Error (HTTP.Response a))+executeRequestWithMgrAndRes mgr auth req = runExceptT $ do     httpReq <- makeHttpRequest (Just auth) req     performHttpReq httpReq req   where-    httpLbs' :: HTTP.Request -> ExceptT Error IO (Response LBS.ByteString)+    httpLbs' :: HTTP.Request -> ExceptT Error IO (HTTP.Response LBS.ByteString)     httpLbs' req' = lift (httpLbs req' mgr) `catch` onHttpException -    performHttpReq :: HTTP.Request -> Request k b -> ExceptT Error IO b-    performHttpReq httpReq (SimpleQuery sreq)   =-        performHttpReq' httpReq sreq-    performHttpReq httpReq (HeaderQuery _ sreq) =-        performHttpReq' httpReq sreq-    performHttpReq httpReq (StatusQuery sm _)   = do-        res <- httpLbs' httpReq-        parseStatus sm  . responseStatus $ res-    performHttpReq httpReq (RedirectQuery _)   = do+    performHttpReq :: forall rw mt b. ParseResponse mt b => HTTP.Request -> GenRequest mt rw b -> ExceptT Error IO (HTTP.Response b)+    performHttpReq httpReq Query {} = do         res <- httpLbs' httpReq-        parseRedirect (getUri httpReq) res+        (<$ res) <$> unTagged (parseResponse httpReq res :: Tagged mt (ExceptT Error IO b)) -    performHttpReq' :: FromJSON b => HTTP.Request -> SimpleRequest k b -> ExceptT Error IO b-    performHttpReq' httpReq Query {} = do-        res <- httpLbs' httpReq-        parseResponse res-    performHttpReq' httpReq (PagedQuery _ _ l) =-        performPagedRequest httpLbs' predicate httpReq-      where-        predicate v = lessFetchCount (V.length v) l-    performHttpReq' httpReq (Command m _ _) = do-        res <- httpLbs' httpReq-        case m of-             Delete -> pure ()-             Put'   -> pure ()-             _      -> parseResponse res+    performHttpReq httpReq (PagedQuery _ _ (FetchPage _)) = do+        (res, _pageLinks) <- unTagged (performPerPageRequest httpLbs' httpReq :: Tagged mt (ExceptT Error IO (HTTP.Response b, PageLinks)))+        return res+    performHttpReq httpReq (PagedQuery _ _ FetchAll) =+        unTagged (performPagedRequest httpLbs' (const True) httpReq :: Tagged mt (ExceptT Error IO (HTTP.Response b)))+    performHttpReq httpReq (PagedQuery _ _ (FetchAtLeast j)) =+        unTagged (performPagedRequest httpLbs' (\v -> length v < fromIntegral j) httpReq :: Tagged mt (ExceptT Error IO (HTTP.Response b))) +    performHttpReq httpReq (Command _ _ _) = do+        res <- httpLbs' httpReq+        (<$ res) <$> unTagged (parseResponse httpReq res :: Tagged mt (ExceptT Error IO b))  -- | Like 'executeRequest' but without authentication.-executeRequest' ::Request 'RO a -> IO (Either Error a)-executeRequest' req = do+executeRequest' :: ParseResponse mt a => GenRequest mt 'RO a -> IO (Either Error a)+executeRequest' req = withOpenSSL $ do     manager <- newManager tlsManagerSettings-    x <- executeRequestWithMgr' manager req-#if !MIN_VERSION_http_client(0, 4, 18)-    closeManager manager-#endif-    pure x+    executeRequestWithMgr' manager req  -- | Like 'executeRequestWithMgr' but without authentication. executeRequestWithMgr'-    :: Manager-    -> Request 'RO a+    :: ParseResponse mt a+    => Manager+    -> GenRequest mt 'RO a     -> IO (Either Error a)-executeRequestWithMgr' mgr req = runExceptT $ do-    httpReq <- makeHttpRequest Nothing req-    performHttpReq httpReq req-  where-    httpLbs' :: HTTP.Request -> ExceptT Error IO (Response LBS.ByteString)-    httpLbs' req' = lift (httpLbs req' mgr) `catch` onHttpException--    performHttpReq :: HTTP.Request -> Request 'RO b -> ExceptT Error IO b-    performHttpReq httpReq (SimpleQuery sreq)   =-        performHttpReq' httpReq sreq-    performHttpReq httpReq (HeaderQuery _ sreq) =-        performHttpReq' httpReq sreq-    performHttpReq httpReq (StatusQuery sm _)   = do-        res <- httpLbs' httpReq-        parseStatus sm  . responseStatus $ res-    performHttpReq httpReq (RedirectQuery _)   = do-        res <- httpLbs' httpReq-        parseRedirect (getUri httpReq) res--    performHttpReq' :: FromJSON b => HTTP.Request -> SimpleRequest 'RO b -> ExceptT Error IO b-    performHttpReq' httpReq Query {} = do-        res <- httpLbs' httpReq-        parseResponse res-    performHttpReq' httpReq (PagedQuery _ _ l) =-        performPagedRequest httpLbs' predicate httpReq-      where-        predicate v = lessFetchCount (V.length v) l+executeRequestWithMgr' mgr = executeRequestWithMgr mgr ()  -- | Helper for picking between 'executeRequest' and 'executeRequest''. -- -- The use is discouraged.-executeRequestMaybe :: Maybe Auth -> Request 'RO a -> IO (Either Error a)+executeRequestMaybe+    :: (AuthMethod am, ParseResponse mt a)+    => Maybe am+    -> GenRequest mt 'RO a+    -> IO (Either Error a) executeRequestMaybe = maybe executeRequest' executeRequest  -- | Partial function to drop authentication need.-unsafeDropAuthRequirements :: Request k' a -> Request k a-unsafeDropAuthRequirements (SimpleQuery (Query ps qs)) =-    SimpleQuery (Query ps qs)-unsafeDropAuthRequirements r                 =+unsafeDropAuthRequirements :: GenRequest mt rw' a -> GenRequest mt rw a+unsafeDropAuthRequirements (Query ps qs) = Query ps qs+unsafeDropAuthRequirements r             =     error $ "Trying to drop authenatication from" ++ show r +-------------------------------------------------------------------------------+-- Parse response+-------------------------------------------------------------------------------++class Accept (mt :: MediaType *) where+    contentType :: Tagged mt BS.ByteString+    contentType = Tagged "application/json" -- default is JSON++    modifyRequest :: Tagged mt (HTTP.Request -> HTTP.Request)+    modifyRequest = Tagged id++class Accept mt => ParseResponse (mt :: MediaType *) a where+    parseResponse+        :: MonadError Error m+        => HTTP.Request -> HTTP.Response LBS.ByteString+        -> Tagged mt (m a)++-------------------------------------------------------------------------------+-- JSON (+ star)+-------------------------------------------------------------------------------++-- | Parse API response.+--+-- @+-- parseResponse :: 'FromJSON' a => 'HTTP.Response' 'LBS.ByteString' -> 'Either' 'Error' a+-- @+parseResponseJSON :: (FromJSON a, MonadError Error m) => HTTP.Response LBS.ByteString -> m a+parseResponseJSON res = case eitherDecode (responseBody res) of+    Right x  -> return x+    Left err -> throwError . ParseError . T.pack $ err++instance Accept 'MtJSON where+    contentType = Tagged "application/vnd.github.v3+json"++instance FromJSON a => ParseResponse 'MtJSON a where+    parseResponse _ res = Tagged (parseResponseJSON res)++instance Accept 'MtStar where+    contentType = Tagged "application/vnd.github.v3.star+json"++instance FromJSON a => ParseResponse 'MtStar a where+    parseResponse _ res = Tagged (parseResponseJSON res)++-------------------------------------------------------------------------------+-- Raw / Diff / Patch / Sha+-------------------------------------------------------------------------------++instance Accept 'MtRaw   where contentType = Tagged "application/vnd.github.v3.raw"+instance Accept 'MtDiff  where contentType = Tagged "application/vnd.github.v3.diff"+instance Accept 'MtPatch where contentType = Tagged "application/vnd.github.v3.patch"+instance Accept 'MtSha   where contentType = Tagged "application/vnd.github.v3.sha"++instance a ~ LBS.ByteString => ParseResponse 'MtRaw   a where parseResponse _ = Tagged . return . responseBody+instance a ~ LBS.ByteString => ParseResponse 'MtDiff  a where parseResponse _ = Tagged . return . responseBody+instance a ~ LBS.ByteString => ParseResponse 'MtPatch a where parseResponse _ = Tagged . return . responseBody+instance a ~ LBS.ByteString => ParseResponse 'MtSha   a where parseResponse _ = Tagged . return . responseBody++-------------------------------------------------------------------------------+-- Redirect+-------------------------------------------------------------------------------++instance Accept 'MtRedirect where+    modifyRequest = Tagged $ \req ->+        setRequestIgnoreStatus $ req { redirectCount = 0 }++instance b ~ URI => ParseResponse 'MtRedirect b where+    parseResponse req = Tagged . parseRedirect (getUri req)++-- | Helper for handling of 'RequestRedirect'.+--+-- @+-- parseRedirect :: 'HTTP.Response' 'LBS.ByteString' -> 'Either' 'Error' a+-- @+parseRedirect :: MonadError Error m => URI -> HTTP.Response LBS.ByteString -> m URI+parseRedirect originalUri rsp = do+    let status = responseStatus rsp+    when (statusCode status /= 302) $+        throwError $ ParseError $ "invalid status: " <> T.pack (show status)+    loc <- maybe noLocation return $ lookup "Location" $ responseHeaders rsp+    case parseURIReference $ T.unpack $ TE.decodeUtf8 loc of+        Nothing -> throwError $ ParseError $+            "location header does not contain a URI: " <> T.pack (show loc)+        Just uri -> return $ uri `relativeTo` originalUri+  where+    noLocation = throwError $ ParseError "no location header in response"++-------------------------------------------------------------------------------+-- Extension point+-------------------------------------------------------------------------------++class PreviewAccept p where+    previewContentType :: Tagged ('MtPreview p) BS.ByteString++    previewModifyRequest :: Tagged ('MtPreview p) (HTTP.Request -> HTTP.Request)+    previewModifyRequest = Tagged id++class PreviewAccept p => PreviewParseResponse p a where+    previewParseResponse+        :: MonadError Error m+        => HTTP.Request -> HTTP.Response LBS.ByteString+        -> Tagged ('MtPreview p) (m a)++instance PreviewAccept p => Accept ('MtPreview p) where+    contentType   = previewContentType+    modifyRequest = previewModifyRequest++instance PreviewParseResponse p a => ParseResponse ('MtPreview p) a where+    parseResponse = previewParseResponse++-------------------------------------------------------------------------------+-- Status+-------------------------------------------------------------------------------++instance Accept 'MtStatus where+    modifyRequest = Tagged setRequestIgnoreStatus++instance HasStatusMap a => ParseResponse 'MtStatus a where+    parseResponse _ = Tagged . parseStatus statusMap . responseStatus++type StatusMap a = [(Int, a)]++class HasStatusMap a where+    statusMap :: StatusMap a++instance HasStatusMap Bool where+    statusMap =+        [ (204, True)+        , (404, False)+        ]++instance HasStatusMap MergeResult where+    statusMap =+        [ (200, MergeSuccessful)+        , (405, MergeCannotPerform)+        , (409, MergeConflict)+        ]++-- | Helper for handling of 'RequestStatus'.+--+-- @+-- parseStatus :: 'StatusMap' a -> 'Status' -> 'Either' 'Error' a+-- @+parseStatus :: MonadError Error m => StatusMap a -> Status -> m a+parseStatus m (Status sci _) =+    maybe err return $ lookup sci m+  where+    err = throwError $ JsonError $ "invalid status: " <> T.pack (show sci)++-------------------------------------------------------------------------------+-- Unit+-------------------------------------------------------------------------------++-- | Note: we don't ignore response status.+--+-- We only accept any response body.+instance Accept 'MtUnit where++instance a ~ () => ParseResponse 'MtUnit a where+    parseResponse _ _ = Tagged (return ())+ ------------------------------------------------------------------------------ -- Tools ------------------------------------------------------------------------------@@ -213,73 +445,44 @@ -- * for 'Status', the 'Request' for underlying 'Request' is created, --   status checking is modifying accordingly. ----- @--- parseResponse :: 'Maybe' 'Auth' -> 'Request' k a -> 'Maybe' 'Request'--- @ makeHttpRequest-    :: MonadThrow m-    => Maybe Auth-    -> Request k a+    :: forall am mt rw a m. (AuthMethod am, MonadThrow m, Accept mt)+    => Maybe am+    -> GenRequest mt rw a     -> m HTTP.Request makeHttpRequest auth r = case r of-    SimpleQuery req ->-        makeHttpSimpleRequest auth req-    StatusQuery sm req -> do-        req' <- makeHttpSimpleRequest auth req-        return $ setCheckStatus (Just sm) req'-    HeaderQuery h req -> do-        req' <- makeHttpSimpleRequest auth req-        return $ req' { requestHeaders = h <> requestHeaders req' }-    RedirectQuery req -> do-        req' <- makeHttpSimpleRequest auth req-        return $ setRequestIgnoreStatus $ req' { redirectCount = 0 }--makeHttpSimpleRequest-    :: MonadThrow m-    => Maybe Auth-    -> SimpleRequest k a-    -> m HTTP.Request-makeHttpSimpleRequest auth r = case r of     Query paths qs -> do         req <- parseUrl' $ url paths         return             $ setReqHeaders-            . setCheckStatus Nothing-            . setAuthRequest auth-            . setQueryString qs+            . unTagged (modifyRequest :: Tagged mt (HTTP.Request -> HTTP.Request))+            . maybe id setAuthRequest auth+            . setQueryString (qs <> extraQueryItems)             $ req     PagedQuery paths qs _ -> do         req <- parseUrl' $ url paths         return             $ setReqHeaders-            . setCheckStatus Nothing-            . setAuthRequest auth-            . setQueryString qs+            . unTagged (modifyRequest :: Tagged mt (HTTP.Request -> HTTP.Request))+            . maybe id setAuthRequest auth+            . setQueryString (qs <> extraQueryItems)             $ req     Command m paths body -> do         req <- parseUrl' $ url paths         return             $ setReqHeaders-            . setCheckStatus Nothing-            . setAuthRequest auth+            . unTagged (modifyRequest :: Tagged mt (HTTP.Request -> HTTP.Request))+            . maybe id setAuthRequest auth             . setBody body             . setMethod (toMethod m)             $ req   where-    parseUrl' :: MonadThrow m => Text -> m HTTP.Request-#if MIN_VERSION_http_client(0,4,30)-    parseUrl' = HTTP.parseRequest . T.unpack-#else-    parseUrl' = HTTP.parseUrl . T.unpack-#endif--    url :: Paths -> Text-    url paths = baseUrl <> "/" <> T.intercalate "/" paths+    parseUrl' :: MonadThrow m => String -> m HTTP.Request+    parseUrl' = HTTP.parseUrlThrow -    baseUrl :: Text-    baseUrl = case auth of-        Just (EnterpriseOAuth endpoint _)  -> endpoint-        _                                  -> "https://api.github.com"+    url :: Paths -> String+    url paths = maybe "https://api.github.com" T.unpack (endpoint =<< auth) ++ "/" ++ intercalate "/" paths' where+        paths' = map (escapeURIString isUnescapedInURIComponent . T.unpack) paths      setReqHeaders :: HTTP.Request -> HTTP.Request     setReqHeaders req = req { requestHeaders = reqHeaders <> requestHeaders req }@@ -288,138 +491,98 @@     setMethod m req = req { method = m }      reqHeaders :: RequestHeaders-    reqHeaders = maybe [] getOAuthHeader auth-        <> [("User-Agent", "github.hs/0.7.4")]-        <> [("Accept", "application/vnd.github.preview")]+    reqHeaders = [("User-Agent", "github.hs/" <> fromString (showVersion version))] -- Version+        <> [("Accept", unTagged (contentType :: Tagged mt BS.ByteString))]      setBody :: LBS.ByteString -> HTTP.Request -> HTTP.Request     setBody body req = req { requestBody = RequestBodyLBS body } -    setAuthRequest :: Maybe Auth -> HTTP.Request -> HTTP.Request-    setAuthRequest (Just (BasicAuth user pass)) = applyBasicAuth user pass-    setAuthRequest _                                  = id--    getOAuthHeader :: Auth -> RequestHeaders-    getOAuthHeader (OAuth token)             = [("Authorization", "token " <> token)]-    getOAuthHeader (EnterpriseOAuth _ token) = [("Authorization", "token " <> token)]-    getOAuthHeader _                         = []+    extraQueryItems :: [(BS.ByteString, Maybe BS.ByteString)]+    extraQueryItems = case r of+      PagedQuery _ _ (FetchPage pp) -> catMaybes [+          (\page -> ("page", Just (LBS.toStrict $ toLazyByteString $ intDec page))) <$> pageParamsPage pp+          , (\perPage -> ("per_page", Just (LBS.toStrict $ toLazyByteString $ intDec perPage))) <$> pageParamsPerPage pp+          ]+      _ -> []  -- | Query @Link@ header with @rel=next@ from the request headers.-getNextUrl :: Response a -> Maybe URI+getNextUrl :: HTTP.Response a -> Maybe URI getNextUrl req = do     linkHeader <- lookup "Link" (responseHeaders req)     links <- parseLinkHeaderBS linkHeader     nextURI <- find isRelNext links     return $ href nextURI   where-    isRelNext :: Link -> Bool+    -- isRelNext :: Link -> Bool or Link uri -> Bool     isRelNext = any (== relNextLinkParam) . linkParams      relNextLinkParam :: (LinkParam, Text)     relNextLinkParam = (Rel, "next") --- | Parse API response.------ @--- parseResponse :: 'FromJSON' a => 'Response' 'LBS.ByteString' -> 'Either' 'Error' a--- @-parseResponse :: (FromJSON a, MonadError Error m) => Response LBS.ByteString -> m a-parseResponse res = case eitherDecode (responseBody res) of-    Right x  -> return x-    Left err -> throwError . ParseError . T.pack $ err---- | Helper for handling of 'RequestStatus'.------ @--- parseStatus :: 'StatusMap' a -> 'Status' -> 'Either' 'Error' a--- @-parseStatus :: MonadError Error m => StatusMap a -> Status -> m a-parseStatus m (Status sci _) =-    maybe err return $ lookup sci m-  where-    err = throwError $ JsonError $ "invalid status: " <> T.pack (show sci)---- | Helper for handling of 'RequestRedirect'.------ @--- parseRedirect :: 'Response' 'LBS.ByteString' -> 'Either' 'Error' a--- @-parseRedirect :: MonadError Error m => URI -> Response LBS.ByteString -> m URI-parseRedirect originalUri rsp = do-    let status = responseStatus rsp-    when (statusCode status /= 302) $-        throwError $ ParseError $ "invalid status: " <> T.pack (show status)-    loc <- maybe noLocation return $ lookup "Location" $ responseHeaders rsp-    case parseURIReference $ T.unpack $ TE.decodeUtf8 loc of-        Nothing -> throwError $ ParseError $-            "location header does not contain a URI: " <> T.pack (show loc)-        Just uri -> return $ uri `relativeTo` originalUri-  where-    noLocation = throwError $ ParseError "no location header in response"- -- | Helper for making paginated requests. Responses, @a@ are combined monoidally. --+-- The result is wrapped in the last received 'HTTP.Response'.+-- -- @ -- performPagedRequest :: ('FromJSON' a, 'Semigroup' a)---                     => ('HTTP.Request' -> 'ExceptT' 'Error' 'IO' ('Response' 'LBS.ByteString'))+--                     => ('HTTP.Request' -> 'ExceptT' 'Error' 'IO' ('HTTP.Response' 'LBS.ByteString')) --                     -> (a -> 'Bool') --                     -> 'HTTP.Request'---                     -> 'ExceptT' 'Error' 'IO' a+--                     -> 'ExceptT' 'Error' 'IO' ('HTTP.Response' a) -- @ performPagedRequest-    :: forall a m. (FromJSON a, Semigroup a, MonadCatch m, MonadError Error m)-    => (HTTP.Request -> m (Response LBS.ByteString))  -- ^ `httpLbs` analogue-    -> (a -> Bool)                                    -- ^ predicate to continue iteration-    -> HTTP.Request                                   -- ^ initial request-    -> m a-performPagedRequest httpLbs' predicate initReq = do+    :: forall a m mt. (ParseResponse mt a, Semigroup a, MonadCatch m, MonadError Error m)+    => (HTTP.Request -> m (HTTP.Response LBS.ByteString))  -- ^ `httpLbs` analogue+    -> (a -> Bool)                                         -- ^ predicate to continue iteration+    -> HTTP.Request                                        -- ^ initial request+    -> Tagged mt (m (HTTP.Response a))+performPagedRequest httpLbs' predicate initReq = Tagged $ do     res <- httpLbs' initReq-    m <- parseResponse res+    m <- unTagged (parseResponse initReq res :: Tagged mt (m a))     go m res initReq   where-    go :: a -> Response LBS.ByteString -> HTTP.Request -> m a+    go :: a -> HTTP.Response LBS.ByteString -> HTTP.Request -> m (HTTP.Response a)     go acc res req =         case (predicate acc, getNextUrl res) of             (True, Just uri) -> do                 req' <- HTTP.setUri req uri                 res' <- httpLbs' req'-                m <- parseResponse res'+                m <- unTagged (parseResponse req' res' :: Tagged mt (m a))                 go (acc <> m) res' req'-            (_, _)           -> return acc------------------------------------------------------------------------------------ Internal--------------------------------------------------------------------------------+            (_, _)           -> return (acc <$ res) +-- | Helper for requesting a single page, as specified by 'PageParams'.+--+-- This parses and returns the 'PageLinks' alongside the HTTP response.+performPerPageRequest+    :: forall a m mt. (ParseResponse mt a, MonadCatch m, MonadError Error m)+    => (HTTP.Request -> m (HTTP.Response LBS.ByteString))  -- ^ `httpLbs` analogue+    -> HTTP.Request                                        -- ^ initial request+    -> Tagged mt (m (HTTP.Response a, PageLinks))+performPerPageRequest httpLbs' initReq = Tagged $ do+    res <- httpLbs' initReq+    m <- unTagged (parseResponse initReq res :: Tagged mt (m a))+    return (m <$ res, parsePageLinks res) -setCheckStatus :: Maybe (StatusMap a) -> HTTP.Request -> HTTP.Request-#if MIN_VERSION_http_client(0,5,0)-setCheckStatus sm req = req { HTTP.checkResponse = successOrMissing sm }-#else-setCheckStatus sm req = req { HTTP.checkStatus = successOrMissing sm }-#endif+-- | Parse the 'PageLinks' from an HTTP response, where the information is+-- encoded in the Link header.+parsePageLinks :: HTTP.Response a -> PageLinks+parsePageLinks res = PageLinks {+    pageLinksPrev = linkToUri <$> find (elem (Rel, "prev") . linkParams) links+    , pageLinksNext = linkToUri <$> find (elem (Rel, "next") . linkParams) links+    , pageLinksLast = linkToUri <$> find (elem (Rel, "last") . linkParams) links+    , pageLinksFirst = linkToUri <$> find (elem (Rel, "first") . linkParams) links+    }+    where+        links :: [Link URI]+        links = fromMaybe [] (lookup "Link" (responseHeaders res) >>= parseLinkHeaderBS) +        linkToUri :: Link URI -> URI+        linkToUri (Link uri _) = uri -#if MIN_VERSION_http_client(0,5,0)-successOrMissing :: Maybe (StatusMap a) -> HTTP.Request -> HTTP.Response HTTP.BodyReader -> IO ()-successOrMissing sm _req res-    | check     = pure ()-    | otherwise = do-        chunk <- HTTP.brReadSome (HTTP.responseBody res) 1024-        let res' = fmap (const ()) res-        HTTP.throwHttp $ HTTP.StatusCodeException res' (LBS.toStrict chunk)-  where-    Status sci _ = HTTP.responseStatus res-#else-successOrMissing :: Maybe (StatusMap a) -> Status -> ResponseHeaders -> HTTP.CookieJar -> Maybe E.SomeException-successOrMissing sm s@(Status sci _) hs cookiejar-    | check     = Nothing-    | otherwise = Just $ E.toException $ StatusCodeException s hs cookiejar-  where-#endif-    check = case sm of-      Nothing  -> 200 <= sci && sci < 300-      Just sm' -> sci `elem` map fst sm'+-------------------------------------------------------------------------------+-- Internal+-------------------------------------------------------------------------------  onHttpException :: MonadError Error m => HttpException -> m a onHttpException = throwError . HTTPError